summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig10
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/acpica/tbutils.c7
-rw-r--r--drivers/acpi/acpica/tbxface.c17
-rw-r--r--drivers/acpi/acpica/uteval.c21
-rw-r--r--drivers/acpi/battery.c25
-rw-r--r--drivers/acpi/container.c5
-rw-r--r--drivers/acpi/dock.c14
-rw-r--r--drivers/acpi/ec.c11
-rw-r--r--drivers/acpi/glue.c8
-rw-r--r--drivers/acpi/osl.c65
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/pci_root.c180
-rw-r--r--drivers/acpi/processor_idle.c667
-rw-r--r--drivers/acpi/processor_perflib.c105
-rw-r--r--drivers/acpi/sleep.c53
-rw-r--r--drivers/acpi/tables.c27
-rw-r--r--drivers/acpi/video.c16
-rw-r--r--drivers/amba/bus.c4
-rw-r--r--drivers/ata/Kconfig6
-rw-r--r--drivers/ata/ahci.c45
-rw-r--r--drivers/ata/ata_piix.c34
-rw-r--r--drivers/ata/libata-core.c97
-rw-r--r--drivers/ata/libata-eh.c87
-rw-r--r--drivers/ata/libata-pmp.c2
-rw-r--r--drivers/ata/libata-scsi.c21
-rw-r--r--drivers/ata/libata-sff.c40
-rw-r--r--drivers/ata/libata.h6
-rw-r--r--drivers/ata/pata_amd.c76
-rw-r--r--drivers/ata/pata_icside.c19
-rw-r--r--drivers/ata/pata_it821x.c3
-rw-r--r--drivers/ata/pata_legacy.c7
-rw-r--r--drivers/ata/pata_qdi.c2
-rw-r--r--drivers/ata/pata_rb532_cf.c62
-rw-r--r--drivers/ata/pata_via.c26
-rw-r--r--drivers/ata/sata_mv.c669
-rw-r--r--drivers/ata/sata_nv.c89
-rw-r--r--drivers/ata/sata_sil.c39
-rw-r--r--drivers/atm/fore200e.c4
-rw-r--r--drivers/atm/lanai.c2
-rw-r--r--drivers/atm/solos-pci.c1
-rw-r--r--drivers/base/base.h33
-rw-r--r--drivers/base/bus.c44
-rw-r--r--drivers/base/core.c83
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/dd.c45
-rw-r--r--drivers/base/driver.c15
-rw-r--r--drivers/base/platform.c44
-rw-r--r--drivers/base/power/main.c3
-rw-r--r--drivers/base/sys.c7
-rw-r--r--drivers/base/topology.c33
-rw-r--r--drivers/block/aoe/aoe.h1
-rw-r--r--drivers/block/aoe/aoenet.c2
-rw-r--r--drivers/block/ataflop.c4
-rw-r--r--drivers/block/cciss.c219
-rw-r--r--drivers/block/floppy.c82
-rw-r--r--drivers/block/nbd.c9
-rw-r--r--drivers/block/paride/pg.c2
-rw-r--r--drivers/block/ub.c11
-rw-r--r--drivers/block/xen-blkfront.c30
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/hvc_iucv.c259
-rw-r--r--drivers/char/hw_random/omap-rng.c2
-rw-r--r--drivers/char/random.c6
-rw-r--r--drivers/char/scc.h2
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/sx.c13
-rw-r--r--drivers/char/sysrq.c4
-rw-r--r--drivers/char/tpm/tpm_atmel.c28
-rw-r--r--drivers/char/tpm/tpm_infineon.c4
-rw-r--r--drivers/char/tpm/tpm_tis.c28
-rw-r--r--drivers/char/tty_io.c4
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/acpi_pm.c2
-rw-r--r--drivers/clocksource/cyclone.c2
-rw-r--r--drivers/clocksource/sh_cmt.c615
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c47
-rw-r--r--drivers/dca/dca-core.c51
-rw-r--r--drivers/dio/dio.c4
-rw-r--r--drivers/dma/Kconfig19
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/dmaengine.c10
-rw-r--r--drivers/dma/dmatest.c35
-rw-r--r--drivers/dma/dw_dmac.c7
-rw-r--r--drivers/dma/dw_dmac_regs.h2
-rw-r--r--drivers/dma/fsldma.c8
-rw-r--r--drivers/dma/ipu/Makefile1
-rw-r--r--drivers/dma/ipu/ipu_idmac.c1740
-rw-r--r--drivers/dma/ipu/ipu_intern.h176
-rw-r--r--drivers/dma/ipu/ipu_irq.c413
-rw-r--r--drivers/edac/cell_edac.c10
-rw-r--r--drivers/edac/mpc85xx_edac.c2
-rw-r--r--drivers/edac/mv64x60_edac.c8
-rw-r--r--drivers/eisa/Kconfig6
-rw-r--r--drivers/eisa/eisa-bus.c4
-rw-r--r--drivers/firewire/fw-card.c13
-rw-r--r--drivers/firewire/fw-device.c123
-rw-r--r--drivers/firewire/fw-device.h1
-rw-r--r--drivers/firewire/fw-ohci.c6
-rw-r--r--drivers/firewire/fw-sbp2.c89
-rw-r--r--drivers/firewire/fw-topology.c12
-rw-r--r--drivers/firewire/fw-transaction.h9
-rw-r--r--drivers/firmware/dcdbas.c12
-rw-r--r--drivers/firmware/dmi_scan.c74
-rw-r--r--drivers/firmware/iscsi_ibft.c4
-rw-r--r--drivers/firmware/memmap.c2
-rw-r--r--drivers/gpio/bt8xxgpio.c2
-rw-r--r--drivers/gpio/gpiolib.c1
-rw-r--r--drivers/gpu/drm/Kconfig15
-rw-r--r--drivers/gpu/drm/drm_agpsupport.c3
-rw-r--r--drivers/gpu/drm/drm_crtc.c17
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c97
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_edid.c8
-rw-r--r--drivers/gpu/drm/drm_fops.c3
-rw-r--r--drivers/gpu/drm/drm_gem.c81
-rw-r--r--drivers/gpu/drm/drm_irq.c176
-rw-r--r--drivers/gpu/drm/drm_memory.c7
-rw-r--r--drivers/gpu/drm/drm_proc.c4
-rw-r--r--drivers/gpu/drm/drm_stub.c8
-rw-r--r--drivers/gpu/drm/drm_sysfs.c4
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c58
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c30
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h11
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c274
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c97
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c13
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h10
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c14
-rw-r--r--drivers/gpu/drm/i915/intel_display.c181
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c8
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c4
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c64
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c872
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo_regs.h404
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c27
-rw-r--r--drivers/hid/Kconfig6
-rw-r--r--drivers/hid/hid-core.c33
-rw-r--r--drivers/hid/hid-ids.h5
-rw-r--r--drivers/hid/hid-microsoft.c13
-rw-r--r--drivers/hid/hidraw.c31
-rw-r--r--drivers/hid/usbhid/hid-core.c475
-rw-r--r--drivers/hid/usbhid/hiddev.c24
-rw-r--r--drivers/hid/usbhid/usbhid.h14
-rw-r--r--drivers/hwmon/abituguru3.c7
-rw-r--r--drivers/hwmon/applesmc.c30
-rw-r--r--drivers/hwmon/ds1621.c172
-rw-r--r--drivers/hwmon/f71882fg.c4
-rw-r--r--drivers/hwmon/hdaps.c66
-rw-r--r--drivers/hwmon/hp_accel.c94
-rw-r--r--drivers/hwmon/lis3lv02d.c195
-rw-r--r--drivers/hwmon/lis3lv02d.h21
-rw-r--r--drivers/hwmon/vt1211.c2
-rw-r--r--drivers/hwmon/w83627ehf.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c4
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c190
-rw-r--r--drivers/i2c/algos/i2c-algo-pcf.c261
-rw-r--r--drivers/i2c/busses/Kconfig8
-rw-r--r--drivers/i2c/busses/i2c-acorn.c6
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c1
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c1
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c1
-rw-r--r--drivers/i2c/busses/i2c-amd756.c1
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c5
-rw-r--r--drivers/i2c/busses/i2c-au1550.c1
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c1
-rw-r--r--drivers/i2c/busses/i2c-davinci.c8
-rw-r--r--drivers/i2c/busses/i2c-elektor.c1
-rw-r--r--drivers/i2c/busses/i2c-hydra.c1
-rw-r--r--drivers/i2c/busses/i2c-i801.c1
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c7
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c3
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c3
-rw-r--r--drivers/i2c/busses/i2c-mpc.c14
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c8
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c11
-rw-r--r--drivers/i2c/busses/i2c-parport-light.c1
-rw-r--r--drivers/i2c/busses/i2c-parport.c1
-rw-r--r--drivers/i2c/busses/i2c-pca-isa.c20
-rw-r--r--drivers/i2c/busses/i2c-pca-platform.c9
-rw-r--r--drivers/i2c/busses/i2c-piix4.c1
-rw-r--r--drivers/i2c/busses/i2c-powermac.c3
-rw-r--r--drivers/i2c/busses/i2c-pxa.c11
-rw-r--r--drivers/i2c/busses/i2c-sibyte.c2
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c1
-rw-r--r--drivers/i2c/busses/i2c-sis630.c1
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c1
-rw-r--r--drivers/i2c/busses/i2c-versatile.c10
-rw-r--r--drivers/i2c/busses/i2c-via.c1
-rw-r--r--drivers/i2c/busses/i2c-viapro.c1
-rw-r--r--drivers/i2c/busses/i2c-voodoo3.c2
-rw-r--r--drivers/i2c/busses/scx200_acb.c1
-rw-r--r--drivers/i2c/busses/scx200_i2c.c3
-rw-r--r--drivers/i2c/chips/Kconfig37
-rw-r--r--drivers/i2c/chips/Makefile2
-rw-r--r--drivers/i2c/i2c-core.c8
-rw-r--r--drivers/i2c/i2c-dev.c6
-rw-r--r--drivers/ide/Kconfig51
-rw-r--r--drivers/ide/Makefile7
-rw-r--r--drivers/ide/aec62xx.c4
-rw-r--r--drivers/ide/alim15x3.c17
-rw-r--r--drivers/ide/amd74xx.c16
-rw-r--r--drivers/ide/atiixp.c7
-rw-r--r--drivers/ide/au1xxx-ide.c86
-rw-r--r--drivers/ide/buddha.c11
-rw-r--r--drivers/ide/cmd64x.c14
-rw-r--r--drivers/ide/cs5520.c3
-rw-r--r--drivers/ide/cs5530.c2
-rw-r--r--drivers/ide/cs5536.c307
-rw-r--r--drivers/ide/delkin_cb.c3
-rw-r--r--drivers/ide/dtc2278.c3
-rw-r--r--drivers/ide/falconide.c45
-rw-r--r--drivers/ide/gayle.c19
-rw-r--r--drivers/ide/hpt366.c20
-rw-r--r--drivers/ide/icside.c34
-rw-r--r--drivers/ide/ide-4drives.c3
-rw-r--r--drivers/ide/ide-acpi.c214
-rw-r--r--drivers/ide/ide-atapi.c116
-rw-r--r--drivers/ide/ide-cd.c678
-rw-r--r--drivers/ide/ide-cd.h6
-rw-r--r--drivers/ide/ide-cs.c1
-rw-r--r--drivers/ide/ide-devsets.c188
-rw-r--r--drivers/ide/ide-disk.c171
-rw-r--r--drivers/ide/ide-disk_proc.c28
-rw-r--r--drivers/ide/ide-dma-sff.c45
-rw-r--r--drivers/ide/ide-dma.c140
-rw-r--r--drivers/ide/ide-eh.c440
-rw-r--r--drivers/ide/ide-floppy.c161
-rw-r--r--drivers/ide/ide-floppy_ioctl.c5
-rw-r--r--drivers/ide/ide-gd.c36
-rw-r--r--drivers/ide/ide-gd.h6
-rw-r--r--drivers/ide/ide-generic.c88
-rw-r--r--drivers/ide/ide-h8300.c66
-rw-r--r--drivers/ide/ide-io-std.c321
-rw-r--r--drivers/ide/ide-io.c596
-rw-r--r--drivers/ide/ide-ioctls.c44
-rw-r--r--drivers/ide/ide-iops.c804
-rw-r--r--drivers/ide/ide-lib.c260
-rw-r--r--drivers/ide/ide-park.c26
-rw-r--r--drivers/ide/ide-pci-generic.c4
-rw-r--r--drivers/ide/ide-pm.c42
-rw-r--r--drivers/ide/ide-pnp.c6
-rw-r--r--drivers/ide/ide-probe.c402
-rw-r--r--drivers/ide/ide-proc.c18
-rw-r--r--drivers/ide/ide-tape.c156
-rw-r--r--drivers/ide/ide-taskfile.c500
-rw-r--r--drivers/ide/ide-xfer-mode.c246
-rw-r--r--drivers/ide/ide.c167
-rw-r--r--drivers/ide/ide_arm.c49
-rw-r--r--drivers/ide/it821x.c10
-rw-r--r--drivers/ide/macide.c7
-rw-r--r--drivers/ide/ns87415.c64
-rw-r--r--drivers/ide/palm_bk3710.c22
-rw-r--r--drivers/ide/pdc202xx_new.c4
-rw-r--r--drivers/ide/pdc202xx_old.c18
-rw-r--r--drivers/ide/piix.c13
-rw-r--r--drivers/ide/pmac.c40
-rw-r--r--drivers/ide/q40ide.c15
-rw-r--r--drivers/ide/qd65xx.c2
-rw-r--r--drivers/ide/qd65xx.h2
-rw-r--r--drivers/ide/sc1200.c6
-rw-r--r--drivers/ide/scc_pata.c121
-rw-r--r--drivers/ide/serverworks.c13
-rw-r--r--drivers/ide/setup-pci.c31
-rw-r--r--drivers/ide/sgiioc4.c43
-rw-r--r--drivers/ide/siimage.c5
-rw-r--r--drivers/ide/sis5513.c4
-rw-r--r--drivers/ide/sl82c105.c13
-rw-r--r--drivers/ide/slc90e66.c1
-rw-r--r--drivers/ide/tc86c001.c3
-rw-r--r--drivers/ide/trm290.c49
-rw-r--r--drivers/ide/tx4938ide.c68
-rw-r--r--drivers/ide/tx4939ide.c124
-rw-r--r--drivers/ide/via82cxxx.c7
-rw-r--r--drivers/ieee1394/dma.h1
-rw-r--r--drivers/ieee1394/dv1394.c8
-rw-r--r--drivers/ieee1394/ieee1394.h4
-rw-r--r--drivers/ieee1394/ieee1394_core.c19
-rw-r--r--drivers/ieee1394/ieee1394_transactions.c31
-rw-r--r--drivers/ieee1394/ieee1394_transactions.h2
-rw-r--r--drivers/ieee1394/iso.h1
-rw-r--r--drivers/ieee1394/nodemgr.c10
-rw-r--r--drivers/ieee1394/nodemgr.h18
-rw-r--r--drivers/ieee1394/ohci1394.h2
-rw-r--r--drivers/ieee1394/pcilynx.c1
-rw-r--r--drivers/ieee1394/sbp2.c54
-rw-r--r--drivers/input/keyboard/Kconfig4
-rw-r--r--drivers/input/keyboard/atkbd.c4
-rw-r--r--drivers/input/keyboard/bf54x-keys.c4
-rw-r--r--drivers/input/keyboard/corgikbd.c10
-rw-r--r--drivers/input/keyboard/omap-keypad.c8
-rw-r--r--drivers/input/keyboard/spitzkbd.c10
-rw-r--r--drivers/input/mouse/Kconfig4
-rw-r--r--drivers/input/mouse/pxa930_trkball.c2
-rw-r--r--drivers/input/serio/ambakmi.c6
-rw-r--r--drivers/input/serio/gscps2.c2
-rw-r--r--drivers/input/serio/sa1111ps2.c4
-rw-r--r--drivers/input/touchscreen/atmel_tsadcc.c2
-rw-r--r--drivers/input/touchscreen/corgi_ts.c10
-rw-r--r--drivers/input/touchscreen/tsc2007.c3
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c19
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c3
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c2
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c2
-rw-r--r--drivers/isdn/sc/shmem.c2
-rw-r--r--drivers/lguest/core.c2
-rw-r--r--drivers/lguest/lguest_user.c5
-rw-r--r--drivers/macintosh/therm_adt746x.c4
-rw-r--r--drivers/mca/mca-bus.c4
-rw-r--r--drivers/md/dm-io.c4
-rw-r--r--drivers/md/dm-ioctl.c7
-rw-r--r--drivers/md/dm-kcopyd.c2
-rw-r--r--drivers/md/dm-target.c104
-rw-r--r--drivers/md/dm.h2
-rw-r--r--drivers/md/linear.c6
-rw-r--r--drivers/md/md.c28
-rw-r--r--drivers/md/raid1.c6
-rw-r--r--drivers/md/raid10.c19
-rw-r--r--drivers/media/Kconfig2
-rw-r--r--drivers/media/common/ir-keymaps.c108
-rw-r--r--drivers/media/common/saa7146_core.c15
-rw-r--r--drivers/media/common/saa7146_fops.c48
-rw-r--r--drivers/media/common/saa7146_i2c.c8
-rw-r--r--drivers/media/common/saa7146_video.c1272
-rw-r--r--drivers/media/common/tuners/Kconfig8
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/mc44s803.c371
-rw-r--r--drivers/media/common/tuners/mc44s803.h46
-rw-r--r--drivers/media/common/tuners/mc44s803_priv.h208
-rw-r--r--drivers/media/common/tuners/mt2060.c2
-rw-r--r--drivers/media/common/tuners/mxl5007t.c2
-rw-r--r--drivers/media/common/tuners/tda827x.c183
-rw-r--r--drivers/media/common/tuners/tda8290.c6
-rw-r--r--drivers/media/common/tuners/tuner-simple.c10
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c2
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c18
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c26
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.h6
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c16
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig1
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-fe.c2
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c90
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h31
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c61
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h3
-rw-r--r--drivers/media/dvb/firewire/Kconfig22
-rw-r--r--drivers/media/dvb/firewire/Makefile8
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c285
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c1315
-rw-r--r--drivers/media/dvb/firewire/firedtv-ci.c260
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c364
-rw-r--r--drivers/media/dvb/firewire/firedtv-fe.c247
-rw-r--r--drivers/media/dvb/firewire/firedtv-rc.c190
-rw-r--r--drivers/media/dvb/firewire/firedtv.h182
-rw-r--r--drivers/media/dvb/frontends/cx24116.c58
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h16
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c7
-rw-r--r--drivers/media/dvb/frontends/stb0899_algo.c3
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c30
-rw-r--r--drivers/media/dvb/siano/sms-cards.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c480
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c88
-rw-r--r--drivers/media/dvb/ttpci/budget.c1
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c2
-rw-r--r--drivers/media/radio/dsbr100.c10
-rw-r--r--drivers/media/radio/radio-mr800.c225
-rw-r--r--drivers/media/radio/radio-si470x.c253
-rw-r--r--drivers/media/radio/radio-tea5764.c3
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c1290
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c90
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c6
-rw-r--r--drivers/media/video/bt8xx/bttv-if.c18
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c2
-rw-r--r--drivers/media/video/bt8xx/bttv.h81
-rw-r--r--drivers/media/video/bt8xx/bttvp.h19
-rw-r--r--drivers/media/video/cs5345.c1
-rw-r--r--drivers/media/video/cs53l32a.c1
-rw-r--r--drivers/media/video/cx18/cx18-audio.c3
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c91
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h19
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c9
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c106
-rw-r--r--drivers/media/video/cx18/cx18-cards.c13
-rw-r--r--drivers/media/video/cx18/cx18-cards.h3
-rw-r--r--drivers/media/video/cx18/cx18-controls.c5
-rw-r--r--drivers/media/video/cx18/cx18-driver.c215
-rw-r--r--drivers/media/video/cx18/cx18-driver.h158
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c2
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c68
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c4
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c176
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c44
-rw-r--r--drivers/media/video/cx18/cx18-queue.c4
-rw-r--r--drivers/media/video/cx18/cx18-queue.h4
-rw-r--r--drivers/media/video/cx18/cx18-streams.c201
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c118
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h2
-rw-r--r--drivers/media/video/cx18/cx23418.h16
-rw-r--r--drivers/media/video/cx2341x.c100
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c3
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c37
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c54
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c6
-rw-r--r--drivers/media/video/cx23885/cx23885.h3
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c20
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c72
-rw-r--r--drivers/media/video/cx88/cx88-video.c1
-rw-r--r--drivers/media/video/cx88/cx88.h2
-rw-r--r--drivers/media/video/dabusb.c70
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c83
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c177
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c52
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c20
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c6
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c95
-rw-r--r--drivers/media/video/em28xx/em28xx.h37
-rw-r--r--drivers/media/video/gspca/Kconfig9
-rw-r--r--drivers/media/video/gspca/Makefile98
-rw-r--r--drivers/media/video/gspca/conex.c15
-rw-r--r--drivers/media/video/gspca/etoms.c36
-rw-r--r--drivers/media/video/gspca/finepix.c12
-rw-r--r--drivers/media/video/gspca/gspca.c145
-rw-r--r--drivers/media/video/gspca/gspca.h13
-rw-r--r--drivers/media/video/gspca/jpeg.h283
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c7
-rw-r--r--drivers/media/video/gspca/mars.c453
-rw-r--r--drivers/media/video/gspca/mr97310a.c378
-rw-r--r--drivers/media/video/gspca/ov519.c7
-rw-r--r--drivers/media/video/gspca/ov534.c9
-rw-r--r--drivers/media/video/gspca/pac207.c8
-rw-r--r--drivers/media/video/gspca/pac7311.c7
-rw-r--r--drivers/media/video/gspca/sonixb.c7
-rw-r--r--drivers/media/video/gspca/sonixj.c829
-rw-r--r--drivers/media/video/gspca/spca500.c48
-rw-r--r--drivers/media/video/gspca/spca501.c22
-rw-r--r--drivers/media/video/gspca/spca505.c525
-rw-r--r--drivers/media/video/gspca/spca506.c57
-rw-r--r--drivers/media/video/gspca/spca508.c128
-rw-r--r--drivers/media/video/gspca/spca561.c192
-rw-r--r--drivers/media/video/gspca/stk014.c20
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c7
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c76
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h65
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c147
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h130
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h8
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c123
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h58
-rw-r--r--drivers/media/video/gspca/sunplus.c73
-rw-r--r--drivers/media/video/gspca/t613.c554
-rw-r--r--drivers/media/video/gspca/tv8532.c483
-rw-r--r--drivers/media/video/gspca/vc032x.c691
-rw-r--r--drivers/media/video/gspca/zc3xx.c816
-rw-r--r--drivers/media/video/hexium_gemini.c292
-rw-r--r--drivers/media/video/hexium_orion.c103
-rw-r--r--drivers/media/video/ir-kbd-i2c.c64
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c97
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c46
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h8
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c68
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.h4
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c6
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c6
-rw-r--r--drivers/media/video/m52790.c1
-rw-r--r--drivers/media/video/mxb.c827
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c24
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c23
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c14
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c14
-rw-r--r--drivers/media/video/pwc/Kconfig10
-rw-r--r--drivers/media/video/pwc/pwc-if.c78
-rw-r--r--drivers/media/video/pwc/pwc.h6
-rw-r--r--drivers/media/video/pxa_camera.c1
-rw-r--r--drivers/media/video/s2255drv.c41
-rw-r--r--drivers/media/video/saa5246a.c70
-rw-r--r--drivers/media/video/saa5249.c71
-rw-r--r--drivers/media/video/saa6588.c189
-rw-r--r--drivers/media/video/saa7115.c2
-rw-r--r--drivers/media/video/saa7127.c52
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c569
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c133
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c98
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c24
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c23
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c33
-rw-r--r--drivers/media/video/saa7134/saa7134.h30
-rw-r--r--drivers/media/video/saa717x.c4
-rw-r--r--drivers/media/video/tcm825x.c22
-rw-r--r--drivers/media/video/tcm825x.h2
-rw-r--r--drivers/media/video/tda7432.c1
-rw-r--r--drivers/media/video/tda9840.c82
-rw-r--r--drivers/media/video/tda9840.h14
-rw-r--r--drivers/media/video/tda9875.c3
-rw-r--r--drivers/media/video/tea6415c.c53
-rw-r--r--drivers/media/video/tea6415c.h12
-rw-r--r--drivers/media/video/tea6420.c69
-rw-r--r--drivers/media/video/tea6420.h27
-rw-r--r--drivers/media/video/tlv320aic23b.c1
-rw-r--r--drivers/media/video/tveeprom.c8
-rw-r--r--drivers/media/video/tvp514x.c4
-rw-r--r--drivers/media/video/tvp5150.c1
-rw-r--r--drivers/media/video/tw9910.c13
-rw-r--r--drivers/media/video/upd64031a.c2
-rw-r--r--drivers/media/video/upd64083.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c44
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c8
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c39
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c9
-rw-r--r--drivers/media/video/uvc/uvc_driver.c82
-rw-r--r--drivers/media/video/uvc/uvc_isight.c2
-rw-r--r--drivers/media/video/uvc/uvc_queue.c31
-rw-r--r--drivers/media/video/uvc/uvc_status.c29
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c24
-rw-r--r--drivers/media/video/uvc/uvc_video.c110
-rw-r--r--drivers/media/video/uvc/uvcvideo.h239
-rw-r--r--drivers/media/video/v4l2-common.c46
-rw-r--r--drivers/media/video/v4l2-device.c2
-rw-r--r--drivers/media/video/v4l2-ioctl.c3
-rw-r--r--drivers/media/video/v4l2-subdev.c14
-rw-r--r--drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--drivers/media/video/videobuf-vmalloc.c2
-rw-r--r--drivers/media/video/vivi.c186
-rw-r--r--drivers/media/video/vp27smpx.c1
-rw-r--r--drivers/media/video/wm8739.c1
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h8
-rw-r--r--drivers/media/video/zoran/zoran.h12
-rw-r--r--drivers/media/video/zoran/zoran_card.c620
-rw-r--r--drivers/media/video/zoran/zoran_card.h2
-rw-r--r--drivers/media/video/zoran/zoran_driver.c109
-rw-r--r--drivers/media/video/zr364xx.c1
-rw-r--r--drivers/message/fusion/mptbase.c4
-rw-r--r--drivers/mfd/htc-egpio.c4
-rw-r--r--drivers/mfd/mcp-core.c2
-rw-r--r--drivers/mfd/pcf50633-core.c2
-rw-r--r--drivers/mfd/sm501.c26
-rw-r--r--drivers/mfd/twl4030-core.c2
-rw-r--r--drivers/mfd/ucb1x00-core.c2
-rw-r--r--drivers/mfd/wm8350-core.c48
-rw-r--r--drivers/mfd/wm8350-regmap.c2
-rw-r--r--drivers/misc/Kconfig14
-rw-r--r--drivers/misc/Makefile2
-rw-r--r--drivers/misc/atmel-ssc.c2
-rw-r--r--drivers/misc/eeprom/Kconfig59
-rw-r--r--drivers/misc/eeprom/Makefile4
-rw-r--r--drivers/misc/eeprom/at24.c (renamed from drivers/i2c/chips/at24.c)0
-rw-r--r--drivers/misc/eeprom/at25.c (renamed from drivers/spi/at25.c)0
-rw-r--r--drivers/misc/eeprom/eeprom.c (renamed from drivers/i2c/chips/eeprom.c)0
-rw-r--r--drivers/misc/eeprom/eeprom_93cx6.c (renamed from drivers/misc/eeprom_93cx6.c)0
-rw-r--r--drivers/misc/hpilo.c8
-rw-r--r--drivers/misc/hpilo.h2
-rw-r--r--drivers/misc/sgi-gru/grufile.c18
-rw-r--r--drivers/misc/sgi-xp/xp.h24
-rw-r--r--drivers/misc/sgi-xp/xpc.h5
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c3
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c2
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c34
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c13
-rw-r--r--drivers/misc/sgi-xp/xpnet.c3
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/mmc/card/mmc_test.c2
-rw-r--r--drivers/mmc/host/Kconfig20
-rw-r--r--drivers/mmc/host/Makefile2
-rw-r--r--drivers/mmc/host/atmel-mci.c7
-rw-r--r--drivers/mmc/host/mmci.c37
-rw-r--r--drivers/mmc/host/mmci.h28
-rw-r--r--drivers/mmc/host/mxcmmc.c880
-rw-r--r--drivers/mmc/host/of_mmc_spi.c2
-rw-r--r--drivers/mmc/host/omap_hsmmc.c1280
-rw-r--r--drivers/mmc/host/pxamci.c28
-rw-r--r--drivers/mmc/host/ricoh_mmc.c8
-rw-r--r--drivers/mmc/host/s3cmci.c4
-rw-r--r--drivers/mmc/host/sdhci-pci.c3
-rw-r--r--drivers/mmc/host/sdhci.c7
-rw-r--r--drivers/mmc/host/sdhci.h3
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c37
-rw-r--r--drivers/mtd/maps/sa1100-flash.c4
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/atmel_nand.c3
-rw-r--r--drivers/mtd/nand/cmx270_nand.c3
-rw-r--r--drivers/mtd/nand/excite_nandflash.c25
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c8
-rw-r--r--drivers/mtd/nand/ndfc.c2
-rw-r--r--drivers/mtd/nand/pasemi_nand.c4
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c1
-rw-r--r--drivers/mtd/onenand/generic.c26
-rw-r--r--drivers/mtd/onenand/omap2.c6
-rw-r--r--drivers/mtd/ubi/Kconfig.debug10
-rw-r--r--drivers/mtd/ubi/build.c21
-rw-r--r--drivers/mtd/ubi/cdev.c184
-rw-r--r--drivers/mtd/ubi/gluebi.c11
-rw-r--r--drivers/mtd/ubi/scan.c8
-rw-r--r--drivers/mtd/ubi/ubi.h11
-rw-r--r--drivers/mtd/ubi/upd.c21
-rw-r--r--drivers/mtd/ubi/vmt.c17
-rw-r--r--drivers/net/3c505.c26
-rw-r--r--drivers/net/3c509.c1
-rw-r--r--drivers/net/Kconfig13
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/arm/Makefile2
-rw-r--r--drivers/net/arm/am79c961a.c20
-rw-r--r--drivers/net/arm/etherh.c12
-rw-r--r--drivers/net/arm/ks8695net.c2
-rw-r--r--drivers/net/atl1c/Makefile2
-rw-r--r--drivers/net/atl1c/atl1c.h606
-rw-r--r--drivers/net/atl1c/atl1c_ethtool.c317
-rw-r--r--drivers/net/atl1c/atl1c_hw.c527
-rw-r--r--drivers/net/atl1c/atl1c_hw.h859
-rw-r--r--drivers/net/atl1c/atl1c_main.c2797
-rw-r--r--drivers/net/au1000_eth.c8
-rw-r--r--drivers/net/bfin_mac.c12
-rw-r--r--drivers/net/bmac.c2
-rw-r--r--drivers/net/bnx2.c36
-rw-r--r--drivers/net/bnx2.h2
-rw-r--r--drivers/net/bnx2_fw.h8515
-rw-r--r--drivers/net/bnx2_fw2.h8795
-rw-r--r--drivers/net/bnx2x.h11
-rw-r--r--drivers/net/bnx2x_link.c64
-rw-r--r--drivers/net/bnx2x_main.c302
-rw-r--r--drivers/net/bnx2x_reg.h2
-rw-r--r--drivers/net/cassini.c4
-rw-r--r--drivers/net/cpmac.c2
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c1
-rw-r--r--drivers/net/cxgb3/sge.c4
-rw-r--r--drivers/net/cxgb3/t3_hw.c7
-rw-r--r--drivers/net/declance.c6
-rw-r--r--drivers/net/depca.c6
-rw-r--r--drivers/net/e1000/e1000_main.c6
-rw-r--r--drivers/net/e1000e/82571.c6
-rw-r--r--drivers/net/e1000e/hw.h1
-rw-r--r--drivers/net/ehea/ehea_main.c2
-rw-r--r--drivers/net/fec.c2
-rw-r--r--drivers/net/fec_mpc52xx.c6
-rw-r--r--drivers/net/forcedeth.c13
-rw-r--r--drivers/net/gianfar.c15
-rw-r--r--drivers/net/gianfar.h2
-rw-r--r--drivers/net/gianfar_mii.c2
-rw-r--r--drivers/net/ibm_newemac/phy.c4
-rw-r--r--drivers/net/igb/e1000_82575.c11
-rw-r--r--drivers/net/igb/igb.h9
-rw-r--r--drivers/net/igb/igb_main.c24
-rw-r--r--drivers/net/irda/mcs7780.c2
-rw-r--r--drivers/net/irda/pxaficp_ir.c3
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c62
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h3
-rw-r--r--drivers/net/jazzsonic.c6
-rw-r--r--drivers/net/korina.c15
-rw-r--r--drivers/net/macb.c18
-rw-r--r--drivers/net/macsonic.c15
-rw-r--r--drivers/net/mipsnet.c26
-rw-r--r--drivers/net/mv643xx_eth.c28
-rw-r--r--drivers/net/myri10ge/myri10ge.c15
-rw-r--r--drivers/net/ne3210.c3
-rw-r--r--drivers/net/netxen/netxen_nic.h12
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c5
-rw-r--r--drivers/net/netxen/netxen_nic_init.c4
-rw-r--r--drivers/net/netxen/netxen_nic_main.c126
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c2
-rw-r--r--drivers/net/phy/mdio-gpio.c2
-rw-r--r--drivers/net/phy/mdio_bus.c8
-rw-r--r--drivers/net/phy/smsc.c12
-rw-r--r--drivers/net/ps3_gelic_wireless.c2
-rw-r--r--drivers/net/qlge/qlge.h10
-rw-r--r--drivers/net/qlge/qlge_main.c62
-rw-r--r--drivers/net/r6040.c1
-rw-r--r--drivers/net/r8169.c93
-rw-r--r--drivers/net/sb1250-mac.c10
-rw-r--r--drivers/net/sfc/efx.c76
-rw-r--r--drivers/net/sfc/efx.h9
-rw-r--r--drivers/net/sfc/ethtool.c3
-rw-r--r--drivers/net/sfc/falcon.c56
-rw-r--r--drivers/net/sfc/mdio_10g.c191
-rw-r--r--drivers/net/sfc/mdio_10g.h3
-rw-r--r--drivers/net/sfc/net_driver.h9
-rw-r--r--drivers/net/sfc/phy.h1
-rw-r--r--drivers/net/sfc/selftest.c7
-rw-r--r--drivers/net/sfc/sfe4001.c42
-rw-r--r--drivers/net/sfc/tenxpress.c213
-rw-r--r--drivers/net/sfc/workarounds.h12
-rw-r--r--drivers/net/skfp/skfddi.c4
-rw-r--r--drivers/net/sky2.c6
-rw-r--r--drivers/net/smc911x.c6
-rw-r--r--drivers/net/smc911x.h3
-rw-r--r--drivers/net/smc91x.c2
-rw-r--r--drivers/net/smc91x.h3
-rw-r--r--drivers/net/smsc911x.c11
-rw-r--r--drivers/net/smsc9420.c25
-rw-r--r--drivers/net/smsc9420.h1
-rw-r--r--drivers/net/sun3lance.c2
-rw-r--r--drivers/net/sundance.c2
-rw-r--r--drivers/net/sungem.c12
-rw-r--r--drivers/net/sungem_phy.c2
-rw-r--r--drivers/net/sunhme.c46
-rw-r--r--drivers/net/sunlance.c4
-rw-r--r--drivers/net/sunqe.c2
-rw-r--r--drivers/net/tc35815.c4
-rw-r--r--drivers/net/tg3.c89
-rw-r--r--drivers/net/tg3.h1
-rw-r--r--drivers/net/tsi108_eth.c2
-rw-r--r--drivers/net/tulip/21142.c23
-rw-r--r--drivers/net/tulip/de2104x.c5
-rw-r--r--drivers/net/tun.c10
-rw-r--r--drivers/net/ucc_geth.c20
-rw-r--r--drivers/net/ucc_geth.h2
-rw-r--r--drivers/net/ucc_geth_mii.c12
-rw-r--r--drivers/net/ucc_geth_mii.h1
-rw-r--r--drivers/net/usb/asix.c8
-rw-r--r--drivers/net/usb/hso.c4
-rw-r--r--drivers/net/usb/mcs7830.c20
-rw-r--r--drivers/net/veth.c9
-rw-r--r--drivers/net/via-velocity.c2
-rw-r--r--drivers/net/virtio_net.c9
-rw-r--r--drivers/net/wimax/i2400m/control.c2
-rw-r--r--drivers/net/wimax/i2400m/debugfs.c14
-rw-r--r--drivers/net/wimax/i2400m/driver.c18
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h2
-rw-r--r--drivers/net/wimax/i2400m/usb-notif.c2
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c9
-rw-r--r--drivers/net/wireless/arlan-main.c4
-rw-r--r--drivers/net/wireless/ath5k/base.c95
-rw-r--r--drivers/net/wireless/ath9k/main.c24
-rw-r--r--drivers/net/wireless/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c17
-rw-r--r--drivers/net/wireless/libertas/ethtool.c12
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h91
-rw-r--r--drivers/net/wireless/libertas/if_usb.c4
-rw-r--r--drivers/net/wireless/libertas/main.c31
-rw-r--r--drivers/net/wireless/libertas/persistcfg.c16
-rw-r--r--drivers/net/wireless/libertas/scan.c4
-rw-r--r--drivers/net/wireless/libertas/tx.c2
-rw-r--r--drivers/net/wireless/libertas/wext.c72
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c51
-rw-r--r--drivers/net/wireless/p54/p54common.c30
-rw-r--r--drivers/net/wireless/p54/p54usb.c41
-rw-r--r--drivers/net/wireless/rndis_wlan.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c13
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.c10
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/net/xtsonic.c2
-rw-r--r--drivers/oprofile/buffer_sync.c14
-rw-r--r--drivers/oprofile/cpu_buffer.c10
-rw-r--r--drivers/oprofile/cpu_buffer.h7
-rw-r--r--drivers/parisc/dino.c11
-rw-r--r--drivers/parisc/sba_iommu.c18
-rw-r--r--drivers/parport/parport_atari.c6
-rw-r--r--drivers/parport/parport_serial.c5
-rw-r--r--drivers/pci/bus.c2
-rw-r--r--drivers/pci/dmar.c80
-rw-r--r--drivers/pci/hotplug/Makefile6
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c5
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c3
-rw-r--r--drivers/pci/hotplug/fakephp.c42
-rw-r--r--drivers/pci/hotplug/pciehp.h15
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c21
-rw-r--r--drivers/pci/hotplug/pciehp_core.c29
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c49
-rw-r--r--drivers/pci/hotplug/shpchp.h10
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c2
-rw-r--r--drivers/pci/intel-iommu.c32
-rw-r--r--drivers/pci/intr_remapping.c24
-rw-r--r--drivers/pci/msi.c98
-rw-r--r--drivers/pci/pci-acpi.c215
-rw-r--r--drivers/pci/pci-driver.c282
-rw-r--r--drivers/pci/pci-sysfs.c23
-rw-r--r--drivers/pci/pci.c126
-rw-r--r--drivers/pci/pci.h26
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c28
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c58
-rw-r--r--drivers/pci/pcie/aspm.c4
-rw-r--r--drivers/pci/pcie/portdrv.h14
-rw-r--r--drivers/pci/pcie/portdrv_bus.c18
-rw-r--r--drivers/pci/pcie/portdrv_core.c378
-rw-r--r--drivers/pci/pcie/portdrv_pci.c63
-rw-r--r--drivers/pci/quirks.c125
-rw-r--r--drivers/pci/remove.c3
-rw-r--r--drivers/pci/rom.c9
-rw-r--r--drivers/pci/setup-bus.c4
-rw-r--r--drivers/pci/slot.c18
-rw-r--r--drivers/pcmcia/au1000_generic.c37
-rw-r--r--drivers/pcmcia/i82365.c28
-rw-r--r--drivers/pcmcia/m32r_cfc.c30
-rw-r--r--drivers/pcmcia/m32r_pcc.c30
-rw-r--r--drivers/pcmcia/pxa2xx_base.c87
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c1
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c1
-rw-r--r--drivers/pcmcia/pxa2xx_e740.c2
-rw-r--r--drivers/pcmcia/pxa2xx_lubbock.c1
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c3
-rw-r--r--drivers/pcmcia/pxa2xx_trizeps4.c3
-rw-r--r--drivers/pcmcia/pxa2xx_viper.c1
-rw-r--r--drivers/pcmcia/rsrc_mgr.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c38
-rw-r--r--drivers/pcmcia/sa11xx_base.c48
-rw-r--r--drivers/pcmcia/soc_common.c54
-rw-r--r--drivers/pcmcia/soc_common.h7
-rw-r--r--drivers/pcmcia/tcic.c30
-rw-r--r--drivers/pcmcia/vrc4171_card.c34
-rw-r--r--drivers/platform/x86/Kconfig3
-rw-r--r--drivers/platform/x86/asus-laptop.c176
-rw-r--r--drivers/platform/x86/asus_acpi.c16
-rw-r--r--drivers/platform/x86/eeepc-laptop.c164
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c25
-rw-r--r--drivers/platform/x86/hp-wmi.c12
-rw-r--r--drivers/platform/x86/panasonic-laptop.c2
-rw-r--r--drivers/power/pcf50633-charger.c3
-rw-r--r--drivers/power/pda_power.c2
-rw-r--r--drivers/rapidio/rio-driver.c2
-rw-r--r--drivers/regulator/bq24022.c6
-rw-r--r--drivers/regulator/wm8350-regulator.c2
-rw-r--r--drivers/rtc/Kconfig6
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-at91sam9.c4
-rw-r--r--drivers/rtc/rtc-au1xxx.c2
-rw-r--r--drivers/rtc/rtc-dm355evm.c175
-rw-r--r--drivers/rtc/rtc-ds1390.c1
-rw-r--r--drivers/rtc/rtc-omap.c4
-rw-r--r--drivers/rtc/rtc-pxa.c2
-rw-r--r--drivers/rtc/rtc-sa1100.c3
-rw-r--r--drivers/rtc/rtc-twl4030.c2
-rw-r--r--drivers/s390/Makefile3
-rw-r--r--drivers/s390/block/dasd.c278
-rw-r--r--drivers/s390/block/dasd_3990_erp.c871
-rw-r--r--drivers/s390/block/dasd_alias.c33
-rw-r--r--drivers/s390/block/dasd_devmap.c9
-rw-r--r--drivers/s390/block/dasd_diag.c57
-rw-r--r--drivers/s390/block/dasd_eckd.c1272
-rw-r--r--drivers/s390/block/dasd_eckd.h49
-rw-r--r--drivers/s390/block/dasd_eer.c21
-rw-r--r--drivers/s390/block/dasd_erp.c19
-rw-r--r--drivers/s390/block/dasd_fba.c48
-rw-r--r--drivers/s390/block/dasd_int.h13
-rw-r--r--drivers/s390/block/dasd_ioctl.c46
-rw-r--r--drivers/s390/block/dasd_proc.c2
-rw-r--r--drivers/s390/char/sclp.c5
-rw-r--r--drivers/s390/char/sclp_cmd.c5
-rw-r--r--drivers/s390/char/tape.h2
-rw-r--r--drivers/s390/char/tape_34xx.c161
-rw-r--r--drivers/s390/char/tape_3590.c364
-rw-r--r--drivers/s390/char/tape_block.c18
-rw-r--r--drivers/s390/char/tape_char.c7
-rw-r--r--drivers/s390/char/tape_core.c62
-rw-r--r--drivers/s390/char/tape_proc.c3
-rw-r--r--drivers/s390/char/tape_std.c21
-rw-r--r--drivers/s390/char/zcore.c88
-rw-r--r--drivers/s390/cio/Makefile2
-rw-r--r--drivers/s390/cio/airq.c2
-rw-r--r--drivers/s390/cio/chp.c6
-rw-r--r--drivers/s390/cio/chsc.c6
-rw-r--r--drivers/s390/cio/cio.c21
-rw-r--r--drivers/s390/cio/crw.c159
-rw-r--r--drivers/s390/cio/css.c37
-rw-r--r--drivers/s390/cio/device.c41
-rw-r--r--drivers/s390/cio/device.h2
-rw-r--r--drivers/s390/cio/device_fsm.c8
-rw-r--r--drivers/s390/cio/qdio_main.c63
-rw-r--r--drivers/s390/cio/qdio_thinint.c18
-rw-r--r--drivers/s390/ebcdic.c246
-rw-r--r--drivers/s390/net/lcs.c8
-rw-r--r--drivers/s390/net/qeth_l3_main.c2
-rw-r--r--drivers/s390/s390mach.c538
-rw-r--r--drivers/s390/s390mach.h122
-rw-r--r--drivers/s390/sysinfo.c469
-rw-r--r--drivers/scsi/a4000t.c26
-rw-r--r--drivers/scsi/arm/cumana_2.c3
-rw-r--r--drivers/scsi/arm/eesox.c3
-rw-r--r--drivers/scsi/arm/powertec.c3
-rw-r--r--drivers/scsi/bvme6000_scsi.c26
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i.h21
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c19
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h5
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_init.c4
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c22
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c146
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.h29
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.c275
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.h2
-rw-r--r--drivers/scsi/hptiop.c1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c19
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c1
-rw-r--r--drivers/scsi/libiscsi.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c1
-rw-r--r--drivers/scsi/mvme16x_scsi.c26
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c19
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_devtbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c60
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c63
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c56
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c38
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c25
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h1
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c10
-rw-r--r--drivers/scsi/scsi_lib.c5
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/sd.c7
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/serial/8250.c15
-rw-r--r--drivers/serial/8250_pci.c42
-rw-r--r--drivers/serial/Kconfig4
-rw-r--r--drivers/serial/atmel_serial.c4
-rw-r--r--drivers/serial/jsm/jsm_driver.c5
-rw-r--r--drivers/serial/jsm/jsm_tty.c6
-rw-r--r--drivers/serial/mcf.c13
-rw-r--r--drivers/serial/mpc52xx_uart.c40
-rw-r--r--drivers/serial/pxa.c30
-rw-r--r--drivers/serial/sh-sci.h9
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/sh/maple/maple.c8
-rw-r--r--drivers/sh/superhyway/superhyway.c4
-rw-r--r--drivers/spi/Kconfig11
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/atmel_spi.c8
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/spi/omap2_mcspi.c2
-rw-r--r--drivers/spi/omap_uwire.c12
-rw-r--r--drivers/spi/orion_spi.c2
-rw-r--r--drivers/spi/pxa2xx_spi.c6
-rw-r--r--drivers/spi/spi_bfin5xx.c4
-rw-r--r--drivers/spi/spi_gpio.c4
-rw-r--r--drivers/spi/spi_imx.c5
-rw-r--r--drivers/spi/spi_mpc83xx.c4
-rw-r--r--drivers/spi/spi_txx9.c3
-rw-r--r--drivers/staging/agnx/agnx.h2
-rw-r--r--drivers/staging/altpciechdma/altpciechdma.c4
-rw-r--r--drivers/staging/android/Kconfig1
-rw-r--r--drivers/staging/android/binder.c16
-rw-r--r--drivers/staging/android/lowmemorykiller.txt16
-rw-r--r--drivers/staging/android/ram_console.c14
-rw-r--r--drivers/staging/android/timed_gpio.c5
-rw-r--r--drivers/staging/at76_usb/Kconfig2
-rw-r--r--drivers/staging/at76_usb/at76_usb.c4620
-rw-r--r--drivers/staging/at76_usb/at76_usb.h227
-rw-r--r--drivers/staging/comedi/Kconfig1
-rw-r--r--drivers/staging/meilhaus/Kconfig21
-rw-r--r--drivers/staging/panel/panel.c10
-rw-r--r--drivers/staging/poch/poch.c2
-rw-r--r--drivers/staging/usbip/usbip_common.c16
-rw-r--r--drivers/tc/tc.c8
-rw-r--r--drivers/uio/Kconfig18
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio.c25
-rw-r--r--drivers/uio/uio_aec.c175
-rw-r--r--drivers/usb/Makefile3
-rw-r--r--drivers/usb/class/cdc-acm.c15
-rw-r--r--drivers/usb/class/usblp.c12
-rw-r--r--drivers/usb/core/devices.c2
-rw-r--r--drivers/usb/core/devio.c23
-rw-r--r--drivers/usb/core/driver.c2
-rw-r--r--drivers/usb/core/endpoint.c9
-rw-r--r--drivers/usb/core/hcd-pci.c112
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/hcd.h2
-rw-r--r--drivers/usb/core/hub.c13
-rw-r--r--drivers/usb/core/inode.c1
-rw-r--r--drivers/usb/core/message.c51
-rw-r--r--drivers/usb/core/urb.c2
-rw-r--r--drivers/usb/core/usb.h6
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/gadget/amd5536udc.c2
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c20
-rw-r--r--drivers/usb/gadget/cdc2.c8
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c3
-rw-r--r--drivers/usb/gadget/composite.c14
-rw-r--r--drivers/usb/gadget/dummy_hcd.c2
-rw-r--r--drivers/usb/gadget/epautoconf.c2
-rw-r--r--drivers/usb/gadget/ether.c8
-rw-r--r--drivers/usb/gadget/f_acm.c10
-rw-r--r--drivers/usb/gadget/f_ecm.c16
-rw-r--r--drivers/usb/gadget/f_loopback.c4
-rw-r--r--drivers/usb/gadget/f_obex.c12
-rw-r--r--drivers/usb/gadget/f_phonet.c8
-rw-r--r--drivers/usb/gadget/f_rndis.c10
-rw-r--r--drivers/usb/gadget/f_serial.c4
-rw-r--r--drivers/usb/gadget/f_sourcesink.c4
-rw-r--r--drivers/usb/gadget/f_subset.c14
-rw-r--r--drivers/usb/gadget/file_storage.c28
-rw-r--r--drivers/usb/gadget/fsl_qe_udc.c46
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c11
-rw-r--r--drivers/usb/gadget/gmidi.c16
-rw-r--r--drivers/usb/gadget/goku_udc.c8
-rw-r--r--drivers/usb/gadget/imx_udc.c250
-rw-r--r--drivers/usb/gadget/imx_udc.h49
-rw-r--r--drivers/usb/gadget/inode.c4
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c16
-rw-r--r--drivers/usb/gadget/net2280.c16
-rw-r--r--drivers/usb/gadget/printer.c18
-rw-r--r--drivers/usb/gadget/pxa25x_udc.c4
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c218
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h10
-rw-r--r--drivers/usb/gadget/serial.c12
-rw-r--r--drivers/usb/gadget/u_serial.c2
-rw-r--r--drivers/usb/gadget/zero.c8
-rw-r--r--drivers/usb/host/Kconfig25
-rw-r--r--drivers/usb/host/Makefile6
-rw-r--r--drivers/usb/host/ehci-hcd.c38
-rw-r--r--drivers/usb/host/ehci-mem.c1
-rw-r--r--drivers/usb/host/ehci-pci.c4
-rw-r--r--drivers/usb/host/ehci-q.c32
-rw-r--r--drivers/usb/host/ehci-sched.c58
-rw-r--r--drivers/usb/host/ehci.h43
-rw-r--r--drivers/usb/host/fhci-dbg.c139
-rw-r--r--drivers/usb/host/fhci-hcd.c836
-rw-r--r--drivers/usb/host/fhci-hub.c345
-rw-r--r--drivers/usb/host/fhci-mem.c113
-rw-r--r--drivers/usb/host/fhci-q.c284
-rw-r--r--drivers/usb/host/fhci-sched.c888
-rw-r--r--drivers/usb/host/fhci-tds.c626
-rw-r--r--drivers/usb/host/fhci.h607
-rw-r--r--drivers/usb/host/isp116x.h8
-rw-r--r--drivers/usb/host/isp1760-hcd.c11
-rw-r--r--drivers/usb/host/isp1760-hcd.h7
-rw-r--r--drivers/usb/host/isp1760-if.c95
-rw-r--r--drivers/usb/host/ohci-ep93xx.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c8
-rw-r--r--drivers/usb/host/ohci-omap.c6
-rw-r--r--drivers/usb/host/ohci-pci.c2
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c22
-rw-r--r--drivers/usb/host/oxu210hp.h8
-rw-r--r--drivers/usb/host/pci-quirks.c2
-rw-r--r--drivers/usb/host/r8a66597-hcd.c15
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/host/uhci-hcd.h10
-rw-r--r--drivers/usb/host/uhci-q.c10
-rw-r--r--drivers/usb/host/whci/asl.c13
-rw-r--r--drivers/usb/host/whci/hw.c15
-rw-r--r--drivers/usb/host/whci/pzl.c13
-rw-r--r--drivers/usb/host/whci/whcd.h1
-rw-r--r--drivers/usb/image/mdc800.c8
-rw-r--r--drivers/usb/misc/ldusb.c2
-rw-r--r--drivers/usb/mon/mon_bin.c239
-rw-r--r--drivers/usb/musb/Kconfig9
-rw-r--r--drivers/usb/musb/cppi_dma.c10
-rw-r--r--drivers/usb/musb/davinci.c91
-rw-r--r--drivers/usb/musb/davinci.h23
-rw-r--r--drivers/usb/musb/musb_core.c20
-rw-r--r--drivers/usb/musb/musb_core.h5
-rw-r--r--drivers/usb/musb/musb_gadget.c10
-rw-r--r--drivers/usb/musb/musb_host.c237
-rw-r--r--drivers/usb/musb/musb_virthub.c2
-rw-r--r--drivers/usb/musb/tusb6010_omap.c4
-rw-r--r--drivers/usb/otg/Kconfig14
-rw-r--r--drivers/usb/otg/Makefile1
-rw-r--r--drivers/usb/otg/gpio_vbus.c42
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c180
-rw-r--r--drivers/usb/otg/twl4030-usb.c73
-rw-r--r--drivers/usb/serial/Kconfig18
-rw-r--r--drivers/usb/serial/Makefile2
-rw-r--r--drivers/usb/serial/aircable.c4
-rw-r--r--drivers/usb/serial/ch341.c396
-rw-r--r--drivers/usb/serial/cp2101.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c34
-rw-r--r--drivers/usb/serial/ftdi_sio.h12
-rw-r--r--drivers/usb/serial/generic.c9
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/opticon.c215
-rw-r--r--drivers/usb/serial/option.c202
-rw-r--r--drivers/usb/serial/qcserial.c145
-rw-r--r--drivers/usb/serial/symbolserial.c340
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c13
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.h4
-rw-r--r--drivers/usb/serial/usb-serial.c20
-rw-r--r--drivers/usb/storage/Kconfig48
-rw-r--r--drivers/usb/storage/Makefile41
-rw-r--r--drivers/usb/storage/alauda.c188
-rw-r--r--drivers/usb/storage/alauda.h100
-rw-r--r--drivers/usb/storage/cypress_atacb.c103
-rw-r--r--drivers/usb/storage/datafab.c100
-rw-r--r--drivers/usb/storage/datafab.h40
-rw-r--r--drivers/usb/storage/freecom.c95
-rw-r--r--drivers/usb/storage/isd200.c94
-rw-r--r--drivers/usb/storage/jumpshot.c99
-rw-r--r--drivers/usb/storage/jumpshot.h39
-rw-r--r--drivers/usb/storage/karma.c96
-rw-r--r--drivers/usb/storage/karma.h7
-rw-r--r--drivers/usb/storage/libusual.c33
-rw-r--r--drivers/usb/storage/onetouch.c90
-rw-r--r--drivers/usb/storage/onetouch.h9
-rw-r--r--drivers/usb/storage/protocol.c3
-rw-r--r--drivers/usb/storage/scsiglue.c4
-rw-r--r--drivers/usb/storage/sddr09.c144
-rw-r--r--drivers/usb/storage/sddr09.h38
-rw-r--r--drivers/usb/storage/sddr55.c96
-rw-r--r--drivers/usb/storage/shuttle_usbat.c199
-rw-r--r--drivers/usb/storage/shuttle_usbat.h123
-rw-r--r--drivers/usb/storage/transport.c46
-rw-r--r--drivers/usb/storage/unusual_alauda.h (renamed from drivers/usb/storage/freecom.h)29
-rw-r--r--drivers/usb/storage/unusual_cypress.h34
-rw-r--r--drivers/usb/storage/unusual_datafab.h98
-rw-r--r--drivers/usb/storage/unusual_devs.h364
-rw-r--r--drivers/usb/storage/unusual_freecom.h (renamed from drivers/usb/storage/cypress_atacb.h)19
-rw-r--r--drivers/usb/storage/unusual_isd200.h57
-rw-r--r--drivers/usb/storage/unusual_jumpshot.h (renamed from drivers/usb/storage/sddr55.h)23
-rw-r--r--drivers/usb/storage/unusual_karma.h (renamed from drivers/usb/storage/isd200.h)21
-rw-r--r--drivers/usb/storage/unusual_onetouch.h36
-rw-r--r--drivers/usb/storage/unusual_sddr09.h56
-rw-r--r--drivers/usb/storage/unusual_sddr55.h44
-rw-r--r--drivers/usb/storage/unusual_usbat.h43
-rw-r--r--drivers/usb/storage/usb.c344
-rw-r--r--drivers/usb/storage/usb.h21
-rw-r--r--drivers/usb/storage/usual-tables.c116
-rw-r--r--drivers/usb/usb-skeleton.c6
-rw-r--r--drivers/usb/wusbcore/devconnect.c3
-rw-r--r--drivers/usb/wusbcore/rh.c3
-rw-r--r--drivers/usb/wusbcore/security.c2
-rw-r--r--drivers/uwb/allocator.c1
-rw-r--r--drivers/uwb/drp.c4
-rw-r--r--drivers/uwb/rsv.c21
-rw-r--r--drivers/video/Kconfig36
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/atafb.c22
-rw-r--r--drivers/video/aty/aty128fb.c34
-rw-r--r--drivers/video/aty/atyfb_base.c42
-rw-r--r--drivers/video/aty/mach64_ct.c11
-rw-r--r--drivers/video/aty/radeon_base.c10
-rw-r--r--drivers/video/aty/radeon_i2c.c1
-rw-r--r--drivers/video/aty/radeon_pm.c103
-rw-r--r--drivers/video/aty/radeonfb.h2
-rw-r--r--drivers/video/au1100fb.c31
-rw-r--r--drivers/video/au1200fb.c25
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/da903x_bl.c (renamed from drivers/video/backlight/da903x.c)0
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c2
-rw-r--r--drivers/video/broadsheetfb.c568
-rw-r--r--drivers/video/cyber2000fb.c2
-rw-r--r--drivers/video/fbcmap.c20
-rw-r--r--drivers/video/fbmem.c135
-rw-r--r--drivers/video/geode/gx1fb_core.c17
-rw-r--r--drivers/video/geode/gxfb_core.c17
-rw-r--r--drivers/video/geode/lxfb_core.c17
-rw-r--r--drivers/video/i810/i810-i2c.c1
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c1
-rw-r--r--drivers/video/mx3fb.c1555
-rw-r--r--drivers/video/nvidia/nv_i2c.c1
-rw-r--r--drivers/video/omap/lcdc.c4
-rw-r--r--drivers/video/pmag-ba-fb.c17
-rw-r--r--drivers/video/pmagb-b-fb.c17
-rw-r--r--drivers/video/ps3fb.c2
-rw-r--r--drivers/video/pxafb.c1
-rw-r--r--drivers/video/s3c2410fb.c4
-rw-r--r--drivers/video/sa1100fb.c21
-rw-r--r--drivers/video/savage/savagefb-i2c.c1
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c2
-rw-r--r--drivers/video/tmiofb.c2
-rw-r--r--drivers/virtio/virtio_pci.c2
-rw-r--r--drivers/w1/slaves/w1_therm.c2
-rw-r--r--drivers/watchdog/Kconfig10
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c5
-rw-r--r--drivers/watchdog/at91sam9_wdt.c1
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c32
-rw-r--r--drivers/watchdog/iTCO_wdt.c35
-rw-r--r--drivers/watchdog/rdc321x_wdt.c2
-rw-r--r--drivers/watchdog/rm9k_wdt.c27
-rw-r--r--drivers/watchdog/sa1100_wdt.c2
-rw-r--r--drivers/xen/balloon.c41
-rw-r--r--drivers/xen/events.c251
-rw-r--r--drivers/xen/manage.c10
-rw-r--r--drivers/xen/xenfs/xenbus.c11
-rw-r--r--drivers/zorro/zorro.c4
1205 files changed, 65208 insertions, 32849 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index d7f9839ba264..8a851d0f4384 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -9,6 +9,7 @@ menuconfig ACPI
depends on PCI
depends on PM
select PNP
+ select CPU_IDLE
default y
---help---
Advanced Configuration and Power Interface (ACPI) support for
@@ -253,13 +254,6 @@ config ACPI_PCI_SLOT
help you correlate PCI bus addresses with the physical geography
of your slots. If you are unsure, say N.
-config ACPI_SYSTEM
- bool
- default y
- help
- This driver will enable your system to shut down using ACPI, and
- dump your ACPI DSDT table using /proc/acpi/dsdt.
-
config X86_PM_TIMER
bool "Power Management Timer Support" if EMBEDDED
depends on X86
@@ -287,7 +281,7 @@ config ACPI_CONTAINER
support physical cpu/memory hot-plug.
If one selects "m", this driver can be loaded with
- "modprobe acpi_container".
+ "modprobe container".
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 65d90c720b5a..b130ea0d0759 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -52,7 +52,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-y += power.o
-obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o
+obj-y += system.o event.o
obj-$(CONFIG_ACPI_DEBUG) += debug.o
obj-$(CONFIG_ACPI_NUMA) += numa.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 9684cc827930..22ce48985720 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -538,10 +538,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
if (ACPI_FAILURE(status)) {
ACPI_WARNING((AE_INFO,
"Truncating %u table entries!",
- (unsigned)
- (acpi_gbl_root_table_list.size -
- acpi_gbl_root_table_list.
- count)));
+ (unsigned) (table_count -
+ (acpi_gbl_root_table_list.
+ count - 2))));
break;
}
}
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index c3e841f3cde9..ab0aff3c7d6a 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -365,7 +365,7 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
/*******************************************************************************
*
- * FUNCTION: acpi_get_table
+ * FUNCTION: acpi_get_table_with_size
*
* PARAMETERS: Signature - ACPI signature of needed table
* Instance - Which instance (for SSDTs)
@@ -377,8 +377,9 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
*
*****************************************************************************/
acpi_status
-acpi_get_table(char *signature,
- u32 instance, struct acpi_table_header **out_table)
+acpi_get_table_with_size(char *signature,
+ u32 instance, struct acpi_table_header **out_table,
+ acpi_size *tbl_size)
{
u32 i;
u32 j;
@@ -408,6 +409,7 @@ acpi_get_table(char *signature,
acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
if (ACPI_SUCCESS(status)) {
*out_table = acpi_gbl_root_table_list.tables[i].pointer;
+ *tbl_size = acpi_gbl_root_table_list.tables[i].length;
}
if (!acpi_gbl_permanent_mmap) {
@@ -420,6 +422,15 @@ acpi_get_table(char *signature,
return (AE_NOT_FOUND);
}
+acpi_status
+acpi_get_table(char *signature,
+ u32 instance, struct acpi_table_header **out_table)
+{
+ acpi_size tbl_size;
+
+ return acpi_get_table_with_size(signature,
+ instance, out_table, &tbl_size);
+}
ACPI_EXPORT_SYMBOL(acpi_get_table)
/*******************************************************************************
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index da9450bc60f7..9c9897dbe907 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -116,9 +116,9 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(AE_NO_MEMORY);
}
- /* Default return value is SUPPORTED */
+ /* Default return value is 0, NOT-SUPPORTED */
- return_desc->integer.value = ACPI_UINT32_MAX;
+ return_desc->integer.value = 0;
walk_state->return_desc = return_desc;
/* Compare input string to static table of supported interfaces */
@@ -127,10 +127,8 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
if (!ACPI_STRCMP
(string_desc->string.pointer,
acpi_interfaces_supported[i])) {
-
- /* The interface is supported */
-
- return_ACPI_STATUS(AE_OK);
+ return_desc->integer.value = ACPI_UINT32_MAX;
+ goto done;
}
}
@@ -141,15 +139,14 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
*/
status = acpi_os_validate_interface(string_desc->string.pointer);
if (ACPI_SUCCESS(status)) {
-
- /* The interface is supported */
-
- return_ACPI_STATUS(AE_OK);
+ return_desc->integer.value = ACPI_UINT32_MAX;
}
- /* The interface is not supported */
+done:
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
+ string_desc->string.pointer,
+ return_desc->integer.value == 0 ? "not-" : ""));
- return_desc->integer.value = 0;
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 65132f920459..69cbc57c2d1c 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -138,6 +138,29 @@ static int acpi_battery_technology(struct acpi_battery *battery)
static int acpi_battery_get_state(struct acpi_battery *battery);
+static int acpi_battery_is_charged(struct acpi_battery *battery)
+{
+ /* either charging or discharging */
+ if (battery->state != 0)
+ return 0;
+
+ /* battery not reporting charge */
+ if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN ||
+ battery->capacity_now == 0)
+ return 0;
+
+ /* good batteries update full_charge as the batteries degrade */
+ if (battery->full_charge_capacity == battery->capacity_now)
+ return 1;
+
+ /* fallback to using design values for broken batteries */
+ if (battery->design_capacity == battery->capacity_now)
+ return 1;
+
+ /* we don't do any sort of metric based on percentages */
+ return 0;
+}
+
static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -155,7 +178,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
else if (battery->state & 0x02)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else if (battery->state == 0)
+ else if (acpi_battery_is_charged(battery))
val->intval = POWER_SUPPLY_STATUS_FULL;
else
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 17020c12623c..fe0cdf83641a 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -163,7 +163,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
case ACPI_NOTIFY_BUS_CHECK:
/* Fall through */
case ACPI_NOTIFY_DEVICE_CHECK:
- printk("Container driver received %s event\n",
+ printk(KERN_WARNING "Container driver received %s event\n",
(type == ACPI_NOTIFY_BUS_CHECK) ?
"ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
status = acpi_bus_get_device(handle, &device);
@@ -174,7 +174,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
kobject_uevent(&device->dev.kobj,
KOBJ_ONLINE);
else
- printk("Failed to add container\n");
+ printk(KERN_WARNING
+ "Failed to add container\n");
}
} else {
if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 5b30b8d91d71..35094f230b1e 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -855,10 +855,14 @@ fdd_out:
static ssize_t show_docked(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ struct acpi_device *tmp;
+
struct dock_station *dock_station = *((struct dock_station **)
dev->platform_data);
- return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
+ if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
+ return snprintf(buf, PAGE_SIZE, "1\n");
+ return snprintf(buf, PAGE_SIZE, "0\n");
}
static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
@@ -984,7 +988,7 @@ static int dock_add(acpi_handle handle)
ret = device_create_file(&dock_device->dev, &dev_attr_docked);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
platform_device_unregister(dock_device);
kfree(dock_station);
dock_station = NULL;
@@ -992,7 +996,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_undock);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
platform_device_unregister(dock_device);
kfree(dock_station);
@@ -1001,7 +1005,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_uid);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
platform_device_unregister(dock_device);
@@ -1011,7 +1015,7 @@ static int dock_add(acpi_handle handle)
}
ret = device_create_file(&dock_device->dev, &dev_attr_flags);
if (ret) {
- printk("Error %d adding sysfs file\n", ret);
+ printk(KERN_ERR "Error %d adding sysfs file\n", ret);
device_remove_file(&dock_device->dev, &dev_attr_docked);
device_remove_file(&dock_device->dev, &dev_attr_undock);
device_remove_file(&dock_device->dev, &dev_attr_uid);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index a2b82c90a683..2fe15060dcdc 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -120,6 +120,8 @@ static struct acpi_ec {
spinlock_t curr_lock;
} *boot_ec, *first_ec;
+static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
+
/* --------------------------------------------------------------------------
Transaction Management
-------------------------------------------------------------------------- */
@@ -259,6 +261,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
acpi_disable_gpe(NULL, ec->gpe);
}
+ if (EC_FLAGS_MSI)
+ udelay(ACPI_EC_DELAY);
/* start transaction */
spin_lock_irqsave(&ec->curr_lock, tmp);
/* following two actions should be kept atomic */
@@ -967,6 +971,11 @@ int __init acpi_ec_ecdt_probe(void)
/*
* Generate a boot ec context
*/
+ if (dmi_name_in_vendors("Micro-Star") ||
+ dmi_name_in_vendors("Notebook")) {
+ pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
+ EC_FLAGS_MSI = 1;
+ }
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_SUCCESS(status)) {
@@ -982,7 +991,7 @@ int __init acpi_ec_ecdt_probe(void)
saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!saved_ec)
return -ENOMEM;
- memcpy(&saved_ec, boot_ec, sizeof(saved_ec));
+ memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
/* fall through */
}
/* This workaround is needed only on some broken machines,
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index adec3d15810a..5479b9f42513 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -255,12 +255,12 @@ static int acpi_platform_notify(struct device *dev)
}
type = acpi_get_bus_type(dev->bus);
if (!type) {
- DBG("No ACPI bus support for %s\n", dev->bus_id);
+ DBG("No ACPI bus support for %s\n", dev_name(dev));
ret = -EINVAL;
goto end;
}
if ((ret = type->find_device(dev, &handle)) != 0)
- DBG("Can't get handler for %s\n", dev->bus_id);
+ DBG("Can't get handler for %s\n", dev_name(dev));
end:
if (!ret)
acpi_bind_one(dev, handle);
@@ -271,10 +271,10 @@ static int acpi_platform_notify(struct device *dev)
acpi_get_name(dev->archdata.acpi_handle,
ACPI_FULL_PATHNAME, &buffer);
- DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
+ DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
kfree(buffer.pointer);
} else
- DBG("Device %s -> No ACPI support\n", dev->bus_id);
+ DBG("Device %s -> No ACPI support\n", dev_name(dev));
#endif
return ret;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 6729a4992f2b..d1dd5160daa9 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -228,10 +228,10 @@ void acpi_os_vprintf(const char *fmt, va_list args)
if (acpi_in_debugger) {
kdb_printf("%s", buffer);
} else {
- printk("%s", buffer);
+ printk(KERN_CONT "%s", buffer);
}
#else
- printk("%s", buffer);
+ printk(KERN_CONT "%s", buffer);
#endif
}
@@ -274,12 +274,19 @@ EXPORT_SYMBOL_GPL(acpi_os_map_memory);
void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
{
- if (acpi_gbl_permanent_mmap) {
+ if (acpi_gbl_permanent_mmap)
iounmap(virt);
- }
+ else
+ __acpi_unmap_table(virt, size);
}
EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
+void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
+{
+ if (!acpi_gbl_permanent_mmap)
+ __acpi_unmap_table(virt, size);
+}
+
#ifdef ACPI_FUTURE_USAGE
acpi_status
acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
@@ -1317,6 +1324,54 @@ acpi_os_validate_interface (char *interface)
return AE_SUPPORT;
}
+#ifdef CONFIG_X86
+
+struct aml_port_desc {
+ uint start;
+ uint end;
+ char* name;
+ char warned;
+};
+
+static struct aml_port_desc aml_invalid_port_list[] = {
+ {0x20, 0x21, "PIC0", 0},
+ {0xA0, 0xA1, "PIC1", 0},
+ {0x4D0, 0x4D1, "ELCR", 0}
+};
+
+/*
+ * valid_aml_io_address()
+ *
+ * if valid, return true
+ * else invalid, warn once, return false
+ */
+static bool valid_aml_io_address(uint address, uint length)
+{
+ int i;
+ int entries = sizeof(aml_invalid_port_list) / sizeof(struct aml_port_desc);
+
+ for (i = 0; i < entries; ++i) {
+ if ((address >= aml_invalid_port_list[i].start &&
+ address <= aml_invalid_port_list[i].end) ||
+ (address + length >= aml_invalid_port_list[i].start &&
+ address + length <= aml_invalid_port_list[i].end))
+ {
+ if (!aml_invalid_port_list[i].warned)
+ {
+ printk(KERN_ERR "ACPI: Denied BIOS AML access"
+ " to invalid port 0x%x+0x%x (%s)\n",
+ address, length,
+ aml_invalid_port_list[i].name);
+ aml_invalid_port_list[i].warned = 1;
+ }
+ return false; /* invalid */
+ }
+ }
+ return true; /* valid */
+}
+#else
+static inline bool valid_aml_io_address(uint address, uint length) { return true; }
+#endif
/******************************************************************************
*
* FUNCTION: acpi_os_validate_address
@@ -1346,6 +1401,8 @@ acpi_os_validate_address (
switch (space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
+ if (!valid_aml_io_address(address, length))
+ return AE_AML_ILLEGAL_ADDRESS;
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
/* Only interference checks against SystemIO and SytemMemory
are needed */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 1c6e73c7865e..6c772ca76bd1 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -593,7 +593,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
return -ENODEV;
} else {
acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
- printk(PREFIX "%s [%s] enabled at IRQ %d\n",
+ printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
acpi_device_name(link->device),
acpi_device_bid(link->device), link->irq.active);
}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5b38a026d122..196f97d00956 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -66,11 +66,18 @@ struct acpi_pci_root {
struct acpi_device * device;
struct acpi_pci_id id;
struct pci_bus *bus;
+
+ u32 osc_support_set; /* _OSC state of support bits */
+ u32 osc_control_set; /* _OSC state of control bits */
+ u32 osc_control_qry; /* the latest _OSC query result */
+
+ u32 osc_queried:1; /* has _OSC control been queried? */
};
static LIST_HEAD(acpi_pci_roots);
static struct acpi_pci_driver *sub_driver;
+static DEFINE_MUTEX(osc_lock);
int acpi_pci_register_driver(struct acpi_pci_driver *driver)
{
@@ -185,6 +192,175 @@ static void acpi_pci_bridge_scan(struct acpi_device *device)
}
}
+static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
+ 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+
+static acpi_status acpi_pci_run_osc(acpi_handle handle,
+ const u32 *capbuf, u32 *retval)
+{
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[4];
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *out_obj;
+ u32 errors;
+
+ /* Setting up input parameters */
+ input.count = 4;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = 16;
+ in_params[0].buffer.pointer = OSC_UUID;
+ in_params[1].type = ACPI_TYPE_INTEGER;
+ in_params[1].integer.value = 1;
+ in_params[2].type = ACPI_TYPE_INTEGER;
+ in_params[2].integer.value = 3;
+ in_params[3].type = ACPI_TYPE_BUFFER;
+ in_params[3].buffer.length = 12;
+ in_params[3].buffer.pointer = (u8 *)capbuf;
+
+ status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ if (!output.length)
+ return AE_NULL_OBJECT;
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ printk(KERN_DEBUG "_OSC evaluation returned wrong type\n");
+ status = AE_TYPE;
+ goto out_kfree;
+ }
+ /* Need to ignore the bit0 in result code */
+ errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+ if (errors) {
+ if (errors & OSC_REQUEST_ERROR)
+ printk(KERN_DEBUG "_OSC request failed\n");
+ if (errors & OSC_INVALID_UUID_ERROR)
+ printk(KERN_DEBUG "_OSC invalid UUID\n");
+ if (errors & OSC_INVALID_REVISION_ERROR)
+ printk(KERN_DEBUG "_OSC invalid revision\n");
+ if (errors & OSC_CAPABILITIES_MASK_ERROR) {
+ if (capbuf[OSC_QUERY_TYPE] & OSC_QUERY_ENABLE)
+ goto out_success;
+ printk(KERN_DEBUG
+ "Firmware did not grant requested _OSC control\n");
+ status = AE_SUPPORT;
+ goto out_kfree;
+ }
+ status = AE_ERROR;
+ goto out_kfree;
+ }
+out_success:
+ *retval = *((u32 *)(out_obj->buffer.pointer + 8));
+ status = AE_OK;
+
+out_kfree:
+ kfree(output.pointer);
+ return status;
+}
+
+static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
+{
+ acpi_status status;
+ u32 support_set, result, capbuf[3];
+
+ /* do _OSC query for all possible controls */
+ support_set = root->osc_support_set | (flags & OSC_SUPPORT_MASKS);
+ capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+ capbuf[OSC_SUPPORT_TYPE] = support_set;
+ capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+
+ status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
+ if (ACPI_SUCCESS(status)) {
+ root->osc_support_set = support_set;
+ root->osc_control_qry = result;
+ root->osc_queried = 1;
+ }
+ return status;
+}
+
+static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
+{
+ acpi_status status;
+ acpi_handle tmp;
+
+ status = acpi_get_handle(root->device->handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+ mutex_lock(&osc_lock);
+ status = acpi_pci_query_osc(root, flags);
+ mutex_unlock(&osc_lock);
+ return status;
+}
+
+static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
+{
+ struct acpi_pci_root *root;
+ list_for_each_entry(root, &acpi_pci_roots, node) {
+ if (root->device->handle == handle)
+ return root;
+ }
+ return NULL;
+}
+
+/**
+ * acpi_pci_osc_control_set - commit requested control to Firmware
+ * @handle: acpi_handle for the target ACPI object
+ * @flags: driver's requested control bits
+ *
+ * Attempt to take control from Firmware on requested control bits.
+ **/
+acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
+{
+ acpi_status status;
+ u32 control_req, result, capbuf[3];
+ acpi_handle tmp;
+ struct acpi_pci_root *root;
+
+ status = acpi_get_handle(handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ control_req = (flags & OSC_CONTROL_MASKS);
+ if (!control_req)
+ return AE_TYPE;
+
+ root = acpi_pci_find_root(handle);
+ if (!root)
+ return AE_NOT_EXIST;
+
+ mutex_lock(&osc_lock);
+ /* No need to evaluate _OSC if the control was already granted. */
+ if ((root->osc_control_set & control_req) == control_req)
+ goto out;
+
+ /* Need to query controls first before requesting them */
+ if (!root->osc_queried) {
+ status = acpi_pci_query_osc(root, root->osc_support_set);
+ if (ACPI_FAILURE(status))
+ goto out;
+ }
+ if ((root->osc_control_qry & control_req) != control_req) {
+ printk(KERN_DEBUG
+ "Firmware did not grant requested _OSC control\n");
+ status = AE_SUPPORT;
+ goto out;
+ }
+
+ capbuf[OSC_QUERY_TYPE] = 0;
+ capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
+ capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req;
+ status = acpi_pci_run_osc(handle, capbuf, &result);
+ if (ACPI_SUCCESS(status))
+ root->osc_control_set = result;
+out:
+ mutex_unlock(&osc_lock);
+ return status;
+}
+EXPORT_SYMBOL(acpi_pci_osc_control_set);
+
static int __devinit acpi_pci_root_add(struct acpi_device *device)
{
int result = 0;
@@ -217,7 +393,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
* PCI domains, so we indicate this in _OSC support capabilities.
*/
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
- pci_acpi_osc_support(device->handle, flags);
+ acpi_pci_osc_support(root, flags);
/*
* Segment
@@ -353,7 +529,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
if (pci_msi_enabled())
flags |= OSC_MSI_SUPPORT;
if (flags != base_flags)
- pci_acpi_osc_support(device->handle, flags);
+ acpi_pci_osc_support(root, flags);
end:
if (result) {
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 66a9d8145562..7bc22a471fe3 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -66,43 +66,17 @@ ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
-#ifndef CONFIG_CPU_IDLE
-#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
-#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
-static void (*pm_idle_save) (void) __read_mostly;
-#else
#define C2_OVERHEAD 1 /* 1us */
#define C3_OVERHEAD 1 /* 1us */
-#endif
#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
-#ifdef CONFIG_CPU_IDLE
module_param(max_cstate, uint, 0000);
-#else
-module_param(max_cstate, uint, 0644);
-#endif
static unsigned int nocst __read_mostly;
module_param(nocst, uint, 0000);
-#ifndef CONFIG_CPU_IDLE
-/*
- * bm_history -- bit-mask with a bit per jiffy of bus-master activity
- * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
- * 800 HZ: 0xFFFFFFFF: 32 jiffies = 40ms
- * 100 HZ: 0x0000000F: 4 jiffies = 40ms
- * reduce history for more aggressive entry into C3
- */
-static unsigned int bm_history __read_mostly =
- (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
-module_param(bm_history, uint, 0644);
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr);
-
-#else /* CONFIG_CPU_IDLE */
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
-#endif
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -224,71 +198,6 @@ static void acpi_safe_halt(void)
current_thread_info()->status |= TS_POLLING;
}
-#ifndef CONFIG_CPU_IDLE
-
-static void
-acpi_processor_power_activate(struct acpi_processor *pr,
- struct acpi_processor_cx *new)
-{
- struct acpi_processor_cx *old;
-
- if (!pr || !new)
- return;
-
- old = pr->power.state;
-
- if (old)
- old->promotion.count = 0;
- new->demotion.count = 0;
-
- /* Cleanup from old state. */
- if (old) {
- switch (old->type) {
- case ACPI_STATE_C3:
- /* Disable bus master reload */
- if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- break;
- }
- }
-
- /* Prepare to use new state. */
- switch (new->type) {
- case ACPI_STATE_C3:
- /* Enable bus master reload */
- if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- break;
- }
-
- pr->power.state = new;
-
- return;
-}
-
-static atomic_t c3_cpu_count;
-
-/* Common C-state entry for C2, C3, .. */
-static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
-{
- /* Don't trace irqs off for idle */
- stop_critical_timings();
- if (cstate->entry_method == ACPI_CSTATE_FFH) {
- /* Call into architectural FFH based C-state */
- acpi_processor_ffh_cstate_enter(cstate);
- } else {
- int unused;
- /* IO port based C-state */
- inb(cstate->address);
- /* Dummy wait op - must do something useless after P_LVL2 read
- because chipsets cannot guarantee that STPCLK# signal
- gets asserted in time to freeze execution properly. */
- unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
- }
- start_critical_timings();
-}
-#endif /* !CONFIG_CPU_IDLE */
-
#ifdef ARCH_APICTIMER_STOPS_ON_C3
/*
@@ -390,421 +299,6 @@ static int tsc_halts_in_c(int state)
}
#endif
-#ifndef CONFIG_CPU_IDLE
-static void acpi_processor_idle(void)
-{
- struct acpi_processor *pr = NULL;
- struct acpi_processor_cx *cx = NULL;
- struct acpi_processor_cx *next_state = NULL;
- int sleep_ticks = 0;
- u32 t1, t2 = 0;
-
- /*
- * Interrupts must be disabled during bus mastering calculations and
- * for C2/C3 transitions.
- */
- local_irq_disable();
-
- pr = __get_cpu_var(processors);
- if (!pr) {
- local_irq_enable();
- return;
- }
-
- /*
- * Check whether we truly need to go idle, or should
- * reschedule:
- */
- if (unlikely(need_resched())) {
- local_irq_enable();
- return;
- }
-
- cx = pr->power.state;
- if (!cx || acpi_idle_suspend) {
- if (pm_idle_save) {
- pm_idle_save(); /* enables IRQs */
- } else {
- acpi_safe_halt();
- local_irq_enable();
- }
-
- return;
- }
-
- /*
- * Check BM Activity
- * -----------------
- * Check for bus mastering activity (if required), record, and check
- * for demotion.
- */
- if (pr->flags.bm_check) {
- u32 bm_status = 0;
- unsigned long diff = jiffies - pr->power.bm_check_timestamp;
-
- if (diff > 31)
- diff = 31;
-
- pr->power.bm_activity <<= diff;
-
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
- if (bm_status) {
- pr->power.bm_activity |= 0x1;
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
- }
- /*
- * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
- * the true state of bus mastering activity; forcing us to
- * manually check the BMIDEA bit of each IDE channel.
- */
- else if (errata.piix4.bmisx) {
- if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
- || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
- pr->power.bm_activity |= 0x1;
- }
-
- pr->power.bm_check_timestamp = jiffies;
-
- /*
- * If bus mastering is or was active this jiffy, demote
- * to avoid a faulty transition. Note that the processor
- * won't enter a low-power state during this call (to this
- * function) but should upon the next.
- *
- * TBD: A better policy might be to fallback to the demotion
- * state (use it for this quantum only) istead of
- * demoting -- and rely on duration as our sole demotion
- * qualification. This may, however, introduce DMA
- * issues (e.g. floppy DMA transfer overrun/underrun).
- */
- if ((pr->power.bm_activity & 0x1) &&
- cx->demotion.threshold.bm) {
- local_irq_enable();
- next_state = cx->demotion.state;
- goto end;
- }
- }
-
-#ifdef CONFIG_HOTPLUG_CPU
- /*
- * Check for P_LVL2_UP flag before entering C2 and above on
- * an SMP system. We do it here instead of doing it at _CST/P_LVL
- * detection phase, to work cleanly with logical CPU hotplug.
- */
- if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
- cx = &pr->power.states[ACPI_STATE_C1];
-#endif
-
- /*
- * Sleep:
- * ------
- * Invoke the current Cx state to put the processor to sleep.
- */
- if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
- if (need_resched()) {
- current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
- return;
- }
- }
-
- switch (cx->type) {
-
- case ACPI_STATE_C1:
- /*
- * Invoke C1.
- * Use the appropriate idle routine, the one that would
- * be used without acpi C-states.
- */
- if (pm_idle_save) {
- pm_idle_save(); /* enables IRQs */
- } else {
- acpi_safe_halt();
- local_irq_enable();
- }
-
- /*
- * TBD: Can't get time duration while in C1, as resumes
- * go to an ISR rather than here. Need to instrument
- * base interrupt handler.
- *
- * Note: the TSC better not stop in C1, sched_clock() will
- * skew otherwise.
- */
- sleep_ticks = 0xFFFFFFFF;
-
- break;
-
- case ACPI_STATE_C2:
- /* Get start time (ticks) */
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- /* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
- /* Invoke C2 */
- acpi_state_timer_broadcast(pr, cx, 1);
- acpi_cstate_enter(cx);
- /* Get end time (ticks) */
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC halts in C2, so notify users */
- if (tsc_halts_in_c(ACPI_STATE_C2))
- mark_tsc_unstable("possible TSC halt in C2");
-#endif
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2);
-
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
- /* Re-enable interrupts */
- local_irq_enable();
- /* Do not account our idle-switching overhead: */
- sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
-
- current_thread_info()->status |= TS_POLLING;
- acpi_state_timer_broadcast(pr, cx, 0);
- break;
-
- case ACPI_STATE_C3:
- acpi_unlazy_tlb(smp_processor_id());
- /*
- * Must be done before busmaster disable as we might
- * need to access HPET !
- */
- acpi_state_timer_broadcast(pr, cx, 1);
- /*
- * disable bus master
- * bm_check implies we need ARB_DIS
- * !bm_check implies we need cache flush
- * bm_control implies whether we can do ARB_DIS
- *
- * That leaves a case where bm_check is set and bm_control is
- * not set. In that case we cannot do much, we enter C3
- * without doing anything.
- */
- if (pr->flags.bm_check && pr->flags.bm_control) {
- if (atomic_inc_return(&c3_cpu_count) ==
- num_online_cpus()) {
- /*
- * All CPUs are trying to go to C3
- * Disable bus master arbitration
- */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
- }
- } else if (!pr->flags.bm_check) {
- /* SMP with no shared cache... Invalidate cache */
- ACPI_FLUSH_CPU_CACHE();
- }
-
- /* Get start time (ticks) */
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- /* Invoke C3 */
- /* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
- acpi_cstate_enter(cx);
- /* Get end time (ticks) */
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- if (pr->flags.bm_check && pr->flags.bm_control) {
- /* Enable bus master arbitration */
- atomic_dec(&c3_cpu_count);
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
- }
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
- /* TSC halts in C3, so notify users */
- if (tsc_halts_in_c(ACPI_STATE_C3))
- mark_tsc_unstable("TSC halts in C3");
-#endif
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks = ticks_elapsed(t1, t2);
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
- /* Re-enable interrupts */
- local_irq_enable();
- /* Do not account our idle-switching overhead: */
- sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
-
- current_thread_info()->status |= TS_POLLING;
- acpi_state_timer_broadcast(pr, cx, 0);
- break;
-
- default:
- local_irq_enable();
- return;
- }
- cx->usage++;
- if ((cx->type != ACPI_STATE_C1) && (sleep_ticks > 0))
- cx->time += sleep_ticks;
-
- next_state = pr->power.state;
-
-#ifdef CONFIG_HOTPLUG_CPU
- /* Don't do promotion/demotion */
- if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) &&
- !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) {
- next_state = cx;
- goto end;
- }
-#endif
-
- /*
- * Promotion?
- * ----------
- * Track the number of longs (time asleep is greater than threshold)
- * and promote when the count threshold is reached. Note that bus
- * mastering activity may prevent promotions.
- * Do not promote above max_cstate.
- */
- if (cx->promotion.state &&
- ((cx->promotion.state - pr->power.states) <= max_cstate)) {
- if (sleep_ticks > cx->promotion.threshold.ticks &&
- cx->promotion.state->latency <=
- pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
- cx->promotion.count++;
- cx->demotion.count = 0;
- if (cx->promotion.count >=
- cx->promotion.threshold.count) {
- if (pr->flags.bm_check) {
- if (!
- (pr->power.bm_activity & cx->
- promotion.threshold.bm)) {
- next_state =
- cx->promotion.state;
- goto end;
- }
- } else {
- next_state = cx->promotion.state;
- goto end;
- }
- }
- }
- }
-
- /*
- * Demotion?
- * ---------
- * Track the number of shorts (time asleep is less than time threshold)
- * and demote when the usage threshold is reached.
- */
- if (cx->demotion.state) {
- if (sleep_ticks < cx->demotion.threshold.ticks) {
- cx->demotion.count++;
- cx->promotion.count = 0;
- if (cx->demotion.count >= cx->demotion.threshold.count) {
- next_state = cx->demotion.state;
- goto end;
- }
- }
- }
-
- end:
- /*
- * Demote if current state exceeds max_cstate
- * or if the latency of the current state is unacceptable
- */
- if ((pr->power.state - pr->power.states) > max_cstate ||
- pr->power.state->latency >
- pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
- if (cx->demotion.state)
- next_state = cx->demotion.state;
- }
-
- /*
- * New Cx State?
- * -------------
- * If we're going to start using a new Cx state we must clean up
- * from the previous and prepare to use the new.
- */
- if (next_state != pr->power.state)
- acpi_processor_power_activate(pr, next_state);
-}
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr)
-{
- unsigned int i;
- unsigned int state_is_set = 0;
- struct acpi_processor_cx *lower = NULL;
- struct acpi_processor_cx *higher = NULL;
- struct acpi_processor_cx *cx;
-
-
- if (!pr)
- return -EINVAL;
-
- /*
- * This function sets the default Cx state policy (OS idle handler).
- * Our scheme is to promote quickly to C2 but more conservatively
- * to C3. We're favoring C2 for its characteristics of low latency
- * (quick response), good power savings, and ability to allow bus
- * mastering activity. Note that the Cx state policy is completely
- * customizable and can be altered dynamically.
- */
-
- /* startup state */
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (!state_is_set)
- pr->power.state = cx;
- state_is_set++;
- break;
- }
-
- if (!state_is_set)
- return -ENODEV;
-
- /* demotion */
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (lower) {
- cx->demotion.state = lower;
- cx->demotion.threshold.ticks = cx->latency_ticks;
- cx->demotion.threshold.count = 1;
- if (cx->type == ACPI_STATE_C3)
- cx->demotion.threshold.bm = bm_history;
- }
-
- lower = cx;
- }
-
- /* promotion */
- for (i = (ACPI_PROCESSOR_MAX_POWER - 1); i > 0; i--) {
- cx = &pr->power.states[i];
- if (!cx->valid)
- continue;
-
- if (higher) {
- cx->promotion.state = higher;
- cx->promotion.threshold.ticks = cx->latency_ticks;
- if (cx->type >= ACPI_STATE_C2)
- cx->promotion.threshold.count = 4;
- else
- cx->promotion.threshold.count = 10;
- if (higher->type == ACPI_STATE_C3)
- cx->promotion.threshold.bm = bm_history;
- }
-
- higher = cx;
- }
-
- return 0;
-}
-#endif /* !CONFIG_CPU_IDLE */
-
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
@@ -1047,11 +541,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
*/
cx->valid = 1;
-#ifndef CONFIG_CPU_IDLE
- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
cx->latency_ticks = cx->latency;
-#endif
return;
}
@@ -1121,7 +611,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
" for C3 to be enabled on SMP systems\n"));
return;
}
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
}
/*
@@ -1132,11 +621,16 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
*/
cx->valid = 1;
-#ifndef CONFIG_CPU_IDLE
- cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
cx->latency_ticks = cx->latency;
-#endif
+ /*
+ * On older chipsets, BM_RLD needs to be set
+ * in order for Bus Master activity to wake the
+ * system from C3. Newer chipsets handle DMA
+ * during C3 automatically and BM_RLD is a NOP.
+ * In either case, the proper way to
+ * handle BM_RLD is to set it and leave it set.
+ */
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
return;
}
@@ -1201,20 +695,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
pr->power.count = acpi_processor_power_verify(pr);
-#ifndef CONFIG_CPU_IDLE
- /*
- * Set Default Policy
- * ------------------
- * Now that we know which states are supported, set the default
- * policy. Note that this policy can be changed dynamically
- * (e.g. encourage deeper sleeps to conserve battery life when
- * not on AC).
- */
- result = acpi_processor_set_power_policy(pr);
- if (result)
- return result;
-#endif
-
/*
* if one state of type C2 or C3 is available, mark this
* CPU as being "idle manageable"
@@ -1312,69 +792,6 @@ static const struct file_operations acpi_processor_power_fops = {
.release = single_release,
};
-#ifndef CONFIG_CPU_IDLE
-
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
- int result = 0;
-
- if (boot_option_idle_override)
- return 0;
-
- if (!pr)
- return -EINVAL;
-
- if (nocst) {
- return -ENODEV;
- }
-
- if (!pr->flags.power_setup_done)
- return -ENODEV;
-
- /*
- * Fall back to the default idle loop, when pm_idle_save had
- * been initialized.
- */
- if (pm_idle_save) {
- pm_idle = pm_idle_save;
- /* Relies on interrupts forcing exit from idle. */
- synchronize_sched();
- }
-
- pr->flags.power = 0;
- result = acpi_processor_get_power_info(pr);
- if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
- pm_idle = acpi_processor_idle;
-
- return result;
-}
-
-#ifdef CONFIG_SMP
-static void smp_callback(void *v)
-{
- /* we already woke the CPU up, nothing more to do */
-}
-
-/*
- * This function gets called when a part of the kernel has a new latency
- * requirement. This means we need to get all processors out of their C-state,
- * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
- * wakes them all right up.
- */
-static int acpi_processor_latency_notify(struct notifier_block *b,
- unsigned long l, void *v)
-{
- smp_call_function(smp_callback, NULL, 1);
- return NOTIFY_OK;
-}
-
-static struct notifier_block acpi_processor_latency_notifier = {
- .notifier_call = acpi_processor_latency_notify,
-};
-
-#endif
-
-#else /* CONFIG_CPU_IDLE */
/**
* acpi_idle_bm_check - checks if bus master activity was detected
@@ -1383,7 +800,7 @@ static int acpi_idle_bm_check(void)
{
u32 bm_status = 0;
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+ acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
if (bm_status)
acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
/*
@@ -1400,25 +817,6 @@ static int acpi_idle_bm_check(void)
}
/**
- * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
- * @pr: the processor
- * @target: the new target state
- */
-static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
- struct acpi_processor_cx *target)
-{
- if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- pr->flags.bm_rld_set = 0;
- }
-
- if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- pr->flags.bm_rld_set = 1;
- }
-}
-
-/**
* acpi_idle_do_entry - a helper function that does C2 and C3 type entry
* @cx: cstate data
*
@@ -1473,9 +871,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return 0;
}
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
acpi_idle_do_entry(cx);
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -1527,9 +922,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
*/
acpi_state_timer_broadcast(pr, cx, 1);
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
@@ -1621,8 +1013,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
*/
acpi_state_timer_broadcast(pr, cx, 1);
- acpi_idle_update_bm_rld(pr, cx);
-
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -1795,8 +1185,6 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
return ret;
}
-#endif /* CONFIG_CPU_IDLE */
-
int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
struct acpi_device *device)
{
@@ -1825,10 +1213,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
-#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP)
- pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
- &acpi_processor_latency_notifier);
-#endif
}
if (!pr)
@@ -1852,11 +1236,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
* platforms that only support C1.
*/
if (pr->flags.power) {
-#ifdef CONFIG_CPU_IDLE
acpi_processor_setup_cpuidle(pr);
if (cpuidle_register_device(&pr->power.dev))
return -EIO;
-#endif
printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
for (i = 1; i <= pr->power.count; i++)
@@ -1864,13 +1246,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
printk(" C%d[C%d]", i,
pr->power.states[i].type);
printk(")\n");
-
-#ifndef CONFIG_CPU_IDLE
- if (pr->id == 0) {
- pm_idle_save = pm_idle;
- pm_idle = acpi_processor_idle;
- }
-#endif
}
/* 'power' [R] */
@@ -1889,34 +1264,12 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
if (boot_option_idle_override)
return 0;
-#ifdef CONFIG_CPU_IDLE
cpuidle_unregister_device(&pr->power.dev);
-#endif
pr->flags.power_setup_done = 0;
if (acpi_device_dir(device))
remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
acpi_device_dir(device));
-#ifndef CONFIG_CPU_IDLE
-
- /* Unregister the idle handler when processor #0 is removed. */
- if (pr->id == 0) {
- if (pm_idle_save)
- pm_idle = pm_idle_save;
-
- /*
- * We are about to unload the current idle thread pm callback
- * (pm_idle), Wait for all processors to update cached/local
- * copies of pm_idle before proceeding.
- */
- cpu_idle_wait();
-#ifdef CONFIG_SMP
- pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
- &acpi_processor_latency_notifier);
-#endif
- }
-#endif
-
return 0;
}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 846e227592d4..9cc769b587ff 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -31,14 +31,6 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#endif
-
#ifdef CONFIG_X86
#include <asm/cpufeature.h>
#endif
@@ -434,96 +426,6 @@ int acpi_processor_notify_smm(struct module *calling_module)
EXPORT_SYMBOL(acpi_processor_notify_smm);
-#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
-/* /proc/acpi/processor/../performance interface (DEPRECATED) */
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
- .owner = THIS_MODULE,
- .open = acpi_processor_perf_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
-{
- struct acpi_processor *pr = seq->private;
- int i;
-
-
- if (!pr)
- goto end;
-
- if (!pr->performance) {
- seq_puts(seq, "<not supported>\n");
- goto end;
- }
-
- seq_printf(seq, "state count: %d\n"
- "active state: P%d\n",
- pr->performance->state_count, pr->performance->state);
-
- seq_puts(seq, "states:\n");
- for (i = 0; i < pr->performance->state_count; i++)
- seq_printf(seq,
- " %cP%d: %d MHz, %d mW, %d uS\n",
- (i == pr->performance->state ? '*' : ' '), i,
- (u32) pr->performance->states[i].core_frequency,
- (u32) pr->performance->states[i].power,
- (u32) pr->performance->states[i].transition_latency);
-
- end:
- return 0;
-}
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_processor_perf_seq_show,
- PDE(inode)->data);
-}
-
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
- struct acpi_device *device = NULL;
-
-
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
- /* add file 'performance' [R/W] */
- proc_create_data(ACPI_PROCESSOR_FILE_PERFORMANCE, S_IFREG | S_IRUGO,
- acpi_device_dir(device),
- &acpi_processor_perf_fops, acpi_driver_data(device));
- return;
-}
-
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
- struct acpi_device *device = NULL;
-
-
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
- /* remove file 'performance' */
- remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
- acpi_device_dir(device));
-
- return;
-}
-
-#else
-static void acpi_cpufreq_add_file(struct acpi_processor *pr)
-{
- return;
-}
-static void acpi_cpufreq_remove_file(struct acpi_processor *pr)
-{
- return;
-}
-#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
-
static int acpi_processor_get_psd(struct acpi_processor *pr)
{
int result = 0;
@@ -747,14 +649,12 @@ err_ret:
}
EXPORT_SYMBOL(acpi_processor_preregister_performance);
-
int
acpi_processor_register_performance(struct acpi_processor_performance
*performance, unsigned int cpu)
{
struct acpi_processor *pr;
-
if (!(acpi_processor_ppc_status & PPC_REGISTERED))
return -EINVAL;
@@ -781,8 +681,6 @@ acpi_processor_register_performance(struct acpi_processor_performance
return -EIO;
}
- acpi_cpufreq_add_file(pr);
-
mutex_unlock(&performance_mutex);
return 0;
}
@@ -795,7 +693,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
{
struct acpi_processor *pr;
-
mutex_lock(&performance_mutex);
pr = per_cpu(processors, cpu);
@@ -808,8 +705,6 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
kfree(pr->performance->states);
pr->performance = NULL;
- acpi_cpufreq_remove_file(pr);
-
mutex_unlock(&performance_mutex);
return;
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 7e3c609cbef2..519266654f06 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -90,31 +90,6 @@ void __init acpi_old_suspend_ordering(void)
old_suspend_ordering = true;
}
-/*
- * According to the ACPI specification the BIOS should make sure that ACPI is
- * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
- * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
- * on such systems during resume. Unfortunately that doesn't help in
- * particularly pathological cases in which SCI_EN has to be set directly on
- * resume, although the specification states very clearly that this flag is
- * owned by the hardware. The set_sci_en_on_resume variable will be set in such
- * cases.
- */
-static bool set_sci_en_on_resume;
-/*
- * The ACPI specification wants us to save NVS memory regions during hibernation
- * and to restore them during the subsequent resume. However, it is not certain
- * if this mechanism is going to work on all machines, so we allow the user to
- * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
- * option.
- */
-static bool s4_no_nvs;
-
-void __init acpi_s4_no_nvs(void)
-{
- s4_no_nvs = true;
-}
-
/**
* acpi_pm_disable_gpes - Disable the GPEs.
*/
@@ -193,6 +168,18 @@ static void acpi_pm_end(void)
#endif /* CONFIG_ACPI_SLEEP */
#ifdef CONFIG_SUSPEND
+/*
+ * According to the ACPI specification the BIOS should make sure that ACPI is
+ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
+ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
+ * on such systems during resume. Unfortunately that doesn't help in
+ * particularly pathological cases in which SCI_EN has to be set directly on
+ * resume, although the specification states very clearly that this flag is
+ * owned by the hardware. The set_sci_en_on_resume variable will be set in such
+ * cases.
+ */
+static bool set_sci_en_on_resume;
+
extern void do_suspend_lowlevel(void);
static u32 acpi_suspend_states[] = {
@@ -396,6 +383,20 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION
+/*
+ * The ACPI specification wants us to save NVS memory regions during hibernation
+ * and to restore them during the subsequent resume. However, it is not certain
+ * if this mechanism is going to work on all machines, so we allow the user to
+ * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
+ * option.
+ */
+static bool s4_no_nvs;
+
+void __init acpi_s4_no_nvs(void)
+{
+ s4_no_nvs = true;
+}
+
static unsigned long s4_hardware_signature;
static struct acpi_table_facs *facs;
static bool nosigcheck;
@@ -679,7 +680,7 @@ static void acpi_power_off_prepare(void)
static void acpi_power_off(void)
{
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
- printk("%s called\n", __func__);
+ printk(KERN_DEBUG "%s called\n", __func__);
local_irq_disable();
acpi_enable_wakeup_device(ACPI_STATE_S5);
acpi_enter_sleep_state(ACPI_STATE_S5);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 775c97a282bd..fec1ae36d431 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -181,14 +181,15 @@ acpi_table_parse_entries(char *id,
struct acpi_subtable_header *entry;
unsigned int count = 0;
unsigned long table_end;
+ acpi_size tbl_size;
if (!handler)
return -EINVAL;
if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
- acpi_get_table(id, acpi_apic_instance, &table_header);
+ acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
else
- acpi_get_table(id, 0, &table_header);
+ acpi_get_table_with_size(id, 0, &table_header, &tbl_size);
if (!table_header) {
printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
@@ -206,8 +207,10 @@ acpi_table_parse_entries(char *id,
table_end) {
if (entry->type == entry_id
&& (!max_entries || count++ < max_entries))
- if (handler(entry, table_end))
+ if (handler(entry, table_end)) {
+ early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return -EINVAL;
+ }
entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length);
@@ -217,6 +220,7 @@ acpi_table_parse_entries(char *id,
"%i found\n", id, entry_id, count - max_entries, count);
}
+ early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return count;
}
@@ -241,17 +245,19 @@ acpi_table_parse_madt(enum acpi_madt_type id,
int __init acpi_table_parse(char *id, acpi_table_handler handler)
{
struct acpi_table_header *table = NULL;
+ acpi_size tbl_size;
if (!handler)
return -EINVAL;
if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
- acpi_get_table(id, acpi_apic_instance, &table);
+ acpi_get_table_with_size(id, acpi_apic_instance, &table, &tbl_size);
else
- acpi_get_table(id, 0, &table);
+ acpi_get_table_with_size(id, 0, &table, &tbl_size);
if (table) {
handler(table);
+ early_acpi_os_unmap_memory(table, tbl_size);
return 0;
} else
return 1;
@@ -265,8 +271,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)
static void __init check_multiple_madt(void)
{
struct acpi_table_header *table = NULL;
+ acpi_size tbl_size;
- acpi_get_table(ACPI_SIG_MADT, 2, &table);
+ acpi_get_table_with_size(ACPI_SIG_MADT, 2, &table, &tbl_size);
if (table) {
printk(KERN_WARNING PREFIX
"BIOS bug: multiple APIC/MADT found,"
@@ -275,6 +282,7 @@ static void __init check_multiple_madt(void)
"If \"acpi_apic_instance=%d\" works better, "
"notify linux-acpi@vger.kernel.org\n",
acpi_apic_instance ? 0 : 2);
+ early_acpi_os_unmap_memory(table, tbl_size);
} else
acpi_apic_instance = 0;
@@ -293,7 +301,12 @@ static void __init check_multiple_madt(void)
int __init acpi_table_init(void)
{
- acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+ acpi_status status;
+
+ status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+ if (ACPI_FAILURE(status))
+ return 1;
+
check_multiple_madt();
return 0;
}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f261737636da..bb5ed059114a 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -1020,7 +1020,7 @@ acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
}
seq_printf(seq, "levels: ");
- for (i = 0; i < dev->brightness->count; i++)
+ for (i = 2; i < dev->brightness->count; i++)
seq_printf(seq, " %d", dev->brightness->levels[i]);
seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
@@ -1059,7 +1059,7 @@ acpi_video_device_write_brightness(struct file *file,
return -EFAULT;
/* validate through the list of available levels */
- for (i = 0; i < dev->brightness->count; i++)
+ for (i = 2; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) {
if (ACPI_SUCCESS
(acpi_video_device_lcd_set_level(dev, level)))
@@ -1260,7 +1260,7 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
printk(KERN_WARNING PREFIX
"This indicates a BIOS bug. Please contact the manufacturer.\n");
}
- printk("%llx\n", options);
+ printk(KERN_WARNING "%llx\n", options);
seq_printf(seq, "can POST: <integrated video>");
if (options & 2)
seq_printf(seq, " <PCI video>");
@@ -1712,7 +1712,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
max = max_below = 0;
min = min_above = 255;
/* Find closest level to level_current */
- for (i = 0; i < device->brightness->count; i++) {
+ for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (abs(l - level_current) < abs(delta)) {
delta = l - level_current;
@@ -1722,7 +1722,7 @@ acpi_video_get_next_level(struct acpi_video_device *device,
}
/* Ajust level_current to closest available level */
level_current += delta;
- for (i = 0; i < device->brightness->count; i++) {
+ for (i = 2; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (l < min)
min = l;
@@ -2006,6 +2006,12 @@ static int acpi_video_bus_add(struct acpi_device *device)
device->pnp.bus_id[3] = '0' + instance;
instance ++;
}
+ /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
+ if (!strcmp(device->pnp.bus_id, "VGA")) {
+ if (instance)
+ device->pnp.bus_id[3] = '0' + instance;
+ instance++;
+ }
video->device = device;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 00c46e0b40e4..3d763fdf99b7 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -210,7 +210,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
dev->dev.release = amba_device_release;
dev->dev.bus = &amba_bustype;
dev->dev.dma_mask = &dev->dma_mask;
- dev->res.name = dev->dev.bus_id;
+ dev->res.name = dev_name(&dev->dev);
if (!dev->dev.coherent_dma_mask && dev->dma_mask)
dev_warn(&dev->dev, "coherent dma mask is unset\n");
@@ -294,7 +294,7 @@ static int amba_find_match(struct device *dev, void *data)
if (d->parent)
r &= d->parent == dev->parent;
if (d->busid)
- r &= strcmp(dev->bus_id, d->busid) == 0;
+ r &= strcmp(dev_name(dev), d->busid) == 0;
if (r) {
get_device(dev);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 503a908afc80..0bcf26464670 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -112,11 +112,11 @@ config ATA_PIIX
If unsure, say N.
config SATA_MV
- tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ tristate "Marvell SATA support"
help
This option enables support for the Marvell Serial ATA family.
- Currently supports 88SX[56]0[48][01] chips.
+ Currently supports 88SX[56]0[48][01] PCI(-X) chips,
+ as well as the newer [67]042 PCI-X/PCIe and SOC devices.
If unsure, say N.
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 96039671e3b9..6813ee8d6d26 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -61,9 +61,14 @@
#define EM_MSG_LED_VALUE_ON 0x00010000
static int ahci_skip_host_reset;
+static int ahci_ignore_sss;
+
module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444);
MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)");
+module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
+MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)");
+
static int ahci_enable_alpm(struct ata_port *ap,
enum link_pm policy);
static void ahci_disable_alpm(struct ata_port *ap);
@@ -2548,6 +2553,32 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
}
}
+static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
+{
+ static const struct dmi_system_id broken_systems[] = {
+ {
+ .ident = "HP Compaq nx6310",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x1FUL,
+ },
+
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
+
+ if (dmi) {
+ unsigned long slot = (unsigned long)dmi->driver_data;
+ /* apply the quirk only to on-board controllers */
+ return slot == PCI_SLOT(pdev->devfn);
+ }
+
+ return false;
+}
+
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
@@ -2616,8 +2647,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
- if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
- pci_intx(pdev, 1);
+ if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
+ pci_enable_msi(pdev);
/* save initial config */
ahci_save_initial_config(pdev, hpriv);
@@ -2647,6 +2678,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
+ if (ahci_broken_system_poweroff(pdev)) {
+ pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN;
+ dev_info(&pdev->dev,
+ "quirky BIOS, skipping spindown on poweroff\n");
+ }
+
/* CAP.NP sometimes indicate the index of the last enabled
* port, at other times, that of the last possible port, so
* determining the maximum port number requires looking at
@@ -2660,8 +2697,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
host->iomap = pcim_iomap_table(pdev);
host->private_data = hpriv;
- if (!(hpriv->cap & HOST_CAP_SSS))
+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN;
+ else
+ printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");
if (pi.flags & ATA_FLAG_EM)
ahci_reset_em(host);
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 887d8f46a287..54961c0b2c73 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1387,6 +1387,32 @@ static void piix_iocfg_bit18_quirk(struct ata_host *host)
}
}
+static bool piix_broken_system_poweroff(struct pci_dev *pdev)
+{
+ static const struct dmi_system_id broken_systems[] = {
+ {
+ .ident = "HP Compaq 2510p",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 2510p"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x1FUL,
+ },
+
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
+
+ if (dmi) {
+ unsigned long slot = (unsigned long)dmi->driver_data;
+ /* apply the quirk only to on-board controllers */
+ return slot == PCI_SLOT(pdev->devfn);
+ }
+
+ return false;
+}
+
/**
* piix_init_one - Register PIIX ATA PCI device with kernel services
* @pdev: PCI device to register
@@ -1422,6 +1448,14 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
if (!in_module_init)
return -ENODEV;
+ if (piix_broken_system_poweroff(pdev)) {
+ piix_port_info[ent->driver_data].flags |=
+ ATA_FLAG_NO_POWEROFF_SPINDOWN |
+ ATA_FLAG_NO_HIBERNATE_SPINDOWN;
+ dev_info(&pdev->dev, "quirky BIOS, skipping spindown "
+ "on poweroff and hibernation\n");
+ }
+
port_info[0] = piix_port_info[ent->driver_data];
port_info[1] = piix_port_info[ent->driver_data];
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 88c242856dae..816738148a6f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -164,6 +164,11 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+static bool ata_sstatus_online(u32 sstatus)
+{
+ return (sstatus & 0xf) == 0x3;
+}
+
/**
* ata_link_next - link iteration helper
* @link: the previous link, NULL to start
@@ -1015,18 +1020,6 @@ static const char *sata_spd_string(unsigned int spd)
return spd_str[spd - 1];
}
-void ata_dev_disable(struct ata_device *dev)
-{
- if (ata_dev_enabled(dev)) {
- if (ata_msg_drv(dev->link->ap))
- ata_dev_printk(dev, KERN_WARNING, "disabled\n");
- ata_acpi_on_disable(dev);
- ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
- ATA_DNXFER_QUIET);
- dev->class++;
- }
-}
-
static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
{
struct ata_link *link = dev->link;
@@ -2239,6 +2232,40 @@ retry:
return rc;
}
+static int ata_do_link_spd_horkage(struct ata_device *dev)
+{
+ struct ata_link *plink = ata_dev_phys_link(dev);
+ u32 target, target_limit;
+
+ if (!sata_scr_valid(plink))
+ return 0;
+
+ if (dev->horkage & ATA_HORKAGE_1_5_GBPS)
+ target = 1;
+ else
+ return 0;
+
+ target_limit = (1 << target) - 1;
+
+ /* if already on stricter limit, no need to push further */
+ if (plink->sata_spd_limit <= target_limit)
+ return 0;
+
+ plink->sata_spd_limit = target_limit;
+
+ /* Request another EH round by returning -EAGAIN if link is
+ * going faster than the target speed. Forward progress is
+ * guaranteed by setting sata_spd_limit to target_limit above.
+ */
+ if (plink->sata_spd > target) {
+ ata_dev_printk(dev, KERN_INFO,
+ "applying link speed limit horkage to %s\n",
+ sata_spd_string(target));
+ return -EAGAIN;
+ }
+ return 0;
+}
+
static inline u8 ata_dev_knobble(struct ata_device *dev)
{
struct ata_port *ap = dev->link->ap;
@@ -2329,6 +2356,10 @@ int ata_dev_configure(struct ata_device *dev)
return 0;
}
+ rc = ata_do_link_spd_horkage(dev);
+ if (rc)
+ return rc;
+
/* let ACPI work its magic */
rc = ata_acpi_on_devcfg(dev);
if (rc)
@@ -2784,7 +2815,7 @@ int ata_bus_probe(struct ata_port *ap)
/* This is the last chance, better to slow
* down than lose it.
*/
- sata_down_spd_limit(&ap->link);
+ sata_down_spd_limit(&ap->link, 0);
ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
}
}
@@ -2880,21 +2911,27 @@ void ata_port_disable(struct ata_port *ap)
/**
* sata_down_spd_limit - adjust SATA spd limit downward
* @link: Link to adjust SATA spd limit for
+ * @spd_limit: Additional limit
*
* Adjust SATA spd limit of @link downward. Note that this
* function only adjusts the limit. The change must be applied
* using sata_set_spd().
*
+ * If @spd_limit is non-zero, the speed is limited to equal to or
+ * lower than @spd_limit if such speed is supported. If
+ * @spd_limit is slower than any supported speed, only the lowest
+ * supported speed is allowed.
+ *
* LOCKING:
* Inherited from caller.
*
* RETURNS:
* 0 on success, negative errno on failure
*/
-int sata_down_spd_limit(struct ata_link *link)
+int sata_down_spd_limit(struct ata_link *link, u32 spd_limit)
{
u32 sstatus, spd, mask;
- int rc, highbit;
+ int rc, bit;
if (!sata_scr_valid(link))
return -EOPNOTSUPP;
@@ -2903,7 +2940,7 @@ int sata_down_spd_limit(struct ata_link *link)
* If not, use cached value in link->sata_spd.
*/
rc = sata_scr_read(link, SCR_STATUS, &sstatus);
- if (rc == 0)
+ if (rc == 0 && ata_sstatus_online(sstatus))
spd = (sstatus >> 4) & 0xf;
else
spd = link->sata_spd;
@@ -2913,8 +2950,8 @@ int sata_down_spd_limit(struct ata_link *link)
return -EINVAL;
/* unconditionally mask off the highest bit */
- highbit = fls(mask) - 1;
- mask &= ~(1 << highbit);
+ bit = fls(mask) - 1;
+ mask &= ~(1 << bit);
/* Mask off all speeds higher than or equal to the current
* one. Force 1.5Gbps if current SPD is not available.
@@ -2928,6 +2965,15 @@ int sata_down_spd_limit(struct ata_link *link)
if (!mask)
return -EINVAL;
+ if (spd_limit) {
+ if (mask & ((1 << spd_limit) - 1))
+ mask &= (1 << spd_limit) - 1;
+ else {
+ bit = ffs(mask) - 1;
+ mask = 1 << bit;
+ }
+ }
+
link->sata_spd_limit = mask;
ata_link_printk(link, KERN_WARNING, "limiting SATA link speed to %s\n",
@@ -4215,6 +4261,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
/* Devices that do not need bridging limits applied */
{ "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, },
+ /* Devices which aren't very happy with higher link speeds */
+ { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, },
+
/* End Marker */
{ }
};
@@ -4709,8 +4758,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
/**
* ata_qc_new - Request an available ATA command, for queueing
- * @ap: Port associated with device @dev
- * @dev: Device from whom we request an available command structure
+ * @ap: target port
*
* LOCKING:
* None.
@@ -5175,7 +5223,7 @@ bool ata_phys_link_online(struct ata_link *link)
u32 sstatus;
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- (sstatus & 0xf) == 0x3)
+ ata_sstatus_online(sstatus))
return true;
return false;
}
@@ -5199,7 +5247,7 @@ bool ata_phys_link_offline(struct ata_link *link)
u32 sstatus;
if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 &&
- (sstatus & 0xf) != 0x3)
+ !ata_sstatus_online(sstatus))
return true;
return false;
}
@@ -5412,8 +5460,8 @@ void ata_dev_init(struct ata_device *dev)
dev->horkage = 0;
spin_unlock_irqrestore(ap->lock, flags);
- memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0,
- sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET);
+ memset((void *)dev + ATA_DEVICE_CLEAR_BEGIN, 0,
+ ATA_DEVICE_CLEAR_END - ATA_DEVICE_CLEAR_BEGIN);
dev->pio_mask = UINT_MAX;
dev->mwdma_mask = UINT_MAX;
dev->udma_mask = UINT_MAX;
@@ -6659,6 +6707,7 @@ EXPORT_SYMBOL_GPL(ata_id_c_string);
EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+EXPORT_SYMBOL_GPL(ata_pio_queue_task);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
EXPORT_SYMBOL_GPL(ata_timing_find_mode);
EXPORT_SYMBOL_GPL(ata_timing_compute);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 8147a8386370..ce2ef0475339 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -82,6 +82,10 @@ enum {
ATA_EH_FASTDRAIN_INTERVAL = 3000,
ATA_EH_UA_TRIES = 5,
+
+ /* probe speed down parameters, see ata_eh_schedule_probe() */
+ ATA_EH_PROBE_TRIAL_INTERVAL = 60000, /* 1 min */
+ ATA_EH_PROBE_TRIALS = 2,
};
/* The following table determines how we sequence resets. Each entry
@@ -1176,6 +1180,32 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc)
}
/**
+ * ata_dev_disable - disable ATA device
+ * @dev: ATA device to disable
+ *
+ * Disable @dev.
+ *
+ * Locking:
+ * EH context.
+ */
+void ata_dev_disable(struct ata_device *dev)
+{
+ if (!ata_dev_enabled(dev))
+ return;
+
+ if (ata_msg_drv(dev->link->ap))
+ ata_dev_printk(dev, KERN_WARNING, "disabled\n");
+ ata_acpi_on_disable(dev);
+ ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);
+ dev->class++;
+
+ /* From now till the next successful probe, ering is used to
+ * track probe failures. Clear accumulated device error info.
+ */
+ ata_ering_clear(&dev->ering);
+}
+
+/**
* ata_eh_detach_dev - detach ATA device
* @dev: ATA device to detach
*
@@ -1849,7 +1879,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
/* speed down? */
if (verdict & ATA_EH_SPDN_SPEED_DOWN) {
/* speed down SATA link speed if possible */
- if (sata_down_spd_limit(link) == 0) {
+ if (sata_down_spd_limit(link, 0) == 0) {
action |= ATA_EH_RESET;
goto done;
}
@@ -2601,11 +2631,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
}
if (try == max_tries - 1) {
- sata_down_spd_limit(link);
+ sata_down_spd_limit(link, 0);
if (slave)
- sata_down_spd_limit(slave);
+ sata_down_spd_limit(slave, 0);
} else if (rc == -EPIPE)
- sata_down_spd_limit(failed_link);
+ sata_down_spd_limit(failed_link, 0);
if (hardreset)
reset = hardreset;
@@ -2744,6 +2774,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link,
readid_flags, dev->id);
switch (rc) {
case 0:
+ /* clear error info accumulated during probe */
+ ata_ering_clear(&dev->ering);
new_mask |= 1 << dev->devno;
break;
case -ENOENT:
@@ -2947,9 +2979,24 @@ static int ata_eh_skip_recovery(struct ata_link *link)
return 1;
}
+static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg)
+{
+ u64 interval = msecs_to_jiffies(ATA_EH_PROBE_TRIAL_INTERVAL);
+ u64 now = get_jiffies_64();
+ int *trials = void_arg;
+
+ if (ent->timestamp < now - min(now, interval))
+ return -1;
+
+ (*trials)++;
+ return 0;
+}
+
static int ata_eh_schedule_probe(struct ata_device *dev)
{
struct ata_eh_context *ehc = &dev->link->eh_context;
+ struct ata_link *link = ata_dev_phys_link(dev);
+ int trials = 0;
if (!(ehc->i.probe_mask & (1 << dev->devno)) ||
(ehc->did_probe_mask & (1 << dev->devno)))
@@ -2962,6 +3009,25 @@ static int ata_eh_schedule_probe(struct ata_device *dev)
ehc->saved_xfer_mode[dev->devno] = 0;
ehc->saved_ncq_enabled &= ~(1 << dev->devno);
+ /* Record and count probe trials on the ering. The specific
+ * error mask used is irrelevant. Because a successful device
+ * detection clears the ering, this count accumulates only if
+ * there are consecutive failed probes.
+ *
+ * If the count is equal to or higher than ATA_EH_PROBE_TRIALS
+ * in the last ATA_EH_PROBE_TRIAL_INTERVAL, link speed is
+ * forced to 1.5Gbps.
+ *
+ * This is to work around cases where failed link speed
+ * negotiation results in device misdetection leading to
+ * infinite DEVXCHG or PHRDY CHG events.
+ */
+ ata_ering_record(&dev->ering, 0, AC_ERR_OTHER);
+ ata_ering_map(&dev->ering, ata_count_probe_trials_cb, &trials);
+
+ if (trials > ATA_EH_PROBE_TRIALS)
+ sata_down_spd_limit(link, 1);
+
return 1;
}
@@ -2969,7 +3035,11 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
{
struct ata_eh_context *ehc = &dev->link->eh_context;
- ehc->tries[dev->devno]--;
+ /* -EAGAIN from EH routine indicates retry without prejudice.
+ * The requester is responsible for ensuring forward progress.
+ */
+ if (err != -EAGAIN)
+ ehc->tries[dev->devno]--;
switch (err) {
case -ENODEV:
@@ -2979,12 +3049,13 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
/* give it just one more chance */
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
case -EIO:
- if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) {
+ if (ehc->tries[dev->devno] == 1) {
/* This is the last chance, better to slow
* down than lose it.
*/
- sata_down_spd_limit(ata_dev_phys_link(dev));
- ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+ sata_down_spd_limit(ata_dev_phys_link(dev), 0);
+ if (dev->pio_mode > XFER_PIO_0)
+ ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
}
}
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 98ca07a2db87..619f2c33950e 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -729,7 +729,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
if (tries) {
/* consecutive revalidation failures? speed down */
if (reval_failed)
- sata_down_spd_limit(link);
+ sata_down_spd_limit(link, 0);
else
reval_failed = 1;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index a1a6e6298c33..b9747fa59e54 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -46,6 +46,7 @@
#include <linux/libata.h>
#include <linux/hdreg.h>
#include <linux/uaccess.h>
+#include <linux/suspend.h>
#include "libata.h"
@@ -414,6 +415,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
/**
* ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
+ * @ap: target port
* @sdev: SCSI device to get identify data for
* @arg: User buffer area for identify data
*
@@ -1303,6 +1305,17 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
} else {
+ /* Some odd clown BIOSen issue spindown on power off (ACPI S4
+ * or S5) causing some drives to spin up and down again.
+ */
+ if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) &&
+ system_state == SYSTEM_POWER_OFF)
+ goto skip;
+
+ if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) &&
+ system_entering_hibernation())
+ goto skip;
+
/* XXX: This is for backward compatibility, will be
* removed. Read Documentation/feature-removal-schedule.txt
* for more info.
@@ -1326,8 +1339,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
scmd->scsi_done = qc->scsidone;
qc->scsidone = ata_delayed_done;
}
- scmd->result = SAM_STAT_GOOD;
- return 1;
+ goto skip;
}
/* Issue ATA STANDBY IMMEDIATE command */
@@ -1343,10 +1355,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
return 0;
-invalid_fld:
+ invalid_fld:
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */
return 1;
+ skip:
+ scmd->result = SAM_STAT_GOOD;
+ return 1;
}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 5a4aad123c42..714cb046b594 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -773,18 +773,32 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
else
iowrite32_rep(data_addr, buf, words);
+ /* Transfer trailing bytes, if any */
if (unlikely(slop)) {
- __le32 pad;
+ unsigned char pad[4];
+
+ /* Point buf to the tail of buffer */
+ buf += buflen - slop;
+
+ /*
+ * Use io*_rep() accessors here as well to avoid pointlessly
+ * swapping bytes to and fro on the big endian machines...
+ */
if (rw == READ) {
- pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
- memcpy(buf + buflen - slop, &pad, slop);
+ if (slop < 3)
+ ioread16_rep(data_addr, pad, 1);
+ else
+ ioread32_rep(data_addr, pad, 1);
+ memcpy(buf, pad, slop);
} else {
- memcpy(&pad, buf + buflen - slop, slop);
- iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ memcpy(pad, buf, slop);
+ if (slop < 3)
+ iowrite16_rep(data_addr, pad, 1);
+ else
+ iowrite32_rep(data_addr, pad, 1);
}
- words++;
}
- return words << 2;
+ return (buflen + 1) & ~1;
}
EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
@@ -1322,7 +1336,7 @@ fsm_start:
* condition. Mark hint.
*/
ata_ehi_push_desc(ehi, "ST-ATA: "
- "DRQ=1 with device error, "
+ "DRQ=0 without device error, "
"dev_stat 0x%X", status);
qc->err_mask |= AC_ERR_HSM |
AC_ERR_NODEV_HINT;
@@ -1358,6 +1372,16 @@ fsm_start:
qc->err_mask |= AC_ERR_HSM;
}
+ /* There are oddball controllers with
+ * status register stuck at 0x7f and
+ * lbal/m/h at zero which makes it
+ * pass all other presence detection
+ * mechanisms we have. Set NODEV_HINT
+ * for it. Kernel bz#7241.
+ */
+ if (status == 0x7f)
+ qc->err_mask |= AC_ERR_NODEV_HINT;
+
/* ata_pio_sectors() might change the
* state to HSM_ST_LAST. so, the state
* is changed after ata_pio_sectors().
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index fe2839e58774..89a1e0018e71 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -79,9 +79,6 @@ 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_pio_queue_task(struct ata_port *ap, void *data,
- unsigned long delay);
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,
@@ -100,7 +97,7 @@ extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
extern int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
unsigned int readid_flags);
extern int ata_dev_configure(struct ata_device *dev);
-extern int sata_down_spd_limit(struct ata_link *link);
+extern int sata_down_spd_limit(struct ata_link *link, u32 spd_limit);
extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel);
extern void ata_sg_clean(struct ata_queued_cmd *qc);
extern void ata_qc_free(struct ata_queued_cmd *qc);
@@ -160,6 +157,7 @@ extern void ata_scsi_error(struct Scsi_Host *host);
extern void ata_port_wait_eh(struct ata_port *ap);
extern void ata_eh_fastdrain_timerfn(unsigned long arg);
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
+extern void ata_dev_disable(struct ata_device *dev);
extern void ata_eh_detach_dev(struct ata_device *dev);
extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
unsigned int action);
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 63719ab9ea44..115b1cd6dcf5 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -24,7 +24,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_amd"
-#define DRV_VERSION "0.3.11"
+#define DRV_VERSION "0.4.1"
/**
* timing_setup - shared timing computation and load
@@ -145,6 +145,13 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
return ata_sff_prereset(link, deadline);
}
+/**
+ * amd_cable_detect - report cable type
+ * @ap: port
+ *
+ * AMD controller/BIOS setups record the cable type in word 0x42
+ */
+
static int amd_cable_detect(struct ata_port *ap)
{
static const u32 bitmask[2] = {0x03, 0x0C};
@@ -158,6 +165,40 @@ static int amd_cable_detect(struct ata_port *ap)
}
/**
+ * amd_fifo_setup - set the PIO FIFO for ATA/ATAPI
+ * @ap: ATA interface
+ * @adev: ATA device
+ *
+ * Set the PCI fifo for this device according to the devices present
+ * on the bus at this point in time. We need to turn the post write buffer
+ * off for ATAPI devices as we may need to issue a word sized write to the
+ * device as the final I/O
+ */
+
+static void amd_fifo_setup(struct ata_port *ap)
+{
+ struct ata_device *adev;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ static const u8 fifobit[2] = { 0xC0, 0x30};
+ u8 fifo = fifobit[ap->port_no];
+ u8 r;
+
+
+ ata_for_each_dev(adev, &ap->link, ENABLED) {
+ if (adev->class == ATA_DEV_ATAPI)
+ fifo = 0;
+ }
+ if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */
+ fifo = 0;
+
+ /* On the later chips the read prefetch bits become no-op bits */
+ pci_read_config_byte(pdev, 0x41, &r);
+ r &= ~fifobit[ap->port_no];
+ r |= fifo;
+ pci_write_config_byte(pdev, 0x41, r);
+}
+
+/**
* amd33_set_piomode - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
@@ -167,21 +208,25 @@ static int amd_cable_detect(struct ata_port *ap)
static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 1);
}
static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 2);
}
static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 3);
}
static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
+ amd_fifo_setup(ap);
timing_setup(ap, adev, 0x40, adev->pio_mode, 4);
}
@@ -397,6 +442,16 @@ static struct ata_port_operations nv133_port_ops = {
.set_dmamode = nv133_set_dmamode,
};
+static void amd_clear_fifo(struct pci_dev *pdev)
+{
+ u8 fifo;
+ /* Disable the FIFO, the FIFO logic will re-enable it as
+ appropriate */
+ pci_read_config_byte(pdev, 0x41, &fifo);
+ fifo &= 0x0F;
+ pci_write_config_byte(pdev, 0x41, fifo);
+}
+
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info[10] = {
@@ -503,14 +558,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (type < 3)
ata_pci_bmdma_clear_simplex(pdev);
-
- /* Check for AMD7411 */
- if (type == 3)
- /* FIFO is broken */
- pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
- else
- pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
-
+ if (pdev->vendor == PCI_VENDOR_ID_AMD)
+ amd_clear_fifo(pdev);
/* Cable detection on Nvidia chips doesn't work too well,
* cache BIOS programmed UDMA mode.
*/
@@ -536,18 +585,11 @@ static int amd_reinit_one(struct pci_dev *pdev)
return rc;
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);
+ amd_clear_fifo(pdev);
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 ||
pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401)
ata_pci_bmdma_clear_simplex(pdev);
}
-
ata_host_resume(host);
return 0;
}
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index cf9e9848f8b5..d7bc925c524d 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -45,8 +45,6 @@ static const struct portinfo pata_icside_portinfo_v6_2 = {
.stepping = 6,
};
-#define PATA_ICSIDE_MAX_SG 128
-
struct pata_icside_state {
void __iomem *irq_port;
void __iomem *ioc_base;
@@ -57,7 +55,6 @@ struct pata_icside_state {
u8 disabled;
unsigned int speed[ATA_MAX_DEVICES];
} port[2];
- struct scatterlist sg[PATA_ICSIDE_MAX_SG];
};
struct pata_icside_info {
@@ -222,9 +219,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pata_icside_state *state = ap->host->private_data;
- struct scatterlist *sg, *rsg = state->sg;
unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE;
- unsigned int si;
/*
* We are simplex; BUG if we try to fiddle with DMA
@@ -233,20 +228,12 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
BUG_ON(dma_channel_active(state->dma));
/*
- * Copy ATAs scattered sg list into a contiguous array of sg
- */
- for_each_sg(qc->sg, sg, qc->n_elem, si) {
- memcpy(rsg, sg, sizeof(*sg));
- rsg++;
- }
-
- /*
* Route the DMA signals to the correct interface
*/
writeb(state->port[ap->port_no].port_sel, state->ioc_base);
set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]);
- set_dma_sg(state->dma, state->sg, rsg - state->sg);
+ set_dma_sg(state->dma, qc->sg, qc->n_elem);
set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ);
/* issue r/w command */
@@ -306,8 +293,8 @@ static int icside_dma_init(struct pata_icside_info *info)
static struct scsi_host_template pata_icside_sht = {
ATA_BASE_SHT(DRV_NAME),
- .sg_tablesize = PATA_ICSIDE_MAX_SG,
- .dma_boundary = ~0, /* no dma boundaries */
+ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
+ .dma_boundary = IOMD_DMA_BOUNDARY,
};
static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index f1bb2f9fecbf..b05b86a912c5 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -557,6 +557,9 @@ static unsigned int it821x_read_id(struct ata_device *adev,
id[83] |= 0x4400; /* Word 83 is valid and LBA48 */
id[86] |= 0x0400; /* LBA48 on */
id[ATA_ID_MAJOR_VER] |= 0x1F;
+ /* Clear the serial number because it's different each boot
+ which breaks validation on resume */
+ memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN);
}
return err_mask;
}
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 6c1d778b63a9..e3bc1b436284 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -283,9 +283,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
unsigned char *buf, unsigned int buflen, int rw)
{
- if (ata_id_has_dword_io(dev->id)) {
+ int slop = buflen & 3;
+ /* 32bit I/O capable *and* we need to write a whole number of dwords */
+ if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) {
struct ata_port *ap = dev->link->ap;
- int slop = buflen & 3;
unsigned long flags;
local_irq_save(flags);
@@ -735,7 +736,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf,
struct ata_port *ap = adev->link->ap;
int slop = buflen & 3;
- if (ata_id_has_dword_io(adev->id)) {
+ if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) {
if (rw == WRITE)
iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 3080f371222c..f1b26f7c8e4d 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -12,7 +12,7 @@
*
* Probe code based on drivers/ide/legacy/qd65xx.c
* Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
*/
#include <linux/kernel.h>
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
index c2e6fb9f2ef9..fbfee1bd85ff 100644
--- a/drivers/ata/pata_rb532_cf.c
+++ b/drivers/ata/pata_rb532_cf.c
@@ -48,65 +48,11 @@
struct rb532_cf_info {
void __iomem *iobase;
unsigned int gpio_line;
- int frozen;
unsigned int irq;
};
/* ------------------------------------------------------------------------ */
-static inline void rb532_pata_finish_io(struct ata_port *ap)
-{
- struct ata_host *ah = ap->host;
- struct rb532_cf_info *info = ah->private_data;
-
- /* FIXME: Keep previous delay. If this is merely a fence then
- ata_sff_sync might be sufficient. */
- ata_sff_dma_pause(ap);
- ndelay(RB500_CF_IO_DELAY);
-
- set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
-}
-
-static void rb532_pata_exec_command(struct ata_port *ap,
- const struct ata_taskfile *tf)
-{
- writeb(tf->command, ap->ioaddr.command_addr);
- rb532_pata_finish_io(ap);
-}
-
-static unsigned int rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
-{
- struct ata_port *ap = adev->link->ap;
- void __iomem *ioaddr = ap->ioaddr.data_addr;
- int retlen = buflen;
-
- if (write_data) {
- for (; buflen > 0; buflen--, buf++)
- writeb(*buf, ioaddr);
- } else {
- for (; buflen > 0; buflen--, buf++)
- *buf = readb(ioaddr);
- }
-
- rb532_pata_finish_io(adev->link->ap);
- return retlen;
-}
-
-static void rb532_pata_freeze(struct ata_port *ap)
-{
- struct rb532_cf_info *info = ap->host->private_data;
-
- info->frozen = 1;
-}
-
-static void rb532_pata_thaw(struct ata_port *ap)
-{
- struct rb532_cf_info *info = ap->host->private_data;
-
- info->frozen = 0;
-}
-
static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
{
struct ata_host *ah = dev_instance;
@@ -114,8 +60,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
if (gpio_get_value(info->gpio_line)) {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
- if (!info->frozen)
- ata_sff_interrupt(info->irq, dev_instance);
+ ata_sff_interrupt(info->irq, dev_instance);
} else {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
}
@@ -125,10 +70,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
static struct ata_port_operations rb532_pata_port_ops = {
.inherits = &ata_sff_port_ops,
- .sff_exec_command = rb532_pata_exec_command,
- .sff_data_xfer = rb532_pata_data_xfer,
- .freeze = rb532_pata_freeze,
- .thaw = rb532_pata_thaw,
+ .sff_data_xfer = ata_sff_data_xfer32,
};
/* ------------------------------------------------------------------------ */
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 681169c9c640..ba556d3e6963 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -86,6 +86,10 @@ enum {
VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */
};
+enum {
+ VIA_IDFLAG_SINGLE = (1 << 0), /* single channel controller) */
+};
+
/*
* VIA SouthBridge chips.
*/
@@ -97,12 +101,17 @@ static const struct via_isa_bridge {
u8 rev_max;
u16 flags;
} via_isa_bridges[] = {
+ { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA },
{ "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 |
VIA_BAD_AST | VIA_SATA_PATA },
+ { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "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 | VIA_SATA_PATA },
- { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
+ { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES },
+ { "vt6415", PCI_DEVICE_ID_VIA_6415, 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 },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -122,6 +131,8 @@ static const struct via_isa_bridge {
{ "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
+ { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f,
+ VIA_UDMA_133 | VIA_BAD_AST },
{ NULL }
};
@@ -460,6 +471,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
u8 enable;
u32 timing;
+ unsigned long flags = id->driver_data;
int rc;
if (!printed_version++)
@@ -469,9 +481,13 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc)
return rc;
+ if (flags & VIA_IDFLAG_SINGLE)
+ ppi[1] = &ata_dummy_port_info;
+
/* To find out how the IDE will behave and what features we
actually have to look at the bridge not the IDE controller */
- for (config = via_isa_bridges; config->id; config++)
+ for (config = via_isa_bridges; config->id != PCI_DEVICE_ID_VIA_ANON;
+ config++)
if ((isa = pci_get_device(PCI_VENDOR_ID_VIA +
!!(config->flags & VIA_BAD_ID),
config->id, NULL))) {
@@ -482,10 +498,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_dev_put(isa);
}
- if (!config->id) {
- printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n");
- return -ENODEV;
- }
pci_dev_put(isa);
if (!(config->flags & VIA_NO_ENABLES)) {
@@ -582,11 +594,13 @@ static int via_reinit_one(struct pci_dev *pdev)
#endif
static const struct pci_device_id via[] = {
+ { PCI_VDEVICE(VIA, 0x0415), },
{ PCI_VDEVICE(VIA, 0x0571), },
{ PCI_VDEVICE(VIA, 0x0581), },
{ PCI_VDEVICE(VIA, 0x1571), },
{ PCI_VDEVICE(VIA, 0x3164), },
{ PCI_VDEVICE(VIA, 0x5324), },
+ { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE },
{ },
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 86918634a4c5..892be326e1d3 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -31,12 +31,6 @@
*
* --> Complete a full errata audit for all chipsets to identify others.
*
- * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it).
- *
- * --> Investigate problems with PCI Message Signalled Interrupts (MSI).
- *
- * --> Cache frequently-accessed registers in mv_port_priv to reduce overhead.
- *
* --> Develop a low-power-consumption strategy, and implement it.
*
* --> [Experiment, low priority] Investigate interrupt coalescing.
@@ -72,7 +66,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.24"
+#define DRV_VERSION "1.26"
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -124,14 +118,15 @@ enum {
MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
- ATA_FLAG_PIO_POLLING,
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
- MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
+ MV_GEN_I_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI,
- MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ MV_GEN_II_FLAGS = MV_COMMON_FLAGS | MV_FLAG_IRQ_COALESCE |
ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ | ATA_FLAG_AN,
+ ATA_FLAG_NCQ,
+
+ MV_GEN_IIE_FLAGS = MV_GEN_II_FLAGS | ATA_FLAG_AN,
CRQB_FLAG_READ = (1 << 0),
CRQB_TAG_SHIFT = 1,
@@ -350,8 +345,12 @@ enum {
EDMA_ARB_CFG_OFS = 0x38,
EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */
+ EDMA_UNKNOWN_RSVD_OFS = 0x6C, /* GenIIe unknown/reserved */
- GEN_II_NCQ_MAX_SECTORS = 256, /* max sects/io on Gen2 w/NCQ */
+ BMDMA_CMD_OFS = 0x224, /* bmdma command register */
+ BMDMA_STATUS_OFS = 0x228, /* bmdma status register */
+ BMDMA_PRD_LOW_OFS = 0x22c, /* bmdma PRD addr 31:0 */
+ BMDMA_PRD_HIGH_OFS = 0x230, /* bmdma PRD addr 63:32 */
/* Host private flags (hp_flags) */
MV_HP_FLAG_MSI = (1 << 0),
@@ -371,6 +370,7 @@ enum {
MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */
MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */
MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */
+ MV_PP_FLAG_FAKE_ATA_BUSY = (1 << 4), /* ignore initial ATA_DRDY */
};
#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
@@ -439,6 +439,18 @@ struct mv_sg {
__le32 reserved;
};
+/*
+ * We keep a local cache of a few frequently accessed port
+ * registers here, to avoid having to read them (very slow)
+ * when switching between EDMA and non-EDMA modes.
+ */
+struct mv_cached_regs {
+ u32 fiscfg;
+ u32 ltmode;
+ u32 haltcond;
+ u32 unknown_rsvd;
+};
+
struct mv_port_priv {
struct mv_crqb *crqb;
dma_addr_t crqb_dma;
@@ -451,6 +463,7 @@ struct mv_port_priv {
unsigned int resp_idx;
u32 pp_flags;
+ struct mv_cached_regs cached;
unsigned int delayed_eh_pmp_map;
};
@@ -541,7 +554,7 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
static int mv_stop_edma(struct ata_port *ap);
static int mv_stop_edma_engine(void __iomem *port_mmio);
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq);
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma);
static void mv_pmp_select(struct ata_port *ap, int pmp);
static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
@@ -552,6 +565,14 @@ static void mv_pmp_error_handler(struct ata_port *ap);
static void mv_process_crpb_entries(struct ata_port *ap,
struct mv_port_priv *pp);
+static void mv_sff_irq_clear(struct ata_port *ap);
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc);
+static void mv_bmdma_setup(struct ata_queued_cmd *qc);
+static void mv_bmdma_start(struct ata_queued_cmd *qc);
+static void mv_bmdma_stop(struct ata_queued_cmd *qc);
+static u8 mv_bmdma_status(struct ata_port *ap);
+static u8 mv_sff_check_status(struct ata_port *ap);
+
/* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
* because we have to allow room for worst case splitting of
* PRDs for 64K boundaries in mv_fill_sg().
@@ -599,6 +620,14 @@ static struct ata_port_operations mv6_ops = {
.pmp_softreset = mv_softreset,
.softreset = mv_softreset,
.error_handler = mv_pmp_error_handler,
+
+ .sff_check_status = mv_sff_check_status,
+ .sff_irq_clear = mv_sff_irq_clear,
+ .check_atapi_dma = mv_check_atapi_dma,
+ .bmdma_setup = mv_bmdma_setup,
+ .bmdma_start = mv_bmdma_start,
+ .bmdma_stop = mv_bmdma_stop,
+ .bmdma_status = mv_bmdma_status,
};
static struct ata_port_operations mv_iie_ops = {
@@ -609,53 +638,49 @@ static struct ata_port_operations mv_iie_ops = {
static const struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
- .flags = MV_COMMON_FLAGS,
+ .flags = MV_GEN_I_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_508x */
- .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_5080 */
- .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_604x */
- .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ,
+ .flags = MV_GEN_II_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_608x */
- .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_II_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_6042 */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_7042 */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_soc */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
@@ -669,8 +694,8 @@ static const struct pci_device_id mv_pci_tbl[] = {
{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
/* RocketRAID 1720/174x have different identifiers */
{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
- { PCI_VDEVICE(TTI, 0x1740), chip_508x },
- { PCI_VDEVICE(TTI, 0x1742), chip_508x },
+ { PCI_VDEVICE(TTI, 0x1740), chip_6042 },
+ { PCI_VDEVICE(TTI, 0x1742), chip_6042 },
{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
@@ -800,6 +825,44 @@ static inline int mv_get_hc_count(unsigned long port_flags)
return ((port_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
}
+/**
+ * mv_save_cached_regs - (re-)initialize cached port registers
+ * @ap: the port whose registers we are caching
+ *
+ * Initialize the local cache of port registers,
+ * so that reading them over and over again can
+ * be avoided on the hotter paths of this driver.
+ * This saves a few microseconds each time we switch
+ * to/from EDMA mode to perform (eg.) a drive cache flush.
+ */
+static void mv_save_cached_regs(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+
+ pp->cached.fiscfg = readl(port_mmio + FISCFG_OFS);
+ pp->cached.ltmode = readl(port_mmio + LTMODE_OFS);
+ pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+ pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD_OFS);
+}
+
+/**
+ * mv_write_cached_reg - write to a cached port register
+ * @addr: hardware address of the register
+ * @old: pointer to cached value of the register
+ * @new: new value for the register
+ *
+ * Write a new value to a cached register,
+ * but only if the value is different from before.
+ */
+static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new)
+{
+ if (new != *old) {
+ *old = new;
+ writel(new, addr);
+ }
+}
+
static void mv_set_edma_ptrs(void __iomem *port_mmio,
struct mv_host_priv *hpriv,
struct mv_port_priv *pp)
@@ -858,8 +921,32 @@ static void mv_enable_port_irqs(struct ata_port *ap,
mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
}
+static void mv_clear_and_enable_port_irqs(struct ata_port *ap,
+ void __iomem *port_mmio,
+ unsigned int port_irqs)
+{
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ int hardport = mv_hardport_from_port(ap->port_no);
+ void __iomem *hc_mmio = mv_hc_base_from_port(
+ mv_host_base(ap->host), ap->port_no);
+ u32 hc_irq_cause;
+
+ /* clear EDMA event indicators, if any */
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+ /* clear pending irq events */
+ hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
+ writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+
+ /* clear FIS IRQ Cause */
+ if (IS_GEN_IIE(hpriv))
+ writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+
+ mv_enable_port_irqs(ap, port_irqs);
+}
+
/**
- * mv_start_dma - Enable eDMA engine
+ * mv_start_edma - Enable eDMA engine
* @base: port base address
* @pp: port private data
*
@@ -869,7 +956,7 @@ static void mv_enable_port_irqs(struct ata_port *ap,
* LOCKING:
* Inherited from caller.
*/
-static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
+static void mv_start_edma(struct ata_port *ap, void __iomem *port_mmio,
struct mv_port_priv *pp, u8 protocol)
{
int want_ncq = (protocol == ATA_PROT_NCQ);
@@ -881,30 +968,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
}
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
struct mv_host_priv *hpriv = ap->host->private_data;
- int hardport = mv_hardport_from_port(ap->port_no);
- void __iomem *hc_mmio = mv_hc_base_from_port(
- mv_host_base(ap->host), hardport);
- u32 hc_irq_cause, ipending;
-
- /* clear EDMA event indicators, if any */
- writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
-
- /* clear EDMA interrupt indicator, if any */
- hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
- ipending = (DEV_IRQ | DMA_IRQ) << hardport;
- if (hc_irq_cause & ipending) {
- writelfl(hc_irq_cause & ~ipending,
- hc_mmio + HC_IRQ_CAUSE_OFS);
- }
- mv_edma_cfg(ap, want_ncq);
-
- /* clear FIS IRQ Cause */
- if (IS_GEN_IIE(hpriv))
- writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+ mv_edma_cfg(ap, want_ncq, 1);
mv_set_edma_ptrs(port_mmio, hpriv, pp);
- mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ);
+ mv_clear_and_enable_port_irqs(ap, port_mmio, DONE_IRQ|ERR_IRQ);
writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
@@ -962,6 +1030,7 @@ static int mv_stop_edma(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
+ int err = 0;
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
return 0;
@@ -969,9 +1038,10 @@ static int mv_stop_edma(struct ata_port *ap)
mv_wait_for_edma_empty_idle(ap);
if (mv_stop_edma_engine(port_mmio)) {
ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
- return -EIO;
+ err = -EIO;
}
- return 0;
+ mv_edma_cfg(ap, 0, 0);
+ return err;
}
#ifdef ATA_DEBUG
@@ -1099,20 +1169,12 @@ static void mv6_dev_config(struct ata_device *adev)
*
* Gen-II does not support NCQ over a port multiplier
* (no FIS-based switching).
- *
- * We don't have hob_nsect when doing NCQ commands on Gen-II.
- * See mv_qc_prep() for more info.
*/
if (adev->flags & ATA_DFLAG_NCQ) {
if (sata_pmp_attached(adev->link->ap)) {
adev->flags &= ~ATA_DFLAG_NCQ;
ata_dev_printk(adev, KERN_INFO,
"NCQ disabled for command-based switching\n");
- } else if (adev->max_sectors > GEN_II_NCQ_MAX_SECTORS) {
- adev->max_sectors = GEN_II_NCQ_MAX_SECTORS;
- ata_dev_printk(adev, KERN_INFO,
- "max_sectors limited to %u for NCQ\n",
- adev->max_sectors);
}
}
}
@@ -1148,35 +1210,33 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
return ATA_DEFER_PORT;
}
-static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs)
+static void mv_config_fbs(struct ata_port *ap, int want_ncq, int want_fbs)
{
- u32 new_fiscfg, old_fiscfg;
- u32 new_ltmode, old_ltmode;
- u32 new_haltcond, old_haltcond;
+ struct mv_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio;
- old_fiscfg = readl(port_mmio + FISCFG_OFS);
- old_ltmode = readl(port_mmio + LTMODE_OFS);
- old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+ u32 fiscfg, *old_fiscfg = &pp->cached.fiscfg;
+ u32 ltmode, *old_ltmode = &pp->cached.ltmode;
+ u32 haltcond, *old_haltcond = &pp->cached.haltcond;
- new_fiscfg = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
- new_ltmode = old_ltmode & ~LTMODE_BIT8;
- new_haltcond = old_haltcond | EDMA_ERR_DEV;
+ ltmode = *old_ltmode & ~LTMODE_BIT8;
+ haltcond = *old_haltcond | EDMA_ERR_DEV;
if (want_fbs) {
- new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC;
- new_ltmode = old_ltmode | LTMODE_BIT8;
+ fiscfg = *old_fiscfg | FISCFG_SINGLE_SYNC;
+ ltmode = *old_ltmode | LTMODE_BIT8;
if (want_ncq)
- new_haltcond &= ~EDMA_ERR_DEV;
+ haltcond &= ~EDMA_ERR_DEV;
else
- new_fiscfg |= FISCFG_WAIT_DEV_ERR;
+ fiscfg |= FISCFG_WAIT_DEV_ERR;
+ } else {
+ fiscfg = *old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
}
- if (new_fiscfg != old_fiscfg)
- writelfl(new_fiscfg, port_mmio + FISCFG_OFS);
- if (new_ltmode != old_ltmode)
- writelfl(new_ltmode, port_mmio + LTMODE_OFS);
- if (new_haltcond != old_haltcond)
- writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS);
+ port_mmio = mv_ap_base(ap);
+ mv_write_cached_reg(port_mmio + FISCFG_OFS, old_fiscfg, fiscfg);
+ mv_write_cached_reg(port_mmio + LTMODE_OFS, old_ltmode, ltmode);
+ mv_write_cached_reg(port_mmio + EDMA_HALTCOND_OFS, old_haltcond, haltcond);
}
static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
@@ -1194,7 +1254,31 @@ static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
}
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
+/**
+ * mv_bmdma_enable - set a magic bit on GEN_IIE to allow bmdma
+ * @ap: Port being initialized
+ *
+ * There are two DMA modes on these chips: basic DMA, and EDMA.
+ *
+ * Bit-0 of the "EDMA RESERVED" register enables/disables use
+ * of basic DMA on the GEN_IIE versions of the chips.
+ *
+ * This bit survives EDMA resets, and must be set for basic DMA
+ * to function, and should be cleared when EDMA is active.
+ */
+static void mv_bmdma_enable_iie(struct ata_port *ap, int enable_bmdma)
+{
+ struct mv_port_priv *pp = ap->private_data;
+ u32 new, *old = &pp->cached.unknown_rsvd;
+
+ if (enable_bmdma)
+ new = *old | 1;
+ else
+ new = *old & ~1;
+ mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD_OFS, old, new);
+}
+
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma)
{
u32 cfg;
struct mv_port_priv *pp = ap->private_data;
@@ -1203,7 +1287,8 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
/* set up non-NCQ EDMA configuration */
cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */
- pp->pp_flags &= ~MV_PP_FLAG_FBS_EN;
+ pp->pp_flags &=
+ ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
if (IS_GEN_I(hpriv))
cfg |= (1 << 8); /* enab config burst size mask */
@@ -1224,7 +1309,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
*/
want_fbs &= want_ncq;
- mv_config_fbs(port_mmio, want_ncq, want_fbs);
+ mv_config_fbs(ap, want_ncq, want_fbs);
if (want_fbs) {
pp->pp_flags |= MV_PP_FLAG_FBS_EN;
@@ -1232,18 +1317,20 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
}
cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */
- cfg |= (1 << 22); /* enab 4-entry host queue cache */
- if (!IS_SOC(hpriv))
- cfg |= (1 << 18); /* enab early completion */
+ if (want_edma) {
+ cfg |= (1 << 22); /* enab 4-entry host queue cache */
+ if (!IS_SOC(hpriv))
+ cfg |= (1 << 18); /* enab early completion */
+ }
if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
+ mv_bmdma_enable_iie(ap, !want_edma);
}
if (want_ncq) {
cfg |= EDMA_CFG_NCQ;
pp->pp_flags |= MV_PP_FLAG_NCQ_EN;
- } else
- pp->pp_flags &= ~MV_PP_FLAG_NCQ_EN;
+ }
writelfl(cfg, port_mmio + EDMA_CFG_OFS);
}
@@ -1327,6 +1414,8 @@ static int mv_port_start(struct ata_port *ap)
pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0];
}
}
+ mv_save_cached_regs(ap);
+ mv_edma_cfg(ap, 0, 0);
return 0;
out_port_free_dma_mem:
@@ -1375,12 +1464,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
u32 offset = addr & 0xffff;
u32 len = sg_len;
- if ((offset + sg_len > 0x10000))
+ if (offset + len > 0x10000)
len = 0x10000 - offset;
mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
mv_sg->flags_size = cpu_to_le32(len & 0xffff);
+ mv_sg->reserved = 0;
sg_len -= len;
addr += len;
@@ -1392,6 +1482,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
if (likely(last_sg))
last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+ mb(); /* ensure data structure is visible to the chipset */
}
static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
@@ -1402,6 +1493,147 @@ static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
}
/**
+ * mv_sff_irq_clear - Clear hardware interrupt after DMA.
+ * @ap: Port associated with this ATA transaction.
+ *
+ * We need this only for ATAPI bmdma transactions,
+ * as otherwise we experience spurious interrupts
+ * after libata-sff handles the bmdma interrupts.
+ */
+static void mv_sff_irq_clear(struct ata_port *ap)
+{
+ mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), ERR_IRQ);
+}
+
+/**
+ * mv_check_atapi_dma - Filter ATAPI cmds which are unsuitable for DMA.
+ * @qc: queued command to check for chipset/DMA compatibility.
+ *
+ * The bmdma engines cannot handle speculative data sizes
+ * (bytecount under/over flow). So only allow DMA for
+ * data transfer commands with known data sizes.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+
+ if (scmd) {
+ switch (scmd->cmnd[0]) {
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_12:
+ case GPCMD_READ_CD:
+ case GPCMD_SEND_DVD_STRUCTURE:
+ case GPCMD_SEND_CUE_SHEET:
+ return 0; /* DMA is safe */
+ }
+ }
+ return -EOPNOTSUPP; /* use PIO instead */
+}
+
+/**
+ * mv_bmdma_setup - Set up BMDMA transaction
+ * @qc: queued command to prepare DMA for.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+
+ mv_fill_sg(qc);
+
+ /* clear all DMA cmd bits */
+ writel(0, port_mmio + BMDMA_CMD_OFS);
+
+ /* load PRD table addr. */
+ writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16,
+ port_mmio + BMDMA_PRD_HIGH_OFS);
+ writelfl(pp->sg_tbl_dma[qc->tag],
+ port_mmio + BMDMA_PRD_LOW_OFS);
+
+ /* issue r/w command */
+ ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+/**
+ * mv_bmdma_start - Start a BMDMA transaction
+ * @qc: queued command to start DMA on.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+ u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START;
+
+ /* start host DMA transaction */
+ writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+}
+
+/**
+ * mv_bmdma_stop - Stop BMDMA transfer
+ * @qc: queued command to stop DMA on.
+ *
+ * Clears the ATA_DMA_START flag in the bmdma control register
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 cmd;
+
+ /* clear start/stop bit */
+ cmd = readl(port_mmio + BMDMA_CMD_OFS);
+ cmd &= ~ATA_DMA_START;
+ writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+
+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+ ata_sff_dma_pause(ap);
+}
+
+/**
+ * mv_bmdma_status - Read BMDMA status
+ * @ap: port for which to retrieve DMA status.
+ *
+ * Read and return equivalent of the sff BMDMA status register.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static u8 mv_bmdma_status(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 reg, status;
+
+ /*
+ * Other bits are valid only if ATA_DMA_ACTIVE==0,
+ * and the ATA_DMA_INTR bit doesn't exist.
+ */
+ reg = readl(port_mmio + BMDMA_STATUS_OFS);
+ if (reg & ATA_DMA_ACTIVE)
+ status = ATA_DMA_ACTIVE;
+ else
+ status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR;
+ return status;
+}
+
+/**
* mv_qc_prep - Host specific command preparation.
* @qc: queued command to prepare
*
@@ -1450,7 +1682,8 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
* only 11 bytes...so we must pick and choose required
* registers based on the command. So, we drop feature and
* hob_feature for [RW] DMA commands, but they are needed for
- * NCQ. NCQ will drop hob_nsect.
+ * NCQ. NCQ will drop hob_nsect, which is not needed there
+ * (nsect is used only for the tag; feat/hob_feat hold true nsect).
*/
switch (tf->command) {
case ATA_CMD_READ:
@@ -1562,6 +1795,132 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
}
/**
+ * mv_sff_check_status - fetch device status, if valid
+ * @ap: ATA port to fetch status from
+ *
+ * When using command issue via mv_qc_issue_fis(),
+ * the initial ATA_BUSY state does not show up in the
+ * ATA status (shadow) register. This can confuse libata!
+ *
+ * So we have a hook here to fake ATA_BUSY for that situation,
+ * until the first time a BUSY, DRQ, or ERR bit is seen.
+ *
+ * The rest of the time, it simply returns the ATA status register.
+ */
+static u8 mv_sff_check_status(struct ata_port *ap)
+{
+ u8 stat = ioread8(ap->ioaddr.status_addr);
+ struct mv_port_priv *pp = ap->private_data;
+
+ if (pp->pp_flags & MV_PP_FLAG_FAKE_ATA_BUSY) {
+ if (stat & (ATA_BUSY | ATA_DRQ | ATA_ERR))
+ pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY;
+ else
+ stat = ATA_BUSY;
+ }
+ return stat;
+}
+
+/**
+ * mv_send_fis - Send a FIS, using the "Vendor-Unique FIS" register
+ * @fis: fis to be sent
+ * @nwords: number of 32-bit words in the fis
+ */
+static unsigned int mv_send_fis(struct ata_port *ap, u32 *fis, int nwords)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 ifctl, old_ifctl, ifstat;
+ int i, timeout = 200, final_word = nwords - 1;
+
+ /* Initiate FIS transmission mode */
+ old_ifctl = readl(port_mmio + SATA_IFCTL_OFS);
+ ifctl = 0x100 | (old_ifctl & 0xf);
+ writelfl(ifctl, port_mmio + SATA_IFCTL_OFS);
+
+ /* Send all words of the FIS except for the final word */
+ for (i = 0; i < final_word; ++i)
+ writel(fis[i], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+
+ /* Flag end-of-transmission, and then send the final word */
+ writelfl(ifctl | 0x200, port_mmio + SATA_IFCTL_OFS);
+ writelfl(fis[final_word], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+
+ /*
+ * Wait for FIS transmission to complete.
+ * This typically takes just a single iteration.
+ */
+ do {
+ ifstat = readl(port_mmio + SATA_IFSTAT_OFS);
+ } while (!(ifstat & 0x1000) && --timeout);
+
+ /* Restore original port configuration */
+ writelfl(old_ifctl, port_mmio + SATA_IFCTL_OFS);
+
+ /* See if it worked */
+ if ((ifstat & 0x3000) != 0x1000) {
+ ata_port_printk(ap, KERN_WARNING,
+ "%s transmission error, ifstat=%08x\n",
+ __func__, ifstat);
+ return AC_ERR_OTHER;
+ }
+ return 0;
+}
+
+/**
+ * mv_qc_issue_fis - Issue a command directly as a FIS
+ * @qc: queued command to start
+ *
+ * Note that the ATA shadow registers are not updated
+ * after command issue, so the device will appear "READY"
+ * if polled, even while it is BUSY processing the command.
+ *
+ * So we use a status hook to fake ATA_BUSY until the drive changes state.
+ *
+ * Note: we don't get updated shadow regs on *completion*
+ * of non-data commands. So avoid sending them via this function,
+ * as they will appear to have completed immediately.
+ *
+ * GEN_IIE has special registers that we could get the result tf from,
+ * but earlier chipsets do not. For now, we ignore those registers.
+ */
+static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mv_port_priv *pp = ap->private_data;
+ struct ata_link *link = qc->dev->link;
+ u32 fis[5];
+ int err = 0;
+
+ ata_tf_to_fis(&qc->tf, link->pmp, 1, (void *)fis);
+ err = mv_send_fis(ap, fis, sizeof(fis) / sizeof(fis[0]));
+ if (err)
+ return err;
+
+ switch (qc->tf.protocol) {
+ case ATAPI_PROT_PIO:
+ pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+ /* fall through */
+ case ATAPI_PROT_NODATA:
+ ap->hsm_task_state = HSM_ST_FIRST;
+ break;
+ case ATA_PROT_PIO:
+ pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ ap->hsm_task_state = HSM_ST_FIRST;
+ else
+ ap->hsm_task_state = HSM_ST;
+ break;
+ default:
+ ap->hsm_task_state = HSM_ST_LAST;
+ break;
+ }
+
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_pio_queue_task(ap, qc, 0);
+ return 0;
+}
+
+/**
* mv_qc_issue - Initiate a command to the host
* @qc: queued command to start
*
@@ -1575,14 +1934,28 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
*/
static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
{
+ static int limit_warnings = 10;
struct ata_port *ap = qc->ap;
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
u32 in_index;
+ unsigned int port_irqs;
- if ((qc->tf.protocol != ATA_PROT_DMA) &&
- (qc->tf.protocol != ATA_PROT_NCQ)) {
- static int limit_warnings = 10;
+ pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; /* paranoia */
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ case ATA_PROT_NCQ:
+ mv_start_edma(ap, port_mmio, pp, qc->tf.protocol);
+ pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
+ in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+
+ /* Write the request in pointer to kick the EDMA to life */
+ writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
+ port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+ return 0;
+
+ case ATA_PROT_PIO:
/*
* Errata SATA#16, SATA#24: warn if multiple DRQs expected.
*
@@ -1600,27 +1973,46 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
": attempting PIO w/multiple DRQ: "
"this may fail due to h/w errata\n");
}
- /*
- * We're about to send a non-EDMA capable command to the
- * port. Turn off EDMA so there won't be problems accessing
- * shadow block, etc registers.
- */
- mv_stop_edma(ap);
- mv_enable_port_irqs(ap, ERR_IRQ);
- mv_pmp_select(ap, qc->dev->link->pmp);
- return ata_sff_qc_issue(qc);
+ /* drop through */
+ case ATA_PROT_NODATA:
+ case ATAPI_PROT_PIO:
+ case ATAPI_PROT_NODATA:
+ if (ap->flags & ATA_FLAG_PIO_POLLING)
+ qc->tf.flags |= ATA_TFLAG_POLLING;
+ break;
}
- mv_start_dma(ap, port_mmio, pp, qc->tf.protocol);
-
- pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
- in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ port_irqs = ERR_IRQ; /* mask device interrupt when polling */
+ else
+ port_irqs = ERR_IRQ | DONE_IRQ; /* unmask all interrupts */
- /* and write the request in pointer to kick the EDMA to life */
- writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
- port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+ /*
+ * We're about to send a non-EDMA capable command to the
+ * port. Turn off EDMA so there won't be problems accessing
+ * shadow block, etc registers.
+ */
+ mv_stop_edma(ap);
+ mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
+ mv_pmp_select(ap, qc->dev->link->pmp);
- return 0;
+ if (qc->tf.command == ATA_CMD_READ_LOG_EXT) {
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ /*
+ * Workaround for 88SX60x1 FEr SATA#25 (part 2).
+ *
+ * After any NCQ error, the READ_LOG_EXT command
+ * from libata-eh *must* use mv_qc_issue_fis().
+ * Otherwise it might fail, due to chip errata.
+ *
+ * Rather than special-case it, we'll just *always*
+ * use this method here for READ_LOG_EXT, making for
+ * easier testing.
+ */
+ if (IS_GEN_II(hpriv))
+ return mv_qc_issue_fis(qc);
+ }
+ return ata_sff_qc_issue(qc);
}
static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
@@ -1631,8 +2023,12 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
if (pp->pp_flags & MV_PP_FLAG_NCQ_EN)
return NULL;
qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
- qc = NULL;
+ if (qc) {
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ qc = NULL;
+ else if (!(qc->flags & ATA_QCFLAG_ACTIVE))
+ qc = NULL;
+ }
return qc;
}
@@ -2214,9 +2610,15 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
struct ata_host *host = dev_instance;
struct mv_host_priv *hpriv = host->private_data;
unsigned int handled = 0;
+ int using_msi = hpriv->hp_flags & MV_HP_FLAG_MSI;
u32 main_irq_cause, pending_irqs;
spin_lock(&host->lock);
+
+ /* for MSI: block new interrupts while in here */
+ if (using_msi)
+ writel(0, hpriv->main_irq_mask_addr);
+
main_irq_cause = readl(hpriv->main_irq_cause_addr);
pending_irqs = main_irq_cause & hpriv->main_irq_mask;
/*
@@ -2230,6 +2632,11 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
handled = mv_host_intr(host, pending_irqs);
}
spin_unlock(&host->lock);
+
+ /* for MSI: unmask; interrupt cause bits will retrigger now */
+ if (using_msi)
+ writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr);
+
return IRQ_RETVAL(handled);
}
@@ -2779,6 +3186,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
mv_reset_channel(hpriv, mmio, ap->port_no);
pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ pp->pp_flags &=
+ ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
/* Workaround for errata FEr SATA#10 (part 2) */
do {
@@ -2798,6 +3207,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
extra = HZ; /* only extend it once, max */
}
} while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123);
+ mv_save_cached_regs(ap);
+ mv_edma_cfg(ap, 0, 0);
return rc;
}
@@ -2821,8 +3232,7 @@ static void mv_eh_thaw(struct ata_port *ap)
writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
/* clear pending irq events */
- hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
- hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
+ hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
mv_enable_port_irqs(ap, ERR_IRQ);
@@ -3075,6 +3485,9 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
hpriv->main_irq_mask_addr = mmio + PCI_HC_MAIN_IRQ_MASK_OFS;
}
+ /* initialize shadow irq mask with register's value */
+ hpriv->main_irq_mask = readl(hpriv->main_irq_mask_addr);
+
/* global interrupt mask: 0 == mask everything */
mv_set_main_irq_mask(host, ~0, 0);
@@ -3118,19 +3531,17 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS);
}
- if (!IS_SOC(hpriv)) {
- /* Clear any currently outstanding host interrupt conditions */
- writelfl(0, mmio + hpriv->irq_cause_ofs);
+ /* Clear any currently outstanding host interrupt conditions */
+ writelfl(0, mmio + hpriv->irq_cause_ofs);
- /* and unmask interrupt generation for host regs */
- writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
+ /* and unmask interrupt generation for host regs */
+ writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs);
- /*
- * enable only global host interrupts for now.
- * The per-port interrupts get done later as ports are set up.
- */
- mv_set_main_irq_mask(host, 0, PCI_ERR);
- }
+ /*
+ * enable only global host interrupts for now.
+ * The per-port interrupts get done later as ports are set up.
+ */
+ mv_set_main_irq_mask(host, 0, PCI_ERR);
done:
return rc;
}
@@ -3430,9 +3841,9 @@ static int mv_pci_init_one(struct pci_dev *pdev,
if (rc)
return rc;
- /* Enable interrupts */
- if (msi && pci_enable_msi(pdev))
- pci_intx(pdev, 1);
+ /* Enable message-switched interrupts, if requested */
+ if (msi && pci_enable_msi(pdev) == 0)
+ hpriv->hp_flags |= MV_HP_FLAG_MSI;
mv_dump_pci_cfg(pdev, 0x68);
mv_print_info(host);
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 6f1460614325..55a8eed3f3a3 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -305,10 +305,10 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
+static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
static void nv_nf2_freeze(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap);
-static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline);
static void nv_ck804_freeze(struct ata_port *ap);
static void nv_ck804_thaw(struct ata_port *ap);
static int nv_adma_slave_config(struct scsi_device *sdev);
@@ -352,6 +352,7 @@ enum nv_host_type
NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */
CK804,
ADMA,
+ MCP5x,
SWNCQ,
};
@@ -363,10 +364,10 @@ static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), SWNCQ },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), MCP5x },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), MCP5x },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), MCP5x },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), MCP5x },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
@@ -420,26 +421,33 @@ static struct ata_port_operations nv_generic_ops = {
.hardreset = ATA_OP_NULL,
};
-/* OSDL bz3352 reports that nf2/3 controllers can't determine device
- * signature reliably. Also, the following thread reports detection
- * failure on cold boot with the standard debouncing timing.
+/* nf2 is ripe with hardreset related problems.
+ *
+ * kernel bz#3352 reports nf2/3 controllers can't determine device
+ * signature reliably. The following thread reports detection failure
+ * on cold boot with the standard debouncing timing.
*
* http://thread.gmane.org/gmane.linux.ide/34098
*
- * Debounce with hotplug timing and request follow-up SRST.
+ * And bz#12176 reports that hardreset simply doesn't work on nf2.
+ * Give up on it and just don't do hardreset.
*/
static struct ata_port_operations nv_nf2_ops = {
- .inherits = &nv_common_ops,
+ .inherits = &nv_generic_ops,
.freeze = nv_nf2_freeze,
.thaw = nv_nf2_thaw,
- .hardreset = nv_nf2_hardreset,
};
-/* CK804 finally gets hardreset right */
+/* For initial probing after boot and hot plugging, hardreset mostly
+ * works fine on CK804 but curiously, reprobing on the initial port by
+ * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS
+ * in somewhat undeterministic way. Use noclassify hardreset.
+ */
static struct ata_port_operations nv_ck804_ops = {
.inherits = &nv_common_ops,
.freeze = nv_ck804_freeze,
.thaw = nv_ck804_thaw,
+ .hardreset = nv_noclassify_hardreset,
.host_stop = nv_ck804_host_stop,
};
@@ -467,8 +475,19 @@ static struct ata_port_operations nv_adma_ops = {
.host_stop = nv_adma_host_stop,
};
+/* Kernel bz#12351 reports that when SWNCQ is enabled, for hotplug to
+ * work, hardreset should be used and hardreset can't report proper
+ * signature, which suggests that mcp5x is closer to nf2 as long as
+ * reset quirkiness is concerned. Define separate ops for mcp5x with
+ * nv_noclassify_hardreset().
+ */
+static struct ata_port_operations nv_mcp5x_ops = {
+ .inherits = &nv_common_ops,
+ .hardreset = nv_noclassify_hardreset,
+};
+
static struct ata_port_operations nv_swncq_ops = {
- .inherits = &nv_generic_ops,
+ .inherits = &nv_mcp5x_ops,
.qc_defer = ata_std_qc_defer,
.qc_prep = nv_swncq_qc_prep,
@@ -531,6 +550,15 @@ static const struct ata_port_info nv_port_info[] = {
.port_ops = &nv_adma_ops,
.private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht),
},
+ /* MCP5x */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+ .pio_mask = NV_PIO_MASK,
+ .mwdma_mask = NV_MWDMA_MASK,
+ .udma_mask = NV_UDMA_MASK,
+ .port_ops = &nv_mcp5x_ops,
+ .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht),
+ },
/* SWNCQ */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
@@ -1530,6 +1558,17 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
return 0;
}
+static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ bool online;
+ int rc;
+
+ rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
+ &online, NULL);
+ return online ? -EAGAIN : rc;
+}
+
static void nv_nf2_freeze(struct ata_port *ap)
{
void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
@@ -1554,17 +1593,6 @@ static void nv_nf2_thaw(struct ata_port *ap)
iowrite8(mask, scr_addr + NV_INT_ENABLE);
}
-static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- bool online;
- int rc;
-
- rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline,
- &online, NULL);
- return online ? -EAGAIN : rc;
-}
-
static void nv_ck804_freeze(struct ata_port *ap)
{
void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
@@ -2355,14 +2383,9 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (type == CK804 && adma_enabled) {
dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
type = ADMA;
- }
-
- if (type == SWNCQ) {
- if (swncq_enabled)
- dev_printk(KERN_NOTICE, &pdev->dev,
- "Using SWNCQ mode\n");
- else
- type = GENERIC;
+ } else if (type == MCP5x && swncq_enabled) {
+ dev_printk(KERN_NOTICE, &pdev->dev, "Using SWNCQ mode\n");
+ type = SWNCQ;
}
ppi[0] = &nv_port_info[type];
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 564c142b03b0..d0091609e210 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -44,6 +44,7 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <linux/dmi.h>
#define DRV_NAME "sata_sil"
#define DRV_VERSION "2.4"
@@ -323,7 +324,7 @@ static void sil_fill_sg(struct ata_queued_cmd *qc)
prd->addr = cpu_to_le32(addr);
prd->flags_len = cpu_to_le32(sg_len);
- VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, sg_len);
+ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len);
last_prd = prd;
prd++;
@@ -695,11 +696,38 @@ static void sil_init_controller(struct ata_host *host)
}
}
+static bool sil_broken_system_poweroff(struct pci_dev *pdev)
+{
+ static const struct dmi_system_id broken_systems[] = {
+ {
+ .ident = "HP Compaq nx6325",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x12UL,
+ },
+
+ { } /* terminate list */
+ };
+ const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
+
+ if (dmi) {
+ unsigned long slot = (unsigned long)dmi->driver_data;
+ /* apply the quirk only to on-board controllers */
+ return slot == PCI_SLOT(pdev->devfn);
+ }
+
+ return false;
+}
+
static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
int board_id = ent->driver_data;
- const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL };
+ struct ata_port_info pi = sil_port_info[board_id];
+ const struct ata_port_info *ppi[] = { &pi, NULL };
struct ata_host *host;
void __iomem *mmio_base;
int n_ports, rc;
@@ -713,6 +741,13 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == sil_3114)
n_ports = 4;
+ if (sil_broken_system_poweroff(pdev)) {
+ pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN |
+ ATA_FLAG_NO_HIBERNATE_SPINDOWN;
+ dev_info(&pdev->dev, "quirky BIOS, skipping spindown "
+ "on poweroff and hibernation\n");
+ }
+
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
if (!host)
return -ENOMEM;
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 937c9c0ef4c9..10f000dbe448 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -2519,8 +2519,8 @@ fore200e_load_and_start_fw(struct fore200e* fore200e)
return err;
sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
- if (request_firmware(&firmware, buf, device) == 1) {
- printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name);
+ if ((err = request_firmware(&firmware, buf, device)) < 0) {
+ printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
return err;
}
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 144a49f15220..8733a2ea04c2 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -901,7 +901,7 @@ static int __devinit eeprom_read(struct lanai_dev *lanai)
clock_l(); udelay(5);
for (i = 128; i != 0; i >>= 1) { /* write command out */
tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |
- (data & i) ? CONFIG1_PROMDATA : 0;
+ ((data & i) ? CONFIG1_PROMDATA : 0);
if (lanai->conf1 != tmp) {
set_config1(tmp);
udelay(5); /* Let new data settle */
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 72fc0f799a64..89d7a6e94c9c 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -685,6 +685,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
out_release_regions:
pci_release_regions(dev);
out:
+ kfree(card);
return err;
}
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 0a5f055dffba..ddc97496db4a 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -63,6 +63,32 @@ struct class_private {
#define to_class(obj) \
container_of(obj, struct class_private, class_subsys.kobj)
+/**
+ * struct device_private - structure to hold the private to the driver core portions of the device structure.
+ *
+ * @klist_children - klist containing all children of this device
+ * @knode_parent - node in sibling list
+ * @knode_driver - node in driver list
+ * @knode_bus - node in bus list
+ * @device - pointer back to the struct class that this structure is
+ * associated with.
+ *
+ * Nothing outside of the driver core should ever touch these fields.
+ */
+struct device_private {
+ struct klist klist_children;
+ struct klist_node knode_parent;
+ struct klist_node knode_driver;
+ struct klist_node knode_bus;
+ struct device *device;
+};
+#define to_device_private_parent(obj) \
+ container_of(obj, struct device_private, knode_parent)
+#define to_device_private_driver(obj) \
+ container_of(obj, struct device_private, knode_driver)
+#define to_device_private_bus(obj) \
+ container_of(obj, struct device_private, knode_bus)
+
/* initialisation functions */
extern int devices_init(void);
extern int buses_init(void);
@@ -86,10 +112,13 @@ extern void bus_remove_driver(struct device_driver *drv);
extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+static inline int driver_match_device(struct device_driver *drv,
+ struct device *dev)
+{
+ return drv->bus->match && drv->bus->match(dev, drv);
+}
extern void sysdev_shutdown(void);
-extern int sysdev_suspend(pm_message_t state);
-extern int sysdev_resume(void);
extern char *make_class_name(const char *name, struct kobject *kobj);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 83f32b891fa9..dc030f1f00f1 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv,
int err = -ENODEV;
dev = bus_find_device_by_name(bus, NULL, buf);
- if (dev && dev->driver == NULL) {
+ if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struct bus_type *bus,
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_bus) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}
/**
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start,
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bus_type *bus,
return NULL;
klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *dev)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
- klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
+ klist_add_tail(&dev->p->knode_bus,
+ &bus->p->klist_devices);
}
}
@@ -528,8 +536,8 @@ void bus_remove_device(struct device *dev)
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
- if (klist_node_attached(&dev->knode_bus))
- klist_del(&dev->knode_bus);
+ if (klist_node_attached(&dev->p->knode_bus))
+ klist_del(&dev->p->knode_bus);
pr_debug("bus: '%s': remove device %s\n",
dev->bus->name, dev_name(dev));
@@ -831,14 +839,16 @@ static void bus_remove_attrs(struct bus_type *bus)
static void klist_devices_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;
get_device(dev);
}
static void klist_devices_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;
put_device(dev);
}
@@ -932,6 +942,7 @@ bus_uevent_fail:
kset_unregister(&bus->p->subsys);
kfree(bus->p);
out:
+ bus->p = NULL;
return retval;
}
EXPORT_SYMBOL_GPL(bus_register);
@@ -953,6 +964,7 @@ void bus_unregister(struct bus_type *bus)
bus_remove_file(bus, &bus_attr_uevent);
kset_unregister(&bus->p->subsys);
kfree(bus->p);
+ bus->p = NULL;
}
EXPORT_SYMBOL_GPL(bus_unregister);
@@ -993,18 +1005,20 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list
{
struct list_head *pos;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *b;
list_for_each(pos, list) {
n = container_of(pos, struct klist_node, n_node);
- b = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ b = dev_prv->device;
if (compare(a, b) <= 0) {
- list_move_tail(&a->knode_bus.n_node,
- &b->knode_bus.n_node);
+ list_move_tail(&a->p->knode_bus.n_node,
+ &b->p->knode_bus.n_node);
return;
}
}
- list_move_tail(&a->knode_bus.n_node, list);
+ list_move_tail(&a->p->knode_bus.n_node, list);
}
void bus_sort_breadthfirst(struct bus_type *bus,
@@ -1014,6 +1028,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
LIST_HEAD(sorted_devices);
struct list_head *pos, *tmp;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *dev;
struct klist *device_klist;
@@ -1022,7 +1037,8 @@ void bus_sort_breadthfirst(struct bus_type *bus,
spin_lock(&device_klist->k_lock);
list_for_each_safe(pos, tmp, &device_klist->k_list) {
n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
device_insertion_sort_klist(dev, &sorted_devices, compare);
}
list_splice(&sorted_devices, &device_klist->k_list);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 8079afca4972..a90f56f64d6f 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops = {
static void device_release(struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
+ struct device_private *p = dev->p;
if (dev->release)
dev->release(dev);
@@ -120,6 +121,7 @@ static void device_release(struct kobject *kobj)
WARN(1, KERN_ERR "Device '%s' does not have a release() "
"function, it is broken and must be fixed.\n",
dev_name(dev));
+ kfree(p);
}
static struct kobj_type device_ktype = {
@@ -507,14 +509,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
static void klist_children_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;
get_device(dev);
}
static void klist_children_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;
put_device(dev);
}
@@ -538,8 +542,6 @@ void device_initialize(struct device *dev)
{
dev->kobj.kset = devices_kset;
kobject_init(&dev->kobj, &device_ktype);
- klist_init(&dev->klist_children, klist_children_get,
- klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
init_MUTEX(&dev->sem);
spin_lock_init(&dev->devres_lock);
@@ -777,11 +779,12 @@ static void device_remove_class_symlinks(struct device *dev)
int dev_set_name(struct device *dev, const char *fmt, ...)
{
va_list vargs;
+ int err;
va_start(vargs, fmt);
- vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
+ err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
va_end(vargs);
- return 0;
+ return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);
@@ -858,12 +861,26 @@ int device_add(struct device *dev)
if (!dev)
goto done;
- /* Temporarily support init_name if it is set.
- * It will override bus_id for now */
- if (dev->init_name)
- dev_set_name(dev, "%s", dev->init_name);
+ dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
+ if (!dev->p) {
+ error = -ENOMEM;
+ goto done;
+ }
+ dev->p->device = dev;
+ klist_init(&dev->p->klist_children, klist_children_get,
+ klist_children_put);
+
+ /*
+ * for statically allocated devices, which should all be converted
+ * some day, we need to initialize the name. We prevent reading back
+ * the name, and force the use of dev_name()
+ */
+ if (dev->init_name) {
+ dev_set_name(dev, dev->init_name);
+ dev->init_name = NULL;
+ }
- if (!strlen(dev->bus_id))
+ if (!dev_name(dev))
goto done;
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -922,7 +939,8 @@ int device_add(struct device *dev)
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
- klist_add_tail(&dev->knode_parent, &parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &parent->p->klist_children);
if (dev->class) {
mutex_lock(&dev->class->p->class_mutex);
@@ -1036,7 +1054,7 @@ void device_del(struct device *dev)
device_pm_remove(dev);
dpm_sysfs_remove(dev);
if (parent)
- klist_del(&dev->knode_parent);
+ klist_del(&dev->p->knode_parent);
if (MAJOR(dev->devt)) {
device_remove_sys_dev_entry(dev);
device_remove_file(dev, &devt_attr);
@@ -1097,7 +1115,14 @@ void device_unregister(struct device *dev)
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ struct device *dev = NULL;
+ struct device_private *p;
+
+ if (n) {
+ p = to_device_private_parent(n);
+ dev = p->device;
+ }
+ return dev;
}
/**
@@ -1119,7 +1144,7 @@ int device_for_each_child(struct device *parent, void *data,
struct device *child;
int error = 0;
- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)) && !error)
error = fn(child, data);
klist_iter_exit(&i);
@@ -1150,7 +1175,7 @@ struct device *device_find_child(struct device *parent, void *data,
if (!parent)
return NULL;
- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)))
if (match(child, data) && get_device(child))
break;
@@ -1274,7 +1299,7 @@ EXPORT_SYMBOL_GPL(__root_device_register);
/**
* root_device_unregister - unregister and free a root device
- * @root: device going away.
+ * @dev: device going away
*
* This function unregisters and cleans up a device that was created by
* root_device_register().
@@ -1342,7 +1367,10 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);
- vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
+ retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
+ if (retval)
+ goto error;
+
retval = device_register(dev);
if (retval)
goto error;
@@ -1446,19 +1474,15 @@ int device_rename(struct device *dev, char *new_name)
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif
- old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
+ old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}
- strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
- strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
error = kobject_rename(&dev->kobj, new_name);
- if (error) {
- strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
+ if (error)
goto out;
- }
#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
@@ -1564,9 +1588,10 @@ int device_move(struct device *dev, struct device *new_parent)
old_parent = dev->parent;
dev->parent = new_parent;
if (old_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
if (new_parent) {
- klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &new_parent->p->klist_children);
set_dev_node(dev, dev_to_node(new_parent));
}
@@ -1578,11 +1603,11 @@ int device_move(struct device *dev, struct device *new_parent)
device_move_class_links(dev, new_parent, old_parent);
if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
if (new_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
dev->parent = old_parent;
if (old_parent) {
- klist_add_tail(&dev->knode_parent,
- &old_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &old_parent->p->klist_children);
set_dev_node(dev, dev_to_node(old_parent));
}
}
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 719ee5c1c8d9..5b257a57bc57 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -107,7 +107,7 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
/*
* Print cpu online, possible, present, and system maps
*/
-static ssize_t print_cpus_map(char *buf, cpumask_t *map)
+static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
{
int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 315bed8d5e7f..f17c3266a0e0 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -18,9 +18,11 @@
*/
#include <linux/device.h>
+#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
+#include <linux/async.h>
#include "base.h"
#include "power/power.h"
@@ -28,7 +30,7 @@
static void driver_bound(struct device *dev)
{
- if (klist_node_attached(&dev->knode_driver)) {
+ if (klist_node_attached(&dev->p->knode_driver)) {
printk(KERN_WARNING "%s: device %s already bound\n",
__func__, kobject_name(&dev->kobj));
return;
@@ -41,7 +43,7 @@ static void driver_bound(struct device *dev)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);
- klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
+ klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
}
static int driver_sysfs_add(struct device *dev)
@@ -168,18 +170,23 @@ int driver_probe_done(void)
}
/**
+ * wait_for_device_probe
+ * Wait for device probing to be completed.
+ */
+void wait_for_device_probe(void)
+{
+ /* wait for the known devices to complete their probing */
+ wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
+ async_synchronize_full();
+}
+
+/**
* driver_probe_device - attempt to bind device & driver together
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
- * First, we call the bus's match function, if one present, which should
- * compare the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know the
- * format of the ID structures, nor what is to be considered a match and
- * what is not.
- *
- * This function returns 1 if a match is found, -ENODEV if the device is
- * not registered, and 0 otherwise.
+ * This function returns -ENODEV if the device is not registered,
+ * 1 if the device is bound sucessfully and 0 otherwise.
*
* This function must be called with @dev->sem held. When called for a
* USB interface, @dev->parent->sem must be held as well.
@@ -190,21 +197,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
if (!device_is_registered(dev))
return -ENODEV;
- if (drv->bus->match && !drv->bus->match(dev, drv))
- goto done;
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);
ret = really_probe(dev, drv);
-done:
return ret;
}
static int __device_attach(struct device_driver *drv, void *data)
{
struct device *dev = data;
+
+ if (!driver_match_device(drv, dev))
+ return 0;
+
return driver_probe_device(drv, dev);
}
@@ -257,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data)
* is an error.
*/
- if (drv->bus->match && !drv->bus->match(dev, drv))
+ if (!driver_match_device(drv, dev))
return 0;
if (dev->parent) /* Needed for USB */
@@ -310,7 +318,7 @@ static void __device_release_driver(struct device *dev)
drv->remove(dev);
devres_release_all(dev);
dev->driver = NULL;
- klist_remove(&dev->knode_driver);
+ klist_remove(&dev->p->knode_driver);
}
}
@@ -340,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver);
*/
void driver_detach(struct device_driver *drv)
{
+ struct device_private *dev_prv;
struct device *dev;
for (;;) {
@@ -348,8 +357,10 @@ void driver_detach(struct device_driver *drv)
spin_unlock(&drv->p->klist_devices.k_lock);
break;
}
- dev = list_entry(drv->p->klist_devices.k_list.prev,
- struct device, knode_driver.n_node);
+ dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
+ struct device_private,
+ knode_driver.n_node);
+ dev = dev_prv->device;
get_device(dev);
spin_unlock(&drv->p->klist_devices.k_lock);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1e2bda780e48..c51f11bb29ae 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -19,7 +19,14 @@
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_driver) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_driver(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}
/**
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device_driver *drv, struct device *start,
return -EINVAL;
klist_iter_init_node(&drv->p->klist_devices, &i,
- start ? &start->knode_driver : NULL);
+ start ? &start->p->knode_driver : NULL);
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct device_driver *drv,
return NULL;
klist_iter_init_node(&drv->p->klist_devices, &i,
- (start ? &start->knode_driver : NULL));
+ (start ? &start->p->knode_driver : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -216,6 +223,8 @@ int driver_register(struct device_driver *drv)
int ret;
struct device_driver *other;
+ BUG_ON(!drv->bus->p);
+
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 349a1013603f..ec993aa6a2ca 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -584,10 +584,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct platform_device *pdev = to_platform_device(dev);
- add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
+ add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+ (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
return 0;
}
+static const struct platform_device_id *platform_match_id(
+ struct platform_device_id *id,
+ struct platform_device *pdev)
+{
+ while (id->name[0]) {
+ if (strcmp(pdev->name, id->name) == 0) {
+ pdev->id_entry = id;
+ return id;
+ }
+ id++;
+ }
+ return NULL;
+}
+
/**
* platform_match - bind platform device to platform driver.
* @dev: device.
@@ -603,9 +618,14 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
*/
static int platform_match(struct device *dev, struct device_driver *drv)
{
- struct platform_device *pdev;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct platform_driver *pdrv = to_platform_driver(drv);
+
+ /* match against the id table first */
+ if (pdrv->id_table)
+ return platform_match_id(pdrv->id_table, pdev) != NULL;
- pdev = container_of(dev, struct platform_device, dev);
+ /* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
@@ -623,26 +643,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->suspend_late)
- ret = drv->suspend_late(pdev, mesg);
+ if (dev->driver && pdrv->suspend_late)
+ ret = pdrv->suspend_late(pdev, mesg);
return ret;
}
static int platform_legacy_resume_early(struct device *dev)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->resume_early)
- ret = drv->resume_early(pdev);
+ if (dev->driver && pdrv->resume_early)
+ ret = pdrv->resume_early(pdev);
return ret;
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 670c9d6c1407..2d14f4ae6c01 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -333,7 +333,6 @@ static void dpm_power_up(pm_message_t state)
*/
void device_power_up(pm_message_t state)
{
- sysdev_resume();
dpm_power_up(state);
}
EXPORT_SYMBOL_GPL(device_power_up);
@@ -577,8 +576,6 @@ int device_power_down(pm_message_t state)
}
dev->power.status = DPM_OFF_IRQ;
}
- if (!error)
- error = sysdev_suspend(state);
if (error)
dpm_power_up(resume_event(state));
return error;
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index c98c31ec2f75..b428c8c4bc64 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -303,7 +303,6 @@ void sysdev_unregister(struct sys_device * sysdev)
* is guaranteed by virtue of the fact that child devices are registered
* after their parents.
*/
-
void sysdev_shutdown(void)
{
struct sysdev_class * cls;
@@ -363,7 +362,6 @@ static void __sysdev_resume(struct sys_device *dev)
* This is only called by the device PM core, so we let them handle
* all synchronization.
*/
-
int sysdev_suspend(pm_message_t state)
{
struct sysdev_class * cls;
@@ -432,7 +430,7 @@ aux_driver:
}
return ret;
}
-
+EXPORT_SYMBOL_GPL(sysdev_suspend);
/**
* sysdev_resume - Bring system devices back to life.
@@ -442,7 +440,6 @@ aux_driver:
*
* Note: Interrupts are disabled when called.
*/
-
int sysdev_resume(void)
{
struct sysdev_class * cls;
@@ -463,7 +460,7 @@ int sysdev_resume(void)
}
return 0;
}
-
+EXPORT_SYMBOL_GPL(sysdev_resume);
int __init system_bus_init(void)
{
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index a778fb52b11f..bf6b13206d00 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -31,7 +31,10 @@
#include <linux/hardirq.h>
#include <linux/topology.h>
-#define define_one_ro(_name) \
+#define define_one_ro_named(_name, _func) \
+static SYSDEV_ATTR(_name, 0444, _func, NULL)
+
+#define define_one_ro(_name) \
static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
#define define_id_show_func(name) \
@@ -42,8 +45,8 @@ static ssize_t show_##name(struct sys_device *dev, \
return sprintf(buf, "%d\n", topology_##name(cpu)); \
}
-#if defined(topology_thread_siblings) || defined(topology_core_siblings)
-static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf)
+#if defined(topology_thread_cpumask) || defined(topology_core_cpumask)
+static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf)
{
ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
int n = 0;
@@ -65,7 +68,7 @@ static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, char *buf) \
{ \
unsigned int cpu = dev->id; \
- return show_cpumap(0, &(topology_##name(cpu)), buf); \
+ return show_cpumap(0, topology_##name(cpu), buf); \
}
#define define_siblings_show_list(name) \
@@ -74,7 +77,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \
char *buf) \
{ \
unsigned int cpu = dev->id; \
- return show_cpumap(1, &(topology_##name(cpu)), buf); \
+ return show_cpumap(1, topology_##name(cpu), buf); \
}
#else
@@ -82,9 +85,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \
static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, char *buf) \
{ \
- unsigned int cpu = dev->id; \
- cpumask_t mask = topology_##name(cpu); \
- return show_cpumap(0, &mask, buf); \
+ return show_cpumap(0, topology_##name(dev->id), buf); \
}
#define define_siblings_show_list(name) \
@@ -92,9 +93,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \
struct sysdev_attribute *attr, \
char *buf) \
{ \
- unsigned int cpu = dev->id; \
- cpumask_t mask = topology_##name(cpu); \
- return show_cpumap(1, &mask, buf); \
+ return show_cpumap(1, topology_##name(dev->id), buf); \
}
#endif
@@ -107,13 +106,13 @@ define_one_ro(physical_package_id);
define_id_show_func(core_id);
define_one_ro(core_id);
-define_siblings_show_func(thread_siblings);
-define_one_ro(thread_siblings);
-define_one_ro(thread_siblings_list);
+define_siblings_show_func(thread_cpumask);
+define_one_ro_named(thread_siblings, show_thread_cpumask);
+define_one_ro_named(thread_siblings_list, show_thread_cpumask_list);
-define_siblings_show_func(core_siblings);
-define_one_ro(core_siblings);
-define_one_ro(core_siblings_list);
+define_siblings_show_func(core_cpumask);
+define_one_ro_named(core_siblings, show_core_cpumask);
+define_one_ro_named(core_siblings_list, show_core_cpumask_list);
static struct attribute *default_attrs[] = {
&attr_physical_package_id.attr,
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index c237527b1aa5..5e41e6dd657b 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -18,6 +18,7 @@
enum {
AOECMD_ATA,
AOECMD_CFG,
+ AOECMD_VEND_MIN = 0xf0,
AOEFL_RSP = (1<<3),
AOEFL_ERR = (1<<2),
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 30de5b1c647e..c6099ba9a4b8 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -142,6 +142,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
aoecmd_cfg_rsp(skb);
break;
default:
+ if (h->cmd >= AOECMD_VEND_MIN)
+ break; /* don't complain about vendor commands */
printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
}
exit:
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 69e1df7dfa14..4234c11c1e4c 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1730,7 +1730,7 @@ static int __init fd_test_drive_present( int drive )
timeout = jiffies + 2*HZ+HZ/2;
while (time_before(jiffies, timeout))
- if (!(mfp.par_dt_reg & 0x20))
+ if (!(st_mfp.par_dt_reg & 0x20))
break;
status = FDC_READ( FDCREG_STATUS );
@@ -1747,7 +1747,7 @@ static int __init fd_test_drive_present( int drive )
/* dummy seek command to make WP bit accessible */
FDC_WRITE( FDCREG_DATA, 0 );
FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );
- while( mfp.par_dt_reg & 0x20 )
+ while( st_mfp.par_dt_reg & 0x20 )
;
status = FDC_READ( FDCREG_STATUS );
}
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 01e69383d9c0..b5a061114630 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3390,6 +3390,203 @@ static void free_hba(int i)
kfree(p);
}
+/* Send a message CDB to the firmware. */
+static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, unsigned char type)
+{
+ typedef struct {
+ CommandListHeader_struct CommandHeader;
+ RequestBlock_struct Request;
+ ErrDescriptor_struct ErrorDescriptor;
+ } Command;
+ static const size_t cmd_sz = sizeof(Command) + sizeof(ErrorInfo_struct);
+ Command *cmd;
+ dma_addr_t paddr64;
+ uint32_t paddr32, tag;
+ void __iomem *vaddr;
+ int i, err;
+
+ vaddr = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+ if (vaddr == NULL)
+ return -ENOMEM;
+
+ /* The Inbound Post Queue only accepts 32-bit physical addresses for the
+ CCISS commands, so they must be allocated from the lower 4GiB of
+ memory. */
+ err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err) {
+ iounmap(vaddr);
+ return -ENOMEM;
+ }
+
+ cmd = pci_alloc_consistent(pdev, cmd_sz, &paddr64);
+ if (cmd == NULL) {
+ iounmap(vaddr);
+ return -ENOMEM;
+ }
+
+ /* This must fit, because of the 32-bit consistent DMA mask. Also,
+ although there's no guarantee, we assume that the address is at
+ least 4-byte aligned (most likely, it's page-aligned). */
+ paddr32 = paddr64;
+
+ cmd->CommandHeader.ReplyQueue = 0;
+ cmd->CommandHeader.SGList = 0;
+ cmd->CommandHeader.SGTotal = 0;
+ cmd->CommandHeader.Tag.lower = paddr32;
+ cmd->CommandHeader.Tag.upper = 0;
+ memset(&cmd->CommandHeader.LUN.LunAddrBytes, 0, 8);
+
+ cmd->Request.CDBLen = 16;
+ cmd->Request.Type.Type = TYPE_MSG;
+ cmd->Request.Type.Attribute = ATTR_HEADOFQUEUE;
+ cmd->Request.Type.Direction = XFER_NONE;
+ cmd->Request.Timeout = 0; /* Don't time out */
+ cmd->Request.CDB[0] = opcode;
+ cmd->Request.CDB[1] = type;
+ memset(&cmd->Request.CDB[2], 0, 14); /* the rest of the CDB is reserved */
+
+ cmd->ErrorDescriptor.Addr.lower = paddr32 + sizeof(Command);
+ cmd->ErrorDescriptor.Addr.upper = 0;
+ cmd->ErrorDescriptor.Len = sizeof(ErrorInfo_struct);
+
+ writel(paddr32, vaddr + SA5_REQUEST_PORT_OFFSET);
+
+ for (i = 0; i < 10; i++) {
+ tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
+ if ((tag & ~3) == paddr32)
+ break;
+ schedule_timeout_uninterruptible(HZ);
+ }
+
+ iounmap(vaddr);
+
+ /* we leak the DMA buffer here ... no choice since the controller could
+ still complete the command. */
+ if (i == 10) {
+ printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n",
+ opcode, type);
+ return -ETIMEDOUT;
+ }
+
+ pci_free_consistent(pdev, cmd_sz, cmd, paddr64);
+
+ if (tag & 2) {
+ printk(KERN_ERR "cciss: controller message %02x:%02x failed\n",
+ opcode, type);
+ return -EIO;
+ }
+
+ printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n",
+ opcode, type);
+ return 0;
+}
+
+#define cciss_soft_reset_controller(p) cciss_message(p, 1, 0)
+#define cciss_noop(p) cciss_message(p, 3, 0)
+
+static __devinit int cciss_reset_msi(struct pci_dev *pdev)
+{
+/* the #defines are stolen from drivers/pci/msi.h. */
+#define msi_control_reg(base) (base + PCI_MSI_FLAGS)
+#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
+
+ int pos;
+ u16 control = 0;
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_MSI);
+ if (pos) {
+ pci_read_config_word(pdev, msi_control_reg(pos), &control);
+ if (control & PCI_MSI_FLAGS_ENABLE) {
+ printk(KERN_INFO "cciss: resetting MSI\n");
+ pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE);
+ }
+ }
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
+ if (pos) {
+ pci_read_config_word(pdev, msi_control_reg(pos), &control);
+ if (control & PCI_MSIX_FLAGS_ENABLE) {
+ printk(KERN_INFO "cciss: resetting MSI-X\n");
+ pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE);
+ }
+ }
+
+ return 0;
+}
+
+/* This does a hard reset of the controller using PCI power management
+ * states. */
+static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev)
+{
+ u16 pmcsr, saved_config_space[32];
+ int i, pos;
+
+ printk(KERN_INFO "cciss: using PCI PM to reset controller\n");
+
+ /* This is very nearly the same thing as
+
+ pci_save_state(pci_dev);
+ pci_set_power_state(pci_dev, PCI_D3hot);
+ pci_set_power_state(pci_dev, PCI_D0);
+ pci_restore_state(pci_dev);
+
+ but we can't use these nice canned kernel routines on
+ kexec, because they also check the MSI/MSI-X state in PCI
+ configuration space and do the wrong thing when it is
+ set/cleared. Also, the pci_save/restore_state functions
+ violate the ordering requirements for restoring the
+ configuration space from the CCISS document (see the
+ comment below). So we roll our own .... */
+
+ for (i = 0; i < 32; i++)
+ pci_read_config_word(pdev, 2*i, &saved_config_space[i]);
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ if (pos == 0) {
+ printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n");
+ return -ENODEV;
+ }
+
+ /* Quoting from the Open CISS Specification: "The Power
+ * Management Control/Status Register (CSR) controls the power
+ * state of the device. The normal operating state is D0,
+ * CSR=00h. The software off state is D3, CSR=03h. To reset
+ * the controller, place the interface device in D3 then to
+ * D0, this causes a secondary PCI reset which will reset the
+ * controller." */
+
+ /* enter the D3hot power management state */
+ pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
+ pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ pmcsr |= PCI_D3hot;
+ pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+
+ schedule_timeout_uninterruptible(HZ >> 1);
+
+ /* enter the D0 power management state */
+ pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ pmcsr |= PCI_D0;
+ pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
+
+ schedule_timeout_uninterruptible(HZ >> 1);
+
+ /* Restore the PCI configuration space. The Open CISS
+ * Specification says, "Restore the PCI Configuration
+ * Registers, offsets 00h through 60h. It is important to
+ * restore the command register, 16-bits at offset 04h,
+ * last. Do not restore the configuration status register,
+ * 16-bits at offset 06h." Note that the offset is 2*i. */
+ for (i = 0; i < 32; i++) {
+ if (i == 2 || i == 3)
+ continue;
+ pci_write_config_word(pdev, 2*i, saved_config_space[i]);
+ }
+ wmb();
+ pci_write_config_word(pdev, 4, saved_config_space[2]);
+
+ return 0;
+}
+
/*
* This is it. Find all the controllers and register them. I really hate
* stealing all these major device numbers.
@@ -3404,6 +3601,28 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
int dac, return_code;
InquiryData_struct *inq_buff = NULL;
+ if (reset_devices) {
+ /* Reset the controller with a PCI power-cycle */
+ if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev))
+ return -ENODEV;
+
+ /* Some devices (notably the HP Smart Array 5i Controller)
+ need a little pause here */
+ schedule_timeout_uninterruptible(30*HZ);
+
+ /* Now try to get the controller to respond to a no-op */
+ for (i=0; i<30; i++) {
+ if (cciss_noop(pdev) == 0)
+ break;
+
+ schedule_timeout_uninterruptible(HZ);
+ }
+ if (i == 30) {
+ printk(KERN_ERR "cciss: controller seems dead\n");
+ return -EBUSY;
+ }
+ }
+
i = alloc_cciss_hba();
if (i < 0)
return -1;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index cf29cc4e6ab7..c2c95e614506 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -558,6 +558,8 @@ static void process_fd_request(void);
static void recalibrate_floppy(void);
static void floppy_shutdown(unsigned long);
+static int floppy_request_regions(int);
+static void floppy_release_regions(int);
static int floppy_grab_irq_and_dma(void);
static void floppy_release_irq_and_dma(void);
@@ -4133,10 +4135,9 @@ static int have_no_fdc = -ENODEV;
static ssize_t floppy_cmos_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct platform_device *p;
+ struct platform_device *p = to_platform_device(dev);
int drive;
- p = container_of(dev, struct platform_device,dev);
drive = p->id;
return sprintf(buf, "%X\n", UDP->cmos);
}
@@ -4274,8 +4275,7 @@ static int __init floppy_init(void)
FDCS->rawcmd = 2;
if (user_reset_fdc(-1, FD_RESET_ALWAYS, 0)) {
/* free ioports reserved by floppy_grab_irq_and_dma() */
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
+ floppy_release_regions(fdc);
FDCS->address = -1;
FDCS->version = FDC_NONE;
continue;
@@ -4284,8 +4284,7 @@ static int __init floppy_init(void)
FDCS->version = get_fdc_version();
if (FDCS->version == FDC_NONE) {
/* free ioports reserved by floppy_grab_irq_and_dma() */
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
+ floppy_release_regions(fdc);
FDCS->address = -1;
continue;
}
@@ -4358,6 +4357,47 @@ out_put_disk:
static DEFINE_SPINLOCK(floppy_usage_lock);
+static const struct io_region {
+ int offset;
+ int size;
+} io_regions[] = {
+ { 2, 1 },
+ /* address + 3 is sometimes reserved by pnp bios for motherboard */
+ { 4, 2 },
+ /* address + 6 is reserved, and may be taken by IDE.
+ * Unfortunately, Adaptec doesn't know this :-(, */
+ { 7, 1 },
+};
+
+static void floppy_release_allocated_regions(int fdc, const struct io_region *p)
+{
+ while (p != io_regions) {
+ p--;
+ release_region(FDCS->address + p->offset, p->size);
+ }
+}
+
+#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))
+
+static int floppy_request_regions(int fdc)
+{
+ const struct io_region *p;
+
+ for (p = io_regions; p < ARRAY_END(io_regions); p++) {
+ if (!request_region(FDCS->address + p->offset, p->size, "floppy")) {
+ DPRINT("Floppy io-port 0x%04lx in use\n", FDCS->address + p->offset);
+ floppy_release_allocated_regions(fdc, p);
+ return -EBUSY;
+ }
+ }
+ return 0;
+}
+
+static void floppy_release_regions(int fdc)
+{
+ floppy_release_allocated_regions(fdc, ARRAY_END(io_regions));
+}
+
static int floppy_grab_irq_and_dma(void)
{
unsigned long flags;
@@ -4399,18 +4439,8 @@ static int floppy_grab_irq_and_dma(void)
for (fdc = 0; fdc < N_FDC; fdc++) {
if (FDCS->address != -1) {
- if (!request_region(FDCS->address + 2, 4, "floppy")) {
- DPRINT("Floppy io-port 0x%04lx in use\n",
- FDCS->address + 2);
- goto cleanup1;
- }
- if (!request_region(FDCS->address + 7, 1, "floppy DIR")) {
- DPRINT("Floppy io-port 0x%04lx in use\n",
- FDCS->address + 7);
- goto cleanup2;
- }
- /* address + 6 is reserved, and may be taken by IDE.
- * Unfortunately, Adaptec doesn't know this :-(, */
+ if (floppy_request_regions(fdc))
+ goto cleanup;
}
}
for (fdc = 0; fdc < N_FDC; fdc++) {
@@ -4432,15 +4462,11 @@ static int floppy_grab_irq_and_dma(void)
fdc = 0;
irqdma_allocated = 1;
return 0;
-cleanup2:
- release_region(FDCS->address + 2, 4);
-cleanup1:
+cleanup:
fd_free_irq();
fd_free_dma();
- while (--fdc >= 0) {
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
- }
+ while (--fdc >= 0)
+ floppy_release_regions(fdc);
spin_lock_irqsave(&floppy_usage_lock, flags);
usage_count--;
spin_unlock_irqrestore(&floppy_usage_lock, flags);
@@ -4501,10 +4527,8 @@ static void floppy_release_irq_and_dma(void)
#endif
old_fdc = fdc;
for (fdc = 0; fdc < N_FDC; fdc++)
- if (FDCS->address != -1) {
- release_region(FDCS->address + 2, 4);
- release_region(FDCS->address + 7, 1);
- }
+ if (FDCS->address != -1)
+ floppy_release_regions(fdc);
fdc = old_fdc;
}
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 34f80fa6fed1..8299e2d3b611 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -549,6 +549,15 @@ static void do_nbd_request(struct request_queue * q)
BUG_ON(lo->magic != LO_MAGIC);
+ if (unlikely(!lo->sock)) {
+ printk(KERN_ERR "%s: Attempted send on closed socket\n",
+ lo->disk->disk_name);
+ req->errors++;
+ nbd_end_request(req);
+ spin_lock_irq(q->queue_lock);
+ continue;
+ }
+
spin_lock_irq(&lo->queue_lock);
list_add_tail(&req->queuelist, &lo->waiting_queue);
spin_unlock_irq(&lo->queue_lock);
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 9dfa27163001..c397b3ddba9b 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -422,7 +422,7 @@ static void xs(char *buf, char *targ, int len)
for (k = 0; k < len; k++) {
char c = *buf++;
- if (c != ' ' || c != l)
+ if (c != ' ' && c != l)
l = *targ++ = c;
}
if (l == ' ')
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 12fb816db7b0..69b7f8e77596 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -391,7 +391,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
*/
#ifdef CONFIG_USB_LIBUSUAL
-#define ub_usb_ids storage_usb_ids
+#define ub_usb_ids usb_storage_usb_ids
#else
static struct usb_device_id ub_usb_ids[] = {
@@ -2146,10 +2146,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
ep = &altsetting->endpoint[i].desc;
/* Is it a BULK endpoint? */
- if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_BULK) {
+ if (usb_endpoint_xfer_bulk(ep)) {
/* BULK in or out? */
- if (ep->bEndpointAddress & USB_DIR_IN) {
+ if (usb_endpoint_dir_in(ep)) {
if (ep_in == NULL)
ep_in = ep;
} else {
@@ -2168,9 +2167,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0);
sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0);
sc->send_bulk_pipe = usb_sndbulkpipe(dev,
- ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_out));
sc->recv_bulk_pipe = usb_rcvbulkpipe(dev,
- ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_in));
return 0;
}
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 918ef725de41..b6c8ce254359 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -40,6 +40,7 @@
#include <linux/hdreg.h>
#include <linux/cdrom.h>
#include <linux/module.h>
+#include <linux/scatterlist.h>
#include <xen/xenbus.h>
#include <xen/grant_table.h>
@@ -82,6 +83,7 @@ struct blkfront_info
enum blkif_state connected;
int ring_ref;
struct blkif_front_ring ring;
+ struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
unsigned int evtchn, irq;
struct request_queue *rq;
struct work_struct work;
@@ -204,12 +206,11 @@ static int blkif_queue_request(struct request *req)
struct blkfront_info *info = req->rq_disk->private_data;
unsigned long buffer_mfn;
struct blkif_request *ring_req;
- struct req_iterator iter;
- struct bio_vec *bvec;
unsigned long id;
unsigned int fsect, lsect;
- int ref;
+ int i, ref;
grant_ref_t gref_head;
+ struct scatterlist *sg;
if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
return 1;
@@ -238,12 +239,13 @@ static int blkif_queue_request(struct request *req)
if (blk_barrier_rq(req))
ring_req->operation = BLKIF_OP_WRITE_BARRIER;
- ring_req->nr_segments = 0;
- rq_for_each_segment(bvec, req, iter) {
- BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST);
- buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page));
- fsect = bvec->bv_offset >> 9;
- lsect = fsect + (bvec->bv_len >> 9) - 1;
+ ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
+ BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
+
+ for_each_sg(info->sg, sg, ring_req->nr_segments, i) {
+ buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg)));
+ fsect = sg->offset >> 9;
+ lsect = fsect + (sg->length >> 9) - 1;
/* install a grant reference. */
ref = gnttab_claim_grant_reference(&gref_head);
BUG_ON(ref == -ENOSPC);
@@ -254,16 +256,12 @@ static int blkif_queue_request(struct request *req)
buffer_mfn,
rq_data_dir(req) );
- info->shadow[id].frame[ring_req->nr_segments] =
- mfn_to_pfn(buffer_mfn);
-
- ring_req->seg[ring_req->nr_segments] =
+ info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn);
+ ring_req->seg[i] =
(struct blkif_request_segment) {
.gref = ref,
.first_sect = fsect,
.last_sect = lsect };
-
- ring_req->nr_segments++;
}
info->ring.req_prod_pvt++;
@@ -622,6 +620,8 @@ static int setup_blkring(struct xenbus_device *dev,
SHARED_RING_INIT(sring);
FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
+ sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+
err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
if (err < 0) {
free_page((unsigned long)sring);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index f5be8081cd81..735bbe2be51a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -761,7 +761,7 @@ source "drivers/char/hw_random/Kconfig"
config NVRAM
tristate "/dev/nvram support"
- depends on ATARI || X86 || ARM || GENERIC_NVRAM
+ depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM
---help---
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index a53496828b76..54481a887769 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -13,10 +13,11 @@
#include <linux/types.h>
#include <asm/ebcdic.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mempool.h>
-#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/tty.h>
#include <linux/wait.h>
#include <net/iucv/iucv.h>
@@ -95,6 +96,12 @@ static unsigned long hvc_iucv_devices = 1;
/* Array of allocated hvc iucv tty lines... */
static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
#define IUCV_HVC_CON_IDX (0)
+/* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
+#define MAX_VMID_FILTER (500)
+static size_t hvc_iucv_filter_size;
+static void *hvc_iucv_filter;
+static const char *hvc_iucv_filter_string;
+static DEFINE_RWLOCK(hvc_iucv_filter_lock);
/* Kmem cache and mempool for iucv_tty_buffer elements */
static struct kmem_cache *hvc_iucv_buffer_cache;
@@ -618,6 +625,27 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
}
/**
+ * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
+ * @ipvmid: Originating z/VM user ID (right padded with blanks)
+ *
+ * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
+ * non-zero.
+ */
+static int hvc_iucv_filter_connreq(u8 ipvmid[8])
+{
+ size_t i;
+
+ /* Note: default policy is ACCEPT if no filter is set */
+ if (!hvc_iucv_filter_size)
+ return 0;
+
+ for (i = 0; i < hvc_iucv_filter_size; i++)
+ if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
+ return 0;
+ return 1;
+}
+
+/**
* hvc_iucv_path_pending() - IUCV handler to process a connection request.
* @path: Pending path (struct iucv_path)
* @ipvmid: z/VM system identifier of originator
@@ -641,6 +669,7 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
{
struct hvc_iucv_private *priv;
u8 nuser_data[16];
+ u8 vm_user_id[9];
int i, rc;
priv = NULL;
@@ -653,6 +682,20 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
if (!priv)
return -ENODEV;
+ /* Enforce that ipvmid is allowed to connect to us */
+ read_lock(&hvc_iucv_filter_lock);
+ rc = hvc_iucv_filter_connreq(ipvmid);
+ read_unlock(&hvc_iucv_filter_lock);
+ if (rc) {
+ iucv_path_sever(path, ipuser);
+ iucv_path_free(path);
+ memcpy(vm_user_id, ipvmid, 8);
+ vm_user_id[8] = 0;
+ pr_info("A connection request from z/VM user ID %s "
+ "was refused\n", vm_user_id);
+ return 0;
+ }
+
spin_lock(&priv->lock);
/* If the terminal is already connected or being severed, then sever
@@ -877,6 +920,171 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
}
/**
+ * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
+ * @filter: String containing a comma-separated list of z/VM user IDs
+ */
+static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
+{
+ const char *nextdelim, *residual;
+ size_t len;
+
+ nextdelim = strchr(filter, ',');
+ if (nextdelim) {
+ len = nextdelim - filter;
+ residual = nextdelim + 1;
+ } else {
+ len = strlen(filter);
+ residual = filter + len;
+ }
+
+ if (len == 0)
+ return ERR_PTR(-EINVAL);
+
+ /* check for '\n' (if called from sysfs) */
+ if (filter[len - 1] == '\n')
+ len--;
+
+ if (len > 8)
+ return ERR_PTR(-EINVAL);
+
+ /* pad with blanks and save upper case version of user ID */
+ memset(dest, ' ', 8);
+ while (len--)
+ dest[len] = toupper(filter[len]);
+ return residual;
+}
+
+/**
+ * hvc_iucv_setup_filter() - Set up z/VM user ID filter
+ * @filter: String consisting of a comma-separated list of z/VM user IDs
+ *
+ * The function parses the @filter string and creates an array containing
+ * the list of z/VM user ID filter entries.
+ * Return code 0 means success, -EINVAL if the filter is syntactically
+ * incorrect, -ENOMEM if there was not enough memory to allocate the
+ * filter list array, or -ENOSPC if too many z/VM user IDs have been specified.
+ */
+static int hvc_iucv_setup_filter(const char *val)
+{
+ const char *residual;
+ int err;
+ size_t size, count;
+ void *array, *old_filter;
+
+ count = strlen(val);
+ if (count == 0 || (count == 1 && val[0] == '\n')) {
+ size = 0;
+ array = NULL;
+ goto out_replace_filter; /* clear filter */
+ }
+
+ /* count user IDs in order to allocate sufficient memory */
+ size = 1;
+ residual = val;
+ while ((residual = strchr(residual, ',')) != NULL) {
+ residual++;
+ size++;
+ }
+
+ /* check if the specified list exceeds the filter limit */
+ if (size > MAX_VMID_FILTER)
+ return -ENOSPC;
+
+ array = kzalloc(size * 8, GFP_KERNEL);
+ if (!array)
+ return -ENOMEM;
+
+ count = size;
+ residual = val;
+ while (*residual && count) {
+ residual = hvc_iucv_parse_filter(residual,
+ array + ((size - count) * 8));
+ if (IS_ERR(residual)) {
+ err = PTR_ERR(residual);
+ kfree(array);
+ goto out_err;
+ }
+ count--;
+ }
+
+out_replace_filter:
+ write_lock_bh(&hvc_iucv_filter_lock);
+ old_filter = hvc_iucv_filter;
+ hvc_iucv_filter_size = size;
+ hvc_iucv_filter = array;
+ write_unlock_bh(&hvc_iucv_filter_lock);
+ kfree(old_filter);
+
+ err = 0;
+out_err:
+ return err;
+}
+
+/**
+ * param_set_vmidfilter() - Set z/VM user ID filter parameter
+ * @val: String consisting of a comma-separated list of z/VM user IDs
+ * @kp: Kernel parameter pointing to hvc_iucv_filter array
+ *
+ * The function sets up the z/VM user ID filter specified as comma-separated
+ * list of user IDs in @val.
+ * Note: If it is called early in the boot process, @val is stored and
+ * parsed later in hvc_iucv_init().
+ */
+static int param_set_vmidfilter(const char *val, struct kernel_param *kp)
+{
+ int rc;
+
+ if (!MACHINE_IS_VM || !hvc_iucv_devices)
+ return -ENODEV;
+
+ if (!val)
+ return -EINVAL;
+
+ rc = 0;
+ if (slab_is_available())
+ rc = hvc_iucv_setup_filter(val);
+ else
+ hvc_iucv_filter_string = val; /* defer... */
+ return rc;
+}
+
+/**
+ * param_get_vmidfilter() - Get z/VM user ID filter
+ * @buffer: Buffer to store z/VM user ID filter,
+ * (buffer size assumption PAGE_SIZE)
+ * @kp: Kernel parameter pointing to the hvc_iucv_filter array
+ *
+ * The function stores the filter as a comma-separated list of z/VM user IDs
+ * in @buffer. Typically, sysfs routines call this function for attr show.
+ */
+static int param_get_vmidfilter(char *buffer, struct kernel_param *kp)
+{
+ int rc;
+ size_t index, len;
+ void *start, *end;
+
+ if (!MACHINE_IS_VM || !hvc_iucv_devices)
+ return -ENODEV;
+
+ rc = 0;
+ read_lock_bh(&hvc_iucv_filter_lock);
+ for (index = 0; index < hvc_iucv_filter_size; index++) {
+ start = hvc_iucv_filter + (8 * index);
+ end = memchr(start, ' ', 8);
+ len = (end) ? end - start : 8;
+ memcpy(buffer + rc, start, len);
+ rc += len;
+ buffer[rc++] = ',';
+ }
+ read_unlock_bh(&hvc_iucv_filter_lock);
+ if (rc)
+ buffer[--rc] = '\0'; /* replace last comma and update rc */
+ return rc;
+}
+
+#define param_check_vmidfilter(name, p) __param_check(name, p, void)
+
+/**
* hvc_iucv_init() - z/VM IUCV HVC device driver initialization
*/
static int __init hvc_iucv_init(void)
@@ -884,24 +1092,53 @@ static int __init hvc_iucv_init(void)
int rc;
unsigned int i;
+ if (!hvc_iucv_devices)
+ return -ENODEV;
+
if (!MACHINE_IS_VM) {
- pr_info("The z/VM IUCV HVC device driver cannot "
+ pr_notice("The z/VM IUCV HVC device driver cannot "
"be used without z/VM\n");
- return -ENODEV;
+ rc = -ENODEV;
+ goto out_error;
}
- if (!hvc_iucv_devices)
- return -ENODEV;
+ if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
+ pr_err("%lu is not a valid value for the hvc_iucv= "
+ "kernel parameter\n", hvc_iucv_devices);
+ rc = -EINVAL;
+ goto out_error;
+ }
- if (hvc_iucv_devices > MAX_HVC_IUCV_LINES)
- return -EINVAL;
+ /* parse hvc_iucv_allow string and create z/VM user ID filter list */
+ if (hvc_iucv_filter_string) {
+ rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
+ switch (rc) {
+ case 0:
+ break;
+ case -ENOMEM:
+ pr_err("Allocating memory failed with "
+ "reason code=%d\n", 3);
+ goto out_error;
+ case -EINVAL:
+ pr_err("hvc_iucv_allow= does not specify a valid "
+ "z/VM user ID list\n");
+ goto out_error;
+ case -ENOSPC:
+ pr_err("hvc_iucv_allow= specifies too many "
+ "z/VM user IDs\n");
+ goto out_error;
+ default:
+ goto out_error;
+ }
+ }
hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
sizeof(struct iucv_tty_buffer),
0, 0, NULL);
if (!hvc_iucv_buffer_cache) {
pr_err("Allocating memory failed with reason code=%d\n", 1);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out_error;
}
hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
@@ -909,7 +1146,8 @@ static int __init hvc_iucv_init(void)
if (!hvc_iucv_mempool) {
pr_err("Allocating memory failed with reason code=%d\n", 2);
kmem_cache_destroy(hvc_iucv_buffer_cache);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out_error;
}
/* register the first terminal device as console
@@ -953,6 +1191,8 @@ out_error_hvc:
out_error_memory:
mempool_destroy(hvc_iucv_mempool);
kmem_cache_destroy(hvc_iucv_buffer_cache);
+out_error:
+ hvc_iucv_devices = 0; /* ensure that we do not provide any device */
return rc;
}
@@ -968,3 +1208,4 @@ static int __init hvc_iucv_config(char *val)
device_initcall(hvc_iucv_init);
__setup("hvc_iucv=", hvc_iucv_config);
+core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index d4e7dca06e4f..ba68a4671cb5 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -102,7 +102,7 @@ static int __init omap_rng_probe(struct platform_device *pdev)
return -EBUSY;
if (cpu_is_omap24xx()) {
- rng_ick = clk_get(NULL, "rng_ick");
+ rng_ick = clk_get(&pdev->dev, "rng_ick");
if (IS_ERR(rng_ick)) {
dev_err(&pdev->dev, "Could not get rng_ick\n");
ret = PTR_ERR(rng_ick);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7c13581ca9cd..7c43ae782b26 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -241,6 +241,10 @@
#include <linux/percpu.h>
#include <linux/cryptohash.h>
+#ifdef CONFIG_GENERIC_HARDIRQS
+# include <linux/irq.h>
+#endif
+
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
unsigned dont_count_entropy:1;
};
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
static struct timer_rand_state *irq_timer_state[NR_IRQS];
diff --git a/drivers/char/scc.h b/drivers/char/scc.h
index 93998f5baff5..341b1142bea8 100644
--- a/drivers/char/scc.h
+++ b/drivers/char/scc.h
@@ -387,7 +387,7 @@ struct scc_port {
/* The SCC needs 3.5 PCLK cycles recovery time between to register
* accesses. PCLK runs with 8 MHz on an Atari, so this delay is 3.5 *
* 125 ns = 437.5 ns. This is too short for udelay().
- * 10/16/95: A tstb mfp.par_dt_reg takes 600ns (sure?) and thus should be
+ * 10/16/95: A tstb st_mfp.par_dt_reg takes 600ns (sure?) and thus should be
* quite right
*/
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index f29fbe9b8ed7..cb8ca5698963 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -268,7 +268,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
/* Allocate a new buffer before freeing the old one ... */
multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */
- bp = kmalloc((sel_end-sel_start)/2*multiplier+1, GFP_KERNEL);
+ bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL);
if (!bp) {
printk(KERN_WARNING "selection: kmalloc() failed\n");
clear_selection();
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index b60be7b0decf..518f2a25d91e 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1713,8 +1713,8 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
for (i = 0; i < SX_NBOARDS; i++)
sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags);
sx_dprintk(SX_DEBUG_FIRMWARE, "\n");
- unlock_kernel();
- return -EIO;
+ rc = -EIO;
+ goto out;
}
switch (cmd) {
@@ -1746,8 +1746,10 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc);
break;
case SXIO_DO_RAMTEST:
- if (sx_initialized) /* Already initialized: better not ramtest the board. */
- return -EPERM;
+ if (sx_initialized) { /* Already initialized: better not ramtest the board. */
+ rc = -EPERM;
+ break;
+ }
if (IS_SX_BOARD(board)) {
rc = do_memtest(board, 0, 0x7000);
if (!rc)
@@ -1787,7 +1789,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
nbytes - i : SX_CHUNK_SIZE)) {
kfree(tmp);
rc = -EFAULT;
- break;
+ goto out;
}
memcpy_toio(board->base2 + offset + i, tmp,
(i + SX_CHUNK_SIZE > nbytes) ?
@@ -1844,6 +1846,7 @@ static long sx_fw_ioctl(struct file *filp, unsigned int cmd,
rc = -ENOTTY;
break;
}
+out:
unlock_kernel();
func_exit();
return rc;
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 33a9351c896d..6f8579d7d654 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,7 +35,7 @@
#include <linux/vt_kern.h>
#include <linux/workqueue.h>
#include <linux/kexec.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/hrtimer.h>
#include <linux/oom.h>
@@ -283,7 +283,7 @@ static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
}
static struct sysrq_key_op sysrq_ftrace_dump_op = {
.handler = sysrq_ftrace_dump,
- .help_msg = "dumpZ-ftrace-buffer",
+ .help_msg = "dump-ftrace-buffer(Z)",
.action_msg = "Dump ftrace buffer",
.enable_mask = SYSRQ_ENABLE_DUMP,
};
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index d0e7926eb486..c64a1bc65349 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
}
}
-static struct device_driver atml_drv = {
- .name = "tpm_atmel",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_atml_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver atml_drv = {
+ .driver = {
+ .name = "tpm_atmel",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_atml_suspend,
+ .resume = tpm_atml_resume,
};
static int __init init_atmel(void)
@@ -184,7 +194,7 @@ static int __init init_atmel(void)
unsigned long base;
struct tpm_chip *chip;
- rc = driver_register(&atml_drv);
+ rc = platform_driver_register(&atml_drv);
if (rc)
return rc;
@@ -223,13 +233,13 @@ err_rel_reg:
atmel_release_region(base,
region_size);
err_unreg_drv:
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
return rc;
}
static void __exit cleanup_atmel(void)
{
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
atml_plat_remove();
}
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 726ee8a0277f..ecba4942fc8e 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -4,7 +4,7 @@
* SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
* Specifications at www.trustedcomputinggroup.org
*
- * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
+ * Copyright (C) 2005, Marcel Selhorst <m.selhorst@sirrix.com>
* Sirrix AG - security technologies, http://www.sirrix.com and
* Applied Data Security Group, Ruhr-University Bochum, Germany
* Project-Homepage: http://www.prosec.rub.de/tpm
@@ -636,7 +636,7 @@ static void __exit cleanup_inf(void)
module_init(init_inf);
module_exit(cleanup_inf);
-MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
+MODULE_AUTHOR("Marcel Selhorst <m.selhorst@sirrix.com>");
MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
MODULE_VERSION("1.9");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 717af7ad1bdf..aec1931608aa 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
-static struct device_driver tis_drv = {
- .name = "tpm_tis",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_tis_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver tis_drv = {
+ .driver = {
+ .name = "tpm_tis",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_tis_suspend,
+ .resume = tpm_tis_resume,
};
static struct platform_device *pdev;
@@ -672,14 +682,14 @@ static int __init init_tis(void)
int rc;
if (force) {
- rc = driver_register(&tis_drv);
+ rc = platform_driver_register(&tis_drv);
if (rc < 0)
return rc;
if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
return PTR_ERR(pdev);
if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
}
return rc;
}
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void)
if (force) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
} else
pnp_unregister_driver(&tis_pnp_driver);
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index d33e5ab06177..bc84e125c6bc 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1817,8 +1817,10 @@ got_driver:
/* check whether we're reopening an existing tty */
tty = tty_driver_lookup_tty(driver, inode, index);
- if (IS_ERR(tty))
+ if (IS_ERR(tty)) {
+ mutex_unlock(&tty_mutex);
return PTR_ERR(tty);
+ }
}
if (tty) {
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 1525882190fd..1efb2879a94f 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
+obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index e1129fad96dd..ee19b6e8fcb4 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -143,7 +143,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
#endif
#ifndef CONFIG_X86_64
-#include "mach_timer.h"
+#include <asm/mach_timer.h>
#define PMTMR_EXPECTED_RATE \
((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10))
/*
diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c
index 1bde303b970b..8615059a8729 100644
--- a/drivers/clocksource/cyclone.c
+++ b/drivers/clocksource/cyclone.c
@@ -7,7 +7,7 @@
#include <asm/pgtable.h>
#include <asm/io.h>
-#include "mach_timer.h"
+#include <asm/mach_timer.h>
#define CYCLONE_CBAR_ADDR 0xFEB00CD0 /* base address ptr */
#define CYCLONE_PMCC_OFFSET 0x51A0 /* offset to control register */
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
new file mode 100644
index 000000000000..7783b42f6914
--- /dev/null
+++ b/drivers/clocksource/sh_cmt.c
@@ -0,0 +1,615 @@
+/*
+ * SuperH Timer Support - CMT
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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/init.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/sh_cmt.h>
+
+struct sh_cmt_priv {
+ void __iomem *mapbase;
+ struct clk *clk;
+ unsigned long width; /* 16 or 32 bit version of hardware block */
+ unsigned long overflow_bit;
+ unsigned long clear_bits;
+ struct irqaction irqaction;
+ struct platform_device *pdev;
+
+ unsigned long flags;
+ unsigned long match_value;
+ unsigned long next_match_value;
+ unsigned long max_match_value;
+ unsigned long rate;
+ spinlock_t lock;
+ struct clock_event_device ced;
+ unsigned long total_cycles;
+};
+
+static DEFINE_SPINLOCK(sh_cmt_lock);
+
+#define CMSTR -1 /* shared register */
+#define CMCSR 0 /* channel register */
+#define CMCNT 1 /* channel register */
+#define CMCOR 2 /* channel register */
+
+static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == CMSTR) {
+ offs = 0;
+ base -= cfg->channel_offset;
+ } else
+ offs = reg_nr;
+
+ if (p->width == 16)
+ offs <<= 1;
+ else {
+ offs <<= 2;
+ if ((reg_nr == CMCNT) || (reg_nr == CMCOR))
+ return ioread32(base + offs);
+ }
+
+ return ioread16(base + offs);
+}
+
+static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
+ unsigned long value)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == CMSTR) {
+ offs = 0;
+ base -= cfg->channel_offset;
+ } else
+ offs = reg_nr;
+
+ if (p->width == 16)
+ offs <<= 1;
+ else {
+ offs <<= 2;
+ if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) {
+ iowrite32(value, base + offs);
+ return;
+ }
+ }
+
+ iowrite16(value, base + offs);
+}
+
+static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
+ int *has_wrapped)
+{
+ unsigned long v1, v2, v3;
+
+ /* Make sure the timer value is stable. Stolen from acpi_pm.c */
+ do {
+ v1 = sh_cmt_read(p, CMCNT);
+ v2 = sh_cmt_read(p, CMCNT);
+ v3 = sh_cmt_read(p, CMCNT);
+ } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+ || (v3 > v1 && v3 < v2)));
+
+ *has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+ return v2;
+}
+
+
+static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ unsigned long flags, value;
+
+ /* start stop register shared by multiple timer channels */
+ spin_lock_irqsave(&sh_cmt_lock, flags);
+ value = sh_cmt_read(p, CMSTR);
+
+ if (start)
+ value |= 1 << cfg->timer_bit;
+ else
+ value &= ~(1 << cfg->timer_bit);
+
+ sh_cmt_write(p, CMSTR, value);
+ spin_unlock_irqrestore(&sh_cmt_lock, flags);
+}
+
+static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ int ret;
+
+ /* enable clock */
+ ret = clk_enable(p->clk);
+ if (ret) {
+ pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk);
+ return ret;
+ }
+ *rate = clk_get_rate(p->clk) / 8;
+
+ /* make sure channel is disabled */
+ sh_cmt_start_stop_ch(p, 0);
+
+ /* configure channel, periodic mode and maximum timeout */
+ if (p->width == 16)
+ sh_cmt_write(p, CMCSR, 0);
+ else
+ sh_cmt_write(p, CMCSR, 0x01a4);
+
+ sh_cmt_write(p, CMCOR, 0xffffffff);
+ sh_cmt_write(p, CMCNT, 0);
+
+ /* enable channel */
+ sh_cmt_start_stop_ch(p, 1);
+ return 0;
+}
+
+static void sh_cmt_disable(struct sh_cmt_priv *p)
+{
+ /* disable channel */
+ sh_cmt_start_stop_ch(p, 0);
+
+ /* stop clock */
+ clk_disable(p->clk);
+}
+
+/* private flags */
+#define FLAG_CLOCKEVENT (1 << 0)
+#define FLAG_CLOCKSOURCE (1 << 1)
+#define FLAG_REPROGRAM (1 << 2)
+#define FLAG_SKIPEVENT (1 << 3)
+#define FLAG_IRQCONTEXT (1 << 4)
+
+static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
+ int absolute)
+{
+ unsigned long new_match;
+ unsigned long value = p->next_match_value;
+ unsigned long delay = 0;
+ unsigned long now = 0;
+ int has_wrapped;
+
+ now = sh_cmt_get_counter(p, &has_wrapped);
+ p->flags |= FLAG_REPROGRAM; /* force reprogram */
+
+ if (has_wrapped) {
+ /* we're competing with the interrupt handler.
+ * -> let the interrupt handler reprogram the timer.
+ * -> interrupt number two handles the event.
+ */
+ p->flags |= FLAG_SKIPEVENT;
+ return;
+ }
+
+ if (absolute)
+ now = 0;
+
+ do {
+ /* reprogram the timer hardware,
+ * but don't save the new match value yet.
+ */
+ new_match = now + value + delay;
+ if (new_match > p->max_match_value)
+ new_match = p->max_match_value;
+
+ sh_cmt_write(p, CMCOR, new_match);
+
+ now = sh_cmt_get_counter(p, &has_wrapped);
+ if (has_wrapped && (new_match > p->match_value)) {
+ /* we are changing to a greater match value,
+ * so this wrap must be caused by the counter
+ * matching the old value.
+ * -> first interrupt reprograms the timer.
+ * -> interrupt number two handles the event.
+ */
+ p->flags |= FLAG_SKIPEVENT;
+ break;
+ }
+
+ if (has_wrapped) {
+ /* we are changing to a smaller match value,
+ * so the wrap must be caused by the counter
+ * matching the new value.
+ * -> save programmed match value.
+ * -> let isr handle the event.
+ */
+ p->match_value = new_match;
+ break;
+ }
+
+ /* be safe: verify hardware settings */
+ if (now < new_match) {
+ /* timer value is below match value, all good.
+ * this makes sure we won't miss any match events.
+ * -> save programmed match value.
+ * -> let isr handle the event.
+ */
+ p->match_value = new_match;
+ break;
+ }
+
+ /* the counter has reached a value greater
+ * than our new match value. and since the
+ * has_wrapped flag isn't set we must have
+ * programmed a too close event.
+ * -> increase delay and retry.
+ */
+ if (delay)
+ delay <<= 1;
+ else
+ delay = 1;
+
+ if (!delay)
+ pr_warning("sh_cmt: too long delay\n");
+
+ } while (delay);
+}
+
+static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+{
+ unsigned long flags;
+
+ if (delta > p->max_match_value)
+ pr_warning("sh_cmt: delta out of range\n");
+
+ spin_lock_irqsave(&p->lock, flags);
+ p->next_match_value = delta;
+ sh_cmt_clock_event_program_verify(p, 0);
+ spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
+{
+ struct sh_cmt_priv *p = dev_id;
+
+ /* clear flags */
+ sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
+
+ /* update clock source counter to begin with if enabled
+ * the wrap flag should be cleared by the timer specific
+ * isr before we end up here.
+ */
+ if (p->flags & FLAG_CLOCKSOURCE)
+ p->total_cycles += p->match_value;
+
+ if (!(p->flags & FLAG_REPROGRAM))
+ p->next_match_value = p->max_match_value;
+
+ p->flags |= FLAG_IRQCONTEXT;
+
+ if (p->flags & FLAG_CLOCKEVENT) {
+ if (!(p->flags & FLAG_SKIPEVENT)) {
+ if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
+ p->next_match_value = p->max_match_value;
+ p->flags |= FLAG_REPROGRAM;
+ }
+
+ p->ced.event_handler(&p->ced);
+ }
+ }
+
+ p->flags &= ~FLAG_SKIPEVENT;
+
+ if (p->flags & FLAG_REPROGRAM) {
+ p->flags &= ~FLAG_REPROGRAM;
+ sh_cmt_clock_event_program_verify(p, 1);
+
+ if (p->flags & FLAG_CLOCKEVENT)
+ if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
+ || (p->match_value == p->next_match_value))
+ p->flags &= ~FLAG_REPROGRAM;
+ }
+
+ p->flags &= ~FLAG_IRQCONTEXT;
+
+ return IRQ_HANDLED;
+}
+
+static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&p->lock, flags);
+
+ if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ ret = sh_cmt_enable(p, &p->rate);
+
+ if (ret)
+ goto out;
+ p->flags |= flag;
+
+ /* setup timeout if no clockevent */
+ if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
+ sh_cmt_set_next(p, p->max_match_value);
+ out:
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ return ret;
+}
+
+static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
+{
+ unsigned long flags;
+ unsigned long f;
+
+ spin_lock_irqsave(&p->lock, flags);
+
+ f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
+ p->flags &= ~flag;
+
+ if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ sh_cmt_disable(p);
+
+ /* adjust the timeout to maximum if only clocksource left */
+ if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
+ sh_cmt_set_next(p, p->max_match_value);
+
+ spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
+{
+ return container_of(ced, struct sh_cmt_priv, ced);
+}
+
+static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ sh_cmt_start(p, FLAG_CLOCKEVENT);
+
+ /* TODO: calculate good shift from rate and counter bit width */
+
+ ced->shift = 32;
+ ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
+ ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
+ ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
+
+ if (periodic)
+ sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
+ else
+ sh_cmt_set_next(p, p->max_match_value);
+}
+
+static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
+ struct clock_event_device *ced)
+{
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ /* deal with old setting first */
+ switch (ced->mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_ONESHOT:
+ sh_cmt_stop(p, FLAG_CLOCKEVENT);
+ break;
+ default:
+ break;
+ }
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_info("sh_cmt: %s used for periodic clock events\n",
+ ced->name);
+ sh_cmt_clock_event_start(p, 1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ pr_info("sh_cmt: %s used for oneshot clock events\n",
+ ced->name);
+ sh_cmt_clock_event_start(p, 0);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ sh_cmt_stop(p, FLAG_CLOCKEVENT);
+ break;
+ default:
+ break;
+ }
+}
+
+static int sh_cmt_clock_event_next(unsigned long delta,
+ struct clock_event_device *ced)
+{
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
+ if (likely(p->flags & FLAG_IRQCONTEXT))
+ p->next_match_value = delta;
+ else
+ sh_cmt_set_next(p, delta);
+
+ return 0;
+}
+
+static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
+ char *name, unsigned long rating)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ memset(ced, 0, sizeof(*ced));
+
+ ced->name = name;
+ ced->features = CLOCK_EVT_FEAT_PERIODIC;
+ ced->features |= CLOCK_EVT_FEAT_ONESHOT;
+ ced->rating = rating;
+ ced->cpumask = cpumask_of(0);
+ ced->set_next_event = sh_cmt_clock_event_next;
+ ced->set_mode = sh_cmt_clock_event_mode;
+
+ pr_info("sh_cmt: %s used for clock events\n", ced->name);
+ ced->mult = 1; /* work around misplaced WARN_ON() in clockevents.c */
+ clockevents_register_device(ced);
+}
+
+int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+ unsigned long clockevent_rating,
+ unsigned long clocksource_rating)
+{
+ if (p->width == (sizeof(p->max_match_value) * 8))
+ p->max_match_value = ~0;
+ else
+ p->max_match_value = (1 << p->width) - 1;
+
+ p->match_value = p->max_match_value;
+ spin_lock_init(&p->lock);
+
+ if (clockevent_rating)
+ sh_cmt_register_clockevent(p, name, clockevent_rating);
+
+ return 0;
+}
+
+static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+{
+ struct sh_cmt_config *cfg = pdev->dev.platform_data;
+ struct resource *res;
+ int irq, ret;
+ ret = -ENXIO;
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ if (!cfg) {
+ dev_err(&p->pdev->dev, "missing platform data\n");
+ goto err0;
+ }
+
+ platform_set_drvdata(pdev, p);
+
+ res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ goto err0;
+ }
+
+ irq = platform_get_irq(p->pdev, 0);
+ if (irq < 0) {
+ dev_err(&p->pdev->dev, "failed to get irq\n");
+ goto err0;
+ }
+
+ /* map memory, let mapbase point to our channel */
+ p->mapbase = ioremap_nocache(res->start, resource_size(res));
+ if (p->mapbase == NULL) {
+ pr_err("sh_cmt: failed to remap I/O memory\n");
+ goto err0;
+ }
+
+ /* request irq using setup_irq() (too early for request_irq()) */
+ p->irqaction.name = cfg->name;
+ p->irqaction.handler = sh_cmt_interrupt;
+ p->irqaction.dev_id = p;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+ p->irqaction.mask = CPU_MASK_NONE;
+ ret = setup_irq(irq, &p->irqaction);
+ if (ret) {
+ pr_err("sh_cmt: failed to request irq %d\n", irq);
+ goto err1;
+ }
+
+ /* get hold of clock */
+ p->clk = clk_get(&p->pdev->dev, cfg->clk);
+ if (IS_ERR(p->clk)) {
+ pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
+ ret = PTR_ERR(p->clk);
+ goto err2;
+ }
+
+ if (resource_size(res) == 6) {
+ p->width = 16;
+ p->overflow_bit = 0x80;
+ p->clear_bits = ~0xc0;
+ } else {
+ p->width = 32;
+ p->overflow_bit = 0x8000;
+ p->clear_bits = ~0xc000;
+ }
+
+ return sh_cmt_register(p, cfg->name,
+ cfg->clockevent_rating,
+ cfg->clocksource_rating);
+ err2:
+ free_irq(irq, p);
+ err1:
+ iounmap(p->mapbase);
+ err0:
+ return ret;
+}
+
+static int __devinit sh_cmt_probe(struct platform_device *pdev)
+{
+ struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+ int ret;
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ ret = sh_cmt_setup(p, pdev);
+ if (ret) {
+ kfree(p);
+
+ platform_set_drvdata(pdev, NULL);
+ }
+ return ret;
+}
+
+static int __devexit sh_cmt_remove(struct platform_device *pdev)
+{
+ return -EBUSY; /* cannot unregister clockevent and clocksource */
+}
+
+static struct platform_driver sh_cmt_device_driver = {
+ .probe = sh_cmt_probe,
+ .remove = __devexit_p(sh_cmt_remove),
+ .driver = {
+ .name = "sh_cmt",
+ }
+};
+
+static int __init sh_cmt_init(void)
+{
+ return platform_driver_register(&sh_cmt_device_driver);
+}
+
+static void __exit sh_cmt_exit(void)
+{
+ platform_driver_unregister(&sh_cmt_device_driver);
+}
+
+module_init(sh_cmt_init);
+module_exit(sh_cmt_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("SuperH CMT Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 6a2b036c9389..6f45b1658a67 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -117,11 +117,7 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
-
- if (!dbs_tuners_ins.ignore_nice) {
- busy_time = cputime64_add(busy_time,
- kstat_cpu(cpu).cpustat.nice);
- }
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice);
idle_time = cputime64_sub(cur_wall_time, busy_time);
if (wall)
@@ -137,23 +133,6 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
if (idle_time == -1ULL)
return get_cpu_idle_time_jiffy(cpu, wall);
- if (dbs_tuners_ins.ignore_nice) {
- cputime64_t cur_nice;
- unsigned long cur_nice_jiffies;
- struct cpu_dbs_info_s *dbs_info;
-
- dbs_info = &per_cpu(cpu_dbs_info, cpu);
- cur_nice = cputime64_sub(kstat_cpu(cpu).cpustat.nice,
- dbs_info->prev_cpu_nice);
- /*
- * Assumption: nice time between sampling periods will be
- * less than 2^32 jiffies for 32 bit sys
- */
- cur_nice_jiffies = (unsigned long)
- cputime64_to_jiffies64(cur_nice);
- dbs_info->prev_cpu_nice = kstat_cpu(cpu).cpustat.nice;
- return idle_time + jiffies_to_usecs(cur_nice_jiffies);
- }
return idle_time;
}
@@ -319,6 +298,9 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
dbs_info = &per_cpu(cpu_dbs_info, j);
dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
&dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice)
+ dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
+
}
mutex_unlock(&dbs_mutex);
@@ -419,6 +401,23 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
j_dbs_info->prev_cpu_idle);
j_dbs_info->prev_cpu_idle = cur_idle_time;
+ if (dbs_tuners_ins.ignore_nice) {
+ cputime64_t cur_nice;
+ unsigned long cur_nice_jiffies;
+
+ cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice,
+ j_dbs_info->prev_cpu_nice);
+ /*
+ * Assumption: nice time between sampling periods will
+ * be less than 2^32 jiffies for 32 bit sys
+ */
+ cur_nice_jiffies = (unsigned long)
+ cputime64_to_jiffies64(cur_nice);
+
+ j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
+ idle_time += jiffies_to_usecs(cur_nice_jiffies);
+ }
+
if (unlikely(!wall_time || wall_time < idle_time))
continue;
@@ -575,6 +574,10 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
&j_dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice) {
+ j_dbs_info->prev_cpu_nice =
+ kstat_cpu(j).cpustat.nice;
+ }
}
this_dbs_info->cpu = cpu;
/*
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
index 55433849bfa6..33bd75347518 100644
--- a/drivers/dca/dca-core.c
+++ b/drivers/dca/dca-core.c
@@ -28,7 +28,7 @@
#include <linux/device.h>
#include <linux/dca.h>
-#define DCA_VERSION "1.4"
+#define DCA_VERSION "1.8"
MODULE_VERSION(DCA_VERSION);
MODULE_LICENSE("GPL");
@@ -60,16 +60,17 @@ int dca_add_requester(struct device *dev)
{
struct dca_provider *dca;
int err, slot = -ENODEV;
+ unsigned long flags;
if (!dev)
return -EFAULT;
- spin_lock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
/* check if the requester has not been added already */
dca = dca_find_provider_by_dev(dev);
if (dca) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return -EEXIST;
}
@@ -78,19 +79,21 @@ int dca_add_requester(struct device *dev)
if (slot >= 0)
break;
}
- if (slot < 0) {
- spin_unlock(&dca_lock);
+
+ spin_unlock_irqrestore(&dca_lock, flags);
+
+ if (slot < 0)
return slot;
- }
err = dca_sysfs_add_req(dca, dev, slot);
if (err) {
- dca->ops->remove_requester(dca, dev);
- spin_unlock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
+ if (dca == dca_find_provider_by_dev(dev))
+ dca->ops->remove_requester(dca, dev);
+ spin_unlock_irqrestore(&dca_lock, flags);
return err;
}
- spin_unlock(&dca_lock);
return 0;
}
EXPORT_SYMBOL_GPL(dca_add_requester);
@@ -103,25 +106,25 @@ int dca_remove_requester(struct device *dev)
{
struct dca_provider *dca;
int slot;
+ unsigned long flags;
if (!dev)
return -EFAULT;
- spin_lock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
dca = dca_find_provider_by_dev(dev);
if (!dca) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return -ENODEV;
}
slot = dca->ops->remove_requester(dca, dev);
- if (slot < 0) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
+
+ if (slot < 0)
return slot;
- }
dca_sysfs_remove_req(dca, slot);
- spin_unlock(&dca_lock);
return 0;
}
EXPORT_SYMBOL_GPL(dca_remove_requester);
@@ -135,17 +138,18 @@ u8 dca_common_get_tag(struct device *dev, int cpu)
{
struct dca_provider *dca;
u8 tag;
+ unsigned long flags;
- spin_lock(&dca_lock);
+ spin_lock_irqsave(&dca_lock, flags);
dca = dca_find_provider_by_dev(dev);
if (!dca) {
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return -ENODEV;
}
tag = dca->ops->get_tag(dca, dev, cpu);
- spin_unlock(&dca_lock);
+ spin_unlock_irqrestore(&dca_lock, flags);
return tag;
}
@@ -217,11 +221,16 @@ static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
int register_dca_provider(struct dca_provider *dca, struct device *dev)
{
int err;
+ unsigned long flags;
err = dca_sysfs_add_provider(dca, dev);
if (err)
return err;
+
+ spin_lock_irqsave(&dca_lock, flags);
list_add(&dca->node, &dca_providers);
+ spin_unlock_irqrestore(&dca_lock, flags);
+
blocking_notifier_call_chain(&dca_provider_chain,
DCA_PROVIDER_ADD, NULL);
return 0;
@@ -234,9 +243,15 @@ EXPORT_SYMBOL_GPL(register_dca_provider);
*/
void unregister_dca_provider(struct dca_provider *dca)
{
+ unsigned long flags;
+
blocking_notifier_call_chain(&dca_provider_chain,
DCA_PROVIDER_REMOVE, NULL);
+
+ spin_lock_irqsave(&dca_lock, flags);
list_del(&dca->node);
+ spin_unlock_irqrestore(&dca_lock, flags);
+
dca_sysfs_remove_provider(dca);
}
EXPORT_SYMBOL_GPL(unregister_dca_provider);
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index 10c3c498358c..55dd88d82d6d 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -182,7 +182,7 @@ static int __init dio_init(void)
/* Initialize the DIO bus */
INIT_LIST_HEAD(&dio_bus.devices);
- strcpy(dio_bus.dev.bus_id, "dio");
+ dev_set_name(&dio_bus.dev, "dio");
error = device_register(&dio_bus.dev);
if (error) {
pr_err("DIO: Error registering dio_bus\n");
@@ -237,7 +237,7 @@ static int __init dio_init(void)
dev->scode = scode;
dev->resource.start = pa;
dev->resource.end = pa + DIO_SIZE(scode, va);
- sprintf(dev->dev.bus_id,"%02x", scode);
+ dev_set_name(&dev->dev, "%02x", scode);
/* read the ID byte(s) and encode if necessary. */
prid = DIO_ID(va);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index e34b06420816..48ea59e79672 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -62,6 +62,25 @@ config MV_XOR
---help---
Enable support for the Marvell XOR engine.
+config MX3_IPU
+ bool "MX3x Image Processing Unit support"
+ depends on ARCH_MX3
+ select DMA_ENGINE
+ default y
+ help
+ If you plan to use the Image Processing unit in the i.MX3x, say
+ Y here. If unsure, select Y.
+
+config MX3_IPU_IRQS
+ int "Number of dynamically mapped interrupts for IPU"
+ depends on MX3_IPU
+ range 2 137
+ default 4
+ help
+ Out of 137 interrupt sources on i.MX31 IPU only very few are used.
+ To avoid bloating the irq_desc[] array we allocate a sufficient
+ number of IRQ slots and map them dynamically to specific sources.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 14f59527d4f6..2e5dc96700d2 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
obj-$(CONFIG_FSL_DMA) += fsldma.o
obj-$(CONFIG_MV_XOR) += mv_xor.o
obj-$(CONFIG_DW_DMAC) += dw_dmac.o
+obj-$(CONFIG_MX3_IPU) += ipu/
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 403dbe781122..280a9d263eb3 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -329,9 +329,6 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
struct dma_chan *chan;
int cpu;
- WARN_ONCE(dmaengine_ref_count == 0,
- "client called %s without a reference", __func__);
-
cpu = get_cpu();
chan = per_cpu_ptr(channel_table[tx_type], cpu)->chan;
put_cpu();
@@ -348,9 +345,6 @@ void dma_issue_pending_all(void)
struct dma_device *device;
struct dma_chan *chan;
- WARN_ONCE(dmaengine_ref_count == 0,
- "client called %s without a reference", __func__);
-
rcu_read_lock();
list_for_each_entry_rcu(device, &dma_device_list, global_node) {
if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
@@ -524,6 +518,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
dma_chan_name(chan), err);
else
break;
+ chan->private = NULL;
chan = NULL;
}
}
@@ -542,6 +537,7 @@ void dma_release_channel(struct dma_chan *chan)
WARN_ONCE(chan->client_count != 1,
"chan reference count %d != 1\n", chan->client_count);
dma_chan_put(chan);
+ chan->private = NULL;
mutex_unlock(&dma_list_mutex);
}
EXPORT_SYMBOL_GPL(dma_release_channel);
@@ -961,6 +957,8 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx)
if (!dep)
return;
+ /* we'll submit tx->next now, so clear the link */
+ tx->next = NULL;
chan = dep->chan;
/* keep submitting up until a channel switch is detected
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 3603f1ea5b28..732fa1ec36ab 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -217,6 +217,10 @@ static int dmatest_func(void *data)
chan = thread->chan;
while (!kthread_should_stop()) {
+ struct dma_device *dev = chan->device;
+ struct dma_async_tx_descriptor *tx;
+ dma_addr_t dma_src, dma_dest;
+
total_tests++;
len = dmatest_random() % test_buf_size + 1;
@@ -226,10 +230,30 @@ static int dmatest_func(void *data)
dmatest_init_srcbuf(thread->srcbuf, src_off, len);
dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
- cookie = dma_async_memcpy_buf_to_buf(chan,
- thread->dstbuf + dst_off,
- thread->srcbuf + src_off,
- len);
+ dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off,
+ len, DMA_TO_DEVICE);
+ /* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
+ dma_dest = dma_map_single(dev->dev, thread->dstbuf,
+ test_buf_size, DMA_BIDIRECTIONAL);
+
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off,
+ dma_src, len,
+ DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP);
+ if (!tx) {
+ dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
+ dma_unmap_single(dev->dev, dma_dest,
+ test_buf_size, DMA_BIDIRECTIONAL);
+ pr_warning("%s: #%u: prep error with src_off=0x%x "
+ "dst_off=0x%x len=0x%x\n",
+ thread_name, total_tests - 1,
+ src_off, dst_off, len);
+ msleep(100);
+ failed_tests++;
+ continue;
+ }
+ tx->callback = NULL;
+ cookie = tx->tx_submit(tx);
+
if (dma_submit_error(cookie)) {
pr_warning("%s: #%u: submit error %d with src_off=0x%x "
"dst_off=0x%x len=0x%x\n",
@@ -253,6 +277,9 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
+ /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
+ dma_unmap_single(dev->dev, dma_dest,
+ test_buf_size, DMA_BIDIRECTIONAL);
error_count = 0;
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 6b702cc46b3d..20ad3d26bec2 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -560,7 +560,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
unsigned long flags)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
- struct dw_dma_slave *dws = dwc->dws;
+ struct dw_dma_slave *dws = chan->private;
struct dw_desc *prev;
struct dw_desc *first;
u32 ctllo;
@@ -790,7 +790,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
cfghi = DWC_CFGH_FIFO_MODE;
cfglo = 0;
- dws = dwc->dws;
+ dws = chan->private;
if (dws) {
/*
* We need controller-specific data to set up slave
@@ -866,7 +866,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
spin_lock_bh(&dwc->lock);
list_splice_init(&dwc->free_list, &list);
dwc->descs_allocated = 0;
- dwc->dws = NULL;
/* Disable interrupts */
channel_clear_bit(dw, MASK.XFER, dwc->mask);
@@ -1012,7 +1011,7 @@ static int __init dw_probe(struct platform_device *pdev)
dma_writel(dw, CFG, DW_CFG_DMA_EN);
printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
- pdev->dev.bus_id, dw->dma.chancnt);
+ dev_name(&pdev->dev), dw->dma.chancnt);
dma_async_device_register(&dw->dma);
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index 00fdd187bb0c..b252b202c5cf 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -139,8 +139,6 @@ struct dw_dma_chan {
struct list_head queue;
struct list_head free_list;
- struct dw_dma_slave *dws;
-
unsigned int descs_allocated;
};
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index ca70a21afc68..70126a606239 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -822,7 +822,7 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
*/
WARN_ON(fdev->feature != new_fsl_chan->feature);
- new_fsl_chan->dev = &new_fsl_chan->common.dev->device;
+ new_fsl_chan->dev = fdev->dev;
new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
@@ -875,7 +875,8 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
}
dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
- compatible, new_fsl_chan->irq);
+ compatible,
+ new_fsl_chan->irq != NO_IRQ ? new_fsl_chan->irq : fdev->irq);
return 0;
@@ -890,7 +891,8 @@ err_no_reg:
static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan)
{
- free_irq(fchan->irq, fchan);
+ if (fchan->irq != NO_IRQ)
+ free_irq(fchan->irq, fchan);
list_del(&fchan->common.device_node);
iounmap(fchan->reg_base);
kfree(fchan);
diff --git a/drivers/dma/ipu/Makefile b/drivers/dma/ipu/Makefile
new file mode 100644
index 000000000000..6704cf48326d
--- /dev/null
+++ b/drivers/dma/ipu/Makefile
@@ -0,0 +1 @@
+obj-y += ipu_irq.o ipu_idmac.o
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
new file mode 100644
index 000000000000..1f154d08e98f
--- /dev/null
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -0,0 +1,1740 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * Copyright (C) 2005-2007 Freescale Semiconductor, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <mach/ipu.h>
+
+#include "ipu_intern.h"
+
+#define FS_VF_IN_VALID 0x00000002
+#define FS_ENC_IN_VALID 0x00000001
+
+/*
+ * There can be only one, we could allocate it dynamically, but then we'd have
+ * to add an extra parameter to some functions, and use something as ugly as
+ * struct ipu *ipu = to_ipu(to_idmac(ichan->dma_chan.device));
+ * in the ISR
+ */
+static struct ipu ipu_data;
+
+#define to_ipu(id) container_of(id, struct ipu, idmac)
+
+static u32 __idmac_read_icreg(struct ipu *ipu, unsigned long reg)
+{
+ return __raw_readl(ipu->reg_ic + reg);
+}
+
+#define idmac_read_icreg(ipu, reg) __idmac_read_icreg(ipu, reg - IC_CONF)
+
+static void __idmac_write_icreg(struct ipu *ipu, u32 value, unsigned long reg)
+{
+ __raw_writel(value, ipu->reg_ic + reg);
+}
+
+#define idmac_write_icreg(ipu, v, reg) __idmac_write_icreg(ipu, v, reg - IC_CONF)
+
+static u32 idmac_read_ipureg(struct ipu *ipu, unsigned long reg)
+{
+ return __raw_readl(ipu->reg_ipu + reg);
+}
+
+static void idmac_write_ipureg(struct ipu *ipu, u32 value, unsigned long reg)
+{
+ __raw_writel(value, ipu->reg_ipu + reg);
+}
+
+/*****************************************************************************
+ * IPU / IC common functions
+ */
+static void dump_idmac_reg(struct ipu *ipu)
+{
+ dev_dbg(ipu->dev, "IDMAC_CONF 0x%x, IC_CONF 0x%x, IDMAC_CHA_EN 0x%x, "
+ "IDMAC_CHA_PRI 0x%x, IDMAC_CHA_BUSY 0x%x\n",
+ idmac_read_icreg(ipu, IDMAC_CONF),
+ idmac_read_icreg(ipu, IC_CONF),
+ idmac_read_icreg(ipu, IDMAC_CHA_EN),
+ idmac_read_icreg(ipu, IDMAC_CHA_PRI),
+ idmac_read_icreg(ipu, IDMAC_CHA_BUSY));
+ dev_dbg(ipu->dev, "BUF0_RDY 0x%x, BUF1_RDY 0x%x, CUR_BUF 0x%x, "
+ "DB_MODE 0x%x, TASKS_STAT 0x%x\n",
+ idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
+ idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
+ idmac_read_ipureg(ipu, IPU_CHA_CUR_BUF),
+ idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL),
+ idmac_read_ipureg(ipu, IPU_TASKS_STAT));
+}
+
+static uint32_t bytes_per_pixel(enum pixel_fmt fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_GENERIC: /* generic data */
+ case IPU_PIX_FMT_RGB332:
+ case IPU_PIX_FMT_YUV420P:
+ case IPU_PIX_FMT_YUV422P:
+ default:
+ return 1;
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_YUYV:
+ case IPU_PIX_FMT_UYVY:
+ return 2;
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ return 3;
+ case IPU_PIX_FMT_GENERIC_32: /* generic data */
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_RGB32:
+ case IPU_PIX_FMT_ABGR32:
+ return 4;
+ }
+}
+
+/* Enable / disable direct write to memory by the Camera Sensor Interface */
+static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
+{
+ uint32_t ic_conf, mask;
+
+ switch (channel) {
+ case IDMAC_IC_0:
+ mask = IC_CONF_PRPENC_EN;
+ break;
+ case IDMAC_IC_7:
+ mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
+ break;
+ default:
+ return;
+ }
+ ic_conf = idmac_read_icreg(ipu, IC_CONF) | mask;
+ idmac_write_icreg(ipu, ic_conf, IC_CONF);
+}
+
+static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
+{
+ uint32_t ic_conf, mask;
+
+ switch (channel) {
+ case IDMAC_IC_0:
+ mask = IC_CONF_PRPENC_EN;
+ break;
+ case IDMAC_IC_7:
+ mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
+ break;
+ default:
+ return;
+ }
+ ic_conf = idmac_read_icreg(ipu, IC_CONF) & ~mask;
+ idmac_write_icreg(ipu, ic_conf, IC_CONF);
+}
+
+static uint32_t ipu_channel_status(struct ipu *ipu, enum ipu_channel channel)
+{
+ uint32_t stat = TASK_STAT_IDLE;
+ uint32_t task_stat_reg = idmac_read_ipureg(ipu, IPU_TASKS_STAT);
+
+ switch (channel) {
+ case IDMAC_IC_7:
+ stat = (task_stat_reg & TSTAT_CSI2MEM_MASK) >>
+ TSTAT_CSI2MEM_OFFSET;
+ break;
+ case IDMAC_IC_0:
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ default:
+ break;
+ }
+ return stat;
+}
+
+struct chan_param_mem_planar {
+ /* Word 0 */
+ u32 xv:10;
+ u32 yv:10;
+ u32 xb:12;
+
+ u32 yb:12;
+ u32 res1:2;
+ u32 nsb:1;
+ u32 lnpb:6;
+ u32 ubo_l:11;
+
+ u32 ubo_h:15;
+ u32 vbo_l:17;
+
+ u32 vbo_h:9;
+ u32 res2:3;
+ u32 fw:12;
+ u32 fh_l:8;
+
+ u32 fh_h:4;
+ u32 res3:28;
+
+ /* Word 1 */
+ u32 eba0;
+
+ u32 eba1;
+
+ u32 bpp:3;
+ u32 sl:14;
+ u32 pfs:3;
+ u32 bam:3;
+ u32 res4:2;
+ u32 npb:6;
+ u32 res5:1;
+
+ u32 sat:2;
+ u32 res6:30;
+} __attribute__ ((packed));
+
+struct chan_param_mem_interleaved {
+ /* Word 0 */
+ u32 xv:10;
+ u32 yv:10;
+ u32 xb:12;
+
+ u32 yb:12;
+ u32 sce:1;
+ u32 res1:1;
+ u32 nsb:1;
+ u32 lnpb:6;
+ u32 sx:10;
+ u32 sy_l:1;
+
+ u32 sy_h:9;
+ u32 ns:10;
+ u32 sm:10;
+ u32 sdx_l:3;
+
+ u32 sdx_h:2;
+ u32 sdy:5;
+ u32 sdrx:1;
+ u32 sdry:1;
+ u32 sdr1:1;
+ u32 res2:2;
+ u32 fw:12;
+ u32 fh_l:8;
+
+ u32 fh_h:4;
+ u32 res3:28;
+
+ /* Word 1 */
+ u32 eba0;
+
+ u32 eba1;
+
+ u32 bpp:3;
+ u32 sl:14;
+ u32 pfs:3;
+ u32 bam:3;
+ u32 res4:2;
+ u32 npb:6;
+ u32 res5:1;
+
+ u32 sat:2;
+ u32 scc:1;
+ u32 ofs0:5;
+ u32 ofs1:5;
+ u32 ofs2:5;
+ u32 ofs3:5;
+ u32 wid0:3;
+ u32 wid1:3;
+ u32 wid2:3;
+
+ u32 wid3:3;
+ u32 dec_sel:1;
+ u32 res6:28;
+} __attribute__ ((packed));
+
+union chan_param_mem {
+ struct chan_param_mem_planar pp;
+ struct chan_param_mem_interleaved ip;
+};
+
+static void ipu_ch_param_set_plane_offset(union chan_param_mem *params,
+ u32 u_offset, u32 v_offset)
+{
+ params->pp.ubo_l = u_offset & 0x7ff;
+ params->pp.ubo_h = u_offset >> 11;
+ params->pp.vbo_l = v_offset & 0x1ffff;
+ params->pp.vbo_h = v_offset >> 17;
+}
+
+static void ipu_ch_param_set_size(union chan_param_mem *params,
+ uint32_t pixel_fmt, uint16_t width,
+ uint16_t height, uint16_t stride)
+{
+ u32 u_offset;
+ u32 v_offset;
+
+ params->pp.fw = width - 1;
+ params->pp.fh_l = height - 1;
+ params->pp.fh_h = (height - 1) >> 8;
+ params->pp.sl = stride - 1;
+
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_GENERIC:
+ /*Represents 8-bit Generic data */
+ params->pp.bpp = 3;
+ params->pp.pfs = 7;
+ params->pp.npb = 31;
+ params->pp.sat = 2; /* SAT = use 32-bit access */
+ break;
+ case IPU_PIX_FMT_GENERIC_32:
+ /*Represents 32-bit Generic data */
+ params->pp.bpp = 0;
+ params->pp.pfs = 7;
+ params->pp.npb = 7;
+ params->pp.sat = 2; /* SAT = use 32-bit access */
+ break;
+ case IPU_PIX_FMT_RGB565:
+ params->ip.bpp = 2;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 0; /* Red bit offset */
+ params->ip.ofs1 = 5; /* Green bit offset */
+ params->ip.ofs2 = 11; /* Blue bit offset */
+ params->ip.ofs3 = 16; /* Alpha bit offset */
+ params->ip.wid0 = 4; /* Red bit width - 1 */
+ params->ip.wid1 = 5; /* Green bit width - 1 */
+ params->ip.wid2 = 4; /* Blue bit width - 1 */
+ break;
+ case IPU_PIX_FMT_BGR24:
+ params->ip.bpp = 1; /* 24 BPP & RGB PFS */
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 0; /* Red bit offset */
+ params->ip.ofs1 = 8; /* Green bit offset */
+ params->ip.ofs2 = 16; /* Blue bit offset */
+ params->ip.ofs3 = 24; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ break;
+ case IPU_PIX_FMT_RGB24:
+ params->ip.bpp = 1; /* 24 BPP & RGB PFS */
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 16; /* Red bit offset */
+ params->ip.ofs1 = 8; /* Green bit offset */
+ params->ip.ofs2 = 0; /* Blue bit offset */
+ params->ip.ofs3 = 24; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ break;
+ case IPU_PIX_FMT_BGRA32:
+ case IPU_PIX_FMT_BGR32:
+ params->ip.bpp = 0;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 8; /* Red bit offset */
+ params->ip.ofs1 = 16; /* Green bit offset */
+ params->ip.ofs2 = 24; /* Blue bit offset */
+ params->ip.ofs3 = 0; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ params->ip.wid3 = 7; /* Alpha bit width - 1 */
+ break;
+ case IPU_PIX_FMT_RGBA32:
+ case IPU_PIX_FMT_RGB32:
+ params->ip.bpp = 0;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 24; /* Red bit offset */
+ params->ip.ofs1 = 16; /* Green bit offset */
+ params->ip.ofs2 = 8; /* Blue bit offset */
+ params->ip.ofs3 = 0; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ params->ip.wid3 = 7; /* Alpha bit width - 1 */
+ break;
+ case IPU_PIX_FMT_ABGR32:
+ params->ip.bpp = 0;
+ params->ip.pfs = 4;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ params->ip.ofs0 = 8; /* Red bit offset */
+ params->ip.ofs1 = 16; /* Green bit offset */
+ params->ip.ofs2 = 24; /* Blue bit offset */
+ params->ip.ofs3 = 0; /* Alpha bit offset */
+ params->ip.wid0 = 7; /* Red bit width - 1 */
+ params->ip.wid1 = 7; /* Green bit width - 1 */
+ params->ip.wid2 = 7; /* Blue bit width - 1 */
+ params->ip.wid3 = 7; /* Alpha bit width - 1 */
+ break;
+ case IPU_PIX_FMT_UYVY:
+ params->ip.bpp = 2;
+ params->ip.pfs = 6;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ break;
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YUV420P:
+ params->ip.bpp = 3;
+ params->ip.pfs = 3;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ u_offset = stride * height;
+ v_offset = u_offset + u_offset / 4;
+ ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
+ break;
+ case IPU_PIX_FMT_YVU422P:
+ params->ip.bpp = 3;
+ params->ip.pfs = 2;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ v_offset = stride * height;
+ u_offset = v_offset + v_offset / 2;
+ ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
+ break;
+ case IPU_PIX_FMT_YUV422P:
+ params->ip.bpp = 3;
+ params->ip.pfs = 2;
+ params->ip.npb = 7;
+ params->ip.sat = 2; /* SAT = 32-bit access */
+ u_offset = stride * height;
+ v_offset = u_offset + u_offset / 2;
+ ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
+ break;
+ default:
+ dev_err(ipu_data.dev,
+ "mxc ipu: unimplemented pixel format %d\n", pixel_fmt);
+ break;
+ }
+
+ params->pp.nsb = 1;
+}
+
+static void ipu_ch_param_set_burst_size(union chan_param_mem *params,
+ uint16_t burst_pixels)
+{
+ params->pp.npb = burst_pixels - 1;
+};
+
+static void ipu_ch_param_set_buffer(union chan_param_mem *params,
+ dma_addr_t buf0, dma_addr_t buf1)
+{
+ params->pp.eba0 = buf0;
+ params->pp.eba1 = buf1;
+};
+
+static void ipu_ch_param_set_rotation(union chan_param_mem *params,
+ enum ipu_rotate_mode rotate)
+{
+ params->pp.bam = rotate;
+};
+
+static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
+ uint32_t num_words)
+{
+ for (; num_words > 0; num_words--) {
+ dev_dbg(ipu_data.dev,
+ "write param mem - addr = 0x%08X, data = 0x%08X\n",
+ addr, *data);
+ idmac_write_ipureg(&ipu_data, addr, IPU_IMA_ADDR);
+ idmac_write_ipureg(&ipu_data, *data++, IPU_IMA_DATA);
+ addr++;
+ if ((addr & 0x7) == 5) {
+ addr &= ~0x7; /* set to word 0 */
+ addr += 8; /* increment to next row */
+ }
+ }
+}
+
+static int calc_resize_coeffs(uint32_t in_size, uint32_t out_size,
+ uint32_t *resize_coeff,
+ uint32_t *downsize_coeff)
+{
+ uint32_t temp_size;
+ uint32_t temp_downsize;
+
+ *resize_coeff = 1 << 13;
+ *downsize_coeff = 1 << 13;
+
+ /* Cannot downsize more than 8:1 */
+ if (out_size << 3 < in_size)
+ return -EINVAL;
+
+ /* compute downsizing coefficient */
+ temp_downsize = 0;
+ temp_size = in_size;
+ while (temp_size >= out_size * 2 && temp_downsize < 2) {
+ temp_size >>= 1;
+ temp_downsize++;
+ }
+ *downsize_coeff = temp_downsize;
+
+ /*
+ * compute resizing coefficient using the following formula:
+ * resize_coeff = M*(SI -1)/(SO - 1)
+ * where M = 2^13, SI - input size, SO - output size
+ */
+ *resize_coeff = (8192L * (temp_size - 1)) / (out_size - 1);
+ if (*resize_coeff >= 16384L) {
+ dev_err(ipu_data.dev, "Warning! Overflow on resize coeff.\n");
+ *resize_coeff = 0x3FFF;
+ }
+
+ dev_dbg(ipu_data.dev, "resizing from %u -> %u pixels, "
+ "downsize=%u, resize=%u.%lu (reg=%u)\n", in_size, out_size,
+ *downsize_coeff, *resize_coeff >= 8192L ? 1 : 0,
+ ((*resize_coeff & 0x1FFF) * 10000L) / 8192L, *resize_coeff);
+
+ return 0;
+}
+
+static enum ipu_color_space format_to_colorspace(enum pixel_fmt fmt)
+{
+ switch (fmt) {
+ case IPU_PIX_FMT_RGB565:
+ case IPU_PIX_FMT_BGR24:
+ case IPU_PIX_FMT_RGB24:
+ case IPU_PIX_FMT_BGR32:
+ case IPU_PIX_FMT_RGB32:
+ return IPU_COLORSPACE_RGB;
+ default:
+ return IPU_COLORSPACE_YCBCR;
+ }
+}
+
+static int ipu_ic_init_prpenc(struct ipu *ipu,
+ union ipu_channel_param *params, bool src_is_csi)
+{
+ uint32_t reg, ic_conf;
+ uint32_t downsize_coeff, resize_coeff;
+ enum ipu_color_space in_fmt, out_fmt;
+
+ /* Setup vertical resizing */
+ calc_resize_coeffs(params->video.in_height,
+ params->video.out_height,
+ &resize_coeff, &downsize_coeff);
+ reg = (downsize_coeff << 30) | (resize_coeff << 16);
+
+ /* Setup horizontal resizing */
+ calc_resize_coeffs(params->video.in_width,
+ params->video.out_width,
+ &resize_coeff, &downsize_coeff);
+ reg |= (downsize_coeff << 14) | resize_coeff;
+
+ /* Setup color space conversion */
+ in_fmt = format_to_colorspace(params->video.in_pixel_fmt);
+ out_fmt = format_to_colorspace(params->video.out_pixel_fmt);
+
+ /*
+ * Colourspace conversion unsupported yet - see _init_csc() in
+ * Freescale sources
+ */
+ if (in_fmt != out_fmt) {
+ dev_err(ipu->dev, "Colourspace conversion unsupported!\n");
+ return -EOPNOTSUPP;
+ }
+
+ idmac_write_icreg(ipu, reg, IC_PRP_ENC_RSC);
+
+ ic_conf = idmac_read_icreg(ipu, IC_CONF);
+
+ if (src_is_csi)
+ ic_conf &= ~IC_CONF_RWS_EN;
+ else
+ ic_conf |= IC_CONF_RWS_EN;
+
+ idmac_write_icreg(ipu, ic_conf, IC_CONF);
+
+ return 0;
+}
+
+static uint32_t dma_param_addr(uint32_t dma_ch)
+{
+ /* Channel Parameter Memory */
+ return 0x10000 | (dma_ch << 4);
+};
+
+static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
+ bool prio)
+{
+ u32 reg = idmac_read_icreg(ipu, IDMAC_CHA_PRI);
+
+ if (prio)
+ reg |= 1UL << channel;
+ else
+ reg &= ~(1UL << channel);
+
+ idmac_write_icreg(ipu, reg, IDMAC_CHA_PRI);
+
+ dump_idmac_reg(ipu);
+}
+
+static uint32_t ipu_channel_conf_mask(enum ipu_channel channel)
+{
+ uint32_t mask;
+
+ switch (channel) {
+ case IDMAC_IC_0:
+ case IDMAC_IC_7:
+ mask = IPU_CONF_CSI_EN | IPU_CONF_IC_EN;
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ mask = IPU_CONF_SDC_EN | IPU_CONF_DI_EN;
+ break;
+ default:
+ mask = 0;
+ break;
+ }
+
+ return mask;
+}
+
+/**
+ * ipu_enable_channel() - enable an IPU channel.
+ * @channel: channel ID.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
+{
+ struct ipu *ipu = to_ipu(idmac);
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ uint32_t reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ /* Reset to buffer 0 */
+ idmac_write_ipureg(ipu, 1UL << channel, IPU_CHA_CUR_BUF);
+ ichan->active_buffer = 0;
+ ichan->status = IPU_CHANNEL_ENABLED;
+
+ switch (channel) {
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ case IDMAC_IC_7:
+ ipu_channel_set_priority(ipu, channel, true);
+ default:
+ break;
+ }
+
+ reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
+
+ idmac_write_icreg(ipu, reg | (1UL << channel), IDMAC_CHA_EN);
+
+ ipu_ic_enable_task(ipu, channel);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+ return 0;
+}
+
+/**
+ * ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
+ * @channel: channel ID.
+ * @pixel_fmt: pixel format of buffer. Pixel format is a FOURCC ASCII code.
+ * @width: width of buffer in pixels.
+ * @height: height of buffer in pixels.
+ * @stride: stride length of buffer in pixels.
+ * @rot_mode: rotation mode of buffer. A rotation setting other than
+ * IPU_ROTATE_VERT_FLIP should only be used for input buffers of
+ * rotation channels.
+ * @phyaddr_0: buffer 0 physical address.
+ * @phyaddr_1: buffer 1 physical address. Setting this to a value other than
+ * NULL enables double buffering mode.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int ipu_init_channel_buffer(struct idmac_channel *ichan,
+ enum pixel_fmt pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ enum ipu_rotate_mode rot_mode,
+ dma_addr_t phyaddr_0, dma_addr_t phyaddr_1)
+{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ struct idmac *idmac = to_idmac(ichan->dma_chan.device);
+ struct ipu *ipu = to_ipu(idmac);
+ union chan_param_mem params = {};
+ unsigned long flags;
+ uint32_t reg;
+ uint32_t stride_bytes;
+
+ stride_bytes = stride * bytes_per_pixel(pixel_fmt);
+
+ if (stride_bytes % 4) {
+ dev_err(ipu->dev,
+ "Stride length must be 32-bit aligned, stride = %d, bytes = %d\n",
+ stride, stride_bytes);
+ return -EINVAL;
+ }
+
+ /* IC channel's stride must be a multiple of 8 pixels */
+ if ((channel <= 13) && (stride % 8)) {
+ dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
+ return -EINVAL;
+ }
+
+ /* Build parameter memory data for DMA channel */
+ ipu_ch_param_set_size(&params, pixel_fmt, width, height, stride_bytes);
+ ipu_ch_param_set_buffer(&params, phyaddr_0, phyaddr_1);
+ ipu_ch_param_set_rotation(&params, rot_mode);
+ /* Some channels (rotation) have restriction on burst length */
+ switch (channel) {
+ case IDMAC_IC_7: /* Hangs with burst 8, 16, other values
+ invalid - Table 44-30 */
+/*
+ ipu_ch_param_set_burst_size(&params, 8);
+ */
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ /* In original code only IPU_PIX_FMT_RGB565 was setting burst */
+ ipu_ch_param_set_burst_size(&params, 16);
+ break;
+ case IDMAC_IC_0:
+ default:
+ break;
+ }
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ ipu_write_param_mem(dma_param_addr(channel), (uint32_t *)&params, 10);
+
+ reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
+
+ if (phyaddr_1)
+ reg |= 1UL << channel;
+ else
+ reg &= ~(1UL << channel);
+
+ idmac_write_ipureg(ipu, reg, IPU_CHA_DB_MODE_SEL);
+
+ ichan->status = IPU_CHANNEL_READY;
+
+ spin_unlock_irqrestore(ipu->lock, flags);
+
+ return 0;
+}
+
+/**
+ * ipu_select_buffer() - mark a channel's buffer as ready.
+ * @channel: channel ID.
+ * @buffer_n: buffer number to mark ready.
+ */
+static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
+{
+ /* No locking - this is a write-one-to-set register, cleared by IPU */
+ if (buffer_n == 0)
+ /* Mark buffer 0 as ready. */
+ idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF0_RDY);
+ else
+ /* Mark buffer 1 as ready. */
+ idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF1_RDY);
+}
+
+/**
+ * ipu_update_channel_buffer() - update physical address of a channel buffer.
+ * @channel: channel ID.
+ * @buffer_n: buffer number to update.
+ * 0 or 1 are the only valid values.
+ * @phyaddr: buffer physical address.
+ * @return: Returns 0 on success or negative error code on failure. This
+ * function will fail if the buffer is set to ready.
+ */
+/* Called under spin_lock(_irqsave)(&ichan->lock) */
+static int ipu_update_channel_buffer(enum ipu_channel channel,
+ int buffer_n, dma_addr_t phyaddr)
+{
+ uint32_t reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ipu_data.lock, flags);
+
+ if (buffer_n == 0) {
+ reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
+ if (reg & (1UL << channel)) {
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+ return -EACCES;
+ }
+
+ /* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
+ idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
+ 0x0008UL, IPU_IMA_ADDR);
+ idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
+ } else {
+ reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
+ if (reg & (1UL << channel)) {
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+ return -EACCES;
+ }
+
+ /* Check if double-buffering is already enabled */
+ reg = idmac_read_ipureg(&ipu_data, IPU_CHA_DB_MODE_SEL);
+
+ if (!(reg & (1UL << channel)))
+ idmac_write_ipureg(&ipu_data, reg | (1UL << channel),
+ IPU_CHA_DB_MODE_SEL);
+
+ /* 44.3.3.1.9 - Row Number 1 (WORD1, offset 1) */
+ idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
+ 0x0009UL, IPU_IMA_ADDR);
+ idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
+ }
+
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+
+ return 0;
+}
+
+/* Called under spin_lock_irqsave(&ichan->lock) */
+static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
+ struct idmac_tx_desc *desc)
+{
+ struct scatterlist *sg;
+ int i, ret = 0;
+
+ for (i = 0, sg = desc->sg; i < 2 && sg; i++) {
+ if (!ichan->sg[i]) {
+ ichan->sg[i] = sg;
+
+ /*
+ * On first invocation this shouldn't be necessary, the
+ * call to ipu_init_channel_buffer() above will set
+ * addresses for us, so we could make it conditional
+ * on status >= IPU_CHANNEL_ENABLED, but doing it again
+ * shouldn't hurt either.
+ */
+ ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i,
+ sg_dma_address(sg));
+ if (ret < 0)
+ return ret;
+
+ ipu_select_buffer(ichan->dma_chan.chan_id, i);
+
+ sg = sg_next(sg);
+ }
+ }
+
+ return ret;
+}
+
+static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct idmac_tx_desc *desc = to_tx_desc(tx);
+ struct idmac_channel *ichan = to_idmac_chan(tx->chan);
+ struct idmac *idmac = to_idmac(tx->chan->device);
+ struct ipu *ipu = to_ipu(idmac);
+ dma_cookie_t cookie;
+ unsigned long flags;
+
+ /* Sanity check */
+ if (!list_empty(&desc->list)) {
+ /* The descriptor doesn't belong to client */
+ dev_err(&ichan->dma_chan.dev->device,
+ "Descriptor %p not prepared!\n", tx);
+ return -EBUSY;
+ }
+
+ mutex_lock(&ichan->chan_mutex);
+
+ if (ichan->status < IPU_CHANNEL_READY) {
+ struct idmac_video_param *video = &ichan->params.video;
+ /*
+ * Initial buffer assignment - the first two sg-entries from
+ * the descriptor will end up in the IDMAC buffers
+ */
+ dma_addr_t dma_1 = sg_is_last(desc->sg) ? 0 :
+ sg_dma_address(&desc->sg[1]);
+
+ WARN_ON(ichan->sg[0] || ichan->sg[1]);
+
+ cookie = ipu_init_channel_buffer(ichan,
+ video->out_pixel_fmt,
+ video->out_width,
+ video->out_height,
+ video->out_stride,
+ IPU_ROTATE_NONE,
+ sg_dma_address(&desc->sg[0]),
+ dma_1);
+ if (cookie < 0)
+ goto out;
+ }
+
+ /* ipu->lock can be taken under ichan->lock, but not v.v. */
+ spin_lock_irqsave(&ichan->lock, flags);
+
+ /* submit_buffers() atomically verifies and fills empty sg slots */
+ cookie = ipu_submit_channel_buffers(ichan, desc);
+
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ if (cookie < 0)
+ goto out;
+
+ cookie = ichan->dma_chan.cookie;
+
+ if (++cookie < 0)
+ cookie = 1;
+
+ /* from dmaengine.h: "last cookie value returned to client" */
+ ichan->dma_chan.cookie = cookie;
+ tx->cookie = cookie;
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_add_tail(&desc->list, &ichan->queue);
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ if (ichan->status < IPU_CHANNEL_ENABLED) {
+ int ret = ipu_enable_channel(idmac, ichan);
+ if (ret < 0) {
+ cookie = ret;
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_del_init(&desc->list);
+ spin_unlock_irqrestore(&ichan->lock, flags);
+ tx->cookie = cookie;
+ ichan->dma_chan.cookie = cookie;
+ }
+ }
+
+ dump_idmac_reg(ipu);
+
+out:
+ mutex_unlock(&ichan->chan_mutex);
+
+ return cookie;
+}
+
+/* Called with ichan->chan_mutex held */
+static int idmac_desc_alloc(struct idmac_channel *ichan, int n)
+{
+ struct idmac_tx_desc *desc = vmalloc(n * sizeof(struct idmac_tx_desc));
+ struct idmac *idmac = to_idmac(ichan->dma_chan.device);
+
+ if (!desc)
+ return -ENOMEM;
+
+ /* No interrupts, just disable the tasklet for a moment */
+ tasklet_disable(&to_ipu(idmac)->tasklet);
+
+ ichan->n_tx_desc = n;
+ ichan->desc = desc;
+ INIT_LIST_HEAD(&ichan->queue);
+ INIT_LIST_HEAD(&ichan->free_list);
+
+ while (n--) {
+ struct dma_async_tx_descriptor *txd = &desc->txd;
+
+ memset(txd, 0, sizeof(*txd));
+ dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
+ txd->tx_submit = idmac_tx_submit;
+ txd->chan = &ichan->dma_chan;
+ INIT_LIST_HEAD(&txd->tx_list);
+
+ list_add(&desc->list, &ichan->free_list);
+
+ desc++;
+ }
+
+ tasklet_enable(&to_ipu(idmac)->tasklet);
+
+ return 0;
+}
+
+/**
+ * ipu_init_channel() - initialize an IPU channel.
+ * @idmac: IPU DMAC context.
+ * @ichan: pointer to the channel object.
+ * @return 0 on success or negative error code on failure.
+ */
+static int ipu_init_channel(struct idmac *idmac, struct idmac_channel *ichan)
+{
+ union ipu_channel_param *params = &ichan->params;
+ uint32_t ipu_conf;
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ unsigned long flags;
+ uint32_t reg;
+ struct ipu *ipu = to_ipu(idmac);
+ int ret = 0, n_desc = 0;
+
+ dev_dbg(ipu->dev, "init channel = %d\n", channel);
+
+ if (channel != IDMAC_SDC_0 && channel != IDMAC_SDC_1 &&
+ channel != IDMAC_IC_7)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ switch (channel) {
+ case IDMAC_IC_7:
+ n_desc = 16;
+ reg = idmac_read_icreg(ipu, IC_CONF);
+ idmac_write_icreg(ipu, reg & ~IC_CONF_CSI_MEM_WR_EN, IC_CONF);
+ break;
+ case IDMAC_IC_0:
+ n_desc = 16;
+ reg = idmac_read_ipureg(ipu, IPU_FS_PROC_FLOW);
+ idmac_write_ipureg(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW);
+ ret = ipu_ic_init_prpenc(ipu, params, true);
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ n_desc = 4;
+ default:
+ break;
+ }
+
+ ipu->channel_init_mask |= 1L << channel;
+
+ /* Enable IPU sub module */
+ ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) |
+ ipu_channel_conf_mask(channel);
+ idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ if (n_desc && !ichan->desc)
+ ret = idmac_desc_alloc(ichan, n_desc);
+
+ dump_idmac_reg(ipu);
+
+ return ret;
+}
+
+/**
+ * ipu_uninit_channel() - uninitialize an IPU channel.
+ * @idmac: IPU DMAC context.
+ * @ichan: pointer to the channel object.
+ */
+static void ipu_uninit_channel(struct idmac *idmac, struct idmac_channel *ichan)
+{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ unsigned long flags;
+ uint32_t reg;
+ unsigned long chan_mask = 1UL << channel;
+ uint32_t ipu_conf;
+ struct ipu *ipu = to_ipu(idmac);
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ if (!(ipu->channel_init_mask & chan_mask)) {
+ dev_err(ipu->dev, "Channel already uninitialized %d\n",
+ channel);
+ spin_unlock_irqrestore(&ipu->lock, flags);
+ return;
+ }
+
+ /* Reset the double buffer */
+ reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
+ idmac_write_ipureg(ipu, reg & ~chan_mask, IPU_CHA_DB_MODE_SEL);
+
+ ichan->sec_chan_en = false;
+
+ switch (channel) {
+ case IDMAC_IC_7:
+ reg = idmac_read_icreg(ipu, IC_CONF);
+ idmac_write_icreg(ipu, reg & ~(IC_CONF_RWS_EN | IC_CONF_PRPENC_EN),
+ IC_CONF);
+ break;
+ case IDMAC_IC_0:
+ reg = idmac_read_icreg(ipu, IC_CONF);
+ idmac_write_icreg(ipu, reg & ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1),
+ IC_CONF);
+ break;
+ case IDMAC_SDC_0:
+ case IDMAC_SDC_1:
+ default:
+ break;
+ }
+
+ ipu->channel_init_mask &= ~(1L << channel);
+
+ ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) &
+ ~ipu_channel_conf_mask(channel);
+ idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ ichan->n_tx_desc = 0;
+ vfree(ichan->desc);
+ ichan->desc = NULL;
+}
+
+/**
+ * ipu_disable_channel() - disable an IPU channel.
+ * @idmac: IPU DMAC context.
+ * @ichan: channel object pointer.
+ * @wait_for_stop: flag to set whether to wait for channel end of frame or
+ * return immediately.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
+ bool wait_for_stop)
+{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
+ struct ipu *ipu = to_ipu(idmac);
+ uint32_t reg;
+ unsigned long flags;
+ unsigned long chan_mask = 1UL << channel;
+ unsigned int timeout;
+
+ if (wait_for_stop && channel != IDMAC_SDC_1 && channel != IDMAC_SDC_0) {
+ timeout = 40;
+ /* This waiting always fails. Related to spurious irq problem */
+ while ((idmac_read_icreg(ipu, IDMAC_CHA_BUSY) & chan_mask) ||
+ (ipu_channel_status(ipu, channel) == TASK_STAT_ACTIVE)) {
+ timeout--;
+ msleep(10);
+
+ if (!timeout) {
+ dev_dbg(ipu->dev,
+ "Warning: timeout waiting for channel %u to "
+ "stop: buf0_rdy = 0x%08X, buf1_rdy = 0x%08X, "
+ "busy = 0x%08X, tstat = 0x%08X\n", channel,
+ idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
+ idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
+ idmac_read_icreg(ipu, IDMAC_CHA_BUSY),
+ idmac_read_ipureg(ipu, IPU_TASKS_STAT));
+ break;
+ }
+ }
+ dev_dbg(ipu->dev, "timeout = %d * 10ms\n", 40 - timeout);
+ }
+ /* SDC BG and FG must be disabled before DMA is disabled */
+ if (wait_for_stop && (channel == IDMAC_SDC_0 ||
+ channel == IDMAC_SDC_1)) {
+ for (timeout = 5;
+ timeout && !ipu_irq_status(ichan->eof_irq); timeout--)
+ msleep(5);
+ }
+
+ spin_lock_irqsave(&ipu->lock, flags);
+
+ /* Disable IC task */
+ ipu_ic_disable_task(ipu, channel);
+
+ /* Disable DMA channel(s) */
+ reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
+ idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN);
+
+ /*
+ * Problem (observed with channel DMAIC_7): after enabling the channel
+ * and initialising buffers, there comes an interrupt with current still
+ * pointing at buffer 0, whereas it should use buffer 0 first and only
+ * generate an interrupt when it is done, then current should already
+ * point to buffer 1. This spurious interrupt also comes on channel
+ * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the
+ * first interrupt, there comes the second with current correctly
+ * pointing to buffer 1 this time. But sometimes this second interrupt
+ * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling
+ * the channel seems to prevent the channel from hanging, but it doesn't
+ * prevent the spurious interrupt. This might also be unsafe. Think
+ * about the IDMAC controller trying to switch to a buffer, when we
+ * clear the ready bit, and re-enable it a moment later.
+ */
+ reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY);
+ idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY);
+ idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY);
+
+ reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY);
+ idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY);
+ idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY);
+
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ return 0;
+}
+
+/*
+ * We have several possibilities here:
+ * current BUF next BUF
+ *
+ * not last sg next not last sg
+ * not last sg next last sg
+ * last sg first sg from next descriptor
+ * last sg NULL
+ *
+ * Besides, the descriptor queue might be empty or not. We process all these
+ * cases carefully.
+ */
+static irqreturn_t idmac_interrupt(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ unsigned int chan_id = ichan->dma_chan.chan_id;
+ struct scatterlist **sg, *sgnext, *sgnew = NULL;
+ /* Next transfer descriptor */
+ struct idmac_tx_desc *desc = NULL, *descnew;
+ dma_async_tx_callback callback;
+ void *callback_param;
+ bool done = false;
+ u32 ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY),
+ ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY),
+ curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+
+ /* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
+
+ pr_debug("IDMAC irq %d\n", irq);
+ /* Other interrupts do not interfere with this channel */
+ spin_lock(&ichan->lock);
+
+ if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
+ ((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
+ int i = 100;
+
+ /* This doesn't help. See comment in ipu_disable_channel() */
+ while (--i) {
+ curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ if (((curbuf >> chan_id) & 1) != ichan->active_buffer)
+ break;
+ cpu_relax();
+ }
+
+ if (!i) {
+ spin_unlock(&ichan->lock);
+ dev_dbg(ichan->dma_chan.device->dev,
+ "IRQ on active buffer on channel %x, active "
+ "%d, ready %x, %x, current %x!\n", chan_id,
+ ichan->active_buffer, ready0, ready1, curbuf);
+ return IRQ_NONE;
+ }
+ }
+
+ if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
+ (!ichan->active_buffer && (ready0 >> chan_id) & 1)
+ )) {
+ spin_unlock(&ichan->lock);
+ dev_dbg(ichan->dma_chan.device->dev,
+ "IRQ with active buffer still ready on channel %x, "
+ "active %d, ready %x, %x!\n", chan_id,
+ ichan->active_buffer, ready0, ready1);
+ return IRQ_NONE;
+ }
+
+ if (unlikely(list_empty(&ichan->queue))) {
+ spin_unlock(&ichan->lock);
+ dev_err(ichan->dma_chan.device->dev,
+ "IRQ without queued buffers on channel %x, active %d, "
+ "ready %x, %x!\n", chan_id,
+ ichan->active_buffer, ready0, ready1);
+ return IRQ_NONE;
+ }
+
+ /*
+ * active_buffer is a software flag, it shows which buffer we are
+ * currently expecting back from the hardware, IDMAC should be
+ * processing the other buffer already
+ */
+ sg = &ichan->sg[ichan->active_buffer];
+ sgnext = ichan->sg[!ichan->active_buffer];
+
+ /*
+ * if sgnext == NULL sg must be the last element in a scatterlist and
+ * queue must be empty
+ */
+ if (unlikely(!sgnext)) {
+ if (unlikely(sg_next(*sg))) {
+ dev_err(ichan->dma_chan.device->dev,
+ "Broken buffer-update locking on channel %x!\n",
+ chan_id);
+ /* We'll let the user catch up */
+ } else {
+ /* Underrun */
+ ipu_ic_disable_task(&ipu_data, chan_id);
+ dev_dbg(ichan->dma_chan.device->dev,
+ "Underrun on channel %x\n", chan_id);
+ ichan->status = IPU_CHANNEL_READY;
+ /* Continue to check for complete descriptor */
+ }
+ }
+
+ desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
+
+ /* First calculate and submit the next sg element */
+ if (likely(sgnext))
+ sgnew = sg_next(sgnext);
+
+ if (unlikely(!sgnew)) {
+ /* Start a new scatterlist, if any queued */
+ if (likely(desc->list.next != &ichan->queue)) {
+ descnew = list_entry(desc->list.next,
+ struct idmac_tx_desc, list);
+ sgnew = &descnew->sg[0];
+ }
+ }
+
+ if (unlikely(!sg_next(*sg)) || !sgnext) {
+ /*
+ * Last element in scatterlist done, remove from the queue,
+ * _init for debugging
+ */
+ list_del_init(&desc->list);
+ done = true;
+ }
+
+ *sg = sgnew;
+
+ if (likely(sgnew)) {
+ int ret;
+
+ ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer,
+ sg_dma_address(*sg));
+ if (ret < 0)
+ dev_err(ichan->dma_chan.device->dev,
+ "Failed to update buffer on channel %x buffer %d!\n",
+ chan_id, ichan->active_buffer);
+ else
+ ipu_select_buffer(chan_id, ichan->active_buffer);
+ }
+
+ /* Flip the active buffer - even if update above failed */
+ ichan->active_buffer = !ichan->active_buffer;
+ if (done)
+ ichan->completed = desc->txd.cookie;
+
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+
+ spin_unlock(&ichan->lock);
+
+ if (done && (desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
+ callback(callback_param);
+
+ return IRQ_HANDLED;
+}
+
+static void ipu_gc_tasklet(unsigned long arg)
+{
+ struct ipu *ipu = (struct ipu *)arg;
+ int i;
+
+ for (i = 0; i < IPU_CHANNELS_NUM; i++) {
+ struct idmac_channel *ichan = ipu->channel + i;
+ struct idmac_tx_desc *desc;
+ unsigned long flags;
+ int j;
+
+ for (j = 0; j < ichan->n_tx_desc; j++) {
+ desc = ichan->desc + j;
+ spin_lock_irqsave(&ichan->lock, flags);
+ if (async_tx_test_ack(&desc->txd)) {
+ list_move(&desc->list, &ichan->free_list);
+ async_tx_clear_ack(&desc->txd);
+ }
+ spin_unlock_irqrestore(&ichan->lock, flags);
+ }
+ }
+}
+
+/*
+ * At the time .device_alloc_chan_resources() method is called, we cannot know,
+ * whether the client will accept the channel. Thus we must only check, if we
+ * can satisfy client's request but the only real criterion to verify, whether
+ * the client has accepted our offer is the client_count. That's why we have to
+ * perform the rest of our allocation tasks on the first call to this function.
+ */
+static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
+ struct scatterlist *sgl, unsigned int sg_len,
+ enum dma_data_direction direction, unsigned long tx_flags)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac_tx_desc *desc = NULL;
+ struct dma_async_tx_descriptor *txd = NULL;
+ unsigned long flags;
+
+ /* We only can handle these three channels so far */
+ if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 &&
+ ichan->dma_chan.chan_id != IDMAC_IC_7)
+ return NULL;
+
+ if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
+ dev_err(chan->device->dev, "Invalid DMA direction %d!\n", direction);
+ return NULL;
+ }
+
+ mutex_lock(&ichan->chan_mutex);
+
+ spin_lock_irqsave(&ichan->lock, flags);
+ if (!list_empty(&ichan->free_list)) {
+ desc = list_entry(ichan->free_list.next,
+ struct idmac_tx_desc, list);
+
+ list_del_init(&desc->list);
+
+ desc->sg_len = sg_len;
+ desc->sg = sgl;
+ txd = &desc->txd;
+ txd->flags = tx_flags;
+ }
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ mutex_unlock(&ichan->chan_mutex);
+
+ tasklet_schedule(&to_ipu(to_idmac(chan->device))->tasklet);
+
+ return txd;
+}
+
+/* Re-select the current buffer and re-activate the channel */
+static void idmac_issue_pending(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+ struct ipu *ipu = to_ipu(idmac);
+ unsigned long flags;
+
+ /* This is not always needed, but doesn't hurt either */
+ spin_lock_irqsave(&ipu->lock, flags);
+ ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer);
+ spin_unlock_irqrestore(&ipu->lock, flags);
+
+ /*
+ * Might need to perform some parts of initialisation from
+ * ipu_enable_channel(), but not all, we do not want to reset to buffer
+ * 0, don't need to set priority again either, but re-enabling the task
+ * and the channel might be a good idea.
+ */
+}
+
+static void __idmac_terminate_all(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+ unsigned long flags;
+ int i;
+
+ ipu_disable_channel(idmac, ichan,
+ ichan->status >= IPU_CHANNEL_ENABLED);
+
+ tasklet_disable(&to_ipu(idmac)->tasklet);
+
+ /* ichan->queue is modified in ISR, have to spinlock */
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_splice_init(&ichan->queue, &ichan->free_list);
+
+ if (ichan->desc)
+ for (i = 0; i < ichan->n_tx_desc; i++) {
+ struct idmac_tx_desc *desc = ichan->desc + i;
+ if (list_empty(&desc->list))
+ /* Descriptor was prepared, but not submitted */
+ list_add(&desc->list,
+ &ichan->free_list);
+
+ async_tx_clear_ack(&desc->txd);
+ }
+
+ ichan->sg[0] = NULL;
+ ichan->sg[1] = NULL;
+ spin_unlock_irqrestore(&ichan->lock, flags);
+
+ tasklet_enable(&to_ipu(idmac)->tasklet);
+
+ ichan->status = IPU_CHANNEL_INITIALIZED;
+}
+
+static void idmac_terminate_all(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+
+ mutex_lock(&ichan->chan_mutex);
+
+ __idmac_terminate_all(chan);
+
+ mutex_unlock(&ichan->chan_mutex);
+}
+
+static int idmac_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+ int ret;
+
+ /* dmaengine.c now guarantees to only offer free channels */
+ BUG_ON(chan->client_count > 1);
+ WARN_ON(ichan->status != IPU_CHANNEL_FREE);
+
+ chan->cookie = 1;
+ ichan->completed = -ENXIO;
+
+ ret = ipu_irq_map(ichan->dma_chan.chan_id);
+ if (ret < 0)
+ goto eimap;
+
+ ichan->eof_irq = ret;
+ ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
+ ichan->eof_name, ichan);
+ if (ret < 0)
+ goto erirq;
+
+ ret = ipu_init_channel(idmac, ichan);
+ if (ret < 0)
+ goto eichan;
+
+ ichan->status = IPU_CHANNEL_INITIALIZED;
+
+ dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n",
+ ichan->dma_chan.chan_id, ichan->eof_irq);
+
+ return ret;
+
+eichan:
+ free_irq(ichan->eof_irq, ichan);
+erirq:
+ ipu_irq_unmap(ichan->dma_chan.chan_id);
+eimap:
+ return ret;
+}
+
+static void idmac_free_chan_resources(struct dma_chan *chan)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+ struct idmac *idmac = to_idmac(chan->device);
+
+ mutex_lock(&ichan->chan_mutex);
+
+ __idmac_terminate_all(chan);
+
+ if (ichan->status > IPU_CHANNEL_FREE) {
+ free_irq(ichan->eof_irq, ichan);
+ ipu_irq_unmap(ichan->dma_chan.chan_id);
+ }
+
+ ichan->status = IPU_CHANNEL_FREE;
+
+ ipu_uninit_channel(idmac, ichan);
+
+ mutex_unlock(&ichan->chan_mutex);
+
+ tasklet_schedule(&to_ipu(idmac)->tasklet);
+}
+
+static enum dma_status idmac_is_tx_complete(struct dma_chan *chan,
+ dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used)
+{
+ struct idmac_channel *ichan = to_idmac_chan(chan);
+
+ if (done)
+ *done = ichan->completed;
+ if (used)
+ *used = chan->cookie;
+ if (cookie != chan->cookie)
+ return DMA_ERROR;
+ return DMA_SUCCESS;
+}
+
+static int __init ipu_idmac_init(struct ipu *ipu)
+{
+ struct idmac *idmac = &ipu->idmac;
+ struct dma_device *dma = &idmac->dma;
+ int i;
+
+ dma_cap_set(DMA_SLAVE, dma->cap_mask);
+ dma_cap_set(DMA_PRIVATE, dma->cap_mask);
+
+ /* Compulsory common fields */
+ dma->dev = ipu->dev;
+ dma->device_alloc_chan_resources = idmac_alloc_chan_resources;
+ dma->device_free_chan_resources = idmac_free_chan_resources;
+ dma->device_is_tx_complete = idmac_is_tx_complete;
+ dma->device_issue_pending = idmac_issue_pending;
+
+ /* Compulsory for DMA_SLAVE fields */
+ dma->device_prep_slave_sg = idmac_prep_slave_sg;
+ dma->device_terminate_all = idmac_terminate_all;
+
+ INIT_LIST_HEAD(&dma->channels);
+ for (i = 0; i < IPU_CHANNELS_NUM; i++) {
+ struct idmac_channel *ichan = ipu->channel + i;
+ struct dma_chan *dma_chan = &ichan->dma_chan;
+
+ spin_lock_init(&ichan->lock);
+ mutex_init(&ichan->chan_mutex);
+
+ ichan->status = IPU_CHANNEL_FREE;
+ ichan->sec_chan_en = false;
+ ichan->completed = -ENXIO;
+ snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i);
+
+ dma_chan->device = &idmac->dma;
+ dma_chan->cookie = 1;
+ dma_chan->chan_id = i;
+ list_add_tail(&ichan->dma_chan.device_node, &dma->channels);
+ }
+
+ idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
+
+ return dma_async_device_register(&idmac->dma);
+}
+
+static void ipu_idmac_exit(struct ipu *ipu)
+{
+ int i;
+ struct idmac *idmac = &ipu->idmac;
+
+ for (i = 0; i < IPU_CHANNELS_NUM; i++) {
+ struct idmac_channel *ichan = ipu->channel + i;
+
+ idmac_terminate_all(&ichan->dma_chan);
+ idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
+ }
+
+ dma_async_device_unregister(&idmac->dma);
+}
+
+/*****************************************************************************
+ * IPU common probe / remove
+ */
+
+static int ipu_probe(struct platform_device *pdev)
+{
+ struct ipu_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *mem_ipu, *mem_ic;
+ int ret;
+
+ spin_lock_init(&ipu_data.lock);
+
+ mem_ipu = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mem_ic = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!pdata || !mem_ipu || !mem_ic)
+ return -EINVAL;
+
+ ipu_data.dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, &ipu_data);
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ goto err_noirq;
+
+ ipu_data.irq_fn = ret;
+ ret = platform_get_irq(pdev, 1);
+ if (ret < 0)
+ goto err_noirq;
+
+ ipu_data.irq_err = ret;
+ ipu_data.irq_base = pdata->irq_base;
+
+ dev_dbg(&pdev->dev, "fn irq %u, err irq %u, irq-base %u\n",
+ ipu_data.irq_fn, ipu_data.irq_err, ipu_data.irq_base);
+
+ /* Remap IPU common registers */
+ ipu_data.reg_ipu = ioremap(mem_ipu->start,
+ mem_ipu->end - mem_ipu->start + 1);
+ if (!ipu_data.reg_ipu) {
+ ret = -ENOMEM;
+ goto err_ioremap_ipu;
+ }
+
+ /* Remap Image Converter and Image DMA Controller registers */
+ ipu_data.reg_ic = ioremap(mem_ic->start,
+ mem_ic->end - mem_ic->start + 1);
+ if (!ipu_data.reg_ic) {
+ ret = -ENOMEM;
+ goto err_ioremap_ic;
+ }
+
+ /* Get IPU clock */
+ ipu_data.ipu_clk = clk_get(&pdev->dev, "ipu_clk");
+ if (IS_ERR(ipu_data.ipu_clk)) {
+ ret = PTR_ERR(ipu_data.ipu_clk);
+ goto err_clk_get;
+ }
+
+ /* Make sure IPU HSP clock is running */
+ clk_enable(ipu_data.ipu_clk);
+
+ /* Disable all interrupts */
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_2);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_3);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_4);
+ idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_5);
+
+ dev_dbg(&pdev->dev, "%s @ 0x%08lx, fn irq %u, err irq %u\n", pdev->name,
+ (unsigned long)mem_ipu->start, ipu_data.irq_fn, ipu_data.irq_err);
+
+ ret = ipu_irq_attach_irq(&ipu_data, pdev);
+ if (ret < 0)
+ goto err_attach_irq;
+
+ /* Initialize DMA engine */
+ ret = ipu_idmac_init(&ipu_data);
+ if (ret < 0)
+ goto err_idmac_init;
+
+ tasklet_init(&ipu_data.tasklet, ipu_gc_tasklet, (unsigned long)&ipu_data);
+
+ ipu_data.dev = &pdev->dev;
+
+ dev_dbg(ipu_data.dev, "IPU initialized\n");
+
+ return 0;
+
+err_idmac_init:
+err_attach_irq:
+ ipu_irq_detach_irq(&ipu_data, pdev);
+ clk_disable(ipu_data.ipu_clk);
+ clk_put(ipu_data.ipu_clk);
+err_clk_get:
+ iounmap(ipu_data.reg_ic);
+err_ioremap_ic:
+ iounmap(ipu_data.reg_ipu);
+err_ioremap_ipu:
+err_noirq:
+ dev_err(&pdev->dev, "Failed to probe IPU: %d\n", ret);
+ return ret;
+}
+
+static int ipu_remove(struct platform_device *pdev)
+{
+ struct ipu *ipu = platform_get_drvdata(pdev);
+
+ ipu_idmac_exit(ipu);
+ ipu_irq_detach_irq(ipu, pdev);
+ clk_disable(ipu->ipu_clk);
+ clk_put(ipu->ipu_clk);
+ iounmap(ipu->reg_ic);
+ iounmap(ipu->reg_ipu);
+ tasklet_kill(&ipu->tasklet);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+/*
+ * We need two MEM resources - with IPU-common and Image Converter registers,
+ * including PF_CONF and IDMAC_* registers, and two IRQs - function and error
+ */
+static struct platform_driver ipu_platform_driver = {
+ .driver = {
+ .name = "ipu-core",
+ .owner = THIS_MODULE,
+ },
+ .remove = ipu_remove,
+};
+
+static int __init ipu_init(void)
+{
+ return platform_driver_probe(&ipu_platform_driver, ipu_probe);
+}
+subsys_initcall(ipu_init);
+
+MODULE_DESCRIPTION("IPU core driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_ALIAS("platform:ipu-core");
diff --git a/drivers/dma/ipu/ipu_intern.h b/drivers/dma/ipu/ipu_intern.h
new file mode 100644
index 000000000000..545cf11a94ab
--- /dev/null
+++ b/drivers/dma/ipu/ipu_intern.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * Copyright (C) 2005-2007 Freescale Semiconductor, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IPU_INTERN_H_
+#define _IPU_INTERN_H_
+
+#include <linux/dmaengine.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+/* IPU Common registers */
+#define IPU_CONF 0x00
+#define IPU_CHA_BUF0_RDY 0x04
+#define IPU_CHA_BUF1_RDY 0x08
+#define IPU_CHA_DB_MODE_SEL 0x0C
+#define IPU_CHA_CUR_BUF 0x10
+#define IPU_FS_PROC_FLOW 0x14
+#define IPU_FS_DISP_FLOW 0x18
+#define IPU_TASKS_STAT 0x1C
+#define IPU_IMA_ADDR 0x20
+#define IPU_IMA_DATA 0x24
+#define IPU_INT_CTRL_1 0x28
+#define IPU_INT_CTRL_2 0x2C
+#define IPU_INT_CTRL_3 0x30
+#define IPU_INT_CTRL_4 0x34
+#define IPU_INT_CTRL_5 0x38
+#define IPU_INT_STAT_1 0x3C
+#define IPU_INT_STAT_2 0x40
+#define IPU_INT_STAT_3 0x44
+#define IPU_INT_STAT_4 0x48
+#define IPU_INT_STAT_5 0x4C
+#define IPU_BRK_CTRL_1 0x50
+#define IPU_BRK_CTRL_2 0x54
+#define IPU_BRK_STAT 0x58
+#define IPU_DIAGB_CTRL 0x5C
+
+/* IPU_CONF Register bits */
+#define IPU_CONF_CSI_EN 0x00000001
+#define IPU_CONF_IC_EN 0x00000002
+#define IPU_CONF_ROT_EN 0x00000004
+#define IPU_CONF_PF_EN 0x00000008
+#define IPU_CONF_SDC_EN 0x00000010
+#define IPU_CONF_ADC_EN 0x00000020
+#define IPU_CONF_DI_EN 0x00000040
+#define IPU_CONF_DU_EN 0x00000080
+#define IPU_CONF_PXL_ENDIAN 0x00000100
+
+/* Image Converter Registers */
+#define IC_CONF 0x88
+#define IC_PRP_ENC_RSC 0x8C
+#define IC_PRP_VF_RSC 0x90
+#define IC_PP_RSC 0x94
+#define IC_CMBP_1 0x98
+#define IC_CMBP_2 0x9C
+#define PF_CONF 0xA0
+#define IDMAC_CONF 0xA4
+#define IDMAC_CHA_EN 0xA8
+#define IDMAC_CHA_PRI 0xAC
+#define IDMAC_CHA_BUSY 0xB0
+
+/* Image Converter Register bits */
+#define IC_CONF_PRPENC_EN 0x00000001
+#define IC_CONF_PRPENC_CSC1 0x00000002
+#define IC_CONF_PRPENC_ROT_EN 0x00000004
+#define IC_CONF_PRPVF_EN 0x00000100
+#define IC_CONF_PRPVF_CSC1 0x00000200
+#define IC_CONF_PRPVF_CSC2 0x00000400
+#define IC_CONF_PRPVF_CMB 0x00000800
+#define IC_CONF_PRPVF_ROT_EN 0x00001000
+#define IC_CONF_PP_EN 0x00010000
+#define IC_CONF_PP_CSC1 0x00020000
+#define IC_CONF_PP_CSC2 0x00040000
+#define IC_CONF_PP_CMB 0x00080000
+#define IC_CONF_PP_ROT_EN 0x00100000
+#define IC_CONF_IC_GLB_LOC_A 0x10000000
+#define IC_CONF_KEY_COLOR_EN 0x20000000
+#define IC_CONF_RWS_EN 0x40000000
+#define IC_CONF_CSI_MEM_WR_EN 0x80000000
+
+#define IDMA_CHAN_INVALID 0x000000FF
+#define IDMA_IC_0 0x00000001
+#define IDMA_IC_1 0x00000002
+#define IDMA_IC_2 0x00000004
+#define IDMA_IC_3 0x00000008
+#define IDMA_IC_4 0x00000010
+#define IDMA_IC_5 0x00000020
+#define IDMA_IC_6 0x00000040
+#define IDMA_IC_7 0x00000080
+#define IDMA_IC_8 0x00000100
+#define IDMA_IC_9 0x00000200
+#define IDMA_IC_10 0x00000400
+#define IDMA_IC_11 0x00000800
+#define IDMA_IC_12 0x00001000
+#define IDMA_IC_13 0x00002000
+#define IDMA_SDC_BG 0x00004000
+#define IDMA_SDC_FG 0x00008000
+#define IDMA_SDC_MASK 0x00010000
+#define IDMA_SDC_PARTIAL 0x00020000
+#define IDMA_ADC_SYS1_WR 0x00040000
+#define IDMA_ADC_SYS2_WR 0x00080000
+#define IDMA_ADC_SYS1_CMD 0x00100000
+#define IDMA_ADC_SYS2_CMD 0x00200000
+#define IDMA_ADC_SYS1_RD 0x00400000
+#define IDMA_ADC_SYS2_RD 0x00800000
+#define IDMA_PF_QP 0x01000000
+#define IDMA_PF_BSP 0x02000000
+#define IDMA_PF_Y_IN 0x04000000
+#define IDMA_PF_U_IN 0x08000000
+#define IDMA_PF_V_IN 0x10000000
+#define IDMA_PF_Y_OUT 0x20000000
+#define IDMA_PF_U_OUT 0x40000000
+#define IDMA_PF_V_OUT 0x80000000
+
+#define TSTAT_PF_H264_PAUSE 0x00000001
+#define TSTAT_CSI2MEM_MASK 0x0000000C
+#define TSTAT_CSI2MEM_OFFSET 2
+#define TSTAT_VF_MASK 0x00000600
+#define TSTAT_VF_OFFSET 9
+#define TSTAT_VF_ROT_MASK 0x000C0000
+#define TSTAT_VF_ROT_OFFSET 18
+#define TSTAT_ENC_MASK 0x00000180
+#define TSTAT_ENC_OFFSET 7
+#define TSTAT_ENC_ROT_MASK 0x00030000
+#define TSTAT_ENC_ROT_OFFSET 16
+#define TSTAT_PP_MASK 0x00001800
+#define TSTAT_PP_OFFSET 11
+#define TSTAT_PP_ROT_MASK 0x00300000
+#define TSTAT_PP_ROT_OFFSET 20
+#define TSTAT_PF_MASK 0x00C00000
+#define TSTAT_PF_OFFSET 22
+#define TSTAT_ADCSYS1_MASK 0x03000000
+#define TSTAT_ADCSYS1_OFFSET 24
+#define TSTAT_ADCSYS2_MASK 0x0C000000
+#define TSTAT_ADCSYS2_OFFSET 26
+
+#define TASK_STAT_IDLE 0
+#define TASK_STAT_ACTIVE 1
+#define TASK_STAT_WAIT4READY 2
+
+struct idmac {
+ struct dma_device dma;
+};
+
+struct ipu {
+ void __iomem *reg_ipu;
+ void __iomem *reg_ic;
+ unsigned int irq_fn; /* IPU Function IRQ to the CPU */
+ unsigned int irq_err; /* IPU Error IRQ to the CPU */
+ unsigned int irq_base; /* Beginning of the IPU IRQ range */
+ unsigned long channel_init_mask;
+ spinlock_t lock;
+ struct clk *ipu_clk;
+ struct device *dev;
+ struct idmac idmac;
+ struct idmac_channel channel[IPU_CHANNELS_NUM];
+ struct tasklet_struct tasklet;
+};
+
+#define to_idmac(d) container_of(d, struct idmac, dma)
+
+extern int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev);
+extern void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev);
+
+extern bool ipu_irq_status(uint32_t irq);
+extern int ipu_irq_map(unsigned int source);
+extern int ipu_irq_unmap(unsigned int source);
+
+#endif
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
new file mode 100644
index 000000000000..83f532cc767f
--- /dev/null
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/ipu.h>
+
+#include "ipu_intern.h"
+
+/*
+ * Register read / write - shall be inlined by the compiler
+ */
+static u32 ipu_read_reg(struct ipu *ipu, unsigned long reg)
+{
+ return __raw_readl(ipu->reg_ipu + reg);
+}
+
+static void ipu_write_reg(struct ipu *ipu, u32 value, unsigned long reg)
+{
+ __raw_writel(value, ipu->reg_ipu + reg);
+}
+
+
+/*
+ * IPU IRQ chip driver
+ */
+
+#define IPU_IRQ_NR_FN_BANKS 3
+#define IPU_IRQ_NR_ERR_BANKS 2
+#define IPU_IRQ_NR_BANKS (IPU_IRQ_NR_FN_BANKS + IPU_IRQ_NR_ERR_BANKS)
+
+struct ipu_irq_bank {
+ unsigned int control;
+ unsigned int status;
+ spinlock_t lock;
+ struct ipu *ipu;
+};
+
+static struct ipu_irq_bank irq_bank[IPU_IRQ_NR_BANKS] = {
+ /* 3 groups of functional interrupts */
+ {
+ .control = IPU_INT_CTRL_1,
+ .status = IPU_INT_STAT_1,
+ }, {
+ .control = IPU_INT_CTRL_2,
+ .status = IPU_INT_STAT_2,
+ }, {
+ .control = IPU_INT_CTRL_3,
+ .status = IPU_INT_STAT_3,
+ },
+ /* 2 groups of error interrupts */
+ {
+ .control = IPU_INT_CTRL_4,
+ .status = IPU_INT_STAT_4,
+ }, {
+ .control = IPU_INT_CTRL_5,
+ .status = IPU_INT_STAT_5,
+ },
+};
+
+struct ipu_irq_map {
+ unsigned int irq;
+ int source;
+ struct ipu_irq_bank *bank;
+ struct ipu *ipu;
+};
+
+static struct ipu_irq_map irq_map[CONFIG_MX3_IPU_IRQS];
+/* Protects allocations from the above array of maps */
+static DEFINE_MUTEX(map_lock);
+/* Protects register accesses and individual mappings */
+static DEFINE_SPINLOCK(bank_lock);
+
+static struct ipu_irq_map *src2map(unsigned int src)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++)
+ if (irq_map[i].source == src)
+ return irq_map + i;
+
+ return NULL;
+}
+
+static void ipu_irq_unmask(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+
+ bank = map->bank;
+ if (!bank) {
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ return;
+ }
+
+ reg = ipu_read_reg(bank->ipu, bank->control);
+ reg |= (1UL << (map->source & 31));
+ ipu_write_reg(bank->ipu, reg, bank->control);
+
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+}
+
+static void ipu_irq_mask(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+
+ bank = map->bank;
+ if (!bank) {
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ return;
+ }
+
+ reg = ipu_read_reg(bank->ipu, bank->control);
+ reg &= ~(1UL << (map->source & 31));
+ ipu_write_reg(bank->ipu, reg, bank->control);
+
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+}
+
+static void ipu_irq_ack(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+
+ bank = map->bank;
+ if (!bank) {
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ return;
+ }
+
+ ipu_write_reg(bank->ipu, 1UL << (map->source & 31), bank->status);
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+}
+
+/**
+ * ipu_irq_status() - returns the current interrupt status of the specified IRQ.
+ * @irq: interrupt line to get status for.
+ * @return: true if the interrupt is pending/asserted or false if the
+ * interrupt is not pending.
+ */
+bool ipu_irq_status(unsigned int irq)
+{
+ struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_bank *bank;
+ unsigned long lock_flags;
+ bool ret;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+ bank = map->bank;
+ ret = bank && ipu_read_reg(bank->ipu, bank->status) &
+ (1UL << (map->source & 31));
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+
+ return ret;
+}
+
+/**
+ * ipu_irq_map() - map an IPU interrupt source to an IRQ number
+ * @source: interrupt source bit position (see below)
+ * @return: mapped IRQ number or negative error code
+ *
+ * The source parameter has to be explained further. On i.MX31 IPU has 137 IRQ
+ * sources, they are broken down in 5 32-bit registers, like 32, 32, 24, 32, 17.
+ * However, the source argument of this function is not the sequence number of
+ * the possible IRQ, but rather its bit position. So, first interrupt in fourth
+ * register has source number 96, and not 88. This makes calculations easier,
+ * and also provides forward compatibility with any future IPU implementations
+ * with any interrupt bit assignments.
+ */
+int ipu_irq_map(unsigned int source)
+{
+ int i, ret = -ENOMEM;
+ struct ipu_irq_map *map;
+
+ might_sleep();
+
+ mutex_lock(&map_lock);
+ map = src2map(source);
+ if (map) {
+ pr_err("IPU: Source %u already mapped to IRQ %u\n", source, map->irq);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
+ if (irq_map[i].source < 0) {
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+ irq_map[i].source = source;
+ irq_map[i].bank = irq_bank + source / 32;
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+
+ ret = irq_map[i].irq;
+ pr_debug("IPU: mapped source %u to IRQ %u\n",
+ source, ret);
+ break;
+ }
+ }
+out:
+ mutex_unlock(&map_lock);
+
+ if (ret < 0)
+ pr_err("IPU: couldn't map source %u: %d\n", source, ret);
+
+ return ret;
+}
+
+/**
+ * ipu_irq_map() - map an IPU interrupt source to an IRQ number
+ * @source: interrupt source bit position (see ipu_irq_map())
+ * @return: 0 or negative error code
+ */
+int ipu_irq_unmap(unsigned int source)
+{
+ int i, ret = -EINVAL;
+
+ might_sleep();
+
+ mutex_lock(&map_lock);
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
+ if (irq_map[i].source == source) {
+ unsigned long lock_flags;
+
+ pr_debug("IPU: unmapped source %u from IRQ %u\n",
+ source, irq_map[i].irq);
+
+ spin_lock_irqsave(&bank_lock, lock_flags);
+ irq_map[i].source = -EINVAL;
+ irq_map[i].bank = NULL;
+ spin_unlock_irqrestore(&bank_lock, lock_flags);
+
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&map_lock);
+
+ return ret;
+}
+
+/* Chained IRQ handler for IPU error interrupt */
+static void ipu_irq_err(unsigned int irq, struct irq_desc *desc)
+{
+ struct ipu *ipu = get_irq_data(irq);
+ u32 status;
+ int i, line;
+
+ for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
+ struct ipu_irq_bank *bank = irq_bank + i;
+
+ spin_lock(&bank_lock);
+ status = ipu_read_reg(ipu, bank->status);
+ /*
+ * Don't think we have to clear all interrupts here, they will
+ * be acked by ->handle_irq() (handle_level_irq). However, we
+ * might want to clear unhandled interrupts after the loop...
+ */
+ status &= ipu_read_reg(ipu, bank->control);
+ spin_unlock(&bank_lock);
+ while ((line = ffs(status))) {
+ struct ipu_irq_map *map;
+
+ line--;
+ status &= ~(1UL << line);
+
+ spin_lock(&bank_lock);
+ map = src2map(32 * i + line);
+ if (map)
+ irq = map->irq;
+ spin_unlock(&bank_lock);
+
+ if (!map) {
+ pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
+ line, i);
+ continue;
+ }
+ generic_handle_irq(irq);
+ }
+ }
+}
+
+/* Chained IRQ handler for IPU function interrupt */
+static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc)
+{
+ struct ipu *ipu = get_irq_data(irq);
+ u32 status;
+ int i, line;
+
+ for (i = 0; i < IPU_IRQ_NR_FN_BANKS; i++) {
+ struct ipu_irq_bank *bank = irq_bank + i;
+
+ spin_lock(&bank_lock);
+ status = ipu_read_reg(ipu, bank->status);
+ /* Not clearing all interrupts, see above */
+ status &= ipu_read_reg(ipu, bank->control);
+ spin_unlock(&bank_lock);
+ while ((line = ffs(status))) {
+ struct ipu_irq_map *map;
+
+ line--;
+ status &= ~(1UL << line);
+
+ spin_lock(&bank_lock);
+ map = src2map(32 * i + line);
+ if (map)
+ irq = map->irq;
+ spin_unlock(&bank_lock);
+
+ if (!map) {
+ pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
+ line, i);
+ continue;
+ }
+ generic_handle_irq(irq);
+ }
+ }
+}
+
+static struct irq_chip ipu_irq_chip = {
+ .name = "ipu_irq",
+ .ack = ipu_irq_ack,
+ .mask = ipu_irq_mask,
+ .unmask = ipu_irq_unmask,
+};
+
+/* Install the IRQ handler */
+int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
+{
+ struct ipu_platform_data *pdata = dev->dev.platform_data;
+ unsigned int irq, irq_base, i;
+
+ irq_base = pdata->irq_base;
+
+ for (i = 0; i < IPU_IRQ_NR_BANKS; i++)
+ irq_bank[i].ipu = ipu;
+
+ for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
+ int ret;
+
+ irq = irq_base + i;
+ ret = set_irq_chip(irq, &ipu_irq_chip);
+ if (ret < 0)
+ return ret;
+ ret = set_irq_chip_data(irq, irq_map + i);
+ if (ret < 0)
+ return ret;
+ irq_map[i].ipu = ipu;
+ irq_map[i].irq = irq;
+ irq_map[i].source = -EINVAL;
+ set_irq_handler(irq, handle_level_irq);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+#endif
+ }
+
+ set_irq_data(ipu->irq_fn, ipu);
+ set_irq_chained_handler(ipu->irq_fn, ipu_irq_fn);
+
+ set_irq_data(ipu->irq_err, ipu);
+ set_irq_chained_handler(ipu->irq_err, ipu_irq_err);
+
+ return 0;
+}
+
+void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev)
+{
+ struct ipu_platform_data *pdata = dev->dev.platform_data;
+ unsigned int irq, irq_base;
+
+ irq_base = pdata->irq_base;
+
+ set_irq_chained_handler(ipu->irq_fn, NULL);
+ set_irq_data(ipu->irq_fn, NULL);
+
+ set_irq_chained_handler(ipu->irq_err, NULL);
+ set_irq_data(ipu->irq_err, NULL);
+
+ for (irq = irq_base; irq < irq_base + CONFIG_MX3_IPU_IRQS; irq++) {
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, 0);
+#endif
+ set_irq_chip(irq, NULL);
+ set_irq_chip_data(irq, NULL);
+ }
+}
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
index cd2e3b8087e7..cb0f639f049d 100644
--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -36,7 +36,7 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
struct csrow_info *csrow = &mci->csrows[0];
unsigned long address, pfn, offset, syndrome;
- dev_dbg(mci->dev, "ECC CE err on node %d, channel %d, ar = 0x%016lx\n",
+ dev_dbg(mci->dev, "ECC CE err on node %d, channel %d, ar = 0x%016llx\n",
priv->node, chan, ar);
/* Address decoding is likely a bit bogus, to dbl check */
@@ -58,7 +58,7 @@ static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar)
struct csrow_info *csrow = &mci->csrows[0];
unsigned long address, pfn, offset;
- dev_dbg(mci->dev, "ECC UE err on node %d, channel %d, ar = 0x%016lx\n",
+ dev_dbg(mci->dev, "ECC UE err on node %d, channel %d, ar = 0x%016llx\n",
priv->node, chan, ar);
/* Address decoding is likely a bit bogus, to dbl check */
@@ -169,7 +169,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
/* Get channel population */
reg = in_be64(&regs->mic_mnt_cfg);
- dev_dbg(&pdev->dev, "MIC_MNT_CFG = 0x%016lx\n", reg);
+ dev_dbg(&pdev->dev, "MIC_MNT_CFG = 0x%016llx\n", reg);
chanmask = 0;
if (reg & CBE_MIC_MNT_CFG_CHAN_0_POP)
chanmask |= 0x1;
@@ -180,7 +180,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
"Yuck ! No channel populated ? Aborting !\n");
return -ENODEV;
}
- dev_dbg(&pdev->dev, "Initial FIR = 0x%016lx\n",
+ dev_dbg(&pdev->dev, "Initial FIR = 0x%016llx\n",
in_be64(&regs->mic_fir));
/* Allocate & init EDAC MC data structure */
@@ -198,7 +198,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
mci->edac_cap = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
mci->mod_name = "cell_edac";
mci->ctl_name = "MIC";
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
mci->edac_check = cell_edac_check;
cell_edac_init_csrows(mci);
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 853ef37ec006..4637a4a757df 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -218,7 +218,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
pci->dev = &op->dev;
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
- pci->dev_name = op->dev.bus_id;
+ pci->dev_name = dev_name(&op->dev);
if (edac_op_state == EDAC_OPSTATE_POLL)
pci->edac_check = mpc85xx_pci_check;
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
index 083ce8d0c63d..5131aaae8e03 100644
--- a/drivers/edac/mv64x60_edac.c
+++ b/drivers/edac/mv64x60_edac.c
@@ -121,7 +121,7 @@ static int __devinit mv64x60_pci_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
platform_set_drvdata(pdev, pci);
pci->dev = &pdev->dev;
- pci->dev_name = pdev->dev.bus_id;
+ pci->dev_name = dev_name(&pdev->dev);
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
@@ -294,7 +294,7 @@ static int __devinit mv64x60_sram_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -462,7 +462,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -713,7 +713,7 @@ static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mci);
pdata->name = "mv64x60_mc_err";
pdata->irq = NO_IRQ;
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
pdata->edac_idx = edac_mc_idx++;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/eisa/Kconfig b/drivers/eisa/Kconfig
index c0646576cf47..2705284f6223 100644
--- a/drivers/eisa/Kconfig
+++ b/drivers/eisa/Kconfig
@@ -3,7 +3,7 @@
#
config EISA_VLB_PRIMING
bool "Vesa Local Bus priming"
- depends on X86_PC && EISA
+ depends on X86 && EISA
default n
---help---
Activate this option if your system contains a Vesa Local
@@ -24,11 +24,11 @@ config EISA_PCI_EISA
When in doubt, say Y.
# Using EISA_VIRTUAL_ROOT on something other than an Alpha or
-# an X86_PC may lead to crashes...
+# an X86 may lead to crashes...
config EISA_VIRTUAL_ROOT
bool "EISA virtual root device"
- depends on EISA && (ALPHA || X86_PC)
+ depends on EISA && (ALPHA || X86)
default y
---help---
Activate this option if your system only have EISA bus
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index c950bf8606d9..66958b3f10b4 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -200,7 +200,7 @@ static int __init eisa_init_device (struct eisa_root_device *root,
edev->dev.bus = &eisa_bus_type;
edev->dev.dma_mask = &edev->dma_mask;
edev->dev.coherent_dma_mask = edev->dma_mask;
- sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot);
+ dev_set_name(&edev->dev, "%02X:%02X", root->bus_nr, slot);
for (i = 0; i < EISA_MAX_RESOURCES; i++) {
#ifdef CONFIG_EISA_NAMES
@@ -301,7 +301,7 @@ static int __init eisa_probe (struct eisa_root_device *root)
struct eisa_device *edev;
printk (KERN_INFO "EISA: Probing bus %d at %s\n",
- root->bus_nr, root->dev->bus_id);
+ root->bus_nr, dev_name(root->dev));
/* First try to get hold of slot 0. If there is no device
* here, simply fail, unless root->force_probe is set. */
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 6bd91a15d5e6..a5dd7a665aa8 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -232,7 +232,7 @@ fw_card_bm_work(struct work_struct *work)
root_id = root_node->node_id;
grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
- if (card->bm_generation + 1 == generation ||
+ if (is_next_generation(generation, card->bm_generation) ||
(card->bm_generation != generation && grace)) {
/*
* This first step is to figure out who is IRM and
@@ -412,6 +412,7 @@ fw_card_add(struct fw_card *card,
{
u32 *config_rom;
size_t length;
+ int err;
card->max_receive = max_receive;
card->link_speed = link_speed;
@@ -422,7 +423,13 @@ fw_card_add(struct fw_card *card,
list_add_tail(&card->link, &card_list);
mutex_unlock(&card_mutex);
- return card->driver->enable(card, config_rom, length);
+ err = card->driver->enable(card, config_rom, length);
+ if (err < 0) {
+ mutex_lock(&card_mutex);
+ list_del(&card->link);
+ mutex_unlock(&card_mutex);
+ }
+ return err;
}
EXPORT_SYMBOL(fw_card_add);
@@ -512,7 +519,7 @@ fw_core_remove_card(struct fw_card *card)
fw_core_initiate_bus_reset(card, 1);
mutex_lock(&card_mutex);
- list_del(&card->link);
+ list_del_init(&card->link);
mutex_unlock(&card_mutex);
/* Set up the dummy driver. */
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 2af5a8d1e012..bf53acb45652 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -25,6 +25,7 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/idr.h>
+#include <linux/jiffies.h>
#include <linux/string.h>
#include <linux/rwsem.h>
#include <linux/semaphore.h>
@@ -634,12 +635,39 @@ struct fw_device *fw_device_get_by_devt(dev_t devt)
return device;
}
+/*
+ * These defines control the retry behavior for reading the config
+ * rom. It shouldn't be necessary to tweak these; if the device
+ * doesn't respond to a config rom read within 10 seconds, it's not
+ * going to respond at all. As for the initial delay, a lot of
+ * devices will be able to respond within half a second after bus
+ * reset. On the other hand, it's not really worth being more
+ * aggressive than that, since it scales pretty well; if 10 devices
+ * are plugged in, they're all getting read within one second.
+ */
+
+#define MAX_RETRIES 10
+#define RETRY_DELAY (3 * HZ)
+#define INITIAL_DELAY (HZ / 2)
+#define SHUTDOWN_DELAY (2 * HZ)
+
static void fw_device_shutdown(struct work_struct *work)
{
struct fw_device *device =
container_of(work, struct fw_device, work.work);
int minor = MINOR(device->device.devt);
+ if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY)
+ && !list_empty(&device->card->link)) {
+ schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
+ return;
+ }
+
+ if (atomic_cmpxchg(&device->state,
+ FW_DEVICE_GONE,
+ FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE)
+ return;
+
fw_device_cdev_remove(device);
device_for_each_child(&device->device, NULL, shutdown_unit);
device_unregister(&device->device);
@@ -647,6 +675,7 @@ static void fw_device_shutdown(struct work_struct *work)
down_write(&fw_device_rwsem);
idr_remove(&fw_device_idr, minor);
up_write(&fw_device_rwsem);
+
fw_device_put(device);
}
@@ -654,25 +683,63 @@ static struct device_type fw_device_type = {
.release = fw_device_release,
};
+static void fw_device_update(struct work_struct *work);
+
/*
- * These defines control the retry behavior for reading the config
- * rom. It shouldn't be necessary to tweak these; if the device
- * doesn't respond to a config rom read within 10 seconds, it's not
- * going to respond at all. As for the initial delay, a lot of
- * devices will be able to respond within half a second after bus
- * reset. On the other hand, it's not really worth being more
- * aggressive than that, since it scales pretty well; if 10 devices
- * are plugged in, they're all getting read within one second.
+ * If a device was pending for deletion because its node went away but its
+ * bus info block and root directory header matches that of a newly discovered
+ * device, revive the existing fw_device.
+ * The newly allocated fw_device becomes obsolete instead.
*/
+static int lookup_existing_device(struct device *dev, void *data)
+{
+ struct fw_device *old = fw_device(dev);
+ struct fw_device *new = data;
+ struct fw_card *card = new->card;
+ int match = 0;
+
+ down_read(&fw_device_rwsem); /* serialize config_rom access */
+ spin_lock_irq(&card->lock); /* serialize node access */
+
+ if (memcmp(old->config_rom, new->config_rom, 6 * 4) == 0 &&
+ atomic_cmpxchg(&old->state,
+ FW_DEVICE_GONE,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
+ struct fw_node *current_node = new->node;
+ struct fw_node *obsolete_node = old->node;
+
+ new->node = obsolete_node;
+ new->node->data = new;
+ old->node = current_node;
+ old->node->data = old;
+
+ old->max_speed = new->max_speed;
+ old->node_id = current_node->node_id;
+ smp_wmb(); /* update node_id before generation */
+ old->generation = card->generation;
+ old->config_rom_retries = 0;
+ fw_notify("rediscovered device %s\n", dev_name(dev));
-#define MAX_RETRIES 10
-#define RETRY_DELAY (3 * HZ)
-#define INITIAL_DELAY (HZ / 2)
+ PREPARE_DELAYED_WORK(&old->work, fw_device_update);
+ schedule_delayed_work(&old->work, 0);
+
+ if (current_node == card->root_node)
+ fw_schedule_bm_work(card, 0);
+
+ match = 1;
+ }
+
+ spin_unlock_irq(&card->lock);
+ up_read(&fw_device_rwsem);
+
+ return match;
+}
static void fw_device_init(struct work_struct *work)
{
struct fw_device *device =
container_of(work, struct fw_device, work.work);
+ struct device *revived_dev;
int minor, err;
/*
@@ -696,6 +763,15 @@ static void fw_device_init(struct work_struct *work)
return;
}
+ revived_dev = device_find_child(device->card->device,
+ device, lookup_existing_device);
+ if (revived_dev) {
+ put_device(revived_dev);
+ fw_device_release(&device->device);
+
+ return;
+ }
+
device_initialize(&device->device);
fw_device_get(device);
@@ -734,9 +810,10 @@ static void fw_device_init(struct work_struct *work)
* fw_node_event().
*/
if (atomic_cmpxchg(&device->state,
- FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
- fw_device_shutdown(work);
+ FW_DEVICE_INITIALIZING,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
+ PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
+ schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
} else {
if (device->config_rom_retries)
fw_notify("created device %s: GUID %08x%08x, S%d00, "
@@ -847,8 +924,8 @@ static void fw_device_refresh(struct work_struct *work)
case REREAD_BIB_UNCHANGED:
if (atomic_cmpxchg(&device->state,
- FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
+ FW_DEVICE_INITIALIZING,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
goto gone;
fw_device_update(work);
@@ -879,8 +956,8 @@ static void fw_device_refresh(struct work_struct *work)
create_units(device);
if (atomic_cmpxchg(&device->state,
- FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
+ FW_DEVICE_INITIALIZING,
+ FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
goto gone;
fw_notify("refreshed device %s\n", dev_name(&device->device));
@@ -890,8 +967,9 @@ static void fw_device_refresh(struct work_struct *work)
give_up:
fw_notify("giving up on refresh of device %s\n", dev_name(&device->device));
gone:
- atomic_set(&device->state, FW_DEVICE_SHUTDOWN);
- fw_device_shutdown(work);
+ atomic_set(&device->state, FW_DEVICE_GONE);
+ PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
+ schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
out:
if (node_id == card->root_node->node_id)
fw_schedule_bm_work(card, 0);
@@ -995,9 +1073,10 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
*/
device = node->data;
if (atomic_xchg(&device->state,
- FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) {
+ FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
- schedule_delayed_work(&device->work, 0);
+ schedule_delayed_work(&device->work,
+ list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
}
break;
}
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index df51732608d9..8ef6ec2ca21c 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -28,6 +28,7 @@
enum fw_device_state {
FW_DEVICE_INITIALIZING,
FW_DEVICE_RUNNING,
+ FW_DEVICE_GONE,
FW_DEVICE_SHUTDOWN,
};
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index ab9c01e462ef..6d19828a93a5 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -226,7 +226,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
#define CONTEXT_DEAD 0x0800
#define CONTEXT_ACTIVE 0x0400
-#define OHCI1394_MAX_AT_REQ_RETRIES 0x2
+#define OHCI1394_MAX_AT_REQ_RETRIES 0xf
#define OHCI1394_MAX_AT_RESP_RETRIES 0x2
#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
@@ -896,11 +896,11 @@ static void context_stop(struct context *ctx)
for (i = 0; i < 10; i++) {
reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs));
if ((reg & CONTEXT_ACTIVE) == 0)
- break;
+ return;
- fw_notify("context_stop: still active (0x%08x)\n", reg);
mdelay(1);
}
+ fw_error("Error: DMA context still active (0x%08x)\n", reg);
}
struct driver_data {
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index e88d5067448c..c71c4419d9e8 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -168,6 +168,7 @@ struct sbp2_target {
int address_high;
unsigned int workarounds;
unsigned int mgt_orb_timeout;
+ unsigned int max_payload;
int dont_block; /* counter for each logical unit */
int blocked; /* ditto */
@@ -310,14 +311,16 @@ struct sbp2_command_orb {
dma_addr_t page_table_bus;
};
+#define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */
+#define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */
+
/*
* List of devices with known bugs.
*
* The firmware_revision field, masked with 0xffff00, is the best
* indicator for the type of bridge chip of a device. It yields a few
* false positives but this did not break correctly behaving devices
- * so far. We use ~0 as a wildcard, since the 24 bit values we get
- * from the config rom can never match that.
+ * so far.
*/
static const struct {
u32 firmware_revision;
@@ -339,33 +342,35 @@ static const struct {
},
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
},
/* PL-3507 bridge with Prolific firmware */ {
.firmware_revision = 0x012800,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_POWER_CONDITION,
},
/* Symbios bridge */ {
.firmware_revision = 0xa0b800,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
.firmware_revision = 0x002600,
- .model = ~0,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
-
/*
- * There are iPods (2nd gen, 3rd gen) with model_id == 0, but
- * these iPods do not feature the read_capacity bug according
- * to one report. Read_capacity behaviour as well as model_id
- * could change due to Apple-supplied firmware updates though.
+ * iPod 2nd generation: needs 128k max transfer size workaround
+ * iPod 3rd generation: needs fix capacity workaround
*/
-
- /* iPod 4th generation. */ {
+ {
+ .firmware_revision = 0x0a2700,
+ .model = 0x000000,
+ .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS |
+ SBP2_WORKAROUND_FIX_CAPACITY,
+ },
+ /* iPod 4th generation */ {
.firmware_revision = 0x0a2700,
.model = 0x000021,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
@@ -1092,7 +1097,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
continue;
if (sbp2_workarounds_table[i].model != model &&
- sbp2_workarounds_table[i].model != ~0)
+ sbp2_workarounds_table[i].model != SBP2_ROM_VALUE_WILDCARD)
continue;
w |= sbp2_workarounds_table[i].workarounds;
@@ -1142,20 +1147,28 @@ static int sbp2_probe(struct device *dev)
fw_device_get(device);
fw_unit_get(unit);
- /* Initialize to values that won't match anything in our table. */
- firmware_revision = 0xff000000;
- model = 0xff000000;
-
/* implicit directory ID */
tgt->directory_id = ((unit->directory - device->config_rom) * 4
+ CSR_CONFIG_ROM) & 0xffffff;
+ firmware_revision = SBP2_ROM_VALUE_MISSING;
+ model = SBP2_ROM_VALUE_MISSING;
+
if (sbp2_scan_unit_dir(tgt, unit->directory, &model,
&firmware_revision) < 0)
goto fail_tgt_put;
sbp2_init_workarounds(tgt, model, firmware_revision);
+ /*
+ * At S100 we can do 512 bytes per packet, at S200 1024 bytes,
+ * and so on up to 4096 bytes. The SBP-2 max_payload field
+ * specifies the max payload size as 2 ^ (max_payload + 2), so
+ * if we set this to max_speed + 7, we get the right value.
+ */
+ tgt->max_payload = min(device->max_speed + 7, 10U);
+ tgt->max_payload = min(tgt->max_payload, device->card->max_receive - 1);
+
/* Do the login in a workqueue so we can easily reschedule retries. */
list_for_each_entry(lu, &tgt->lu_list, link)
sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
@@ -1273,6 +1286,19 @@ static struct fw_driver sbp2_driver = {
.id_table = sbp2_id_table,
};
+static void sbp2_unmap_scatterlist(struct device *card_device,
+ struct sbp2_command_orb *orb)
+{
+ if (scsi_sg_count(orb->cmd))
+ dma_unmap_sg(card_device, scsi_sglist(orb->cmd),
+ scsi_sg_count(orb->cmd),
+ orb->cmd->sc_data_direction);
+
+ if (orb->request.misc & cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT))
+ dma_unmap_single(card_device, orb->page_table_bus,
+ sizeof(orb->page_table), DMA_TO_DEVICE);
+}
+
static unsigned int
sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
{
@@ -1352,15 +1378,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
dma_unmap_single(device->card->device, orb->base.request_bus,
sizeof(orb->request), DMA_TO_DEVICE);
-
- if (scsi_sg_count(orb->cmd) > 0)
- dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
- scsi_sg_count(orb->cmd),
- orb->cmd->sc_data_direction);
-
- if (orb->page_table_bus != 0)
- dma_unmap_single(device->card->device, orb->page_table_bus,
- sizeof(orb->page_table), DMA_TO_DEVICE);
+ sbp2_unmap_scatterlist(device->card->device, orb);
orb->cmd->result = result;
orb->done(orb->cmd);
@@ -1434,7 +1452,6 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
struct sbp2_logical_unit *lu = cmd->device->hostdata;
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_command_orb *orb;
- unsigned int max_payload;
int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
/*
@@ -1462,17 +1479,9 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
orb->done = done;
orb->cmd = cmd;
- orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL);
- /*
- * At speed 100 we can do 512 bytes per packet, at speed 200,
- * 1024 bytes per packet etc. The SBP-2 max_payload field
- * specifies the max payload size as 2 ^ (max_payload + 2), so
- * if we set this to max_speed + 7, we get the right value.
- */
- max_payload = min(device->max_speed + 7,
- device->card->max_receive - 1);
+ orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL);
orb->request.misc = cpu_to_be32(
- COMMAND_ORB_MAX_PAYLOAD(max_payload) |
+ COMMAND_ORB_MAX_PAYLOAD(lu->tgt->max_payload) |
COMMAND_ORB_SPEED(device->max_speed) |
COMMAND_ORB_NOTIFY);
@@ -1491,8 +1500,10 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
orb->base.request_bus =
dma_map_single(device->card->device, &orb->request,
sizeof(orb->request), DMA_TO_DEVICE);
- if (dma_mapping_error(device->card->device, orb->base.request_bus))
+ if (dma_mapping_error(device->card->device, orb->base.request_bus)) {
+ sbp2_unmap_scatterlist(device->card->device, orb);
goto out;
+ }
sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation,
lu->command_block_agent_address + SBP2_ORB_POINTER);
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index c9be6e6948c4..8dd6703b55cd 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -518,6 +518,18 @@ fw_core_handle_bus_reset(struct fw_card *card,
struct fw_node *local_node;
unsigned long flags;
+ /*
+ * If the selfID buffer is not the immediate successor of the
+ * previously processed one, we cannot reliably compare the
+ * old and new topologies.
+ */
+ if (!is_next_generation(generation, card->generation) &&
+ card->local_node != NULL) {
+ fw_notify("skipped bus generations, destroying all nodes\n");
+ fw_destroy_nodes(card);
+ card->bm_retries = 0;
+ }
+
spin_lock_irqsave(&card->lock, flags);
card->node_id = node_id;
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index c9ab12a15f6e..1d78e9cc5940 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -276,6 +276,15 @@ static inline void fw_card_put(struct fw_card *card)
extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);
/*
+ * Check whether new_generation is the immediate successor of old_generation.
+ * Take counter roll-over at 255 (as per to OHCI) into account.
+ */
+static inline bool is_next_generation(int new_generation, int old_generation)
+{
+ return (new_generation & 0xff) == ((old_generation + 1) & 0xff);
+}
+
+/*
* The iso packet format allows for an immediate header/payload part
* stored in 'header' immediately after the packet info plus an
* indirect payload part that is pointer to by the 'payload' field.
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 777fba48d2d3..3009e0171e54 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -244,7 +244,7 @@ static ssize_t host_control_on_shutdown_store(struct device *dev,
*/
int dcdbas_smi_request(struct smi_cmd *smi_cmd)
{
- cpumask_t old_mask;
+ cpumask_var_t old_mask;
int ret = 0;
if (smi_cmd->magic != SMI_CMD_MAGIC) {
@@ -254,8 +254,11 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
}
/* SMI requires CPU 0 */
- old_mask = current->cpus_allowed;
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(0));
+ if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
+ return -ENOMEM;
+
+ cpumask_copy(old_mask, &current->cpus_allowed);
+ set_cpus_allowed_ptr(current, cpumask_of(0));
if (smp_processor_id() != 0) {
dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
__func__);
@@ -275,7 +278,8 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
);
out:
- set_cpus_allowed_ptr(current, &old_mask);
+ set_cpus_allowed_ptr(current, old_mask);
+ free_cpumask_var(old_mask);
return ret;
}
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index d76adfea5df7..8f0f7c449305 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -415,6 +415,29 @@ void __init dmi_scan_machine(void)
}
/**
+ * dmi_matches - check if dmi_system_id structure matches system DMI data
+ * @dmi: pointer to the dmi_system_id structure to check
+ */
+static bool dmi_matches(const struct dmi_system_id *dmi)
+{
+ int i;
+
+ WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
+
+ for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) {
+ int s = dmi->matches[i].slot;
+ if (s == DMI_NONE)
+ continue;
+ if (dmi_ident[s]
+ && strstr(dmi_ident[s], dmi->matches[i].substr))
+ continue;
+ /* No match */
+ return false;
+ }
+ return true;
+}
+
+/**
* dmi_check_system - check system DMI data
* @list: array of dmi_system_id structures to match against
* All non-null elements of the list must match
@@ -429,32 +452,45 @@ void __init dmi_scan_machine(void)
*/
int dmi_check_system(const struct dmi_system_id *list)
{
- int i, count = 0;
- const struct dmi_system_id *d = list;
-
- WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
-
- while (d->ident) {
- for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
- int s = d->matches[i].slot;
- if (s == DMI_NONE)
- continue;
- if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
- continue;
- /* No match */
- goto fail;
+ int count = 0;
+ const struct dmi_system_id *d;
+
+ for (d = list; d->ident; d++)
+ if (dmi_matches(d)) {
+ count++;
+ if (d->callback && d->callback(d))
+ break;
}
- count++;
- if (d->callback && d->callback(d))
- break;
-fail: d++;
- }
return count;
}
EXPORT_SYMBOL(dmi_check_system);
/**
+ * dmi_first_match - find dmi_system_id structure matching system DMI data
+ * @list: array of dmi_system_id structures to match against
+ * All non-null elements of the list must match
+ * their slot's (field index's) data (i.e., each
+ * list string must be a substring of the specified
+ * DMI slot's string data) to be considered a
+ * successful match.
+ *
+ * Walk the blacklist table until the first match is found. Return the
+ * pointer to the matching entry or NULL if there's no match.
+ */
+const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list)
+{
+ const struct dmi_system_id *d;
+
+ for (d = list; d->ident; d++)
+ if (dmi_matches(d))
+ return d;
+
+ return NULL;
+}
+EXPORT_SYMBOL(dmi_first_match);
+
+/**
* dmi_get_system_info - return DMI data value
* @field: data index (see enum dmi_field)
*
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 3ab3e4a41d67..7b7ddc2d51c9 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -938,8 +938,8 @@ static int __init ibft_init(void)
return -ENOMEM;
if (ibft_addr) {
- printk(KERN_INFO "iBFT detected at 0x%lx.\n",
- virt_to_phys((void *)ibft_addr));
+ printk(KERN_INFO "iBFT detected at 0x%llx.\n",
+ (u64)virt_to_phys((void *)ibft_addr));
rc = ibft_check_device();
if (rc)
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 261b9aa3f248..05aa2d406ac6 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/firmware/memmap.c
* Copyright (C) 2008 SUSE LINUX Products GmbH
- * by Bernhard Walle <bwalle@suse.de>
+ * by Bernhard Walle <bernhard.walle@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License v2.0 as published by
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c
index 7a1168249dd5..984b587f0f96 100644
--- a/drivers/gpio/bt8xxgpio.c
+++ b/drivers/gpio/bt8xxgpio.c
@@ -160,7 +160,7 @@ static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
{
struct gpio_chip *c = &bg->gpio;
- c->label = bg->pdev->dev.bus_id;
+ c->label = dev_name(&bg->pdev->dev);
c->owner = THIS_MODULE;
c->direction_input = bt8xxgpio_gpio_direction_input;
c->get = bt8xxgpio_gpio_get;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 35e7aea4222c..42fb2fd24c0c 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -789,6 +789,7 @@ int gpio_request(unsigned gpio, const char *label)
} else {
status = -EBUSY;
module_put(chip->owner);
+ goto done;
}
if (chip->request) {
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 5130b72d593c..3a22eb9be378 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -70,7 +70,7 @@ config DRM_I915
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- depends on FB
+ select FB
tristate "i915 driver"
help
Choose this option if you have a system that has Intel 830M, 845G,
@@ -80,18 +80,17 @@ config DRM_I915
XFree86 4.4 and above. If unsure, build this and i830 as modules and
the X server will load the correct one.
-endchoice
-
config DRM_I915_KMS
bool "Enable modesetting on intel by default"
depends on DRM_I915
help
- Choose this option if you want kernel modesetting enabled by default,
- and you have a new enough userspace to support this. Running old
- userspaces with this enabled will cause pain. Note that this causes
- the driver to bind to PCI devices, which precludes loading things
- like intelfb.
+ Choose this option if you want kernel modesetting enabled by default,
+ and you have a new enough userspace to support this. Running old
+ userspaces with this enabled will cause pain. Note that this causes
+ the driver to bind to PCI devices, which precludes loading things
+ like intelfb.
+endchoice
config DRM_MGA
tristate "Matrox g200/g400"
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
index 3d33b8252b58..14796594e5d9 100644
--- a/drivers/gpu/drm/drm_agpsupport.c
+++ b/drivers/gpu/drm/drm_agpsupport.c
@@ -33,10 +33,11 @@
#include "drmP.h"
#include <linux/module.h>
-#include <asm/agp.h>
#if __OS_HAS_AGP
+#include <asm/agp.h>
+
/**
* Get AGP information.
*
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5b2cbb778162..94a768871734 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -194,7 +194,6 @@ char *drm_get_connector_status_name(enum drm_connector_status status)
* @type: object type
*
* LOCKING:
- * Caller must hold DRM mode_config lock.
*
* Create a unique identifier based on @ptr in @dev's identifier space. Used
* for tracking modes, CRTCs and connectors.
@@ -209,15 +208,15 @@ static int drm_mode_object_get(struct drm_device *dev,
int new_id = 0;
int ret;
- WARN(!mutex_is_locked(&dev->mode_config.mutex),
- "%s called w/o mode_config lock\n", __func__);
again:
if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
DRM_ERROR("Ran out memory getting a mode number\n");
return -EINVAL;
}
+ mutex_lock(&dev->mode_config.idr_mutex);
ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
+ mutex_unlock(&dev->mode_config.idr_mutex);
if (ret == -EAGAIN)
goto again;
@@ -239,16 +238,20 @@ again:
static void drm_mode_object_put(struct drm_device *dev,
struct drm_mode_object *object)
{
+ mutex_lock(&dev->mode_config.idr_mutex);
idr_remove(&dev->mode_config.crtc_idr, object->id);
+ mutex_unlock(&dev->mode_config.idr_mutex);
}
void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type)
{
- struct drm_mode_object *obj;
+ struct drm_mode_object *obj = NULL;
+ mutex_lock(&dev->mode_config.idr_mutex);
obj = idr_find(&dev->mode_config.crtc_idr, id);
if (!obj || (obj->type != type) || (obj->id != id))
- return NULL;
+ obj = NULL;
+ mutex_unlock(&dev->mode_config.idr_mutex);
return obj;
}
@@ -786,6 +789,7 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
void drm_mode_config_init(struct drm_device *dev)
{
mutex_init(&dev->mode_config.mutex);
+ mutex_init(&dev->mode_config.idr_mutex);
INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.fb_kernel_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list);
@@ -1737,9 +1741,8 @@ out:
* RETURNS:
* Zero on success, errno on failure.
*/
-void drm_fb_release(struct file *filp)
+void drm_fb_release(struct drm_file *priv)
{
- struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_framebuffer *fb, *tfb;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 964c5eb1fada..1c3a8c557140 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -452,6 +452,59 @@ static void drm_setup_crtcs(struct drm_device *dev)
kfree(modes);
kfree(enabled);
}
+
+/**
+ * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
+ * @encoder: encoder to test
+ * @crtc: crtc to test
+ *
+ * Return false if @encoder can't be driven by @crtc, true otherwise.
+ */
+static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
+ struct drm_crtc *crtc)
+{
+ struct drm_device *dev;
+ struct drm_crtc *tmp;
+ int crtc_mask = 1;
+
+ WARN(!crtc, "checking null crtc?");
+
+ dev = crtc->dev;
+
+ list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
+ if (tmp == crtc)
+ break;
+ crtc_mask <<= 1;
+ }
+
+ if (encoder->possible_crtcs & crtc_mask)
+ return true;
+ return false;
+}
+
+/*
+ * Check the CRTC we're going to map each output to vs. its current
+ * CRTC. If they don't match, we have to disable the output and the CRTC
+ * since the driver will have to re-route things.
+ */
+static void
+drm_crtc_prepare_encoders(struct drm_device *dev)
+{
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ struct drm_encoder *encoder;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ encoder_funcs = encoder->helper_private;
+ /* Disable unused encoders */
+ if (encoder->crtc == NULL)
+ (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+ /* Disable encoders whose CRTC is about to change */
+ if (encoder_funcs->get_crtc &&
+ encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
+ (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+ }
+}
+
/**
* drm_crtc_set_mode - set a mode
* @crtc: CRTC to program
@@ -512,8 +565,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
if (drm_mode_equal(&saved_mode, &crtc->mode)) {
if (saved_x != crtc->x || saved_y != crtc->y ||
depth_changed || bpp_changed) {
- crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
- old_fb);
+ ret = !crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
+ old_fb);
goto done;
}
}
@@ -547,12 +600,16 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
encoder_funcs->prepare(encoder);
}
+ drm_crtc_prepare_encoders(dev);
+
crtc_funcs->prepare(crtc);
/* Set up the DPLL and any encoders state that needs to adjust or depend
* on the DPLL.
*/
- crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+ ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+ if (!ret)
+ goto done;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -615,7 +672,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
struct drm_device *dev;
struct drm_crtc **save_crtcs, *new_crtc;
struct drm_encoder **save_encoders, *new_encoder;
- struct drm_framebuffer *old_fb;
+ struct drm_framebuffer *old_fb = NULL;
bool save_enabled;
bool mode_changed = false;
bool fb_changed = false;
@@ -666,9 +723,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
* and then just flip_or_move it */
if (set->crtc->fb != set->fb) {
/* If we have no fb then treat it as a full mode set */
- if (set->crtc->fb == NULL)
+ if (set->crtc->fb == NULL) {
+ DRM_DEBUG("crtc has no fb, full mode set\n");
mode_changed = true;
- else if ((set->fb->bits_per_pixel !=
+ } else if ((set->fb->bits_per_pixel !=
set->crtc->fb->bits_per_pixel) ||
set->fb->depth != set->crtc->fb->depth)
fb_changed = true;
@@ -680,7 +738,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fb_changed = true;
if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
- DRM_DEBUG("modes are different\n");
+ DRM_DEBUG("modes are different, full mode set\n");
drm_mode_debug_printmodeline(&set->crtc->mode);
drm_mode_debug_printmodeline(set->mode);
mode_changed = true;
@@ -706,6 +764,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
}
if (new_encoder != connector->encoder) {
+ DRM_DEBUG("encoder changed, full mode switch\n");
mode_changed = true;
connector->encoder = new_encoder;
}
@@ -732,10 +791,20 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (set->connectors[ro] == connector)
new_crtc = set->crtc;
}
+
+ /* Make sure the new CRTC will work with the encoder */
+ if (new_crtc &&
+ !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
+ ret = -EINVAL;
+ goto fail_set_mode;
+ }
if (new_crtc != connector->encoder->crtc) {
+ DRM_DEBUG("crtc changed, full mode switch\n");
mode_changed = true;
connector->encoder->crtc = new_crtc;
}
+ DRM_DEBUG("setting connector %d crtc to %p\n",
+ connector->base.id, new_crtc);
}
/* mode_set_base is not a required function */
@@ -752,6 +821,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
set->x, set->y,
old_fb)) {
+ DRM_ERROR("failed to set mode on crtc %p\n",
+ set->crtc);
ret = -EINVAL;
goto fail_set_mode;
}
@@ -765,7 +836,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
old_fb = set->crtc->fb;
if (set->crtc->fb != set->fb)
set->crtc->fb = set->fb;
- crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb);
+ ret = crtc_funcs->mode_set_base(set->crtc,
+ set->x, set->y, old_fb);
+ if (ret != 0)
+ goto fail_set_mode;
}
kfree(save_encoders);
@@ -774,9 +848,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
fail_set_mode:
set->crtc->enabled = save_enabled;
+ set->crtc->fb = old_fb;
count = 0;
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder)
+ continue;
+
connector->encoder->crtc = save_crtcs[count++];
+ }
fail_no_encoder:
kfree(save_crtcs);
count = 0;
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 5ff88d952226..14c7a23dc157 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -294,6 +294,7 @@ EXPORT_SYMBOL(drm_init);
*/
static void drm_cleanup(struct drm_device * dev)
{
+ struct drm_map_list *r_list, *list_temp;
DRM_DEBUG("\n");
if (!dev) {
@@ -325,6 +326,9 @@ static void drm_cleanup(struct drm_device * dev)
drm_ht_remove(&dev->map_hash);
drm_ctxbitmap_cleanup(dev);
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+ drm_rmmap(dev, r_list->map);
+
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_put_minor(&dev->control);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0fbb0da342cb..a839a28d8ee6 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -125,7 +125,7 @@ static bool edid_is_valid(struct edid *edid)
DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
goto bad;
}
- if (edid->revision <= 0 || edid->revision > 3) {
+ if (edid->revision > 3) {
DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision);
goto bad;
}
@@ -320,10 +320,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo);
mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo;
- mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 8) |
+ mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) |
pt->vsync_offset_lo);
mode->vsync_end = mode->vsync_start +
- ((pt->vsync_pulse_width_hi << 8) |
+ ((pt->vsync_pulse_width_hi << 4) |
pt->vsync_pulse_width_lo);
mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo);
@@ -660,7 +660,7 @@ struct edid *drm_get_edid(struct drm_connector *connector,
edid = (struct edid *)drm_ddc_read(adapter);
if (!edid) {
- dev_warn(&connector->dev->pdev->dev, "%s: no EDID data\n",
+ dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
drm_get_connector_name(connector));
return NULL;
}
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index b06a53715853..6c020fe5431c 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -457,6 +457,9 @@ int drm_release(struct inode *inode, struct file *filp)
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, file_priv);
+ if (dev->driver->driver_features & DRIVER_MODESET)
+ drm_fb_release(file_priv);
+
mutex_lock(&dev->ctxlist_mutex);
if (!list_empty(&dev->ctxlist)) {
struct drm_ctx_list *pos, *n;
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 9da581452874..88d3368ffddd 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -104,8 +104,8 @@ drm_gem_init(struct drm_device *dev)
if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
DRM_FILE_PAGE_OFFSET_SIZE)) {
- drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
drm_ht_remove(&mm->offset_hash);
+ drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
return -ENOMEM;
}
@@ -136,7 +136,7 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
obj->dev = dev;
- obj->filp = shmem_file_setup("drm mm object", size, 0);
+ obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
if (IS_ERR(obj->filp)) {
kfree(obj);
return NULL;
@@ -295,35 +295,37 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
return -EBADF;
again:
- if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
- return -ENOMEM;
+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) {
+ ret = -ENOMEM;
+ goto err;
+ }
spin_lock(&dev->object_name_lock);
- if (obj->name) {
- args->name = obj->name;
+ if (!obj->name) {
+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
+ &obj->name);
+ args->name = (uint64_t) obj->name;
spin_unlock(&dev->object_name_lock);
- return 0;
- }
- ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
- &obj->name);
- spin_unlock(&dev->object_name_lock);
- if (ret == -EAGAIN)
- goto again;
- if (ret != 0) {
- mutex_lock(&dev->struct_mutex);
- drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
+ if (ret == -EAGAIN)
+ goto again;
- /*
- * Leave the reference from the lookup around as the
- * name table now holds one
- */
- args->name = (uint64_t) obj->name;
+ if (ret != 0)
+ goto err;
- return 0;
+ /* Allocate a reference for the name table. */
+ drm_gem_object_reference(obj);
+ } else {
+ args->name = (uint64_t) obj->name;
+ spin_unlock(&dev->object_name_lock);
+ ret = 0;
+ }
+
+err:
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
}
/**
@@ -448,6 +450,7 @@ drm_gem_object_handle_free(struct kref *kref)
spin_lock(&dev->object_name_lock);
if (obj->name) {
idr_remove(&dev->object_name_idr, obj->name);
+ obj->name = 0;
spin_unlock(&dev->object_name_lock);
/*
* The object name held a reference to this object, drop
@@ -460,6 +463,26 @@ drm_gem_object_handle_free(struct kref *kref)
}
EXPORT_SYMBOL(drm_gem_object_handle_free);
+void drm_gem_vm_open(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+
+ drm_gem_object_reference(obj);
+}
+EXPORT_SYMBOL(drm_gem_vm_open);
+
+void drm_gem_vm_close(struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj = vma->vm_private_data;
+ struct drm_device *dev = obj->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+}
+EXPORT_SYMBOL(drm_gem_vm_close);
+
+
/**
* drm_gem_mmap - memory map routine for GEM objects
* @filp: DRM file pointer
@@ -521,6 +544,14 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
#endif
vma->vm_page_prot = __pgprot(prot);
+ /* Take a ref for this mapping of the object, so that the fault
+ * handler can dereference the mmap offset's pointer to the object.
+ * This reference is cleaned up by the corresponding vm_close
+ * (which should happen whether the vma was created by this call, or
+ * by a vm_open due to mremap or partial unmap or whatever).
+ */
+ drm_gem_object_reference(obj);
+
vma->vm_file = filp; /* Needed for drm_vm_open() */
drm_vm_open_locked(vma);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 477caa1b1e4b..93e677a481f5 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -106,8 +106,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
DRM_MEM_DRIVER);
- drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
- DRM_MEM_DRIVER);
drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
dev->num_crtcs, DRM_MEM_DRIVER);
drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
@@ -132,7 +130,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
(unsigned long)dev);
spin_lock_init(&dev->vbl_lock);
- atomic_set(&dev->vbl_signal_pending, 0);
dev->num_crtcs = num_crtcs;
dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
@@ -140,11 +137,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
if (!dev->vbl_queue)
goto err;
- dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
- DRM_MEM_DRIVER);
- if (!dev->vbl_sigs)
- goto err;
-
dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
DRM_MEM_DRIVER);
if (!dev->_vblank_count)
@@ -177,7 +169,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
/* Zero per-crtc vblank stuff */
for (i = 0; i < num_crtcs; i++) {
init_waitqueue_head(&dev->vbl_queue[i]);
- INIT_LIST_HEAD(&dev->vbl_sigs[i]);
atomic_set(&dev->_vblank_count[i], 0);
atomic_set(&dev->vblank_refcount[i], 0);
}
@@ -285,6 +276,7 @@ int drm_irq_uninstall(struct drm_device * dev)
for (i = 0; i < dev->num_crtcs; i++) {
DRM_WAKEUP(&dev->vbl_queue[i]);
dev->vblank_enabled[i] = 0;
+ dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -443,6 +435,8 @@ EXPORT_SYMBOL(drm_vblank_get);
*/
void drm_vblank_put(struct drm_device *dev, int crtc)
{
+ BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0);
+
/* Last user schedules interrupt disable */
if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
@@ -468,8 +462,9 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
* so that interrupts remain enabled in the interim.
*/
if (!dev->vblank_inmodeset[crtc]) {
- dev->vblank_inmodeset[crtc] = 1;
- drm_vblank_get(dev, crtc);
+ dev->vblank_inmodeset[crtc] = 0x1;
+ if (drm_vblank_get(dev, crtc) == 0)
+ dev->vblank_inmodeset[crtc] |= 0x2;
}
}
EXPORT_SYMBOL(drm_vblank_pre_modeset);
@@ -481,9 +476,12 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
if (dev->vblank_inmodeset[crtc]) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
dev->vblank_disable_allowed = 1;
- dev->vblank_inmodeset[crtc] = 0;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- drm_vblank_put(dev, crtc);
+
+ if (dev->vblank_inmodeset[crtc] & 0x2)
+ drm_vblank_put(dev, crtc);
+
+ dev->vblank_inmodeset[crtc] = 0;
}
}
EXPORT_SYMBOL(drm_vblank_post_modeset);
@@ -540,15 +538,10 @@ out:
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
*
- * Verifies the IRQ is installed.
- *
- * If a signal is requested checks if this task has already scheduled the same signal
- * for the same vblank sequence number - nothing to be done in
- * that case. If the number of tasks waiting for the interrupt exceeds 100 the
- * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
- * task.
- *
- * If a signal is not requested, then calls vblank_wait().
+ * This function enables the vblank interrupt on the pipe requested, then
+ * sleeps waiting for the requested sequence number to occur, and drops
+ * the vblank interrupt refcount afterwards. (vblank irq disable follows that
+ * after a timeout with no further vblank waits scheduled).
*/
int drm_wait_vblank(struct drm_device *dev, void *data,
struct drm_file *file_priv)
@@ -560,6 +553,9 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
if ((!dev->pdev->irq) || (!dev->irq_enabled))
return -EINVAL;
+ if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
+ return -EINVAL;
+
if (vblwait->request.type &
~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
@@ -597,89 +593,26 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
vblwait->request.sequence = seq + 1;
}
- if (flags & _DRM_VBLANK_SIGNAL) {
- unsigned long irqflags;
- struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
- struct drm_vbl_sig *vbl_sig;
-
- spin_lock_irqsave(&dev->vbl_lock, irqflags);
-
- /* Check if this task has already scheduled the same signal
- * for the same vblank sequence number; nothing to be done in
- * that case
- */
- list_for_each_entry(vbl_sig, vbl_sigs, head) {
- if (vbl_sig->sequence == vblwait->request.sequence
- && vbl_sig->info.si_signo ==
- vblwait->request.signal
- && vbl_sig->task == current) {
- spin_unlock_irqrestore(&dev->vbl_lock,
- irqflags);
- vblwait->reply.sequence = seq;
- goto done;
- }
- }
-
- if (atomic_read(&dev->vbl_signal_pending) >= 100) {
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- ret = -EBUSY;
- goto done;
- }
-
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
-
- vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
- DRM_MEM_DRIVER);
- if (!vbl_sig) {
- ret = -ENOMEM;
- goto done;
- }
-
- /* Get a refcount on the vblank, which will be released by
- * drm_vbl_send_signals().
- */
- ret = drm_vblank_get(dev, crtc);
- if (ret) {
- drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
- DRM_MEM_DRIVER);
- goto done;
- }
-
- atomic_inc(&dev->vbl_signal_pending);
-
- vbl_sig->sequence = vblwait->request.sequence;
- vbl_sig->info.si_signo = vblwait->request.signal;
- vbl_sig->task = current;
+ DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
+ vblwait->request.sequence, crtc);
+ dev->last_vblank_wait[crtc] = vblwait->request.sequence;
+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
+ (((drm_vblank_count(dev, crtc) -
+ vblwait->request.sequence) <= (1 << 23)) ||
+ !dev->irq_enabled));
- spin_lock_irqsave(&dev->vbl_lock, irqflags);
-
- list_add_tail(&vbl_sig->head, vbl_sigs);
+ if (ret != -EINTR) {
+ struct timeval now;
- spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ do_gettimeofday(&now);
- vblwait->reply.sequence = seq;
+ vblwait->reply.tval_sec = now.tv_sec;
+ vblwait->reply.tval_usec = now.tv_usec;
+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
+ DRM_DEBUG("returning %d to client\n",
+ vblwait->reply.sequence);
} else {
- DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
- vblwait->request.sequence, crtc);
- dev->last_vblank_wait[crtc] = vblwait->request.sequence;
- DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
- (((drm_vblank_count(dev, crtc) -
- vblwait->request.sequence) <= (1 << 23)) ||
- !dev->irq_enabled));
-
- if (ret != -EINTR) {
- struct timeval now;
-
- do_gettimeofday(&now);
-
- vblwait->reply.tval_sec = now.tv_sec;
- vblwait->reply.tval_usec = now.tv_usec;
- vblwait->reply.sequence = drm_vblank_count(dev, crtc);
- DRM_DEBUG("returning %d to client\n",
- vblwait->reply.sequence);
- } else {
- DRM_DEBUG("vblank wait interrupted by signal\n");
- }
+ DRM_DEBUG("vblank wait interrupted by signal\n");
}
done:
@@ -688,46 +621,6 @@ done:
}
/**
- * Send the VBLANK signals.
- *
- * \param dev DRM device.
- * \param crtc CRTC where the vblank event occurred
- *
- * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
- *
- * If a signal is not requested, then calls vblank_wait().
- */
-static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
-{
- struct drm_vbl_sig *vbl_sig, *tmp;
- struct list_head *vbl_sigs;
- unsigned int vbl_seq;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->vbl_lock, flags);
-
- vbl_sigs = &dev->vbl_sigs[crtc];
- vbl_seq = drm_vblank_count(dev, crtc);
-
- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
- vbl_sig->info.si_code = vbl_seq;
- send_sig_info(vbl_sig->info.si_signo,
- &vbl_sig->info, vbl_sig->task);
-
- list_del(&vbl_sig->head);
-
- drm_free(vbl_sig, sizeof(*vbl_sig),
- DRM_MEM_DRIVER);
- atomic_dec(&dev->vbl_signal_pending);
- drm_vblank_put(dev, crtc);
- }
- }
-
- spin_unlock_irqrestore(&dev->vbl_lock, flags);
-}
-
-/**
* drm_handle_vblank - handle a vblank event
* @dev: DRM device
* @crtc: where this event occurred
@@ -739,6 +632,5 @@ void drm_handle_vblank(struct drm_device *dev, int crtc)
{
atomic_inc(&dev->_vblank_count[crtc]);
DRM_WAKEUP(&dev->vbl_queue[crtc]);
- drm_vbl_send_signals(dev, crtc);
}
EXPORT_SYMBOL(drm_handle_vblank);
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index 803bc9e7ce3c..bcc869bc4092 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -171,9 +171,14 @@ EXPORT_SYMBOL(drm_core_ioremap);
void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev)
{
- map->handle = ioremap_wc(map->offset, map->size);
+ if (drm_core_has_AGP(dev) &&
+ dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
+ map->handle = agp_remap(map->offset, map->size, dev);
+ else
+ map->handle = ioremap_wc(map->offset, map->size);
}
EXPORT_SYMBOL(drm_core_ioremap_wc);
+
void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
{
if (!map->handle || !map->size)
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index 8df849f66830..b756f043a5f4 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -678,9 +678,9 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
*start = &buf[offset];
*eof = 0;
- DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+ DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%llx\n",
atomic_read(&dev->vma_count),
- high_memory, virt_to_phys(high_memory));
+ high_memory, (u64)virt_to_phys(high_memory));
list_for_each_entry(pt, &dev->vmalist, head) {
if (!(vma = pt->vma))
continue;
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 5ca132afa4f2..46bb923b097c 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -118,12 +118,20 @@ static void drm_master_destroy(struct kref *kref)
struct drm_master *master = container_of(kref, struct drm_master, refcount);
struct drm_magic_entry *pt, *next;
struct drm_device *dev = master->minor->dev;
+ struct drm_map_list *r_list, *list_temp;
list_del(&master->head);
if (dev->driver->master_destroy)
dev->driver->master_destroy(dev, master);
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
+ if (r_list->master == master) {
+ drm_rmmap_locked(dev, r_list->map);
+ r_list = NULL;
+ }
+ }
+
if (master->unique) {
drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER);
master->unique = NULL;
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 5aa6780652aa..186d08159d48 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -359,8 +359,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
DRM_DEBUG("adding \"%s\" to sysfs\n",
drm_get_connector_name(connector));
- snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
- dev->primary->index, drm_get_connector_name(connector));
+ dev_set_name(&connector->kdev, "card%d-%s",
+ dev->primary->index, drm_get_connector_name(connector));
ret = device_register(&connector->kdev);
if (ret) {
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index bbadf1c04142..cc4649577a61 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -202,7 +202,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->ring.map.flags = 0;
dev_priv->ring.map.mtrr = 0;
- drm_core_ioremap(&dev_priv->ring.map, dev);
+ drm_core_ioremap_wc(&dev_priv->ring.map, dev);
if (dev_priv->ring.map.handle == NULL) {
i915_dma_cleanup(dev);
@@ -731,8 +731,11 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_GEM:
value = dev_priv->has_gem;
break;
+ case I915_PARAM_NUM_FENCES_AVAIL:
+ value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
+ break;
default:
- DRM_ERROR("Unknown parameter %d\n", param->param);
+ DRM_DEBUG("Unknown parameter %d\n", param->param);
return -EINVAL;
}
@@ -764,8 +767,15 @@ static int i915_setparam(struct drm_device *dev, void *data,
case I915_SETPARAM_ALLOW_BATCHBUFFER:
dev_priv->allow_batchbuffer = param->value;
break;
+ case I915_SETPARAM_NUM_USED_FENCES:
+ if (param->value > dev_priv->num_fence_regs ||
+ param->value < 0)
+ return -EINVAL;
+ /* Userspace can use first N regs */
+ dev_priv->fence_reg_start = param->value;
+ break;
default:
- DRM_ERROR("unknown parameter %d\n", param->param);
+ DRM_DEBUG("unknown parameter %d\n", param->param);
return -EINVAL;
}
@@ -801,7 +811,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
dev_priv->hws_map.flags = 0;
dev_priv->hws_map.mtrr = 0;
- drm_core_ioremap(&dev_priv->hws_map, dev);
+ drm_core_ioremap_wc(&dev_priv->hws_map, dev);
if (dev_priv->hws_map.handle == NULL) {
i915_dma_cleanup(dev);
dev_priv->status_gfx_addr = 0;
@@ -944,13 +954,14 @@ static int i915_load_modeset_init(struct drm_device *dev)
dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
0xff000000;
- DRM_DEBUG("*** fb base 0x%08lx\n", dev->mode_config.fb_base);
-
- if (IS_MOBILE(dev) || (IS_I9XX(dev) && !IS_I965G(dev) && !IS_G33(dev)))
+ if (IS_MOBILE(dev) || IS_I9XX(dev))
dev_priv->cursor_needs_physical = true;
else
dev_priv->cursor_needs_physical = false;
+ if (IS_I965G(dev) || IS_G33(dev))
+ dev_priv->cursor_needs_physical = false;
+
ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
if (ret)
goto kfree_devname;
@@ -965,10 +976,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto kfree_devname;
- dev_priv->mm.gtt_mapping =
- io_mapping_create_wc(dev->agp->base,
- dev->agp->agp_info.aper_size * 1024*1024);
-
/* Allow hardware batchbuffers unless told otherwise.
*/
dev_priv->allow_batchbuffer = 1;
@@ -1080,6 +1087,23 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto free_priv;
}
+ dev_priv->mm.gtt_mapping =
+ io_mapping_create_wc(dev->agp->base,
+ dev->agp->agp_info.aper_size * 1024*1024);
+ /* Set up a WC MTRR for non-PAT systems. This is more common than
+ * one would think, because the kernel disables PAT on first
+ * generation Core chips because WC PAT gets overridden by a UC
+ * MTRR if present. Even if a UC MTRR isn't present.
+ */
+ dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base,
+ dev->agp->agp_info.aper_size *
+ 1024 * 1024,
+ MTRR_TYPE_WRCOMB, 1);
+ if (dev_priv->mm.gtt_mtrr < 0) {
+ DRM_INFO("MTRR allocation failed\n. Graphics "
+ "performance may suffer.\n");
+ }
+
#ifdef CONFIG_HIGHMEM64G
/* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
dev_priv->has_gem = 0;
@@ -1088,6 +1112,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->has_gem = 1;
#endif
+ dev->driver->get_vblank_counter = i915_get_vblank_counter;
+ if (IS_GM45(dev))
+ dev->driver->get_vblank_counter = gm45_get_vblank_counter;
+
i915_gem_load(dev);
/* Init HWS */
@@ -1144,8 +1172,14 @@ int i915_driver_unload(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ io_mapping_free(dev_priv->mm.gtt_mapping);
+ if (dev_priv->mm.gtt_mtrr >= 0) {
+ mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base,
+ dev->agp->agp_info.aper_size * 1024 * 1024);
+ dev_priv->mm.gtt_mtrr = -1;
+ }
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- io_mapping_free(dev_priv->mm.gtt_mapping);
drm_irq_uninstall(dev);
}
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index f8b3df0926c0..b293ef0bae71 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -27,6 +27,7 @@
*
*/
+#include <linux/device.h>
#include "drmP.h"
#include "drm.h"
#include "i915_drm.h"
@@ -66,6 +67,14 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
i915_save_state(dev);
+ /* If KMS is active, we do the leavevt stuff here */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ if (i915_gem_idle(dev))
+ dev_err(&dev->pdev->dev,
+ "GEM idle failed, resume may fail\n");
+ drm_irq_uninstall(dev);
+ }
+
intel_opregion_free(dev);
if (state.event == PM_EVENT_SUSPEND) {
@@ -79,6 +88,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
static int i915_resume(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret = 0;
+
pci_set_power_state(dev->pdev, PCI_D0);
pci_restore_state(dev->pdev);
if (pci_enable_device(dev->pdev))
@@ -89,11 +101,26 @@ static int i915_resume(struct drm_device *dev)
intel_opregion_init(dev);
- return 0;
+ /* KMS EnterVT equivalent */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ mutex_lock(&dev->struct_mutex);
+ dev_priv->mm.suspended = 0;
+
+ ret = i915_gem_init_ringbuffer(dev);
+ if (ret != 0)
+ ret = -1;
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_irq_install(dev);
+ }
+
+ return ret;
}
static struct vm_operations_struct i915_gem_vm_ops = {
.fault = i915_gem_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
};
static struct drm_driver driver = {
@@ -112,7 +139,6 @@ static struct drm_driver driver = {
.suspend = i915_suspend,
.resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
- .get_vblank_counter = i915_get_vblank_counter,
.enable_vblank = i915_enable_vblank,
.disable_vblank = i915_disable_vblank,
.irq_preinstall = i915_driver_irq_preinstall,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e13518252007..17fa40858d26 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -184,6 +184,8 @@ typedef struct drm_i915_private {
unsigned int lvds_dither:1;
unsigned int lvds_vbt:1;
unsigned int int_crt_support:1;
+ unsigned int lvds_use_ssc:1;
+ int lvds_ssc_freq;
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
@@ -284,6 +286,7 @@ typedef struct drm_i915_private {
struct drm_mm gtt_space;
struct io_mapping *gtt_mapping;
+ int gtt_mtrr;
/**
* List of objects currently involved in rendering from the
@@ -534,6 +537,7 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
extern int i915_enable_vblank(struct drm_device *dev, int crtc);
extern void i915_disable_vblank(struct drm_device *dev, int crtc);
extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
+extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
@@ -601,6 +605,7 @@ int i915_gem_init_object(struct drm_gem_object *obj);
void i915_gem_free_object(struct drm_gem_object *obj);
int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
void i915_gem_object_unpin(struct drm_gem_object *obj);
+int i915_gem_object_unbind(struct drm_gem_object *obj);
void i915_gem_lastclose(struct drm_device *dev);
uint32_t i915_get_gem_seqno(struct drm_device *dev);
void i915_gem_retire_requests(struct drm_device *dev);
@@ -613,6 +618,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
int i915_gem_do_init(struct drm_device *dev, unsigned long start,
unsigned long end);
+int i915_gem_idle(struct drm_device *dev);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
int write);
@@ -784,6 +790,11 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
+/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
+ * rows, which changed the alignment requirements and fence programming.
+ */
+#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
+ IS_I915GM(dev)))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 96316fd47233..85685bfd12da 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -34,10 +34,6 @@
#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
-static void
-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain);
static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -52,7 +48,7 @@ static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
unsigned alignment);
-static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
+static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write);
static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
static int i915_gem_evict_something(struct drm_device *dev);
static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
@@ -567,6 +563,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
pgoff_t page_offset;
unsigned long pfn;
int ret = 0;
+ bool write = !!(vmf->flags & FAULT_FLAG_WRITE);
/* We don't use vmf->pgoff since that has the fake offset */
page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >>
@@ -585,8 +582,13 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
/* Need a new fence register? */
if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
- obj_priv->tiling_mode != I915_TILING_NONE)
- i915_gem_object_get_fence_reg(obj);
+ obj_priv->tiling_mode != I915_TILING_NONE) {
+ ret = i915_gem_object_get_fence_reg(obj, write);
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return VM_FAULT_SIGBUS;
+ }
+ }
pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
page_offset;
@@ -601,8 +603,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case -EAGAIN:
return VM_FAULT_OOM;
case -EFAULT:
- case -EBUSY:
- DRM_ERROR("can't insert pfn?? fault or busy...\n");
return VM_FAULT_SIGBUS;
default:
return VM_FAULT_NOPAGE;
@@ -678,6 +678,30 @@ out_free_list:
return ret;
}
+static void
+i915_gem_free_mmap_offset(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_map_list *list;
+
+ list = &obj->map_list;
+ drm_ht_remove_item(&mm->offset_hash, &list->hash);
+
+ if (list->file_offset_node) {
+ drm_mm_put_block(list->file_offset_node);
+ list->file_offset_node = NULL;
+ }
+
+ if (list->map) {
+ drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER);
+ list->map = NULL;
+ }
+
+ obj_priv->mmap_offset = 0;
+}
+
/**
* i915_gem_get_gtt_alignment - return required GTT alignment for an object
* @obj: object to check
@@ -752,8 +776,11 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
if (!obj_priv->mmap_offset) {
ret = i915_gem_create_mmap_offset(obj);
- if (ret)
+ if (ret) {
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return ret;
+ }
}
args->offset = obj_priv->mmap_offset;
@@ -1024,6 +1051,9 @@ i915_gem_retire_requests(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t seqno;
+ if (!dev_priv->hw_status_page)
+ return;
+
seqno = i915_get_gem_seqno(dev);
while (!list_empty(&dev_priv->mm.request_list)) {
@@ -1211,7 +1241,7 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj)
/**
* Unbinds an object from the GTT aperture.
*/
-static int
+int
i915_gem_object_unbind(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
@@ -1445,21 +1475,26 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
int regnum = obj_priv->fence_reg;
+ int tile_width;
uint32_t val;
uint32_t pitch_val;
if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
(obj_priv->gtt_offset & (obj->size - 1))) {
- WARN(1, "%s: object not 1M or size aligned\n", __func__);
+ WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n",
+ __func__, obj_priv->gtt_offset, obj->size);
return;
}
- if (obj_priv->tiling_mode == I915_TILING_Y && (IS_I945G(dev) ||
- IS_I945GM(dev) ||
- IS_G33(dev)))
- pitch_val = (obj_priv->stride / 128) - 1;
+ if (obj_priv->tiling_mode == I915_TILING_Y &&
+ HAS_128_BYTE_Y_TILING(dev))
+ tile_width = 128;
else
- pitch_val = (obj_priv->stride / 512) - 1;
+ tile_width = 512;
+
+ /* Note: pitch better be a power of two tile widths */
+ pitch_val = obj_priv->stride / tile_width;
+ pitch_val = ffs(pitch_val) - 1;
val = obj_priv->gtt_offset;
if (obj_priv->tiling_mode == I915_TILING_Y)
@@ -1483,7 +1518,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
(obj_priv->gtt_offset & (obj->size - 1))) {
- WARN(1, "%s: object not 1M or size aligned\n", __func__);
+ WARN(1, "%s: object 0x%08x not 1M or size aligned\n",
+ __func__, obj_priv->gtt_offset);
return;
}
@@ -1503,6 +1539,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
/**
* i915_gem_object_get_fence_reg - set up a fence reg for an object
* @obj: object to map through a fence reg
+ * @write: object is about to be written
*
* When mapping objects through the GTT, userspace wants to be able to write
* to them without having to worry about swizzling if the object is tiled.
@@ -1513,8 +1550,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
* It then sets up the reg based on the object's properties: address, pitch
* and tiling format.
*/
-static void
-i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
+static int
+i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write)
{
struct drm_device *dev = obj->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1527,12 +1564,18 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
WARN(1, "allocating a fence for non-tiled object?\n");
break;
case I915_TILING_X:
- WARN(obj_priv->stride & (512 - 1),
- "object is X tiled but has non-512B pitch\n");
+ if (!obj_priv->stride)
+ return -EINVAL;
+ WARN((obj_priv->stride & (512 - 1)),
+ "object 0x%08x is X tiled but has non-512B pitch\n",
+ obj_priv->gtt_offset);
break;
case I915_TILING_Y:
- WARN(obj_priv->stride & (128 - 1),
- "object is Y tiled but has non-128B pitch\n");
+ if (!obj_priv->stride)
+ return -EINVAL;
+ WARN((obj_priv->stride & (128 - 1)),
+ "object 0x%08x is Y tiled but has non-128B pitch\n",
+ obj_priv->gtt_offset);
break;
}
@@ -1563,10 +1606,11 @@ try_again:
* objects to finish before trying again.
*/
if (i == dev_priv->num_fence_regs) {
- ret = i915_gem_object_wait_rendering(reg->obj);
+ ret = i915_gem_object_set_to_gtt_domain(reg->obj, 0);
if (ret) {
- WARN(ret, "wait_rendering failed: %d\n", ret);
- return;
+ WARN(ret != -ERESTARTSYS,
+ "switch to GTT domain failed: %d\n", ret);
+ return ret;
}
goto try_again;
}
@@ -1591,6 +1635,8 @@ try_again:
i915_write_fence_reg(reg);
else
i830_write_fence_reg(reg);
+
+ return 0;
}
/**
@@ -1631,7 +1677,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
if (dev_priv->mm.suspended)
return -EBUSY;
if (alignment == 0)
- alignment = PAGE_SIZE;
+ alignment = i915_gem_get_gtt_alignment(obj);
if (alignment & (PAGE_SIZE - 1)) {
DRM_ERROR("Invalid object alignment requested %u\n", alignment);
return -EINVAL;
@@ -1974,30 +2020,28 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
* drm_agp_chipset_flush
*/
static void
-i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
- uint32_t read_domains,
- uint32_t write_domain)
+i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
uint32_t invalidate_domains = 0;
uint32_t flush_domains = 0;
- BUG_ON(read_domains & I915_GEM_DOMAIN_CPU);
- BUG_ON(write_domain == I915_GEM_DOMAIN_CPU);
+ BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
+ BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
#if WATCH_BUF
DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
__func__, obj,
- obj->read_domains, read_domains,
- obj->write_domain, write_domain);
+ obj->read_domains, obj->pending_read_domains,
+ obj->write_domain, obj->pending_write_domain);
#endif
/*
* If the object isn't moving to a new write domain,
* let the object stay in multiple read domains
*/
- if (write_domain == 0)
- read_domains |= obj->read_domains;
+ if (obj->pending_write_domain == 0)
+ obj->pending_read_domains |= obj->read_domains;
else
obj_priv->dirty = 1;
@@ -2007,15 +2051,17 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
* any read domains which differ from the old
* write domain
*/
- if (obj->write_domain && obj->write_domain != read_domains) {
+ if (obj->write_domain &&
+ obj->write_domain != obj->pending_read_domains) {
flush_domains |= obj->write_domain;
- invalidate_domains |= read_domains & ~obj->write_domain;
+ invalidate_domains |=
+ obj->pending_read_domains & ~obj->write_domain;
}
/*
* Invalidate any read caches which may have
* stale data. That is, any new read domains.
*/
- invalidate_domains |= read_domains & ~obj->read_domains;
+ invalidate_domains |= obj->pending_read_domains & ~obj->read_domains;
if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
#if WATCH_BUF
DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
@@ -2024,9 +2070,15 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
i915_gem_clflush_object(obj);
}
- if ((write_domain | flush_domains) != 0)
- obj->write_domain = write_domain;
- obj->read_domains = read_domains;
+ /* The actual obj->write_domain will be updated with
+ * pending_write_domain after we emit the accumulated flush for all
+ * of our domain changes in execbuffers (which clears objects'
+ * write_domains). So if we have a current write domain that we
+ * aren't changing, set pending_write_domain to that.
+ */
+ if (flush_domains == 0 && obj->pending_write_domain == 0)
+ obj->pending_write_domain = obj->write_domain;
+ obj->read_domains = obj->pending_read_domains;
dev->invalidate_domains |= invalidate_domains;
dev->flush_domains |= flush_domains;
@@ -2229,6 +2281,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
(int) reloc.offset,
reloc.read_domains,
reloc.write_domain);
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
return -EINVAL;
}
@@ -2458,13 +2512,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
if (dev_priv->mm.wedged) {
DRM_ERROR("Execbuf while wedged\n");
mutex_unlock(&dev->struct_mutex);
- return -EIO;
+ ret = -EIO;
+ goto pre_mutex_err;
}
if (dev_priv->mm.suspended) {
DRM_ERROR("Execbuf while VT-switched.\n");
mutex_unlock(&dev->struct_mutex);
- return -EBUSY;
+ ret = -EBUSY;
+ goto pre_mutex_err;
}
/* Look up object handles */
@@ -2532,9 +2588,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_gem_object *obj = object_list[i];
/* Compute new gpu domains and update invalidate/flush */
- i915_gem_object_set_to_gpu_domain(obj,
- obj->pending_read_domains,
- obj->pending_write_domain);
+ i915_gem_object_set_to_gpu_domain(obj);
}
i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -2553,6 +2607,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
(void)i915_add_request(dev, dev->flush_domains);
}
+ for (i = 0; i < args->buffer_count; i++) {
+ struct drm_gem_object *obj = object_list[i];
+
+ obj->write_domain = obj->pending_write_domain;
+ }
+
i915_verify_inactive(dev, __FILE__, __LINE__);
#if WATCH_COHERENCY
@@ -2610,15 +2670,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
i915_verify_inactive(dev, __FILE__, __LINE__);
- /* Copy the new buffer offsets back to the user's exec list. */
- ret = copy_to_user((struct drm_i915_relocation_entry __user *)
- (uintptr_t) args->buffers_ptr,
- exec_list,
- sizeof(*exec_list) * args->buffer_count);
- if (ret)
- DRM_ERROR("failed to copy %d exec entries "
- "back to user (%d)\n",
- args->buffer_count, ret);
err:
for (i = 0; i < pinned; i++)
i915_gem_object_unpin(object_list[i]);
@@ -2628,6 +2679,18 @@ err:
mutex_unlock(&dev->struct_mutex);
+ if (!ret) {
+ /* Copy the new buffer offsets back to the user's exec list. */
+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
+ (uintptr_t) args->buffers_ptr,
+ exec_list,
+ sizeof(*exec_list) * args->buffer_count);
+ if (ret)
+ DRM_ERROR("failed to copy %d exec entries "
+ "back to user (%d)\n",
+ args->buffer_count, ret);
+ }
+
pre_mutex_err:
drm_free(object_list, sizeof(*object_list) * args->buffer_count,
DRM_MEM_DRIVER);
@@ -2652,6 +2715,14 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
DRM_ERROR("Failure to bind: %d", ret);
return ret;
}
+ /*
+ * Pre-965 chips need a fence register set up in order to
+ * properly handle tiled surfaces.
+ */
+ if (!IS_I965G(dev) &&
+ obj_priv->fence_reg == I915_FENCE_REG_NONE &&
+ obj_priv->tiling_mode != I915_TILING_NONE)
+ i915_gem_object_get_fence_reg(obj, true);
}
obj_priv->pin_count++;
@@ -2723,6 +2794,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) {
DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
args->handle);
+ drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
@@ -2803,6 +2875,13 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
return -EBADF;
}
+ /* Update the active list for the hardware's current position.
+ * Otherwise this only updates on a delayed timer or when irqs are
+ * actually unmasked, and our working set ends up being larger than
+ * required.
+ */
+ i915_gem_retire_requests(dev);
+
obj_priv = obj->driver_private;
/* Don't count being on the flushing list against the object being
* done. Otherwise, a buffer left on the flushing list but not getting
@@ -2855,9 +2934,6 @@ int i915_gem_init_object(struct drm_gem_object *obj)
void i915_gem_free_object(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_map *map;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
while (obj_priv->pin_count > 0)
@@ -2868,19 +2944,7 @@ void i915_gem_free_object(struct drm_gem_object *obj)
i915_gem_object_unbind(obj);
- list = &obj->map_list;
- drm_ht_remove_item(&mm->offset_hash, &list->hash);
-
- if (list->file_offset_node) {
- drm_mm_put_block(list->file_offset_node);
- list->file_offset_node = NULL;
- }
-
- map = list->map;
- if (map) {
- drm_free(map, sizeof(*map), DRM_MEM_DRIVER);
- list->map = NULL;
- }
+ i915_gem_free_mmap_offset(obj);
drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
@@ -2919,7 +2983,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
return 0;
}
-static int
+int
i915_gem_idle(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -3065,6 +3129,7 @@ i915_gem_init_hws(struct drm_device *dev)
if (dev_priv->hw_status_page == NULL) {
DRM_ERROR("Failed to map status page.\n");
memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+ i915_gem_object_unpin(obj);
drm_gem_object_unreference(obj);
return -EINVAL;
}
@@ -3077,6 +3142,31 @@ i915_gem_init_hws(struct drm_device *dev)
return 0;
}
+static void
+i915_gem_cleanup_hws(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ if (dev_priv->hws_obj == NULL)
+ return;
+
+ obj = dev_priv->hws_obj;
+ obj_priv = obj->driver_private;
+
+ kunmap(obj_priv->page_list[0]);
+ i915_gem_object_unpin(obj);
+ drm_gem_object_unreference(obj);
+ dev_priv->hws_obj = NULL;
+
+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+ dev_priv->hw_status_page = NULL;
+
+ /* Write high address into HWS_PGA when disabling. */
+ I915_WRITE(HWS_PGA, 0x1ffff000);
+}
+
int
i915_gem_init_ringbuffer(struct drm_device *dev)
{
@@ -3094,6 +3184,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
obj = drm_gem_object_alloc(dev, 128 * 1024);
if (obj == NULL) {
DRM_ERROR("Failed to allocate ringbuffer\n");
+ i915_gem_cleanup_hws(dev);
return -ENOMEM;
}
obj_priv = obj->driver_private;
@@ -3101,6 +3192,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
ret = i915_gem_object_pin(obj, 4096);
if (ret != 0) {
drm_gem_object_unreference(obj);
+ i915_gem_cleanup_hws(dev);
return ret;
}
@@ -3118,7 +3210,9 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
if (ring->map.handle == NULL) {
DRM_ERROR("Failed to map ringbuffer.\n");
memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
+ i915_gem_object_unpin(obj);
drm_gem_object_unreference(obj);
+ i915_gem_cleanup_hws(dev);
return -EINVAL;
}
ring->ring_obj = obj;
@@ -3198,20 +3292,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
dev_priv->ring.ring_obj = NULL;
memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
- if (dev_priv->hws_obj != NULL) {
- struct drm_gem_object *obj = dev_priv->hws_obj;
- struct drm_i915_gem_object *obj_priv = obj->driver_private;
-
- kunmap(obj_priv->page_list[0]);
- i915_gem_object_unpin(obj);
- drm_gem_object_unreference(obj);
- dev_priv->hws_obj = NULL;
- memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
- dev_priv->hw_status_page = NULL;
-
- /* Write high address into HWS_PGA when disabling. */
- I915_WRITE(HWS_PGA, 0x1ffff000);
- }
+ i915_gem_cleanup_hws(dev);
}
int
@@ -3229,10 +3310,6 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
dev_priv->mm.wedged = 0;
}
- dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base,
- dev->agp->agp_info.aper_size
- * 1024 * 1024);
-
mutex_lock(&dev->struct_mutex);
dev_priv->mm.suspended = 0;
@@ -3255,7 +3332,6 @@ int
i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
if (drm_core_check_feature(dev, DRIVER_MODESET))
@@ -3264,7 +3340,6 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
ret = i915_gem_idle(dev);
drm_irq_uninstall(dev);
- io_mapping_free(dev_priv->mm.gtt_mapping);
return ret;
}
@@ -3273,6 +3348,9 @@ i915_gem_lastclose(struct drm_device *dev)
{
int ret;
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
ret = i915_gem_idle(dev);
if (ret)
DRM_ERROR("failed to idle hardware: %d\n", ret);
@@ -3294,7 +3372,7 @@ i915_gem_load(struct drm_device *dev)
/* Old X drivers will take 0-2 for front, back, depth buffers */
dev_priv->fence_reg_start = 3;
- if (IS_I965G(dev))
+ if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
dev_priv->num_fence_regs = 16;
else
dev_priv->num_fence_regs = 8;
@@ -3364,7 +3442,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev)
{
int i;
- for (i = 0; i < I915_MAX_PHYS_OBJECT; i++)
+ for (i = I915_GEM_PHYS_CURSOR_0; i <= I915_MAX_PHYS_OBJECT; i++)
i915_gem_free_phys_object(dev, i);
}
@@ -3427,7 +3505,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
ret = i915_gem_init_phys_object(dev, id,
obj->size);
if (ret) {
- DRM_ERROR("failed to init phys object %d size: %d\n", id, obj->size);
+ DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size);
goto out;
}
}
@@ -3470,7 +3548,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
user_data = (char __user *) (uintptr_t) args->data_ptr;
obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
- DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size);
+ DRM_DEBUG("obj_addr %p, %lld\n", obj_addr, args->size);
ret = copy_from_user(obj_addr, user_data, args->size);
if (ret)
return -EFAULT;
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 241f39b7f460..7fb4191ef934 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -173,6 +173,73 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
dev_priv->mm.bit_6_swizzle_y = swizzle_y;
}
+
+/**
+ * Returns the size of the fence for a tiled object of the given size.
+ */
+static int
+i915_get_fence_size(struct drm_device *dev, int size)
+{
+ int i;
+ int start;
+
+ if (IS_I965G(dev)) {
+ /* The 965 can have fences at any page boundary. */
+ return ALIGN(size, 4096);
+ } else {
+ /* Align the size to a power of two greater than the smallest
+ * fence size.
+ */
+ if (IS_I9XX(dev))
+ start = 1024 * 1024;
+ else
+ start = 512 * 1024;
+
+ for (i = start; i < size; i <<= 1)
+ ;
+
+ return i;
+ }
+}
+
+/* Check pitch constriants for all chips & tiling formats */
+static bool
+i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
+{
+ int tile_width;
+
+ /* Linear is always fine */
+ if (tiling_mode == I915_TILING_NONE)
+ return true;
+
+ if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
+ tile_width = 128;
+ else
+ tile_width = 512;
+
+ /* 965+ just needs multiples of tile width */
+ if (IS_I965G(dev)) {
+ if (stride & (tile_width - 1))
+ return false;
+ return true;
+ }
+
+ /* Pre-965 needs power of two tile widths */
+ if (stride < tile_width)
+ return false;
+
+ if (stride & (stride - 1))
+ return false;
+
+ /* We don't handle the aperture area covered by the fence being bigger
+ * than the object size.
+ */
+ if (i915_get_fence_size(dev, size) != size)
+ return false;
+
+ return true;
+}
+
/**
* Sets the tiling mode of an object, returning the required swizzling of
* bit 6 of addresses in the object.
@@ -191,6 +258,11 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
return -EINVAL;
obj_priv = obj->driver_private;
+ if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
+ drm_gem_object_unreference(obj);
+ return -EINVAL;
+ }
+
mutex_lock(&dev->struct_mutex);
if (args->tiling_mode == I915_TILING_NONE) {
@@ -207,12 +279,28 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
}
}
- obj_priv->tiling_mode = args->tiling_mode;
- obj_priv->stride = args->stride;
+ if (args->tiling_mode != obj_priv->tiling_mode) {
+ int ret;
- mutex_unlock(&dev->struct_mutex);
+ /* Unbind the object, as switching tiling means we're
+ * switching the cache organization due to fencing, probably.
+ */
+ ret = i915_gem_object_unbind(obj);
+ if (ret != 0) {
+ WARN(ret != -ERESTARTSYS,
+ "failed to unbind object for tiling switch");
+ args->tiling_mode = obj_priv->tiling_mode;
+ mutex_unlock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+
+ return ret;
+ }
+ obj_priv->tiling_mode = args->tiling_mode;
+ }
+ obj_priv->stride = args->stride;
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
@@ -251,9 +339,8 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
DRM_ERROR("unknown tiling mode\n");
}
- mutex_unlock(&dev->struct_mutex);
-
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 6290219de6c8..548ff2c66431 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -174,6 +174,19 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
return count;
}
+u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
+
+ if (!i915_pipe_enabled(dev, pipe)) {
+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+ return 0;
+ }
+
+ return I915_READ(reg);
+}
+
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 273162579e1b..9d6539a868b3 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -186,12 +186,12 @@
#define FENCE_REG_830_0 0x2000
#define I830_FENCE_START_MASK 0x07f80000
#define I830_FENCE_TILING_Y_SHIFT 12
-#define I830_FENCE_SIZE_BITS(size) ((get_order(size >> 19) - 1) << 8)
+#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
#define I830_FENCE_PITCH_SHIFT 4
#define I830_FENCE_REG_VALID (1<<0)
#define I915_FENCE_START_MASK 0x0ff00000
-#define I915_FENCE_SIZE_BITS(size) ((get_order(size >> 20) - 1) << 8)
+#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8)
#define FENCE_REG_965_0 0x03000
#define I965_FENCE_PITCH_SHIFT 2
@@ -1371,6 +1371,9 @@
#define PIPE_FRAME_LOW_SHIFT 24
#define PIPE_PIXEL_MASK 0x00ffffff
#define PIPE_PIXEL_SHIFT 0
+/* GM45+ just has to be different */
+#define PIPEA_FRMCOUNT_GM45 0x70040
+#define PIPEA_FLIPCOUNT_GM45 0x70044
/* Cursor A & B regs */
#define CURACNTR 0x70080
@@ -1439,6 +1442,9 @@
#define PIPEBSTAT 0x71024
#define PIPEBFRAMEHIGH 0x71040
#define PIPEBFRAMEPIXEL 0x71044
+#define PIPEB_FRMCOUNT_GM45 0x71040
+#define PIPEB_FLIPCOUNT_GM45 0x71044
+
/* Display B control */
#define DSPBCNTR 0x71180
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4ca82a025525..fc28e2bbd542 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -111,6 +111,12 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
panel_fixed_mode->clock = dvo_timing->clock * 10;
panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+ /* Some VBTs have bogus h/vtotal values */
+ if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
+ panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
+ if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
+ panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+
drm_mode_set_name(panel_fixed_mode);
dev_priv->vbt_mode = panel_fixed_mode;
@@ -135,6 +141,14 @@ parse_general_features(struct drm_i915_private *dev_priv,
if (general) {
dev_priv->int_tv_support = general->int_tv_support;
dev_priv->int_crt_support = general->int_crt_support;
+ dev_priv->lvds_use_ssc = general->enable_ssc;
+
+ if (dev_priv->lvds_use_ssc) {
+ if (IS_I855(dev_priv->dev))
+ dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48;
+ else
+ dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96;
+ }
}
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 31c3732b7a69..a2834276cb38 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -90,12 +90,12 @@ typedef struct {
#define I9XX_DOT_MAX 400000
#define I9XX_VCO_MIN 1400000
#define I9XX_VCO_MAX 2800000
-#define I9XX_N_MIN 3
-#define I9XX_N_MAX 8
+#define I9XX_N_MIN 1
+#define I9XX_N_MAX 6
#define I9XX_M_MIN 70
#define I9XX_M_MAX 120
#define I9XX_M1_MIN 10
-#define I9XX_M1_MAX 20
+#define I9XX_M1_MAX 22
#define I9XX_M2_MIN 5
#define I9XX_M2_MAX 9
#define I9XX_P_SDVO_DAC_MIN 5
@@ -189,9 +189,7 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
return limit;
}
-/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
-
-static void i8xx_clock(int refclk, intel_clock_t *clock)
+static void intel_clock(int refclk, intel_clock_t *clock)
{
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
clock->p = clock->p1 * clock->p2;
@@ -199,25 +197,6 @@ static void i8xx_clock(int refclk, intel_clock_t *clock)
clock->dot = clock->vco / clock->p;
}
-/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
-
-static void i9xx_clock(int refclk, intel_clock_t *clock)
-{
- clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
- clock->p = clock->p1 * clock->p2;
- clock->vco = refclk * clock->m / (clock->n + 2);
- clock->dot = clock->vco / clock->p;
-}
-
-static void intel_clock(struct drm_device *dev, int refclk,
- intel_clock_t *clock)
-{
- if (IS_I9XX(dev))
- i9xx_clock (refclk, clock);
- else
- i8xx_clock (refclk, clock);
-}
-
/**
* Returns whether any output on the specified pipe is of the specified type
*/
@@ -238,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
return false;
}
-#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
+#define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0)
/**
* Returns whether the given set of divisors are valid for a given refclk with
* the given connectors.
@@ -318,7 +297,7 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
clock.p1 <= limit->p1.max; clock.p1++) {
int this_err;
- intel_clock(dev, refclk, &clock);
+ intel_clock(refclk, &clock);
if (!intel_PLL_is_valid(crtc, &clock))
continue;
@@ -343,7 +322,7 @@ intel_wait_for_vblank(struct drm_device *dev)
udelay(20000);
}
-static void
+static int
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
@@ -361,11 +340,21 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
u32 dspcntr, alignment;
+ int ret;
/* no fb bound */
if (!crtc->fb) {
DRM_DEBUG("No FB bound\n");
- return;
+ return 0;
+ }
+
+ switch (pipe) {
+ case 0:
+ case 1:
+ break;
+ default:
+ DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
+ return -EINVAL;
}
intel_fb = to_intel_framebuffer(crtc->fb);
@@ -377,28 +366,30 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
alignment = 64 * 1024;
break;
case I915_TILING_X:
- if (IS_I9XX(dev))
- alignment = 1024 * 1024;
- else
- alignment = 512 * 1024;
+ /* pin() will align the object as required by fence */
+ alignment = 0;
break;
case I915_TILING_Y:
/* FIXME: Is this true? */
DRM_ERROR("Y tiled not allowed for scan out buffers\n");
- return;
+ return -EINVAL;
default:
BUG();
}
- if (i915_gem_object_pin(intel_fb->obj, alignment))
- return;
-
- i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
-
- Start = obj_priv->gtt_offset;
- Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_object_pin(intel_fb->obj, alignment);
+ if (ret != 0) {
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
- I915_WRITE(dspstride, crtc->fb->pitch);
+ ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
+ if (ret != 0) {
+ i915_gem_object_unpin(intel_fb->obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
dspcntr = I915_READ(dspcntr_reg);
/* Mask out pixel format bits in case we change it */
@@ -419,11 +410,17 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
break;
default:
DRM_ERROR("Unknown color depth\n");
- return;
+ i915_gem_object_unpin(intel_fb->obj);
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
}
I915_WRITE(dspcntr_reg, dspcntr);
+ Start = obj_priv->gtt_offset;
+ Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+
DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+ I915_WRITE(dspstride, crtc->fb->pitch);
if (IS_I965G(dev)) {
I915_WRITE(dspbase, Offset);
I915_READ(dspbase);
@@ -440,27 +437,24 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
intel_fb = to_intel_framebuffer(old_fb);
i915_gem_object_unpin(intel_fb->obj);
}
+ mutex_unlock(&dev->struct_mutex);
if (!dev->primary->master)
- return;
+ return 0;
master_priv = dev->primary->master->driver_priv;
if (!master_priv->sarea_priv)
- return;
+ return 0;
- switch (pipe) {
- case 0:
- master_priv->sarea_priv->pipeA_x = x;
- master_priv->sarea_priv->pipeA_y = y;
- break;
- case 1:
+ if (pipe) {
master_priv->sarea_priv->pipeB_x = x;
master_priv->sarea_priv->pipeB_y = y;
- break;
- default:
- DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
- break;
+ } else {
+ master_priv->sarea_priv->pipeA_x = x;
+ master_priv->sarea_priv->pipeA_y = y;
}
+
+ return 0;
}
@@ -708,11 +702,11 @@ static int intel_panel_fitter_pipe (struct drm_device *dev)
return 1;
}
-static void intel_crtc_mode_set(struct drm_crtc *crtc,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode,
- int x, int y,
- struct drm_framebuffer *old_fb)
+static int intel_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -732,13 +726,14 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
- int refclk;
+ int refclk, num_outputs = 0;
intel_clock_t clock;
u32 dpll = 0, fp = 0, dspcntr, pipeconf;
bool ok, is_sdvo = false, is_dvo = false;
bool is_crt = false, is_lvds = false, is_tv = false;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;
+ int ret;
drm_vblank_pre_modeset(dev, pipe);
@@ -755,6 +750,8 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
case INTEL_OUTPUT_SDVO:
case INTEL_OUTPUT_HDMI:
is_sdvo = true;
+ if (intel_output->needs_tv_clock)
+ is_tv = true;
break;
case INTEL_OUTPUT_DVO:
is_dvo = true;
@@ -766,9 +763,14 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
is_crt = true;
break;
}
+
+ num_outputs++;
}
- if (IS_I9XX(dev)) {
+ if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+ refclk = dev_priv->lvds_ssc_freq * 1000;
+ DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000);
+ } else if (IS_I9XX(dev)) {
refclk = 96000;
} else {
refclk = 48000;
@@ -777,7 +779,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
- return;
+ return -EINVAL;
}
fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
@@ -827,11 +829,14 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
}
}
- if (is_tv) {
+ if (is_sdvo && is_tv)
+ dpll |= PLL_REF_INPUT_TVCLKINBC;
+ else if (is_tv)
/* XXX: just matching BIOS for now */
-/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
+ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
dpll |= 3;
- }
+ else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+ dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;
@@ -948,9 +953,13 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(dspcntr_reg, dspcntr);
/* Flush the plane changes */
- intel_pipe_set_base(crtc, x, y, old_fb);
+ ret = intel_pipe_set_base(crtc, x, y, old_fb);
+ if (ret != 0)
+ return ret;
drm_vblank_post_modeset(dev, pipe);
+
+ return 0;
}
/** Loads the palette/gamma unit for the CRTC with the prepared values */
@@ -999,6 +1008,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
temp = CURSOR_MODE_DISABLE;
addr = 0;
bo = NULL;
+ mutex_lock(&dev->struct_mutex);
goto finish;
}
@@ -1021,18 +1031,19 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
}
/* we only need to pin inside GTT if cursor is non-phy */
+ mutex_lock(&dev->struct_mutex);
if (!dev_priv->cursor_needs_physical) {
ret = i915_gem_object_pin(bo, PAGE_SIZE);
if (ret) {
DRM_ERROR("failed to pin cursor bo\n");
- goto fail;
+ goto fail_locked;
}
addr = obj_priv->gtt_offset;
} else {
ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
if (ret) {
DRM_ERROR("failed to attach phys object\n");
- goto fail;
+ goto fail_locked;
}
addr = obj_priv->phys_obj->handle->busaddr;
}
@@ -1052,10 +1063,9 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
} else
i915_gem_object_unpin(intel_crtc->cursor_bo);
- mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(intel_crtc->cursor_bo);
- mutex_unlock(&dev->struct_mutex);
}
+ mutex_unlock(&dev->struct_mutex);
intel_crtc->cursor_addr = addr;
intel_crtc->cursor_bo = bo;
@@ -1063,6 +1073,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
return 0;
fail:
mutex_lock(&dev->struct_mutex);
+fail_locked:
drm_gem_object_unreference(bo);
mutex_unlock(&dev->struct_mutex);
return ret;
@@ -1290,7 +1301,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
}
/* XXX: Handle the 100Mhz refclk */
- i9xx_clock(96000, &clock);
+ intel_clock(96000, &clock);
} else {
bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
@@ -1302,9 +1313,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
if ((dpll & PLL_REF_INPUT_MASK) ==
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
/* XXX: might not be 66MHz */
- i8xx_clock(66000, &clock);
+ intel_clock(66000, &clock);
} else
- i8xx_clock(48000, &clock);
+ intel_clock(48000, &clock);
} else {
if (dpll & PLL_P1_DIVIDE_BY_TWO)
clock.p1 = 2;
@@ -1317,7 +1328,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
else
clock.p2 = 2;
- i8xx_clock(48000, &clock);
+ intel_clock(48000, &clock);
}
}
@@ -1452,6 +1463,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
static void intel_setup_outputs(struct drm_device *dev)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_connector *connector;
intel_crt_init(dev);
@@ -1463,13 +1475,16 @@ static void intel_setup_outputs(struct drm_device *dev)
if (IS_I9XX(dev)) {
int found;
- found = intel_sdvo_init(dev, SDVOB);
- if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
- intel_hdmi_init(dev, SDVOB);
-
- found = intel_sdvo_init(dev, SDVOC);
- if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
- intel_hdmi_init(dev, SDVOC);
+ if (I915_READ(SDVOB) & SDVO_DETECTED) {
+ found = intel_sdvo_init(dev, SDVOB);
+ if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+ intel_hdmi_init(dev, SDVOB);
+ }
+ if (!IS_G4X(dev) || (I915_READ(SDVOB) & SDVO_DETECTED)) {
+ found = intel_sdvo_init(dev, SDVOC);
+ if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+ intel_hdmi_init(dev, SDVOC);
+ }
} else
intel_dvo_init(dev);
@@ -1592,7 +1607,9 @@ intel_user_framebuffer_create(struct drm_device *dev,
ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj);
if (ret) {
+ mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
return NULL;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8a4cc50c5b4e..957daef8edff 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -82,6 +82,7 @@ struct intel_output {
struct intel_i2c_chan *i2c_bus; /* for control functions */
struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */
bool load_detect_temp;
+ bool needs_tv_clock;
void *dev_priv;
};
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index afd1217b8a02..b7f0ebe9f810 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -473,7 +473,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo);
if (ret) {
DRM_ERROR("failed to allocate fb.\n");
- goto out_unref;
+ goto out_unpin;
}
list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
@@ -484,7 +484,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
info = framebuffer_alloc(sizeof(struct intelfb_par), device);
if (!info) {
ret = -ENOMEM;
- goto out_unref;
+ goto out_unpin;
}
par = info->par;
@@ -513,7 +513,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
size);
if (!info->screen_base) {
ret = -ENOSPC;
- goto out_unref;
+ goto out_unpin;
}
info->screen_size = size;
@@ -608,6 +608,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
mutex_unlock(&dev->struct_mutex);
return 0;
+out_unpin:
+ i915_gem_object_unpin(fbo);
out_unref:
drm_gem_object_unreference(fbo);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index a5a2f5339e9e..5ee9d4c25753 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -137,10 +137,6 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
chan->reg = reg;
snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
chan->adapter.owner = THIS_MODULE;
-#ifndef I2C_HW_B_INTELFB
-#define I2C_HW_B_INTELFB I2C_HW_B_I810
-#endif
- chan->adapter.id = I2C_HW_B_INTELFB;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &dev->pdev->dev;
chan->algo.setsda = set_data;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 2fafdcc108fe..0d211af98854 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -27,6 +27,7 @@
* Jesse Barnes <jesse.barnes@intel.com>
*/
+#include <linux/dmi.h>
#include <linux/i2c.h>
#include "drmP.h"
#include "drm.h"
@@ -311,10 +312,8 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
if (dev_priv->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
- mutex_unlock(&dev->mode_config.mutex);
mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
drm_mode_probed_add(connector, mode);
- mutex_unlock(&dev->mode_config.mutex);
return 1;
}
@@ -340,6 +339,18 @@ static void intel_lvds_destroy(struct drm_connector *connector)
kfree(connector);
}
+static int intel_lvds_set_property(struct drm_connector *connector,
+ struct drm_property *property,
+ uint64_t value)
+{
+ struct drm_device *dev = connector->dev;
+
+ if (property == dev->mode_config.dpms_property && connector->encoder)
+ intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf));
+
+ return 0;
+}
+
static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
.dpms = intel_lvds_dpms,
.mode_fixup = intel_lvds_mode_fixup,
@@ -359,6 +370,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.restore = intel_lvds_restore,
.detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
+ .set_property = intel_lvds_set_property,
.destroy = intel_lvds_destroy,
};
@@ -392,6 +404,16 @@ void intel_lvds_init(struct drm_device *dev)
u32 lvds;
int pipe;
+ /* Blacklist machines that we know falsely report LVDS. */
+ /* FIXME: add a check for the Aopen Mini PC */
+
+ /* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */
+ if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") ||
+ dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) {
+ DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n");
+ return;
+ }
+
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output) {
return;
@@ -445,7 +467,7 @@ void intel_lvds_init(struct drm_device *dev)
dev_priv->panel_fixed_mode =
drm_mode_duplicate(dev, scan);
mutex_unlock(&dev->mode_config.mutex);
- goto out; /* FIXME: check for quirks */
+ goto out;
}
mutex_unlock(&dev->mode_config.mutex);
}
@@ -459,8 +481,6 @@ void intel_lvds_init(struct drm_device *dev)
if (dev_priv->panel_fixed_mode) {
dev_priv->panel_fixed_mode->type |=
DRM_MODE_TYPE_PREFERRED;
- drm_mode_probed_add(connector,
- dev_priv->panel_fixed_mode);
goto out;
}
}
@@ -479,7 +499,7 @@ void intel_lvds_init(struct drm_device *dev)
if (dev_priv->panel_fixed_mode) {
dev_priv->panel_fixed_mode->type |=
DRM_MODE_TYPE_PREFERRED;
- goto out; /* FIXME: check for quirks */
+ goto out;
}
}
@@ -487,38 +507,6 @@ void intel_lvds_init(struct drm_device *dev)
if (!dev_priv->panel_fixed_mode)
goto failed;
- /* FIXME: detect aopen & mac mini type stuff automatically? */
- /*
- * Blacklist machines with BIOSes that list an LVDS panel without
- * actually having one.
- */
- if (IS_I945GM(dev)) {
- /* aopen mini pc */
- if (dev->pdev->subsystem_vendor == 0xa0a0)
- goto failed;
-
- if ((dev->pdev->subsystem_vendor == 0x8086) &&
- (dev->pdev->subsystem_device == 0x7270)) {
- /* It's a Mac Mini or Macbook Pro.
- *
- * Apple hardware is out to get us. The macbook pro
- * has a real LVDS panel, but the mac mini does not,
- * and they have the same device IDs. We'll
- * distinguish by panel size, on the assumption
- * that Apple isn't about to make any machines with an
- * 800x600 display.
- */
-
- if (dev_priv->panel_fixed_mode != NULL &&
- dev_priv->panel_fixed_mode->hdisplay == 800 &&
- dev_priv->panel_fixed_mode->vdisplay == 600) {
- DRM_DEBUG("Suspected Mac Mini, ignoring the LVDS\n");
- goto failed;
- }
- }
- }
-
-
out:
drm_sysfs_connector_add(connector);
return;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 407215469102..fbe6f3931b1b 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -40,13 +40,59 @@
struct intel_sdvo_priv {
struct intel_i2c_chan *i2c_bus;
int slaveaddr;
+
+ /* Register for the SDVO device: SDVOB or SDVOC */
int output_device;
- u16 active_outputs;
+ /* Active outputs controlled by this SDVO output */
+ uint16_t controlled_output;
+ /*
+ * Capabilities of the SDVO device returned by
+ * i830_sdvo_get_capabilities()
+ */
struct intel_sdvo_caps caps;
+
+ /* Pixel clock limitations reported by the SDVO device, in kHz */
int pixel_clock_min, pixel_clock_max;
+ /**
+ * This is set if we're going to treat the device as TV-out.
+ *
+ * While we have these nice friendly flags for output types that ought
+ * to decide this for us, the S-Video output on our HDMI+S-Video card
+ * shows up as RGB1 (VGA).
+ */
+ bool is_tv;
+
+ /**
+ * This is set if we treat the device as HDMI, instead of DVI.
+ */
+ bool is_hdmi;
+
+ /**
+ * Returned SDTV resolutions allowed for the current format, if the
+ * device reported it.
+ */
+ struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
+
+ /**
+ * Current selected TV format.
+ *
+ * This is stored in the same structure that's passed to the device, for
+ * convenience.
+ */
+ struct intel_sdvo_tv_format tv_format;
+
+ /*
+ * supported encoding mode, used to determine whether HDMI is
+ * supported
+ */
+ struct intel_sdvo_encode encode;
+
+ /* DDC bus used by this SDVO output */
+ uint8_t ddc_bus;
+
int save_sdvo_mult;
u16 save_active_outputs;
struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
@@ -147,9 +193,9 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
/** Mapping of command numbers to names, for debug output */
-const static struct _sdvo_cmd_name {
- u8 cmd;
- char *name;
+static const struct _sdvo_cmd_name {
+ u8 cmd;
+ char *name;
} sdvo_cmd_names[] = {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
@@ -186,8 +232,35 @@ const static struct _sdvo_cmd_name {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
- SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
+ /* HDMI op code */
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA),
+ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
};
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
@@ -506,6 +579,50 @@ static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
}
+static bool
+intel_sdvo_create_preferred_input_timing(struct intel_output *output,
+ uint16_t clock,
+ uint16_t width,
+ uint16_t height)
+{
+ struct intel_sdvo_preferred_input_timing_args args;
+ uint8_t status;
+
+ args.clock = clock;
+ args.width = width;
+ args.height = height;
+ intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+ &args, sizeof(args));
+ status = intel_sdvo_read_response(output, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return true;
+}
+
+static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
+ struct intel_sdvo_dtd *dtd)
+{
+ bool status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+ NULL, 0);
+
+ status = intel_sdvo_read_response(output, &dtd->part1,
+ sizeof(dtd->part1));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+ NULL, 0);
+
+ status = intel_sdvo_read_response(output, &dtd->part2,
+ sizeof(dtd->part2));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+
+ return false;
+}
static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
{
@@ -536,36 +653,12 @@ static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8
return true;
}
-static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO
- * device will be told of the multiplier during mode_set.
- */
- adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
- return true;
-}
-
-static void intel_sdvo_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
+ struct drm_display_mode *mode)
{
- struct drm_device *dev = encoder->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = encoder->crtc;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_output *intel_output = enc_to_intel_output(encoder);
- struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
- u16 width, height;
- u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
- u16 h_sync_offset, v_sync_offset;
- u32 sdvox;
- struct intel_sdvo_dtd output_dtd;
- int sdvo_pixel_multiply;
-
- if (!mode)
- return;
+ uint16_t width, height;
+ uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
+ uint16_t h_sync_offset, v_sync_offset;
width = mode->crtc_hdisplay;
height = mode->crtc_vdisplay;
@@ -580,93 +673,423 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
- output_dtd.part1.clock = mode->clock / 10;
- output_dtd.part1.h_active = width & 0xff;
- output_dtd.part1.h_blank = h_blank_len & 0xff;
- output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
+ dtd->part1.clock = mode->clock / 10;
+ dtd->part1.h_active = width & 0xff;
+ dtd->part1.h_blank = h_blank_len & 0xff;
+ dtd->part1.h_high = (((width >> 8) & 0xf) << 4) |
((h_blank_len >> 8) & 0xf);
- output_dtd.part1.v_active = height & 0xff;
- output_dtd.part1.v_blank = v_blank_len & 0xff;
- output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
+ dtd->part1.v_active = height & 0xff;
+ dtd->part1.v_blank = v_blank_len & 0xff;
+ dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
((v_blank_len >> 8) & 0xf);
- output_dtd.part2.h_sync_off = h_sync_offset;
- output_dtd.part2.h_sync_width = h_sync_len & 0xff;
- output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
+ dtd->part2.h_sync_off = h_sync_offset;
+ dtd->part2.h_sync_width = h_sync_len & 0xff;
+ dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
(v_sync_len & 0xf);
- output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
+ dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
((v_sync_len & 0x30) >> 4);
- output_dtd.part2.dtd_flags = 0x18;
+ dtd->part2.dtd_flags = 0x18;
if (mode->flags & DRM_MODE_FLAG_PHSYNC)
- output_dtd.part2.dtd_flags |= 0x2;
+ dtd->part2.dtd_flags |= 0x2;
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
- output_dtd.part2.dtd_flags |= 0x4;
+ dtd->part2.dtd_flags |= 0x4;
+
+ dtd->part2.sdvo_flags = 0;
+ dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
+ dtd->part2.reserved = 0;
+}
+
+static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
+ struct intel_sdvo_dtd *dtd)
+{
+ uint16_t width, height;
+ uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
+ uint16_t h_sync_offset, v_sync_offset;
+
+ width = mode->crtc_hdisplay;
+ height = mode->crtc_vdisplay;
+
+ /* do some mode translations */
+ h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
+ h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+
+ v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
+ v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
+
+ h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
+ v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
+
+ mode->hdisplay = dtd->part1.h_active;
+ mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
+ mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off;
+ mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2;
+ mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width;
+ mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
+ mode->htotal = mode->hdisplay + dtd->part1.h_blank;
+ mode->htotal += (dtd->part1.h_high & 0xf) << 8;
+
+ mode->vdisplay = dtd->part1.v_active;
+ mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
+ mode->vsync_start = mode->vdisplay;
+ mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
+ mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2;
+ mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0;
+ mode->vsync_end = mode->vsync_start +
+ (dtd->part2.v_sync_off_width & 0xf);
+ mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
+ mode->vtotal = mode->vdisplay + dtd->part1.v_blank;
+ mode->vtotal += (dtd->part1.v_high & 0xf) << 8;
+
+ mode->clock = dtd->part1.clock * 10;
+
+ mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+ if (dtd->part2.dtd_flags & 0x2)
+ mode->flags |= DRM_MODE_FLAG_PHSYNC;
+ if (dtd->part2.dtd_flags & 0x4)
+ mode->flags |= DRM_MODE_FLAG_PVSYNC;
+}
+
+static bool intel_sdvo_get_supp_encode(struct intel_output *output,
+ struct intel_sdvo_encode *encode)
+{
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+ status = intel_sdvo_read_response(output, encode, sizeof(*encode));
+ if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
+ memset(encode, 0, sizeof(*encode));
+ return false;
+ }
+
+ return true;
+}
+
+static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
+{
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
+ status = intel_sdvo_read_response(output, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+static bool intel_sdvo_set_colorimetry(struct intel_output *output,
+ uint8_t mode)
+{
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+ status = intel_sdvo_read_response(output, NULL, 0);
+
+ return (status == SDVO_CMD_STATUS_SUCCESS);
+}
+
+#if 0
+static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
+{
+ int i, j;
+ uint8_t set_buf_index[2];
+ uint8_t av_split;
+ uint8_t buf_size;
+ uint8_t buf[48];
+ uint8_t *pos;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+ intel_sdvo_read_response(output, &av_split, 1);
+
+ for (i = 0; i <= av_split; i++) {
+ set_buf_index[0] = i; set_buf_index[1] = 0;
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+ set_buf_index, 2);
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+ intel_sdvo_read_response(output, &buf_size, 1);
+
+ pos = buf;
+ for (j = 0; j <= buf_size; j += 8) {
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA,
+ NULL, 0);
+ intel_sdvo_read_response(output, pos, 8);
+ pos += 8;
+ }
+ }
+}
+#endif
+
+static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
+ uint8_t *data, int8_t size, uint8_t tx_rate)
+{
+ uint8_t set_buf_index[2];
+
+ set_buf_index[0] = index;
+ set_buf_index[1] = 0;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+
+ for (; size > 0; size -= 8) {
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+ data += 8;
+ }
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+}
+
+static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
+{
+ uint8_t csum = 0;
+ int i;
+
+ for (i = 0; i < size; i++)
+ csum += data[i];
+
+ return 0x100 - csum;
+}
+
+#define DIP_TYPE_AVI 0x82
+#define DIP_VERSION_AVI 0x2
+#define DIP_LEN_AVI 13
+
+struct dip_infoframe {
+ uint8_t type;
+ uint8_t version;
+ uint8_t len;
+ uint8_t checksum;
+ union {
+ struct {
+ /* Packet Byte #1 */
+ uint8_t S:2;
+ uint8_t B:2;
+ uint8_t A:1;
+ uint8_t Y:2;
+ uint8_t rsvd1:1;
+ /* Packet Byte #2 */
+ uint8_t R:4;
+ uint8_t M:2;
+ uint8_t C:2;
+ /* Packet Byte #3 */
+ uint8_t SC:2;
+ uint8_t Q:2;
+ uint8_t EC:3;
+ uint8_t ITC:1;
+ /* Packet Byte #4 */
+ uint8_t VIC:7;
+ uint8_t rsvd2:1;
+ /* Packet Byte #5 */
+ uint8_t PR:4;
+ uint8_t rsvd3:4;
+ /* Packet Byte #6~13 */
+ uint16_t top_bar_end;
+ uint16_t bottom_bar_start;
+ uint16_t left_bar_end;
+ uint16_t right_bar_start;
+ } avi;
+ struct {
+ /* Packet Byte #1 */
+ uint8_t channel_count:3;
+ uint8_t rsvd1:1;
+ uint8_t coding_type:4;
+ /* Packet Byte #2 */
+ uint8_t sample_size:2; /* SS0, SS1 */
+ uint8_t sample_frequency:3;
+ uint8_t rsvd2:3;
+ /* Packet Byte #3 */
+ uint8_t coding_type_private:5;
+ uint8_t rsvd3:3;
+ /* Packet Byte #4 */
+ uint8_t channel_allocation;
+ /* Packet Byte #5 */
+ uint8_t rsvd4:3;
+ uint8_t level_shift:4;
+ uint8_t downmix_inhibit:1;
+ } audio;
+ uint8_t payload[28];
+ } __attribute__ ((packed)) u;
+} __attribute__((packed));
+
+static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
+ struct drm_display_mode * mode)
+{
+ struct dip_infoframe avi_if = {
+ .type = DIP_TYPE_AVI,
+ .version = DIP_VERSION_AVI,
+ .len = DIP_LEN_AVI,
+ };
+
+ avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
+ 4 + avi_if.len);
+ intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+ SDVO_HBUF_TX_VSYNC);
+}
+
+static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct intel_output *output = enc_to_intel_output(encoder);
+ struct intel_sdvo_priv *dev_priv = output->dev_priv;
- output_dtd.part2.sdvo_flags = 0;
- output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
- output_dtd.part2.reserved = 0;
+ if (!dev_priv->is_tv) {
+ /* Make the CRTC code factor in the SDVO pixel multiplier. The
+ * SDVO device will be told of the multiplier during mode_set.
+ */
+ adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
+ } else {
+ struct intel_sdvo_dtd output_dtd;
+ bool success;
+
+ /* We need to construct preferred input timings based on our
+ * output timings. To do that, we have to set the output
+ * timings, even though this isn't really the right place in
+ * the sequence to do it. Oh well.
+ */
+
+
+ /* Set output timings */
+ intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+ intel_sdvo_set_target_output(output,
+ dev_priv->controlled_output);
+ intel_sdvo_set_output_timing(output, &output_dtd);
+
+ /* Set the input timing to the screen. Assume always input 0. */
+ intel_sdvo_set_target_input(output, true, false);
+
+
+ success = intel_sdvo_create_preferred_input_timing(output,
+ mode->clock / 10,
+ mode->hdisplay,
+ mode->vdisplay);
+ if (success) {
+ struct intel_sdvo_dtd input_dtd;
- /* Set the output timing to the screen */
- intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs);
- intel_sdvo_set_output_timing(intel_output, &output_dtd);
+ intel_sdvo_get_preferred_input_timing(output,
+ &input_dtd);
+ intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void intel_sdvo_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = encoder->crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_output *output = enc_to_intel_output(encoder);
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ u32 sdvox = 0;
+ int sdvo_pixel_multiply;
+ struct intel_sdvo_in_out_map in_out;
+ struct intel_sdvo_dtd input_dtd;
+ u8 status;
+
+ if (!mode)
+ return;
+
+ /* First, set the input mapping for the first input to our controlled
+ * output. This is only correct if we're a single-input device, in
+ * which case the first input is the output from the appropriate SDVO
+ * channel on the motherboard. In a two-input device, the first input
+ * will be SDVOB and the second SDVOC.
+ */
+ in_out.in0 = sdvo_priv->controlled_output;
+ in_out.in1 = 0;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
+ &in_out, sizeof(in_out));
+ status = intel_sdvo_read_response(output, NULL, 0);
+
+ if (sdvo_priv->is_hdmi) {
+ intel_sdvo_set_avi_infoframe(output, mode);
+ sdvox |= SDVO_AUDIO_ENABLE;
+ }
+
+ intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
+
+ /* If it's a TV, we already set the output timing in mode_fixup.
+ * Otherwise, the output timing is equal to the input timing.
+ */
+ if (!sdvo_priv->is_tv) {
+ /* Set the output timing to the screen */
+ intel_sdvo_set_target_output(output,
+ sdvo_priv->controlled_output);
+ intel_sdvo_set_output_timing(output, &input_dtd);
+ }
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(intel_output, true, false);
+ intel_sdvo_set_target_input(output, true, false);
- /* We would like to use i830_sdvo_create_preferred_input_timing() to
+ /* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
* feature. However, presumably we would need to adjust the CRTC to
* output the preferred timing, and we don't support that currently.
*/
- intel_sdvo_set_input_timing(intel_output, &output_dtd);
+#if 0
+ success = intel_sdvo_create_preferred_input_timing(output, clock,
+ width, height);
+ if (success) {
+ struct intel_sdvo_dtd *input_dtd;
+
+ intel_sdvo_get_preferred_input_timing(output, &input_dtd);
+ intel_sdvo_set_input_timing(output, &input_dtd);
+ }
+#else
+ intel_sdvo_set_input_timing(output, &input_dtd);
+#endif
switch (intel_sdvo_get_pixel_multiplier(mode)) {
case 1:
- intel_sdvo_set_clock_rate_mult(intel_output,
+ intel_sdvo_set_clock_rate_mult(output,
SDVO_CLOCK_RATE_MULT_1X);
break;
case 2:
- intel_sdvo_set_clock_rate_mult(intel_output,
+ intel_sdvo_set_clock_rate_mult(output,
SDVO_CLOCK_RATE_MULT_2X);
break;
case 4:
- intel_sdvo_set_clock_rate_mult(intel_output,
+ intel_sdvo_set_clock_rate_mult(output,
SDVO_CLOCK_RATE_MULT_4X);
break;
}
/* Set the SDVO control regs. */
- if (0/*IS_I965GM(dev)*/) {
- sdvox = SDVO_BORDER_ENABLE;
- } else {
- sdvox = I915_READ(sdvo_priv->output_device);
- switch (sdvo_priv->output_device) {
- case SDVOB:
- sdvox &= SDVOB_PRESERVE_MASK;
- break;
- case SDVOC:
- sdvox &= SDVOC_PRESERVE_MASK;
- break;
- }
- sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
- }
+ if (IS_I965G(dev)) {
+ sdvox |= SDVO_BORDER_ENABLE |
+ SDVO_VSYNC_ACTIVE_HIGH |
+ SDVO_HSYNC_ACTIVE_HIGH;
+ } else {
+ sdvox |= I915_READ(sdvo_priv->output_device);
+ switch (sdvo_priv->output_device) {
+ case SDVOB:
+ sdvox &= SDVOB_PRESERVE_MASK;
+ break;
+ case SDVOC:
+ sdvox &= SDVOC_PRESERVE_MASK;
+ break;
+ }
+ sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
+ }
if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
if (IS_I965G(dev)) {
- /* done in crtc_mode_set as the dpll_md reg must be written
- early */
- } else if (IS_I945G(dev) || IS_I945GM(dev)) {
- /* done in crtc_mode_set as it lives inside the
- dpll register */
+ /* done in crtc_mode_set as the dpll_md reg must be written early */
+ } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
+ /* done in crtc_mode_set as it lives inside the dpll register */
} else {
sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
}
- intel_sdvo_write_sdvox(intel_output, sdvox);
+ intel_sdvo_write_sdvox(output, sdvox);
}
static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
@@ -714,7 +1137,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
if (0)
intel_sdvo_set_encoder_power_state(intel_output, mode);
- intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs);
+ intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
}
return;
}
@@ -752,6 +1175,9 @@ static void intel_sdvo_save(struct drm_connector *connector)
&sdvo_priv->save_output_dtd[o]);
}
}
+ if (sdvo_priv->is_tv) {
+ /* XXX: Save TV format/enhancements. */
+ }
sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
}
@@ -759,7 +1185,6 @@ static void intel_sdvo_save(struct drm_connector *connector)
static void intel_sdvo_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_output *intel_output = to_intel_output(connector);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int o;
@@ -790,7 +1215,11 @@ static void intel_sdvo_restore(struct drm_connector *connector)
intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
- I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
+ if (sdvo_priv->is_tv) {
+ /* XXX: Restore TV format/enhancements. */
+ }
+
+ intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
{
@@ -916,20 +1345,173 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
status = intel_sdvo_read_response(intel_output, &response, 2);
DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
+
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return connector_status_unknown;
+
if ((response[0] != 0) || (response[1] != 0))
return connector_status_connected;
else
return connector_status_disconnected;
}
-static int intel_sdvo_get_modes(struct drm_connector *connector)
+static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
{
struct intel_output *intel_output = to_intel_output(connector);
+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
/* set the bus switch and get the modes */
- intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2);
+ intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
intel_ddc_get_modes(intel_output);
+#if 0
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ /* Mac mini hack. On this device, I get DDC through the analog, which
+ * load-detects as disconnected. I fail to DDC through the SDVO DDC,
+ * but it does load-detect as connected. So, just steal the DDC bits
+ * from analog when we fail at finding it the right way.
+ */
+ crt = xf86_config->output[0];
+ intel_output = crt->driver_private;
+ if (intel_output->type == I830_OUTPUT_ANALOG &&
+ crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
+ I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A");
+ edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus);
+ xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true);
+ }
+ if (edid_mon) {
+ xf86OutputSetEDID(output, edid_mon);
+ modes = xf86OutputGetEDIDModes(output);
+ }
+#endif
+}
+
+/**
+ * This function checks the current TV format, and chooses a default if
+ * it hasn't been set.
+ */
+static void
+intel_sdvo_check_tv_format(struct intel_output *output)
+{
+ struct intel_sdvo_priv *dev_priv = output->dev_priv;
+ struct intel_sdvo_tv_format format, unset;
+ uint8_t status;
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
+ status = intel_sdvo_read_response(output, &format, sizeof(format));
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return;
+
+ memset(&unset, 0, sizeof(unset));
+ if (memcmp(&format, &unset, sizeof(format))) {
+ DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
+ SDVO_NAME(dev_priv));
+
+ format.ntsc_m = true;
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
+ status = intel_sdvo_read_response(output, NULL, 0);
+ }
+}
+
+/*
+ * Set of SDVO TV modes.
+ * Note! This is in reply order (see loop in get_tv_modes).
+ * XXX: all 60Hz refresh?
+ */
+struct drm_display_mode sdvo_tv_modes[] = {
+ { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416,
+ 200, 0, 232, 201, 233, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416,
+ 240, 0, 272, 241, 273, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496,
+ 300, 0, 332, 301, 333, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736,
+ 350, 0, 382, 351, 383, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
+ 400, 0, 432, 401, 433, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
+ 400, 0, 432, 401, 433, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800,
+ 480, 0, 512, 481, 513, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800,
+ 576, 0, 608, 577, 609, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816,
+ 350, 0, 382, 351, 383, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816,
+ 400, 0, 432, 401, 433, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816,
+ 480, 0, 512, 481, 513, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816,
+ 540, 0, 572, 541, 573, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816,
+ 576, 0, 608, 577, 609, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864,
+ 576, 0, 608, 577, 609, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896,
+ 600, 0, 632, 601, 633, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928,
+ 624, 0, 656, 625, 657, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016,
+ 766, 0, 798, 767, 799, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120,
+ 768, 0, 800, 769, 801, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376,
+ 1024, 0, 1056, 1025, 1057, 4196112, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+};
+
+static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
+{
+ struct intel_output *output = to_intel_output(connector);
+ uint32_t reply = 0;
+ uint8_t status;
+ int i = 0;
+
+ intel_sdvo_check_tv_format(output);
+
+ /* Read the list of supported input resolutions for the selected TV
+ * format.
+ */
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
+ NULL, 0);
+ status = intel_sdvo_read_response(output, &reply, 3);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
+ if (reply & (1 << i))
+ drm_mode_probed_add(connector, &sdvo_tv_modes[i]);
+}
+
+static int intel_sdvo_get_modes(struct drm_connector *connector)
+{
+ struct intel_output *output = to_intel_output(connector);
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+
+ if (sdvo_priv->is_tv)
+ intel_sdvo_get_tv_modes(connector);
+ else
+ intel_sdvo_get_ddc_modes(connector);
+
if (list_empty(&connector->probed_modes))
return 0;
return 1;
@@ -978,6 +1560,65 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
};
+/**
+ * Choose the appropriate DDC bus for control bus switch command for this
+ * SDVO output based on the controlled output.
+ *
+ * DDC bus number assignment is in a priority order of RGB outputs, then TMDS
+ * outputs, then LVDS outputs.
+ */
+static void
+intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
+{
+ uint16_t mask = 0;
+ unsigned int num_bits;
+
+ /* Make a mask of outputs less than or equal to our own priority in the
+ * list.
+ */
+ switch (dev_priv->controlled_output) {
+ case SDVO_OUTPUT_LVDS1:
+ mask |= SDVO_OUTPUT_LVDS1;
+ case SDVO_OUTPUT_LVDS0:
+ mask |= SDVO_OUTPUT_LVDS0;
+ case SDVO_OUTPUT_TMDS1:
+ mask |= SDVO_OUTPUT_TMDS1;
+ case SDVO_OUTPUT_TMDS0:
+ mask |= SDVO_OUTPUT_TMDS0;
+ case SDVO_OUTPUT_RGB1:
+ mask |= SDVO_OUTPUT_RGB1;
+ case SDVO_OUTPUT_RGB0:
+ mask |= SDVO_OUTPUT_RGB0;
+ break;
+ }
+
+ /* Count bits to find what number we are in the priority list. */
+ mask &= dev_priv->caps.output_flags;
+ num_bits = hweight16(mask);
+ if (num_bits > 3) {
+ /* if more than 3 outputs, default to DDC bus 3 for now */
+ num_bits = 3;
+ }
+
+ /* Corresponds to SDVO_CONTROL_BUS_DDCx */
+ dev_priv->ddc_bus = 1 << num_bits;
+}
+
+static bool
+intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
+{
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ uint8_t status;
+
+ intel_sdvo_set_target_output(output, sdvo_priv->controlled_output);
+
+ intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0);
+ status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ return false;
+ return true;
+}
+
bool intel_sdvo_init(struct drm_device *dev, int output_device)
{
struct drm_connector *connector;
@@ -1040,45 +1681,76 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
- memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
+ if (sdvo_priv->caps.output_flags &
+ (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
+ if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+ sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0;
+ else
+ sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
+
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_TMDS;
+ connector_type = DRM_MODE_CONNECTOR_DVID;
- /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
- if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
+ if (intel_sdvo_get_supp_encode(intel_output,
+ &sdvo_priv->encode) &&
+ intel_sdvo_get_digital_encoding_mode(intel_output) &&
+ sdvo_priv->is_hdmi) {
+ /* enable hdmi encoding mode if supported */
+ intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
+ intel_sdvo_set_colorimetry(intel_output,
+ SDVO_COLORIMETRY_RGB256);
+ connector_type = DRM_MODE_CONNECTOR_HDMIA;
+ }
+ }
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_TVDAC;
+ connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+ sdvo_priv->is_tv = true;
+ intel_output->needs_tv_clock = true;
+ }
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
+ {
+ sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
encoder_type = DRM_MODE_ENCODER_DAC;
connector_type = DRM_MODE_CONNECTOR_VGA;
}
else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
encoder_type = DRM_MODE_ENCODER_DAC;
connector_type = DRM_MODE_CONNECTOR_VGA;
}
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- encoder_type = DRM_MODE_ENCODER_TMDS;
- connector_type = DRM_MODE_CONNECTOR_DVID;
+ encoder_type = DRM_MODE_ENCODER_LVDS;
+ connector_type = DRM_MODE_CONNECTOR_LVDS;
}
- else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
+ else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
{
- sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
+ sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
- encoder_type = DRM_MODE_ENCODER_TMDS;
- connector_type = DRM_MODE_CONNECTOR_DVID;
+ encoder_type = DRM_MODE_ENCODER_LVDS;
+ connector_type = DRM_MODE_CONNECTOR_LVDS;
}
else
{
unsigned char bytes[2];
+ sdvo_priv->controlled_output = 0;
memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
- DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
+ DRM_DEBUG("%s: Unknown SDVO output type (0x%02x%02x)\n",
SDVO_NAME(sdvo_priv),
bytes[0], bytes[1]);
+ encoder_type = DRM_MODE_ENCODER_NONE;
+ connector_type = DRM_MODE_CONNECTOR_Unknown;
goto err_i2c;
}
@@ -1089,6 +1761,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
drm_sysfs_connector_add(connector);
+ intel_sdvo_select_ddc_bus(sdvo_priv);
+
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(intel_output, true, false);
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
index 861a43f8693c..1117b9c151a6 100644
--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
@@ -173,6 +173,9 @@ struct intel_sdvo_get_trained_inputs_response {
* Returns two struct intel_sdvo_output_flags structures.
*/
#define SDVO_CMD_GET_IN_OUT_MAP 0x06
+struct intel_sdvo_in_out_map {
+ u16 in0, in1;
+};
/**
* Sets the current mapping of SDVO inputs to outputs on the device.
@@ -206,7 +209,8 @@ struct intel_sdvo_get_trained_inputs_response {
struct intel_sdvo_get_interrupt_event_source_response {
u16 interrupt_status;
unsigned int ambient_light_interrupt:1;
- unsigned int pad:7;
+ unsigned int hdmi_audio_encrypt_change:1;
+ unsigned int pad:6;
} __attribute__((packed));
/**
@@ -305,23 +309,411 @@ struct intel_sdvo_set_target_input_args {
# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
+/** 5 bytes of bit flags for TV formats shared by all TV format functions */
+struct intel_sdvo_tv_format {
+ unsigned int ntsc_m:1;
+ unsigned int ntsc_j:1;
+ unsigned int ntsc_443:1;
+ unsigned int pal_b:1;
+ unsigned int pal_d:1;
+ unsigned int pal_g:1;
+ unsigned int pal_h:1;
+ unsigned int pal_i:1;
+
+ unsigned int pal_m:1;
+ unsigned int pal_n:1;
+ unsigned int pal_nc:1;
+ unsigned int pal_60:1;
+ unsigned int secam_b:1;
+ unsigned int secam_d:1;
+ unsigned int secam_g:1;
+ unsigned int secam_k:1;
+
+ unsigned int secam_k1:1;
+ unsigned int secam_l:1;
+ unsigned int secam_60:1;
+ unsigned int hdtv_std_smpte_240m_1080i_59:1;
+ unsigned int hdtv_std_smpte_240m_1080i_60:1;
+ unsigned int hdtv_std_smpte_260m_1080i_59:1;
+ unsigned int hdtv_std_smpte_260m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080i_50:1;
+
+ unsigned int hdtv_std_smpte_274m_1080i_59:1;
+ unsigned int hdtv_std_smpte_274m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080p_23:1;
+ unsigned int hdtv_std_smpte_274m_1080p_24:1;
+ unsigned int hdtv_std_smpte_274m_1080p_25:1;
+ unsigned int hdtv_std_smpte_274m_1080p_29:1;
+ unsigned int hdtv_std_smpte_274m_1080p_30:1;
+ unsigned int hdtv_std_smpte_274m_1080p_50:1;
+
+ unsigned int hdtv_std_smpte_274m_1080p_59:1;
+ unsigned int hdtv_std_smpte_274m_1080p_60:1;
+ unsigned int hdtv_std_smpte_295m_1080i_50:1;
+ unsigned int hdtv_std_smpte_295m_1080p_50:1;
+ unsigned int hdtv_std_smpte_296m_720p_59:1;
+ unsigned int hdtv_std_smpte_296m_720p_60:1;
+ unsigned int hdtv_std_smpte_296m_720p_50:1;
+ unsigned int hdtv_std_smpte_293m_480p_59:1;
+
+ unsigned int hdtv_std_smpte_170m_480i_59:1;
+ unsigned int hdtv_std_iturbt601_576i_50:1;
+ unsigned int hdtv_std_iturbt601_576p_50:1;
+ unsigned int hdtv_std_eia_7702a_480i_60:1;
+ unsigned int hdtv_std_eia_7702a_480p_60:1;
+ unsigned int pad:3;
+} __attribute__((packed));
#define SDVO_CMD_GET_TV_FORMAT 0x28
#define SDVO_CMD_SET_TV_FORMAT 0x29
+/** Returns the resolutiosn that can be used with the given TV format */
+#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83
+struct intel_sdvo_sdtv_resolution_request {
+ unsigned int ntsc_m:1;
+ unsigned int ntsc_j:1;
+ unsigned int ntsc_443:1;
+ unsigned int pal_b:1;
+ unsigned int pal_d:1;
+ unsigned int pal_g:1;
+ unsigned int pal_h:1;
+ unsigned int pal_i:1;
+
+ unsigned int pal_m:1;
+ unsigned int pal_n:1;
+ unsigned int pal_nc:1;
+ unsigned int pal_60:1;
+ unsigned int secam_b:1;
+ unsigned int secam_d:1;
+ unsigned int secam_g:1;
+ unsigned int secam_k:1;
+
+ unsigned int secam_k1:1;
+ unsigned int secam_l:1;
+ unsigned int secam_60:1;
+ unsigned int pad:5;
+} __attribute__((packed));
+
+struct intel_sdvo_sdtv_resolution_reply {
+ unsigned int res_320x200:1;
+ unsigned int res_320x240:1;
+ unsigned int res_400x300:1;
+ unsigned int res_640x350:1;
+ unsigned int res_640x400:1;
+ unsigned int res_640x480:1;
+ unsigned int res_704x480:1;
+ unsigned int res_704x576:1;
+
+ unsigned int res_720x350:1;
+ unsigned int res_720x400:1;
+ unsigned int res_720x480:1;
+ unsigned int res_720x540:1;
+ unsigned int res_720x576:1;
+ unsigned int res_768x576:1;
+ unsigned int res_800x600:1;
+ unsigned int res_832x624:1;
+
+ unsigned int res_920x766:1;
+ unsigned int res_1024x768:1;
+ unsigned int res_1280x1024:1;
+ unsigned int pad:5;
+} __attribute__((packed));
+
+/* Get supported resolution with squire pixel aspect ratio that can be
+ scaled for the requested HDTV format */
+#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85
+
+struct intel_sdvo_hdtv_resolution_request {
+ unsigned int hdtv_std_smpte_240m_1080i_59:1;
+ unsigned int hdtv_std_smpte_240m_1080i_60:1;
+ unsigned int hdtv_std_smpte_260m_1080i_59:1;
+ unsigned int hdtv_std_smpte_260m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080i_50:1;
+ unsigned int hdtv_std_smpte_274m_1080i_59:1;
+ unsigned int hdtv_std_smpte_274m_1080i_60:1;
+ unsigned int hdtv_std_smpte_274m_1080p_23:1;
+
+ unsigned int hdtv_std_smpte_274m_1080p_24:1;
+ unsigned int hdtv_std_smpte_274m_1080p_25:1;
+ unsigned int hdtv_std_smpte_274m_1080p_29:1;
+ unsigned int hdtv_std_smpte_274m_1080p_30:1;
+ unsigned int hdtv_std_smpte_274m_1080p_50:1;
+ unsigned int hdtv_std_smpte_274m_1080p_59:1;
+ unsigned int hdtv_std_smpte_274m_1080p_60:1;
+ unsigned int hdtv_std_smpte_295m_1080i_50:1;
+
+ unsigned int hdtv_std_smpte_295m_1080p_50:1;
+ unsigned int hdtv_std_smpte_296m_720p_59:1;
+ unsigned int hdtv_std_smpte_296m_720p_60:1;
+ unsigned int hdtv_std_smpte_296m_720p_50:1;
+ unsigned int hdtv_std_smpte_293m_480p_59:1;
+ unsigned int hdtv_std_smpte_170m_480i_59:1;
+ unsigned int hdtv_std_iturbt601_576i_50:1;
+ unsigned int hdtv_std_iturbt601_576p_50:1;
+
+ unsigned int hdtv_std_eia_7702a_480i_60:1;
+ unsigned int hdtv_std_eia_7702a_480p_60:1;
+ unsigned int pad:6;
+} __attribute__((packed));
+
+struct intel_sdvo_hdtv_resolution_reply {
+ unsigned int res_640x480:1;
+ unsigned int res_800x600:1;
+ unsigned int res_1024x768:1;
+ unsigned int res_1280x960:1;
+ unsigned int res_1400x1050:1;
+ unsigned int res_1600x1200:1;
+ unsigned int res_1920x1440:1;
+ unsigned int res_2048x1536:1;
+
+ unsigned int res_2560x1920:1;
+ unsigned int res_3200x2400:1;
+ unsigned int res_3840x2880:1;
+ unsigned int pad1:5;
+
+ unsigned int res_848x480:1;
+ unsigned int res_1064x600:1;
+ unsigned int res_1280x720:1;
+ unsigned int res_1360x768:1;
+ unsigned int res_1704x960:1;
+ unsigned int res_1864x1050:1;
+ unsigned int res_1920x1080:1;
+ unsigned int res_2128x1200:1;
+
+ unsigned int res_2560x1400:1;
+ unsigned int res_2728x1536:1;
+ unsigned int res_3408x1920:1;
+ unsigned int res_4264x2400:1;
+ unsigned int res_5120x2880:1;
+ unsigned int pad2:3;
+
+ unsigned int res_768x480:1;
+ unsigned int res_960x600:1;
+ unsigned int res_1152x720:1;
+ unsigned int res_1124x768:1;
+ unsigned int res_1536x960:1;
+ unsigned int res_1680x1050:1;
+ unsigned int res_1728x1080:1;
+ unsigned int res_1920x1200:1;
+
+ unsigned int res_2304x1440:1;
+ unsigned int res_2456x1536:1;
+ unsigned int res_3072x1920:1;
+ unsigned int res_3840x2400:1;
+ unsigned int res_4608x2880:1;
+ unsigned int pad3:3;
+
+ unsigned int res_1280x1024:1;
+ unsigned int pad4:7;
+
+ unsigned int res_1280x768:1;
+ unsigned int pad5:7;
+} __attribute__((packed));
+
+/* Get supported power state returns info for encoder and monitor, rely on
+ last SetTargetInput and SetTargetOutput calls */
#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a
+/* Get power state returns info for encoder and monitor, rely on last
+ SetTargetInput and SetTargetOutput calls */
+#define SDVO_CMD_GET_POWER_STATE 0x2b
#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b
#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c
# define SDVO_ENCODER_STATE_ON (1 << 0)
# define SDVO_ENCODER_STATE_STANDBY (1 << 1)
# define SDVO_ENCODER_STATE_SUSPEND (1 << 2)
# define SDVO_ENCODER_STATE_OFF (1 << 3)
+# define SDVO_MONITOR_STATE_ON (1 << 4)
+# define SDVO_MONITOR_STATE_STANDBY (1 << 5)
+# define SDVO_MONITOR_STATE_SUSPEND (1 << 6)
+# define SDVO_MONITOR_STATE_OFF (1 << 7)
+
+#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d
+#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e
+#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f
+/**
+ * The panel power sequencing parameters are in units of milliseconds.
+ * The high fields are bits 8:9 of the 10-bit values.
+ */
+struct sdvo_panel_power_sequencing {
+ u8 t0;
+ u8 t1;
+ u8 t2;
+ u8 t3;
+ u8 t4;
+
+ unsigned int t0_high:2;
+ unsigned int t1_high:2;
+ unsigned int t2_high:2;
+ unsigned int t3_high:2;
+
+ unsigned int t4_high:2;
+ unsigned int pad:6;
+} __attribute__((packed));
+
+#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30
+struct sdvo_max_backlight_reply {
+ u8 max_value;
+ u8 default_value;
+} __attribute__((packed));
+
+#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31
+#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32
+
+#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33
+struct sdvo_get_ambient_light_reply {
+ u16 trip_low;
+ u16 trip_high;
+ u16 value;
+} __attribute__((packed));
+#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34
+struct sdvo_set_ambient_light_reply {
+ u16 trip_low;
+ u16 trip_high;
+ unsigned int enable:1;
+ unsigned int pad:7;
+} __attribute__((packed));
+
+/* Set display power state */
+#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d
+# define SDVO_DISPLAY_STATE_ON (1 << 0)
+# define SDVO_DISPLAY_STATE_STANDBY (1 << 1)
+# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2)
+# define SDVO_DISPLAY_STATE_OFF (1 << 3)
+
+#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84
+struct intel_sdvo_enhancements_reply {
+ unsigned int flicker_filter:1;
+ unsigned int flicker_filter_adaptive:1;
+ unsigned int flicker_filter_2d:1;
+ unsigned int saturation:1;
+ unsigned int hue:1;
+ unsigned int brightness:1;
+ unsigned int contrast:1;
+ unsigned int overscan_h:1;
+
+ unsigned int overscan_v:1;
+ unsigned int position_h:1;
+ unsigned int position_v:1;
+ unsigned int sharpness:1;
+ unsigned int dot_crawl:1;
+ unsigned int dither:1;
+ unsigned int max_tv_chroma_filter:1;
+ unsigned int max_tv_luma_filter:1;
+} __attribute__((packed));
+
+/* Picture enhancement limits below are dependent on the current TV format,
+ * and thus need to be queried and set after it.
+ */
+#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d
+#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b
+#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52
+#define SDVO_CMD_GET_MAX_SATURATION 0x55
+#define SDVO_CMD_GET_MAX_HUE 0x58
+#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b
+#define SDVO_CMD_GET_MAX_CONTRAST 0x5e
+#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61
+#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64
+#define SDVO_CMD_GET_MAX_POSITION_H 0x67
+#define SDVO_CMD_GET_MAX_POSITION_V 0x6a
+#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d
+#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74
+#define SDVO_CMD_GET_MAX_TV_LUMA 0x77
+struct intel_sdvo_enhancement_limits_reply {
+ u16 max_value;
+ u16 default_value;
+} __attribute__((packed));
-#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93
+#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f
+#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80
+# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0)
+# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0)
+# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2)
+# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2)
+# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4)
+# define SDVO_LVDS_DUAL_CHANNEL (1 << 4)
+
+#define SDVO_CMD_GET_FLICKER_FILTER 0x4e
+#define SDVO_CMD_SET_FLICKER_FILTER 0x4f
+#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50
+#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51
+#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53
+#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54
+#define SDVO_CMD_GET_SATURATION 0x56
+#define SDVO_CMD_SET_SATURATION 0x57
+#define SDVO_CMD_GET_HUE 0x59
+#define SDVO_CMD_SET_HUE 0x5a
+#define SDVO_CMD_GET_BRIGHTNESS 0x5c
+#define SDVO_CMD_SET_BRIGHTNESS 0x5d
+#define SDVO_CMD_GET_CONTRAST 0x5f
+#define SDVO_CMD_SET_CONTRAST 0x60
+#define SDVO_CMD_GET_OVERSCAN_H 0x62
+#define SDVO_CMD_SET_OVERSCAN_H 0x63
+#define SDVO_CMD_GET_OVERSCAN_V 0x65
+#define SDVO_CMD_SET_OVERSCAN_V 0x66
+#define SDVO_CMD_GET_POSITION_H 0x68
+#define SDVO_CMD_SET_POSITION_H 0x69
+#define SDVO_CMD_GET_POSITION_V 0x6b
+#define SDVO_CMD_SET_POSITION_V 0x6c
+#define SDVO_CMD_GET_SHARPNESS 0x6e
+#define SDVO_CMD_SET_SHARPNESS 0x6f
+#define SDVO_CMD_GET_TV_CHROMA 0x75
+#define SDVO_CMD_SET_TV_CHROMA 0x76
+#define SDVO_CMD_GET_TV_LUMA 0x78
+#define SDVO_CMD_SET_TV_LUMA 0x79
+struct intel_sdvo_enhancements_arg {
+ u16 value;
+}__attribute__((packed));
+
+#define SDVO_CMD_GET_DOT_CRAWL 0x70
+#define SDVO_CMD_SET_DOT_CRAWL 0x71
+# define SDVO_DOT_CRAWL_ON (1 << 0)
+# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1)
+
+#define SDVO_CMD_GET_DITHER 0x72
+#define SDVO_CMD_SET_DITHER 0x73
+# define SDVO_DITHER_ON (1 << 0)
+# define SDVO_DITHER_DEFAULT_ON (1 << 1)
#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a
-# define SDVO_CONTROL_BUS_PROM 0x0
-# define SDVO_CONTROL_BUS_DDC1 0x1
-# define SDVO_CONTROL_BUS_DDC2 0x2
-# define SDVO_CONTROL_BUS_DDC3 0x3
+# define SDVO_CONTROL_BUS_PROM (1 << 0)
+# define SDVO_CONTROL_BUS_DDC1 (1 << 1)
+# define SDVO_CONTROL_BUS_DDC2 (1 << 2)
+# define SDVO_CONTROL_BUS_DDC3 (1 << 3)
+
+/* HDMI op codes */
+#define SDVO_CMD_GET_SUPP_ENCODE 0x9d
+#define SDVO_CMD_GET_ENCODE 0x9e
+#define SDVO_CMD_SET_ENCODE 0x9f
+ #define SDVO_ENCODE_DVI 0x0
+ #define SDVO_ENCODE_HDMI 0x1
+#define SDVO_CMD_SET_PIXEL_REPLI 0x8b
+#define SDVO_CMD_GET_PIXEL_REPLI 0x8c
+#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d
+#define SDVO_CMD_SET_COLORIMETRY 0x8e
+ #define SDVO_COLORIMETRY_RGB256 0x0
+ #define SDVO_COLORIMETRY_RGB220 0x1
+ #define SDVO_COLORIMETRY_YCrCb422 0x3
+ #define SDVO_COLORIMETRY_YCrCb444 0x4
+#define SDVO_CMD_GET_COLORIMETRY 0x8f
+#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90
+#define SDVO_CMD_SET_AUDIO_STAT 0x91
+#define SDVO_CMD_GET_AUDIO_STAT 0x92
+#define SDVO_CMD_SET_HBUF_INDEX 0x93
+#define SDVO_CMD_GET_HBUF_INDEX 0x94
+#define SDVO_CMD_GET_HBUF_INFO 0x95
+#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96
+#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97
+#define SDVO_CMD_SET_HBUF_DATA 0x98
+#define SDVO_CMD_GET_HBUF_DATA 0x99
+#define SDVO_CMD_SET_HBUF_TXRATE 0x9a
+#define SDVO_CMD_GET_HBUF_TXRATE 0x9b
+ #define SDVO_HBUF_TX_DISABLED (0 << 6)
+ #define SDVO_HBUF_TX_ONCE (2 << 6)
+ #define SDVO_HBUF_TX_VSYNC (3 << 6)
+#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c
+
+struct intel_sdvo_encode{
+ u8 dvi_rev;
+ u8 hdmi_rev;
+} __attribute__ ((packed));
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index fbb35dc56f5c..56485d67369b 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -411,7 +411,7 @@ struct tv_mode {
* These values account for -1s required.
*/
-const static struct tv_mode tv_modes[] = {
+static const struct tv_mode tv_modes[] = {
{
.name = "NTSC-M",
.clock = 107520,
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 63212d7bbc28..92965dbb3c14 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -557,8 +557,10 @@ static int radeon_do_engine_reset(struct drm_device * dev)
}
static void radeon_cp_init_ring_buffer(struct drm_device * dev,
- drm_radeon_private_t * dev_priv)
+ drm_radeon_private_t *dev_priv,
+ struct drm_file *file_priv)
{
+ struct drm_radeon_master_private *master_priv;
u32 ring_start, cur_read_ptr;
u32 tmp;
@@ -677,6 +679,14 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
dev_priv->scratch[2] = 0;
RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
+ /* reset sarea copies of these */
+ master_priv = file_priv->master->driver_priv;
+ if (master_priv->sarea_priv) {
+ master_priv->sarea_priv->last_frame = 0;
+ master_priv->sarea_priv->last_dispatch = 0;
+ master_priv->sarea_priv->last_clear = 0;
+ }
+
radeon_do_wait_for_idle(dev_priv);
/* Sync everything up */
@@ -1039,9 +1049,9 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
- drm_core_ioremap(dev_priv->cp_ring, dev);
- drm_core_ioremap(dev_priv->ring_rptr, dev);
- drm_core_ioremap(dev->agp_buffer_map, dev);
+ drm_core_ioremap_wc(dev_priv->cp_ring, dev);
+ drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
+ drm_core_ioremap_wc(dev->agp_buffer_map, dev);
if (!dev_priv->cp_ring->handle ||
!dev_priv->ring_rptr->handle ||
!dev->agp_buffer_map->handle) {
@@ -1215,7 +1225,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
}
radeon_cp_load_microcode(dev_priv);
- radeon_cp_init_ring_buffer(dev, dev_priv);
+ radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
dev_priv->last_buf = 0;
@@ -1281,7 +1291,7 @@ static int radeon_do_cleanup_cp(struct drm_device * dev)
*
* Charl P. Botha <http://cpbotha.net>
*/
-static int radeon_do_resume_cp(struct drm_device * dev)
+static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1304,7 +1314,7 @@ static int radeon_do_resume_cp(struct drm_device * dev)
}
radeon_cp_load_microcode(dev_priv);
- radeon_cp_init_ring_buffer(dev, dev_priv);
+ radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
radeon_do_engine_reset(dev);
radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
@@ -1479,8 +1489,7 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri
*/
int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
-
- return radeon_do_resume_cp(dev);
+ return radeon_do_resume_cp(dev, file_priv);
}
int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e85c8fe9ffcf..97183066a27b 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -29,11 +29,11 @@ config HID
For docs and specs, see http://www.usb.org/developers/hidpage/
- If unsure, say Y
+ If unsure, say Y.
config HID_DEBUG
bool "HID debugging support"
- default y if !EMBEDDED
+ default y
depends on HID
---help---
This option lets the HID layer output diagnostics about its internal
@@ -44,7 +44,7 @@ config HID_DEBUG
This feature is useful for those who are either debugging the HID parser
or any HID hardware device.
- If unsure, say N
+ If unsure, say Y.
config HIDRAW
bool "/dev/hidraw raw HID device support"
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5d7640e49dc5..feaeb6167ea4 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1218,6 +1218,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
}
EXPORT_SYMBOL_GPL(hid_connect);
+/* a list of devices for which there is a specialized driver on HID bus */
static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
@@ -1299,7 +1300,13 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
@@ -1476,6 +1483,7 @@ static struct bus_type hid_bus_type = {
.uevent = hid_uevent,
};
+/* a list of devices that shouldn't be handled by HID core at all */
static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) },
@@ -1603,15 +1611,14 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
- { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
@@ -1622,8 +1629,6 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
{ HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
{ }
};
@@ -1817,6 +1822,22 @@ static DECLARE_WORK(hid_compat_work, hid_compat_load);
static struct workqueue_struct *hid_compat_wq;
#endif
+int hid_check_keys_pressed(struct hid_device *hid)
+{
+ struct hid_input *hidinput;
+ int i;
+
+ list_for_each_entry(hidinput, &hid->inputs, list) {
+ for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
+ if (hidinput->input->key[i])
+ return 1;
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
+
static int __init hid_init(void)
{
int ret;
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index acc1abc834a4..88511970508d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -348,6 +348,9 @@
#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
+#define USB_VENDOR_ID_POWERCOM 0x0d9f
+#define USB_DEVICE_ID_POWERCOM_UPS 0x0002
+
#define USB_VENDOR_ID_SAITEK 0x06a3
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
@@ -362,6 +365,8 @@
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4 0x0044
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5 0x0045
#define USB_VENDOR_ID_SUN 0x0430
#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index d718b1607d0f..25b10dcad90d 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -30,7 +30,7 @@
#define MS_NOGET 0x10
/*
- * Microsoft Wireless Desktop Receiver (Model 1028) has several
+ * Microsoft Wireless Desktop Receiver (Model 1028) has
* 'Usage Min/Max' where it ought to have 'Physical Min/Max'
*/
static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -38,17 +38,12 @@ static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
{
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
- if ((quirks & MS_RDESC) && rsize == 571 && rdesc[284] == 0x19 &&
- rdesc[286] == 0x2a && rdesc[304] == 0x19 &&
- rdesc[306] == 0x29 && rdesc[352] == 0x1a &&
- rdesc[355] == 0x2a && rdesc[557] == 0x19 &&
+ if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 &&
rdesc[559] == 0x29) {
dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver "
"Model 1028 report descriptor\n");
- rdesc[284] = rdesc[304] = rdesc[557] = 0x35;
- rdesc[352] = 0x36;
- rdesc[286] = rdesc[355] = 0x46;
- rdesc[306] = rdesc[559] = 0x45;
+ rdesc[557] = 0x35;
+ rdesc[559] = 0x45;
}
}
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 732449628971..e263d4731179 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *inode, struct file *file)
dev = hidraw_table[minor];
if (!dev->open++) {
+ if (dev->hid->ll_driver->power) {
+ err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
+ if (err < 0)
+ goto out_unlock;
+ }
err = dev->hid->ll_driver->open(dev->hid);
- if (err < 0)
+ if (err < 0) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->open--;
+ }
}
out_unlock:
@@ -209,10 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
list_del(&list->node);
dev = hidraw_table[minor];
if (!--dev->open) {
- if (list->hidraw->exist)
+ if (list->hidraw->exist) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->hid->ll_driver->close(dev->hid);
- else
+ } else {
kfree(list->hidraw);
+ }
}
kfree(list);
@@ -267,8 +278,10 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
default:
{
struct hid_device *hid = dev->hid;
- if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
- return -EINVAL;
+ if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) {
+ ret = -EINVAL;
+ break;
+ }
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
int len;
@@ -277,8 +290,9 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
len = strlen(hid->name) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->name, len) ?
+ ret = copy_to_user(user_arg, hid->name, len) ?
-EFAULT : len;
+ break;
}
if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
@@ -288,12 +302,13 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
len = strlen(hid->phys) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->phys, len) ?
+ ret = copy_to_user(user_arg, hid->phys, len) ?
-EFAULT : len;
+ break;
}
}
- ret = -ENOTTY;
+ ret = -ENOTTY;
}
unlock_kernel();
return ret;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index f0a0f72238ab..bc017cd03b85 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -5,6 +5,7 @@
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
* Copyright (c) 2006-2008 Jiri Kosina
+ * Copyright (c) 2007-2008 Oliver Neukum
*/
/*
@@ -27,6 +28,7 @@
#include <asm/byteorder.h>
#include <linux/input.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <linux/usb.h>
@@ -53,6 +55,10 @@ static unsigned int hid_mousepoll_interval;
module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
+static unsigned int ignoreled;
+module_param_named(ignoreled, ignoreled, uint, 0644);
+MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
+
/* Quirks specified at module load time */
static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
@@ -63,8 +69,13 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
/*
* Input submission and I/O error handler.
*/
+static DEFINE_MUTEX(hid_open_mut);
+static struct workqueue_struct *resumption_waker;
static void hid_io_error(struct hid_device *hid);
+static int hid_submit_out(struct hid_device *hid);
+static int hid_submit_ctrl(struct hid_device *hid);
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
/* Start up the input URB */
static int hid_start_in(struct hid_device *hid)
@@ -73,15 +84,16 @@ static int hid_start_in(struct hid_device *hid)
int rc = 0;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
- if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
+ spin_lock_irqsave(&usbhid->lock, flags);
+ if (hid->open > 0 &&
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
+ !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
if (rc != 0)
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
}
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return rc;
}
@@ -145,7 +157,7 @@ static void hid_io_error(struct hid_device *hid)
unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
/* Stop when disconnected */
if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
@@ -175,7 +187,51 @@ static void hid_io_error(struct hid_device *hid)
mod_timer(&usbhid->io_retry,
jiffies + msecs_to_jiffies(usbhid->retry_delay));
done:
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+}
+
+static void usbhid_mark_busy(struct usbhid_device *usbhid)
+{
+ struct usb_interface *intf = usbhid->intf;
+
+ usb_mark_last_busy(interface_to_usbdev(intf));
+}
+
+static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->outhead != usbhid->outtail))) {
+ dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
+ if (hid_submit_out(hid)) {
+ clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
+}
+
+static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ WARN_ON(hid == NULL);
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
+ dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
+ if (hid_submit_ctrl(hid)) {
+ clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
}
/*
@@ -190,12 +246,23 @@ static void hid_irq_in(struct urb *urb)
switch (urb->status) {
case 0: /* success */
+ usbhid_mark_busy(usbhid);
usbhid->retry_delay = 0;
hid_input_report(urb->context, HID_INPUT_REPORT,
urb->transfer_buffer,
urb->actual_length, 1);
+ /*
+ * autosuspend refused while keys are pressed
+ * because most keyboards don't wake up when
+ * a key is released
+ */
+ if (hid_check_keys_pressed(hid))
+ set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
+ else
+ clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
break;
case -EPIPE: /* stall */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
set_bit(HID_CLEAR_HALT, &usbhid->iofl);
schedule_work(&usbhid->reset_work);
@@ -209,6 +276,7 @@ static void hid_irq_in(struct urb *urb)
case -EPROTO: /* protocol error or unplug */
case -ETIME: /* protocol error or unplug */
case -ETIMEDOUT: /* Should never happen, but... */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
hid_io_error(hid);
return;
@@ -239,16 +307,25 @@ static int hid_submit_out(struct hid_device *hid)
report = usbhid->out[usbhid->outtail].report;
raw_report = usbhid->out[usbhid->outtail].raw_report;
- usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- usbhid->urbout->dev = hid_to_usb_dev(hid);
- memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
- kfree(raw_report);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ usbhid->urbout->dev = hid_to_usb_dev(hid);
+ memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
+ kfree(raw_report);
- dbg_hid("submitting out urb\n");
+ dbg_hid("submitting out urb\n");
- if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(out) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(out) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -266,41 +343,50 @@ static int hid_submit_ctrl(struct hid_device *hid)
raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
dir = usbhid->ctrl[usbhid->ctrltail].dir;
- len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- if (dir == USB_DIR_OUT) {
- usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
- usbhid->urbctrl->transfer_buffer_length = len;
- memcpy(usbhid->ctrlbuf, raw_report, len);
- kfree(raw_report);
- } else {
- int maxpacket, padlen;
-
- usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
- maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
- if (maxpacket > 0) {
- padlen = DIV_ROUND_UP(len, maxpacket);
- padlen *= maxpacket;
- if (padlen > usbhid->bufsize)
- padlen = usbhid->bufsize;
- } else
- padlen = 0;
- usbhid->urbctrl->transfer_buffer_length = padlen;
- }
- usbhid->urbctrl->dev = hid_to_usb_dev(hid);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ if (dir == USB_DIR_OUT) {
+ usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
+ usbhid->urbctrl->transfer_buffer_length = len;
+ memcpy(usbhid->ctrlbuf, raw_report, len);
+ kfree(raw_report);
+ } else {
+ int maxpacket, padlen;
+
+ usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
+ maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
+ if (maxpacket > 0) {
+ padlen = DIV_ROUND_UP(len, maxpacket);
+ padlen *= maxpacket;
+ if (padlen > usbhid->bufsize)
+ padlen = usbhid->bufsize;
+ } else
+ padlen = 0;
+ usbhid->urbctrl->transfer_buffer_length = padlen;
+ }
+ usbhid->urbctrl->dev = hid_to_usb_dev(hid);
- usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
- usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
- usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
- usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
- usbhid->cr->wLength = cpu_to_le16(len);
+ usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+ usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+ usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
+ usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
+ usbhid->cr->wLength = cpu_to_le16(len);
- dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
- usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
- usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
+ dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
+ usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
+ usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
- if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(ctrl) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(ctrl) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -332,7 +418,7 @@ static void hid_irq_out(struct urb *urb)
"received\n", urb->status);
}
- spin_lock_irqsave(&usbhid->outlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
if (unplug)
usbhid->outtail = usbhid->outhead;
@@ -344,12 +430,12 @@ static void hid_irq_out(struct urb *urb)
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return;
}
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
wake_up(&usbhid->wait);
}
@@ -361,12 +447,11 @@ static void hid_ctrl(struct urb *urb)
{
struct hid_device *hid = urb->context;
struct usbhid_device *usbhid = hid->driver_data;
- unsigned long flags;
- int unplug = 0;
+ int unplug = 0, status = urb->status;
- spin_lock_irqsave(&usbhid->ctrllock, flags);
+ spin_lock(&usbhid->lock);
- switch (urb->status) {
+ switch (status) {
case 0: /* success */
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
hid_input_report(urb->context,
@@ -383,7 +468,7 @@ static void hid_ctrl(struct urb *urb)
break;
default: /* error */
dev_warn(&urb->dev->dev, "ctrl urb status %d "
- "received\n", urb->status);
+ "received\n", status);
}
if (unplug)
@@ -396,19 +481,18 @@ static void hid_ctrl(struct urb *urb)
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
return;
}
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
wake_up(&usbhid->wait);
}
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
{
int head;
- unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
@@ -416,18 +500,13 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
return;
if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
-
- spin_lock_irqsave(&usbhid->outlock, flags);
-
if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queue full\n");
return;
}
usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->out[usbhid->outhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queueing failed\n");
return;
}
@@ -438,15 +517,10 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
if (hid_submit_out(hid))
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-
- spin_unlock_irqrestore(&usbhid->outlock, flags);
return;
}
- spin_lock_irqsave(&usbhid->ctrllock, flags);
-
if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queue full\n");
return;
}
@@ -454,7 +528,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (dir == USB_DIR_OUT) {
usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queueing failed\n");
return;
}
@@ -467,15 +540,25 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
if (hid_submit_ctrl(hid))
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+}
+
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+ unsigned long flags;
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
+ __usbhid_submit_report(hid, report, dir);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
}
EXPORT_SYMBOL_GPL(usbhid_submit_report);
static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct hid_device *hid = input_get_drvdata(dev);
+ struct usbhid_device *usbhid = hid->driver_data;
struct hid_field *field;
+ unsigned long flags;
int offset;
if (type == EV_FF)
@@ -490,6 +573,15 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un
}
hid_set_field(field, offset, value);
+ if (value) {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount++;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ } else {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount--;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ }
usbhid_submit_report(hid, field->report, USB_DIR_OUT);
return 0;
@@ -538,15 +630,22 @@ int usbhid_open(struct hid_device *hid)
struct usbhid_device *usbhid = hid->driver_data;
int res;
+ mutex_lock(&hid_open_mut);
if (!hid->open++) {
res = usb_autopm_get_interface(usbhid->intf);
+ /* the device must be awake to reliable request remote wakeup */
if (res < 0) {
hid->open--;
+ mutex_unlock(&hid_open_mut);
return -EIO;
}
+ usbhid->intf->needs_remote_wakeup = 1;
+ if (hid_start_in(hid))
+ hid_io_error(hid);
+
+ usb_autopm_put_interface(usbhid->intf);
}
- if (hid_start_in(hid))
- hid_io_error(hid);
+ mutex_unlock(&hid_open_mut);
return 0;
}
@@ -554,10 +653,22 @@ void usbhid_close(struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
+ mutex_lock(&hid_open_mut);
+
+ /* protecting hid->open to make sure we don't restart
+ * data acquistion due to a resumption we no longer
+ * care about
+ */
+ spin_lock_irq(&usbhid->lock);
if (!--hid->open) {
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
- usb_autopm_put_interface(usbhid->intf);
+ flush_scheduled_work();
+ usbhid->intf->needs_remote_wakeup = 0;
+ } else {
+ spin_unlock_irq(&usbhid->lock);
}
+ mutex_unlock(&hid_open_mut);
}
/*
@@ -687,6 +798,25 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
return ret;
}
+static void usbhid_restart_queues(struct usbhid_device *usbhid)
+{
+ if (usbhid->urbout)
+ usbhid_restart_out_queue(usbhid);
+ usbhid_restart_ctrl_queue(usbhid);
+}
+
+static void __usbhid_restart_queues(struct work_struct *work)
+{
+ struct usbhid_device *usbhid =
+ container_of(work, struct usbhid_device, restart_work);
+ int r;
+
+ r = usb_autopm_get_interface(usbhid->intf);
+ if (r < 0)
+ return;
+ usb_autopm_put_interface(usbhid->intf);
+}
+
static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
@@ -711,6 +841,9 @@ static int usbhid_parse(struct hid_device *hid)
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
+ if (quirks & HID_QUIRK_IGNORE)
+ return -ENODEV;
+
/* Many keyboards and mice don't like to be polled for reports,
* so we will always set the HID_QUIRK_NOGET flag for them. */
if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
@@ -850,11 +983,11 @@ static int usbhid_start(struct hid_device *hid)
init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset);
+ INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
- spin_lock_init(&usbhid->inlock);
- spin_lock_init(&usbhid->outlock);
- spin_lock_init(&usbhid->ctrllock);
+ spin_lock_init(&usbhid->lock);
+ spin_lock_init(&usbhid->lock);
usbhid->intf = intf;
usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -906,15 +1039,14 @@ static void usbhid_stop(struct hid_device *hid)
return;
clear_bit(HID_STARTED, &usbhid->iofl);
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
set_bit(HID_DISCONNECTED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
usb_kill_urb(usbhid->urbout);
usb_kill_urb(usbhid->urbctrl);
- del_timer_sync(&usbhid->io_retry);
- cancel_work_sync(&usbhid->reset_work);
+ hid_cancel_delayed_stuff(usbhid);
if (hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hid);
@@ -935,12 +1067,28 @@ static void usbhid_stop(struct hid_device *hid)
hid_free_buffers(hid_to_usb_dev(hid), hid);
}
+static int usbhid_power(struct hid_device *hid, int lvl)
+{
+ int r = 0;
+
+ switch (lvl) {
+ case PM_HINT_FULLON:
+ r = usbhid_get_power(hid);
+ break;
+ case PM_HINT_NORMAL:
+ usbhid_put_power(hid);
+ break;
+ }
+ return r;
+}
+
static struct hid_ll_driver usb_hid_driver = {
.parse = usbhid_parse,
.start = usbhid_start,
.stop = usbhid_stop,
.open = usbhid_open,
.close = usbhid_close,
+ .power = usbhid_power,
.hidinput_input_event = usb_hidinput_input_event,
};
@@ -1049,19 +1197,126 @@ static void hid_disconnect(struct usb_interface *intf)
kfree(usbhid);
}
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
+{
+ del_timer_sync(&usbhid->io_retry);
+ cancel_work_sync(&usbhid->restart_work);
+ cancel_work_sync(&usbhid->reset_work);
+}
+
+static void hid_cease_io(struct usbhid_device *usbhid)
+{
+ del_timer(&usbhid->io_retry);
+ usb_kill_urb(usbhid->urbin);
+ usb_kill_urb(usbhid->urbctrl);
+ usb_kill_urb(usbhid->urbout);
+ flush_scheduled_work();
+}
+
+/* Treat USB reset pretty much the same as suspend/resume */
+static int hid_pre_reset(struct usb_interface *intf)
+{
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ hid_cease_io(usbhid);
+
+ return 0;
+}
+
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+ int status;
+
+ spin_lock_irq(&usbhid->lock);
+ clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
+ /* FIXME: Any more reinitialization needed? */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
+
+ return 0;
+}
+
+int usbhid_get_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ return usb_autopm_get_interface(usbhid->intf);
+}
+
+void usbhid_put_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ usb_autopm_put_interface(usbhid->intf);
+}
+
+
+#ifdef CONFIG_PM
static int hid_suspend(struct usb_interface *intf, pm_message_t message)
{
- struct hid_device *hid = usb_get_intfdata (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
struct usbhid_device *usbhid = hid->driver_data;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ int status;
- if (!test_bit(HID_STARTED, &usbhid->iofl))
- return 0;
+ if (udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
+ if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
+ && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
+ && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
+ && (!usbhid->ledcount || ignoreled))
+ {
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ } else {
+ usbhid_mark_busy(usbhid);
+ spin_unlock_irq(&usbhid->lock);
+ return -EBUSY;
+ }
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
- set_bit(HID_SUSPENDED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
- del_timer_sync(&usbhid->io_retry);
- usb_kill_urb(usbhid->urbin);
+ } else {
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ if (usbhid_wait_io(hid) < 0)
+ return -EIO;
+ }
+
+ if (!ignoreled && udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock);
+ if (test_bit(HID_LED_ON, &usbhid->iofl)) {
+ spin_unlock_irq(&usbhid->lock);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
+ spin_unlock_irq(&usbhid->lock);
+ }
+
+ hid_cancel_delayed_stuff(usbhid);
+ hid_cease_io(usbhid);
+
+ if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+ /* lost race against keypresses */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
dev_dbg(&intf->dev, "suspend\n");
return 0;
}
@@ -1075,32 +1330,33 @@ static int hid_resume(struct usb_interface *intf)
if (!test_bit(HID_STARTED, &usbhid->iofl))
return 0;
- clear_bit(HID_SUSPENDED, &usbhid->iofl);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ usbhid_mark_busy(usbhid);
+
+ if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
+ test_bit(HID_RESET_PENDING, &usbhid->iofl))
+ schedule_work(&usbhid->reset_work);
usbhid->retry_delay = 0;
status = hid_start_in(hid);
- dev_dbg(&intf->dev, "resume status %d\n", status);
- return status;
-}
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
- /* FIXME: What if the interface is already suspended? */
- hid_suspend(intf, PMSG_ON);
+ dev_dbg(&intf->dev, "resume status %d\n", status);
return 0;
}
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
+static int hid_reset_resume(struct usb_interface *intf)
{
- struct usb_device *dev = interface_to_usbdev (intf);
-
- hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
- /* FIXME: Any more reinitialization needed? */
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
- return hid_resume(intf);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ return hid_post_reset(intf);
}
+#endif /* CONFIG_PM */
+
static struct usb_device_id hid_usb_ids [] = {
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
.bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -1113,9 +1369,11 @@ static struct usb_driver hid_driver = {
.name = "usbhid",
.probe = hid_probe,
.disconnect = hid_disconnect,
+#ifdef CONFIG_PM
.suspend = hid_suspend,
.resume = hid_resume,
- .reset_resume = hid_post_reset,
+ .reset_resume = hid_reset_resume,
+#endif
.pre_reset = hid_pre_reset,
.post_reset = hid_post_reset,
.id_table = hid_usb_ids,
@@ -1134,7 +1392,11 @@ static struct hid_driver hid_usb_driver = {
static int __init hid_init(void)
{
- int retval;
+ int retval = -ENOMEM;
+
+ resumption_waker = create_freezeable_workqueue("usbhid_resumer");
+ if (!resumption_waker)
+ goto no_queue;
retval = hid_register_driver(&hid_usb_driver);
if (retval)
goto hid_register_fail;
@@ -1158,6 +1420,8 @@ hiddev_init_fail:
usbhid_quirks_init_fail:
hid_unregister_driver(&hid_usb_driver);
hid_register_fail:
+ destroy_workqueue(resumption_waker);
+no_queue:
return retval;
}
@@ -1167,6 +1431,7 @@ static void __exit hid_exit(void)
hiddev_exit();
usbhid_quirks_exit();
hid_unregister_driver(&hid_usb_driver);
+ destroy_workqueue(resumption_waker);
}
module_init(hid_init);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index d73eea382ab3..7da275cdb08d 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -249,10 +249,12 @@ static int hiddev_release(struct inode * inode, struct file * file)
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
if (!--list->hiddev->open) {
- if (list->hiddev->exist)
+ if (list->hiddev->exist) {
usbhid_close(list->hiddev->hid);
- else
+ usbhid_put_power(list->hiddev->hid);
+ } else {
kfree(list->hiddev);
+ }
}
kfree(list);
@@ -303,6 +305,17 @@ static int hiddev_open(struct inode *inode, struct file *file)
list_add_tail(&list->node, &hiddev_table[i]->list);
spin_unlock_irq(&list->hiddev->list_lock);
+ if (!list->hiddev->open++)
+ if (list->hiddev->exist) {
+ struct hid_device *hid = hiddev_table[i]->hid;
+ res = usbhid_get_power(hid);
+ if (res < 0) {
+ res = -EIO;
+ goto bail;
+ }
+ usbhid_open(hid);
+ }
+
return 0;
bail:
file->private_data = NULL;
@@ -656,7 +669,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case HIDIOCGSTRING:
mutex_lock(&hiddev->existancelock);
- if (!hiddev->exist)
+ if (hiddev->exist)
r = hiddev_ioctl_string(hiddev, cmd, user_arg);
else
r = -ENODEV;
@@ -878,16 +891,21 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
hiddev->hid = hid;
hiddev->exist = 1;
+ /* when lock_kernel() usage is fixed in usb_open(),
+ * we could also fix it here */
+ lock_kernel();
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
err_hid("Not able to get a minor for this device.");
hid->hiddev = NULL;
+ unlock_kernel();
kfree(hiddev);
return -1;
} else {
hid->minor = usbhid->intf->minor;
hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 9eb30564be9c..08f505ca2e3d 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hid);
void usbhid_close(struct hid_device *hid);
int usbhid_open(struct hid_device *hid);
void usbhid_init_reports(struct hid_device *hid);
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+void usbhid_submit_report
+(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+int usbhid_get_power(struct hid_device *hid);
+void usbhid_put_power(struct hid_device *hid);
/* iofl flags */
#define HID_CTRL_RUNNING 1
@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
#define HID_CLEAR_HALT 6
#define HID_DISCONNECTED 7
#define HID_STARTED 8
+#define HID_REPORTED_IDLE 9
+#define HID_KEYS_PRESSED 10
+#define HID_LED_ON 11
/*
* USB-specific HID struct, to be pointed to
@@ -66,7 +72,6 @@ struct usbhid_device {
struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */
- spinlock_t inlock; /* Input fifo spinlock */
struct urb *urbctrl; /* Control URB */
struct usb_ctrlrequest *cr; /* Control request struct */
@@ -75,21 +80,22 @@ struct usbhid_device {
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char *ctrlbuf; /* Control buffer */
dma_addr_t ctrlbuf_dma; /* Control buffer dma */
- spinlock_t ctrllock; /* Control fifo spinlock */
struct urb *urbout; /* Output URB */
struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
unsigned char outhead, outtail; /* Output pipe fifo head & tail */
char *outbuf; /* Output buffer */
dma_addr_t outbuf_dma; /* Output buffer dma */
- spinlock_t outlock; /* Output fifo spinlock */
+ spinlock_t lock; /* fifo spinlock */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct timer_list io_retry; /* Retry timer */
unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */
+ struct work_struct restart_work; /* waking up for output to be done in a task */
wait_queue_head_t wait; /* For sleeping */
+ int ledcount; /* counting the number of active leds */
};
#define hid_to_usb_dev(hid_dev) \
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index e52b38806d03..ad2b3431b725 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -760,8 +760,11 @@ static int abituguru3_read_increment_offset(struct abituguru3_data *data,
for (i = 0; i < offset_count; i++)
if ((x = abituguru3_read(data, bank, offset + i, count,
- buf + i * count)) != count)
- return i * count + (i && (x < 0)) ? 0 : x;
+ buf + i * count)) != count) {
+ if (x < 0)
+ return x;
+ return i * count + x;
+ }
return i * count;
}
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index e30186236588..678e34b01e52 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -83,7 +83,7 @@
/*
* Temperature sensors keys (sp78 - 2 bytes).
*/
-static const char* temperature_sensors_sets[][36] = {
+static const char *temperature_sensors_sets[][41] = {
/* Set 0: Macbook Pro */
{ "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
"Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
@@ -135,6 +135,13 @@ static const char* temperature_sensors_sets[][36] = {
{ "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0",
"TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P",
"Ts0S", NULL },
+/* Set 16: Mac Pro 3,1 (2 x Quad-Core) */
+ { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
+ "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P",
+ "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P",
+ "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
+ "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
+ NULL },
};
/* List of keys used to read/write fan speeds */
@@ -1153,6 +1160,16 @@ static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
applesmc_show_temperature, NULL, 33);
static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
applesmc_show_temperature, NULL, 34);
+static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 35);
+static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 36);
+static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 37);
+static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 38);
+static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 39);
static struct attribute *temperature_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -1190,6 +1207,11 @@ static struct attribute *temperature_attributes[] = {
&sensor_dev_attr_temp33_input.dev_attr.attr,
&sensor_dev_attr_temp34_input.dev_attr.attr,
&sensor_dev_attr_temp35_input.dev_attr.attr,
+ &sensor_dev_attr_temp36_input.dev_attr.attr,
+ &sensor_dev_attr_temp37_input.dev_attr.attr,
+ &sensor_dev_attr_temp38_input.dev_attr.attr,
+ &sensor_dev_attr_temp39_input.dev_attr.attr,
+ &sensor_dev_attr_temp40_input.dev_attr.attr,
NULL
};
@@ -1312,6 +1334,8 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
{ .accelerometer = 0, .light = 0, .temperature_set = 14 },
/* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */
{ .accelerometer = 1, .light = 1, .temperature_set = 15 },
+/* MacPro3,1: temperature set 16 */
+ { .accelerometer = 0, .light = 0, .temperature_set = 16 },
};
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1369,6 +1393,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
&applesmc_dmi_data[4]},
+ { applesmc_dmi_match, "Apple MacPro3", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacPro3") },
+ &applesmc_dmi_data[16]},
{ applesmc_dmi_match, "Apple MacPro", {
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 7415381601c3..53f88f511816 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -81,71 +81,84 @@ struct ds1621_data {
u8 conf; /* Register encoding, combined */
};
-static int ds1621_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int ds1621_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info);
-static void ds1621_init_client(struct i2c_client *client);
-static int ds1621_remove(struct i2c_client *client);
-static struct ds1621_data *ds1621_update_client(struct device *dev);
-
-static const struct i2c_device_id ds1621_id[] = {
- { "ds1621", ds1621 },
- { "ds1625", ds1621 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ds1621_id);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver ds1621_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "ds1621",
- },
- .probe = ds1621_probe,
- .remove = ds1621_remove,
- .id_table = ds1621_id,
- .detect = ds1621_detect,
- .address_data = &addr_data,
-};
-
-/* All registers are word-sized, except for the configuration register.
+/* Temperature registers are word-sized.
DS1621 uses a high-byte first convention, which is exactly opposite to
the SMBus standard. */
-static int ds1621_read_value(struct i2c_client *client, u8 reg)
+static int ds1621_read_temp(struct i2c_client *client, u8 reg)
{
- if (reg == DS1621_REG_CONF)
- return i2c_smbus_read_byte_data(client, reg);
- else
- return swab16(i2c_smbus_read_word_data(client, reg));
+ int ret;
+
+ ret = i2c_smbus_read_word_data(client, reg);
+ if (ret < 0)
+ return ret;
+ return swab16(ret);
}
-static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
+static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value)
{
- if (reg == DS1621_REG_CONF)
- return i2c_smbus_write_byte_data(client, reg, value);
- else
- return i2c_smbus_write_word_data(client, reg, swab16(value));
+ return i2c_smbus_write_word_data(client, reg, swab16(value));
}
static void ds1621_init_client(struct i2c_client *client)
{
- int reg = ds1621_read_value(client, DS1621_REG_CONF);
+ u8 conf, new_conf;
+
+ new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
/* switch to continuous conversion mode */
- reg &= ~ DS1621_REG_CONFIG_1SHOT;
+ new_conf &= ~DS1621_REG_CONFIG_1SHOT;
/* setup output polarity */
if (polarity == 0)
- reg &= ~DS1621_REG_CONFIG_POLARITY;
+ new_conf &= ~DS1621_REG_CONFIG_POLARITY;
else if (polarity == 1)
- reg |= DS1621_REG_CONFIG_POLARITY;
+ new_conf |= DS1621_REG_CONFIG_POLARITY;
- ds1621_write_value(client, DS1621_REG_CONF, reg);
+ if (conf != new_conf)
+ i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf);
/* start conversion */
i2c_smbus_write_byte(client, DS1621_COM_START);
}
+static struct ds1621_data *ds1621_update_client(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1621_data *data = i2c_get_clientdata(client);
+ u8 new_conf;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i;
+
+ dev_dbg(&client->dev, "Starting ds1621 update\n");
+
+ data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+
+ for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+ data->temp[i] = ds1621_read_temp(client,
+ DS1621_REG_TEMP[i]);
+
+ /* reset alarms if necessary */
+ new_conf = data->conf;
+ if (data->temp[0] > data->temp[1]) /* input > min */
+ new_conf &= ~DS1621_ALARM_TEMP_LOW;
+ if (data->temp[0] < data->temp[2]) /* input < max */
+ new_conf &= ~DS1621_ALARM_TEMP_HIGH;
+ if (data->conf != new_conf)
+ i2c_smbus_write_byte_data(client, DS1621_REG_CONF,
+ new_conf);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
char *buf)
{
@@ -160,13 +173,13 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
- struct ds1621_data *data = ds1621_update_client(dev);
+ struct ds1621_data *data = i2c_get_clientdata(client);
u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10));
mutex_lock(&data->update_lock);
data->temp[attr->index] = val;
- ds1621_write_value(client, DS1621_REG_TEMP[attr->index],
- data->temp[attr->index]);
+ ds1621_write_temp(client, DS1621_REG_TEMP[attr->index],
+ data->temp[attr->index]);
mutex_unlock(&data->update_lock);
return count;
}
@@ -228,13 +241,14 @@ static int ds1621_detect(struct i2c_client *client, int kind,
/* The NVB bit should be low if no EEPROM write has been
requested during the latest 10ms, which is highly
improbable in our case. */
- conf = ds1621_read_value(client, DS1621_REG_CONF);
- if (conf & DS1621_REG_CONFIG_NVB)
+ conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+ if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
return -ENODEV;
/* The 7 lowest bits of a temperature should always be 0. */
for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
- temp = ds1621_read_value(client, DS1621_REG_TEMP[i]);
- if (temp & 0x007f)
+ temp = i2c_smbus_read_word_data(client,
+ DS1621_REG_TEMP[i]);
+ if (temp < 0 || (temp & 0x7f00))
return -ENODEV;
}
}
@@ -294,45 +308,25 @@ static int ds1621_remove(struct i2c_client *client)
return 0;
}
+static const struct i2c_device_id ds1621_id[] = {
+ { "ds1621", ds1621 },
+ { "ds1625", ds1621 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ds1621_id);
-static struct ds1621_data *ds1621_update_client(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct ds1621_data *data = i2c_get_clientdata(client);
- u8 new_conf;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
- int i;
-
- dev_dbg(&client->dev, "Starting ds1621 update\n");
-
- data->conf = ds1621_read_value(client, DS1621_REG_CONF);
-
- for (i = 0; i < ARRAY_SIZE(data->temp); i++)
- data->temp[i] = ds1621_read_value(client,
- DS1621_REG_TEMP[i]);
-
- /* reset alarms if necessary */
- new_conf = data->conf;
- if (data->temp[0] > data->temp[1]) /* input > min */
- new_conf &= ~DS1621_ALARM_TEMP_LOW;
- if (data->temp[0] < data->temp[2]) /* input < max */
- new_conf &= ~DS1621_ALARM_TEMP_HIGH;
- if (data->conf != new_conf)
- ds1621_write_value(client, DS1621_REG_CONF,
- new_conf);
-
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- mutex_unlock(&data->update_lock);
-
- return data;
-}
+/* This is the driver that will be inserted */
+static struct i2c_driver ds1621_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ds1621",
+ },
+ .probe = ds1621_probe,
+ .remove = ds1621_remove,
+ .id_table = ds1621_id,
+ .detect = ds1621_detect,
+ .address_data = &addr_data,
+};
static int __init ds1621_init(void)
{
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 609cafff86bc..5f81ddf71508 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -1872,7 +1872,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
devid = superio_inw(sioaddr, SIO_REG_MANID);
if (devid != SIO_FINTEK_ID) {
- printk(KERN_INFO DRVNAME ": Not a Fintek device\n");
+ pr_debug(DRVNAME ": Not a Fintek device\n");
goto exit;
}
@@ -1932,7 +1932,7 @@ static int __init f71882fg_device_add(unsigned short address,
res.name = f71882fg_pdev->name;
err = acpi_check_resource_conflict(&res);
if (err)
- return err;
+ goto exit_device_put;
err = platform_device_add_resources(f71882fg_pdev, &res, 1);
if (err) {
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index a4d92d246d52..d3612a1f1981 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -65,6 +65,10 @@
#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
#define HDAPS_INPUT_FLAT 4
+#define HDAPS_X_AXIS (1 << 0)
+#define HDAPS_Y_AXIS (1 << 1)
+#define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS)
+
static struct platform_device *pdev;
static struct input_polled_dev *hdaps_idev;
static unsigned int hdaps_invert;
@@ -182,11 +186,11 @@ static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
km_activity = inb(HDAPS_PORT_KMACT);
__device_complete();
- /* if hdaps_invert is set, negate the two values */
- if (hdaps_invert) {
+ /* hdaps_invert is a bitvector to negate the axes */
+ if (hdaps_invert & HDAPS_X_AXIS)
*x = -*x;
+ if (hdaps_invert & HDAPS_Y_AXIS)
*y = -*y;
- }
return 0;
}
@@ -436,7 +440,8 @@ static ssize_t hdaps_invert_store(struct device *dev,
{
int invert;
- if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0))
+ if (sscanf(buf, "%d", &invert) != 1 ||
+ invert < 0 || invert > HDAPS_BOTH_AXES)
return -EINVAL;
hdaps_invert = invert;
@@ -483,56 +488,52 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id)
/* hdaps_dmi_match_invert - found an inverted match. */
static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
{
- hdaps_invert = 1;
- printk(KERN_INFO "hdaps: inverting axis readings.\n");
+ hdaps_invert = (unsigned long)id->driver_data;
+ printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n",
+ hdaps_invert);
return hdaps_dmi_match(id);
}
-#define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \
- .ident = vendor " " model, \
- .callback = hdaps_dmi_match, \
- .matches = { \
- DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
- DMI_MATCH(DMI_PRODUCT_VERSION, model) \
- } \
-}
-
-#define HDAPS_DMI_MATCH_INVERT(vendor, model) { \
+#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) { \
.ident = vendor " " model, \
.callback = hdaps_dmi_match_invert, \
+ .driver_data = (void *)axes, \
.matches = { \
DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
} \
}
+#define HDAPS_DMI_MATCH_NORMAL(vendor, model) \
+ HDAPS_DMI_MATCH_INVERT(vendor, model, 0)
+
/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
"ThinkPad T42p", so the order of the entries matters.
If your ThinkPad is not recognized, please update to latest
BIOS. This is especially the case for some R52 ThinkPads. */
static struct dmi_system_id __initdata hdaps_whitelist[] = {
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"),
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
- HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X41", HDAPS_Y_AXIS),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES),
{ .ident = NULL }
};
@@ -627,8 +628,9 @@ static void __exit hdaps_exit(void)
module_init(hdaps_init);
module_exit(hdaps_exit);
-module_param_named(invert, hdaps_invert, bool, 0);
-MODULE_PARM_DESC(invert, "invert data along each axis");
+module_param_named(invert, hdaps_invert, int, 0);
+MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, "
+ "2 invert y-axis, 3 invert both axes.");
MODULE_AUTHOR("Robert Love");
MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 03705240000f..29c83b5b9697 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -153,7 +153,10 @@ static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3};
static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3};
static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3};
static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3};
static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3};
+static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3};
#define AXIS_DMI_MATCH(_ident, _name, _axis) { \
.ident = _ident, \
@@ -163,6 +166,18 @@ static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3};
}, \
.driver_data = &lis3lv02d_axis_##_axis \
}
+
+#define AXIS_DMI_MATCH2(_ident, _class1, _name1, \
+ _class2, _name2, \
+ _axis) { \
+ .ident = _ident, \
+ .callback = lis3lv02d_dmi_matched, \
+ .matches = { \
+ DMI_MATCH(DMI_##_class1, _name1), \
+ DMI_MATCH(DMI_##_class2, _name2), \
+ }, \
+ .driver_data = &lis3lv02d_axis_##_axis \
+}
static struct dmi_system_id lis3lv02d_dmi_ids[] = {
/* product names are truncated to match all kinds of a same model */
AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted),
@@ -172,10 +187,22 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
+ AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
+ AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
+ AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
+ AXIS_DMI_MATCH("NC671xx", "HP Compaq 671", xy_swap_yz_inverted),
+ /* Intel-based HP Pavilion dv5 */
+ AXIS_DMI_MATCH2("HPDV5_I",
+ PRODUCT_NAME, "HP Pavilion dv5",
+ BOARD_NAME, "3603",
+ x_inverted),
+ /* AMD-based HP Pavilion dv5 */
+ AXIS_DMI_MATCH2("HPDV5_A",
+ PRODUCT_NAME, "HP Pavilion dv5",
+ BOARD_NAME, "3600",
+ y_inverted),
{ NULL, }
/* Laptop models without axis info (yet):
- * "NC651xx" "HP Compaq 651"
- * "NC671xx" "HP Compaq 671"
* "NC6910" "HP Compaq 6910"
* HP Compaq 8710x Notebook PC / Mobile Workstation
* "NC2400" "HP Compaq nc2400"
@@ -208,9 +235,49 @@ static struct delayed_led_classdev hpled_led = {
.set_brightness = hpled_set,
};
+static acpi_status
+lis3lv02d_get_resource(struct acpi_resource *resource, void *context)
+{
+ if (resource->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
+ struct acpi_resource_extended_irq *irq;
+ u32 *device_irq = context;
+
+ irq = &resource->data.extended_irq;
+ *device_irq = irq->interrupts[0];
+ }
+
+ return AE_OK;
+}
+
+static void lis3lv02d_enum_resources(struct acpi_device *device)
+{
+ acpi_status status;
+
+ status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+ lis3lv02d_get_resource, &adev.irq);
+ if (ACPI_FAILURE(status))
+ printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
+}
+
+static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
+{
+ u8 lo, hi;
+
+ adev.read(handle, reg - 1, &lo);
+ adev.read(handle, reg, &hi);
+ /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
+ return (s16)((hi << 8) | lo);
+}
+
+static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
+{
+ s8 lo;
+ adev.read(handle, reg, &lo);
+ return lo;
+}
+
static int lis3lv02d_add(struct acpi_device *device)
{
- u8 val;
int ret;
if (!device)
@@ -224,10 +291,22 @@ static int lis3lv02d_add(struct acpi_device *device)
strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
device->driver_data = &adev;
- lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val);
- if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) {
+ lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
+ switch (adev.whoami) {
+ case LIS_DOUBLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
+ adev.read_data = lis3lv02d_read_16;
+ adev.mdps_max_val = 2048;
+ break;
+ case LIS_SINGLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+ adev.read_data = lis3lv02d_read_8;
+ adev.mdps_max_val = 128;
+ break;
+ default:
printk(KERN_ERR DRIVER_NAME
- ": Accelerometer chip not LIS3LV02D{L,Q}\n");
+ ": unknown sensor type 0x%X\n", adev.whoami);
+ return -EINVAL;
}
/* If possible use a "standard" axes order */
@@ -242,6 +321,9 @@ static int lis3lv02d_add(struct acpi_device *device)
if (ret)
return ret;
+ /* obtain IRQ number of our device from ACPI */
+ lis3lv02d_enum_resources(adev.device);
+
ret = lis3lv02d_init_device(&adev);
if (ret) {
flush_work(&hpled_led.work);
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 219d2d0d5a62..8bb2158f0453 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2007-2008 Yan Burman
* Copyright (C) 2008 Eric Piel
- * Copyright (C) 2008 Pavel Machek
+ * Copyright (C) 2008-2009 Pavel Machek
*
* 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
@@ -35,6 +35,7 @@
#include <linux/poll.h>
#include <linux/freezer.h>
#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
#include <acpi/acpi_drivers.h>
#include <asm/atomic.h>
#include "lis3lv02d.h"
@@ -52,24 +53,14 @@
* joystick.
*/
-/* Maximum value our axis may get for the input device (signed 12 bits) */
-#define MDPS_MAX_VAL 2048
+struct acpi_lis3lv02d adev = {
+ .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
+};
-struct acpi_lis3lv02d adev;
EXPORT_SYMBOL_GPL(adev);
static int lis3lv02d_add_fs(struct acpi_device *device);
-static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
-{
- u8 lo, hi;
-
- adev.read(handle, reg, &lo);
- adev.read(handle, reg + 1, &hi);
- /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
- return (s16)((hi << 8) | lo);
-}
-
/**
* lis3lv02d_get_axis - For the given axis, give the value converted
* @axis: 1,2,3 - can also be negative
@@ -98,9 +89,9 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
{
int position[3];
- position[0] = lis3lv02d_read_16(handle, OUTX_L);
- position[1] = lis3lv02d_read_16(handle, OUTY_L);
- position[2] = lis3lv02d_read_16(handle, OUTZ_L);
+ position[0] = adev.read_data(handle, OUTX);
+ position[1] = adev.read_data(handle, OUTY);
+ position[2] = adev.read_data(handle, OUTZ);
*x = lis3lv02d_get_axis(adev.ac.x, position);
*y = lis3lv02d_get_axis(adev.ac.y, position);
@@ -110,26 +101,13 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
void lis3lv02d_poweroff(acpi_handle handle)
{
adev.is_on = 0;
- /* disable X,Y,Z axis and power down */
- adev.write(handle, CTRL_REG1, 0x00);
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
void lis3lv02d_poweron(acpi_handle handle)
{
- u8 val;
-
adev.is_on = 1;
adev.init(handle);
- adev.write(handle, FF_WU_CFG, 0);
- /*
- * BDU: LSB and MSB values are not updated until both have been read.
- * So the value read will always be correct.
- * IEN: Interrupt for free-fall and DD, not for data-ready.
- */
- adev.read(handle, CTRL_REG2, &val);
- val |= CTRL2_BDU | CTRL2_IEN;
- adev.write(handle, CTRL_REG2, val);
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
@@ -162,6 +140,140 @@ static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev)
mutex_unlock(&dev->lock);
}
+static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
+{
+ /*
+ * Be careful: on some HP laptops the bios force DD when on battery and
+ * the lid is closed. This leads to interrupts as soon as a little move
+ * is done.
+ */
+ atomic_inc(&adev.count);
+
+ wake_up_interruptible(&adev.misc_wait);
+ kill_fasync(&adev.async_queue, SIGIO, POLL_IN);
+ return IRQ_HANDLED;
+}
+
+static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ if (test_and_set_bit(0, &adev.misc_opened))
+ return -EBUSY; /* already open */
+
+ atomic_set(&adev.count, 0);
+
+ /*
+ * The sensor can generate interrupts for free-fall and direction
+ * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep
+ * the things simple and _fast_ we activate it only for free-fall, so
+ * no need to read register (very slow with ACPI). For the same reason,
+ * we forbid shared interrupts.
+ *
+ * IRQF_TRIGGER_RISING seems pointless on HP laptops because the
+ * io-apic is not configurable (and generates a warning) but I keep it
+ * in case of support for other hardware.
+ */
+ ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
+ DRIVER_NAME, &adev);
+
+ if (ret) {
+ clear_bit(0, &adev.misc_opened);
+ printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq);
+ return -EBUSY;
+ }
+ lis3lv02d_increase_use(&adev);
+ printk("lis3: registered interrupt %d\n", adev.irq);
+ return 0;
+}
+
+static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
+{
+ fasync_helper(-1, file, 0, &adev.async_queue);
+ lis3lv02d_decrease_use(&adev);
+ free_irq(adev.irq, &adev);
+ clear_bit(0, &adev.misc_opened); /* release the device */
+ return 0;
+}
+
+static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ u32 data;
+ unsigned char byte_data;
+ ssize_t retval = 1;
+
+ if (count < 1)
+ return -EINVAL;
+
+ add_wait_queue(&adev.misc_wait, &wait);
+ while (true) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ data = atomic_xchg(&adev.count, 0);
+ if (data)
+ break;
+
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto out;
+ }
+
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ goto out;
+ }
+
+ schedule();
+ }
+
+ if (data < 255)
+ byte_data = data;
+ else
+ byte_data = 255;
+
+ /* make sure we are not going into copy_to_user() with
+ * TASK_INTERRUPTIBLE state */
+ set_current_state(TASK_RUNNING);
+ if (copy_to_user(buf, &byte_data, sizeof(byte_data)))
+ retval = -EFAULT;
+
+out:
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&adev.misc_wait, &wait);
+
+ return retval;
+}
+
+static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
+{
+ poll_wait(file, &adev.misc_wait, wait);
+ if (atomic_read(&adev.count))
+ return POLLIN | POLLRDNORM;
+ return 0;
+}
+
+static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
+{
+ return fasync_helper(fd, file, on, &adev.async_queue);
+}
+
+static const struct file_operations lis3lv02d_misc_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = lis3lv02d_misc_read,
+ .open = lis3lv02d_misc_open,
+ .release = lis3lv02d_misc_release,
+ .poll = lis3lv02d_misc_poll,
+ .fasync = lis3lv02d_misc_fasync,
+};
+
+static struct miscdevice lis3lv02d_misc_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "freefall",
+ .fops = &lis3lv02d_misc_fops,
+};
+
/**
* lis3lv02d_joystick_kthread - Kthread polling function
* @data: unused - here to conform to threadfn prototype
@@ -203,7 +315,6 @@ static void lis3lv02d_joystick_close(struct input_dev *input)
lis3lv02d_decrease_use(&adev);
}
-
static inline void lis3lv02d_calibrate_joystick(void)
{
lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
@@ -231,9 +342,9 @@ int lis3lv02d_joystick_enable(void)
adev.idev->close = lis3lv02d_joystick_close;
set_bit(EV_ABS, adev.idev->evbit);
- input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
- input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
- input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
+ input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+ input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+ input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
err = input_register_device(adev.idev);
if (err) {
@@ -250,6 +361,7 @@ void lis3lv02d_joystick_disable(void)
if (!adev.idev)
return;
+ misc_deregister(&lis3lv02d_misc_device);
input_unregister_device(adev.idev);
adev.idev = NULL;
}
@@ -268,6 +380,19 @@ int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
if (lis3lv02d_joystick_enable())
printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
+ printk("lis3_init_device: irq %d\n", dev->irq);
+
+ /* if we did not get an IRQ from ACPI - we have nothing more to do */
+ if (!dev->irq) {
+ printk(KERN_ERR DRIVER_NAME
+ ": No IRQ in ACPI. Disabling /dev/freefall\n");
+ goto out;
+ }
+
+ printk("lis3: registering device\n");
+ if (misc_register(&lis3lv02d_misc_device))
+ printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
+out:
lis3lv02d_decrease_use(dev);
return 0;
}
@@ -351,6 +476,6 @@ int lis3lv02d_remove_fs(void)
EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
-MODULE_AUTHOR("Yan Burman and Eric Piel");
+MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 223f1c0763bb..75972bf372ff 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -22,12 +22,15 @@
/*
* The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to
* be connected via SPI. There exists also several similar chips (such as LIS302DL or
- * LIS3L02DQ) but not in the HP laptops and they have slightly different registers.
+ * LIS3L02DQ) and they have slightly different registers, but we can provide a
+ * common interface for all of them.
* They can also be connected via I²C.
*/
-#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */
-#define LIS302DL_ID 0x3B /* Also the LIS202DL! */
+/* 2-byte registers */
+#define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */
+/* 1-byte registers */
+#define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */
enum lis3lv02d_reg {
WHO_AM_I = 0x0F,
@@ -44,10 +47,13 @@ enum lis3lv02d_reg {
STATUS_REG = 0x27,
OUTX_L = 0x28,
OUTX_H = 0x29,
+ OUTX = 0x29,
OUTY_L = 0x2A,
OUTY_H = 0x2B,
+ OUTY = 0x2B,
OUTZ_L = 0x2C,
OUTZ_H = 0x2D,
+ OUTZ = 0x2D,
FF_WU_CFG = 0x30,
FF_WU_SRC = 0x31,
FF_WU_ACK = 0x32,
@@ -159,6 +165,10 @@ struct acpi_lis3lv02d {
acpi_status (*write) (acpi_handle handle, int reg, u8 val);
acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
+ u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
+ s16 (*read_data) (acpi_handle handle, int reg);
+ int mdps_max_val;
+
struct input_dev *idev; /* input device */
struct task_struct *kthread; /* kthread for input */
struct mutex lock;
@@ -170,6 +180,11 @@ struct acpi_lis3lv02d {
unsigned char is_on; /* whether the device is on or off */
unsigned char usage; /* usage counter */
struct axis_conversion ac; /* hw -> logical axis */
+
+ u32 irq; /* IRQ number */
+ struct fasync_struct *async_queue; /* queue for the misc device */
+ wait_queue_head_t misc_wait; /* Wait queue for the misc device */
+ unsigned long misc_opened; /* bit0: whether the device is open */
};
int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index b0ce37852281..73f77a9b8b18 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -1262,7 +1262,7 @@ static int __init vt1211_device_add(unsigned short address)
res.name = pdev->name;
err = acpi_check_resource_conflict(&res);
if (err)
- goto EXIT;
+ goto EXIT_DEV_PUT;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index cb808d015361..feae743ba991 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -1548,7 +1548,7 @@ static int __init sensors_w83627ehf_init(void)
err = acpi_check_resource_conflict(&res);
if (err)
- goto exit;
+ goto exit_device_put;
err = platform_device_add_resources(pdev, &res, 1);
if (err) {
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index eb8f72ca02f4..d420cc5f5633 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -604,9 +604,7 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
/* register new adapter to i2c module... */
adap->algo = &i2c_bit_algo;
-
- adap->timeout = 100; /* default values, should */
- adap->retries = 3; /* be replaced by defines */
+ adap->retries = 3;
return 0;
}
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index d50b329a3c94..a8e51bd1a4f5 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -27,9 +27,12 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-pca.h>
-#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0)
-#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
-#define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0)
+#define DEB1(fmt, args...) do { if (i2c_debug >= 1) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB2(fmt, args...) do { if (i2c_debug >= 2) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB3(fmt, args...) do { if (i2c_debug >= 3) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
static int i2c_debug;
@@ -43,6 +46,14 @@ static int i2c_debug;
#define pca_wait(adap) adap->wait_for_completion(adap->data)
#define pca_reset(adap) adap->reset_chip(adap->data)
+static void pca9665_reset(void *pd)
+{
+ struct i2c_algo_pca_data *adap = pd;
+ pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
+ pca_outw(adap, I2C_PCA_IND, 0xA5);
+ pca_outw(adap, I2C_PCA_IND, 0x5A);
+}
+
/*
* Generate a start condition on the i2c bus.
*
@@ -313,7 +324,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
ret = curmsg;
out:
- DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
+ DEB1("}}} transfered %d/%d messages. "
"status is %#04x. control is %#04x\n",
curmsg, num, pca_status(adap),
pca_get_con(adap));
@@ -330,26 +341,171 @@ static const struct i2c_algorithm pca_algo = {
.functionality = pca_func,
};
-static int pca_init(struct i2c_adapter *adap)
+static unsigned int pca_probe_chip(struct i2c_adapter *adap)
{
- static int freqs[] = {330,288,217,146,88,59,44,36};
- int clock;
struct i2c_algo_pca_data *pca_data = adap->algo_data;
-
- if (pca_data->i2c_clock > 7) {
- printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n",
- adap->name);
- pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ /* The trick here is to check if there is an indirect register
+ * available. If there is one, we will read the value we first
+ * wrote on I2C_PCA_IADR. Otherwise, we will read the last value
+ * we wrote on I2C_PCA_ADR
+ */
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+ pca_outw(pca_data, I2C_PCA_IND, 0xAA);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO);
+ pca_outw(pca_data, I2C_PCA_IND, 0x00);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+ if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
+ printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
+ return I2C_PCA_CHIP_9665;
+ } else {
+ printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
+ return I2C_PCA_CHIP_9564;
}
+}
+
+static int pca_init(struct i2c_adapter *adap)
+{
+ struct i2c_algo_pca_data *pca_data = adap->algo_data;
adap->algo = &pca_algo;
- pca_reset(pca_data);
+ if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) {
+ static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36};
+ int clock;
+
+ if (pca_data->i2c_clock > 7) {
+ switch (pca_data->i2c_clock) {
+ case 330000:
+ pca_data->i2c_clock = I2C_PCA_CON_330kHz;
+ break;
+ case 288000:
+ pca_data->i2c_clock = I2C_PCA_CON_288kHz;
+ break;
+ case 217000:
+ pca_data->i2c_clock = I2C_PCA_CON_217kHz;
+ break;
+ case 146000:
+ pca_data->i2c_clock = I2C_PCA_CON_146kHz;
+ break;
+ case 88000:
+ pca_data->i2c_clock = I2C_PCA_CON_88kHz;
+ break;
+ case 59000:
+ pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ break;
+ case 44000:
+ pca_data->i2c_clock = I2C_PCA_CON_44kHz;
+ break;
+ case 36000:
+ pca_data->i2c_clock = I2C_PCA_CON_36kHz;
+ break;
+ default:
+ printk(KERN_WARNING
+ "%s: Invalid I2C clock speed selected."
+ " Using default 59kHz.\n", adap->name);
+ pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ }
+ } else {
+ printk(KERN_WARNING "%s: "
+ "Choosing the clock frequency based on "
+ "index is deprecated."
+ " Use the nominal frequency.\n", adap->name);
+ }
+
+ pca_reset(pca_data);
+
+ clock = pca_clock(pca_data);
+ printk(KERN_INFO "%s: Clock frequency is %dkHz\n",
+ adap->name, freqs[clock]);
+
+ pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+ } else {
+ int clock;
+ int mode;
+ int tlow, thi;
+ /* Values can be found on PCA9665 datasheet section 7.3.2.6 */
+ int min_tlow, min_thi;
+ /* These values are the maximum raise and fall values allowed
+ * by the I2C operation mode (Standard, Fast or Fast+)
+ * They are used (added) below to calculate the clock dividers
+ * of PCA9665. Note that they are slightly different of the
+ * real maximum, to allow the change on mode exactly on the
+ * maximum clock rate for each mode
+ */
+ int raise_fall_time;
+
+ struct i2c_algo_pca_data *pca_data = adap->algo_data;
+
+ /* Ignore the reset function from the module,
+ * we can use the parallel bus reset
+ */
+ pca_data->reset_chip = pca9665_reset;
+
+ if (pca_data->i2c_clock > 1265800) {
+ printk(KERN_WARNING "%s: I2C clock speed too high."
+ " Using 1265.8kHz.\n", adap->name);
+ pca_data->i2c_clock = 1265800;
+ }
+
+ if (pca_data->i2c_clock < 60300) {
+ printk(KERN_WARNING "%s: I2C clock speed too low."
+ " Using 60.3kHz.\n", adap->name);
+ pca_data->i2c_clock = 60300;
+ }
+
+ /* To avoid integer overflow, use clock/100 for calculations */
+ clock = pca_clock(pca_data) / 100;
+
+ if (pca_data->i2c_clock > 10000) {
+ mode = I2C_PCA_MODE_TURBO;
+ min_tlow = 14;
+ min_thi = 5;
+ raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+ } else if (pca_data->i2c_clock > 4000) {
+ mode = I2C_PCA_MODE_FASTP;
+ min_tlow = 17;
+ min_thi = 9;
+ raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+ } else if (pca_data->i2c_clock > 1000) {
+ mode = I2C_PCA_MODE_FAST;
+ min_tlow = 44;
+ min_thi = 20;
+ raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */
+ } else {
+ mode = I2C_PCA_MODE_STD;
+ min_tlow = 157;
+ min_thi = 134;
+ raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */
+ }
+
+ /* The minimum clock that respects the thi/tlow = 134/157 is
+ * 64800 Hz. Below that, we have to fix the tlow to 255 and
+ * calculate the thi factor.
+ */
+ if (clock < 648) {
+ tlow = 255;
+ thi = 1000000 - clock * raise_fall_time;
+ thi /= (I2C_PCA_OSC_PER * clock) - tlow;
+ } else {
+ tlow = (1000000 - clock * raise_fall_time) * min_tlow;
+ tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow);
+ thi = tlow * min_thi / min_tlow;
+ }
+
+ pca_reset(pca_data);
- clock = pca_clock(pca_data);
- DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]);
+ printk(KERN_INFO
+ "%s: Clock frequency is %dHz\n", adap->name, clock * 100);
- pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE);
+ pca_outw(pca_data, I2C_PCA_IND, mode);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
+ pca_outw(pca_data, I2C_PCA_IND, tlow);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
+ pca_outw(pca_data, I2C_PCA_IND, thi);
+
+ pca_set_con(pca_data, I2C_PCA_CON_ENSIO);
+ }
udelay(500); /* 500 us for oscilator to stabilise */
return 0;
@@ -384,7 +540,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
"Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
+MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
MODULE_LICENSE("GPL");
module_param(i2c_debug, int, 0);
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index 3e01992230b8..7ce75775ec73 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -1,31 +1,30 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */
-/* ------------------------------------------------------------------------- */
-/* Copyright (C) 1995-1997 Simon G. Vogl
- 1998-2000 Hans Berglund
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
- Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
- <mbailey@littlefeet-inc.com> */
-
-/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
- messages, proper stop/repstart signaling during receive,
- added detect code */
+/*
+ * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters
+ *
+ * Copyright (C) 1995-1997 Simon G. Vogl
+ * 1998-2000 Hans Berglund
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
+ * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
+ * <mbailey@littlefeet-inc.com>
+ *
+ * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
+ * messages, proper stop/repstart signaling during receive, added detect code
+ */
#include <linux/kernel.h>
#include <linux/module.h>
@@ -38,17 +37,18 @@
#include "i2c-algo-pcf.h"
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEBPROTO(x) if (i2c_debug>=9) x;
- /* debug the protocol by showing transferred bits */
+#define DEB2(x) if (i2c_debug >= 2) x
+#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */
+#define DEBPROTO(x) if (i2c_debug >= 9) x;
+ /* debug the protocol by showing transferred bits */
#define DEF_TIMEOUT 16
-/* module parameters:
+/*
+ * module parameters:
*/
static int i2c_debug;
-/* --- setting states on the bus with the right timing: --------------- */
+/* setting states on the bus with the right timing: */
#define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
#define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
@@ -57,22 +57,21 @@ static int i2c_debug;
#define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
#define i2c_inb(adap) adap->getpcf(adap->data, 0)
-/* --- other auxiliary functions -------------------------------------- */
+/* other auxiliary functions */
-static void i2c_start(struct i2c_algo_pcf_data *adap)
+static void i2c_start(struct i2c_algo_pcf_data *adap)
{
- DEBPROTO(printk("S "));
+ DEBPROTO(printk(KERN_DEBUG "S "));
set_pcf(adap, 1, I2C_PCF_START);
}
-static void i2c_repstart(struct i2c_algo_pcf_data *adap)
+static void i2c_repstart(struct i2c_algo_pcf_data *adap)
{
DEBPROTO(printk(" Sr "));
set_pcf(adap, 1, I2C_PCF_REPSTART);
}
-
-static void i2c_stop(struct i2c_algo_pcf_data *adap)
+static void i2c_stop(struct i2c_algo_pcf_data *adap)
{
DEBPROTO(printk("P\n"));
set_pcf(adap, 1, I2C_PCF_STOP);
@@ -82,17 +81,17 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
{
DEB2(printk(KERN_INFO
"i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
- *status));
-
- /* Cleanup from LAB -- reset and enable ESO.
+ *status));
+ /*
+ * Cleanup from LAB -- reset and enable ESO.
* This resets the PCF8584; since we've lost the bus, no
* further attempts should be made by callers to clean up
* (no i2c_stop() etc.)
*/
set_pcf(adap, 1, I2C_PCF_PIN);
set_pcf(adap, 1, I2C_PCF_ESO);
-
- /* We pause for a time period sufficient for any running
+ /*
+ * We pause for a time period sufficient for any running
* I2C transaction to complete -- the arbitration logic won't
* work properly until the next START is seen.
* It is assumed the bus driver or client has set a proper value.
@@ -108,48 +107,50 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
get_pcf(adap, 1)));
}
-static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
+static int wait_for_bb(struct i2c_algo_pcf_data *adap)
+{
int timeout = DEF_TIMEOUT;
int status;
status = get_pcf(adap, 1);
-#ifndef STUB_I2C
- while (timeout-- && !(status & I2C_PCF_BB)) {
+
+ while (!(status & I2C_PCF_BB) && --timeout) {
udelay(100); /* wait for 100 us */
status = get_pcf(adap, 1);
}
-#endif
- if (timeout <= 0) {
+
+ if (timeout == 0) {
printk(KERN_ERR "Timeout waiting for Bus Busy\n");
+ return -ETIMEDOUT;
}
-
- return (timeout<=0);
-}
+ return 0;
+}
-static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
+static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)
+{
int timeout = DEF_TIMEOUT;
*status = get_pcf(adap, 1);
-#ifndef STUB_I2C
- while (timeout-- && (*status & I2C_PCF_PIN)) {
+
+ while ((*status & I2C_PCF_PIN) && --timeout) {
adap->waitforpin(adap->data);
*status = get_pcf(adap, 1);
}
if (*status & I2C_PCF_LAB) {
handle_lab(adap, status);
- return(-EINTR);
+ return -EINTR;
}
-#endif
- if (timeout <= 0)
- return(-1);
- else
- return(0);
+
+ if (timeout == 0)
+ return -ETIMEDOUT;
+
+ return 0;
}
-/*
+/*
* This should perform the 'PCF8584 initialization sequence' as described
* in the Philips IC12 data book (1995, Aug 29).
* There should be a 30 clock cycle wait after reset, I assume this
@@ -164,18 +165,21 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
{
unsigned char temp;
- DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
+ DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
+ get_pcf(adap, 1)));
/* S1=0x80: S0 selected, serial interface off */
set_pcf(adap, 1, I2C_PCF_PIN);
- /* check to see S1 now used as R/W ctrl -
- PCF8584 does that when ESO is zero */
+ /*
+ * check to see S1 now used as R/W ctrl -
+ * PCF8584 does that when ESO is zero
+ */
if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
return -ENXIO; /* definetly not PCF8584 */
}
- /* load own address in S0, effective address is (own << 1) */
+ /* load own address in S0, effective address is (own << 1) */
i2c_outb(adap, get_own(adap));
/* check it's really written */
if ((temp = i2c_inb(adap)) != get_own(adap)) {
@@ -183,7 +187,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* S1=0xA0, next byte in S2 */
+ /* S1=0xA0, next byte in S2 */
set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
/* check to see S2 now selected */
if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
@@ -191,7 +195,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* load clock register S2 */
+ /* load clock register S2 */
i2c_outb(adap, get_clock(adap));
/* check it's really written, the only 5 lowest bits does matter */
if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
@@ -199,7 +203,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* Enable serial interface, idle, S0 selected */
+ /* Enable serial interface, idle, S0 selected */
set_pcf(adap, 1, I2C_PCF_IDLE);
/* check to see PCF is really idled and we can access status register */
@@ -207,57 +211,47 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
return -ENXIO;
}
-
+
printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
return 0;
}
-
-/* ----- Utility functions
- */
-
static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
- int count, int last)
+ int count, int last)
{
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
int wrcount, status, timeout;
-
+
for (wrcount=0; wrcount<count; ++wrcount) {
DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
- buf[wrcount]&0xff));
+ buf[wrcount] & 0xff));
i2c_outb(adap, buf[wrcount]);
timeout = wait_for_pin(adap, &status);
if (timeout) {
- if (timeout == -EINTR) {
- /* arbitration lost */
- return -EINTR;
- }
+ if (timeout == -EINTR)
+ return -EINTR; /* arbitration lost */
+
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
return -EREMOTEIO; /* got a better one ?? */
}
-#ifndef STUB_I2C
if (status & I2C_PCF_LRB) {
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
return -EREMOTEIO; /* got a better one ?? */
}
-#endif
}
- if (last) {
+ if (last)
i2c_stop(adap);
- }
- else {
+ else
i2c_repstart(adap);
- }
- return (wrcount);
+ return wrcount;
}
-
static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
- int count, int last)
+ int count, int last)
{
int i, status;
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
@@ -267,42 +261,36 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
for (i = 0; i <= count; i++) {
if ((wfp = wait_for_pin(adap, &status))) {
- if (wfp == -EINTR) {
- /* arbitration lost */
- return -EINTR;
- }
+ if (wfp == -EINTR)
+ return -EINTR; /* arbitration lost */
+
i2c_stop(adap);
dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
- return (-1);
+ return -1;
}
-#ifndef STUB_I2C
if ((status & I2C_PCF_LRB) && (i != count)) {
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");
- return (-1);
+ return -1;
}
-#endif
-
+
if (i == count - 1) {
set_pcf(adap, 1, I2C_PCF_ESO);
- } else
- if (i == count) {
- if (last) {
+ } else if (i == count) {
+ if (last)
i2c_stop(adap);
- } else {
+ else
i2c_repstart(adap);
- }
- };
+ }
- if (i) {
+ if (i)
buf[i - 1] = i2c_inb(adap);
- } else {
+ else
i2c_inb(adap); /* dummy read */
- }
}
- return (i - 1);
+ return i - 1;
}
@@ -323,14 +311,14 @@ static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
}
static int pcf_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs,
+ struct i2c_msg *msgs,
int num)
{
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
struct i2c_msg *pmsg;
int i;
int ret=0, timeout, status;
-
+
if (adap->xfer_begin)
adap->xfer_begin(adap->data);
@@ -338,25 +326,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
timeout = wait_for_bb(adap);
if (timeout) {
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
- "Timeout waiting for BB in pcf_xfer\n");)
+ "Timeout waiting for BB in pcf_xfer\n");)
i = -EIO;
goto out;
}
-
+
for (i = 0;ret >= 0 && i < num; i++) {
pmsg = &msgs[i];
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->len, pmsg->addr, i + 1, num);)
-
+ pmsg->len, pmsg->addr, i + 1, num);)
+
ret = pcf_doAddress(adap, pmsg);
/* Send START */
- if (i == 0) {
- i2c_start(adap);
- }
-
+ if (i == 0)
+ i2c_start(adap);
+
/* Wait for PIN (pending interrupt NOT) */
timeout = wait_for_pin(adap, &status);
if (timeout) {
@@ -371,8 +358,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
i = -EREMOTEIO;
goto out;
}
-
-#ifndef STUB_I2C
+
/* Check LRB (last rcvd bit - slave ack) */
if (status & I2C_PCF_LRB) {
i2c_stop(adap);
@@ -380,27 +366,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
i = -EREMOTEIO;
goto out;
}
-#endif
-
+
DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
-
- /* Read */
+
if (pmsg->flags & I2C_M_RD) {
- /* read bytes into buffer*/
ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
+ (i + 1 == num));
+
if (ret != pmsg->len) {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
"only read %d bytes.\n",ret));
} else {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
}
- } else { /* Write */
+ } else {
ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
+ (i + 1 == num));
+
if (ret != pmsg->len) {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
"only wrote %d bytes.\n",ret));
@@ -413,24 +396,23 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
out:
if (adap->xfer_end)
adap->xfer_end(adap->data);
- return (i);
+ return i;
}
static u32 pcf_func(struct i2c_adapter *adap)
{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_PROTOCOL_MANGLING;
}
-/* -----exported algorithm data: ------------------------------------- */
-
+/* exported algorithm data: */
static const struct i2c_algorithm pcf_algo = {
.master_xfer = pcf_xfer,
.functionality = pcf_func,
};
-/*
- * registering functions to load algorithms at runtime
+/*
+ * registering functions to load algorithms at runtime
*/
int i2c_pcf_add_bus(struct i2c_adapter *adap)
{
@@ -441,7 +423,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
/* register new adapter to i2c module... */
adap->algo = &pcf_algo;
- adap->timeout = 100;
if ((rval = pcf_init_8584(pcf_adap)))
return rval;
@@ -458,4 +439,4 @@ MODULE_LICENSE("GPL");
module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
+ "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 7f95905bbb9d..68650643d116 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -617,12 +617,12 @@ config I2C_ELEKTOR
will be called i2c-elektor.
config I2C_PCA_ISA
- tristate "PCA9564 on an ISA bus"
+ tristate "PCA9564/PCA9665 on an ISA bus"
depends on ISA
select I2C_ALGOPCA
default n
help
- This driver supports ISA boards using the Philips PCA9564
+ This driver supports ISA boards using the Philips PCA9564/PCA9665
parallel bus to I2C bus controller.
This driver can also be built as a module. If so, the module
@@ -634,11 +634,11 @@ config I2C_PCA_ISA
time). If unsure, say N.
config I2C_PCA_PLATFORM
- tristate "PCA9564 as platform device"
+ tristate "PCA9564/PCA9665 as platform device"
select I2C_ALGOPCA
default n
help
- This driver supports a memory mapped Philips PCA9564
+ This driver supports a memory mapped Philips PCA9564/PCA9665
parallel bus to I2C bus controller.
This driver can also be built as a module. If so, the module
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c
index 75089febbc13..9aefb5e5864d 100644
--- a/drivers/i2c/busses/i2c-acorn.c
+++ b/drivers/i2c/busses/i2c-acorn.c
@@ -79,11 +79,11 @@ static struct i2c_algo_bit_data ioc_data = {
.getsda = ioc_getsda,
.getscl = ioc_getscl,
.udelay = 80,
- .timeout = 100
+ .timeout = HZ,
};
static struct i2c_adapter ioc_ops = {
- .id = I2C_HW_B_IOC,
+ .nr = 0,
.algo_data = &ioc_data,
};
@@ -91,7 +91,7 @@ static int __init i2c_ioc_init(void)
{
force_ones = FORCE_ONES | SCL | SDA;
- return i2c_bit_add_bus(&ioc_ops);
+ return i2c_bit_add_numbered_bus(&ioc_ops);
}
module_init(i2c_ioc_init);
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index 9cead9b9458e..981e080b32ae 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -476,7 +476,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter ali1535_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_ALI1535,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index dd9e796fad69..f70f46582c6c 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -386,7 +386,6 @@ static const struct i2c_algorithm ali1563_algorithm = {
static struct i2c_adapter ali1563_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_ALI1563,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &ali1563_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index 234fdde7d40e..39066dee46e3 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -473,7 +473,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter ali15x3_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_ALI15X3,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 36bee5b9c952..220f4a1eee1d 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -298,7 +298,6 @@ static const struct i2c_algorithm smbus_algorithm = {
struct i2c_adapter amd756_smbus = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_AMD756,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index 3972208876b3..a7c59908c457 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -72,7 +72,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
{
int timeout = 500;
- while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF))
+ while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
udelay(1);
if (!timeout) {
@@ -88,7 +88,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
{
int timeout = 500;
- while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF))
+ while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
udelay(1);
if (!timeout) {
@@ -387,7 +387,6 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
smbus->adapter.owner = THIS_MODULE;
snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus2 AMD8111 adapter at %04x", smbus->base);
- smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index 66a04c2c660f..f78ce523e3db 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -400,7 +400,6 @@ i2c_au1550_probe(struct platform_device *pdev)
priv->xfer_timeout = 200;
priv->ack_timeout = 200;
- priv->adap.id = I2C_HW_AU1550_PSC;
priv->adap.nr = pdev->id;
priv->adap.algo = &au1550_algo;
priv->adap.algo_data = priv;
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index 3fd2c417c1e0..fc548b3d002e 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -651,7 +651,6 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
iface->timeout_timer.data = (unsigned long)iface;
p_adap = &iface->adap;
- p_adap->id = I2C_HW_BLACKFIN;
p_adap->nr = pdev->id;
strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
p_adap->algo = &bfin_twi_algorithm;
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 5d7789834b95..3fae3a91ce5b 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -216,7 +216,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
{
unsigned long timeout;
- timeout = jiffies + DAVINCI_I2C_TIMEOUT;
+ timeout = jiffies + dev->adapter.timeout;
while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
& DAVINCI_I2C_STR_BB) {
if (time_after(jiffies, timeout)) {
@@ -289,7 +289,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
- DAVINCI_I2C_TIMEOUT);
+ dev->adapter.timeout);
if (r == 0) {
dev_err(dev->dev, "controller timed out\n");
i2c_davinci_init(dev);
@@ -546,9 +546,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
adap->algo = &i2c_davinci_algo;
adap->dev.parent = &pdev->dev;
-
- /* FIXME */
- adap->timeout = 1;
+ adap->timeout = DAVINCI_I2C_TIMEOUT;
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 0ed3ccb81b63..448b4bf35eb7 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -202,7 +202,6 @@ static struct i2c_algo_pcf_data pcf_isa_data = {
static struct i2c_adapter pcf_isa_ops = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .id = I2C_HW_P_ELEK,
.algo_data = &pcf_isa_data,
.name = "i2c-elektor",
};
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 648aa7baff83..bec9b845dd16 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -102,7 +102,6 @@ static struct i2c_algo_bit_data hydra_bit_data = {
static struct i2c_adapter hydra_adap = {
.owner = THIS_MODULE,
.name = "Hydra i2c",
- .id = I2C_HW_B_HYDRA,
.algo_data = &hydra_bit_data,
};
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 526625eaa84b..230238df56c4 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -556,7 +556,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter i801_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_I801,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 651f2f1ae5b7..8b92a4666e02 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -415,7 +415,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
if (dev->irq >= 0){
/* Interrupt mode */
ret = wait_event_interruptible_timeout(dev->wq,
- !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ);
+ !(in_8(&iic->sts) & STS_PT), dev->adap.timeout);
if (unlikely(ret < 0))
DBG("%d: wait interrupted\n", dev->idx);
@@ -426,7 +426,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
}
else {
/* Polling mode */
- unsigned long x = jiffies + dev->adap.timeout * HZ;
+ unsigned long x = jiffies + dev->adap.timeout;
while (in_8(&iic->sts) & STS_PT){
if (unlikely(time_after(jiffies, x))){
@@ -746,10 +746,9 @@ static int __devinit iic_probe(struct of_device *ofdev,
adap->dev.parent = &ofdev->dev;
strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
i2c_set_adapdata(adap, dev);
- adap->id = I2C_HW_OCP;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo = &iic_algo;
- adap->timeout = 1;
+ adap->timeout = HZ;
ret = i2c_add_adapter(adap);
if (ret < 0) {
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index fc2714ac0c0f..a75c75e77b92 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -480,7 +480,6 @@ iop3xx_i2c_probe(struct platform_device *pdev)
}
memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
- new_adapter->id = I2C_HW_IOP3XX;
new_adapter->owner = THIS_MODULE;
new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
new_adapter->dev.parent = &pdev->dev;
@@ -489,7 +488,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
/*
* Default values...should these come in from board code?
*/
- new_adapter->timeout = 100;
+ new_adapter->timeout = HZ;
new_adapter->algo = &iop3xx_i2c_algo;
init_waitqueue_head(&adapter_data->waitq);
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index 05d72e981353..c016f7a2c5fc 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -114,9 +114,8 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.getsda = ixp2000_bit_getsda;
drv_data->algo_data.getscl = ixp2000_bit_getscl;
drv_data->algo_data.udelay = 6;
- drv_data->algo_data.timeout = 100;
+ drv_data->algo_data.timeout = HZ;
- drv_data->adapter.id = I2C_HW_B_IXP2000,
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
sizeof(drv_data->adapter.name));
drv_data->adapter.algo_data = &drv_data->algo_data,
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index a9a45fcc8544..26bf37010586 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -70,7 +70,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
/* Read again to allow register to stabilise */
i2c->interrupt = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR);
- wake_up_interruptible(&i2c->queue);
+ wake_up(&i2c->queue);
}
return IRQ_HANDLED;
}
@@ -115,13 +115,10 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
writeb(0, i2c->base + MPC_I2C_SR);
} else {
/* Interrupt mode */
- result = wait_event_interruptible_timeout(i2c->queue,
- (i2c->interrupt & CSR_MIF), timeout * HZ);
+ result = wait_event_timeout(i2c->queue,
+ (i2c->interrupt & CSR_MIF), timeout);
- if (unlikely(result < 0)) {
- pr_debug("I2C: wait interrupted\n");
- writeccr(i2c, 0);
- } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
+ if (unlikely(!(i2c->interrupt & CSR_MIF))) {
pr_debug("I2C: wait timeout\n");
writeccr(i2c, 0);
result = -ETIMEDOUT;
@@ -310,9 +307,8 @@ static const struct i2c_algorithm mpc_algo = {
static struct i2c_adapter mpc_ops = {
.owner = THIS_MODULE,
.name = "MPC adapter",
- .id = I2C_HW_MPC107,
.algo = &mpc_algo,
- .timeout = 1,
+ .timeout = HZ,
};
static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match)
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 9e8118d2fe64..4e3f0735ccf5 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -358,7 +358,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
char abort = 0;
time_left = wait_event_interruptible_timeout(drv_data->waitq,
- !drv_data->block, msecs_to_jiffies(drv_data->adapter.timeout));
+ !drv_data->block, drv_data->adapter.timeout);
spin_lock_irqsave(&drv_data->lock, flags);
if (!time_left) { /* Timed out */
@@ -374,8 +374,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
spin_unlock_irqrestore(&drv_data->lock, flags);
time_left = wait_event_timeout(drv_data->waitq,
- !drv_data->block,
- msecs_to_jiffies(drv_data->adapter.timeout));
+ !drv_data->block, drv_data->adapter.timeout);
if ((time_left <= 0) && drv_data->block) {
drv_data->state = MV64XXX_I2C_STATE_IDLE;
@@ -527,11 +526,10 @@ mv64xxx_i2c_probe(struct platform_device *pd)
goto exit_unmap_regs;
}
drv_data->adapter.dev.parent = &pd->dev;
- drv_data->adapter.id = I2C_HW_MV64XXX;
drv_data->adapter.algo = &mv64xxx_i2c_algo;
drv_data->adapter.owner = THIS_MODULE;
drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- drv_data->adapter.timeout = pdata->timeout;
+ drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
drv_data->adapter.nr = pd->id;
platform_set_drvdata(pd, drv_data);
i2c_set_adapdata(&drv_data->adapter, drv_data);
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 3b19bc41a60b..b9580e07bfff 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -31,10 +31,13 @@
nForce3 250Gb MCP 00E4
nForce4 MCP 0052
nForce4 MCP-04 0034
- nForce4 MCP51 0264
- nForce4 MCP55 0368
+ nForce MCP51 0264
+ nForce MCP55 0368
nForce MCP61 03EB
nForce MCP65 0446
+ nForce MCP67 0542
+ nForce MCP73 07D8
+ nForce MCP79 0AA2
This driver supports the 2 SMBuses that are included in the MCP of the
nForce2/3/4/5xx chipsets.
@@ -315,6 +318,9 @@ static struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) },
{ 0 }
};
@@ -355,7 +361,6 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
return -EBUSY;
}
smbus->adapter.owner = THIS_MODULE;
- smbus->adapter.id = I2C_HW_SMBUS_NFORCE2;
smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
index b2b8380f6602..322c5691e38e 100644
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -115,7 +115,6 @@ static struct i2c_algo_bit_data parport_algo_data = {
static struct i2c_adapter parport_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON,
- .id = I2C_HW_B_LP,
.algo_data = &parport_algo_data,
.name = "Parallel port adapter (light)",
};
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index a257cd5cd134..0d8998610c74 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -164,7 +164,6 @@ static void i2c_parport_attach (struct parport *port)
/* Fill the rest of the structure */
adapter->adapter.owner = THIS_MODULE;
adapter->adapter.class = I2C_CLASS_HWMON;
- adapter->adapter.id = I2C_HW_B_LP;
strlcpy(adapter->adapter.name, "Parallel port adapter",
sizeof(adapter->adapter.name));
adapter->algo_data = parport_algo_data;
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
index 9eb76268ec78..0cc8017b3f64 100644
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -41,7 +41,7 @@ static int irq = -1;
/* Data sheet recommends 59kHz for 100kHz operation due to variation
* in the actual clock rate */
-static int clock = I2C_PCA_CON_59kHz;
+static int clock = 59000;
static wait_queue_head_t pca_wait;
@@ -49,7 +49,8 @@ static void pca_isa_writebyte(void *pd, int reg, int val)
{
#ifdef DEBUG_IO
static char *names[] = { "T/O", "DAT", "ADR", "CON" };
- printk("*** write %s at %#lx <= %#04x\n", names[reg], base+reg, val);
+ printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg],
+ base+reg, val);
#endif
outb(val, base+reg);
}
@@ -60,7 +61,7 @@ static int pca_isa_readbyte(void *pd, int reg)
#ifdef DEBUG_IO
{
static char *names[] = { "STA", "DAT", "ADR", "CON" };
- printk("*** read %s => %#04x\n", names[reg], res);
+ printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res);
}
#endif
return res;
@@ -101,9 +102,8 @@ static struct i2c_algo_pca_data pca_isa_data = {
static struct i2c_adapter pca_isa_ops = {
.owner = THIS_MODULE,
- .id = I2C_HW_A_ISA,
.algo_data = &pca_isa_data,
- .name = "PCA9564 ISA Adapter",
+ .name = "PCA9564/PCA9665 ISA Adapter",
.timeout = 100,
};
@@ -196,7 +196,7 @@ static void __exit pca_isa_exit(void)
}
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
-MODULE_DESCRIPTION("ISA base PCA9564 driver");
+MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver");
MODULE_LICENSE("GPL");
module_param(base, ulong, 0);
@@ -205,7 +205,13 @@ MODULE_PARM_DESC(base, "I/O base address");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq, "IRQ");
module_param(clock, int, 0);
-MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet");
+MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t"
+ "For PCA9564: 330000,288000,217000,146000,"
+ "88000,59000,44000,36000\n"
+ "\t\tFor PCA9665:\tStandard: 60300 - 100099\n"
+ "\t\t\t\tFast: 100100 - 400099\n"
+ "\t\t\t\tFast+: 400100 - 10000099\n"
+ "\t\t\t\tTurbo: Up to 1265800");
module_init(pca_isa_init);
module_exit(pca_isa_exit);
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
index 6bb15ad0a6b6..51d179bbddf9 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -172,8 +172,9 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
i2c->adap.owner = THIS_MODULE;
- snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx",
- (unsigned long) res->start);
+ snprintf(i2c->adap.name, sizeof(i2c->adap.name),
+ "PCA9564/PCA9665 at 0x%08lx",
+ (unsigned long) res->start);
i2c->adap.algo_data = &i2c->algo_data;
i2c->adap.dev.parent = &pdev->dev;
i2c->adap.timeout = platform_data->timeout;
@@ -246,7 +247,7 @@ e_remap:
e_alloc:
release_mem_region(res->start, res_len(res));
e_print:
- printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret);
+ printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret);
return ret;
}
@@ -290,7 +291,7 @@ static void __exit i2c_pca_pf_exit(void)
}
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-PCA9564 platform driver");
+MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
MODULE_LICENSE("GPL");
module_init(i2c_pca_pf_init);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index eaa9b387543e..761f9dd53620 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -403,7 +403,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter piix4_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_PIIX4,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 60ca91745e55..3c9d71f60187 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -191,7 +191,8 @@ static int __devexit i2c_powermac_remove(struct platform_device *dev)
i2c_set_adapdata(adapter, NULL);
/* We aren't that prepared to deal with this... */
if (rc)
- printk("i2c-powermac.c: Failed to remove bus %s !\n",
+ printk(KERN_WARNING
+ "i2c-powermac.c: Failed to remove bus %s !\n",
adapter->name);
platform_set_drvdata(dev, NULL);
kfree(adapter);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 6af68146c342..bfa45868a480 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -210,11 +210,12 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
{
unsigned int i;
- printk("i2c: error: %s\n", why);
- printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
+ printk(KERN_ERR "i2c: error: %s\n", why);
+ printk(KERN_ERR "i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
- printk("i2c: ICR: %08x ISR: %08x\n"
- "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c)));
+ printk(KERN_ERR "i2c: ICR: %08x ISR: %08x\n"
+ readl(_ICR(i2c)), readl(_ISR(i2c)));
+ printk(KERN_DEBUG "i2c: log: ");
for (i = 0; i < i2c->irqlogidx; i++)
printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
printk("\n");
@@ -644,7 +645,7 @@ static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
i2c_pxa_start_message(i2c);
- while (timeout-- && i2c->msg_num > 0) {
+ while (i2c->msg_num > 0 && --timeout) {
i2c_pxa_handler(0, i2c);
udelay(10);
}
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
index 4ddefbf238e9..98b1ec489159 100644
--- a/drivers/i2c/busses/i2c-sibyte.c
+++ b/drivers/i2c/busses/i2c-sibyte.c
@@ -155,7 +155,6 @@ static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
static struct i2c_adapter sibyte_board_adapter[2] = {
{
.owner = THIS_MODULE,
- .id = I2C_HW_SIBYTE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = NULL,
.algo_data = &sibyte_board_data[0],
@@ -164,7 +163,6 @@ static struct i2c_adapter sibyte_board_adapter[2] = {
},
{
.owner = THIS_MODULE,
- .id = I2C_HW_SIBYTE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = NULL,
.algo_data = &sibyte_board_data[1],
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 8ce2daff985c..f320ab27da46 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -365,7 +365,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis5595_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_SIS5595,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 9c9c016ff2b5..50c3610e6028 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -464,7 +464,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis630_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_SIS630,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index f1bba6396641..7e1594b40579 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -241,7 +241,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter sis96x_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_SIS96X,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
index 4678babd3ce6..fede619ba227 100644
--- a/drivers/i2c/busses/i2c-versatile.c
+++ b/drivers/i2c/busses/i2c-versatile.c
@@ -102,7 +102,13 @@ static int i2c_versatile_probe(struct platform_device *dev)
i2c->algo = i2c_versatile_algo;
i2c->algo.data = i2c;
- ret = i2c_bit_add_bus(&i2c->adap);
+ if (dev->id >= 0) {
+ /* static bus numbering */
+ i2c->adap.nr = dev->id;
+ ret = i2c_bit_add_numbered_bus(&i2c->adap);
+ } else
+ /* dynamic bus numbering */
+ ret = i2c_bit_add_bus(&i2c->adap);
if (ret >= 0) {
platform_set_drvdata(dev, i2c);
return 0;
@@ -146,7 +152,7 @@ static void __exit i2c_versatile_exit(void)
platform_driver_unregister(&i2c_versatile_driver);
}
-module_init(i2c_versatile_init);
+subsys_initcall(i2c_versatile_init);
module_exit(i2c_versatile_exit);
MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 29cef0433f34..8b24f192103a 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -83,7 +83,6 @@ static struct i2c_algo_bit_data bit_data = {
static struct i2c_adapter vt586b_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_B_VIA,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.name = "VIA i2c",
.algo_data = &bit_data,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 9f194d9efd91..02e6f724b05f 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -321,7 +321,6 @@ static const struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter vt596_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_SMBUS_VIA2,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &smbus_algorithm,
};
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
index 1d4ae26ba73d..1a474acc0ddd 100644
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -163,7 +163,6 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = {
static struct i2c_adapter voodoo3_i2c_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_B_VOO,
.class = I2C_CLASS_TV_ANALOG,
.name = "I2C Voodoo3/Banshee adapter",
.algo_data = &voo_i2c_bit_data,
@@ -180,7 +179,6 @@ static struct i2c_algo_bit_data voo_ddc_bit_data = {
static struct i2c_adapter voodoo3_ddc_adapter = {
.owner = THIS_MODULE,
- .id = I2C_HW_B_VOO,
.class = I2C_CLASS_DDC,
.name = "DDC Voodoo3/Banshee adapter",
.algo_data = &voo_ddc_bit_data,
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index ed794b145a11..648ecc6f60e6 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -440,7 +440,6 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
i2c_set_adapdata(adapter, iface);
snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index);
adapter->owner = THIS_MODULE;
- adapter->id = I2C_HW_SMBUS_SCX200;
adapter->algo = &scx200_acb_algorithm;
adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adapter->dev.parent = dev;
diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
index e4c98539c517..42df0eca43d5 100644
--- a/drivers/i2c/busses/scx200_i2c.c
+++ b/drivers/i2c/busses/scx200_i2c.c
@@ -76,13 +76,12 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
.getsda = scx200_i2c_getsda,
.getscl = scx200_i2c_getscl,
.udelay = 10,
- .timeout = 100,
+ .timeout = HZ,
};
static struct i2c_adapter scx200_i2c_ops = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
- .id = I2C_HW_B_SCX200,
.algo_data = &scx200_i2c_data,
.name = "NatSemi SCx200 I2C",
};
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index b9bef04b7be4..c80312c1f382 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -16,43 +16,6 @@ config DS1682
This driver can also be built as a module. If so, the module
will be called ds1682.
-config AT24
- tristate "EEPROMs from most vendors"
- depends on SYSFS && EXPERIMENTAL
- help
- Enable this driver to get read/write support to most I2C EEPROMs,
- after you configure the driver to know about each EEPROM on
- your target board. Use these generic chip names, instead of
- vendor-specific ones like at24c64 or 24lc02:
-
- 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
- 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
-
- Unless you like data loss puzzles, always be sure that any chip
- you configure as a 24c32 (32 kbit) or larger is NOT really a
- 24c16 (16 kbit) or smaller, and vice versa. Marking the chip
- as read-only won't help recover from this. Also, if your chip
- has any software write-protect mechanism you may want to review the
- code to make sure this driver won't turn it on by accident.
-
- If you use this with an SMBus adapter instead of an I2C adapter,
- full functionality is not available. Only smaller devices are
- supported (24c16 and below, max 4 kByte).
-
- This driver can also be built as a module. If so, the module
- will be called at24.
-
-config SENSORS_EEPROM
- tristate "EEPROM reader"
- depends on EXPERIMENTAL
- help
- If you say yes here you get read-only access to the EEPROM data
- available on modern memory DIMMs and Sony Vaio laptops. Such
- EEPROMs could theoretically be available on other devices as well.
-
- This driver can also be built as a module. If so, the module
- will be called eeprom.
-
config SENSORS_PCF8574
tristate "Philips PCF8574 and PCF8574A (DEPRECATED)"
depends on EXPERIMENTAL && GPIO_PCF857X = "n"
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 00fcb5193ac2..d142f238a2de 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -11,8 +11,6 @@
#
obj-$(CONFIG_DS1682) += ds1682.o
-obj-$(CONFIG_AT24) += at24.o
-obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b1c9abe24c7b..62c925fd0c41 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -459,6 +459,11 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
pr_debug("I2C adapter driver [%s] forgot to specify "
"physical device\n", adap->name);
}
+
+ /* Set default timeout to 1 second if not already set */
+ if (adap->timeout == 0)
+ adap->timeout = HZ;
+
dev_set_name(&adap->dev, "i2c-%d", adap->nr);
adap->dev.release = &i2c_adapter_dev_release;
adap->dev.class = &i2c_adapter_class;
@@ -1831,7 +1836,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
case I2C_SMBUS_QUICK:
msg[0].len = 0;
/* Special case: The read/write field is used as data */
- msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0;
+ msg[0].flags = flags | (read_write == I2C_SMBUS_READ ?
+ I2C_M_RD : 0);
num = 1;
break;
case I2C_SMBUS_BYTE:
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index c171988a9f51..7e13d2df9af3 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -35,6 +35,7 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/smp_lock.h>
+#include <linux/jiffies.h>
#include <asm/uaccess.h>
static struct i2c_driver i2cdev_driver;
@@ -422,7 +423,10 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
client->adapter->retries = arg;
break;
case I2C_TIMEOUT:
- client->adapter->timeout = arg;
+ /* For historical reasons, user-space sets the timeout
+ * value in units of 10 ms.
+ */
+ client->adapter->timeout = msecs_to_jiffies(arg * 10);
break;
default:
/* NOTE: returning a fault code here could cause trouble
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index b1c6f68d98ce..63c1103ade81 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -46,7 +46,7 @@ menuconfig IDE
SMART parameters from disk drives.
To compile this driver as a module, choose M here: the
- module will be called ide.
+ module will be called ide-core.ko.
For further information, please read <file:Documentation/ide/ide.txt>.
@@ -56,8 +56,12 @@ if IDE
comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
+config IDE_XFER_MODE
+ bool
+
config IDE_TIMINGS
bool
+ select IDE_XFER_MODE
config IDE_ATAPI
bool
@@ -218,7 +222,8 @@ comment "IDE chipset support/bugfixes"
config IDE_GENERIC
tristate "generic/default IDE chipset support"
- depends on ALPHA || X86 || IA64 || M32R || MIPS
+ depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
+ default ARM && (ARCH_RPC || ARCH_SHARK)
help
This is the generic IDE driver. This driver attaches to the
fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
@@ -465,6 +470,16 @@ config BLK_DEV_CS5535
It is safe to say Y to this question.
+config BLK_DEV_CS5536
+ tristate "CS5536 chipset support"
+ depends on X86_32
+ select BLK_DEV_IDEDMA_PCI
+ help
+ This option enables support for the AMD CS5536
+ companion chip used with the Geode LX processor family.
+
+ If unsure, say N.
+
config BLK_DEV_HPT366
tristate "HPT36X/37X chipset support"
select BLK_DEV_IDEDMA_PCI
@@ -688,6 +703,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST
config BLK_DEV_IDE_AU1XXX
bool "IDE for AMD Alchemy Au1200"
depends on SOC_AU1200
+ select IDE_XFER_MODE
choice
prompt "IDE Mode for AMD Alchemy Au1200"
default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
@@ -711,11 +727,6 @@ config BLK_DEV_IDE_TX4939
depends on SOC_TX4939
select BLK_DEV_IDEDMA_SFF
-config IDE_ARM
- tristate "ARM IDE support"
- depends on ARM && (ARCH_RPC || ARCH_SHARK)
- default y
-
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
depends on ARM && ARCH_ACORN
@@ -754,27 +765,20 @@ config BLK_DEV_GAYLE
This includes on-board IDE interfaces on some Amiga models (A600,
A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
bus (M-Tech E-Matrix 530 expansion card).
- Say Y if you have an Amiga with a Gayle IDE interface and want to use
- IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
- it.
- Note that you also have to enable Zorro bus support if you want to
- use Gayle IDE interfaces on the Zorro expansion bus.
-config BLK_DEV_IDEDOUBLER
- bool "Amiga IDE Doubler support (EXPERIMENTAL)"
- depends on BLK_DEV_GAYLE && EXPERIMENTAL
- ---help---
- This feature provides support for the so-called `IDE doublers' (made
+ It also provides support for the so-called `IDE doublers' (made
by various manufacturers, e.g. Eyetech) that can be connected to
the on-board IDE interface of some Amiga models. Using such an IDE
doubler, you can connect up to four instead of two IDE devices to
- the Amiga's on-board IDE interface.
+ the Amiga's on-board IDE interface. The feature is enabled at kernel
+ runtime using the "gayle.doubler" kernel boot parameter.
- Note that the normal Amiga Gayle IDE driver may not work correctly
- if you have an IDE doubler and don't enable this feature!
+ Say Y if you have an Amiga with a Gayle IDE interface and want to use
+ IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
+ it.
- Say Y if you have an IDE doubler. The feature is enabled at kernel
- runtime using the "gayle.doubler" kernel boot parameter.
+ Note that you also have to enable Zorro bus support if you want to
+ use Gayle IDE interfaces on the Zorro expansion bus.
config BLK_DEV_BUDDHA
tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
@@ -856,6 +860,7 @@ config BLK_DEV_ALI14XX
config BLK_DEV_DTC2278
tristate "DTC-2278 support"
+ select IDE_XFER_MODE
select IDE_LEGACY
help
This driver is enabled at runtime using the "dtc2278.probe" kernel
@@ -887,6 +892,7 @@ config BLK_DEV_QD65XX
config BLK_DEV_UMC8672
tristate "UMC-8672 support"
+ select IDE_XFER_MODE
select IDE_LEGACY
help
This driver is enabled at runtime using the "umc8672.probe" kernel
@@ -900,5 +906,6 @@ endif
config BLK_DEV_IDEDMA
def_bool BLK_DEV_IDEDMA_SFF || \
BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ select IDE_XFER_MODE
endif # IDE
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index c2b9c93f0095..af65113456e5 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -5,9 +5,11 @@
EXTRA_CFLAGS += -Idrivers/ide
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
- ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o
+ ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
+ ide-io-std.o ide-eh.o
# core IDE code
+ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o
ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
@@ -19,8 +21,6 @@ ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o
obj-$(CONFIG_IDE) += ide-core.o
-obj-$(CONFIG_IDE_ARM) += ide_arm.o
-
obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
@@ -43,6 +43,7 @@ obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
+obj-$(CONFIG_BLK_DEV_CS5536) += cs5536.o
obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 4485b9c6f0e6..878f8ec6dbe1 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -139,7 +139,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
}
-static unsigned int init_chipset_aec62xx(struct pci_dev *dev)
+static int init_chipset_aec62xx(struct pci_dev *dev)
{
/* These are necessary to get AEC6280 Macintosh cards to work */
if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) ||
@@ -156,7 +156,7 @@ static unsigned int init_chipset_aec62xx(struct pci_dev *dev)
pci_write_config_byte(dev, 0x4a, reg4ah | 0x80);
}
- return dev->irq;
+ return 0;
}
static u8 atp86x_cable_detect(ide_hwif_t *hwif)
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 66f43083408b..537da1cde16d 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -189,19 +189,20 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * ali15x3_dma_setup - begin a DMA phase
+ * ali_dma_check - DMA check
* @drive: target device
+ * @cmd: command
*
* Returns 1 if the DMA cannot be performed, zero on success.
*/
-static int ali15x3_dma_setup(ide_drive_t *drive)
+static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
if (m5229_revision < 0xC2 && drive->media != ide_disk) {
- if (rq_data_dir(drive->hwif->rq))
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
return 1; /* try PIO instead of DMA */
}
- return ide_dma_setup(drive);
+ return 0;
}
/**
@@ -212,7 +213,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive)
* appropriate also sets up the 1533 southbridge.
*/
-static unsigned int init_chipset_ali15x3(struct pci_dev *dev)
+static int init_chipset_ali15x3(struct pci_dev *dev)
{
unsigned long flags;
u8 tmpbyte;
@@ -502,13 +503,13 @@ static const struct ide_port_ops ali_port_ops = {
static const struct ide_dma_ops ali_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ali15x3_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_setup = ide_dma_setup,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_check = ali_dma_check,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index 69660a431cd9..628cd2e5fed8 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -140,7 +140,7 @@ static void amd7411_cable_detect(struct pci_dev *dev)
* The initialization callback. Initialize drive independent registers.
*/
-static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
+static int init_chipset_amd74xx(struct pci_dev *dev)
{
u8 t = 0, offset = amd_offset(dev);
@@ -166,13 +166,13 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
* Check for broken FIFO support.
*/
if (dev->vendor == PCI_VENDOR_ID_AMD &&
- dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411)
+ dev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
t &= 0x0f;
else
t |= 0xf0;
pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t);
- return dev->irq;
+ return 0;
}
static u8 amd_cable_detect(ide_hwif_t *hwif)
@@ -183,14 +183,6 @@ static u8 amd_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA40;
}
-static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- if (hwif->irq == 0) /* 0 is bogus but will do for now */
- hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
-}
-
static const struct ide_port_ops amd_port_ops = {
.set_pio_mode = amd_set_pio_mode,
.set_dma_mode = amd_set_drive,
@@ -207,7 +199,6 @@ static const struct ide_port_ops amd_port_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_amd74xx, \
- .init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
.port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
@@ -221,7 +212,6 @@ static const struct ide_port_ops amd_port_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_amd74xx, \
- .init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
.port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c
index b2735d28f5cc..923cbfe259d3 100644
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -52,7 +52,7 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
unsigned long flags;
- int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
+ int timing_shift = (drive->dn ^ 1) * 8;
u32 pio_timing_data;
u16 pio_mode_data;
@@ -85,7 +85,7 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
unsigned long flags;
- int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
+ int timing_shift = (drive->dn ^ 1) * 8;
u32 tmp32;
u16 tmp16;
u16 udma_ctl = 0;
@@ -142,7 +142,6 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
.port_ops = &atiixp_port_ops,
- .host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -151,7 +150,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
.port_ops = &atiixp_port_ops,
- .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 79a2dfed8eb7..c219ddda890e 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -86,13 +86,13 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-static void au1xxx_input_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
}
-static void au1xxx_output_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
@@ -209,23 +209,17 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
*/
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static int auide_build_dmatable(ide_drive_t *drive)
+static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
- int i, iswrite, count = 0;
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
_auide_hwif *ahwif = &auide_hwif;
struct scatterlist *sg;
+ int i = cmd->sg_nents, count = 0;
+ int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- iswrite = (rq_data_dir(rq) == WRITE);
/* Save for interrupt context */
ahwif->drive = drive;
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
/* fill the descriptors */
sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
@@ -278,21 +272,12 @@ static int auide_build_dmatable(ide_drive_t *drive)
if (count)
return 1;
- use_pio_instead:
- ide_destroy_dmatable(drive);
-
+use_pio_instead:
return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
-
- if (hwif->sg_nents) {
- ide_destroy_dmatable(drive);
- hwif->sg_nents = 0;
- }
-
return 0;
}
@@ -301,23 +286,11 @@ static void auide_dma_start(ide_drive_t *drive )
}
-static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr,
- (2*WAIT_CMD), NULL);
-}
-
-static int auide_dma_setup(ide_drive_t *drive)
-{
- struct request *rq = drive->hwif->rq;
-
- if (!auide_build_dmatable(drive)) {
- ide_map_sg(drive, rq);
+ if (auide_build_dmatable(drive, cmd) == 0)
return 1;
- }
- drive->waiting_for_dma = 1;
return 0;
}
@@ -342,16 +315,11 @@ static void auide_dma_host_set(ide_drive_t *drive, int on)
static void auide_ddma_tx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
static void auide_ddma_rx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
-
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
@@ -369,12 +337,10 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de
static const struct ide_dma_ops au1xxx_dma_ops = {
.dma_host_set = auide_dma_host_set,
.dma_setup = auide_dma_setup,
- .dma_exec_cmd = auide_dma_exec_cmd,
.dma_start = auide_dma_start,
.dma_end = auide_dma_end,
.dma_test_irq = auide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
@@ -536,9 +502,8 @@ static const struct ide_port_info au1xxx_port_info = {
#endif
};
-static int au_ide_probe(struct device *dev)
+static int au_ide_probe(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
_auide_hwif *ahwif = &auide_hwif;
struct resource *res;
struct ide_host *host;
@@ -552,23 +517,23 @@ static int au_ide_probe(struct device *dev)
#endif
memset(&auide_hwif, 0, sizeof(_auide_hwif));
- ahwif->irq = platform_get_irq(pdev, 0);
+ ahwif->irq = platform_get_irq(dev, 0);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (res == NULL) {
- pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no base address\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}
if (ahwif->irq < 0) {
- pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no IRQ\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}
if (!request_mem_region(res->start, res->end - res->start + 1,
- pdev->name)) {
+ dev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
ret = -EBUSY;
goto out;
@@ -583,7 +548,7 @@ static int au_ide_probe(struct device *dev)
memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif);
hw.irq = ahwif->irq;
- hw.dev = dev;
+ hw.dev = &dev->dev;
hw.chipset = ide_au1xxx;
ret = ide_host_add(&au1xxx_port_info, hws, &host);
@@ -592,7 +557,7 @@ static int au_ide_probe(struct device *dev)
auide_hwif.hwif = host->ports[0];
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
@@ -600,38 +565,39 @@ static int au_ide_probe(struct device *dev)
return ret;
}
-static int au_ide_remove(struct device *dev)
+static int au_ide_remove(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
- struct ide_host *host = dev_get_drvdata(dev);
+ struct ide_host *host = platform_get_drvdata(dev);
_auide_hwif *ahwif = &auide_hwif;
ide_host_remove(host);
iounmap((void *)ahwif->regbase);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
release_mem_region(res->start, res->end - res->start + 1);
return 0;
}
-static struct device_driver au1200_ide_driver = {
- .name = "au1200-ide",
- .bus = &platform_bus_type,
+static struct platform_driver au1200_ide_driver = {
+ .driver = {
+ .name = "au1200-ide",
+ .owner = THIS_MODULE,
+ },
.probe = au_ide_probe,
.remove = au_ide_remove,
};
static int __init au_ide_init(void)
{
- return driver_register(&au1200_ide_driver);
+ return platform_driver_register(&au1200_ide_driver);
}
static void __exit au_ide_exit(void)
{
- driver_unregister(&au1200_ide_driver);
+ platform_driver_unregister(&au1200_ide_driver);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c
index c5a3c9ef6a5d..d028f8864bc1 100644
--- a/drivers/ide/buddha.c
+++ b/drivers/ide/buddha.c
@@ -143,6 +143,11 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
+static const struct ide_port_info buddha_port_info = {
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
+};
+
/*
* Probe for a Buddha or Catweasel IDE interface
*/
@@ -172,10 +177,6 @@ static int __init buddha_init(void)
board = z->resource.start;
-/*
- * FIXME: we now have selectable mmio v/s iomio transports.
- */
-
if(type != BOARD_XSURF) {
if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
continue;
@@ -224,7 +225,7 @@ fail_base2:
hws[i] = &hw[i];
}
- ide_host_add(NULL, hws, NULL);
+ ide_host_add(&buddha_port_info, hws, NULL);
}
return 0;
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 2f9688d87ecd..80b777e4247b 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -318,7 +318,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
/* get DMA status */
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* read DMA command state */
@@ -327,13 +326,11 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
/* clear the INTR & ERROR bits */
outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
-static unsigned int init_chipset_cmd64x(struct pci_dev *dev)
+static int init_chipset_cmd64x(struct pci_dev *dev)
{
u8 mrdmode = 0;
@@ -379,36 +376,33 @@ static const struct ide_port_ops cmd64x_port_ops = {
static const struct ide_dma_ops cmd64x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd64x_dma_end,
.dma_test_irq = cmd64x_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd646_1_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd648_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd648_dma_end,
.dma_test_irq = cmd648_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c
index d003bec56ff9..58fb90e5b763 100644
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -133,7 +133,8 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
* do all the device setup for us
*/
- ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]);
+ ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
+ hw[0].irq = 14;
return ide_host_add(d, hws, NULL);
}
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index d8ede85fe17f..8e8b35a89901 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -135,7 +135,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
* Initialize the cs5530 bridge for reliable IDE DMA operation.
*/
-static unsigned int init_chipset_cs5530(struct pci_dev *dev)
+static int init_chipset_cs5530(struct pci_dev *dev)
{
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
new file mode 100644
index 000000000000..353a35bbba63
--- /dev/null
+++ b/drivers/ide/cs5536.c
@@ -0,0 +1,307 @@
+/*
+ * CS5536 PATA support
+ * (C) 2007 Martin K. Petersen <mkp@mkp.net>
+ * (C) 2009 Bartlomiej Zolnierkiewicz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Documentation:
+ * Available from AMD web site.
+ *
+ * The IDE timing registers for the CS5536 live in the Geode Machine
+ * Specific Register file and not PCI config space. Most BIOSes
+ * virtualize the PCI registers so the chip looks like a standard IDE
+ * controller. Unfortunately not all implementations get this right.
+ * In particular some have problems with unaligned accesses to the
+ * virtualized PCI registers. This driver always does full dword
+ * writes to work around the issue. Also, in case of a bad BIOS this
+ * driver can be loaded with the "msr=1" parameter which forces using
+ * the Machine Specific Registers to configure the device.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+#include <asm/msr.h>
+
+#define DRV_NAME "cs5536"
+
+enum {
+ MSR_IDE_CFG = 0x51300010,
+ PCI_IDE_CFG = 0x40,
+
+ CFG = 0,
+ DTC = 2,
+ CAST = 3,
+ ETC = 4,
+
+ IDE_CFG_CHANEN = (1 << 1),
+ IDE_CFG_CABLE = (1 << 17) | (1 << 16),
+
+ IDE_D0_SHIFT = 24,
+ IDE_D1_SHIFT = 16,
+ IDE_DRV_MASK = 0xff,
+
+ IDE_CAST_D0_SHIFT = 6,
+ IDE_CAST_D1_SHIFT = 4,
+ IDE_CAST_DRV_MASK = 0x3,
+
+ IDE_CAST_CMD_SHIFT = 24,
+ IDE_CAST_CMD_MASK = 0xff,
+
+ IDE_ETC_UDMA_MASK = 0xc0,
+};
+
+static int use_msr;
+
+static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
+{
+ if (unlikely(use_msr)) {
+ u32 dummy;
+
+ rdmsr(MSR_IDE_CFG + reg, *val, dummy);
+ return 0;
+ }
+
+ return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static int cs5536_write(struct pci_dev *pdev, int reg, int val)
+{
+ if (unlikely(use_msr)) {
+ wrmsr(MSR_IDE_CFG + reg, val, 0);
+ return 0;
+ }
+
+ return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static void cs5536_program_dtc(ide_drive_t *drive, u8 tim)
+{
+ struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ u32 dtc;
+
+ cs5536_read(pdev, DTC, &dtc);
+ dtc &= ~(IDE_DRV_MASK << dshift);
+ dtc |= tim << dshift;
+ cs5536_write(pdev, DTC, dtc);
+}
+
+/**
+ * cs5536_cable_detect - detect cable type
+ * @hwif: Port to detect on
+ *
+ * Perform cable detection for ATA66 capable cable.
+ *
+ * Returns a cable type.
+ */
+
+static u8 cs5536_cable_detect(ide_hwif_t *hwif)
+{
+ struct pci_dev *pdev = to_pci_dev(hwif->dev);
+ u32 cfg;
+
+ cs5536_read(pdev, CFG, &cfg);
+
+ if (cfg & IDE_CFG_CABLE)
+ return ATA_CBL_PATA80;
+ else
+ return ATA_CBL_PATA40;
+}
+
+/**
+ * cs5536_set_pio_mode - PIO timing setup
+ * @drive: ATA device
+ * @pio: PIO mode number
+ */
+
+static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ static const u8 drv_timings[5] = {
+ 0x98, 0x55, 0x32, 0x21, 0x20,
+ };
+
+ static const u8 addr_timings[5] = {
+ 0x2, 0x1, 0x0, 0x0, 0x0,
+ };
+
+ static const u8 cmd_timings[5] = {
+ 0x99, 0x92, 0x90, 0x22, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ ide_drive_t *pair = ide_get_pair_dev(drive);
+ int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+ u32 cast;
+ u8 cmd_pio = pio;
+
+ if (pair)
+ cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));
+
+ drive->drive_data &= (IDE_DRV_MASK << 8);
+ drive->drive_data |= drv_timings[pio];
+
+ cs5536_program_dtc(drive, drv_timings[pio]);
+
+ cs5536_read(pdev, CAST, &cast);
+
+ cast &= ~(IDE_CAST_DRV_MASK << cshift);
+ cast |= addr_timings[pio] << cshift;
+
+ cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
+ cast |= cmd_timings[cmd_pio] << IDE_CAST_CMD_SHIFT;
+
+ cs5536_write(pdev, CAST, cast);
+}
+
+/**
+ * cs5536_set_dma_mode - DMA timing setup
+ * @drive: ATA device
+ * @mode: DMA mode
+ */
+
+static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+ static const u8 udma_timings[6] = {
+ 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
+ };
+
+ static const u8 mwdma_timings[3] = {
+ 0x67, 0x21, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ u32 etc;
+
+ cs5536_read(pdev, ETC, &etc);
+
+ if (mode >= XFER_UDMA_0) {
+ etc &= ~(IDE_DRV_MASK << dshift);
+ etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
+ } else { /* MWDMA */
+ etc &= ~(IDE_ETC_UDMA_MASK << dshift);
+ drive->drive_data &= IDE_DRV_MASK;
+ drive->drive_data |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
+ }
+
+ cs5536_write(pdev, ETC, etc);
+}
+
+static void cs5536_dma_start(ide_drive_t *drive)
+{
+ if (drive->current_speed < XFER_UDMA_0 &&
+ (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
+ cs5536_program_dtc(drive, drive->drive_data >> 8);
+
+ ide_dma_start(drive);
+}
+
+static int cs5536_dma_end(ide_drive_t *drive)
+{
+ int ret = ide_dma_end(drive);
+
+ if (drive->current_speed < XFER_UDMA_0 &&
+ (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
+ cs5536_program_dtc(drive, drive->drive_data & IDE_DRV_MASK);
+
+ return ret;
+}
+
+static const struct ide_port_ops cs5536_port_ops = {
+ .set_pio_mode = cs5536_set_pio_mode,
+ .set_dma_mode = cs5536_set_dma_mode,
+ .cable_detect = cs5536_cable_detect,
+};
+
+static const struct ide_dma_ops cs5536_dma_ops = {
+ .dma_host_set = ide_dma_host_set,
+ .dma_setup = ide_dma_setup,
+ .dma_start = cs5536_dma_start,
+ .dma_end = cs5536_dma_end,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+};
+
+static const struct ide_port_info cs5536_info = {
+ .name = DRV_NAME,
+ .port_ops = &cs5536_port_ops,
+ .dma_ops = &cs5536_dma_ops,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
+};
+
+/**
+ * cs5536_init_one
+ * @dev: PCI device
+ * @id: Entry in match table
+ */
+
+static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ u32 cfg;
+
+ if (use_msr)
+ printk(KERN_INFO DRV_NAME ": Using MSR regs instead of PCI\n");
+
+ cs5536_read(dev, CFG, &cfg);
+
+ if ((cfg & IDE_CFG_CHANEN) == 0) {
+ printk(KERN_ERR DRV_NAME ": disabled by BIOS\n");
+ return -ENODEV;
+ }
+
+ return ide_pci_init_one(dev, &cs5536_info, NULL);
+}
+
+static const struct pci_device_id cs5536_pci_tbl[] = {
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), },
+ { },
+};
+
+static struct pci_driver cs5536_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = cs5536_pci_tbl,
+ .probe = cs5536_init_one,
+ .remove = ide_pci_remove,
+ .suspend = ide_pci_suspend,
+ .resume = ide_pci_resume,
+};
+
+static int __init cs5536_init(void)
+{
+ return pci_register_driver(&cs5536_pci_driver);
+}
+
+static void __exit cs5536_exit(void)
+{
+ pci_unregister_driver(&cs5536_pci_driver);
+}
+
+MODULE_AUTHOR("Martin K. Petersen, Bartlomiej Zolnierkiewicz");
+MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, cs5536_pci_tbl);
+
+module_param_named(msr, use_msr, int, 0644);
+MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
+
+module_init(cs5536_init);
+module_exit(cs5536_exit);
diff --git a/drivers/ide/delkin_cb.c b/drivers/ide/delkin_cb.c
index 8f1b2d9f0513..f153b95619bb 100644
--- a/drivers/ide/delkin_cb.c
+++ b/drivers/ide/delkin_cb.c
@@ -46,7 +46,7 @@ static const struct ide_port_ops delkin_cb_port_ops = {
.quirkproc = ide_undecoded_slave,
};
-static unsigned int delkin_cb_init_chipset(struct pci_dev *dev)
+static int delkin_cb_init_chipset(struct pci_dev *dev)
{
unsigned long base = pci_resource_start(dev, 0);
int i;
@@ -66,6 +66,7 @@ static const struct ide_port_info delkin_cb_port_info = {
.port_ops = &delkin_cb_port_ops,
.host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
.init_chipset = delkin_cb_init_chipset,
};
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c
index 689b2e493413..c6b138122981 100644
--- a/drivers/ide/dtc2278.c
+++ b/drivers/ide/dtc2278.c
@@ -100,7 +100,8 @@ static const struct ide_port_info dtc2278_port_info __initdata = {
IDE_HFLAG_IO_32BIT |
/* disallow ->io_32bit changes */
IDE_HFLAG_NO_IO_32BIT |
- IDE_HFLAG_NO_DMA,
+ IDE_HFLAG_NO_DMA |
+ IDE_HFLAG_DTC2278,
.pio_mask = ATA_PIO4,
};
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index a5ba820d69bb..b368a5effc3a 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -40,29 +40,48 @@
* which is shared between several drivers.
*/
-int falconide_intr_lock;
-EXPORT_SYMBOL(falconide_intr_lock);
+static int falconide_intr_lock;
-static void falconide_input_data(ide_drive_t *drive, struct request *rq,
+static void falconide_release_lock(void)
+{
+ if (falconide_intr_lock == 0) {
+ printk(KERN_ERR "%s: bug\n", __func__);
+ return;
+ }
+ falconide_intr_lock = 0;
+ stdma_release();
+}
+
+static void falconide_get_lock(irq_handler_t handler, void *data)
+{
+ if (falconide_intr_lock == 0) {
+ if (in_interrupt() > 0)
+ panic("Falcon IDE hasn't ST-DMA lock in interrupt");
+ stdma_lock(handler, data);
+ falconide_intr_lock = 1;
+ }
+}
+
+static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return insw(data_addr, buf, (len + 1) / 2);
- insw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
-static void falconide_output_data(ide_drive_t *drive, struct request *rq,
+static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return outsw(data_addr, buf, (len + 1) / 2);
- outsw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
/* Atari has a byte-swapped IDE interface */
@@ -81,8 +100,12 @@ static const struct ide_tp_ops falconide_tp_ops = {
};
static const struct ide_port_info falconide_port_info = {
+ .get_lock = falconide_get_lock,
+ .release_lock = falconide_release_lock,
.tp_ops = &falconide_tp_ops,
- .host_flags = IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
static void __init falconide_setup_ports(hw_regs_t *hw)
@@ -132,9 +155,9 @@ static int __init falconide_init(void)
goto err;
}
- ide_get_lock(NULL, NULL);
+ falconide_get_lock(NULL, NULL);
rc = ide_host_register(host, &falconide_port_info, hws);
- ide_release_lock();
+ falconide_release_lock();
if (rc)
goto err_free;
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index 59bd0be9dcb3..c7119516c5a7 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -53,11 +53,6 @@
#define GAYLE_NEXT_PORT 0x1000
-#ifndef CONFIG_BLK_DEV_IDEDOUBLER
-#define GAYLE_NUM_HWIFS 1
-#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS
-#define GAYLE_HAS_CONTROL_REG 1
-#else /* CONFIG_BLK_DEV_IDEDOUBLER */
#define GAYLE_NUM_HWIFS 2
#define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \
GAYLE_NUM_HWIFS-1)
@@ -66,8 +61,6 @@
static int ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-
/*
* Check and acknowledge the interrupt status
@@ -118,7 +111,9 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
}
static const struct ide_port_info gayle_port_info = {
- .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
/*
@@ -149,10 +144,7 @@ static int __init gayle_init(void)
found:
printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
a4000 ? 4000 : 1200,
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
- ide_doubler ? ", IDE doubler" :
-#endif
- "");
+ ide_doubler ? ", IDE doubler" : "");
if (a4000) {
phys_base = GAYLE_BASE_4000;
@@ -163,9 +155,6 @@ found:
irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200);
ack_intr = gayle_ack_intr_a1200;
}
-/*
- * FIXME: we now have selectable modes between mmio v/s iomio
- */
res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
res_n = GAYLE_IDEREG_SIZE;
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 3eb9b5c63a0f..a0eb87f59134 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -835,12 +835,6 @@ static int hpt370_dma_end(ide_drive_t *drive)
return ide_dma_end(drive);
}
-static void hpt370_dma_timeout(ide_drive_t *drive)
-{
- hpt370_irq_timeout(drive);
- ide_dma_timeout(drive);
-}
-
/* returns 1 if DMA IRQ issued, 0 otherwise */
static int hpt374_dma_test_irq(ide_drive_t *drive)
{
@@ -995,7 +989,7 @@ static void hpt3xx_disable_fast_irq(struct pci_dev *dev, u8 mcr_addr)
pci_write_config_byte(dev, mcr_addr + 1, new_mcr);
}
-static unsigned int init_chipset_hpt366(struct pci_dev *dev)
+static int init_chipset_hpt366(struct pci_dev *dev)
{
unsigned long io_base = pci_resource_start(dev, 4);
struct hpt_info *info = hpt3xx_get_info(&dev->dev);
@@ -1237,7 +1231,7 @@ static unsigned int init_chipset_hpt366(struct pci_dev *dev)
hpt3xx_disable_fast_irq(dev, 0x50);
hpt3xx_disable_fast_irq(dev, 0x54);
- return dev->irq;
+ return 0;
}
static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
@@ -1418,36 +1412,34 @@ static const struct ide_port_ops hpt3xx_port_ops = {
static const struct ide_dma_ops hpt37x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = hpt374_dma_end,
.dma_test_irq = hpt374_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt370_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = hpt370_dma_start,
.dma_end = hpt370_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = hpt370_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = hpt370_irq_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = hpt366_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 97a35c667aee..4e16ce68b063 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -287,13 +287,8 @@ static int icside_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
- drive->waiting_for_dma = 0;
-
disable_dma(ec->dma);
- /* Teardown mappings after DMA has completed. */
- ide_destroy_dmatable(drive);
-
return get_dma_residue(ec->dma) != 0;
}
@@ -307,15 +302,14 @@ static void icside_dma_start(ide_drive_t *drive)
enable_dma(ec->dma);
}
-static int icside_dma_setup(ide_drive_t *drive)
+static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
- struct request *rq = hwif->rq;
unsigned int dma_mode;
- if (rq_data_dir(rq))
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
dma_mode = DMA_MODE_WRITE;
else
dma_mode = DMA_MODE_READ;
@@ -325,8 +319,6 @@ static int icside_dma_setup(ide_drive_t *drive)
*/
BUG_ON(dma_channel_active(ec->dma));
- hwif->sg_nents = ide_build_sglist(drive, rq);
-
/*
* Ensure that we have the right interrupt routed.
*/
@@ -346,20 +338,12 @@ static int icside_dma_setup(ide_drive_t *drive)
* Tell the DMA engine about the SG table and
* data direction.
*/
- set_dma_sg(ec->dma, hwif->sg_table, hwif->sg_nents);
+ set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
set_dma_mode(ec->dma, dma_mode);
- drive->waiting_for_dma = 1;
-
return 0;
}
-static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL);
-}
-
static int icside_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
@@ -383,11 +367,9 @@ static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
static const struct ide_dma_ops icside_v6_dma_ops = {
.dma_host_set = icside_dma_host_set,
.dma_setup = icside_dma_setup,
- .dma_exec_cmd = icside_dma_exec_cmd,
.dma_start = icside_dma_start,
.dma_end = icside_dma_end,
.dma_test_irq = icside_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
};
#else
@@ -419,6 +401,10 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
hw->chipset = ide_acorn;
}
+static const struct ide_port_info icside_v5_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static int __devinit
icside_register_v5(struct icside_state *state, struct expansion_card *ec)
{
@@ -445,7 +431,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
- host = ide_host_alloc(NULL, hws);
+ host = ide_host_alloc(&icside_v5_port_info, hws);
if (host == NULL)
return -ENODEV;
@@ -453,7 +439,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
ecard_set_drvdata(ec, state);
- ret = ide_host_register(host, NULL, hws);
+ ret = ide_host_register(host, &icside_v5_port_info, hws);
if (ret)
goto err_free;
@@ -534,7 +520,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
d.dma_ops = NULL;
}
- ret = ide_host_register(host, NULL, hws);
+ ret = ide_host_register(host, &d, hws);
if (ret)
goto err_free;
diff --git a/drivers/ide/ide-4drives.c b/drivers/ide/ide-4drives.c
index 9e85b1ec9607..78aca75a2c48 100644
--- a/drivers/ide/ide-4drives.c
+++ b/drivers/ide/ide-4drives.c
@@ -23,7 +23,8 @@ static const struct ide_port_ops ide_4drives_port_ops = {
static const struct ide_port_info ide_4drives_port_info = {
.port_ops = &ide_4drives_port_ops,
- .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA |
+ IDE_HFLAG_4DRIVES,
};
static int __init ide_4drives_init(void)
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index d8f295bdad76..12f436951bff 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -20,9 +20,6 @@
#include <acpi/acpi_bus.h>
#define REGS_PER_GTF 7
-struct taskfile_array {
- u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
-};
struct GTM_buffer {
u32 PIO_speed0;
@@ -89,12 +86,8 @@ static const struct dmi_system_id ide_acpi_dmi_table[] = {
{ } /* terminate list */
};
-static int ide_acpi_blacklist(void)
+int ide_acpi_init(void)
{
- static int done;
- if (done)
- return 0;
- done = 1;
dmi_check_system(ide_acpi_dmi_table);
return 0;
}
@@ -202,40 +195,6 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
}
/**
- * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive
- * @drive: device to locate
- *
- * Retrieves the object handle of a given drive. According to the ACPI
- * spec the drive is a child of the hwif.
- *
- * Returns handle on success, 0 on error.
- */
-static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- int port;
- acpi_handle drive_handle;
-
- if (!hwif->acpidata)
- return NULL;
-
- if (!hwif->acpidata->obj_handle)
- return NULL;
-
- port = hwif->channel ? drive->dn - 2: drive->dn;
-
- DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
- drive->name, hwif->channel, port);
-
-
- /* TBD: could also check ACPI object VALID bits */
- drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port);
- DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle);
-
- return drive_handle;
-}
-
-/**
* do_drive_get_GTF - get the drive bootup default taskfile settings
* @drive: the drive for which the taskfile settings should be retrieved
* @gtf_length: number of bytes of _GTF data returned at @gtf_address
@@ -257,47 +216,15 @@ static int do_drive_get_GTF(ide_drive_t *drive,
acpi_status status;
struct acpi_buffer output;
union acpi_object *out_obj;
- ide_hwif_t *hwif = drive->hwif;
- struct device *dev = hwif->gendev.parent;
int err = -ENODEV;
- int port;
*gtf_length = 0;
*gtf_address = 0UL;
*obj_loc = 0UL;
- if (ide_noacpi)
- return 0;
-
- if (!dev) {
- DEBPRINT("no PCI device for %s\n", hwif->name);
- goto out;
- }
-
- if (!hwif->acpidata) {
- DEBPRINT("no ACPI data for %s\n", hwif->name);
- goto out;
- }
-
- port = hwif->channel ? drive->dn - 2: drive->dn;
-
- DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
- hwif->name, dev->bus_id, port, hwif->channel);
-
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) {
- DEBPRINT("%s drive %d:%d not present\n",
- hwif->name, hwif->channel, port);
- goto out;
- }
-
- /* Get this drive's _ADR info. if not already known. */
if (!drive->acpidata->obj_handle) {
- drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
- if (!drive->acpidata->obj_handle) {
- DEBPRINT("No ACPI object found for %s\n",
- drive->name);
- goto out;
- }
+ DEBPRINT("No ACPI object found for %s\n", drive->name);
+ goto out;
}
/* Setting up output buffer */
@@ -355,43 +282,6 @@ out:
}
/**
- * taskfile_load_raw - send taskfile registers to drive
- * @drive: drive to which output is sent
- * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
- *
- * Outputs IDE taskfile to the drive.
- */
-static int taskfile_load_raw(ide_drive_t *drive,
- const struct taskfile_array *gtf)
-{
- ide_task_t args;
- int err = 0;
-
- DEBPRINT("(0x1f1-1f7): hex: "
- "%02x %02x %02x %02x %02x %02x %02x\n",
- gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
- gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
-
- memset(&args, 0, sizeof(ide_task_t));
-
- /* convert gtf to IDE Taskfile */
- memcpy(&args.tf_array[7], &gtf->tfa, 7);
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-
- if (!ide_acpigtf) {
- DEBPRINT("_GTF execution disabled\n");
- return err;
- }
-
- err = ide_no_data_taskfile(drive, &args);
- if (err)
- printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
- __func__, err);
-
- return err;
-}
-
-/**
* do_drive_set_taskfiles - write the drive taskfile settings from _GTF
* @drive: the drive to which the taskfile command should be sent
* @gtf_length: total number of bytes of _GTF taskfiles
@@ -404,43 +294,41 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
unsigned int gtf_length,
unsigned long gtf_address)
{
- int rc = -ENODEV, err;
+ int rc = 0, err;
int gtf_count = gtf_length / REGS_PER_GTF;
int ix;
- struct taskfile_array *gtf;
-
- if (ide_noacpi)
- return 0;
-
- DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn);
-
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- goto out;
-
- if (!gtf_count) /* shouldn't be here */
- goto out;
DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n",
gtf_length, gtf_length, gtf_count, gtf_address);
- if (gtf_length % REGS_PER_GTF) {
- printk(KERN_ERR "%s: unexpected GTF length (%d)\n",
- __func__, gtf_length);
- goto out;
- }
-
- rc = 0;
+ /* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */
for (ix = 0; ix < gtf_count; ix++) {
- gtf = (struct taskfile_array *)
- (gtf_address + ix * REGS_PER_GTF);
+ u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF);
+ struct ide_cmd cmd;
- /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
- err = taskfile_load_raw(drive, gtf);
- if (err)
+ DEBPRINT("(0x1f1-1f7): "
+ "hex: %02x %02x %02x %02x %02x %02x %02x\n",
+ gtf[0], gtf[1], gtf[2],
+ gtf[3], gtf[4], gtf[5], gtf[6]);
+
+ if (!ide_acpigtf) {
+ DEBPRINT("_GTF execution disabled\n");
+ continue;
+ }
+
+ /* convert GTF to taskfile */
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ err = ide_no_data_taskfile(drive, &cmd);
+ if (err) {
+ printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
+ __func__, err);
rc = err;
+ }
}
-out:
return rc;
}
@@ -647,26 +535,23 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
DEBPRINT("no ACPI data for %s\n", hwif->name);
return;
}
+
/* channel first and then drives for power on and verse versa for power off */
if (on)
acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0);
- ide_port_for_each_dev(i, drive, hwif) {
- if (!drive->acpidata->obj_handle)
- drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
-
- if (drive->acpidata->obj_handle &&
- (drive->dev_flags & IDE_DFLAG_PRESENT)) {
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ if (drive->acpidata->obj_handle)
acpi_bus_set_power(drive->acpidata->obj_handle,
- on? ACPI_STATE_D0: ACPI_STATE_D3);
- }
+ on ? ACPI_STATE_D0 : ACPI_STATE_D3);
}
+
if (!on)
acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3);
}
/**
- * ide_acpi_init - initialize the ACPI link for an IDE interface
+ * ide_acpi_init_port - initialize the ACPI link for an IDE interface
* @hwif: target IDE interface (channel)
*
* The ACPI spec is not quite clear when the drive identify buffer
@@ -676,10 +561,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
* So we get the information during startup; but this means that
* any changes during run-time will be lost after resume.
*/
-void ide_acpi_init(ide_hwif_t *hwif)
+void ide_acpi_init_port(ide_hwif_t *hwif)
{
- ide_acpi_blacklist();
-
hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
if (!hwif->acpidata)
return;
@@ -708,15 +591,24 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
hwif->devices[0]->acpidata = &hwif->acpidata->master;
hwif->devices[1]->acpidata = &hwif->acpidata->slave;
- /*
- * Send IDENTIFY for each drive
- */
- ide_port_for_each_dev(i, drive, hwif) {
- memset(drive->acpidata, 0, sizeof(*drive->acpidata));
+ /* get _ADR info for each device */
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ acpi_handle dev_handle;
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
+ DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
+ drive->name, hwif->channel, drive->dn & 1);
+
+ /* TBD: could also check ACPI object VALID bits */
+ dev_handle = acpi_get_child(hwif->acpidata->obj_handle,
+ drive->dn & 1);
+
+ DEBPRINT("drive %s handle 0x%p\n", drive->name, dev_handle);
+
+ drive->acpidata->obj_handle = dev_handle;
+ }
+ /* send IDENTIFY for each device */
+ ide_port_for_each_present_dev(i, drive, hwif) {
err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
if (err)
DEBPRINT("identify device %s failed (%d)\n",
@@ -736,9 +628,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
ide_acpi_get_timing(hwif);
ide_acpi_push_timing(hwif);
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT)
- /* Execute ACPI startup code */
- ide_acpi_exec_tfs(drive);
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ ide_acpi_exec_tfs(drive);
}
}
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index e96c01260598..ff6adeadc666 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -143,7 +143,10 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
- ide_do_drive_cmd(drive, rq);
+
+ drive->hwif->rq = NULL;
+
+ elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
/*
@@ -285,6 +288,21 @@ int ide_cd_get_xferlen(struct request *rq)
}
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
+void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
+{
+ struct ide_cmd cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
+ IDE_TFLAG_IN_NSECT;
+
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
+
+ *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam;
+ *ireason = cmd.tf.nsect & 3;
+}
+EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
+
/*
* This is the usual interrupt handler which will be called during a packet
* command. We will transfer some of the data (as requested by the drive)
@@ -294,6 +312,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
@@ -306,17 +325,17 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
: WAIT_TAPE_CMD;
- if (pc->flags & PC_FLAG_TIMEDOUT) {
- drive->pc_callback(drive, 0);
- return ide_stopped;
- }
-
/* Clear the interrupt */
stat = tp_ops->read_status(hwif);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- if (hwif->dma_ops->dma_end(drive) ||
- (drive->media == ide_tape && (stat & ATA_ERR))) {
+ int rc;
+
+ drive->waiting_for_dma = 0;
+ rc = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+
+ if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
if (drive->media == ide_floppy)
printk(KERN_ERR "%s: DMA %s error\n",
drive->name, rq_data_dir(pc->rq)
@@ -332,6 +351,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* No more interrupts */
if ((stat & ATA_DRQ) == 0) {
+ int uptodate;
+
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
@@ -370,7 +391,22 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
dsc = 1;
/* Command finished - Call the callback function */
- drive->pc_callback(drive, dsc);
+ uptodate = drive->pc_callback(drive, dsc);
+
+ if (uptodate == 0)
+ drive->failed_pc = NULL;
+
+ if (blk_special_request(rq)) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+ } else {
+ if (blk_fs_request(rq) == 0 && uptodate <= 0) {
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ }
+ ide_complete_rq(drive, uptodate ? 0 : -EIO,
+ ide_rq_bytes(rq));
+ }
return ide_stopped;
}
@@ -428,7 +464,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* FIXME: don't do partial completions */
if (drive->media == ide_floppy)
- ide_end_request(drive, 1, done >> 9);
+ ide_complete_rq(drive, 0,
+ done ? done : ide_rq_bytes(rq));
} else
xferfunc(drive, NULL, pc->cur_pos, bcount);
@@ -440,20 +477,32 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
rq->cmd[0], bcount);
next_irq:
/* And set the interrupt handler again */
- ide_set_handler(drive, ide_pc_intr, timeout, NULL);
+ ide_set_handler(drive, ide_pc_intr, timeout);
return ide_started;
}
+static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
+ u16 bcount, u8 dma)
+{
+ cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
+ cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
+ IDE_TFLAG_OUT_FEATURE | tf_flags;
+ cmd->tf.command = ATA_CMD_PACKET;
+ cmd->tf.feature = dma; /* Use PIO/DMA */
+ cmd->tf.lbam = bcount & 0xff;
+ cmd->tf.lbah = (bcount >> 8) & 0xff;
+}
+
static u8 ide_read_ireason(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_NSECT;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_NSECT;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.nsect & 3;
+ return cmd.tf.nsect & 3;
}
static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
@@ -548,11 +597,13 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
}
+ hwif->expiry = expiry;
+
/* Set the interrupt routine */
ide_set_handler(drive,
(dev_is_idecd(drive) ? drive->irq_handler
: ide_pc_intr),
- timeout, expiry);
+ timeout);
/* Begin DMA, if necessary */
if (dev_is_idecd(drive)) {
@@ -572,23 +623,25 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
return ide_started;
}
-ide_startstop_t ide_issue_pc(ide_drive_t *drive)
+ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_atapi_pc *pc;
ide_hwif_t *hwif = drive->hwif;
ide_expiry_t *expiry = NULL;
+ struct request *rq = hwif->rq;
unsigned int timeout;
u32 tf_flags;
u16 bcount;
+ u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
if (dev_is_idecd(drive)) {
tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
- bcount = ide_cd_get_xferlen(hwif->rq);
+ bcount = ide_cd_get_xferlen(rq);
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;
if (drive->dma)
- drive->dma = !hwif->dma_ops->dma_setup(drive);
+ drive->dma = !ide_dma_prepare(drive, cmd);
} else {
pc = drive->pc;
@@ -606,9 +659,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
ide_dma_off(drive);
}
- if ((pc->flags & PC_FLAG_DMA_OK) &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA))
- drive->dma = !hwif->dma_ops->dma_setup(drive);
+ if (pc->flags & PC_FLAG_DMA_OK)
+ drive->dma = !ide_dma_prepare(drive, cmd);
if (!drive->dma)
pc->flags &= ~PC_FLAG_DMA_OK;
@@ -617,18 +669,18 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
: WAIT_TAPE_CMD;
}
- ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
+ ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma);
- /* Issue the packet command */
- if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
+ (void)do_rw_taskfile(drive, cmd);
+
+ if (drq_int) {
if (drive->dma)
drive->waiting_for_dma = 0;
- ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
- timeout, expiry);
- return ide_started;
- } else {
- ide_execute_pkt_cmd(drive);
- return ide_transfer_pc(drive);
+ hwif->expiry = expiry;
}
+
+ ide_execute_command(drive, cmd, ide_transfer_pc, timeout);
+
+ return drq_int ? ide_started : ide_transfer_pc(drive);
}
EXPORT_SYMBOL_GPL(ide_issue_pc);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index cae69372cf45..091d41435b30 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -4,7 +4,7 @@
* Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov>
* Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org>
* Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de>
- * Copyright (C) 2005, 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
@@ -12,12 +12,9 @@
* See Documentation/cdrom/ide-cd for usage information.
*
* Suggestions are welcome. Patches that work are more welcome though. ;-)
- * For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by
- * anonymous ftp from:
- * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
- * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
+ *
+ * Documentation:
+ * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards.
*
* For historical changelog please see:
* Documentation/ide/ChangeLog.ide-cd.1994-2004
@@ -55,7 +52,7 @@
static DEFINE_MUTEX(idecd_ref_mutex);
-static void ide_cd_release(struct kref *);
+static void ide_cd_release(struct device *);
static struct cdrom_info *ide_cd_get(struct gendisk *disk)
{
@@ -67,7 +64,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk)
if (ide_device_get(cd->drive))
cd = NULL;
else
- kref_get(&cd->kref);
+ get_device(&cd->dev);
}
mutex_unlock(&idecd_ref_mutex);
@@ -79,7 +76,7 @@ static void ide_cd_put(struct cdrom_info *cd)
ide_drive_t *drive = cd->drive;
mutex_lock(&idecd_ref_mutex);
- kref_put(&cd->kref, ide_cd_release);
+ put_device(&cd->dev);
ide_device_put(drive);
mutex_unlock(&idecd_ref_mutex);
}
@@ -100,8 +97,7 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
{
int log = 0;
- ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__,
- sense->sense_key);
+ ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
return 0;
@@ -151,13 +147,12 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
unsigned long bio_sectors;
struct cdrom_info *info = drive->driver_data;
- ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, "
- "sense_key: 0x%x\n", __func__, sense->error_code,
- sense->sense_key);
+ ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
+ sense->error_code, sense->sense_key);
if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n",
- __func__, failed_command->cmd[0]);
+ ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
+ failed_command->cmd[0]);
if (!cdrom_log_sense(drive, failed_command, sense))
return;
@@ -194,6 +189,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
bio_sectors = max(bio_sectors(failed_command->bio), 4U);
sector &= ~(bio_sectors - 1);
+ /*
+ * The SCSI specification allows for the value
+ * returned by READ CAPACITY to be up to 75 2K
+ * sectors past the last readable block.
+ * Therefore, if we hit a medium error within the
+ * last 75 2K sectors, we decrease the saved size
+ * value.
+ */
if (sector < get_capacity(info->disk) &&
drive->probed_capacity - sector < 4 * 75)
set_capacity(info->disk, sector);
@@ -207,9 +210,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command)
{
struct cdrom_info *info = drive->driver_data;
- struct request *rq = &info->request_sense_request;
+ struct request *rq = &drive->request_sense_rq;
- ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_SENSE, "enter");
if (sense == NULL)
sense = &info->sense_data;
@@ -231,77 +234,42 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
rq->buffer = (void *) failed_command;
if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n",
- failed_command->cmd[0]);
+ ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
+ failed_command->cmd[0]);
- ide_do_drive_cmd(drive, rq);
+ drive->hwif->rq = NULL;
+
+ elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
-static void cdrom_end_request(ide_drive_t *drive, int uptodate)
+static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
- struct request *rq = drive->hwif->rq;
- int nsectors = rq->hard_cur_sectors;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, "
- "nsectors: %d\n", __func__, rq->cmd[0], uptodate,
- nsectors);
-
- if (blk_sense_request(rq) && uptodate) {
- /*
- * For REQ_TYPE_SENSE, "rq->buffer" points to the original
- * failed request
- */
- struct request *failed = (struct request *) rq->buffer;
- struct cdrom_info *info = drive->driver_data;
- void *sense = &info->sense_data;
-
- if (failed) {
- if (failed->sense) {
- sense = failed->sense;
- failed->sense_len = rq->sense_len;
- }
- cdrom_analyze_sense_data(drive, failed, sense);
- /*
- * now end the failed request
- */
- if (blk_fs_request(failed)) {
- if (ide_end_dequeued_request(drive, failed, 0,
- failed->hard_nr_sectors))
- BUG();
- } else {
- if (blk_end_request(failed, -EIO,
- failed->data_len))
- BUG();
- }
- } else
- cdrom_analyze_sense_data(drive, NULL, sense);
- }
-
- if (!rq->current_nr_sectors && blk_fs_request(rq))
- uptodate = 1;
- /* make sure it's fully ended */
- if (blk_pc_request(rq))
- nsectors = (rq->data_len + 511) >> 9;
- if (!nsectors)
- nsectors = 1;
-
- ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n",
- __func__, uptodate, nsectors);
+ /*
+ * For REQ_TYPE_SENSE, "rq->buffer" points to the original
+ * failed request
+ */
+ struct request *failed = (struct request *)rq->buffer;
+ struct cdrom_info *info = drive->driver_data;
+ void *sense = &info->sense_data;
- ide_end_request(drive, uptodate, nsectors);
-}
+ if (failed) {
+ if (failed->sense) {
+ sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }
+ cdrom_analyze_sense_data(drive, failed, sense);
-static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
-{
- if (st & 0x80)
- return;
- ide_dump_status(drive, msg, st);
+ if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
+ BUG();
+ } else
+ cdrom_analyze_sense_data(drive, NULL, sense);
}
/*
* Returns:
* 0: if the request should be continued.
- * 1: if the request was ended.
+ * 1: if the request will be going through error recovery.
+ * 2: if the request should be ended.
*/
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
{
@@ -322,15 +290,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
err = ide_read_error(drive);
sense_key = err >> 4;
- if (rq == NULL) {
- printk(KERN_ERR PFX "%s: missing rq in %s\n",
- drive->name, __func__);
- return 1;
- }
-
- ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, "
- "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n",
- __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err);
+ ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, "
+ "rq->cmd_type: 0x%x, err: 0x%x",
+ stat, good_stat, rq->cmd[0], rq->cmd_type,
+ err);
if (blk_sense_request(rq)) {
/*
@@ -339,10 +302,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* Just give up.
*/
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
- ide_error(drive, "request sense failure", stat);
- return 1;
-
+ return 2;
} else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
/* All other functions, except for READ. */
@@ -445,21 +405,19 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* No point in retrying after an illegal request or data
* protect error.
*/
- ide_dump_status_no_sense(drive, "command error", stat);
+ ide_dump_status(drive, "command error", stat);
do_end_request = 1;
} else if (sense_key == MEDIUM_ERROR) {
/*
* No point in re-trying a zillion times on a bad
* sector. If we got here the error is not correctable.
*/
- ide_dump_status_no_sense(drive,
- "media error (bad sector)",
- stat);
+ ide_dump_status(drive, "media error (bad sector)",
+ stat);
do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
/* disk appears blank ?? */
- ide_dump_status_no_sense(drive, "media error (blank)",
- stat);
+ ide_dump_status(drive, "media error (blank)", stat);
do_end_request = 1;
} else if ((err & ~ATA_ABORTED) != 0) {
/* go to the default handler for other errors */
@@ -484,14 +442,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
*/
if (stat & ATA_ERR)
cdrom_queue_request_sense(drive, NULL, NULL);
+ return 1;
} else {
blk_dump_rq_flags(rq, PFX "bad rq");
- cdrom_end_request(drive, 0);
+ return 2;
}
- /* retry, or handle the next request */
- return 1;
-
end_request:
if (stat & ATA_ERR) {
struct request_queue *q = drive->queue;
@@ -504,10 +460,9 @@ end_request:
hwif->rq = NULL;
cdrom_queue_request_sense(drive, rq->sense, rq);
+ return 1;
} else
- cdrom_end_request(drive, 0);
-
- return 1;
+ return 2;
}
/*
@@ -520,8 +475,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
{
ide_hwif_t *hwif = drive->hwif;
- ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n",
- __func__, ireason, rw);
+ ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw);
/*
* ireason == 0: the drive wants to receive data from us
@@ -552,115 +506,28 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
if (rq->cmd_type == REQ_TYPE_ATA_PC)
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
return -1;
}
-/*
- * Assume that the drive will always provide data in multiples of at least
- * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise.
- */
-static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
+static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len);
+ struct request *rq = cmd->rq;
- if ((len % SECTOR_SIZE) == 0)
- return 0;
-
- printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name,
- __func__, len);
-
- if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES)
- printk(KERN_ERR PFX "This drive is not supported by this "
- "version of the driver\n");
- else {
- printk(KERN_ERR PFX "Trying to limit transfer sizes\n");
- drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES;
- }
-
- return 1;
-}
-
-static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
- struct request *rq)
-{
- ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__,
- rq->cmd_flags);
-
- if (rq_data_dir(rq) == READ) {
- unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
- int nskip = rq->sector & (sectors_per_frame - 1);
-
- /*
- * If the requested sector doesn't start on a frame boundary,
- * we must adjust the start of the transfer so that it does,
- * and remember to skip the first few sectors.
- *
- * If the rq->current_nr_sectors field is larger than the size
- * of the buffer, it will mean that we're to skip a number of
- * sectors equal to the amount by which rq->current_nr_sectors
- * is larger than the buffer size.
- */
- if (nskip > 0) {
- /* sanity check... */
- if (rq->current_nr_sectors !=
- bio_cur_sectors(rq->bio)) {
- printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- rq->current_nr_sectors += nskip;
- }
- }
-
- /* set up the command */
- rq->timeout = ATAPI_WAIT_PC;
-
- return ide_started;
-}
-
-/*
- * Fix up a possibly partially-processed request so that we can start it over
- * entirely, or even put it back on the request queue.
- */
-static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
-{
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- if (rq->buffer != bio_data(rq->bio)) {
- sector_t n =
- (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;
-
- rq->buffer = bio_data(rq->bio);
- rq->nr_sectors += n;
- rq->sector -= n;
- }
- rq->current_nr_sectors = bio_cur_sectors(rq->bio);
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->hard_nr_sectors = rq->nr_sectors;
- rq->hard_sector = rq->sector;
- rq->q->prep_rq_fn(rq->q, rq);
-}
-
-static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
-{
- ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n",
- __func__, rq->cmd[0]);
+ ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
/*
* Some of the trailing request sense fields are optional,
* and some drives don't send them. Sigh.
*/
if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
- rq->data_len > 0 && rq->data_len <= 5)
- while (rq->data_len > 0) {
- *(u8 *)rq->data++ = 0;
- --rq->data_len;
+ cmd->nleft > 0 && cmd->nleft <= 5) {
+ unsigned int ofs = cmd->nbytes - cmd->nleft;
+
+ while (cmd->nleft > 0) {
+ *((u8 *)rq->data + ofs++) = 0;
+ cmd->nleft--;
}
+ }
}
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
@@ -676,9 +543,9 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
if (!sense)
sense = &local_sense;
- ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, "
- "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write,
- timeout, cmd_flags);
+ ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
+ "cmd_flags: 0x%x",
+ cmd[0], write, timeout, cmd_flags);
/* start of retry loop */
do {
@@ -740,36 +607,40 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
return (flags & REQ_FAILED) ? -EIO : 0;
}
-/*
- * Called from blk_end_request_callback() after the data of the request is
- * completed and before the request itself is completed. By returning value '1',
- * blk_end_request_callback() returns immediately without completing it.
- */
-static int cdrom_newpc_intr_dummy_cb(struct request *rq)
+static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
- return 1;
+ unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
+
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
+ nr_bytes -= cmd->last_xfer_len;
+
+ if (nr_bytes > 0)
+ ide_complete_rq(drive, 0, nr_bytes);
}
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
- xfer_func_t *xferfunc;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, stat, thislen, uptodate = 0;
- int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
+ int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors;
+ int sense = blk_sense_request(rq);
unsigned int timeout;
u16 len;
u8 ireason;
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n",
- __func__, rq->cmd[0], write);
+ ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x",
+ rq->cmd[0], write);
/* check for errors */
dma = drive->dma;
if (dma) {
drive->dma = 0;
+ drive->waiting_for_dma = 0;
dma_error = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
if (dma_error) {
printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name,
write ? "write" : "read");
@@ -777,28 +648,29 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
}
}
- if (cdrom_decode_status(drive, 0, &stat))
+ rc = cdrom_decode_status(drive, 0, &stat);
+ if (rc) {
+ if (rc == 2)
+ goto out_end;
return ide_stopped;
+ }
/* using dma, transfer is complete now */
if (dma) {
if (dma_error)
return ide_error(drive, "dma error", stat);
- if (blk_fs_request(rq)) {
- ide_end_request(drive, 1, rq->nr_sectors);
- return ide_stopped;
- }
- goto end_request;
+ uptodate = 1;
+ goto out_end;
}
ide_read_bcount_and_ireason(drive, &len, &ireason);
- thislen = blk_fs_request(rq) ? len : rq->data_len;
+ thislen = blk_fs_request(rq) ? len : cmd->nleft;
if (thislen > len)
thislen = len;
- ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n",
- __func__, stat, thislen);
+ ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d",
+ stat, thislen);
/* If DRQ is clear, the command has completed. */
if ((stat & ATA_DRQ) == 0) {
@@ -808,135 +680,62 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
* Otherwise, complete the command normally.
*/
uptodate = 1;
- if (rq->current_nr_sectors > 0) {
+ if (cmd->nleft > 0) {
printk(KERN_ERR PFX "%s: %s: data underrun "
- "(%d blocks)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
+ "(%u bytes)\n", drive->name, __func__,
+ cmd->nleft);
if (!write)
rq->cmd_flags |= REQ_FAILED;
uptodate = 0;
}
- cdrom_end_request(drive, uptodate);
- return ide_stopped;
} else if (!blk_pc_request(rq)) {
- ide_cd_request_sense_fixup(drive, rq);
+ ide_cd_request_sense_fixup(drive, cmd);
/* complain if we still have data left to transfer */
- uptodate = rq->data_len ? 0 : 1;
+ uptodate = cmd->nleft ? 0 : 1;
+ if (uptodate == 0)
+ rq->cmd_flags |= REQ_FAILED;
}
- goto end_request;
+ goto out_end;
}
/* check which way to transfer data */
- if (ide_cd_check_ireason(drive, rq, len, ireason, write))
- return ide_stopped;
-
- if (blk_fs_request(rq)) {
- if (write == 0) {
- int nskip;
-
- if (ide_cd_check_transfer_size(drive, len)) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
-
- /*
- * First, figure out if we need to bit-bucket
- * any of the leading sectors.
- */
- nskip = min_t(int, rq->current_nr_sectors
- - bio_cur_sectors(rq->bio),
- thislen >> 9);
- if (nskip > 0) {
- ide_pad_transfer(drive, write, nskip << 9);
- rq->current_nr_sectors -= nskip;
- thislen -= (nskip << 9);
- }
- }
- }
+ rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
+ if (rc)
+ goto out_end;
- if (ireason == 0) {
- write = 1;
- xferfunc = hwif->tp_ops->output_data;
- } else {
- write = 0;
- xferfunc = hwif->tp_ops->input_data;
- }
+ cmd->last_xfer_len = 0;
- ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, "
- "ireason: 0x%x\n", __func__, rq->cmd_type, ireason);
+ ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, "
+ "ireason: 0x%x",
+ rq->cmd_type, ireason);
/* transfer data */
while (thislen > 0) {
- u8 *ptr = blk_fs_request(rq) ? NULL : rq->data;
- int blen = rq->data_len;
-
- /* bio backed? */
- if (rq->bio) {
- if (blk_fs_request(rq)) {
- ptr = rq->buffer;
- blen = rq->current_nr_sectors << 9;
- } else {
- ptr = bio_data(rq->bio);
- blen = bio_iovec(rq->bio)->bv_len;
- }
- }
+ int blen = min_t(int, thislen, cmd->nleft);
- if (!ptr) {
- if (blk_fs_request(rq) && !write)
- /*
- * If the buffers are full, pipe the rest into
- * oblivion.
- */
- ide_pad_transfer(drive, 0, thislen);
- else {
- printk(KERN_ERR PFX "%s: confused, missing data\n",
- drive->name);
- blk_dump_rq_flags(rq, rq_data_dir(rq)
- ? "cdrom_newpc_intr, write"
- : "cdrom_newpc_intr, read");
- }
+ if (cmd->nleft == 0)
break;
- }
- if (blen > thislen)
- blen = thislen;
-
- xferfunc(drive, NULL, ptr, blen);
+ ide_pio_bytes(drive, cmd, write, blen);
+ cmd->last_xfer_len += blen;
thislen -= blen;
len -= blen;
- if (blk_fs_request(rq)) {
- rq->buffer += blen;
- rq->nr_sectors -= (blen >> 9);
- rq->current_nr_sectors -= (blen >> 9);
- rq->sector += (blen >> 9);
-
- if (rq->current_nr_sectors == 0 && rq->nr_sectors)
- cdrom_end_request(drive, 1);
- } else {
- rq->data_len -= blen;
-
- /*
- * The request can't be completed until DRQ is cleared.
- * So complete the data, but don't complete the request
- * using the dummy function for the callback feature
- * of blk_end_request_callback().
- */
- if (rq->bio)
- blk_end_request_callback(rq, 0, blen,
- cdrom_newpc_intr_dummy_cb);
- else
- rq->data += blen;
- }
- if (!write && blk_sense_request(rq))
+ if (sense && write == 0)
rq->sense_len += blen;
}
/* pad, if necessary */
- if (!blk_fs_request(rq) && len > 0)
- ide_pad_transfer(drive, write, len);
+ if (len > 0) {
+ if (blk_fs_request(rq) == 0 || write == 0)
+ ide_pad_transfer(drive, write, len);
+ else {
+ printk(KERN_ERR PFX "%s: confused, missing data\n",
+ drive->name);
+ blk_dump_rq_flags(rq, "cdrom_newpc_intr");
+ }
+ }
if (blk_pc_request(rq)) {
timeout = rq->timeout;
@@ -946,24 +745,54 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
expiry = ide_cd_expiry;
}
- ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);
+ hwif->expiry = expiry;
+ ide_set_handler(drive, cdrom_newpc_intr, timeout);
return ide_started;
-end_request:
- if (blk_pc_request(rq)) {
+out_end:
+ if (blk_pc_request(rq) && rc == 0) {
unsigned int dlen = rq->data_len;
- if (dma)
- rq->data_len = 0;
+ rq->data_len = 0;
if (blk_end_request(rq, 0, dlen))
BUG();
hwif->rq = NULL;
} else {
- if (!uptodate)
- rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, uptodate);
+ if (sense && uptodate)
+ ide_cd_complete_failed_rq(drive, rq);
+
+ if (blk_fs_request(rq)) {
+ if (cmd->nleft == 0)
+ uptodate = 1;
+ } else {
+ if (uptodate <= 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ }
+
+ if (uptodate == 0)
+ ide_cd_error_cmd(drive, cmd);
+
+ /* make sure it's fully ended */
+ if (blk_pc_request(rq))
+ nsectors = (rq->data_len + 511) >> 9;
+ else
+ nsectors = rq->hard_nr_sectors;
+
+ if (nsectors == 0)
+ nsectors = 1;
+
+ if (blk_fs_request(rq) == 0) {
+ rq->data_len -= (cmd->nbytes - cmd->nleft);
+ if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
+ rq->data_len += cmd->last_xfer_len;
+ }
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ if (sense && rc == 2)
+ ide_error(drive, "request sense failure", stat);
}
return ide_stopped;
}
@@ -971,51 +800,48 @@ end_request:
static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
+ struct request_queue *q = drive->queue;
int write = rq_data_dir(rq) == WRITE;
unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
+ queue_hardsect_size(q) >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
- "secs_per_frame: %u\n",
- __func__, rq->cmd[0], write, sectors_per_frame);
+ ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
+ "secs_per_frame: %u",
+ rq->cmd[0], rq->cmd_flags, sectors_per_frame);
if (write) {
/* disk has become write protected */
- if (get_disk_ro(cd->disk)) {
- cdrom_end_request(drive, 0);
+ if (get_disk_ro(cd->disk))
return ide_stopped;
- }
} else {
/*
* We may be retrying this request after an error. Fix up any
* weirdness which might be present in the request packet.
*/
- ide_cd_restore_request(drive, rq);
+ q->prep_rq_fn(q, rq);
}
- /* use DMA, if possible / writes *must* be hardware frame aligned */
+ /* fs requests *must* be hardware frame aligned */
if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
- (rq->sector & (sectors_per_frame - 1))) {
- if (write) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- drive->dma = 0;
- } else
- drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+ (rq->sector & (sectors_per_frame - 1)))
+ return ide_stopped;
+
+ /* use DMA, if possible */
+ drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
if (write)
cd->devinfo.media_written = 1;
+ rq->timeout = ATAPI_WAIT_PC;
+
return ide_started;
}
static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
{
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, "
- "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0],
- rq->cmd_type);
+ ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
+ rq->cmd[0], rq->cmd_type);
if (blk_pc_request(rq))
rq->cmd_flags |= REQ_QUIET;
@@ -1054,17 +880,18 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
sector_t block)
{
- ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
- "rq->cmd_type: 0x%x, block: %llu\n",
- __func__, rq->cmd[0], rq->cmd_type,
- (unsigned long long)block);
+ struct ide_cmd cmd;
+ int uptodate = 0, nsectors;
+
+ ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
+ rq->cmd[0], (unsigned long long)block);
+
+ if (drive->debug_mask & IDE_DBG_RQ)
+ blk_dump_rq_flags(rq, "ide_cd_do_request");
if (blk_fs_request(rq)) {
if (cdrom_start_rw(drive, rq) == ide_stopped)
- return ide_stopped;
-
- if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
- return ide_stopped;
+ goto out_end;
} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
rq->cmd_type == REQ_TYPE_ATA_PC) {
if (!rq->timeout)
@@ -1073,15 +900,36 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
cdrom_do_block_pc(drive, rq);
} else if (blk_special_request(rq)) {
/* right now this can only be a reset... */
- cdrom_end_request(drive, 1);
- return ide_stopped;
+ uptodate = 1;
+ goto out_end;
} else {
blk_dump_rq_flags(rq, DRV_NAME " bad flags");
- cdrom_end_request(drive, 0);
- return ide_stopped;
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ goto out_end;
}
- return ide_issue_pc(drive);
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
+ ide_init_sg_cmd(&cmd,
+ blk_fs_request(rq) ? (rq->nr_sectors << 9) : rq->data_len);
+ ide_map_sg(drive, &cmd);
+
+ return ide_issue_pc(drive, &cmd);
+out_end:
+ nsectors = rq->hard_nr_sectors;
+
+ if (nsectors == 0)
+ nsectors = 1;
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ return ide_stopped;
}
/*
@@ -1106,7 +954,7 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
struct cdrom_device_info *cdi = &info->devinfo;
unsigned char cmd[BLK_MAX_CDB];
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_TEST_UNIT_READY;
@@ -1134,7 +982,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
unsigned len = sizeof(capbuf);
u32 blocklen;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_READ_CDVD_CAPACITY;
@@ -1166,8 +1014,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
*capacity = 1 + be32_to_cpu(capbuf.lba);
*sectors_per_frame = blocklen >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n",
- __func__, *capacity, *sectors_per_frame);
+ ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu",
+ *capacity, *sectors_per_frame);
return 0;
}
@@ -1178,7 +1026,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
{
unsigned char cmd[BLK_MAX_CDB];
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
@@ -1208,7 +1056,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
long last_written;
unsigned long sectors_per_frame = SECTORS_PER_FRAME;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (toc == NULL) {
/* try to allocate space */
@@ -1370,7 +1218,7 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
struct packet_command cgc;
int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0)
size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
@@ -1390,7 +1238,7 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
struct cdrom_info *cd = drive->driver_data;
u16 curspeed, maxspeed;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
@@ -1400,8 +1248,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
}
- ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n",
- __func__, curspeed, maxspeed);
+ ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
+ curspeed, maxspeed);
cd->current_speed = (curspeed + (176/2)) / 176;
cd->max_speed = (maxspeed + (176/2)) / 176;
@@ -1435,7 +1283,7 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots)
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots);
+ ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots);
devinfo->ops = &ide_cdrom_dops;
devinfo->speed = info->current_speed;
@@ -1458,9 +1306,8 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
mechtype_t mechtype;
int nslots = 1;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, "
- "drive->atapi_flags: 0x%lx\n", __func__, drive->media,
- drive->atapi_flags);
+ ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx",
+ drive->media, drive->atapi_flags);
cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
@@ -1674,9 +1521,6 @@ static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
#endif
static const struct cd_list_entry ide_cd_quirks_list[] = {
- /* Limit transfer size per interrupt. */
- { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_AFLAG_LIMIT_NFRAMES },
- { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_AFLAG_LIMIT_NFRAMES },
/* SCR-3231 doesn't support the SET_CD_SPEED command. */
{ "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT },
/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
@@ -1737,18 +1581,18 @@ static int ide_cdrom_setup(ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
+ struct request_queue *q = drive->queue;
u16 *id = drive->id;
char *fw_rev = (char *)&id[ATA_ID_FW_REV];
int nslots;
- ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_PROBE, "enter");
+
+ blk_queue_prep_rq(q, ide_cdrom_prep_fn);
+ blk_queue_dma_alignment(q, 31);
+ blk_queue_update_dma_pad(q, 15);
- blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
- blk_queue_dma_alignment(drive->queue, 31);
- blk_queue_update_dma_pad(drive->queue, 15);
- drive->queue->unplug_delay = (1 * HZ) / 1000;
- if (!drive->queue->unplug_delay)
- drive->queue->unplug_delay = 1;
+ q->unplug_delay = max((1 * HZ) / 1000, 1);
drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
@@ -1766,8 +1610,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities(drive);
- /* set correct block size */
- blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
+ blk_queue_hardsect_size(q, CD_FRAMESIZE);
if (ide_cdrom_register(drive, nslots)) {
printk(KERN_ERR PFX "%s: %s failed to register device with the"
@@ -1784,23 +1627,25 @@ static void ide_cd_remove(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
ide_proc_unregister_driver(drive, info->driver);
-
+ device_del(&info->dev);
del_gendisk(info->disk);
- ide_cd_put(info);
+ mutex_lock(&idecd_ref_mutex);
+ put_device(&info->dev);
+ mutex_unlock(&idecd_ref_mutex);
}
-static void ide_cd_release(struct kref *kref)
+static void ide_cd_release(struct device *dev)
{
- struct cdrom_info *info = to_ide_drv(kref, cdrom_info);
+ struct cdrom_info *info = to_ide_drv(dev, cdrom_info);
struct cdrom_device_info *devinfo = &info->devinfo;
ide_drive_t *drive = info->drive;
struct gendisk *g = info->disk;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
kfree(info->toc);
if (devinfo->handle == drive)
@@ -1824,7 +1669,6 @@ static struct ide_driver ide_cdrom_driver = {
.remove = ide_cd_remove,
.version = IDECD_VERSION,
.do_request = ide_cd_do_request,
- .end_request = ide_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_cd_proc_entries,
.proc_devsets = ide_cd_proc_devsets,
@@ -1945,9 +1789,6 @@ static struct block_device_operations idecd_ops = {
};
/* module options */
-static char *ignore;
-module_param(ignore, charp, 0400);
-
static unsigned long debug_mask;
module_param(debug_mask, ulong, 0644);
@@ -1959,9 +1800,8 @@ static int ide_cd_probe(ide_drive_t *drive)
struct gendisk *g;
struct request_sense sense;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, "
- "drive->media: 0x%x\n", __func__, drive->driver_req,
- drive->media);
+ ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x",
+ drive->driver_req, drive->media);
if (!strstr("ide-cdrom", drive->driver_req))
goto failed;
@@ -1969,15 +1809,6 @@ static int ide_cd_probe(ide_drive_t *drive)
if (drive->media != ide_cdrom && drive->media != ide_optical)
goto failed;
- /* skip drives that we were told to ignore */
- if (ignore != NULL) {
- if (strstr(ignore, drive->name)) {
- printk(KERN_INFO PFX "ignoring drive %s\n",
- drive->name);
- goto failed;
- }
- }
-
drive->debug_mask = debug_mask;
drive->irq_handler = cdrom_newpc_intr;
@@ -1994,7 +1825,12 @@ static int ide_cd_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
- kref_init(&info->kref);
+ info->dev.parent = &drive->gendev;
+ info->dev.release = ide_cd_release;
+ dev_set_name(&info->dev, dev_name(&drive->gendev));
+
+ if (device_register(&info->dev))
+ goto out_free_disk;
info->drive = drive;
info->driver = &ide_cdrom_driver;
@@ -2008,7 +1844,7 @@ static int ide_cd_probe(ide_drive_t *drive)
g->driverfs_dev = &drive->gendev;
g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
if (ide_cdrom_setup(drive)) {
- ide_cd_release(&info->kref);
+ put_device(&info->dev);
goto failed;
}
@@ -2018,6 +1854,8 @@ static int ide_cd_probe(ide_drive_t *drive)
add_disk(g);
return 0;
+out_free_disk:
+ put_disk(g);
out_free_cd:
kfree(info);
failed:
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index ac40d6cb90a2..1d97101099ce 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -11,7 +11,7 @@
#define IDECD_DEBUG_LOG 0
#if IDECD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
#else
#define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif
@@ -80,7 +80,7 @@ struct cdrom_info {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
- struct kref kref;
+ struct device dev;
/* Buffer for table of contents. NULL if we haven't allocated
a TOC buffer for this device yet. */
@@ -91,8 +91,6 @@ struct cdrom_info {
on this device. */
struct request_sense sense_data;
- struct request request_sense_request;
-
u8 max_speed; /* Max speed of the drive. */
u8 current_speed; /* Current speed of the drive. */
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index f50210fe558f..9e47f3529d55 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -154,6 +154,7 @@ static const struct ide_port_ops idecs_port_ops = {
static const struct ide_port_info idecs_port_info = {
.port_ops = &idecs_port_ops,
.host_flags = IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c
new file mode 100644
index 000000000000..5bf958e5b1d5
--- /dev/null
+++ b/drivers/ide/ide-devsets.c
@@ -0,0 +1,188 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+DEFINE_MUTEX(ide_setting_mtx);
+
+ide_devset_get(io_32bit, io_32bit);
+
+static int set_io_32bit(ide_drive_t *drive, int arg)
+{
+ if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
+ return -EPERM;
+
+ if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
+ return -EINVAL;
+
+ drive->io_32bit = arg;
+
+ return 0;
+}
+
+ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
+
+static int set_ksettings(ide_drive_t *drive, int arg)
+{
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (arg)
+ drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
+ else
+ drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
+
+ return 0;
+}
+
+ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
+
+static int set_using_dma(ide_drive_t *drive, int arg)
+{
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ int err = -EPERM;
+
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (ata_id_has_dma(drive->id) == 0)
+ goto out;
+
+ if (drive->hwif->dma_ops == NULL)
+ goto out;
+
+ err = 0;
+
+ if (arg) {
+ if (ide_set_dma(drive))
+ err = -EIO;
+ } else
+ ide_dma_off(drive);
+
+out:
+ return err;
+#else
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ return -EPERM;
+#endif
+}
+
+/*
+ * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
+ */
+static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
+{
+ switch (req_pio) {
+ case 202:
+ case 201:
+ case 200:
+ case 102:
+ case 101:
+ case 100:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
+ case 9:
+ case 8:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
+ case 7:
+ case 6:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
+ default:
+ return 0;
+ }
+}
+
+static int set_pio_mode(ide_drive_t *drive, int arg)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (arg < 0 || arg > 255)
+ return -EINVAL;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return -ENOSYS;
+
+ if (set_pio_mode_abuse(drive->hwif, arg)) {
+ if (arg == 8 || arg == 9) {
+ unsigned long flags;
+
+ /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
+ spin_lock_irqsave(&hwif->lock, flags);
+ port_ops->set_pio_mode(drive, arg);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ } else
+ port_ops->set_pio_mode(drive, arg);
+ } else {
+ int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+
+ ide_set_pio(drive, arg);
+
+ if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
+ if (keep_dma)
+ ide_dma_on(drive);
+ }
+ }
+
+ return 0;
+}
+
+ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
+
+static int set_unmaskirq(ide_drive_t *drive, int arg)
+{
+ if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
+ return -EPERM;
+
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (arg)
+ drive->dev_flags |= IDE_DFLAG_UNMASK;
+ else
+ drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+
+ return 0;
+}
+
+ide_ext_devset_rw_sync(io_32bit, io_32bit);
+ide_ext_devset_rw_sync(keepsettings, ksettings);
+ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
+ide_ext_devset_rw_sync(using_dma, using_dma);
+__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
+
+int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
+ int arg)
+{
+ struct request_queue *q = drive->queue;
+ struct request *rq;
+ int ret = 0;
+
+ if (!(setting->flags & DS_SYNC))
+ return setting->set(drive, arg);
+
+ rq = blk_get_request(q, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_len = 5;
+ rq->cmd[0] = REQ_DEVSET_EXEC;
+ *(int *)&rq->cmd[1] = arg;
+ rq->special = setting->set;
+
+ if (blk_execute_rq(q, NULL, rq, 0))
+ ret = rq->errors;
+ blk_put_request(rq);
+
+ return ret;
+}
+
+ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
+{
+ int err, (*setfunc)(ide_drive_t *, int) = rq->special;
+
+ err = setfunc(drive, *(int *)&rq->cmd[1]);
+ if (err)
+ rq->errors = err;
+ ide_complete_rq(drive, err, ide_rq_bytes(rq));
+ return ide_stopped;
+}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 806760d24cef..ca934c8a1289 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -28,7 +28,6 @@
#include <linux/mutex.h>
#include <linux/leds.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -53,33 +52,26 @@ static const u8 ide_rw_cmds[] = {
ATA_CMD_WRITE_EXT,
};
-static const u8 ide_data_phases[] = {
- TASKFILE_MULTI_IN,
- TASKFILE_MULTI_OUT,
- TASKFILE_IN,
- TASKFILE_OUT,
- TASKFILE_IN_DMA,
- TASKFILE_OUT_DMA,
-};
-
-static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
+static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma)
{
u8 index, lba48, write;
- lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
- write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
+ lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
+ write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
- if (dma)
+ if (dma) {
+ cmd->protocol = ATA_PROT_DMA;
index = 8;
- else
- index = drive->mult_count ? 0 : 4;
-
- task->tf.command = ide_rw_cmds[index + lba48 + write];
-
- if (dma)
- index = 8; /* fixup index */
+ } else {
+ cmd->protocol = ATA_PROT_PIO;
+ if (drive->mult_count) {
+ cmd->tf_flags |= IDE_TFLAG_MULTI_PIO;
+ index = 0;
+ } else
+ index = 4;
+ }
- task->data_phase = ide_data_phases[index / 2 + write];
+ cmd->tf.command = ide_rw_cmds[index + lba48 + write];
}
/*
@@ -93,8 +85,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
u16 nsectors = (u16)rq->nr_sectors;
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
ide_startstop_t rc;
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
@@ -104,13 +96,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
lba48 = 0;
}
- if (!dma) {
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- }
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (drive->dev_flags & IDE_DFLAG_LBA) {
if (lba48) {
@@ -129,7 +116,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->lbam = (u8)(block >> 8);
tf->lbah = (u8)(block >> 16);
- task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
} else {
tf->nsect = nsectors & 0xff;
tf->lbal = block;
@@ -156,23 +143,27 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->device = head;
}
+ cmd.tf_flags |= IDE_TFLAG_FS;
+
if (rq_data_dir(rq))
- task.tf_flags |= IDE_TFLAG_WRITE;
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ ide_tf_set_cmd(drive, &cmd, dma);
+ cmd.rq = rq;
- ide_tf_set_cmd(drive, &task, dma);
- if (!dma)
- hwif->data_phase = task.data_phase;
- task.rq = rq;
+ if (dma == 0) {
+ ide_init_sg_cmd(&cmd, nsectors << 9);
+ ide_map_sg(drive, &cmd);
+ }
- rc = do_rw_taskfile(drive, &task);
+ rc = do_rw_taskfile(drive, &cmd);
if (rc == ide_stopped && dma) {
/* fallback to PIO */
- task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
- ide_tf_set_cmd(drive, &task, 0);
- hwif->data_phase = task.data_phase;
- ide_init_sg_cmd(drive, rq);
- rc = do_rw_taskfile(drive, &task);
+ cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
+ ide_tf_set_cmd(drive, &cmd, 0);
+ ide_init_sg_cmd(&cmd, nsectors << 9);
+ rc = do_rw_taskfile(drive, &cmd);
}
return rc;
@@ -193,7 +184,9 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
if (!blk_fs_request(rq)) {
blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
- ide_end_request(drive, 0, 0);
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
return ide_stopped;
}
@@ -216,22 +209,22 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
*/
static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u64 addr = 0;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
if (lba48)
tf->command = ATA_CMD_READ_NATIVE_MAX_EXT;
else
tf->command = ATA_CMD_READ_NATIVE_MAX;
tf->device = ATA_LBA;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
- /* submit command request */
- ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+
+ ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
if ((tf->status & 0x01) == 0)
@@ -246,13 +239,13 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
*/
static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u64 addr_set = 0;
addr_req--;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(ide_task_t));
+
+ memset(&cmd, 0, sizeof(cmd));
tf->lbal = (addr_req >> 0) & 0xff;
tf->lbam = (addr_req >>= 8) & 0xff;
tf->lbah = (addr_req >>= 8) & 0xff;
@@ -266,11 +259,13 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
tf->command = ATA_CMD_SET_MAX;
}
tf->device |= ATA_LBA;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
- /* submit command request */
- ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+
+ ide_no_data_taskfile(drive, &cmd);
+
/* if OK, compute maximum address value */
if ((tf->status & 0x01) == 0)
addr_set = ide_get_lba_addr(tf, lba48) + 1;
@@ -389,24 +384,24 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
{
ide_drive_t *drive = q->queuedata;
- ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC);
+ struct ide_cmd *cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
/* FIXME: map struct ide_taskfile on rq->cmd[] */
- BUG_ON(task == NULL);
+ BUG_ON(cmd == NULL);
- memset(task, 0, sizeof(*task));
+ memset(cmd, 0, sizeof(*cmd));
if (ata_id_flush_ext_enabled(drive->id) &&
(drive->capacity64 >= (1UL << 28)))
- task->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd->tf.command = ATA_CMD_FLUSH_EXT;
else
- task->tf.command = ATA_CMD_FLUSH;
- task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
- IDE_TFLAG_DYN;
- task->data_phase = TASKFILE_NO_DATA;
+ cmd->tf.command = ATA_CMD_FLUSH;
+ cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
+ IDE_TFLAG_DYN;
+ cmd->protocol = ATA_PROT_NODATA;
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
rq->cmd_flags |= REQ_SOFTBARRIER;
- rq->special = task;
+ rq->special = cmd;
}
ide_devset_get(multcount, mult_count);
@@ -456,15 +451,15 @@ static int set_nowerr(ide_drive_t *drive, int arg)
static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf.feature = feature;
- task.tf.nsect = nsect;
- task.tf.command = ATA_CMD_SET_FEATURES;
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.feature = feature;
+ cmd.tf.nsect = nsect;
+ cmd.tf.command = ATA_CMD_SET_FEATURES;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &task);
+ return ide_no_data_taskfile(drive, &cmd);
}
static void update_ordered(ide_drive_t *drive)
@@ -531,15 +526,16 @@ static int set_wcache(ide_drive_t *drive, int arg)
static int do_idedisk_flushcache(ide_drive_t *drive)
{
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
if (ata_id_flush_ext_enabled(drive->id))
- args.tf.command = ATA_CMD_FLUSH_EXT;
+ cmd.tf.command = ATA_CMD_FLUSH_EXT;
else
- args.tf.command = ATA_CMD_FLUSH;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &args);
+ cmd.tf.command = ATA_CMD_FLUSH;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ return ide_no_data_taskfile(drive, &cmd);
}
ide_devset_get(acoustic, acoustic);
@@ -711,17 +707,17 @@ static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk)
static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
int on)
{
- ide_task_t task;
+ struct ide_cmd cmd;
int ret;
if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
return 0;
- memset(&task, 0, sizeof(task));
- task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- ret = ide_no_data_taskfile(drive, &task);
+ ret = ide_no_data_taskfile(drive, &cmd);
if (ret)
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
@@ -737,6 +733,5 @@ const struct ide_disk_ops ide_ata_disk_ops = {
.init_media = ide_disk_init_media,
.set_doorlock = ide_disk_set_doorlock,
.do_request = ide_do_rw_disk,
- .end_request = ide_end_request,
.ioctl = ide_disk_ioctl,
};
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 1146f4204c6e..3f2a0788978b 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -1,38 +1,38 @@
#include <linux/kernel.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include "ide-disk.h"
static int smart_enable(ide_drive_t *drive)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = ATA_SMART_ENABLE;
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ return ide_no_data_taskfile(drive, &cmd);
}
static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = sub_cmd;
tf->nsect = 0x01;
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args.data_phase = TASKFILE_IN;
- (void) smart_enable(drive);
- return ide_raw_taskfile(drive, &args, buf, 1);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.protocol = ATA_PROT_PIO;
+
+ return ide_raw_taskfile(drive, &cmd, buf, 1);
}
static int proc_idedisk_read_cache
@@ -67,6 +67,8 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off,
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
+ (void)smart_enable(drive);
+
if (get_smart_data(drive, page, sub_cmd) == 0) {
unsigned short *val = (unsigned short *) page;
char *out = (char *)val + SECTOR_SIZE;
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 123d393658af..f8c7d0cd2ff8 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -111,7 +111,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
* May also be invoked from trm290.c
*/
-int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
__le32 *table = (__le32 *)hwif->dmatable_cpu;
@@ -120,11 +120,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
struct scatterlist *sg;
u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);
- hwif->sg_nents = ide_build_sglist(drive, rq);
- if (hwif->sg_nents == 0)
- return 0;
-
- for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+ for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
u32 cur_addr, cur_len, xcount, bcount;
cur_addr = sg_dma_address(sg);
@@ -170,8 +166,6 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
EXPORT_SYMBOL_GPL(ide_build_dmatable);
@@ -179,6 +173,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
/**
* ide_dma_setup - begin a DMA phase
* @drive: target device
+ * @cmd: command
*
* Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers for a device
@@ -189,17 +184,16 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
* is returned.
*/
-int ide_dma_setup(ide_drive_t *drive)
+int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
u8 dma_stat;
/* fall back to pio! */
- if (!ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (ide_build_dmatable(drive, cmd) == 0) {
+ ide_map_sg(drive, cmd);
return 1;
}
@@ -212,9 +206,9 @@ int ide_dma_setup(ide_drive_t *drive)
/* specify r/w */
if (mmio)
- writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+ writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
else
- outb(reading, hwif->dma_base + ATA_DMA_CMD);
+ outb(rw, hwif->dma_base + ATA_DMA_CMD);
/* read DMA status for INTR & ERROR flags */
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -222,13 +216,12 @@ int ide_dma_setup(ide_drive_t *drive)
/* clear INTR & ERROR flags */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- drive->waiting_for_dma = 1;
return 0;
}
EXPORT_SYMBOL_GPL(ide_dma_setup);
/**
- * dma_timer_expiry - handle a DMA timeout
+ * ide_dma_sff_timer_expiry - handle a DMA timeout
* @drive: Drive that timed out
*
* An IDE DMA transfer timed out. In the event of an error we ask
@@ -241,7 +234,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
* This can occur if an interrupt is lost or due to hang or bugs.
*/
-static int dma_timer_expiry(ide_drive_t *drive)
+int ide_dma_sff_timer_expiry(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -265,14 +258,7 @@ static int dma_timer_expiry(ide_drive_t *drive)
return 0; /* Status is unknown -- reset the bus */
}
-
-void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
- dma_timer_expiry);
-}
-EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
+EXPORT_SYMBOL_GPL(ide_dma_sff_timer_expiry);
void ide_dma_start(ide_drive_t *drive)
{
@@ -303,8 +289,6 @@ int ide_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0, mask;
- drive->waiting_for_dma = 0;
-
/* stop DMA */
if (hwif->host_flags & IDE_HFLAG_MMIO) {
dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
@@ -321,8 +305,6 @@ int ide_dma_end(ide_drive_t *drive)
/* clear INTR & ERROR bits */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
wmb();
/* verify good DMA status */
@@ -346,12 +328,11 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq);
const struct ide_dma_ops sff_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
EXPORT_SYMBOL_GPL(sff_dma_ops);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 72ebab0bc755..a5612eadc306 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -89,16 +89,21 @@ static const struct drive_list_entry drive_blacklist[] = {
ide_startstop_t ide_dma_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
u8 stat = 0, dma_stat = 0;
+ drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
if (!dma_stat) {
- struct request *rq = hwif->rq;
-
- task_end_request(drive, rq, stat);
+ if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+ ide_finish_cmd(drive, cmd, stat);
+ else
+ ide_complete_rq(drive, 0,
+ cmd->rq->nr_sectors << 9);
return ide_stopped;
}
printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n",
@@ -106,7 +111,6 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive)
}
return ide_error(drive, "dma_intr", stat);
}
-EXPORT_SYMBOL_GPL(ide_dma_intr);
int ide_dma_good_drive(ide_drive_t *drive)
{
@@ -114,9 +118,9 @@ int ide_dma_good_drive(ide_drive_t *drive)
}
/**
- * ide_build_sglist - map IDE scatter gather for DMA I/O
- * @drive: the drive to build the DMA table for
- * @rq: the request holding the sg list
+ * ide_dma_map_sg - map IDE scatter gather for DMA I/O
+ * @drive: the drive to map the DMA table for
+ * @cmd: command
*
* Perform the DMA mapping magic necessary to access the source or
* target buffers of a request via DMA. The lower layers of the
@@ -124,25 +128,28 @@ int ide_dma_good_drive(ide_drive_t *drive)
* operate in a portable fashion.
*/
-int ide_build_sglist(ide_drive_t *drive, struct request *rq)
+static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
+ int i;
- ide_map_sg(drive, rq);
-
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
+ cmd->sg_dma_direction = DMA_TO_DEVICE;
else
- hwif->sg_dma_direction = DMA_TO_DEVICE;
+ cmd->sg_dma_direction = DMA_FROM_DEVICE;
+
+ i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
+ if (i) {
+ cmd->orig_sg_nents = cmd->sg_nents;
+ cmd->sg_nents = i;
+ }
- return dma_map_sg(hwif->dev, sg, hwif->sg_nents,
- hwif->sg_dma_direction);
+ return i;
}
-EXPORT_SYMBOL_GPL(ide_build_sglist);
/**
- * ide_destroy_dmatable - clean up DMA mapping
+ * ide_dma_unmap_sg - clean up DMA mapping
* @drive: The drive to unmap
*
* Teardown mappings after DMA has completed. This must be called
@@ -152,14 +159,14 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
* time.
*/
-void ide_destroy_dmatable(ide_drive_t *drive)
+void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents,
- hwif->sg_dma_direction);
+ dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents,
+ cmd->sg_dma_direction);
}
-EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
+EXPORT_SYMBOL_GPL(ide_dma_unmap_sg);
/**
* ide_dma_off_quietly - Generic DMA kill
@@ -449,20 +456,75 @@ void ide_dma_lost_irq(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
-void ide_dma_timeout(ide_drive_t *drive)
+/*
+ * un-busy the port etc, and clear any pending DMA status. we want to
+ * retry the current request in pio mode instead of risking tossing it
+ * all away
+ */
+ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_dma_ops *dma_ops = hwif->dma_ops;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct request *rq;
+ ide_startstop_t ret = ide_stopped;
- printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+ /*
+ * end current dma transaction
+ */
- if (hwif->dma_ops->dma_test_irq(drive))
- return;
+ if (error < 0) {
+ printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+ ret = ide_error(drive, "dma timeout error",
+ hwif->tp_ops->read_status(hwif));
+ } else {
+ printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
+ if (dma_ops->dma_clear)
+ dma_ops->dma_clear(drive);
+ printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+ if (dma_ops->dma_test_irq(drive) == 0) {
+ ide_dump_status(drive, "DMA timeout",
+ hwif->tp_ops->read_status(hwif));
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+ }
+ }
- ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
+ /*
+ * disable dma for now, but remember that we did so because of
+ * a timeout -- we'll reenable after we finish this next request
+ * (or rather the first chunk of it) in pio.
+ */
+ drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
+ drive->retry_pio++;
+ ide_dma_off_quietly(drive);
- hwif->dma_ops->dma_end(drive);
+ /*
+ * un-busy drive etc and make sure request is sane
+ */
+
+ rq = hwif->rq;
+ if (!rq)
+ goto out;
+
+ hwif->rq = NULL;
+
+ rq->errors = 0;
+
+ if (!rq->bio)
+ goto out;
+
+ rq->sector = rq->bio->bi_sector;
+ rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+ rq->hard_cur_sectors = rq->current_nr_sectors;
+ rq->buffer = bio_data(rq->bio);
+out:
+ return ret;
}
-EXPORT_SYMBOL_GPL(ide_dma_timeout);
void ide_release_dma_engine(ide_hwif_t *hwif)
{
@@ -499,3 +561,25 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif)
return 0;
}
EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
+
+int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops;
+
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
+ (dma_ops->dma_check && dma_ops->dma_check(drive, cmd)))
+ goto out;
+ ide_map_sg(drive, cmd);
+ if (ide_dma_map_sg(drive, cmd) == 0)
+ goto out_map;
+ if (dma_ops->dma_setup(drive, cmd))
+ goto out_dma_unmap;
+ drive->waiting_for_dma = 1;
+ return 0;
+out_dma_unmap:
+ ide_dma_unmap_sg(drive, cmd);
+out_map:
+ ide_map_sg(drive, cmd);
+out:
+ return 1;
+}
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c
new file mode 100644
index 000000000000..11664976eea3
--- /dev/null
+++ b/drivers/ide/ide-eh.c
@@ -0,0 +1,440 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+
+static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else if (stat & ATA_ERR) {
+ /* err has different meaning on cdrom and tape */
+ if (err == ATA_ABORTED) {
+ if ((drive->dev_flags & IDE_DFLAG_LBA) &&
+ /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
+ hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
+ return ide_stopped;
+ } else if ((err & BAD_CRC) == BAD_CRC) {
+ /* UDMA crc error, just retry the operation */
+ drive->crc_count++;
+ } else if (err & (ATA_BBK | ATA_UNC)) {
+ /* retries won't help these */
+ rq->errors = ERROR_MAX;
+ } else if (err & ATA_TRK0NF) {
+ /* help it find track zero */
+ rq->errors |= ERROR_RECAL;
+ }
+ }
+
+ if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
+ (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
+ int nsect = drive->mult_count ? drive->mult_count : 1;
+
+ ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
+ }
+
+ if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
+ ide_kill_rq(drive, rq);
+ return ide_stopped;
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ rq->errors |= ERROR_RESET;
+
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+
+ if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ drive->special.b.recalibrate = 1;
+
+ ++rq->errors;
+
+ return ide_stopped;
+}
+
+static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else {
+ /* add decoding error stuff */
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ /* force an abort */
+ hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+
+ if (rq->errors >= ERROR_MAX) {
+ ide_kill_rq(drive, rq);
+ } else {
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+ ++rq->errors;
+ }
+
+ return ide_stopped;
+}
+
+static ide_startstop_t __ide_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ if (drive->media == ide_disk)
+ return ide_ata_error(drive, rq, stat, err);
+ return ide_atapi_error(drive, rq, stat, err);
+}
+
+/**
+ * ide_error - handle an error on the IDE
+ * @drive: drive the error occurred on
+ * @msg: message to report
+ * @stat: status bits
+ *
+ * ide_error() takes action based on the error returned by the drive.
+ * For normal I/O that may well include retries. We deal with
+ * both new-style (taskfile) and old style command handling here.
+ * In the case of taskfile command handling there is work left to
+ * do
+ */
+
+ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
+{
+ struct request *rq;
+ u8 err;
+
+ err = ide_dump_status(drive, msg, stat);
+
+ rq = drive->hwif->rq;
+ if (rq == NULL)
+ return ide_stopped;
+
+ /* retry only "normal" I/O: */
+ if (!blk_fs_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+ struct ide_cmd *cmd = rq->special;
+
+ if (cmd)
+ ide_complete_cmd(drive, cmd, stat, err);
+ } else if (blk_pm_request(rq)) {
+ rq->errors = 1;
+ ide_complete_pm_rq(drive, rq);
+ return ide_stopped;
+ }
+ rq->errors = err;
+ ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
+ return ide_stopped;
+ }
+
+ return __ide_error(drive, rq, stat, err);
+}
+EXPORT_SYMBOL_GPL(ide_error);
+
+static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
+{
+ struct request *rq = drive->hwif->rq;
+
+ if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) {
+ if (err <= 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq));
+ }
+}
+
+/* needed below */
+static ide_startstop_t do_reset1(ide_drive_t *, int);
+
+/*
+ * atapi_reset_pollfunc() gets invoked to poll the interface for completion
+ * every 50ms during an atapi drive reset operation. If the drive has not yet
+ * responded, and we have not yet hit our maximum waiting time, then the timer
+ * is restarted for another 50ms.
+ */
+static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 stat;
+
+ SELECT_DRIVE(drive);
+ udelay(10);
+ stat = hwif->tp_ops->read_status(hwif);
+
+ if (OK_STAT(stat, 0, ATA_BUSY))
+ printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
+ else {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
+ /* continue polling */
+ return ide_started;
+ }
+ /* end of polling */
+ hwif->polling = 0;
+ printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
+ drive->name, stat);
+ /* do it the old fashioned way */
+ return do_reset1(drive, 1);
+ }
+ /* done polling */
+ hwif->polling = 0;
+ ide_complete_drive_reset(drive, 0);
+ return ide_stopped;
+}
+
+static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
+{
+ static const char *err_master_vals[] =
+ { NULL, "passed", "formatter device error",
+ "sector buffer error", "ECC circuitry error",
+ "controlling MPU error" };
+
+ u8 err_master = err & 0x7f;
+
+ printk(KERN_ERR "%s: reset: master: ", hwif->name);
+ if (err_master && err_master < 6)
+ printk(KERN_CONT "%s", err_master_vals[err_master]);
+ else
+ printk(KERN_CONT "error (0x%02x?)", err);
+ if (err & 0x80)
+ printk(KERN_CONT "; slave: failed");
+ printk(KERN_CONT "\n");
+}
+
+/*
+ * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
+ * during an ide reset operation. If the drives have not yet responded,
+ * and we have not yet hit our maximum waiting time, then the timer is restarted
+ * for another 50ms.
+ */
+static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+ u8 tmp;
+ int err = 0;
+
+ if (port_ops && port_ops->reset_poll) {
+ err = port_ops->reset_poll(drive);
+ if (err) {
+ printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
+ hwif->name, drive->name);
+ goto out;
+ }
+ }
+
+ tmp = hwif->tp_ops->read_status(hwif);
+
+ if (!OK_STAT(tmp, 0, ATA_BUSY)) {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &reset_pollfunc, HZ/20);
+ /* continue polling */
+ return ide_started;
+ }
+ printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n",
+ hwif->name, tmp);
+ drive->failures++;
+ err = -EIO;
+ } else {
+ tmp = ide_read_error(drive);
+
+ if (tmp == 1) {
+ printk(KERN_INFO "%s: reset: success\n", hwif->name);
+ drive->failures = 0;
+ } else {
+ ide_reset_report_error(hwif, tmp);
+ drive->failures++;
+ err = -EIO;
+ }
+ }
+out:
+ hwif->polling = 0; /* done polling */
+ ide_complete_drive_reset(drive, err);
+ return ide_stopped;
+}
+
+static void ide_disk_pre_reset(ide_drive_t *drive)
+{
+ int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
+
+ drive->special.all = 0;
+ drive->special.b.set_geometry = legacy;
+ drive->special.b.recalibrate = legacy;
+
+ drive->mult_count = 0;
+ drive->dev_flags &= ~IDE_DFLAG_PARKED;
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
+ (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
+ drive->mult_req = 0;
+
+ if (drive->mult_req != drive->mult_count)
+ drive->special.b.set_multmode = 1;
+}
+
+static void pre_reset(ide_drive_t *drive)
+{
+ const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+
+ if (drive->media == ide_disk)
+ ide_disk_pre_reset(drive);
+ else
+ drive->dev_flags |= IDE_DFLAG_POST_RESET;
+
+ if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
+ if (drive->crc_count)
+ ide_check_dma_crc(drive);
+ else
+ ide_dma_off(drive);
+ }
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
+ drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+ drive->io_32bit = 0;
+ }
+ return;
+ }
+
+ if (port_ops && port_ops->pre_reset)
+ port_ops->pre_reset(drive);
+
+ if (drive->current_speed != 0xff)
+ drive->desired_speed = drive->current_speed;
+ drive->current_speed = 0xff;
+}
+
+/*
+ * do_reset1() attempts to recover a confused drive by resetting it.
+ * Unfortunately, resetting a disk drive actually resets all devices on
+ * the same interface, so it can really be thought of as resetting the
+ * interface rather than resetting the drive.
+ *
+ * ATAPI devices have their own reset mechanism which allows them to be
+ * individually reset without clobbering other devices on the same interface.
+ *
+ * Unfortunately, the IDE interface does not generate an interrupt to let
+ * us know when the reset operation has finished, so we must poll for this.
+ * Equally poor, though, is the fact that this may a very long time to complete,
+ * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
+ * we set a timer to poll at 50ms intervals.
+ */
+static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ const struct ide_port_ops *port_ops;
+ ide_drive_t *tdrive;
+ unsigned long flags, timeout;
+ int i;
+ DEFINE_WAIT(wait);
+
+ spin_lock_irqsave(&hwif->lock, flags);
+
+ /* We must not reset with running handlers */
+ BUG_ON(hwif->handler != NULL);
+
+ /* For an ATAPI device, first try an ATAPI SRST. */
+ if (drive->media != ide_disk && !do_not_try_atapi) {
+ pre_reset(drive);
+ SELECT_DRIVE(drive);
+ udelay(20);
+ tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
+ ndelay(400);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+ }
+
+ /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
+ do {
+ unsigned long now;
+
+ prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
+ timeout = jiffies;
+ ide_port_for_each_present_dev(i, tdrive, hwif) {
+ if ((tdrive->dev_flags & IDE_DFLAG_PARKED) &&
+ time_after(tdrive->sleep, timeout))
+ timeout = tdrive->sleep;
+ }
+
+ now = jiffies;
+ if (time_before_eq(timeout, now))
+ break;
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ timeout = schedule_timeout_uninterruptible(timeout - now);
+ spin_lock_irqsave(&hwif->lock, flags);
+ } while (timeout);
+ finish_wait(&ide_park_wq, &wait);
+
+ /*
+ * First, reset any device state data we were maintaining
+ * for any of the drives on this interface.
+ */
+ ide_port_for_each_dev(i, tdrive, hwif)
+ pre_reset(tdrive);
+
+ if (io_ports->ctl_addr == 0) {
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ ide_complete_drive_reset(drive, -ENXIO);
+ return ide_stopped;
+ }
+
+ /*
+ * Note that we also set nIEN while resetting the device,
+ * to mask unwanted interrupts from the interface during the reset.
+ * However, due to the design of PC hardware, this will cause an
+ * immediate interrupt due to the edge transition it produces.
+ * This single interrupt gives us a "fast poll" for drives that
+ * recover from reset very quickly, saving us the first 50ms wait time.
+ *
+ * TODO: add ->softreset method and stop abusing ->set_irq
+ */
+ /* set SRST and nIEN */
+ tp_ops->set_irq(hwif, 4);
+ /* more than enough time */
+ udelay(10);
+ /* clear SRST, leave nIEN (unless device is on the quirk list) */
+ tp_ops->set_irq(hwif, drive->quirk_list == 2);
+ /* more than enough time */
+ udelay(10);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &reset_pollfunc, HZ/20);
+
+ /*
+ * Some weird controller like resetting themselves to a strange
+ * state when the disks are reset this way. At least, the Winbond
+ * 553 documentation says that
+ */
+ port_ops = hwif->port_ops;
+ if (port_ops && port_ops->resetproc)
+ port_ops->resetproc(drive);
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+}
+
+/*
+ * ide_do_reset() is the entry point to the drive/interface reset code.
+ */
+
+ide_startstop_t ide_do_reset(ide_drive_t *drive)
+{
+ return do_reset1(drive, 0);
+}
+EXPORT_SYMBOL(ide_do_reset);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 3eab1c6c9b31..50d918a21553 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -61,50 +61,6 @@
*/
#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
-/* Error code returned in rq->errors to the higher part of the driver. */
-#define IDEFLOPPY_ERROR_GENERAL 101
-
-/*
- * Used to finish servicing a request. For read/write requests, we will call
- * ide_end_request to pass to the next buffer.
- */
-static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
-{
- struct ide_disk_obj *floppy = drive->driver_data;
- struct request *rq = drive->hwif->rq;
- int error;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- switch (uptodate) {
- case 0:
- error = IDEFLOPPY_ERROR_GENERAL;
- break;
-
- case 1:
- error = 0;
- break;
-
- default:
- error = uptodate;
- }
-
- if (error)
- floppy->failed_pc = NULL;
- /* Why does this happen? */
- if (!rq)
- return 0;
- if (!blk_special_request(rq)) {
- /* our real local end request function */
- ide_end_request(drive, uptodate, nsecs);
- return 0;
- }
- rq->errors = error;
- /* fixme: need to move this local also */
- ide_end_drive_cmd(drive, 0, 0);
- return 0;
-}
-
static void idefloppy_update_buffers(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
@@ -112,22 +68,23 @@ static void idefloppy_update_buffers(ide_drive_t *drive,
struct bio *bio = rq->bio;
while ((bio = rq->bio) != NULL)
- ide_floppy_end_request(drive, 1, 0);
+ ide_complete_rq(drive, 0, ide_rq_bytes(rq));
}
-static void ide_floppy_callback(ide_drive_t *drive, int dsc)
+static int ide_floppy_callback(ide_drive_t *drive, int dsc)
{
struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
+ struct request *rq = pc->rq;
int uptodate = pc->error ? 0 : 1;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
- if (floppy->failed_pc == pc)
- floppy->failed_pc = NULL;
+ if (drive->failed_pc == pc)
+ drive->failed_pc = NULL;
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
- (pc->rq && blk_pc_request(pc->rq)))
+ (rq && blk_pc_request(rq)))
uptodate = 1; /* FIXME */
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
u8 *buf = pc->buf;
@@ -139,19 +96,22 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
floppy->progress_indication = buf[15] & 0x80 ?
(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
- if (floppy->failed_pc)
- ide_debug_log(IDE_DBG_PC, "pc = %x, ",
- floppy->failed_pc->c[0]);
+ if (drive->failed_pc)
+ ide_debug_log(IDE_DBG_PC, "pc = %x",
+ drive->failed_pc->c[0]);
ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x,"
- "ascq = %x\n", floppy->sense_key,
+ "ascq = %x", floppy->sense_key,
floppy->asc, floppy->ascq);
} else
printk(KERN_ERR PFX "Error in REQUEST SENSE itself - "
"Aborting request!\n");
}
- ide_floppy_end_request(drive, uptodate, 0);
+ if (blk_special_request(rq))
+ rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
+
+ return uptodate;
}
static void ide_floppy_report_error(struct ide_disk_obj *floppy,
@@ -170,14 +130,15 @@ static void ide_floppy_report_error(struct ide_disk_obj *floppy,
}
-static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
+static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
+ struct ide_cmd *cmd,
+ struct ide_atapi_pc *pc)
{
struct ide_disk_obj *floppy = drive->driver_data;
- if (floppy->failed_pc == NULL &&
+ if (drive->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE)
- floppy->failed_pc = pc;
+ drive->failed_pc = pc;
/* Set the current packet command */
drive->pc = pc;
@@ -186,18 +147,18 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
ide_floppy_report_error(floppy, pc);
/* Giving up */
- pc->error = IDEFLOPPY_ERROR_GENERAL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
- floppy->failed_pc = NULL;
+ drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
return ide_stopped;
}
- ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries);
+ ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries);
pc->retries++;
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, cmd);
}
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -242,8 +203,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
int blocks = rq->nr_sectors / floppy->bs_factor;
int cmd = rq_data_dir(rq);
- ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__,
- block, blocks);
+ ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
ide_init_pc(pc);
pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
@@ -285,34 +245,34 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
{
struct ide_disk_obj *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd cmd;
struct ide_atapi_pc *pc;
- ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
- "errors: %d\n",
- __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?",
- rq->cmd[0], rq->cmd_type, rq->errors);
-
- ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, "
- "current_nr_sectors: %d\n",
- __func__, (long)rq->sector, rq->nr_sectors,
- rq->current_nr_sectors);
+ if (drive->debug_mask & IDE_DBG_RQ)
+ blk_dump_rq_flags(rq, (rq->rq_disk
+ ? rq->rq_disk->disk_name
+ : "dev?"));
if (rq->errors >= ERROR_MAX) {
- if (floppy->failed_pc)
- ide_floppy_report_error(floppy, floppy->failed_pc);
- else
+ if (drive->failed_pc) {
+ ide_floppy_report_error(floppy, drive->failed_pc);
+ drive->failed_pc = NULL;
+ } else
printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ if (blk_special_request(rq)) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+ return ide_stopped;
+ } else
+ goto out_end;
}
if (blk_fs_request(rq)) {
if (((long)rq->sector % floppy->bs_factor) ||
(rq->nr_sectors % floppy->bs_factor)) {
printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
pc = &floppy->queued_pc;
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
@@ -323,19 +283,31 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
idefloppy_blockpc_cmd(floppy, pc, rq);
} else {
blk_dump_rq_flags(rq, PFX "unsupported command in queue");
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
+ ide_init_sg_cmd(&cmd, rq->nr_sectors << 9);
+ ide_map_sg(drive, &cmd);
pc->sg = hwif->sg_table;
- pc->sg_cnt = hwif->sg_nents;
+ pc->sg_cnt = cmd.sg_nents;
pc->rq = rq;
- return idefloppy_issue_pc(drive, pc);
+ return ide_floppy_issue_pc(drive, &cmd, pc);
+out_end:
+ drive->failed_pc = NULL;
+ if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
+ return ide_stopped;
}
/*
@@ -411,7 +383,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *cap_desc;
- u8 header_len, desc_cnt;
+ u8 pc_buf[256], header_len, desc_cnt;
int i, rc = 1, blocks, length;
drive->bios_cyl = 0;
@@ -421,6 +393,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive->capacity64 = 0;
ide_floppy_create_read_capacity_cmd(&pc);
+ pc.buf = &pc_buf[0];
+ pc.buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR PFX "Can't get floppy parameters\n");
return 1;
@@ -436,8 +411,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, "
- "%d sector size\n",
- i, blocks * length / 1024, blocks, length);
+ "%d sector size",
+ i, blocks * length / 1024,
+ blocks, length);
if (i)
continue;
@@ -493,8 +469,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
"in drive\n", drive->name);
break;
}
- ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n",
- pc.buf[desc_start + 4] & 0x03);
+ ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d",
+ pc.buf[desc_start + 4] & 0x03);
}
/* Clik! disk does not support get_flexible_disk_page */
@@ -573,6 +549,5 @@ const struct ide_disk_ops ide_atapi_disk_ops = {
.init_media = ide_floppy_init_media,
.set_doorlock = ide_set_media_lock,
.do_request = ide_floppy_do_request,
- .end_request = ide_floppy_end_request,
.ioctl = ide_floppy_ioctl,
};
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index 8f8be8546038..cd8a42027ede 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -36,9 +36,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
int __user *arg)
{
struct ide_disk_obj *floppy = drive->driver_data;
- u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
int __user *argp;
+ u8 pc_buf[256], header_len, desc_cnt;
if (get_user(u_array_size, arg))
return -EFAULT;
@@ -47,6 +47,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return -EINVAL;
ide_floppy_create_read_capacity_cmd(pc);
+ pc->buf = &pc_buf[0];
+ pc->buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, floppy->disk, pc)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return -EIO;
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 7857b209c6df..1aebdf1a4f58 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -25,7 +25,7 @@ module_param(debug_mask, ulong, 0644);
static DEFINE_MUTEX(ide_disk_ref_mutex);
-static void ide_disk_release(struct kref *);
+static void ide_disk_release(struct device *);
static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
{
@@ -37,7 +37,7 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
if (ide_device_get(idkp->drive))
idkp = NULL;
else
- kref_get(&idkp->kref);
+ get_device(&idkp->dev);
}
mutex_unlock(&ide_disk_ref_mutex);
return idkp;
@@ -48,7 +48,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp)
ide_drive_t *drive = idkp->drive;
mutex_lock(&ide_disk_ref_mutex);
- kref_put(&idkp->kref, ide_disk_release);
+ put_device(&idkp->dev);
ide_device_put(drive);
mutex_unlock(&ide_disk_ref_mutex);
}
@@ -66,17 +66,18 @@ static void ide_gd_remove(ide_drive_t *drive)
struct gendisk *g = idkp->disk;
ide_proc_unregister_driver(drive, idkp->driver);
-
+ device_del(&idkp->dev);
del_gendisk(g);
-
drive->disk_ops->flush(drive);
- ide_disk_put(idkp);
+ mutex_lock(&ide_disk_ref_mutex);
+ put_device(&idkp->dev);
+ mutex_unlock(&ide_disk_ref_mutex);
}
-static void ide_disk_release(struct kref *kref)
+static void ide_disk_release(struct device *dev)
{
- struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj);
+ struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
struct gendisk *g = idkp->disk;
@@ -144,11 +145,6 @@ static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
return drive->disk_ops->do_request(drive, rq, sector);
}
-static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
-{
- return drive->disk_ops->end_request(drive, uptodate, nrsecs);
-}
-
static struct ide_driver ide_gd_driver = {
.gen_driver = {
.owner = THIS_MODULE,
@@ -161,7 +157,6 @@ static struct ide_driver ide_gd_driver = {
.shutdown = ide_gd_shutdown,
.version = IDE_GD_VERSION,
.do_request = ide_gd_do_request,
- .end_request = ide_gd_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_disk_proc_entries,
.proc_devsets = ide_disk_proc_devsets,
@@ -181,7 +176,7 @@ static int ide_gd_open(struct block_device *bdev, fmode_t mode)
drive = idkp->drive;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
idkp->openers++;
@@ -231,7 +226,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (idkp->openers == 1)
drive->disk_ops->flush(drive);
@@ -348,7 +343,12 @@ static int ide_gd_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
- kref_init(&idkp->kref);
+ idkp->dev.parent = &drive->gendev;
+ idkp->dev.release = ide_disk_release;
+ dev_set_name(&idkp->dev, dev_name(&drive->gendev));
+
+ if (device_register(&idkp->dev))
+ goto out_free_disk;
idkp->drive = drive;
idkp->driver = &ide_gd_driver;
@@ -373,6 +373,8 @@ static int ide_gd_probe(ide_drive_t *drive)
add_disk(g);
return 0;
+out_free_disk:
+ put_disk(g);
out_free_idkp:
kfree(idkp);
failed:
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
index a86779f0756b..55970772bd04 100644
--- a/drivers/ide/ide-gd.h
+++ b/drivers/ide/ide-gd.h
@@ -8,7 +8,7 @@
#define IDE_GD_DEBUG_LOG 0
#if IDE_GD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
#else
#define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif
@@ -17,11 +17,9 @@ struct ide_disk_obj {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
- struct kref kref;
+ struct device dev;
unsigned int openers; /* protected by BKL for now */
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
/* used for blk_{fs,pc}_request() requests */
struct ide_atapi_pc queued_pc;
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 81a5282ce1eb..7812ca0be13b 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -1,27 +1,22 @@
/*
* generic/default IDE host driver
*
- * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz
* This code was split off from ide.c. See it for original copyrights.
*
* May be copied or modified under the terms of the GNU General Public License.
*/
-/*
- * For special cases new interfaces may be added using sysfs, i.e.
- *
- * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
- *
- * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
- */
-
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci_ids.h>
-/* FIXME: convert m32r to use ide_platform host driver */
+/* FIXME: convert arm and m32r to use ide_platform host driver */
+#ifdef CONFIG_ARM
+#include <asm/irq.h>
+#endif
#ifdef CONFIG_M32R
#include <asm/m32r.h>
#endif
@@ -32,62 +27,15 @@ static int probe_mask;
module_param(probe_mask, int, 0);
MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
-static ssize_t store_add(struct class *cls, const char *buf, size_t n)
-{
- unsigned int base, ctl;
- int irq, rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
- return -EINVAL;
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = irq;
- hw.chipset = ide_generic;
-
- rc = ide_host_add(NULL, hws, NULL);
- if (rc)
- return rc;
-
- return n;
-};
-
-static struct class_attribute ide_generic_class_attrs[] = {
- __ATTR(add, S_IWUSR, NULL, store_add),
- __ATTR_NULL
+static const struct ide_port_info ide_generic_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
};
-static void ide_generic_class_release(struct class *cls)
-{
- kfree(cls);
-}
-
-static int __init ide_generic_sysfs_init(void)
-{
- struct class *cls;
- int rc;
-
- cls = kzalloc(sizeof(*cls), GFP_KERNEL);
- if (!cls)
- return -ENOMEM;
-
- cls->name = DRV_NAME;
- cls->owner = THIS_MODULE;
- cls->class_release = ide_generic_class_release;
- cls->class_attrs = ide_generic_class_attrs;
-
- rc = class_register(cls);
- if (rc) {
- kfree(cls);
- return rc;
- }
-
- return 0;
-}
-
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \
- || defined(CONFIG_PLAT_OPSPUT)
+#ifdef CONFIG_ARM
+static const u16 legacy_bases[] = { 0x1f0 };
+static const int legacy_irqs[] = { IRQ_HARDDISK };
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
+ defined(CONFIG_PLAT_OPSPUT)
static const u16 legacy_bases[] = { 0x1f0 };
static const int legacy_irqs[] = { PLD_IRQ_CFIREQ };
#elif defined(CONFIG_PLAT_MAPPI3)
@@ -103,11 +51,11 @@ static const int legacy_irqs[] = { 14, 15, 11, 10, 8, 12 };
static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
{
+#ifdef CONFIG_PCI
struct pci_dev *p = NULL;
u16 val;
for_each_pci_dev(p) {
-
if (pci_resource_start(p, 0) == 0x1f0)
*primary = 1;
if (pci_resource_start(p, 2) == 0x170)
@@ -122,7 +70,6 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
/* Intel MPIIX - PIO ATA on non PCI side of bridge */
if (p->vendor == PCI_VENDOR_ID_INTEL &&
p->device == PCI_DEVICE_ID_INTEL_82371MX) {
-
pci_read_config_word(p, 0x6C, &val);
if (val & 0x8000) {
/* ATA port enabled */
@@ -133,6 +80,7 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
}
}
}
+#endif
}
static int __init ide_generic_init(void)
@@ -164,6 +112,7 @@ static int __init ide_generic_init(void)
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
"not free.\n",
DRV_NAME, io_addr, io_addr + 7);
+ rc = -EBUSY;
continue;
}
@@ -172,6 +121,7 @@ static int __init ide_generic_init(void)
"not free.\n",
DRV_NAME, io_addr + 0x206);
release_region(io_addr, 8);
+ rc = -EBUSY;
continue;
}
@@ -184,7 +134,7 @@ static int __init ide_generic_init(void)
#endif
hw.chipset = ide_generic;
- rc = ide_host_add(NULL, hws, NULL);
+ rc = ide_host_add(&ide_generic_port_info, hws, NULL);
if (rc) {
release_region(io_addr + 0x206, 1);
release_region(io_addr, 8);
@@ -192,10 +142,6 @@ static int __init ide_generic_init(void)
}
}
- if (ide_generic_sysfs_init())
- printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
- "class\n");
-
return rc;
}
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
index 9270d3255ee0..ff8339ed59ab 100644
--- a/drivers/ide/ide-h8300.c
+++ b/drivers/ide/ide-h8300.c
@@ -44,53 +44,53 @@ static u16 mm_inw(unsigned long a)
return r;
}
-static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA)
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA)
mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_taskfile *tf = &cmd->tf;
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data = mm_inw(io_ports->data_addr);
tf->data = data & 0xff;
@@ -100,31 +100,31 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
/* be sure we're looking at the low order bits */
outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
@@ -143,13 +143,13 @@ static void mm_insw(unsigned long addr, void *buf, u32 len)
*bp = bswap(*(volatile u16 *)addr);
}
-static void h8300_input_data(ide_drive_t *drive, struct request *rq,
+static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
}
-static void h8300_output_data(ide_drive_t *drive, struct request *rq,
+static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
new file mode 100644
index 000000000000..931acd097018
--- /dev/null
+++ b/drivers/ide/ide-io-std.c
@@ -0,0 +1,321 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \
+ defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC)
+#include <asm/ide.h>
+#else
+#include <asm-generic/ide_iops.h>
+#endif
+
+/*
+ * Conventional PIO operations for ATA devices
+ */
+
+static u8 ide_inb(unsigned long port)
+{
+ return (u8) inb(port);
+}
+
+static void ide_outb(u8 val, unsigned long port)
+{
+ outb(val, port);
+}
+
+/*
+ * MMIO operations, typically used for SATA controllers
+ */
+
+static u8 ide_mm_inb(unsigned long port)
+{
+ return (u8) readb((void __iomem *) port);
+}
+
+static void ide_mm_outb(u8 value, unsigned long port)
+{
+ writeb(value, (void __iomem *) port);
+}
+
+void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
+ else
+ outb(cmd, hwif->io_ports.command_addr);
+}
+EXPORT_SYMBOL_GPL(ide_exec_command);
+
+u8 ide_read_status(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.status_addr);
+ else
+ return inb(hwif->io_ports.status_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_status);
+
+u8 ide_read_altstatus(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ return inb(hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_altstatus);
+
+void ide_set_irq(ide_hwif_t *hwif, int on)
+{
+ u8 ctl = ATA_DEVCTL_OBS;
+
+ if (on == 4) { /* hack for SRST */
+ ctl |= 4;
+ on &= ~4;
+ }
+
+ ctl |= on ? 0 : 2;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ outb(ctl, hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_set_irq);
+
+void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &cmd->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+
+ if (mmio)
+ tf_outb = ide_mm_outb;
+ else
+ tf_outb = ide_outb;
+
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
+ HIHI = 0xFF;
+
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
+ u16 data = (tf->hob_data << 8) | tf->data;
+
+ if (mmio)
+ writew(data, (void __iomem *)io_ports->data_addr);
+ else
+ outw(data, io_ports->data_addr);
+ }
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ tf_outb(tf->hob_feature, io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ tf_outb(tf->hob_nsect, io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ tf_outb(tf->hob_lbal, io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ tf_outb(tf->hob_lbam, io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ tf_outb(tf->hob_lbah, io_ports->lbah_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ tf_outb(tf->feature, io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
+ tf_outb(tf->nsect, io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
+ tf_outb(tf->lbal, io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
+ tf_outb(tf->lbam, io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
+ tf_outb(tf->lbah, io_ports->lbah_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ tf_outb((tf->device & HIHI) | drive->select,
+ io_ports->device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_tf_load);
+
+void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &cmd->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 (*tf_inb)(unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (mmio) {
+ tf_outb = ide_mm_outb;
+ tf_inb = ide_mm_inb;
+ } else {
+ tf_outb = ide_outb;
+ tf_inb = ide_inb;
+ }
+
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
+ u16 data;
+
+ if (mmio)
+ data = readw((void __iomem *)io_ports->data_addr);
+ else
+ data = inw(io_ports->data_addr);
+
+ tf->data = data & 0xff;
+ tf->hob_data = (data >> 8) & 0xff;
+ }
+
+ /* be sure we're looking at the low order bits */
+ tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
+ tf->feature = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = tf_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = tf_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = tf_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = tf_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = tf_inb(io_ports->device_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ tf->hob_feature = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tf_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tf_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tf_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tf_inb(io_ports->lbah_addr);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_tf_read);
+
+/*
+ * Some localbus EIDE interfaces require a special access sequence
+ * when using 32-bit I/O instructions to transfer data. We call this
+ * the "vlb_sync" sequence, which consists of three successive reads
+ * of the sector count register location, with interrupts disabled
+ * to ensure that the reads all happen together.
+ */
+static void ata_vlb_sync(unsigned long port)
+{
+ (void)inb(port);
+ (void)inb(port);
+ (void)inb(port);
+}
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ *
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd len is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
+ */
+void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ len++;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ if (mmio)
+ __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
+ else
+ insl(data_addr, buf, len / 4);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if ((len & 3) >= 2) {
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr,
+ (u8 *)buf + (len & ~3), 1);
+ else
+ insw(data_addr, (u8 *)buf + (len & ~3), 1);
+ }
+ } else {
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
+ else
+ insw(data_addr, buf, len / 2);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_input_data);
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ if (mmio)
+ __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
+ else
+ outsl(data_addr, buf, len / 4);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if ((len & 3) >= 2) {
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr,
+ (u8 *)buf + (len & ~3), 1);
+ else
+ outsw(data_addr, (u8 *)buf + (len & ~3), 1);
+ }
+ } else {
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
+ else
+ outsw(data_addr, buf, len / 2);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_output_data);
+
+const struct ide_tp_ops default_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+
+ .set_irq = ide_set_irq,
+
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index cc163319dfbd..481fb1b79f17 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -40,7 +40,6 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include <linux/completion.h>
#include <linux/reboot.h>
#include <linux/cdrom.h>
@@ -55,25 +54,9 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-static int __ide_end_request(ide_drive_t *drive, struct request *rq,
- int uptodate, unsigned int nr_bytes, int dequeue)
+int ide_end_rq(ide_drive_t *drive, struct request *rq, int error,
+ unsigned int nr_bytes)
{
- int ret = 1;
- int error = 0;
-
- if (uptodate <= 0)
- error = uptodate ? uptodate : -EIO;
-
- /*
- * if failfast is set on a request, override number of sectors and
- * complete the whole request right now
- */
- if (blk_noretry_request(rq) && error)
- nr_bytes = rq->hard_nr_sectors << 9;
-
- if (!blk_fs_request(rq) && error && !rq->errors)
- rq->errors = -EIO;
-
/*
* decide whether to reenable DMA -- 3 is a random magic for now,
* if we DMA timeout more than 3 times, just stay in PIO
@@ -84,255 +67,87 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
ide_dma_on(drive);
}
- if (!blk_end_request(rq, error, nr_bytes))
- ret = 0;
-
- if (ret == 0 && dequeue)
- drive->hwif->rq = NULL;
-
- return ret;
+ return blk_end_request(rq, error, nr_bytes);
}
+EXPORT_SYMBOL_GPL(ide_end_rq);
-/**
- * ide_end_request - complete an IDE I/O
- * @drive: IDE device for the I/O
- * @uptodate:
- * @nr_sectors: number of sectors completed
- *
- * This is our end_request wrapper function. We complete the I/O
- * update random number input and dequeue the request, which if
- * it was tagged may be out of order.
- */
-
-int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
+void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
{
- unsigned int nr_bytes = nr_sectors << 9;
- struct request *rq = drive->hwif->rq;
+ struct ide_taskfile *tf = &cmd->tf;
+ struct request *rq = cmd->rq;
+ u8 tf_cmd = tf->command;
- if (!nr_bytes) {
- if (blk_pc_request(rq))
- nr_bytes = rq->data_len;
- else
- nr_bytes = rq->hard_cur_sectors << 9;
- }
+ tf->error = err;
+ tf->status = stat;
- return __ide_end_request(drive, rq, uptodate, nr_bytes, 1);
-}
-EXPORT_SYMBOL(ide_end_request);
+ drive->hwif->tp_ops->tf_read(drive, cmd);
-/**
- * ide_end_dequeued_request - complete an IDE I/O
- * @drive: IDE device for the I/O
- * @uptodate:
- * @nr_sectors: number of sectors completed
- *
- * Complete an I/O that is no longer on the request queue. This
- * typically occurs when we pull the request and issue a REQUEST_SENSE.
- * We must still finish the old request but we must not tamper with the
- * queue in the meantime.
- *
- * NOTE: This path does not handle barrier, but barrier is not supported
- * on ide-cd anyway.
- */
-
-int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
- int uptodate, int nr_sectors)
-{
- BUG_ON(!blk_rq_started(rq));
-
- return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0);
-}
-EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
-
-/**
- * ide_end_drive_cmd - end an explicit drive command
- * @drive: command
- * @stat: status bits
- * @err: error bits
- *
- * Clean up after success/failure of an explicit drive command.
- * These get thrown onto the queue so they are synchronized with
- * real I/O operations on the drive.
- *
- * In LBA48 mode we have to read the register set twice to get
- * all the extra information out.
- */
-
-void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
-
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- ide_task_t *task = (ide_task_t *)rq->special;
-
- if (task) {
- struct ide_taskfile *tf = &task->tf;
-
- tf->error = err;
- tf->status = stat;
-
- drive->hwif->tp_ops->tf_read(drive, task);
-
- if (task->tf_flags & IDE_TFLAG_DYN)
- kfree(task);
- }
- } else if (blk_pm_request(rq)) {
- struct request_pm_state *pm = rq->data;
-
- ide_complete_power_step(drive, rq);
- if (pm->pm_step == IDE_PM_COMPLETED)
- ide_complete_pm_request(drive, rq);
- return;
+ if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
+ tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
+ if (tf->lbal != 0xc4) {
+ printk(KERN_ERR "%s: head unload failed!\n",
+ drive->name);
+ ide_tf_dump(drive->name, tf);
+ } else
+ drive->dev_flags |= IDE_DFLAG_PARKED;
}
- hwif->rq = NULL;
-
- rq->errors = err;
+ if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
+ memcpy(rq->special, cmd, sizeof(*cmd));
- if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0),
- blk_rq_bytes(rq))))
- BUG();
+ if (cmd->tf_flags & IDE_TFLAG_DYN)
+ kfree(cmd);
}
-EXPORT_SYMBOL(ide_end_drive_cmd);
-static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
+/* obsolete, blk_rq_bytes() should be used instead */
+unsigned int ide_rq_bytes(struct request *rq)
{
- if (rq->rq_disk) {
- struct ide_driver *drv;
-
- drv = *(struct ide_driver **)rq->rq_disk->private_data;
- drv->end_request(drive, 0, 0);
- } else
- ide_end_request(drive, 0, 0);
+ if (blk_pc_request(rq))
+ return rq->data_len;
+ else
+ return rq->hard_cur_sectors << 9;
}
+EXPORT_SYMBOL_GPL(ide_rq_bytes);
-static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
{
ide_hwif_t *hwif = drive->hwif;
+ struct request *rq = hwif->rq;
+ int rc;
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else if (stat & ATA_ERR) {
- /* err has different meaning on cdrom and tape */
- if (err == ATA_ABORTED) {
- if ((drive->dev_flags & IDE_DFLAG_LBA) &&
- /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
- hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
- return ide_stopped;
- } else if ((err & BAD_CRC) == BAD_CRC) {
- /* UDMA crc error, just retry the operation */
- drive->crc_count++;
- } else if (err & (ATA_BBK | ATA_UNC)) {
- /* retries won't help these */
- rq->errors = ERROR_MAX;
- } else if (err & ATA_TRK0NF) {
- /* help it find track zero */
- rq->errors |= ERROR_RECAL;
- }
- }
-
- if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
- (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
- int nsect = drive->mult_count ? drive->mult_count : 1;
-
- ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
- }
-
- if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
- ide_kill_rq(drive, rq);
- return ide_stopped;
- }
-
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- rq->errors |= ERROR_RESET;
-
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
-
- if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
+ /*
+ * if failfast is set on a request, override number of sectors
+ * and complete the whole request right now
+ */
+ if (blk_noretry_request(rq) && error <= 0)
+ nr_bytes = rq->hard_nr_sectors << 9;
- ++rq->errors;
+ rc = ide_end_rq(drive, rq, error, nr_bytes);
+ if (rc == 0)
+ hwif->rq = NULL;
- return ide_stopped;
+ return rc;
}
+EXPORT_SYMBOL(ide_complete_rq);
-static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
-
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else {
- /* add decoding error stuff */
- }
+ u8 drv_req = blk_special_request(rq) && rq->rq_disk;
+ u8 media = drive->media;
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- /* force an abort */
- hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+ drive->failed_pc = NULL;
- if (rq->errors >= ERROR_MAX) {
- ide_kill_rq(drive, rq);
+ if ((media == ide_floppy || media == ide_tape) && drv_req) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
} else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
- ++rq->errors;
- }
-
- return ide_stopped;
-}
-
-static ide_startstop_t
-__ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- if (drive->media == ide_disk)
- return ide_ata_error(drive, rq, stat, err);
- return ide_atapi_error(drive, rq, stat, err);
-}
-
-/**
- * ide_error - handle an error on the IDE
- * @drive: drive the error occurred on
- * @msg: message to report
- * @stat: status bits
- *
- * ide_error() takes action based on the error returned by the drive.
- * For normal I/O that may well include retries. We deal with
- * both new-style (taskfile) and old style command handling here.
- * In the case of taskfile command handling there is work left to
- * do
- */
-
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
- struct request *rq;
- u8 err;
-
- err = ide_dump_status(drive, msg, stat);
-
- rq = drive->hwif->rq;
- if (rq == NULL)
- return ide_stopped;
-
- /* retry only "normal" I/O: */
- if (!blk_fs_request(rq)) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
- return ide_stopped;
+ if (media == ide_tape)
+ rq->errors = IDE_DRV_ERROR_GENERAL;
+ else if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
}
-
- return __ide_error(drive, rq, stat, err);
}
-EXPORT_SYMBOL_GPL(ide_error);
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
{
@@ -359,20 +174,20 @@ static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
static ide_startstop_t ide_disk_special(ide_drive_t *drive)
{
special_t *s = &drive->special;
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
- args.data_phase = TASKFILE_NO_DATA;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.protocol = ATA_PROT_NODATA;
if (s->b.set_geometry) {
s->b.set_geometry = 0;
- ide_tf_set_specify_cmd(drive, &args.tf);
+ ide_tf_set_specify_cmd(drive, &cmd.tf);
} else if (s->b.recalibrate) {
s->b.recalibrate = 0;
- ide_tf_set_restore_cmd(drive, &args.tf);
+ ide_tf_set_restore_cmd(drive, &cmd.tf);
} else if (s->b.set_multmode) {
s->b.set_multmode = 0;
- ide_tf_set_setmult_cmd(drive, &args.tf);
+ ide_tf_set_setmult_cmd(drive, &cmd.tf);
} else if (s->all) {
int special = s->all;
s->all = 0;
@@ -380,10 +195,10 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
return ide_stopped;
}
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
- IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
+ IDE_TFLAG_CUSTOM_HANDLER;
- do_rw_taskfile(drive, &args);
+ do_rw_taskfile(drive, &cmd);
return ide_started;
}
@@ -413,30 +228,29 @@ static ide_startstop_t do_special (ide_drive_t *drive)
return ide_stopped;
}
-void ide_map_sg(ide_drive_t *drive, struct request *rq)
+void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
+ struct request *rq = cmd->rq;
- if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) {
- hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
- } else {
+ if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- hwif->sg_nents = 1;
- }
+ cmd->sg_nents = 1;
+ } else if (!rq->bio) {
+ sg_init_one(sg, rq->data, rq->data_len);
+ cmd->sg_nents = 1;
+ } else
+ cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
}
-
EXPORT_SYMBOL_GPL(ide_map_sg);
-void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
+void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes)
{
- ide_hwif_t *hwif = drive->hwif;
-
- hwif->nsect = hwif->nleft = rq->nr_sectors;
- hwif->cursg_ofs = 0;
- hwif->cursg = NULL;
+ cmd->nbytes = cmd->nleft = nr_bytes;
+ cmd->cursg_ofs = 0;
+ cmd->cursg = NULL;
}
-
EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
/**
@@ -454,24 +268,15 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
- ide_task_t *task = rq->special;
-
- if (task) {
- hwif->data_phase = task->data_phase;
-
- switch (hwif->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- default:
- break;
+ struct ide_cmd *cmd = rq->special;
+
+ if (cmd) {
+ if (cmd->protocol == ATA_PROT_PIO) {
+ ide_init_sg_cmd(cmd, rq->nr_sectors << 9);
+ ide_map_sg(drive, cmd);
}
- return do_rw_taskfile(drive, task);
+ return do_rw_taskfile(drive, cmd);
}
/*
@@ -481,83 +286,26 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
#ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
- ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif),
- ide_read_error(drive));
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
}
-int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
- int arg)
-{
- struct request_queue *q = drive->queue;
- struct request *rq;
- int ret = 0;
-
- if (!(setting->flags & DS_SYNC))
- return setting->set(drive, arg);
-
- rq = blk_get_request(q, READ, __GFP_WAIT);
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_len = 5;
- rq->cmd[0] = REQ_DEVSET_EXEC;
- *(int *)&rq->cmd[1] = arg;
- rq->special = setting->set;
-
- if (blk_execute_rq(q, NULL, rq, 0))
- ret = rq->errors;
- blk_put_request(rq);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(ide_devset_execute);
-
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
{
u8 cmd = rq->cmd[0];
- if (cmd == REQ_PARK_HEADS || cmd == REQ_UNPARK_HEADS) {
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
-
- memset(&task, 0, sizeof(task));
- if (cmd == REQ_PARK_HEADS) {
- drive->sleep = *(unsigned long *)rq->special;
- drive->dev_flags |= IDE_DFLAG_SLEEPING;
- tf->command = ATA_CMD_IDLEIMMEDIATE;
- tf->feature = 0x44;
- tf->lbal = 0x4c;
- tf->lbam = 0x4e;
- tf->lbah = 0x55;
- task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
- } else /* cmd == REQ_UNPARK_HEADS */
- tf->command = ATA_CMD_CHK_POWER;
-
- task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- task.rq = rq;
- drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA;
- return do_rw_taskfile(drive, &task);
- }
-
switch (cmd) {
+ case REQ_PARK_HEADS:
+ case REQ_UNPARK_HEADS:
+ return ide_do_park_unpark(drive, rq);
case REQ_DEVSET_EXEC:
- {
- int err, (*setfunc)(ide_drive_t *, int) = rq->special;
-
- err = setfunc(drive, *(int *)&rq->cmd[1]);
- if (err)
- rq->errors = err;
- else
- err = 1;
- ide_end_request(drive, err, 0);
- return ide_stopped;
- }
+ return ide_do_devset(drive, rq);
case REQ_DRIVE_RESET:
return ide_do_reset(drive);
default:
- blk_dump_rq_flags(rq, "ide_special_rq - bad request");
- ide_end_request(drive, 0, 0);
- return ide_stopped;
+ BUG();
}
}
@@ -617,7 +365,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
startstop = ide_start_power_step(drive, rq);
if (startstop == ide_stopped &&
pm->pm_step == IDE_PM_COMPLETED)
- ide_complete_pm_request(drive, rq);
+ ide_complete_pm_rq(drive, rq);
return startstop;
} else if (!rq->rq_disk && blk_special_request(rq))
/*
@@ -680,8 +428,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
if (rc == 0) {
- /* for atari only */
- ide_get_lock(ide_intr, hwif);
+ if (host->get_lock)
+ host->get_lock(ide_intr, hwif);
}
}
return rc;
@@ -690,8 +438,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
static inline void ide_unlock_host(struct ide_host *host)
{
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
- /* for atari only */
- ide_release_lock();
+ if (host->release_lock)
+ host->release_lock();
clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
}
}
@@ -817,63 +565,6 @@ plug_device_2:
blk_plug_device(q);
}
-/*
- * un-busy the port etc, and clear any pending DMA status. we want to
- * retry the current request in pio mode instead of risking tossing it
- * all away
- */
-static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq;
- ide_startstop_t ret = ide_stopped;
-
- /*
- * end current dma transaction
- */
-
- if (error < 0) {
- printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
- (void)hwif->dma_ops->dma_end(drive);
- ret = ide_error(drive, "dma timeout error",
- hwif->tp_ops->read_status(hwif));
- } else {
- printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
- hwif->dma_ops->dma_timeout(drive);
- }
-
- /*
- * disable dma for now, but remember that we did so because of
- * a timeout -- we'll reenable after we finish this next request
- * (or rather the first chunk of it) in pio.
- */
- drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
- drive->retry_pio++;
- ide_dma_off_quietly(drive);
-
- /*
- * un-busy drive etc and make sure request is sane
- */
-
- rq = hwif->rq;
- if (!rq)
- goto out;
-
- hwif->rq = NULL;
-
- rq->errors = 0;
-
- if (!rq->bio)
- goto out;
-
- rq->sector = rq->bio->bi_sector;
- rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->buffer = bio_data(rq->bio);
-out:
- return ret;
-}
-
static void ide_plug_device(ide_drive_t *drive)
{
struct request_queue *q = drive->queue;
@@ -885,6 +576,29 @@ static void ide_plug_device(ide_drive_t *drive)
spin_unlock_irqrestore(q->queue_lock, flags);
}
+static int drive_is_ready(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 stat = 0;
+
+ if (drive->waiting_for_dma)
+ return hwif->dma_ops->dma_test_irq(drive);
+
+ if (hwif->io_ports.ctl_addr &&
+ (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
+ stat = hwif->tp_ops->read_altstatus(hwif);
+ else
+ /* Note: this may clear a pending IRQ!! */
+ stat = hwif->tp_ops->read_status(hwif);
+
+ if (stat & ATA_BUSY)
+ /* drive busy: definitely not interrupting */
+ return 0;
+
+ /* drive ready: *might* be interrupting */
+ return 1;
+}
+
/**
* ide_timer_expiry - handle lack of an IDE interrupt
* @data: timer callback magic (hwif)
@@ -937,6 +651,7 @@ void ide_timer_expiry (unsigned long data)
}
}
hwif->handler = NULL;
+ hwif->expiry = NULL;
/*
* We need to simulate a real interrupt when invoking
* the handler() function, which means we need to
@@ -952,7 +667,8 @@ void ide_timer_expiry (unsigned long data)
} else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma)
hwif->dma_ops->dma_lost_irq(drive);
- (void)ide_ack_intr(hwif);
+ if (hwif->ack_intr)
+ hwif->ack_intr(hwif);
printk(KERN_WARNING "%s: lost interrupt\n",
drive->name);
startstop = handler(drive);
@@ -1053,6 +769,7 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif)
irqreturn_t ide_intr (int irq, void *dev_id)
{
ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
+ struct ide_host *host = hwif->host;
ide_drive_t *uninitialized_var(drive);
ide_handler_t *handler;
unsigned long flags;
@@ -1060,14 +777,14 @@ irqreturn_t ide_intr (int irq, void *dev_id)
irqreturn_t irq_ret = IRQ_NONE;
int plug_device = 0;
- if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) {
- if (hwif != hwif->host->cur_port)
+ if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+ if (hwif != host->cur_port)
goto out_early;
}
spin_lock_irqsave(&hwif->lock, flags);
- if (!ide_ack_intr(hwif))
+ if (hwif->ack_intr && hwif->ack_intr(hwif) == 0)
goto out;
handler = hwif->handler;
@@ -1084,27 +801,19 @@ irqreturn_t ide_intr (int irq, void *dev_id)
*
* For PCI, we cannot tell the difference,
* so in that case we just ignore it and hope it goes away.
- *
- * FIXME: unexpected_intr should be hwif-> then we can
- * remove all the ifdef PCI crap
*/
-#ifdef CONFIG_BLK_DEV_IDEPCI
- if (hwif->chipset != ide_pci)
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- {
+ if ((host->irq_flags & IRQF_SHARED) == 0) {
/*
* Probably not a shared PCI interrupt,
* so we can safely try to do something about it:
*/
unexpected_intr(irq, hwif);
-#ifdef CONFIG_BLK_DEV_IDEPCI
} else {
/*
* Whack the status register, just in case
* we have a leftover pending IRQ.
*/
(void)hwif->tp_ops->read_status(hwif);
-#endif /* CONFIG_BLK_DEV_IDEPCI */
}
goto out;
}
@@ -1122,6 +831,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
goto out;
hwif->handler = NULL;
+ hwif->expiry = NULL;
hwif->req_gen++;
del_timer(&hwif->timer);
spin_unlock(&hwif->lock);
@@ -1160,54 +870,6 @@ out_early:
return irq_ret;
}
-/**
- * ide_do_drive_cmd - issue IDE special command
- * @drive: device to issue command
- * @rq: request to issue
- *
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * the rq is queued at the head of the request queue, displacing
- * the currently-being-processed request and this function
- * returns immediately without waiting for the new rq to be
- * completed. This is VERY DANGEROUS, and is intended for
- * careful use by the ATAPI tape/cdrom driver code.
- */
-
-void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
-{
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
- drive->hwif->rq = NULL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
- spin_unlock_irqrestore(q->queue_lock, flags);
-}
-EXPORT_SYMBOL(ide_do_drive_cmd);
-
-void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
-{
- ide_hwif_t *hwif = drive->hwif;
- ide_task_t task;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
- IDE_TFLAG_OUT_FEATURE | tf_flags;
- task.tf.feature = dma; /* Use PIO/DMA */
- task.tf.lbam = bcount & 0xff;
- task.tf.lbah = (bcount >> 8) & 0xff;
-
- ide_tf_dump(drive->name, &task.tf);
- hwif->tp_ops->set_irq(hwif, 1);
- SELECT_MASK(drive, 0);
- hwif->tp_ops->tf_load(drive, &task);
-}
-
-EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
-
void ide_pad_transfer(ide_drive_t *drive, int write, int len)
{
ide_hwif_t *hwif = drive->hwif;
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 1be263eb9c07..770142767437 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -111,13 +111,13 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
return 0;
}
-static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
{
u8 *buf = NULL;
int bufsize = 0, err = 0;
u8 args[4], xfer_rate = 0;
- ide_task_t tfargs;
- struct ide_taskfile *tf = &tfargs.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u16 *id = drive->id;
if (NULL == (void *) arg) {
@@ -134,24 +134,24 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
if (copy_from_user(args, (void __user *)arg, 4))
return -EFAULT;
- memset(&tfargs, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = args[2];
if (args[0] == ATA_CMD_SMART) {
tf->nsect = args[3];
tf->lbal = args[1];
tf->lbam = 0x4f;
tf->lbah = 0xc2;
- tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
+ cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
} else {
tf->nsect = args[1];
- tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
- IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
+ IDE_TFLAG_IN_NSECT;
}
tf->command = args[0];
- tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
+ cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA;
if (args[3]) {
- tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
+ cmd.tf_flags |= IDE_TFLAG_IO_16BIT;
bufsize = SECTOR_SIZE * args[3];
buf = kzalloc(bufsize, GFP_KERNEL);
if (buf == NULL)
@@ -172,7 +172,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
}
}
- err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
+ err = ide_raw_taskfile(drive, &cmd, buf, args[3]);
args[0] = tf->status;
args[1] = tf->error;
@@ -194,25 +194,25 @@ abort:
return err;
}
-static int ide_task_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
{
void __user *p = (void __user *)arg;
int err = 0;
u8 args[7];
- ide_task_t task;
+ struct ide_cmd cmd;
if (copy_from_user(args, p, 7))
return -EFAULT;
- memset(&task, 0, sizeof(task));
- memcpy(&task.tf_array[7], &args[1], 6);
- task.tf.command = args[0];
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&cmd.tf_array[7], &args[1], 6);
+ cmd.tf.command = args[0];
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- err = ide_no_data_taskfile(drive, &task);
+ err = ide_no_data_taskfile(drive, &cmd);
- args[0] = task.tf.command;
- memcpy(&args[1], &task.tf_array[7], 6);
+ args[0] = cmd.tf.command;
+ memcpy(&args[1], &cmd.tf_array[7], 6);
if (copy_to_user(p, args, 7))
err = -EFAULT;
@@ -262,17 +262,17 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
if (drive->media == ide_disk)
- return ide_taskfile_ioctl(drive, cmd, arg);
+ return ide_taskfile_ioctl(drive, arg);
return -ENOMSG;
#endif
case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return ide_cmd_ioctl(drive, cmd, arg);
+ return ide_cmd_ioctl(drive, arg);
case HDIO_DRIVE_TASK:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return ide_task_ioctl(drive, cmd, arg);
+ return ide_task_ioctl(drive, arg);
case HDIO_DRIVE_RESET:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 753b92ebe0ae..5403e4a44be4 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -27,47 +27,19 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-/*
- * Conventional PIO operations for ATA devices
- */
-
-static u8 ide_inb (unsigned long port)
-{
- return (u8) inb(port);
-}
-
-static void ide_outb (u8 val, unsigned long port)
-{
- outb(val, port);
-}
-
-/*
- * MMIO operations, typically used for SATA controllers
- */
-
-static u8 ide_mm_inb (unsigned long port)
-{
- return (u8) readb((void __iomem *) port);
-}
-
-static void ide_mm_outb (u8 value, unsigned long port)
-{
- writeb(value, (void __iomem *) port);
-}
-
-void SELECT_DRIVE (ide_drive_t *drive)
+void SELECT_DRIVE(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
- ide_task_t task;
+ struct ide_cmd cmd;
if (port_ops && port_ops->selectproc)
port_ops->selectproc(drive);
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_OUT_DEVICE;
- drive->hwif->tp_ops->tf_load(drive, &task);
+ drive->hwif->tp_ops->tf_load(drive, &cmd);
}
void SELECT_MASK(ide_drive_t *drive, int mask)
@@ -78,317 +50,19 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
port_ops->maskproc(drive, mask);
}
-void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
- else
- outb(cmd, hwif->io_ports.command_addr);
-}
-EXPORT_SYMBOL_GPL(ide_exec_command);
-
-u8 ide_read_status(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.status_addr);
- else
- return inb(hwif->io_ports.status_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_status);
-
-u8 ide_read_altstatus(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.ctl_addr);
- else
- return inb(hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_altstatus);
-
-void ide_set_irq(ide_hwif_t *hwif, int on)
-{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
- else
- outb(ctl, hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_set_irq);
-
-void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (mmio)
- tf_outb = ide_mm_outb;
- else
- tf_outb = ide_outb;
-
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- if (mmio)
- writew(data, (void __iomem *)io_ports->data_addr);
- else
- outw(data, io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- tf_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- tf_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- tf_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- tf_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- tf_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
- tf_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
- tf_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
- tf_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
- tf_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
- tf_outb(tf->lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tf_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
-}
-EXPORT_SYMBOL_GPL(ide_tf_load);
-
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 (*tf_inb)(unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- if (mmio) {
- tf_outb = ide_mm_outb;
- tf_inb = ide_mm_inb;
- } else {
- tf_outb = ide_outb;
- tf_inb = ide_inb;
- }
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- if (mmio)
- data = readw((void __iomem *)io_ports->data_addr);
- else
- data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
- /* be sure we're looking at the low order bits */
- tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = tf_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = tf_inb(io_ports->device_addr);
-
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tf_inb(io_ports->lbah_addr);
- }
-}
-EXPORT_SYMBOL_GPL(ide_tf_read);
-
-/*
- * Some localbus EIDE interfaces require a special access sequence
- * when using 32-bit I/O instructions to transfer data. We call this
- * the "vlb_sync" sequence, which consists of three successive reads
- * of the sector count register location, with interrupts disabled
- * to ensure that the reads all happen together.
- */
-static void ata_vlb_sync(unsigned long port)
-{
- (void)inb(port);
- (void)inb(port);
- (void)inb(port);
-}
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd len is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- len++;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
- else
- insl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- insw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
- else
- insw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_input_data);
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
- else
- outsl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- outsw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
- else
- outsw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_output_data);
-
u8 ide_read_error(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_FEATURE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_FEATURE;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.error;
+ return cmd.tf.error;
}
EXPORT_SYMBOL_GPL(ide_read_error);
-void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
-{
- ide_task_t task;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
- IDE_TFLAG_IN_NSECT;
-
- drive->hwif->tp_ops->tf_read(drive, &task);
-
- *bcount = (task.tf.lbah << 8) | task.tf.lbam;
- *ireason = task.tf.nsect & 3;
-}
-EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
-
-const struct ide_tp_ops default_tp_ops = {
- .exec_command = ide_exec_command,
- .read_status = ide_read_status,
- .read_altstatus = ide_read_altstatus,
-
- .set_irq = ide_set_irq,
-
- .tf_load = ide_tf_load,
- .tf_read = ide_tf_read,
-
- .input_data = ide_input_data,
- .output_data = ide_output_data,
-};
-
void ide_fix_driveid(u16 *id)
{
#ifndef __LITTLE_ENDIAN
@@ -410,7 +84,7 @@ void ide_fix_driveid(u16 *id)
* returned by the ATA_CMD_ID_ATA[PI] commands.
*/
-void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
+void ide_fixstring(u8 *s, const int bytecount, const int byteswap)
{
u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
@@ -433,44 +107,9 @@ void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
while (p != end)
*p++ = '\0';
}
-
EXPORT_SYMBOL(ide_fixstring);
/*
- * Needed for PCI irq sharing
- */
-int drive_is_ready (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 stat = 0;
-
- if (drive->waiting_for_dma)
- return hwif->dma_ops->dma_test_irq(drive);
-
- /*
- * We do a passive status test under shared PCI interrupts on
- * cards that truly share the ATA side interrupt, but may also share
- * an interrupt with another pci card/device. We make no assumptions
- * about possible isa-pnp and pci-pnp issues yet.
- */
- if (hwif->io_ports.ctl_addr &&
- (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
- stat = hwif->tp_ops->read_altstatus(hwif);
- else
- /* Note: this may clear a pending IRQ!! */
- stat = hwif->tp_ops->read_status(hwif);
-
- if (stat & ATA_BUSY)
- /* drive busy: definitely not interrupting */
- return 0;
-
- /* drive ready: *might* be interrupting */
- return 1;
-}
-
-EXPORT_SYMBOL(drive_is_ready);
-
-/*
* This routine busy-waits for the drive status to be not "busy".
* It then checks the status for all of the "good" bits and none
* of the "bad" bits, and if all is okay it returns 0. All other
@@ -481,7 +120,8 @@ EXPORT_SYMBOL(drive_is_ready);
* setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out.
*/
-static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
+static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
+ unsigned long timeout, u8 *rstat)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -539,7 +179,8 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti
* The caller should return the updated value of "startstop" in this case,
* "startstop" is unchanged when the function returns 0.
*/
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout)
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good,
+ u8 bad, unsigned long timeout)
{
int err;
u8 stat;
@@ -559,7 +200,6 @@ int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 ba
return err;
}
-
EXPORT_SYMBOL(ide_wait_stat);
/**
@@ -580,7 +220,6 @@ int ide_in_drive_list(u16 *id, const struct drive_list_entry *table)
return 1;
return 0;
}
-
EXPORT_SYMBOL_GPL(ide_in_drive_list);
/*
@@ -605,7 +244,7 @@ static const struct drive_list_entry ivb_list[] = {
* All hosts that use the 80c ribbon must use!
* The name is derived from upper byte of word 93 and the 80c ribbon.
*/
-u8 eighty_ninty_three (ide_drive_t *drive)
+u8 eighty_ninty_three(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u16 *id = drive->id;
@@ -650,47 +289,19 @@ no_80w:
int ide_driveid_update(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u16 *id;
- unsigned long flags;
- u8 stat;
-
- /*
- * Re-read drive->id for possible DMA mode
- * change (copied from ide-probe.c)
- */
-
- SELECT_MASK(drive, 1);
- tp_ops->set_irq(hwif, 0);
- msleep(50);
- tp_ops->exec_command(hwif, ATA_CMD_ID_ATA);
+ int rc;
- if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) {
- SELECT_MASK(drive, 0);
+ id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
+ if (id == NULL)
return 0;
- }
- msleep(50); /* wait for IRQ and ATA_DRQ */
- stat = tp_ops->read_status(hwif);
-
- if (!OK_STAT(stat, ATA_DRQ, BAD_R_STAT)) {
- SELECT_MASK(drive, 0);
- printk("%s: CHECK for good STATUS\n", drive->name);
- return 0;
- }
- local_irq_save(flags);
+ SELECT_MASK(drive, 1);
+ rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id);
SELECT_MASK(drive, 0);
- id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
- if (!id) {
- local_irq_restore(flags);
- return 0;
- }
- tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
- (void)tp_ops->read_status(hwif); /* clear drive IRQ */
- local_irq_enable();
- local_irq_restore(flags);
- ide_fix_driveid(id);
+
+ if (rc)
+ goto out_err;
drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES];
drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
@@ -703,6 +314,12 @@ int ide_driveid_update(ide_drive_t *drive)
ide_dma_off(drive);
return 1;
+out_err:
+ SELECT_MASK(drive, 0);
+ if (rc == 2)
+ printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
+ kfree(id);
+ return 0;
}
int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
@@ -712,7 +329,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
u16 *id = drive->id, i;
int error = 0;
u8 stat;
- ide_task_t task;
+ struct ide_cmd cmd;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_ops) /* check if host supports DMA */
@@ -729,30 +346,27 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
* but for some reason these don't work at
* this point (lost interrupt).
*/
- /*
- * Select the drive, and issue the SETFEATURES command
- */
- disable_irq_nosync(hwif->irq);
-
+
/*
* FIXME: we race against the running IRQ here if
* this is called from non IRQ context. If we use
* disable_irq() we hang on the error path. Work
* is needed.
*/
-
+ disable_irq_nosync(hwif->irq);
+
udelay(1);
SELECT_DRIVE(drive);
SELECT_MASK(drive, 1);
udelay(1);
tp_ops->set_irq(hwif, 0);
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
- task.tf.feature = SETFEATURES_XFER;
- task.tf.nsect = speed;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
+ cmd.tf.feature = SETFEATURES_XFER;
+ cmd.tf.nsect = speed;
- tp_ops->tf_load(drive, &task);
+ tp_ops->tf_load(drive, &cmd);
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
@@ -810,55 +424,55 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
*
* See also ide_execute_command
*/
-static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout)
{
ide_hwif_t *hwif = drive->hwif;
BUG_ON(hwif->handler);
hwif->handler = handler;
- hwif->expiry = expiry;
hwif->timer.expires = jiffies + timeout;
hwif->req_gen_timer = hwif->req_gen;
add_timer(&hwif->timer);
}
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
spin_lock_irqsave(&hwif->lock, flags);
- __ide_set_handler(drive, handler, timeout, expiry);
+ __ide_set_handler(drive, handler, timeout);
spin_unlock_irqrestore(&hwif->lock, flags);
}
-
EXPORT_SYMBOL(ide_set_handler);
-
+
/**
* ide_execute_command - execute an IDE command
* @drive: IDE drive to issue the command against
- * @command: command byte to write
+ * @cmd: command
* @handler: handler for next phase
* @timeout: timeout for command
- * @expiry: handler to run on timeout
*
* Helper function to issue an IDE command. This handles the
- * atomicity requirements, command timing and ensures that the
+ * atomicity requirements, command timing and ensures that the
* handler and IRQ setup do not race. All IDE command kick off
* should go via this function or do equivalent locking.
*/
-void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
- unsigned timeout, ide_expiry_t *expiry)
+void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd,
+ ide_handler_t *handler, unsigned timeout)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
spin_lock_irqsave(&hwif->lock, flags);
- __ide_set_handler(drive, handler, timeout, expiry);
- hwif->tp_ops->exec_command(hwif, cmd);
+ if ((cmd->protocol != ATAPI_PROT_DMA &&
+ cmd->protocol != ATAPI_PROT_PIO) ||
+ (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT))
+ __ide_set_handler(drive, handler, timeout);
+ hwif->tp_ops->exec_command(hwif, cmd->tf.command);
/*
* Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that.
@@ -868,314 +482,6 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
ndelay(400);
spin_unlock_irqrestore(&hwif->lock, flags);
}
-EXPORT_SYMBOL(ide_execute_command);
-
-void ide_execute_pkt_cmd(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- unsigned long flags;
-
- spin_lock_irqsave(&hwif->lock, flags);
- hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET);
- ndelay(400);
- spin_unlock_irqrestore(&hwif->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
-
-static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
-{
- struct request *rq = drive->hwif->rq;
-
- if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
- ide_end_request(drive, err ? err : 1, 0);
-}
-
-/* needed below */
-static ide_startstop_t do_reset1 (ide_drive_t *, int);
-
-/*
- * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an atapi drive reset operation. If the drive has not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 stat;
-
- SELECT_DRIVE(drive);
- udelay (10);
- stat = hwif->tp_ops->read_status(hwif);
-
- if (OK_STAT(stat, 0, ATA_BUSY))
- printk("%s: ATAPI reset complete\n", drive->name);
- else {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- /* continue polling */
- return ide_started;
- }
- /* end of polling */
- hwif->polling = 0;
- printk("%s: ATAPI reset timed-out, status=0x%02x\n",
- drive->name, stat);
- /* do it the old fashioned way */
- return do_reset1(drive, 1);
- }
- /* done polling */
- hwif->polling = 0;
- ide_complete_drive_reset(drive, 0);
- return ide_stopped;
-}
-
-static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
-{
- static const char *err_master_vals[] =
- { NULL, "passed", "formatter device error",
- "sector buffer error", "ECC circuitry error",
- "controlling MPU error" };
-
- u8 err_master = err & 0x7f;
-
- printk(KERN_ERR "%s: reset: master: ", hwif->name);
- if (err_master && err_master < 6)
- printk(KERN_CONT "%s", err_master_vals[err_master]);
- else
- printk(KERN_CONT "error (0x%02x?)", err);
- if (err & 0x80)
- printk(KERN_CONT "; slave: failed");
- printk(KERN_CONT "\n");
-}
-
-/*
- * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an ide reset operation. If the drives have not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- u8 tmp;
- int err = 0;
-
- if (port_ops && port_ops->reset_poll) {
- err = port_ops->reset_poll(drive);
- if (err) {
- printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
- hwif->name, drive->name);
- goto out;
- }
- }
-
- tmp = hwif->tp_ops->read_status(hwif);
-
- if (!OK_STAT(tmp, 0, ATA_BUSY)) {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
- /* continue polling */
- return ide_started;
- }
- printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
- drive->failures++;
- err = -EIO;
- } else {
- tmp = ide_read_error(drive);
-
- if (tmp == 1) {
- printk(KERN_INFO "%s: reset: success\n", hwif->name);
- drive->failures = 0;
- } else {
- ide_reset_report_error(hwif, tmp);
- drive->failures++;
- err = -EIO;
- }
- }
-out:
- hwif->polling = 0; /* done polling */
- ide_complete_drive_reset(drive, err);
- return ide_stopped;
-}
-
-static void ide_disk_pre_reset(ide_drive_t *drive)
-{
- int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
-
- drive->special.all = 0;
- drive->special.b.set_geometry = legacy;
- drive->special.b.recalibrate = legacy;
-
- drive->mult_count = 0;
- drive->dev_flags &= ~IDE_DFLAG_PARKED;
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
- drive->mult_req = 0;
-
- if (drive->mult_req != drive->mult_count)
- drive->special.b.set_multmode = 1;
-}
-
-static void pre_reset(ide_drive_t *drive)
-{
- const struct ide_port_ops *port_ops = drive->hwif->port_ops;
-
- if (drive->media == ide_disk)
- ide_disk_pre_reset(drive);
- else
- drive->dev_flags |= IDE_DFLAG_POST_RESET;
-
- if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
- if (drive->crc_count)
- ide_check_dma_crc(drive);
- else
- ide_dma_off(drive);
- }
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
- drive->dev_flags &= ~IDE_DFLAG_UNMASK;
- drive->io_32bit = 0;
- }
- return;
- }
-
- if (port_ops && port_ops->pre_reset)
- port_ops->pre_reset(drive);
-
- if (drive->current_speed != 0xff)
- drive->desired_speed = drive->current_speed;
- drive->current_speed = 0xff;
-}
-
-/*
- * do_reset1() attempts to recover a confused drive by resetting it.
- * Unfortunately, resetting a disk drive actually resets all devices on
- * the same interface, so it can really be thought of as resetting the
- * interface rather than resetting the drive.
- *
- * ATAPI devices have their own reset mechanism which allows them to be
- * individually reset without clobbering other devices on the same interface.
- *
- * Unfortunately, the IDE interface does not generate an interrupt to let
- * us know when the reset operation has finished, so we must poll for this.
- * Equally poor, though, is the fact that this may a very long time to complete,
- * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
- * we set a timer to poll at 50ms intervals.
- */
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- const struct ide_port_ops *port_ops;
- ide_drive_t *tdrive;
- unsigned long flags, timeout;
- int i;
- DEFINE_WAIT(wait);
-
- spin_lock_irqsave(&hwif->lock, flags);
-
- /* We must not reset with running handlers */
- BUG_ON(hwif->handler != NULL);
-
- /* For an ATAPI device, first try an ATAPI SRST. */
- if (drive->media != ide_disk && !do_not_try_atapi) {
- pre_reset(drive);
- SELECT_DRIVE(drive);
- udelay (20);
- tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
- ndelay(400);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
- }
-
- /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
- do {
- unsigned long now;
-
- prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
- timeout = jiffies;
- ide_port_for_each_dev(i, tdrive, hwif) {
- if (tdrive->dev_flags & IDE_DFLAG_PRESENT &&
- tdrive->dev_flags & IDE_DFLAG_PARKED &&
- time_after(tdrive->sleep, timeout))
- timeout = tdrive->sleep;
- }
-
- now = jiffies;
- if (time_before_eq(timeout, now))
- break;
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- timeout = schedule_timeout_uninterruptible(timeout - now);
- spin_lock_irqsave(&hwif->lock, flags);
- } while (timeout);
- finish_wait(&ide_park_wq, &wait);
-
- /*
- * First, reset any device state data we were maintaining
- * for any of the drives on this interface.
- */
- ide_port_for_each_dev(i, tdrive, hwif)
- pre_reset(tdrive);
-
- if (io_ports->ctl_addr == 0) {
- spin_unlock_irqrestore(&hwif->lock, flags);
- ide_complete_drive_reset(drive, -ENXIO);
- return ide_stopped;
- }
-
- /*
- * Note that we also set nIEN while resetting the device,
- * to mask unwanted interrupts from the interface during the reset.
- * However, due to the design of PC hardware, this will cause an
- * immediate interrupt due to the edge transition it produces.
- * This single interrupt gives us a "fast poll" for drives that
- * recover from reset very quickly, saving us the first 50ms wait time.
- *
- * TODO: add ->softreset method and stop abusing ->set_irq
- */
- /* set SRST and nIEN */
- tp_ops->set_irq(hwif, 4);
- /* more than enough time */
- udelay(10);
- /* clear SRST, leave nIEN (unless device is on the quirk list) */
- tp_ops->set_irq(hwif, drive->quirk_list == 2);
- /* more than enough time */
- udelay(10);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
-
- /*
- * Some weird controller like resetting themselves to a strange
- * state when the disks are reset this way. At least, the Winbond
- * 553 documentation says that
- */
- port_ops = hwif->port_ops;
- if (port_ops && port_ops->resetproc)
- port_ops->resetproc(drive);
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
-}
-
-/*
- * ide_do_reset() is the entry point to the drive/interface reset code.
- */
-
-ide_startstop_t ide_do_reset (ide_drive_t *drive)
-{
- return do_reset1(drive, 0);
-}
-
-EXPORT_SYMBOL(ide_do_reset);
/*
* ide_wait_not_busy() waits for the currently selected device on the hwif
@@ -1185,7 +491,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
{
u8 stat = 0;
- while(timeout--) {
+ while (timeout--) {
/*
* Turn this into a schedule() sleep once I'm sure
* about locking issues (2.5 work ?).
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 09526a0de734..217b7fdf2b17 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -5,163 +5,6 @@
#include <linux/ide.h>
#include <linux/bitops.h>
-static const char *udma_str[] =
- { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
- "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
-static const char *mwdma_str[] =
- { "MWDMA0", "MWDMA1", "MWDMA2" };
-static const char *swdma_str[] =
- { "SWDMA0", "SWDMA1", "SWDMA2" };
-static const char *pio_str[] =
- { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
-
-/**
- * ide_xfer_verbose - return IDE mode names
- * @mode: transfer mode
- *
- * Returns a constant string giving the name of the mode
- * requested.
- */
-
-const char *ide_xfer_verbose(u8 mode)
-{
- const char *s;
- u8 i = mode & 0xf;
-
- if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
- s = udma_str[i];
- else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
- s = mwdma_str[i];
- else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
- s = swdma_str[i];
- else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
- s = pio_str[i & 0x7];
- else if (mode == XFER_PIO_SLOW)
- s = "PIO SLOW";
- else
- s = "XFER ERROR";
-
- return s;
-}
-EXPORT_SYMBOL(ide_xfer_verbose);
-
-/**
- * ide_rate_filter - filter transfer mode
- * @drive: IDE device
- * @speed: desired speed
- *
- * Given the available transfer modes this function returns
- * the best available speed at or below the speed requested.
- *
- * TODO: check device PIO capabilities
- */
-
-static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 mode = ide_find_dma_mode(drive, speed);
-
- if (mode == 0) {
- if (hwif->pio_mask)
- mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
- else
- mode = XFER_PIO_4;
- }
-
-/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
-
- return min(speed, mode);
-}
-
-/**
- * ide_get_best_pio_mode - get PIO mode from drive
- * @drive: drive to consider
- * @mode_wanted: preferred mode
- * @max_mode: highest allowed mode
- *
- * This routine returns the recommended PIO settings for a given drive,
- * based on the drive->id information and the ide_pio_blacklist[].
- *
- * Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
- * This is used by most chipset support modules when "auto-tuning".
- */
-
-u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
-{
- u16 *id = drive->id;
- int pio_mode = -1, overridden = 0;
-
- if (mode_wanted != 255)
- return min_t(u8, mode_wanted, max_mode);
-
- if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
- pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
-
- if (pio_mode != -1) {
- printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
- } else {
- pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
- if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
- pio_mode = 2;
- overridden = 1;
- }
-
- if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
- if (ata_id_has_iordy(id)) {
- if (id[ATA_ID_PIO_MODES] & 7) {
- overridden = 0;
- if (id[ATA_ID_PIO_MODES] & 4)
- pio_mode = 5;
- else if (id[ATA_ID_PIO_MODES] & 2)
- pio_mode = 4;
- else
- pio_mode = 3;
- }
- }
- }
-
- if (overridden)
- printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
- drive->name);
- }
-
- if (pio_mode > max_mode)
- pio_mode = max_mode;
-
- return pio_mode;
-}
-EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
-
-/* req_pio == "255" for auto-tune */
-void ide_set_pio(ide_drive_t *drive, u8 req_pio)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- u8 host_pio, pio;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return;
-
- BUG_ON(hwif->pio_mask == 0x00);
-
- host_pio = fls(hwif->pio_mask) - 1;
-
- pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
-
- /*
- * TODO:
- * - report device max PIO mode
- * - check req_pio != 255 against device max PIO mode
- */
- printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
- drive->name, host_pio, req_pio,
- req_pio == 255 ? "(auto-tune)" : "", pio);
-
- (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
-}
-EXPORT_SYMBOL_GPL(ide_set_pio);
-
/**
* ide_toggle_bounce - handle bounce buffering
* @drive: drive to update
@@ -188,105 +31,22 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
blk_queue_bounce_limit(drive->queue, addr);
}
-int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 0;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL)
- return -1;
-
- /*
- * TODO: temporary hack for some legacy host drivers that didn't
- * set transfer mode on the device in ->set_pio_mode method...
- */
- if (port_ops->set_dma_mode == NULL) {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return 0;
- }
-
- if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
- if (ide_config_drive_speed(drive, mode))
- return -1;
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return 0;
- } else {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return ide_config_drive_speed(drive, mode);
- }
-}
-
-int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 0;
-
- if (port_ops == NULL || port_ops->set_dma_mode == NULL)
- return -1;
-
- if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
- if (ide_config_drive_speed(drive, mode))
- return -1;
- port_ops->set_dma_mode(drive, mode);
- return 0;
- } else {
- port_ops->set_dma_mode(drive, mode);
- return ide_config_drive_speed(drive, mode);
- }
-}
-EXPORT_SYMBOL_GPL(ide_set_dma_mode);
-
-/**
- * ide_set_xfer_rate - set transfer rate
- * @drive: drive to set
- * @rate: speed to attempt to set
- *
- * General helper for setting the speed of an IDE device. This
- * function knows about user enforced limits from the configuration
- * which ->set_pio_mode/->set_dma_mode does not.
- */
-
-int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return -1;
-
- rate = ide_rate_filter(drive, rate);
-
- BUG_ON(rate < XFER_PIO_0);
-
- if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
- return ide_set_pio_mode(drive, rate);
-
- return ide_set_dma_mode(drive, rate);
-}
-
static void ide_dump_opcode(ide_drive_t *drive)
{
struct request *rq = drive->hwif->rq;
- ide_task_t *task = NULL;
+ struct ide_cmd *cmd = NULL;
if (!rq)
return;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
- task = rq->special;
+ cmd = rq->special;
printk(KERN_ERR "ide: failed opcode was: ");
- if (task == NULL)
+ if (cmd == NULL)
printk(KERN_CONT "unknown\n");
else
- printk(KERN_CONT "0x%02x\n", task->tf.command);
+ printk(KERN_CONT "0x%02x\n", cmd->tf.command);
}
u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
@@ -306,18 +66,18 @@ EXPORT_SYMBOL_GPL(ide_get_lba_addr);
static void ide_dump_sector(ide_drive_t *drive)
{
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
- memset(&task, 0, sizeof(task));
+ memset(&cmd, 0, sizeof(cmd));
if (lba48)
- task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
+ cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
IDE_TFLAG_LBA48;
else
- task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
+ cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
if (lba48 || (tf->device & ATA_LBA))
printk(KERN_CONT ", LBAsect=%llu",
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index c875a957596c..9490b446519f 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -60,6 +60,32 @@ out:
return;
}
+ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
+{
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
+
+ memset(&cmd, 0, sizeof(cmd));
+ if (rq->cmd[0] == REQ_PARK_HEADS) {
+ drive->sleep = *(unsigned long *)rq->special;
+ drive->dev_flags |= IDE_DFLAG_SLEEPING;
+ tf->command = ATA_CMD_IDLEIMMEDIATE;
+ tf->feature = 0x44;
+ tf->lbal = 0x4c;
+ tf->lbam = 0x4e;
+ tf->lbah = 0x55;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ } else /* cmd == REQ_UNPARK_HEADS */
+ tf->command = ATA_CMD_CHK_POWER;
+
+ cmd.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.protocol = ATA_PROT_NODATA;
+
+ cmd.rq = rq;
+
+ return do_rw_taskfile(drive, &cmd);
+}
+
ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c
index bddae2b329a0..61111fd27130 100644
--- a/drivers/ide/ide-pci-generic.c
+++ b/drivers/ide/ide-pci-generic.c
@@ -33,8 +33,6 @@ static int ide_generic_all; /* Set to claim all devices */
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
-#define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS)
-
#define DECLARE_GENERIC_PCI_DEV(extra_flags) \
{ \
.name = DRV_NAME, \
@@ -61,7 +59,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
/* 2: SAMURAI / HT6565 / HINT_IDE */
DECLARE_GENERIC_PCI_DEV(0),
/* 3: UM8673F / UM8886A / UM8886BF */
- DECLARE_GENERIC_PCI_DEV(IDE_HFLAGS_UMC),
+ DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_DMA),
/* 4: VIA_IDE / OPTI621V / Piccolo010{2,3,5} */
DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_AUTODMA),
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index 60538d9c84ee..ebf2d21ebdcb 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -1,6 +1,5 @@
#include <linux/kernel.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{
@@ -8,7 +7,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- ide_task_t args;
+ struct ide_cmd cmd;
int ret;
/* call ACPI _GTM only once */
@@ -16,10 +15,10 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_acpi_get_timing(hwif);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
+ memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_SUSPEND;
- rq->special = &args;
+ rq->special = &cmd;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_SUSPEND;
if (mesg.event == PM_EVENT_PRETHAW)
@@ -42,7 +41,7 @@ int generic_ide_resume(struct device *dev)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- ide_task_t args;
+ struct ide_cmd cmd;
int err;
/* call ACPI _PS0 / _STM only once */
@@ -54,11 +53,11 @@ int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
+ memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_RESUME;
rq->cmd_flags |= REQ_PREEMPT;
- rq->special = &args;
+ rq->special = &cmd;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_RESUME;
rqpm.pm_state = PM_EVENT_ON;
@@ -109,9 +108,9 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{
struct request_pm_state *pm = rq->data;
- ide_task_t *args = rq->special;
+ struct ide_cmd *cmd = rq->special;
- memset(args, 0, sizeof(*args));
+ memset(cmd, 0, sizeof(*cmd));
switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
@@ -124,12 +123,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
}
if (ata_id_flush_ext_enabled(drive->id))
- args->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd->tf.command = ATA_CMD_FLUSH_EXT;
else
- args->tf.command = ATA_CMD_FLUSH;
+ cmd->tf.command = ATA_CMD_FLUSH;
goto out_do_tf;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
- args->tf.command = ATA_CMD_STANDBYNOW1;
+ cmd->tf.command = ATA_CMD_STANDBYNOW1;
goto out_do_tf;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
ide_set_max_pio(drive);
@@ -142,7 +141,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
ide_complete_power_step(drive, rq);
return ide_stopped;
case IDE_PM_IDLE: /* Resume step 2 (idle) */
- args->tf.command = ATA_CMD_IDLEIMMEDIATE;
+ cmd->tf.command = ATA_CMD_IDLEIMMEDIATE;
goto out_do_tf;
case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */
/*
@@ -160,27 +159,34 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
}
pm->pm_step = IDE_PM_COMPLETED;
+
return ide_stopped;
out_do_tf:
- args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args->data_phase = TASKFILE_NO_DATA;
- return do_rw_taskfile(drive, args);
+ cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd->protocol = ATA_PROT_NODATA;
+
+ return do_rw_taskfile(drive, cmd);
}
/**
- * ide_complete_pm_request - end the current Power Management request
+ * ide_complete_pm_rq - end the current Power Management request
* @drive: target drive
* @rq: request
*
* This function cleans up the current PM request and stops the queue
* if necessary.
*/
-void ide_complete_pm_request(ide_drive_t *drive, struct request *rq)
+void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
+ struct request_pm_state *pm = rq->data;
unsigned long flags;
+ ide_complete_power_step(drive, rq);
+ if (pm->pm_step != IDE_PM_COMPLETED)
+ return;
+
#ifdef DEBUG_PM
printk("%s: completing PM request, %s\n", drive->name,
blk_pm_suspend_request(rq) ? "suspend" : "resume");
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index bac9b392b689..6e80b774e88a 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -27,6 +27,10 @@ static struct pnp_device_id idepnp_devices[] = {
{.id = ""}
};
+static const struct ide_port_info ide_pnp_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct ide_host *host;
@@ -60,7 +64,7 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
hw.irq = pnp_irq(dev, 0);
hw.chipset = ide_generic;
- rc = ide_host_add(NULL, hws, &host);
+ rc = ide_host_add(&ide_pnp_port_info, hws, &host);
if (rc)
goto out;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 312127ea443a..daf8bd0b0296 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -181,16 +181,16 @@ static void ide_classify_atapi_dev(ide_drive_t *drive)
* do_identify - identify a drive
* @drive: drive to identify
* @cmd: command used
+ * @id: buffer for IDENTIFY data
*
* Called when we have issued a drive identify command to
* read and parse the results. This function is run with
* interrupts disabled.
*/
-static void do_identify(ide_drive_t *drive, u8 cmd)
+static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
{
ide_hwif_t *hwif = drive->hwif;
- u16 *id = drive->id;
char *m = (char *)&id[ATA_ID_PROD];
unsigned long flags;
int bswap = 1;
@@ -228,43 +228,25 @@ static void do_identify(ide_drive_t *drive, u8 cmd)
m[ATA_ID_PROD_LEN - 1] = '\0';
if (strstr(m, "E X A B Y T E N E S T"))
- goto err_misc;
-
- drive->dev_flags |= IDE_DFLAG_PRESENT;
- drive->dev_flags &= ~IDE_DFLAG_DEAD;
-
- /*
- * Check for an ATAPI device
- */
- if (cmd == ATA_CMD_ID_ATAPI)
- ide_classify_atapi_dev(drive);
+ drive->dev_flags &= ~IDE_DFLAG_PRESENT;
else
- /*
- * Not an ATAPI device: looks like a "regular" hard disk
- */
- ide_classify_ata_dev(drive);
- return;
-err_misc:
- kfree(id);
- drive->dev_flags &= ~IDE_DFLAG_PRESENT;
+ drive->dev_flags |= IDE_DFLAG_PRESENT;
}
/**
- * actual_try_to_identify - send ata/atapi identify
+ * ide_dev_read_id - send ATA/ATAPI IDENTIFY command
* @drive: drive to identify
* @cmd: command to use
+ * @id: buffer for IDENTIFY data
*
- * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
- * and waits for a response. It also monitors irqs while this is
- * happening, in hope of automatically determining which one is
- * being used by the interface.
+ * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
*
* Returns: 0 device was identified
* 1 device timed-out (no response to identify request)
* 2 device aborted the command (refused to identify itself)
*/
-static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
+int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -273,6 +255,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
unsigned long timeout;
u8 s = 0, a = 0;
+ /*
+ * Disable device IRQ. Otherwise we'll get spurious interrupts
+ * during the identify phase that the IRQ handler isn't expecting.
+ */
+ if (io_ports->ctl_addr)
+ tp_ops->set_irq(hwif, 0);
+
/* take a deep breath */
msleep(50);
@@ -294,13 +283,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
* identify command to be sure of reply
*/
if (cmd == ATA_CMD_ID_ATAPI) {
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
+ memset(&cmd, 0, sizeof(cmd));
/* disable DMA & overlap */
- task.tf_flags = IDE_TFLAG_OUT_FEATURE;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE;
- tp_ops->tf_load(drive, &task);
+ tp_ops->tf_load(drive, &cmd);
}
/* ask drive for ID */
@@ -317,7 +306,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
/* drive returned ID */
- do_identify(drive, cmd);
+ do_identify(drive, cmd, id);
/* drive responded with ID */
rc = 0;
/* clear drive IRQ */
@@ -329,63 +318,6 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
return rc;
}
-/**
- * try_to_identify - try to identify a drive
- * @drive: drive to probe
- * @cmd: command to use
- *
- * Issue the identify command and then do IRQ probing to
- * complete the identification when needed by finding the
- * IRQ the drive is attached to
- */
-
-static int try_to_identify (ide_drive_t *drive, u8 cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- int retval;
- int autoprobe = 0;
- unsigned long cookie = 0;
-
- /*
- * Disable device irq unless we need to
- * probe for it. Otherwise we'll get spurious
- * interrupts during the identify-phase that
- * the irq handler isn't expecting.
- */
- if (hwif->io_ports.ctl_addr) {
- if (!hwif->irq) {
- autoprobe = 1;
- cookie = probe_irq_on();
- }
- tp_ops->set_irq(hwif, autoprobe);
- }
-
- retval = actual_try_to_identify(drive, cmd);
-
- if (autoprobe) {
- int irq;
-
- tp_ops->set_irq(hwif, 0);
- /* clear drive IRQ */
- (void)tp_ops->read_status(hwif);
- udelay(5);
- irq = probe_irq_off(cookie);
- if (!hwif->irq) {
- if (irq > 0) {
- hwif->irq = irq;
- } else {
- /* Mmmm.. multiple IRQs..
- * don't know which was ours
- */
- printk(KERN_ERR "%s: IRQ probe failed (0x%lx)\n",
- drive->name, cookie);
- }
- }
- }
- return retval;
-}
-
int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
{
u8 stat;
@@ -405,14 +337,14 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
static u8 ide_read_device(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_DEVICE;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.device;
+ return cmd.tf.device;
}
/**
@@ -440,6 +372,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ u16 *id = drive->id;
int rc;
u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
@@ -475,11 +408,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
present || cmd == ATA_CMD_ID_ATAPI) {
- /* send cmd and wait */
- if ((rc = try_to_identify(drive, cmd))) {
+ rc = ide_dev_read_id(drive, cmd, id);
+ if (rc)
/* failed: try again */
- rc = try_to_identify(drive,cmd);
- }
+ rc = ide_dev_read_id(drive, cmd, id);
stat = tp_ops->read_status(hwif);
@@ -494,7 +426,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
- rc = try_to_identify(drive, cmd);
+ rc = ide_dev_read_id(drive, cmd, id);
}
/* ensure drive IRQ is clear */
@@ -517,37 +449,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
return rc;
}
-/*
- *
- */
-static void enable_nest (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- u8 stat;
-
- printk(KERN_INFO "%s: enabling %s -- ",
- hwif->name, (char *)&drive->id[ATA_ID_PROD]);
-
- SELECT_DRIVE(drive);
- msleep(50);
- tp_ops->exec_command(hwif, ATA_EXABYTE_ENABLE_NEST);
-
- if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 0)) {
- printk(KERN_CONT "failed (timeout)\n");
- return;
- }
-
- msleep(50);
-
- stat = tp_ops->read_status(hwif);
-
- if (!OK_STAT(stat, 0, BAD_STAT))
- printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
- else
- printk(KERN_CONT "success\n");
-}
-
/**
* probe_for_drives - upper level drive probe
* @drive: drive to probe for
@@ -563,6 +464,8 @@ static void enable_nest (ide_drive_t *drive)
static u8 probe_for_drive(ide_drive_t *drive)
{
char *m;
+ int rc;
+ u8 cmd;
/*
* In order to keep things simple we have an id
@@ -586,20 +489,17 @@ static u8 probe_for_drive(ide_drive_t *drive)
/* skip probing? */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) {
-retry:
/* if !(success||timed-out) */
- if (do_probe(drive, ATA_CMD_ID_ATA) >= 2)
+ cmd = ATA_CMD_ID_ATA;
+ rc = do_probe(drive, cmd);
+ if (rc >= 2) {
/* look for ATAPI device */
- (void)do_probe(drive, ATA_CMD_ID_ATAPI);
+ cmd = ATA_CMD_ID_ATAPI;
+ rc = do_probe(drive, cmd);
+ }
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- /* drive not found */
- return 0;
-
- if (strstr(m, "E X A B Y T E N E S T")) {
- enable_nest(drive);
- goto retry;
- }
+ goto out_free;
/* identification failed? */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -614,12 +514,16 @@ retry:
printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name);
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
}
+ } else {
+ if (cmd == ATA_CMD_ID_ATAPI)
+ ide_classify_atapi_dev(drive);
+ else
+ ide_classify_ata_dev(drive);
}
- /* drive was found */
}
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- return 0;
+ goto out_free;
/* The drive wasn't being helpful. Add generic info only */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -632,7 +536,10 @@ retry:
ide_disk_init_mult_count(drive);
}
- return !!(drive->dev_flags & IDE_DFLAG_PRESENT);
+ return 1;
+out_free:
+ kfree(drive->id);
+ return 0;
}
static void hwif_release_dev(struct device *dev)
@@ -649,7 +556,8 @@ static int ide_register_port(ide_hwif_t *hwif)
/* register with global device tree */
dev_set_name(&hwif->gendev, hwif->name);
hwif->gendev.driver_data = hwif;
- hwif->gendev.parent = hwif->dev;
+ if (hwif->gendev.parent == NULL)
+ hwif->gendev.parent = hwif->dev;
hwif->gendev.release = hwif_release_dev;
ret = device_register(&hwif->gendev);
@@ -778,7 +686,6 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
static int ide_probe_port(ide_hwif_t *hwif)
{
ide_drive_t *drive;
- unsigned long flags;
unsigned int irqd;
int i, rc = -ENODEV;
@@ -796,9 +703,6 @@ static int ide_probe_port(ide_hwif_t *hwif)
if (irqd)
disable_irq(hwif->irq);
- local_save_flags(flags);
- local_irq_enable_in_hardirq();
-
if (ide_port_wait_ready(hwif) == -EBUSY)
printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
@@ -812,8 +716,6 @@ static int ide_probe_port(ide_hwif_t *hwif)
rc = 0;
}
- local_irq_restore(flags);
-
/*
* Use cached IRQ number. It might be (and is...) changed by probe
* code above
@@ -830,29 +732,18 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
int i;
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- if (port_ops && port_ops->quirkproc)
- port_ops->quirkproc(drive);
- }
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ if (port_ops && port_ops->quirkproc)
+ port_ops->quirkproc(drive);
}
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- ide_set_max_pio(drive);
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ ide_set_max_pio(drive);
- drive->dev_flags |= IDE_DFLAG_NICE1;
+ drive->dev_flags |= IDE_DFLAG_NICE1;
- if (hwif->dma_ops)
- ide_set_dma(drive);
- }
- }
-
- ide_port_for_each_dev(i, drive, hwif) {
- if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
- drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
- else
- drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
+ if (hwif->dma_ops)
+ ide_set_dma(drive);
}
}
@@ -923,10 +814,7 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
int i, j = 0;
mutex_lock(&ide_cfg_mtx);
- ide_port_for_each_dev(i, drive, hwif) {
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
-
+ ide_port_for_each_present_dev(i, drive, hwif) {
if (ide_init_queue(drive)) {
printk(KERN_ERR "ide: failed to init %s\n",
drive->name);
@@ -949,21 +837,7 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
static int init_irq (ide_hwif_t *hwif)
{
struct ide_io_ports *io_ports = &hwif->io_ports;
- int sa = 0;
-
- mutex_lock(&ide_cfg_mtx);
- spin_lock_init(&hwif->lock);
-
- init_timer(&hwif->timer);
- hwif->timer.function = &ide_timer_expiry;
- hwif->timer.data = (unsigned long)hwif;
-
-#if defined(__mc68000__)
- sa = IRQF_SHARED;
-#endif /* __mc68000__ */
-
- if (hwif->chipset == ide_pci)
- sa = IRQF_SHARED;
+ int sa = hwif->host->irq_flags;
if (io_ports->ctl_addr)
hwif->tp_ops->set_irq(hwif, 1);
@@ -971,14 +845,6 @@ static int init_irq (ide_hwif_t *hwif)
if (request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwif))
goto out_up;
- if (!hwif->rqsize) {
- if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
- (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
- hwif->rqsize = 256;
- else
- hwif->rqsize = 65536;
- }
-
#if !defined(__mc68000__)
printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
io_ports->data_addr, io_ports->status_addr,
@@ -991,10 +857,8 @@ static int init_irq (ide_hwif_t *hwif)
printk(KERN_CONT " (serialized)");
printk(KERN_CONT "\n");
- mutex_unlock(&ide_cfg_mtx);
return 0;
out_up:
- mutex_unlock(&ide_cfg_mtx);
return 1;
}
@@ -1073,34 +937,25 @@ EXPORT_SYMBOL_GPL(ide_init_disk);
static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
- ide_hwif_t *hwif = drive->hwif;
ide_proc_unregister_device(drive);
- spin_lock_irq(&hwif->lock);
+ blk_cleanup_queue(drive->queue);
+ drive->queue = NULL;
+
kfree(drive->id);
drive->id = NULL;
+
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
- /* Messed up locking ... */
- spin_unlock_irq(&hwif->lock);
- blk_cleanup_queue(drive->queue);
- spin_lock_irq(&hwif->lock);
- drive->queue = NULL;
- spin_unlock_irq(&hwif->lock);
complete(&drive->gendev_rel_comp);
}
static int hwif_init(ide_hwif_t *hwif)
{
- int old_irq;
-
if (!hwif->irq) {
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- if (!hwif->irq) {
- printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
- return 0;
- }
+ printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
+ return 0;
}
if (register_blkdev(hwif->major, hwif->name))
@@ -1118,29 +973,12 @@ static int hwif_init(ide_hwif_t *hwif)
sg_init_table(hwif->sg_table, hwif->sg_max_nents);
- if (init_irq(hwif) == 0)
- goto done;
-
- old_irq = hwif->irq;
- /*
- * It failed to initialise. Find the default IRQ for
- * this port and try that.
- */
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- if (!hwif->irq) {
- printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
- hwif->name, old_irq);
- goto out;
- }
if (init_irq(hwif)) {
- printk(KERN_ERR "%s: probed IRQ %d and default IRQ %d failed\n",
- hwif->name, old_irq, hwif->irq);
+ printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
+ hwif->name, hwif->irq);
goto out;
}
- printk(KERN_WARNING "%s: probed IRQ %d failed, using default\n",
- hwif->name, hwif->irq);
-done:
blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
THIS_MODULE, ata_probe, ata_lock, hwif);
return 1;
@@ -1155,13 +993,10 @@ static void hwif_register_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
unsigned int i;
- ide_port_for_each_dev(i, drive, hwif) {
+ ide_port_for_each_present_dev(i, drive, hwif) {
struct device *dev = &drive->gendev;
int ret;
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
-
dev_set_name(dev, "%u.%u", hwif->index, i);
dev->parent = &hwif->gendev;
dev->bus = &ide_bus_type;
@@ -1186,6 +1021,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
drive->io_32bit = 1;
+ if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
+ drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
drive->dev_flags |= IDE_DFLAG_UNMASK;
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
@@ -1207,10 +1044,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (d->init_iops)
d->init_iops(hwif);
- if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
- (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
- hwif->irq = port ? 15 : 14;
-
/* ->host_flags may be set by ->init_iops (or even earlier...) */
hwif->host_flags |= d->host_flags;
hwif->pio_mask = d->pio_mask;
@@ -1219,7 +1052,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
hwif->tp_ops = d->tp_ops;
/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
- if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
+ if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0)
hwif->port_ops = d->port_ops;
hwif->swdma_mask = d->swdma_mask;
@@ -1253,6 +1086,13 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (d->max_sectors)
hwif->rqsize = d->max_sectors;
+ else {
+ if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+ (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
+ hwif->rqsize = 256;
+ else
+ hwif->rqsize = 65536;
+ }
/* call chipset specific routine for each enabled port */
if (d->init_hwif)
@@ -1311,6 +1151,12 @@ static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
hwif->name[2] = 'e';
hwif->name[3] = '0' + index;
+ spin_lock_init(&hwif->lock);
+
+ init_timer(&hwif->timer);
+ hwif->timer.function = &ide_timer_expiry;
+ hwif->timer.data = (unsigned long)hwif;
+
init_completion(&hwif->gendev_rel_comp);
hwif->tp_ops = &default_tp_ops;
@@ -1459,6 +1305,8 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
if (d) {
host->init_chipset = d->init_chipset;
+ host->get_lock = d->get_lock;
+ host->release_lock = d->release_lock;
host->host_flags = d->host_flags;
}
@@ -1466,6 +1314,30 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
}
EXPORT_SYMBOL_GPL(ide_host_alloc);
+static void ide_port_free(ide_hwif_t *hwif)
+{
+ ide_port_free_devices(hwif);
+ ide_free_port_slot(hwif->index);
+ kfree(hwif);
+}
+
+static void ide_disable_port(ide_hwif_t *hwif)
+{
+ struct ide_host *host = hwif->host;
+ int i;
+
+ printk(KERN_INFO "%s: disabling port\n", hwif->name);
+
+ for (i = 0; i < MAX_HOST_PORTS; i++) {
+ if (host->ports[i] == hwif) {
+ host->ports[i] = NULL;
+ host->n_ports--;
+ }
+ }
+
+ ide_port_free(hwif);
+}
+
int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
hw_regs_t **hws)
{
@@ -1481,20 +1353,15 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_init_port_hw(hwif, hws[i]);
ide_port_apply_params(hwif);
- if (d == NULL) {
- mate = NULL;
- } else {
- if ((i & 1) && mate) {
- hwif->mate = mate;
- mate->mate = hwif;
- }
-
- mate = (i & 1) ? NULL : hwif;
-
- ide_init_port(hwif, i & 1, d);
- ide_port_cable_detect(hwif);
+ if ((i & 1) && mate) {
+ hwif->mate = mate;
+ mate->mate = hwif;
}
+ mate = (i & 1) ? NULL : hwif;
+
+ ide_init_port(hwif, i & 1, d);
+ ide_port_cable_detect(hwif);
ide_port_init_devices(hwif);
}
@@ -1505,9 +1372,13 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
if (ide_probe_port(hwif) == 0)
hwif->present = 1;
- if (hwif->chipset != ide_4drives || !hwif->mate ||
- !hwif->mate->present)
- ide_register_port(hwif);
+ if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
+ hwif->mate == NULL || hwif->mate->present == 0) {
+ if (ide_register_port(hwif)) {
+ ide_disable_port(hwif);
+ continue;
+ }
+ }
if (hwif->present)
ide_port_tune_devices(hwif);
@@ -1520,7 +1391,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
if (hwif_init(hwif) == 0) {
printk(KERN_INFO "%s: failed to initialize IDE "
"interface\n", hwif->name);
- hwif->present = 0;
+ device_unregister(&hwif->gendev);
+ ide_disable_port(hwif);
continue;
}
@@ -1532,7 +1404,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
j++;
- ide_acpi_init(hwif);
+ ide_acpi_init_port(hwif);
if (hwif->present)
ide_acpi_port_init_devices(hwif);
@@ -1589,11 +1461,9 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
int i;
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- device_unregister(&drive->gendev);
- wait_for_completion(&drive->gendev_rel_comp);
- }
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ device_unregister(&drive->gendev);
+ wait_for_completion(&drive->gendev_rel_comp);
}
}
@@ -1659,12 +1529,8 @@ void ide_host_free(struct ide_host *host)
int i;
ide_host_for_each_port(i, hwif, host) {
- if (hwif == NULL)
- continue;
-
- ide_port_free_devices(hwif);
- ide_free_port_slot(hwif->index);
- kfree(hwif);
+ if (hwif)
+ ide_port_free(hwif);
}
kfree(host);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 1d8978b3314a..0ee8887ba277 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -194,20 +194,20 @@ ide_devset_get(xfer_rate, current_speed);
static int set_xfer_rate (ide_drive_t *drive, int arg)
{
- ide_task_t task;
+ struct ide_cmd cmd;
int err;
if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
return -EINVAL;
- memset(&task, 0, sizeof(task));
- task.tf.command = ATA_CMD_SET_FEATURES;
- task.tf.feature = SETFEATURES_XFER;
- task.tf.nsect = (u8)arg;
- task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
- IDE_TFLAG_IN_NSECT;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.command = ATA_CMD_SET_FEATURES;
+ cmd.tf.feature = SETFEATURES_XFER;
+ cmd.tf.nsect = (u8)arg;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
+ IDE_TFLAG_IN_NSECT;
- err = ide_no_data_taskfile(drive, &task);
+ err = ide_no_data_taskfile(drive, &cmd);
if (!err) {
ide_set_xfer_rate(drive, (u8) arg);
@@ -600,7 +600,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif)
int i;
ide_port_for_each_dev(i, drive, hwif) {
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc)
+ if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
continue;
drive->proc = proc_mkdir(drive->name, parent);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index d7ecd3c79757..733cb515d781 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -152,11 +152,6 @@ struct idetape_bh {
#define IDETAPE_LU_RETENSION_MASK 2
#define IDETAPE_LU_EOT_MASK 4
-/* Error codes returned in rq->errors to the higher part of the driver. */
-#define IDETAPE_ERROR_GENERAL 101
-#define IDETAPE_ERROR_FILEMARK 102
-#define IDETAPE_ERROR_EOD 103
-
/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
#define IDETAPE_BLOCK_DESCRIPTOR 0
#define IDETAPE_CAPABILITIES_PAGE 0x2a
@@ -169,16 +164,8 @@ typedef struct ide_tape_obj {
ide_drive_t *drive;
struct ide_driver *driver;
struct gendisk *disk;
- struct kref kref;
+ struct device dev;
- /*
- * failed_pc points to the last failed packet command, or contains
- * NULL if we do not need to retry any packet command. This is
- * required since an additional packet command is needed before the
- * retry, to get detailed information on what went wrong.
- */
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
/* used by REQ_IDETAPE_{READ,WRITE} requests */
struct ide_atapi_pc queued_pc;
@@ -245,9 +232,6 @@ typedef struct ide_tape_obj {
/* Wasted space in each stage */
int excess_bh_size;
- /* protects the ide-tape queue */
- spinlock_t lock;
-
/* Measures average tape speed */
unsigned long avg_time;
int avg_size;
@@ -267,7 +251,7 @@ static DEFINE_MUTEX(idetape_ref_mutex);
static struct class *idetape_sysfs_class;
-static void ide_tape_release(struct kref *);
+static void ide_tape_release(struct device *);
static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
{
@@ -279,7 +263,7 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
if (ide_device_get(tape->drive))
tape = NULL;
else
- kref_get(&tape->kref);
+ get_device(&tape->dev);
}
mutex_unlock(&idetape_ref_mutex);
return tape;
@@ -290,7 +274,7 @@ static void ide_tape_put(struct ide_tape_obj *tape)
ide_drive_t *drive = tape->drive;
mutex_lock(&idetape_ref_mutex);
- kref_put(&tape->kref, ide_tape_release);
+ put_device(&tape->dev);
ide_device_put(drive);
mutex_unlock(&idetape_ref_mutex);
}
@@ -308,7 +292,7 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
mutex_lock(&idetape_ref_mutex);
tape = idetape_devs[i];
if (tape)
- kref_get(&tape->kref);
+ get_device(&tape->dev);
mutex_unlock(&idetape_ref_mutex);
return tape;
}
@@ -400,7 +384,7 @@ static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
{
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->failed_pc;
+ struct ide_atapi_pc *pc = drive->failed_pc;
tape->sense_key = sense[2] & 0xF;
tape->asc = sense[12];
@@ -433,19 +417,19 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
}
}
if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
- pc->error = IDETAPE_ERROR_FILEMARK;
+ pc->error = IDE_DRV_ERROR_FILEMARK;
pc->flags |= PC_FLAG_ABORT;
}
if (pc->c[0] == WRITE_6) {
if ((sense[2] & 0x40) || (tape->sense_key == 0xd
&& tape->asc == 0x0 && tape->ascq == 0x2)) {
- pc->error = IDETAPE_ERROR_EOD;
+ pc->error = IDE_DRV_ERROR_EOD;
pc->flags |= PC_FLAG_ABORT;
}
}
if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
if (tape->sense_key == 8) {
- pc->error = IDETAPE_ERROR_EOD;
+ pc->error = IDE_DRV_ERROR_EOD;
pc->flags |= PC_FLAG_ABORT;
}
if (!(pc->flags & PC_FLAG_ABORT) &&
@@ -477,52 +461,23 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
}
}
-static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
-{
- struct request *rq = drive->hwif->rq;
- idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
- int error;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- switch (uptodate) {
- case 0: error = IDETAPE_ERROR_GENERAL; break;
- case 1: error = 0; break;
- default: error = uptodate;
- }
- rq->errors = error;
- if (error)
- tape->failed_pc = NULL;
-
- if (!blk_special_request(rq)) {
- ide_end_request(drive, uptodate, nr_sects);
- return 0;
- }
-
- spin_lock_irqsave(&tape->lock, flags);
-
- ide_end_drive_cmd(drive, 0, 0);
-
- spin_unlock_irqrestore(&tape->lock, flags);
- return 0;
-}
-
static void ide_tape_handle_dsc(ide_drive_t *);
-static void ide_tape_callback(ide_drive_t *drive, int dsc)
+static int ide_tape_callback(ide_drive_t *drive, int dsc)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
+ struct request *rq = drive->hwif->rq;
int uptodate = pc->error ? 0 : 1;
+ int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
debug_log(DBG_PROCS, "Enter %s\n", __func__);
if (dsc)
ide_tape_handle_dsc(drive);
- if (tape->failed_pc == pc)
- tape->failed_pc = NULL;
+ if (drive->failed_pc == pc)
+ drive->failed_pc = NULL;
if (pc->c[0] == REQUEST_SENSE) {
if (uptodate)
@@ -531,7 +486,6 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
"itself - Aborting request!\n");
} else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
- struct request *rq = drive->hwif->rq;
int blocks = pc->xferred / tape->blk_size;
tape->avg_size += blocks * tape->blk_size;
@@ -546,8 +500,10 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
tape->first_frame += blocks;
rq->current_nr_sectors -= blocks;
- if (pc->error)
- uptodate = pc->error;
+ if (pc->error) {
+ uptodate = 0;
+ err = pc->error;
+ }
} else if (pc->c[0] == READ_POSITION && uptodate) {
u8 *readpos = pc->buf;
@@ -561,6 +517,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
"to the tape\n");
clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
uptodate = 0;
+ err = IDE_DRV_ERROR_GENERAL;
} else {
debug_log(DBG_SENSE, "Block Location - %u\n",
be32_to_cpup((__be32 *)&readpos[4]));
@@ -571,7 +528,9 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
}
}
- idetape_end_request(drive, uptodate, 0);
+ rq->errors = err;
+
+ return uptodate;
}
/*
@@ -621,7 +580,7 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
*
* The handling will be done in three stages:
*
- * 1. idetape_issue_pc will send the packet command to the drive, and will set
+ * 1. ide_tape_issue_pc will send the packet command to the drive, and will set
* the interrupt handler to ide_pc_intr.
*
* 2. On each interrupt, ide_pc_intr will be called. This step will be
@@ -649,8 +608,9 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
* request.
*/
-static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
+static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
+ struct ide_cmd *cmd,
+ struct ide_atapi_pc *pc)
{
idetape_tape_t *tape = drive->driver_data;
@@ -660,8 +620,8 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
"Two request sense in serial were issued\n");
}
- if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
- tape->failed_pc = pc;
+ if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
+ drive->failed_pc = pc;
/* Set the current packet command */
drive->pc = pc;
@@ -685,9 +645,9 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
tape->ascq);
}
/* Giving up */
- pc->error = IDETAPE_ERROR_GENERAL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
}
- tape->failed_pc = NULL;
+ drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
return ide_stopped;
}
@@ -695,7 +655,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
pc->retries++;
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, cmd);
}
/* A mode sense command is used to "sense" tape parameters. */
@@ -746,8 +706,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
}
pc->error = 0;
} else {
- pc->error = IDETAPE_ERROR_GENERAL;
- tape->failed_pc = NULL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
+ drive->failed_pc = NULL;
}
drive->pc_callback(drive, 0);
return ide_stopped;
@@ -790,6 +750,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = NULL;
struct request *postponed_rq = tape->postponed_rq;
+ struct ide_cmd cmd;
u8 stat;
debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
@@ -801,13 +762,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
/* We do not support buffer cache originated requests. */
printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
"request queue (%d)\n", drive->name, rq->cmd_type);
- ide_end_request(drive, 0, 0);
+ if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
return ide_stopped;
}
/* Retry a failed packet command */
- if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
- pc = tape->failed_pc;
+ if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
+ pc = drive->failed_pc;
goto out;
}
@@ -815,7 +778,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
if (rq != postponed_rq) {
printk(KERN_ERR "ide-tape: ide-tape.c bug - "
"Two DSC requests were queued\n");
- idetape_end_request(drive, 0, 0);
+ drive->failed_pc = NULL;
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
}
@@ -881,7 +846,14 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
BUG();
out:
- return idetape_issue_pc(drive, pc);
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
+ return ide_tape_issue_pc(drive, &cmd, pc);
}
/*
@@ -1226,7 +1198,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
if (tape->merge_bh)
idetape_init_merge_buffer(tape);
- if (errors == IDETAPE_ERROR_GENERAL)
+ if (errors == IDE_DRV_ERROR_GENERAL)
return -EIO;
return ret;
}
@@ -2042,9 +2014,13 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
+ u8 pc_buf[256];
char fw_rev[4], vendor_id[8], product_id[16];
idetape_create_inquiry_cmd(&pc);
+ pc.buf = &pc_buf[0];
+ pc.buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
tape->name);
@@ -2192,8 +2168,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
drive->pc_update_buffers = idetape_update_buffers;
drive->pc_io_buffers = ide_tape_io_buffers;
- spin_lock_init(&tape->lock);
-
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2256,15 +2230,17 @@ static void ide_tape_remove(ide_drive_t *drive)
idetape_tape_t *tape = drive->driver_data;
ide_proc_unregister_driver(drive, tape->driver);
-
+ device_del(&tape->dev);
ide_unregister_region(tape->disk);
- ide_tape_put(tape);
+ mutex_lock(&idetape_ref_mutex);
+ put_device(&tape->dev);
+ mutex_unlock(&idetape_ref_mutex);
}
-static void ide_tape_release(struct kref *kref)
+static void ide_tape_release(struct device *dev)
{
- struct ide_tape_obj *tape = to_ide_drv(kref, ide_tape_obj);
+ struct ide_tape_obj *tape = to_ide_drv(dev, ide_tape_obj);
ide_drive_t *drive = tape->drive;
struct gendisk *g = tape->disk;
@@ -2323,7 +2299,6 @@ static struct ide_driver idetape_driver = {
.remove = ide_tape_remove,
.version = IDETAPE_VERSION,
.do_request = idetape_do_request,
- .end_request = idetape_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_tape_proc_entries,
.proc_devsets = ide_tape_proc_devsets,
@@ -2407,7 +2382,12 @@ static int ide_tape_probe(ide_drive_t *drive)
ide_init_disk(g, drive);
- kref_init(&tape->kref);
+ tape->dev.parent = &drive->gendev;
+ tape->dev.release = ide_tape_release;
+ dev_set_name(&tape->dev, dev_name(&drive->gendev));
+
+ if (device_register(&tape->dev))
+ goto out_free_disk;
tape->drive = drive;
tape->driver = &idetape_driver;
@@ -2436,6 +2416,8 @@ static int ide_tape_probe(ide_drive_t *drive)
return 0;
+out_free_disk:
+ put_disk(g);
out_free_tape:
kfree(tape);
failed:
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 16138bce84a7..dba68db629bf 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -39,88 +39,84 @@ void ide_tf_dump(const char *s, struct ide_taskfile *tf)
int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
{
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
- args.tf.nsect = 0x01;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.nsect = 0x01;
if (drive->media == ide_disk)
- args.tf.command = ATA_CMD_ID_ATA;
+ cmd.tf.command = ATA_CMD_ID_ATA;
else
- args.tf.command = ATA_CMD_ID_ATAPI;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args.data_phase = TASKFILE_IN;
- return ide_raw_taskfile(drive, &args, buf, 1);
+ cmd.tf.command = ATA_CMD_ID_ATAPI;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.protocol = ATA_PROT_PIO;
+
+ return ide_raw_taskfile(drive, &cmd, buf, 1);
}
static ide_startstop_t task_no_data_intr(ide_drive_t *);
-static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
-static ide_startstop_t task_in_intr(ide_drive_t *);
+static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *);
+static ide_startstop_t task_pio_intr(ide_drive_t *);
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct ide_taskfile *tf = &cmd->tf;
ide_handler_t *handler = NULL;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
- if (task->data_phase == TASKFILE_MULTI_IN ||
- task->data_phase == TASKFILE_MULTI_OUT) {
- if (!drive->mult_count) {
- printk(KERN_ERR "%s: multimode not set!\n",
- drive->name);
- return ide_stopped;
- }
+ if (orig_cmd->protocol == ATA_PROT_PIO &&
+ (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
+ drive->mult_count == 0) {
+ printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+ return ide_stopped;
}
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;
+ if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
+ orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
- memcpy(&hwif->task, task, sizeof(*task));
+ memcpy(cmd, orig_cmd, sizeof(*cmd));
- if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
+ if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
ide_tf_dump(drive->name, tf);
tp_ops->set_irq(hwif, 1);
SELECT_MASK(drive, 0);
- tp_ops->tf_load(drive, task);
+ tp_ops->tf_load(drive, cmd);
}
- switch (task->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- tp_ops->exec_command(hwif, tf->command);
- ndelay(400); /* FIXME */
- return pre_task_out_intr(drive, task->rq);
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- handler = task_in_intr;
+ switch (cmd->protocol) {
+ case ATA_PROT_PIO:
+ if (cmd->tf_flags & IDE_TFLAG_WRITE) {
+ tp_ops->exec_command(hwif, tf->command);
+ ndelay(400); /* FIXME */
+ return pre_task_out_intr(drive, cmd);
+ }
+ handler = task_pio_intr;
/* fall-through */
- case TASKFILE_NO_DATA:
+ case ATA_PROT_NODATA:
if (handler == NULL)
handler = task_no_data_intr;
- ide_execute_command(drive, tf->command, handler,
- WAIT_WORSTCASE, NULL);
+ ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
return ide_started;
- default:
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
- dma_ops->dma_setup(drive))
+ case ATA_PROT_DMA:
+ if (ide_dma_prepare(drive, cmd))
return ide_stopped;
- dma_ops->dma_exec_cmd(drive, tf->command);
+ hwif->expiry = dma_ops->dma_timer_expiry;
+ ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
dma_ops->dma_start(drive);
+ default:
return ide_started;
}
}
EXPORT_SYMBOL_GPL(do_rw_taskfile);
-/*
- * Handler for commands without a data phase
- */
static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- ide_task_t *task = &hwif->task;
- struct ide_taskfile *tf = &task->tf;
- int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct ide_taskfile *tf = &cmd->tf;
+ int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
u8 stat;
@@ -142,28 +138,26 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
} else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
ide_set_handler(drive, &task_no_data_intr,
- WAIT_WORSTCASE, NULL);
+ WAIT_WORSTCASE);
return ide_started;
}
}
return ide_error(drive, "task_no_data_intr", stat);
- /* calls ide_end_drive_cmd */
}
- if (!custom)
- ide_end_drive_cmd(drive, stat, ide_read_error(drive));
- else if (tf->command == ATA_CMD_IDLEIMMEDIATE) {
- hwif->tp_ops->tf_read(drive, task);
- if (tf->lbal != 0xc4) {
- printk(KERN_ERR "%s: head unload failed!\n",
- drive->name);
- ide_tf_dump(drive->name, tf);
- } else
- drive->dev_flags |= IDE_DFLAG_PARKED;
- ide_end_drive_cmd(drive, stat, ide_read_error(drive));
- } else if (tf->command == ATA_CMD_SET_MULTI)
+ if (custom && tf->command == ATA_CMD_SET_MULTI)
drive->mult_count = drive->mult_req;
+ if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE ||
+ tf->command == ATA_CMD_CHK_POWER) {
+ struct request *rq = hwif->rq;
+
+ if (blk_pm_request(rq))
+ ide_complete_pm_rq(drive, rq);
+ else
+ ide_finish_cmd(drive, cmd, stat);
+ }
+
return ide_stopped;
}
@@ -192,239 +186,188 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat;
}
-static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
- unsigned int write)
+void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
+ unsigned int write, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
- struct scatterlist *cursg = hwif->cursg;
+ struct scatterlist *cursg = cmd->cursg;
struct page *page;
-#ifdef CONFIG_HIGHMEM
unsigned long flags;
-#endif
unsigned int offset;
u8 *buf;
- cursg = hwif->cursg;
- if (!cursg) {
- cursg = sg;
- hwif->cursg = sg;
- }
+ cursg = cmd->cursg;
+ if (cursg == NULL)
+ cursg = cmd->cursg = sg;
- page = sg_page(cursg);
- offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
+ while (len) {
+ unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
- /* get the current page and offset */
- page = nth_page(page, (offset >> PAGE_SHIFT));
- offset %= PAGE_SIZE;
+ if (nr_bytes > PAGE_SIZE)
+ nr_bytes = PAGE_SIZE;
-#ifdef CONFIG_HIGHMEM
- local_irq_save(flags);
-#endif
- buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
+ page = sg_page(cursg);
+ offset = cursg->offset + cmd->cursg_ofs;
- hwif->nleft--;
- hwif->cursg_ofs++;
+ /* get the current page and offset */
+ page = nth_page(page, (offset >> PAGE_SHIFT));
+ offset %= PAGE_SIZE;
- if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
- hwif->cursg = sg_next(hwif->cursg);
- hwif->cursg_ofs = 0;
- }
+ if (PageHighMem(page))
+ local_irq_save(flags);
- /* do the actual data transfer */
- if (write)
- hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);
- else
- hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);
+ buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
- kunmap_atomic(buf, KM_BIO_SRC_IRQ);
-#ifdef CONFIG_HIGHMEM
- local_irq_restore(flags);
-#endif
-}
+ cmd->nleft -= nr_bytes;
+ cmd->cursg_ofs += nr_bytes;
-static void ide_pio_multi(ide_drive_t *drive, struct request *rq,
- unsigned int write)
-{
- unsigned int nsect;
+ if (cmd->cursg_ofs == cursg->length) {
+ cursg = cmd->cursg = sg_next(cmd->cursg);
+ cmd->cursg_ofs = 0;
+ }
- nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
- while (nsect--)
- ide_pio_sector(drive, rq, write);
+ /* do the actual data transfer */
+ if (write)
+ hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
+ else
+ hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
+
+ kunmap_atomic(buf, KM_BIO_SRC_IRQ);
+
+ if (PageHighMem(page))
+ local_irq_restore(flags);
+
+ len -= nr_bytes;
+ }
}
+EXPORT_SYMBOL_GPL(ide_pio_bytes);
-static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
- unsigned int write)
+static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
+ unsigned int write)
{
- u8 saved_io_32bit = drive->io_32bit;
+ unsigned int nr_bytes;
- if (rq->bio) /* fs request */
- rq->errors = 0;
+ u8 saved_io_32bit = drive->io_32bit;
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- ide_task_t *task = rq->special;
+ if (cmd->tf_flags & IDE_TFLAG_FS)
+ cmd->rq->errors = 0;
- if (task->tf_flags & IDE_TFLAG_IO_16BIT)
- drive->io_32bit = 0;
- }
+ if (cmd->tf_flags & IDE_TFLAG_IO_16BIT)
+ drive->io_32bit = 0;
touch_softlockup_watchdog();
- switch (drive->hwif->data_phase) {
- case TASKFILE_MULTI_IN:
- case TASKFILE_MULTI_OUT:
- ide_pio_multi(drive, rq, write);
- break;
- default:
- ide_pio_sector(drive, rq, write);
- break;
- }
+ if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+ nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
+ else
+ nr_bytes = SECTOR_SIZE;
+
+ ide_pio_bytes(drive, cmd, write, nr_bytes);
drive->io_32bit = saved_io_32bit;
}
-static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
- const char *s, u8 stat)
+static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
- if (rq->bio) {
- ide_hwif_t *hwif = drive->hwif;
- int sectors = hwif->nsect - hwif->nleft;
-
- switch (hwif->data_phase) {
- case TASKFILE_IN:
- if (hwif->nleft)
- break;
- /* fall through */
- case TASKFILE_OUT:
- sectors--;
- break;
- case TASKFILE_MULTI_IN:
- if (hwif->nleft)
- break;
- /* fall through */
- case TASKFILE_MULTI_OUT:
- sectors -= drive->mult_count;
- default:
- break;
+ if (cmd->tf_flags & IDE_TFLAG_FS) {
+ int nr_bytes = cmd->nbytes - cmd->nleft;
+
+ if (cmd->protocol == ATA_PROT_PIO &&
+ ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) {
+ if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+ nr_bytes -= drive->mult_count << 9;
+ else
+ nr_bytes -= SECTOR_SIZE;
}
- if (sectors > 0) {
- struct ide_driver *drv;
-
- drv = *(struct ide_driver **)rq->rq_disk->private_data;
- drv->end_request(drive, 1, sectors);
- }
+ if (nr_bytes > 0)
+ ide_complete_rq(drive, 0, nr_bytes);
}
- return ide_error(drive, s, stat);
}
-void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
+void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
{
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- u8 err = ide_read_error(drive);
-
- ide_end_drive_cmd(drive, stat, err);
- return;
- }
-
- if (rq->rq_disk) {
- struct ide_driver *drv;
+ struct request *rq = drive->hwif->rq;
+ u8 err = ide_read_error(drive);
- drv = *(struct ide_driver **)rq->rq_disk->private_data;;
- drv->end_request(drive, 1, rq->nr_sectors);
- } else
- ide_end_request(drive, 1, rq->nr_sectors);
+ ide_complete_cmd(drive, cmd, stat, err);
+ rq->errors = err;
+ ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
}
/*
- * We got an interrupt on a task_in case, but no errors and no DRQ.
- *
- * It might be a spurious irq (shared irq), but it might be a
- * command that had no output.
+ * Handler for command with PIO data phase.
*/
-static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
-{
- /* Command all done? */
- if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) {
- task_end_request(drive, rq, stat);
- return ide_stopped;
- }
-
- /* Assume it was a spurious irq */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
- return ide_started;
-}
-
-/*
- * Handler for command with PIO data-in phase (Read/Read Multiple).
- */
-static ide_startstop_t task_in_intr(ide_drive_t *drive)
+static ide_startstop_t task_pio_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
+ struct ide_cmd *cmd = &drive->hwif->cmd;
u8 stat = hwif->tp_ops->read_status(hwif);
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- /* Error? */
- if (stat & ATA_ERR)
- return task_error(drive, rq, __func__, stat);
+ if (write == 0) {
+ /* Error? */
+ if (stat & ATA_ERR)
+ goto out_err;
- /* Didn't want any data? Odd. */
- if ((stat & ATA_DRQ) == 0)
- return task_in_unexpected(drive, rq, stat);
+ /* Didn't want any data? Odd. */
+ if ((stat & ATA_DRQ) == 0) {
+ /* Command all done? */
+ if (OK_STAT(stat, ATA_DRDY, ATA_BUSY))
+ goto out_end;
- ide_pio_datablock(drive, rq, 0);
+ /* Assume it was a spurious irq */
+ goto out_wait;
+ }
+ } else {
+ if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
+ goto out_err;
- /* Are we done? Check status and finish transfer. */
- if (!hwif->nleft) {
- stat = wait_drive_not_busy(drive);
- if (!OK_STAT(stat, 0, BAD_STAT))
- return task_error(drive, rq, __func__, stat);
- task_end_request(drive, rq, stat);
- return ide_stopped;
+ /* Deal with unexpected ATA data phase. */
+ if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0))
+ goto out_err;
}
- /* Still data left to transfer. */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
+ if (write && cmd->nleft == 0)
+ goto out_end;
- return ide_started;
-}
-
-/*
- * Handler for command with PIO data-out phase (Write/Write Multiple).
- */
-static ide_startstop_t task_out_intr (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- u8 stat = hwif->tp_ops->read_status(hwif);
-
- if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
- return task_error(drive, rq, __func__, stat);
+ /* Still data left to transfer. */
+ ide_pio_datablock(drive, cmd, write);
- /* Deal with unexpected ATA data phase. */
- if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft)
- return task_error(drive, rq, __func__, stat);
+ /* Are we done? Check status and finish transfer. */
+ if (write == 0 && cmd->nleft == 0) {
+ stat = wait_drive_not_busy(drive);
+ if (!OK_STAT(stat, 0, BAD_STAT))
+ goto out_err;
- if (!hwif->nleft) {
- task_end_request(drive, rq, stat);
- return ide_stopped;
+ goto out_end;
}
-
+out_wait:
/* Still data left to transfer. */
- ide_pio_datablock(drive, rq, 1);
- ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
-
+ ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
return ide_started;
+out_end:
+ if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+ ide_finish_cmd(drive, cmd, stat);
+ else
+ ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9);
+ return ide_stopped;
+out_err:
+ ide_error_cmd(drive, cmd);
+ return ide_error(drive, __func__, stat);
}
-static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
+static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
+ struct ide_cmd *cmd)
{
ide_startstop_t startstop;
if (ide_wait_stat(&startstop, drive, ATA_DRQ,
drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
- drive->name, drive->hwif->data_phase ? "MULT" : "",
+ drive->name,
+ (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
return startstop;
}
@@ -432,13 +375,15 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
local_irq_disable();
- ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
- ide_pio_datablock(drive, rq, 1);
+ ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
+
+ ide_pio_datablock(drive, cmd, 1);
return ide_started;
}
-int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
+int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
+ u16 nsect)
{
struct request *rq;
int error;
@@ -456,11 +401,11 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
rq->hard_nr_sectors = rq->nr_sectors = nsect;
rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
- if (task->tf_flags & IDE_TFLAG_WRITE)
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
rq->cmd_flags |= REQ_RW;
- rq->special = task;
- task->rq = rq;
+ rq->special = cmd;
+ cmd->rq = rq;
error = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
@@ -470,19 +415,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
EXPORT_SYMBOL(ide_raw_taskfile);
-int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
+int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
{
- task->data_phase = TASKFILE_NO_DATA;
+ cmd->protocol = ATA_PROT_NODATA;
- return ide_raw_taskfile(drive, task, NULL, 0);
+ return ide_raw_taskfile(drive, cmd, NULL, 0);
}
EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
#ifdef CONFIG_IDE_TASK_IOCTL
-int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
{
ide_task_request_t *req_task;
- ide_task_t args;
+ struct ide_cmd cmd;
u8 *outbuf = NULL;
u8 *inbuf = NULL;
u8 *data_buf = NULL;
@@ -536,53 +481,63 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
}
}
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
- memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(&cmd.tf_array[0], req_task->hob_ports,
+ HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(&cmd.tf_array[6], req_task->io_ports,
+ HDIO_DRIVE_TASK_HDR_SIZE);
- args.data_phase = req_task->data_phase;
+ cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
+ IDE_TFLAG_IN_TF;
- args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
- IDE_TFLAG_IN_TF;
if (drive->dev_flags & IDE_DFLAG_LBA48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
if (req_task->out_flags.all) {
- args.tf_flags |= IDE_TFLAG_FLAGGED;
+ cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
if (req_task->out_flags.b.data)
- args.tf_flags |= IDE_TFLAG_OUT_DATA;
+ cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
if (req_task->out_flags.b.nsector_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
if (req_task->out_flags.b.sector_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
if (req_task->out_flags.b.lcyl_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
if (req_task->out_flags.b.hcyl_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
if (req_task->out_flags.b.error_feature)
- args.tf_flags |= IDE_TFLAG_OUT_FEATURE;
+ cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE;
if (req_task->out_flags.b.nsector)
- args.tf_flags |= IDE_TFLAG_OUT_NSECT;
+ cmd.tf_flags |= IDE_TFLAG_OUT_NSECT;
if (req_task->out_flags.b.sector)
- args.tf_flags |= IDE_TFLAG_OUT_LBAL;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAL;
if (req_task->out_flags.b.lcyl)
- args.tf_flags |= IDE_TFLAG_OUT_LBAM;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAM;
if (req_task->out_flags.b.hcyl)
- args.tf_flags |= IDE_TFLAG_OUT_LBAH;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAH;
} else {
- args.tf_flags |= IDE_TFLAG_OUT_TF;
- if (args.tf_flags & IDE_TFLAG_LBA48)
- args.tf_flags |= IDE_TFLAG_OUT_HOB;
+ cmd.tf_flags |= IDE_TFLAG_OUT_TF;
+ if (cmd.tf_flags & IDE_TFLAG_LBA48)
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB;
}
if (req_task->in_flags.b.data)
- args.tf_flags |= IDE_TFLAG_IN_DATA;
+ cmd.ftf_flags |= IDE_FTFLAG_IN_DATA;
+
+ if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) {
+ /* fixup data phase if needed */
+ if (req_task->data_phase == TASKFILE_IN_DMAQ ||
+ req_task->data_phase == TASKFILE_IN_DMA)
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+ }
- switch(req_task->data_phase) {
+ cmd.protocol = ATA_PROT_DMA;
+
+ switch (req_task->data_phase) {
case TASKFILE_MULTI_OUT:
if (!drive->mult_count) {
/* (hs): give up if multcount is not set */
@@ -592,11 +547,14 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
err = -EPERM;
goto abort;
}
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_OUT:
+ cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_OUT_DMAQ:
case TASKFILE_OUT_DMA:
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
nsect = taskout / SECTOR_SIZE;
data_buf = outbuf;
break;
@@ -609,8 +567,10 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
err = -EPERM;
goto abort;
}
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_IN:
+ cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA:
@@ -618,6 +578,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
data_buf = inbuf;
break;
case TASKFILE_NO_DATA:
+ cmd.protocol = ATA_PROT_NODATA;
break;
default:
err = -EFAULT;
@@ -627,7 +588,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
nsect = 0;
else if (!nsect) {
- nsect = (args.tf.hob_nsect << 8) | args.tf.nsect;
+ nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect;
if (!nsect) {
printk(KERN_ERR "%s: in/out command without data\n",
@@ -637,15 +598,14 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
}
}
- if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE)
- args.tf_flags |= IDE_TFLAG_WRITE;
-
- err = ide_raw_taskfile(drive, &args, data_buf, nsect);
+ err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
- memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(req_task->hob_ports, &cmd.tf_array[0],
+ HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(req_task->io_ports, &cmd.tf_array[6],
+ HDIO_DRIVE_TASK_HDR_SIZE);
- if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) &&
+ if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
req_task->in_flags.all == 0) {
req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->dev_flags & IDE_DFLAG_LBA48)
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c
new file mode 100644
index 000000000000..6910f6a257e8
--- /dev/null
+++ b/drivers/ide/ide-xfer-mode.c
@@ -0,0 +1,246 @@
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/ide.h>
+#include <linux/bitops.h>
+
+static const char *udma_str[] =
+ { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
+ "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
+static const char *mwdma_str[] =
+ { "MWDMA0", "MWDMA1", "MWDMA2" };
+static const char *swdma_str[] =
+ { "SWDMA0", "SWDMA1", "SWDMA2" };
+static const char *pio_str[] =
+ { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
+
+/**
+ * ide_xfer_verbose - return IDE mode names
+ * @mode: transfer mode
+ *
+ * Returns a constant string giving the name of the mode
+ * requested.
+ */
+
+const char *ide_xfer_verbose(u8 mode)
+{
+ const char *s;
+ u8 i = mode & 0xf;
+
+ if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
+ s = udma_str[i];
+ else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
+ s = mwdma_str[i];
+ else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
+ s = swdma_str[i];
+ else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
+ s = pio_str[i & 0x7];
+ else if (mode == XFER_PIO_SLOW)
+ s = "PIO SLOW";
+ else
+ s = "XFER ERROR";
+
+ return s;
+}
+EXPORT_SYMBOL(ide_xfer_verbose);
+
+/**
+ * ide_get_best_pio_mode - get PIO mode from drive
+ * @drive: drive to consider
+ * @mode_wanted: preferred mode
+ * @max_mode: highest allowed mode
+ *
+ * This routine returns the recommended PIO settings for a given drive,
+ * based on the drive->id information and the ide_pio_blacklist[].
+ *
+ * Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
+ * This is used by most chipset support modules when "auto-tuning".
+ */
+
+u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
+{
+ u16 *id = drive->id;
+ int pio_mode = -1, overridden = 0;
+
+ if (mode_wanted != 255)
+ return min_t(u8, mode_wanted, max_mode);
+
+ if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
+ pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
+
+ if (pio_mode != -1) {
+ printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
+ } else {
+ pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
+ if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
+ pio_mode = 2;
+ overridden = 1;
+ }
+
+ if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
+ if (ata_id_has_iordy(id)) {
+ if (id[ATA_ID_PIO_MODES] & 7) {
+ overridden = 0;
+ if (id[ATA_ID_PIO_MODES] & 4)
+ pio_mode = 5;
+ else if (id[ATA_ID_PIO_MODES] & 2)
+ pio_mode = 4;
+ else
+ pio_mode = 3;
+ }
+ }
+ }
+
+ if (overridden)
+ printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
+ drive->name);
+ }
+
+ if (pio_mode > max_mode)
+ pio_mode = max_mode;
+
+ return pio_mode;
+}
+EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
+
+int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+ return 0;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL)
+ return -1;
+
+ /*
+ * TODO: temporary hack for some legacy host drivers that didn't
+ * set transfer mode on the device in ->set_pio_mode method...
+ */
+ if (port_ops->set_dma_mode == NULL) {
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ }
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ } else {
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+
+int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+ return 0;
+
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL)
+ return -1;
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ port_ops->set_dma_mode(drive, mode);
+ return 0;
+ } else {
+ port_ops->set_dma_mode(drive, mode);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_set_dma_mode);
+
+/* req_pio == "255" for auto-tune */
+void ide_set_pio(ide_drive_t *drive, u8 req_pio)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+ u8 host_pio, pio;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return;
+
+ BUG_ON(hwif->pio_mask == 0x00);
+
+ host_pio = fls(hwif->pio_mask) - 1;
+
+ pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
+
+ /*
+ * TODO:
+ * - report device max PIO mode
+ * - check req_pio != 255 against device max PIO mode
+ */
+ printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
+ drive->name, host_pio, req_pio,
+ req_pio == 255 ? "(auto-tune)" : "", pio);
+
+ (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
+}
+EXPORT_SYMBOL_GPL(ide_set_pio);
+
+/**
+ * ide_rate_filter - filter transfer mode
+ * @drive: IDE device
+ * @speed: desired speed
+ *
+ * Given the available transfer modes this function returns
+ * the best available speed at or below the speed requested.
+ *
+ * TODO: check device PIO capabilities
+ */
+
+static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 mode = ide_find_dma_mode(drive, speed);
+
+ if (mode == 0) {
+ if (hwif->pio_mask)
+ mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
+ else
+ mode = XFER_PIO_4;
+ }
+
+/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
+
+ return min(speed, mode);
+}
+
+/**
+ * ide_set_xfer_rate - set transfer rate
+ * @drive: drive to set
+ * @rate: speed to attempt to set
+ *
+ * General helper for setting the speed of an IDE device. This
+ * function knows about user enforced limits from the configuration
+ * which ->set_pio_mode/->set_dma_mode does not.
+ */
+
+int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return -1;
+
+ rate = ide_rate_filter(drive, rate);
+
+ BUG_ON(rate < XFER_PIO_0);
+
+ if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
+ return ide_set_pio_mode(drive, rate);
+
+ return ide_set_dma_mode(drive, rate);
+}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 258805da15c3..92c9b90931e7 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -62,160 +62,6 @@
struct class *ide_port_class;
-/*
- * Locks for IDE setting functionality
- */
-
-DEFINE_MUTEX(ide_setting_mtx);
-
-ide_devset_get(io_32bit, io_32bit);
-
-static int set_io_32bit(ide_drive_t *drive, int arg)
-{
- if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
- return -EPERM;
-
- if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
- return -EINVAL;
-
- drive->io_32bit = arg;
-
- return 0;
-}
-
-ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
-
-static int set_ksettings(ide_drive_t *drive, int arg)
-{
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (arg)
- drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
- else
- drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
-
- return 0;
-}
-
-ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
-
-static int set_using_dma(ide_drive_t *drive, int arg)
-{
-#ifdef CONFIG_BLK_DEV_IDEDMA
- int err = -EPERM;
-
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (ata_id_has_dma(drive->id) == 0)
- goto out;
-
- if (drive->hwif->dma_ops == NULL)
- goto out;
-
- err = 0;
-
- if (arg) {
- if (ide_set_dma(drive))
- err = -EIO;
- } else
- ide_dma_off(drive);
-
-out:
- return err;
-#else
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- return -EPERM;
-#endif
-}
-
-/*
- * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
- */
-static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
-{
- switch (req_pio) {
- case 202:
- case 201:
- case 200:
- case 102:
- case 101:
- case 100:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
- case 9:
- case 8:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
- case 7:
- case 6:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
- default:
- return 0;
- }
-}
-
-static int set_pio_mode(ide_drive_t *drive, int arg)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (arg < 0 || arg > 255)
- return -EINVAL;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return -ENOSYS;
-
- if (set_pio_mode_abuse(drive->hwif, arg)) {
- if (arg == 8 || arg == 9) {
- unsigned long flags;
-
- /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
- spin_lock_irqsave(&hwif->lock, flags);
- port_ops->set_pio_mode(drive, arg);
- spin_unlock_irqrestore(&hwif->lock, flags);
- } else
- port_ops->set_pio_mode(drive, arg);
- } else {
- int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
-
- ide_set_pio(drive, arg);
-
- if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
- if (keep_dma)
- ide_dma_on(drive);
- }
- }
-
- return 0;
-}
-
-ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
-
-static int set_unmaskirq(ide_drive_t *drive, int arg)
-{
- if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
- return -EPERM;
-
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (arg)
- drive->dev_flags |= IDE_DFLAG_UNMASK;
- else
- drive->dev_flags &= ~IDE_DFLAG_UNMASK;
-
- return 0;
-}
-
-ide_ext_devset_rw_sync(io_32bit, io_32bit);
-ide_ext_devset_rw_sync(keepsettings, ksettings);
-ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
-ide_ext_devset_rw_sync(using_dma, using_dma);
-__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
-
/**
* ide_device_get - get an additional reference to a ide_drive_t
* @drive: device to get a reference to
@@ -337,6 +183,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
int a, b, i, j = 1;
unsigned int *dev_param_mask = (unsigned int *)kp->arg;
+ /* controller . device (0 or 1) [ : 1 (set) | 0 (clear) ] */
if (sscanf(s, "%d.%d:%d", &a, &b, &j) != 3 &&
sscanf(s, "%d.%d", &a, &b) != 2)
return -EINVAL;
@@ -349,7 +196,7 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
if (j)
*dev_param_mask |= (1 << i);
else
- *dev_param_mask &= (1 << i);
+ *dev_param_mask &= ~(1 << i);
return 0;
}
@@ -392,6 +239,8 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
{
int a, b, c = 0, h = 0, s = 0, i, j = 1;
+ /* controller . device (0 or 1) : Cylinders , Heads , Sectors */
+ /* controller . device (0 or 1) : 1 (use CHS) | 0 (ignore CHS) */
if (sscanf(str, "%d.%d:%d,%d,%d", &a, &b, &c, &h, &s) != 5 &&
sscanf(str, "%d.%d:%d", &a, &b, &j) != 3)
return -EINVAL;
@@ -407,7 +256,7 @@ static int ide_set_disk_chs(const char *str, struct kernel_param *kp)
if (j)
ide_disks |= (1 << i);
else
- ide_disks &= (1 << i);
+ ide_disks &= ~(1 << i);
ide_disks_chs[i].cyl = c;
ide_disks_chs[i].head = h;
@@ -469,6 +318,8 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
{
int i, j = 1;
+ /* controller (ignore) */
+ /* controller : 1 (ignore) | 0 (use) */
if (sscanf(s, "%d:%d", &i, &j) != 2 && sscanf(s, "%d", &i) != 1)
return -EINVAL;
@@ -478,7 +329,7 @@ static int ide_set_ignore_cable(const char *s, struct kernel_param *kp)
if (j)
ide_ignore_cable |= (1 << i);
else
- ide_ignore_cable &= (1 << i);
+ ide_ignore_cable &= ~(1 << i);
return 0;
}
@@ -522,6 +373,8 @@ static int __init ide_init(void)
goto out_port_class;
}
+ ide_acpi_init();
+
proc_ide_create();
return 0;
diff --git a/drivers/ide/ide_arm.c b/drivers/ide/ide_arm.c
deleted file mode 100644
index bdcac94d7c1f..000000000000
--- a/drivers/ide/ide_arm.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ARM default IDE host driver
- *
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
- * Based on code by: Russell King, Ian Molton and Alexander Schulz.
- *
- * May be copied or modified under the terms of the GNU General Public License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#include <asm/irq.h>
-
-#define DRV_NAME "ide_arm"
-
-#define IDE_ARM_IO 0x1f0
-#define IDE_ARM_IRQ IRQ_HARDDISK
-
-static int __init ide_arm_init(void)
-{
- unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (!request_region(base, 8, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
- DRV_NAME, base, base + 7);
- return -EBUSY;
- }
-
- if (!request_region(ctl, 1, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
- DRV_NAME, ctl);
- release_region(base, 8);
- return -EBUSY;
- }
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = IDE_ARM_IRQ;
- hw.chipset = ide_generic;
-
- return ide_host_add(NULL, hws, NULL);
-}
-
-module_init(ide_arm_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index e1c4f5437396..51aa745246dc 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -5,9 +5,8 @@
* May be copied or modified under the terms of the GNU General Public License
* Based in part on the ITE vendor provided SCSI driver.
*
- * Documentation available from
- * http://www.ite.com.tw/pc/IT8212F_V04.pdf
- * Some other documents are NDA.
+ * Documentation:
+ * Datasheet is freely available, some other documents under NDA.
*
* The ITE8212 isn't exactly a standard IDE controller. It has two
* modes. In pass through mode then it is an IDE controller. In its smart
@@ -509,12 +508,11 @@ static void it821x_quirkproc(ide_drive_t *drive)
static struct ide_dma_ops it821x_pass_through_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = it821x_dma_start,
.dma_end = it821x_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -604,7 +602,7 @@ static void it8212_disable_raid(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
}
-static unsigned int init_chipset_it821x(struct pci_dev *dev)
+static int init_chipset_it821x(struct pci_dev *dev)
{
u8 conf;
static char *mode[2] = { "pass through", "smart" };
diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c
index 3c60064f1d4f..4b1718e83283 100644
--- a/drivers/ide/macide.c
+++ b/drivers/ide/macide.c
@@ -80,6 +80,11 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
+static const struct ide_port_info macide_port_info = {
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
+};
+
static const char *mac_ide_name[] =
{ "Quadra", "Powerbook", "Powerbook Baboon" };
@@ -122,7 +127,7 @@ static int __init macide_init(void)
macide_setup_ports(&hw, base, irq, ack_intr);
- return ide_host_add(NULL, hws, NULL);
+ return ide_host_add(&macide_port_info, hws, NULL);
}
module_init(macide_init);
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 83643ed9a426..cbc1d1110385 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -61,12 +61,12 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif)
return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
}
-static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_taskfile *tf = &cmd->tf;
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data = inw(io_ports->data_addr);
tf->data = data & 0xff;
@@ -76,31 +76,31 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
/* be sure we're looking at the low order bits */
outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = superio_ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
@@ -196,12 +196,17 @@ static void ns87415_selectproc (ide_drive_t *drive)
!!(drive->dev_flags & IDE_DFLAG_USING_DMA));
}
+static void ns87415_dma_start(ide_drive_t *drive)
+{
+ ns87415_prepare_drive(drive, 1);
+ ide_dma_start(drive);
+}
+
static int ns87415_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
/* get DMA command mode */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
@@ -210,21 +215,11 @@ static int ns87415_dma_end(ide_drive_t *drive)
/* from ERRATA: clear the INTR & ERROR bits */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
- return (dma_stat & 7) != 4;
-}
-static int ns87415_dma_setup(ide_drive_t *drive)
-{
- /* select DMA xfer */
- ns87415_prepare_drive(drive, 1);
- if (!ide_dma_setup(drive))
- return 0;
- /* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
- return 1;
+
+ /* verify good DMA status */
+ return (dma_stat & 7) != 4;
}
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
@@ -286,9 +281,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
}
if (!using_inta)
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- else if (!hwif->irq && hwif->mate && hwif->mate->irq)
- hwif->irq = hwif->mate->irq; /* share IRQ with mate */
+ hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
if (!hwif->dma_base)
return;
@@ -302,13 +295,12 @@ static const struct ide_port_ops ns87415_port_ops = {
static const struct ide_dma_ops ns87415_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ns87415_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
- .dma_start = ide_dma_start,
+ .dma_setup = ide_dma_setup,
+ .dma_start = ns87415_dma_start,
.dma_end = ns87415_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = superio_dma_sff_read_status,
};
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index a7ac490c9ae3..c7acca0b8733 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -346,7 +346,8 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
{
struct clk *clk;
struct resource *mem, *irq;
- unsigned long base, rate;
+ void __iomem *base;
+ unsigned long rate, mem_size;
int i, rc;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
@@ -373,20 +374,27 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
return -ENODEV;
}
- if (request_mem_region(mem->start, mem->end - mem->start + 1,
- "palm_bk3710") == NULL) {
+ mem_size = mem->end - mem->start + 1;
+ if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) {
printk(KERN_ERR "failed to request memory region\n");
return -EBUSY;
}
- base = IO_ADDRESS(mem->start);
+ base = ioremap(mem->start, mem_size);
+ if (!base) {
+ printk(KERN_ERR "failed to map IO memory\n");
+ release_mem_region(mem->start, mem_size);
+ return -ENOMEM;
+ }
/* Configure the Palm Chip controller */
- palm_bk3710_chipinit((void __iomem *)base);
+ palm_bk3710_chipinit(base);
for (i = 0; i < IDE_NR_PORTS - 2; i++)
- hw.io_ports_array[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i;
- hw.io_ports.ctl_addr = base + IDE_PALM_ATA_PRI_CTL_OFFSET;
+ hw.io_ports_array[i] = (unsigned long)
+ (base + IDE_PALM_ATA_PRI_REG_OFFSET + i);
+ hw.io_ports.ctl_addr = (unsigned long)
+ (base + IDE_PALM_ATA_PRI_CTL_OFFSET);
hw.irq = irq->start;
hw.dev = &pdev->dev;
hw.chipset = ide_palm3710;
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c
index f21290c4b447..b68906c3c17e 100644
--- a/drivers/ide/pdc202xx_new.c
+++ b/drivers/ide/pdc202xx_new.c
@@ -325,7 +325,7 @@ static void apple_kiwi_init(struct pci_dev *pdev)
}
#endif /* CONFIG_PPC_PMAC */
-static unsigned int init_chipset_pdcnew(struct pci_dev *dev)
+static int init_chipset_pdcnew(struct pci_dev *dev)
{
const char *name = DRV_NAME;
unsigned long dma_base = pci_resource_start(dev, 4);
@@ -444,7 +444,7 @@ static unsigned int init_chipset_pdcnew(struct pci_dev *dev)
#endif
out:
- return dev->irq;
+ return 0;
}
static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index 97193323aebf..248a54bd2386 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -258,13 +258,7 @@ static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
ide_dma_lost_irq(drive);
}
-static void pdc202xx_dma_timeout(ide_drive_t *drive)
-{
- pdc202xx_reset(drive);
- ide_dma_timeout(drive);
-}
-
-static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
+static int init_chipset_pdc202xx(struct pci_dev *dev)
{
unsigned long dmabase = pci_resource_start(dev, 4);
u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
@@ -290,7 +284,7 @@ static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
}
out:
- return dev->irq;
+ return 0;
}
static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
@@ -331,24 +325,24 @@ static const struct ide_port_ops pdc2026x_port_ops = {
static const struct ide_dma_ops pdc20246_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops pdc2026x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = pdc202xx_dma_start,
.dma_end = pdc202xx_dma_end,
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index f1e2e4ef0d71..2aa699933064 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -204,7 +204,7 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
* out to be nice and simple.
*/
-static unsigned int init_chipset_ich(struct pci_dev *dev)
+static int init_chipset_ich(struct pci_dev *dev)
{
u32 extra = 0;
@@ -318,19 +318,12 @@ static const struct ide_port_ops ich_port_ops = {
.cable_detect = piix_cable_detect,
};
-#ifndef CONFIG_IA64
- #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
-#else
- #define IDE_HFLAGS_PIIX 0
-#endif
-
#define DECLARE_PIIX_DEV(udma) \
{ \
.name = DRV_NAME, \
.init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
.port_ops = &piix_port_ops, \
- .host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
.mwdma_mask = ATA_MWDMA12_ONLY, \
@@ -344,7 +337,6 @@ static const struct ide_port_ops ich_port_ops = {
.init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
.port_ops = &ich_port_ops, \
- .host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
.mwdma_mask = ATA_MWDMA12_ONLY, \
@@ -360,8 +352,7 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {
*/
.name = DRV_NAME,
.enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
- .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA |
- IDE_HFLAGS_PIIX,
+ .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
/* This is a painful system best to let it self tune for now */
},
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 74625e821a43..e6119916cd0c 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -404,7 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
#define IDE_WAKEUP_DELAY (1*HZ)
static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
-static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
static void pmac_ide_selectproc(ide_drive_t *drive);
static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
@@ -1422,17 +1421,16 @@ out:
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
-static int
-pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct dbdma_cmd *table;
- int i, count = 0;
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
struct scatterlist *sg;
- int wr = (rq_data_dir(rq) == WRITE);
+ int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
+ int i = cmd->sg_nents, count = 0;
/* DMA table is already aligned */
table = (struct dbdma_cmd *) pmif->dma_table_cpu;
@@ -1442,11 +1440,6 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
while (readl(&dma->status) & RUN)
udelay(1);
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
/* Build DBDMA commands list */
sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
@@ -1500,8 +1493,6 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
@@ -1509,39 +1500,27 @@ use_pio_instead:
* Prepare a DMA transfer. We build the DMA table, adjust the timings for
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/
-static int
-pmac_ide_dma_setup(ide_drive_t *drive)
+static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
- struct request *rq = hwif->rq;
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (!pmac_ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (pmac_ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
- writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
+ writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
PMAC_IDE_REG(IDE_TIMING_CONFIG));
(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
- drive->waiting_for_dma = 1;
-
return 0;
}
-static void
-pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-}
-
/*
* Kick the DMA controller into life after the DMA command has been issued
* to the drive.
@@ -1573,12 +1552,9 @@ pmac_ide_dma_end (ide_drive_t *drive)
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
u32 dstat;
- drive->waiting_for_dma = 0;
dstat = readl(&dma->status);
writel(((RUN|WAKE|DEAD) << 16), &dma->control);
- ide_destroy_dmatable(drive);
-
/* verify good dma status. we don't check for ACTIVE beeing 0. We should...
* in theory, but with ATAPI decices doing buffer underruns, that would
* cause us to disable DMA, which isn't what we want
@@ -1662,11 +1638,9 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive)
static const struct ide_dma_ops pmac_dma_ops = {
.dma_host_set = pmac_ide_dma_host_set,
.dma_setup = pmac_ide_dma_setup,
- .dma_exec_cmd = pmac_ide_dma_exec_cmd,
.dma_start = pmac_ide_dma_start,
.dma_end = pmac_ide_dma_end,
.dma_test_irq = pmac_ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = pmac_ide_dma_lost_irq,
};
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index 9f9c0b3cc3a3..2a43a2f49633 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -72,26 +72,26 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
-static void q40ide_input_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return insw(data_addr, buf, (len + 1) / 2);
- insw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
-static void q40ide_output_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return outsw(data_addr, buf, (len + 1) / 2);
- outsw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
/* Q40 has a byte-swapped IDE interface */
@@ -111,7 +111,8 @@ static const struct ide_tp_ops q40ide_tp_ops = {
static const struct ide_port_info q40ide_port_info = {
.tp_ops = &q40ide_tp_ops,
- .host_flags = IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
/*
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index 5b2e3af43c4b..08c4fa35e9b1 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -16,7 +16,7 @@
/*
* Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
*/
#include <linux/module.h>
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h
index 6636f9665d16..d7e67a1a1dcc 100644
--- a/drivers/ide/qd65xx.h
+++ b/drivers/ide/qd65xx.h
@@ -4,7 +4,7 @@
/*
* Authors: Petr Soucek <petr@ryston.cz>
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
*/
/* truncates a in [b,c] */
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index dbdd2985a0d8..13e3988f00f0 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -183,9 +183,6 @@ static int sc1200_dma_end(ide_drive_t *drive)
outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */
outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive); /* purge DMA mappings */
-
return (dma_stat & 7) != 4; /* verify good DMA status */
}
@@ -286,12 +283,11 @@ static const struct ide_port_ops sc1200_port_ops = {
static const struct ide_dma_ops sc1200_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = sc1200_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 8d2314b6327c..542419ffa9b7 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -303,8 +303,9 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
}
/**
- * scc_ide_dma_setup - begin a DMA phase
+ * scc_dma_setup - begin a DMA phase
* @drive: target device
+ * @cmd: command
*
* Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers.
@@ -313,36 +314,28 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
* is returned.
*/
-static int scc_dma_setup(ide_drive_t *drive)
+static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int reading;
+ u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
u8 dma_stat;
- if (rq_data_dir(rq))
- reading = 0;
- else
- reading = 1 << 3;
-
/* fall back to pio! */
- if (!ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
/* specify r/w */
- out_be32((void __iomem *)hwif->dma_base, reading);
+ out_be32((void __iomem *)hwif->dma_base, rw);
/* read DMA status for INTR & ERROR flags */
dma_stat = scc_dma_sff_read_status(hwif);
/* clear INTR & ERROR flags */
out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
- drive->waiting_for_dma = 1;
+
return 0;
}
@@ -361,7 +354,6 @@ static int __scc_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat, dma_cmd;
- drive->waiting_for_dma = 0;
/* get DMA command mode */
dma_cmd = scc_ide_inb(hwif->dma_base);
/* stop DMA */
@@ -370,8 +362,6 @@ static int __scc_dma_end(ide_drive_t *drive)
dma_stat = scc_dma_sff_read_status(hwif);
/* clear the INTR & ERROR bits */
scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
wmb();
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
@@ -666,52 +656,52 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
return rc;
}
-static void scc_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA)
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA)
out_be32((void *)io_ports->data_addr,
(tf->hob_data << 8) | tf->data);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
scc_ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
scc_ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
scc_ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
scc_ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
scc_ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
scc_ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_taskfile *tf = &cmd->tf;
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data = (u16)in_be32((void *)io_ports->data_addr);
tf->data = data & 0xff;
@@ -721,36 +711,36 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
/* be sure we're looking at the low order bits */
scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = scc_ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = scc_ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = scc_ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = scc_ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = scc_ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
}
}
-static void scc_input_data(ide_drive_t *drive, struct request *rq,
+static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -766,7 +756,7 @@ static void scc_input_data(ide_drive_t *drive, struct request *rq,
scc_ide_insw(data_addr, buf, len / 2);
}
-static void scc_output_data(ide_drive_t *drive, struct request *rq,
+static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -873,30 +863,25 @@ static const struct ide_port_ops scc_port_ops = {
static const struct ide_dma_ops scc_dma_ops = {
.dma_host_set = scc_dma_host_set,
.dma_setup = scc_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = scc_dma_start,
.dma_end = scc_dma_end,
.dma_test_irq = scc_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = scc_dma_sff_read_status,
};
-#define DECLARE_SCC_DEV(name_str) \
- { \
- .name = name_str, \
- .init_iops = init_iops_scc, \
- .init_dma = scc_init_dma, \
- .init_hwif = init_hwif_scc, \
- .tp_ops = &scc_tp_ops, \
- .port_ops = &scc_port_ops, \
- .dma_ops = &scc_dma_ops, \
- .host_flags = IDE_HFLAG_SINGLE, \
- .pio_mask = ATA_PIO4, \
- }
-
-static const struct ide_port_info scc_chipsets[] __devinitdata = {
- /* 0 */ DECLARE_SCC_DEV("sccIDE"),
+static const struct ide_port_info scc_chipset __devinitdata = {
+ .name = "sccIDE",
+ .init_iops = init_iops_scc,
+ .init_dma = scc_init_dma,
+ .init_hwif = init_hwif_scc,
+ .tp_ops = &scc_tp_ops,
+ .port_ops = &scc_port_ops,
+ .dma_ops = &scc_dma_ops,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .irq_flags = IRQF_SHARED,
+ .pio_mask = ATA_PIO4,
};
/**
@@ -910,7 +895,7 @@ static const struct ide_port_info scc_chipsets[] __devinitdata = {
static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return init_setup_scc(dev, &scc_chipsets[id->driver_data]);
+ return init_setup_scc(dev, &scc_chipset);
}
/**
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index 382102ba467b..b6554ef92716 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -175,7 +175,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, ultra_enable);
}
-static unsigned int init_chipset_svwks(struct pci_dev *dev)
+static int init_chipset_svwks(struct pci_dev *dev)
{
unsigned int reg;
u8 btr;
@@ -270,7 +270,7 @@ static unsigned int init_chipset_svwks(struct pci_dev *dev)
pci_write_config_byte(dev, 0x5A, btr);
}
- return dev->irq;
+ return 0;
}
static u8 ata66_svwks_svwks(ide_hwif_t *hwif)
@@ -353,14 +353,11 @@ static const struct ide_port_ops svwks_port_ops = {
.cable_detect = svwks_cable_detect,
};
-#define IDE_HFLAGS_SVWKS IDE_HFLAG_LEGACY_IRQS
-
static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
{ /* 0: OSB4 */
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &osb4_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* UDMA is problematic on OSB4 */
@@ -369,7 +366,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -378,7 +374,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -387,7 +382,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -396,7 +391,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index e85d1ed29c2a..a19dbccd7617 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -305,7 +305,6 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
* @dev: PCI device holding interface
* @d: IDE port info
* @port: port number
- * @irq: PCI IRQ
* @hw: hw_regs_t instance corresponding to this port
*
* Perform the initial set up for the hardware interface structure. This
@@ -316,7 +315,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
*/
static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
- unsigned int port, int irq, hw_regs_t *hw)
+ unsigned int port, hw_regs_t *hw)
{
unsigned long ctl = 0, base = 0;
@@ -344,7 +343,6 @@ static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
}
memset(hw, 0, sizeof(*hw));
- hw->irq = irq;
hw->dev = &dev->dev;
hw->chipset = d->chipset ? d->chipset : ide_pci;
ide_std_init_ports(hw, base, ctl | 2);
@@ -448,7 +446,6 @@ out:
* ide_pci_setup_ports - configure ports/devices on PCI IDE
* @dev: PCI device
* @d: IDE port info
- * @pciirq: IRQ line
* @hw: hw_regs_t instances corresponding to this PCI IDE device
* @hws: hw_regs_t pointers table to update
*
@@ -462,7 +459,7 @@ out:
*/
void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
- int pciirq, hw_regs_t *hw, hw_regs_t **hws)
+ hw_regs_t *hw, hw_regs_t **hws)
{
int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
u8 tmp;
@@ -481,7 +478,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
continue; /* port not enabled */
}
- if (ide_hw_configure(dev, d, port, pciirq, hw + port))
+ if (ide_hw_configure(dev, d, port, hw + port))
continue;
*(hws + port) = hw + port;
@@ -524,7 +521,7 @@ static int do_ide_setup_pci_device(struct pci_dev *dev,
if (noisy)
printk(KERN_INFO "%s %s: not 100%% native mode: will "
"probe irqs later\n", d->name, pci_name(dev));
- pciirq = ret;
+ pciirq = 0;
} else if (!pciirq && noisy) {
printk(KERN_WARNING "%s %s: bad irq (%d): will probe later\n",
d->name, pci_name(dev), pciirq);
@@ -549,7 +546,7 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
if (ret < 0)
goto out;
- ide_pci_setup_ports(dev, d, 0, &hw[0], &hws[0]);
+ ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
host = ide_host_alloc(d, hws);
if (host == NULL) {
@@ -561,6 +558,8 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
host->host_priv = priv;
+ host->irq_flags = IRQF_SHARED;
+
pci_set_drvdata(dev, host);
ret = do_ide_setup_pci_device(dev, d, 1);
@@ -568,7 +567,11 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
goto out;
/* fixup IRQ */
- hw[1].irq = hw[0].irq = ret;
+ if (ide_pci_is_in_compatibility_mode(dev)) {
+ hw[0].irq = pci_get_legacy_ide_irq(dev, 0);
+ hw[1].irq = pci_get_legacy_ide_irq(dev, 1);
+ } else
+ hw[1].irq = hw[0].irq = ret;
ret = ide_host_register(host, d, hws);
if (ret)
@@ -591,7 +594,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
if (ret < 0)
goto out;
- ide_pci_setup_ports(pdev[i], d, 0, &hw[i*2], &hws[i*2]);
+ ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]);
}
host = ide_host_alloc(d, hws);
@@ -605,6 +608,8 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
host->host_priv = priv;
+ host->irq_flags = IRQF_SHARED;
+
pci_set_drvdata(pdev[0], host);
pci_set_drvdata(pdev[1], host);
@@ -619,7 +624,11 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
goto out;
/* fixup IRQ */
- hw[i*2 + 1].irq = hw[i*2].irq = ret;
+ if (ide_pci_is_in_compatibility_mode(pdev[i])) {
+ hw[i*2].irq = pci_get_legacy_ide_irq(pdev[i], 0);
+ hw[i*2 + 1].irq = pci_get_legacy_ide_irq(pdev[i], 1);
+ } else
+ hw[i*2 + 1].irq = hw[i*2].irq = ret;
}
ret = ide_host_register(host, d, hws);
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index fdb9d7037694..6884a153e15a 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -258,9 +258,6 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
}
}
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive);
-
return dma_stat;
}
@@ -280,10 +277,12 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
sgiioc4_clearirq(drive);
}
-static void
-sgiioc4_resetproc(ide_drive_t * drive)
+static void sgiioc4_resetproc(ide_drive_t *drive)
{
+ struct ide_cmd *cmd = &drive->hwif->cmd;
+
sgiioc4_dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
sgiioc4_clearirq(drive);
}
@@ -412,7 +411,6 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
- drive->waiting_for_dma = 1;
}
/* IOC4 Scatter Gather list Format */
@@ -424,20 +422,13 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */
/* --------------------------------------------------------------------- */
/* Creates the scatter gather list, DMA Table */
-static unsigned int
-sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
+static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
unsigned int *table = hwif->dmatable_cpu;
- unsigned int count = 0, i = 1;
- struct scatterlist *sg;
-
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0; /* sglist of length Zero */
+ unsigned int count = 0, i = cmd->sg_nents;
+ struct scatterlist *sg = hwif->sg_table;
- sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
dma_addr_t cur_addr;
int cur_len;
@@ -485,29 +476,19 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
}
use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
-static int sgiioc4_dma_setup(ide_drive_t *drive)
+static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- struct request *rq = drive->hwif->rq;
- unsigned int count = 0;
int ddir;
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (rq_data_dir(rq))
- ddir = PCI_DMA_TODEVICE;
- else
- ddir = PCI_DMA_FROMDEVICE;
-
- if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
+ if (sgiioc4_build_dmatable(drive, cmd) == 0)
/* try PIO instead of DMA */
- ide_map_sg(drive, rq);
return 1;
- }
- if (rq_data_dir(rq))
+ if (write)
/* Writes TO the IOC4 FROM Main Memory */
ddir = IOC4_DMA_READ;
else
@@ -546,7 +527,6 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
.dma_end = sgiioc4_dma_end,
.dma_test_irq = sgiioc4_dma_test_irq,
.dma_lost_irq = sgiioc4_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info sgiioc4_port_info __devinitconst = {
@@ -557,6 +537,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = {
.port_ops = &sgiioc4_port_ops,
.dma_ops = &sgiioc4_dma_ops,
.host_flags = IDE_HFLAG_MMIO,
+ .irq_flags = IRQF_SHARED,
.mwdma_mask = ATA_MWDMA2_ONLY,
};
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index cb2b352b876b..e4973cd1fba9 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -464,7 +464,7 @@ static void sil_sata_pre_reset(ide_drive_t *drive)
* to 133 MHz clocking if the system isn't already set up to do it.
*/
-static unsigned int init_chipset_siimage(struct pci_dev *dev)
+static int init_chipset_siimage(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
void __iomem *ioaddr = host->host_priv;
@@ -711,11 +711,10 @@ static const struct ide_port_ops sil_sata_port_ops = {
static const struct ide_dma_ops sil_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = siimage_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_lost_irq = ide_dma_lost_irq,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index 9ec1a4a4432c..afca22beaadf 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -447,7 +447,7 @@ static int __devinit sis_find_family(struct pci_dev *dev)
return chipset_family;
}
-static unsigned int init_chipset_sis5513(struct pci_dev *dev)
+static int init_chipset_sis5513(struct pci_dev *dev)
{
/* Make general config ops here
1/ tell IDE channels to operate in Compatibility mode only
@@ -563,7 +563,7 @@ static const struct ide_port_info sis5513_chipset __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_sis5513,
.enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA,
+ .host_flags = IDE_HFLAG_NO_AUTODMA,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
};
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 6297956507c0..d6f8977191c8 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -189,14 +189,13 @@ static void sl82c105_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
-static void sl82c105_dma_timeout(ide_drive_t *drive)
+static void sl82c105_dma_clear(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
+ DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
sl82c105_reset_host(dev);
- ide_dma_timeout(drive);
}
static int sl82c105_dma_end(ide_drive_t *drive)
@@ -271,7 +270,7 @@ static u8 sl82c105_bridge_revision(struct pci_dev *dev)
* channel 0 here at least, but channel 1 has to be enabled by
* firmware or arch code. We still set both to 16 bits mode.
*/
-static unsigned int init_chipset_sl82c105(struct pci_dev *dev)
+static int init_chipset_sl82c105(struct pci_dev *dev)
{
u32 val;
@@ -281,7 +280,7 @@ static unsigned int init_chipset_sl82c105(struct pci_dev *dev)
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
- return dev->irq;
+ return 0;
}
static const struct ide_port_ops sl82c105_port_ops = {
@@ -293,12 +292,12 @@ static const struct ide_port_ops sl82c105_port_ops = {
static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = sl82c105_dma_start,
.dma_end = sl82c105_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = sl82c105_dma_lost_irq,
- .dma_timeout = sl82c105_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = sl82c105_dma_clear,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index 40b4b94a4288..f55d7d6313e8 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -136,7 +136,6 @@ static const struct ide_port_info slc90e66_chipset __devinitdata = {
.name = DRV_NAME,
.enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
.port_ops = &slc90e66_port_ops,
- .host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.swdma_mask = ATA_SWDMA2_ONLY,
.mwdma_mask = ATA_MWDMA12_ONLY,
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index 84109f5a1632..b4cf42dc8a6f 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -182,12 +182,11 @@ static const struct ide_port_ops tc86c001_port_ops = {
static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = tc86c001_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index b6a1285a4021..c0528f27fcae 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -176,53 +176,44 @@ static void trm290_selectproc (ide_drive_t *drive)
trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
}
-static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
+static int trm290_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL);
-}
-
-static int trm290_dma_setup(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int count, rw;
-
- if (rq_data_dir(rq)) {
+ if (cmd->tf_flags & IDE_TFLAG_WRITE) {
#ifdef TRM290_NO_DMA_WRITES
/* always use PIO for writes */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
#endif
- rw = 1;
- } else
- rw = 2;
+ }
+ return 0;
+}
- if (!(count = ide_build_dmatable(drive, rq))) {
+static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ unsigned int count, rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 2;
+
+ count = ide_build_dmatable(drive, cmd);
+ if (count == 0)
/* try PIO instead of DMA */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
- }
- /* select DMA xfer */
- trm290_prepare_drive(drive, 1);
+
outl(hwif->dmatable_dma | rw, hwif->dma_base);
- drive->waiting_for_dma = 1;
/* start DMA */
outw(count * 2 - 1, hwif->dma_base + 2);
+
return 0;
}
static void trm290_dma_start(ide_drive_t *drive)
{
+ trm290_prepare_drive(drive, 1);
}
static int trm290_dma_end(ide_drive_t *drive)
{
- u16 status;
+ u16 status = inw(drive->hwif->dma_base + 2);
- drive->waiting_for_dma = 0;
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- status = inw(drive->hwif->dma_base + 2);
+ trm290_prepare_drive(drive, 0);
return status != 0x00ff;
}
@@ -277,9 +268,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
if (reg & 0x10)
/* legacy mode */
hwif->irq = hwif->channel ? 15 : 14;
- else if (!hwif->irq && hwif->mate && hwif->mate->irq)
- /* sharing IRQ with mate */
- hwif->irq = hwif->mate->irq;
#if 1
{
@@ -317,12 +305,11 @@ static const struct ide_port_ops trm290_port_ops = {
static struct ide_dma_ops trm290_dma_ops = {
.dma_host_set = trm290_dma_host_set,
.dma_setup = trm290_dma_setup,
- .dma_exec_cmd = trm290_dma_exec_cmd,
.dma_start = trm290_dma_start,
.dma_end = trm290_dma_end,
.dma_test_irq = trm290_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_check = trm290_dma_check,
};
static const struct ide_port_info trm290_chipset __devinitdata = {
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index d9095345f7ca..657a61890b1c 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -15,6 +15,8 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+
+#include <asm/ide.h>
#include <asm/txx9/tx4938.h>
static void tx4938ide_tune_ebusc(unsigned int ebus_ch,
@@ -80,57 +82,57 @@ static void tx4938ide_outb(u8 value, unsigned long port)
__raw_writeb(value, (void __iomem *)port);
}
-static void tx4938ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
u16 data = (tf->hob_data << 8) | tf->data;
/* no endian swap */
__raw_writew(data, (void __iomem *)io_ports->data_addr);
}
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
tx4938ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
tx4938ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
tx4938ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
tx4938ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
tx4938ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
tx4938ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_taskfile *tf = &cmd->tf;
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data;
/* no endian swap */
@@ -142,37 +144,37 @@ static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task)
/* be sure we're looking at the low order bits */
tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = tx4938ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = tx4938ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = tx4938ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature =
tx4938ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
}
}
-static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
@@ -184,7 +186,7 @@ static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq,
__ide_flush_dcache_range((unsigned long)buf, roundup(len, 2));
}
-static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 882f6f07c476..faf0d97b9ce8 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -18,6 +18,8 @@
#include <linux/io.h>
#include <linux/scatterlist.h>
+#include <asm/ide.h>
+
#define MODNAME "tx4939ide"
/* ATA Shadow Registers (8-bit except for Data which is 16-bit) */
@@ -230,7 +232,7 @@ static u8 tx4939ide_clear_dma_status(void __iomem *base)
#ifdef __BIG_ENDIAN
/* custom ide_build_dmatable to handle swapped layout */
-static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
u32 *table = (u32 *)hwif->dmatable_cpu;
@@ -238,11 +240,7 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
int i;
struct scatterlist *sg;
- hwif->sg_nents = ide_build_sglist(drive, rq);
- if (hwif->sg_nents == 0)
- return 0;
-
- for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+ for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
u32 cur_addr, cur_len, bcount;
cur_addr = sg_dma_address(sg);
@@ -261,9 +259,9 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
bcount = cur_len;
/*
* This workaround for zero count seems required.
- * (standard ide_build_dmatable do it too)
+ * (standard ide_build_dmatable does it too)
*/
- if ((bcount & 0xffff) == 0x0000)
+ if (bcount == 0x10000)
bcount = 0x8000;
*table++ = bcount & 0xffff;
*table++ = cur_addr;
@@ -281,48 +279,36 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
#else
#define tx4939ide_build_dmatable ide_build_dmatable
#endif
-static int tx4939ide_dma_setup(ide_drive_t *drive)
+static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
void __iomem *base = TX4939IDE_BASE(hwif);
- struct request *rq = hwif->rq;
- u8 reading;
- int nent;
-
- if (rq_data_dir(rq))
- reading = 0;
- else
- reading = ATA_DMA_WR;
+ u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
/* fall back to PIO! */
- nent = tx4939ide_build_dmatable(drive, rq);
- if (!nent) {
- ide_map_sg(drive, rq);
+ if (tx4939ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
/* specify r/w */
- tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd);
+ tx4939ide_writeb(rw, base, TX4939IDE_DMA_Cmd);
/* clear INTR & ERROR flags */
tx4939ide_clear_dma_status(base);
- drive->waiting_for_dma = 1;
-
tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
- tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
+ tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
return 0;
}
@@ -333,8 +319,6 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
void __iomem *base = TX4939IDE_BASE(hwif);
u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
- drive->waiting_for_dma = 0;
-
/* get DMA command mode */
dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd);
/* stop DMA */
@@ -343,11 +327,9 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
/* read and clear the INTR & ERROR bits */
dma_stat = tx4939ide_clear_dma_status(base);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
wmb();
+ /* verify good DMA status */
if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
(ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
(TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
@@ -437,7 +419,7 @@ static int tx4939ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
return ide_allocate_dma_engine(hwif);
}
-static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
void __iomem *base = TX4939IDE_BASE(hwif);
@@ -465,59 +447,59 @@ static void tx4939ide_outb(u8 value, unsigned long port)
__raw_writeb(value, (void __iomem *)port);
}
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
u16 data = (tf->hob_data << 8) | tf->data;
/* no endian swap */
__raw_writew(data, (void __iomem *)io_ports->data_addr);
}
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
tx4939ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
tx4939ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
tx4939ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
tx4939ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
tx4939ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) {
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) {
tx4939ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
- tx4939ide_tf_load_fixup(drive, task);
+ tx4939ide_tf_load_fixup(drive);
}
}
-static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_taskfile *tf = &cmd->tf;
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
u16 data;
/* no endian swap */
@@ -529,32 +511,32 @@ static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task)
/* be sure we're looking at the low order bits */
tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
tf->feature = tx4939ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = tx4939ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = tx4939ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
tf->hob_feature =
tx4939ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
}
}
@@ -601,11 +583,12 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
#else /* __LITTLE_ENDIAN */
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_tf_load(drive, task);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tx4939ide_tf_load_fixup(drive, task);
+ ide_tf_load(drive, cmd);
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ tx4939ide_tf_load_fixup(drive);
}
static const struct ide_tp_ops tx4939ide_tp_ops = {
@@ -634,12 +617,11 @@ static const struct ide_port_ops tx4939ide_port_ops = {
static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_host_set = tx4939ide_dma_host_set,
.dma_setup = tx4939ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = tx4939ide_dma_end,
.dma_test_irq = tx4939ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 703c3eeb20a8..3ff7231e4858 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -267,7 +267,7 @@ static void via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
* and initialize its drive independent registers.
*/
-static unsigned int init_chipset_via82cxxx(struct pci_dev *dev)
+static int init_chipset_via82cxxx(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct via82cxxx_dev *vdev = host->host_priv;
@@ -443,11 +443,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
if ((via_config->flags & VIA_NO_UNMASK) == 0)
d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
-#ifdef CONFIG_PPC_CHRP
- if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos)
- d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
-#endif
-
d.udma_mask = via_config->udma_mask;
vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
diff --git a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h
index 2727bcd24194..467373cab8e5 100644
--- a/drivers/ieee1394/dma.h
+++ b/drivers/ieee1394/dma.h
@@ -12,6 +12,7 @@
#include <asm/types.h>
+struct file;
struct pci_dev;
struct scatterlist;
struct vm_area_struct;
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index a329e6bd5d2d..3838bc4acaba 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1823,6 +1823,10 @@ static int dv1394_open(struct inode *inode, struct file *file)
#endif
+ printk(KERN_INFO "%s: NOTE, the dv1394 interface is unsupported "
+ "and will not be available in the new firewire driver stack. "
+ "Try libraw1394 based programs instead.\n", current->comm);
+
return 0;
}
@@ -2567,10 +2571,6 @@ static int __init dv1394_init_module(void)
{
int ret;
- printk(KERN_WARNING
- "NOTE: The dv1394 driver is unsupported and may be removed in a "
- "future Linux release. Use raw1394 instead.\n");
-
cdev_init(&dv1394_cdev, &dv1394_fops);
dv1394_cdev.owner = THIS_MODULE;
ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16);
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
index e0ae0d3d747f..af320e2c5079 100644
--- a/drivers/ieee1394/ieee1394.h
+++ b/drivers/ieee1394/ieee1394.h
@@ -54,9 +54,7 @@
#define IEEE1394_SPEED_800 0x03
#define IEEE1394_SPEED_1600 0x04
#define IEEE1394_SPEED_3200 0x05
-
-/* The current highest tested speed supported by the subsystem */
-#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800
+#define IEEE1394_SPEED_MAX IEEE1394_SPEED_3200
/* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[];
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index dcdb71a7718d..872338003721 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -338,6 +338,7 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
u8 cldcnt[nodecount];
u8 *map = host->speed_map;
u8 *speedcap = host->speed;
+ u8 local_link_speed = host->csr.lnk_spd;
struct selfid *sid;
struct ext_selfid *esid;
int i, j, n;
@@ -373,8 +374,8 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;
speedcap[n] = sid->speed;
- if (speedcap[n] > host->csr.lnk_spd)
- speedcap[n] = host->csr.lnk_spd;
+ if (speedcap[n] > local_link_speed)
+ speedcap[n] = local_link_speed;
n--;
}
}
@@ -407,12 +408,11 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
}
}
-#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
- /* assume maximum speed for 1394b PHYs, nodemgr will correct it */
- for (n = 0; n < nodecount; n++)
- if (speedcap[n] == SELFID_SPEED_UNKNOWN)
- speedcap[n] = IEEE1394_SPEED_MAX;
-#endif
+ /* assume a maximum speed for 1394b PHYs, nodemgr will correct it */
+ if (local_link_speed > SELFID_SPEED_UNKNOWN)
+ for (i = 0; i < nodecount; i++)
+ if (speedcap[i] == SELFID_SPEED_UNKNOWN)
+ speedcap[i] = local_link_speed;
}
@@ -1275,7 +1275,7 @@ static void __exit ieee1394_cleanup(void)
unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
}
-module_init(ieee1394_init);
+fs_initcall(ieee1394_init);
module_exit(ieee1394_cleanup);
/* Exported symbols */
@@ -1314,6 +1314,7 @@ EXPORT_SYMBOL(hpsb_make_lock64packet);
EXPORT_SYMBOL(hpsb_make_phypacket);
EXPORT_SYMBOL(hpsb_read);
EXPORT_SYMBOL(hpsb_write);
+EXPORT_SYMBOL(hpsb_lock);
EXPORT_SYMBOL(hpsb_packet_success);
/** highlevel.c **/
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index 10c3d9f8c038..675b3135d5f1 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -501,8 +501,6 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
- BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
-
packet = hpsb_make_readpacket(host, node, addr, length);
if (!packet) {
@@ -550,8 +548,6 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
if (length == 0)
return -EINVAL;
- BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
-
packet = hpsb_make_writepacket(host, node, addr, buffer, length);
if (!packet)
@@ -570,3 +566,30 @@ int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
return retval;
}
+
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+ u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
+{
+ struct hpsb_packet *packet;
+ int retval = 0;
+
+ packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
+ if (!packet)
+ return -ENOMEM;
+
+ packet->generation = generation;
+ retval = hpsb_send_packet_and_wait(packet);
+ if (retval < 0)
+ goto hpsb_lock_fail;
+
+ retval = hpsb_packet_success(packet);
+
+ if (retval == 0)
+ *data = packet->data[0];
+
+hpsb_lock_fail:
+ hpsb_free_tlabel(packet);
+ hpsb_free_packet(packet);
+
+ return retval;
+}
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h
index d2d5bc3546d7..20b693be14b2 100644
--- a/drivers/ieee1394/ieee1394_transactions.h
+++ b/drivers/ieee1394/ieee1394_transactions.h
@@ -30,6 +30,8 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
u64 addr, quadlet_t *buffer, size_t length);
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+ u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
#ifdef HPSB_DEBUG_TLABELS
extern spinlock_t hpsb_tlabel_lock;
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
index b5de5f21ef78..c2089c093aa7 100644
--- a/drivers/ieee1394/iso.h
+++ b/drivers/ieee1394/iso.h
@@ -13,6 +13,7 @@
#define IEEE1394_ISO_H
#include <linux/spinlock_types.h>
+#include <linux/wait.h>
#include <asm/atomic.h>
#include <asm/types.h>
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 906c5a98d814..53aada5bbe1e 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -971,6 +971,9 @@ static struct unit_directory *nodemgr_process_unit_directory
ud->ud_kv = ud_kv;
ud->id = (*id)++;
+ /* inherit vendor_id from root directory if none exists in unit dir */
+ ud->vendor_id = ne->vendor_id;
+
csr1212_for_each_dir_entry(ne->csr, kv, ud_kv, dentry) {
switch (kv->key.id) {
case CSR1212_KV_ID_VENDOR:
@@ -1265,7 +1268,8 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
csr1212_destroy_csr(csr);
}
- /* Mark the node current */
+ /* Finally, mark the node current */
+ smp_wmb();
ne->generation = generation;
if (ne->in_limbo) {
@@ -1798,7 +1802,7 @@ void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet)
{
packet->host = ne->host;
packet->generation = ne->generation;
- barrier();
+ smp_rmb();
packet->node_id = ne->nodeid;
}
@@ -1807,7 +1811,7 @@ int hpsb_node_write(struct node_entry *ne, u64 addr,
{
unsigned int generation = ne->generation;
- barrier();
+ smp_rmb();
return hpsb_write(ne->host, ne->nodeid, generation,
addr, buffer, length);
}
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 15ea09733e84..ee5acdbd114a 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -21,9 +21,11 @@
#define _IEEE1394_NODEMGR_H
#include <linux/device.h>
+#include <asm/system.h>
#include <asm/types.h>
#include "ieee1394_core.h"
+#include "ieee1394_transactions.h"
#include "ieee1394_types.h"
struct csr1212_csr;
@@ -154,6 +156,22 @@ static inline int hpsb_node_entry_valid(struct node_entry *ne)
void hpsb_node_fill_packet(struct node_entry *ne, struct hpsb_packet *packet);
int hpsb_node_write(struct node_entry *ne, u64 addr,
quadlet_t *buffer, size_t length);
+static inline int hpsb_node_read(struct node_entry *ne, u64 addr,
+ quadlet_t *buffer, size_t length)
+{
+ unsigned int g = ne->generation;
+
+ smp_rmb();
+ return hpsb_read(ne->host, ne->nodeid, g, addr, buffer, length);
+}
+static inline int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode,
+ quadlet_t *buffer, quadlet_t arg)
+{
+ unsigned int g = ne->generation;
+
+ smp_rmb();
+ return hpsb_lock(ne->host, ne->nodeid, g, addr, extcode, buffer, arg);
+}
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *));
int init_ieee1394_nodemgr(void);
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
index 4320bf010495..7fb8ab9780ae 100644
--- a/drivers/ieee1394/ohci1394.h
+++ b/drivers/ieee1394/ohci1394.h
@@ -26,7 +26,7 @@
#define OHCI1394_DRIVER_NAME "ohci1394"
-#define OHCI1394_MAX_AT_REQ_RETRIES 0x2
+#define OHCI1394_MAX_AT_REQ_RETRIES 0xf
#define OHCI1394_MAX_AT_RESP_RETRIES 0x2
#define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8
#define OHCI1394_MAX_SELF_ID_ERRORS 16
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index dc15cadb06ef..38f712036201 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -1419,7 +1419,6 @@ static int __devinit add_card(struct pci_dev *dev,
i2c_ad = kzalloc(sizeof(*i2c_ad), GFP_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
- i2c_ad->id = I2C_HW_B_PCILYNX;
strlcpy(i2c_ad->name, "PCILynx I2C", sizeof(i2c_ad->name));
i2c_adapter_data = bit_data;
i2c_ad->algo_data = &i2c_adapter_data;
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index ab1034ccb7fb..f3fd8657ce4b 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -115,8 +115,8 @@
*/
static int sbp2_max_speed = IEEE1394_SPEED_MAX;
module_param_named(max_speed, sbp2_max_speed, int, 0644);
-MODULE_PARM_DESC(max_speed, "Force max speed "
- "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)");
+MODULE_PARM_DESC(max_speed, "Limit data transfer speed (5 <= 3200, "
+ "4 <= 1600, 3 <= 800, 2 <= 400, 1 <= 200, 0 = 100 Mb/s)");
/*
* Set serialize_io to 0 or N to use dynamically appended lists of command ORBs.
@@ -256,7 +256,7 @@ static int sbp2_set_busy_timeout(struct sbp2_lu *);
static int sbp2_max_speed_and_size(struct sbp2_lu *);
-static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
+static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xa, 0xa, 0xa };
static DEFINE_RWLOCK(sbp2_hi_logical_units_lock);
@@ -347,8 +347,8 @@ static struct scsi_host_template sbp2_shost_template = {
.sdev_attrs = sbp2_sysfs_sdev_attrs,
};
-/* for match-all entries in sbp2_workarounds_table */
-#define SBP2_ROM_VALUE_WILDCARD 0x1000000
+#define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */
+#define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */
/*
* List of devices with known bugs.
@@ -359,60 +359,70 @@ static struct scsi_host_template sbp2_shost_template = {
*/
static const struct {
u32 firmware_revision;
- u32 model_id;
+ u32 model;
unsigned workarounds;
} sbp2_workarounds_table[] = {
/* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
.firmware_revision = 0x002800,
- .model_id = 0x001010,
+ .model = 0x001010,
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
SBP2_WORKAROUND_MODE_SENSE_8 |
SBP2_WORKAROUND_POWER_CONDITION,
},
/* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
.firmware_revision = 0x002800,
- .model_id = 0x000000,
+ .model = 0x000000,
.workarounds = SBP2_WORKAROUND_DELAY_INQUIRY |
SBP2_WORKAROUND_POWER_CONDITION,
},
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_INQUIRY_36,
},
/* PL-3507 bridge with Prolific firmware */ {
.firmware_revision = 0x012800,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_POWER_CONDITION,
},
/* Symbios bridge */ {
.firmware_revision = 0xa0b800,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
/* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ {
.firmware_revision = 0x002600,
- .model_id = SBP2_ROM_VALUE_WILDCARD,
+ .model = SBP2_ROM_VALUE_WILDCARD,
.workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
},
+ /*
+ * iPod 2nd generation: needs 128k max transfer size workaround
+ * iPod 3rd generation: needs fix capacity workaround
+ */
+ {
+ .firmware_revision = 0x0a2700,
+ .model = 0x000000,
+ .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS |
+ SBP2_WORKAROUND_FIX_CAPACITY,
+ },
/* iPod 4th generation */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x000021,
+ .model = 0x000021,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
},
/* iPod mini */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x000022,
+ .model = 0x000022,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
},
/* iPod mini */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x000023,
+ .model = 0x000023,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
},
/* iPod Photo */ {
.firmware_revision = 0x0a2700,
- .model_id = 0x00007e,
+ .model = 0x00007e,
.workarounds = SBP2_WORKAROUND_FIX_CAPACITY,
}
};
@@ -1341,13 +1351,15 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
struct csr1212_keyval *kv;
struct csr1212_dentry *dentry;
u64 management_agent_addr;
- u32 unit_characteristics, firmware_revision;
+ u32 unit_characteristics, firmware_revision, model;
unsigned workarounds;
int i;
management_agent_addr = 0;
unit_characteristics = 0;
- firmware_revision = 0;
+ firmware_revision = SBP2_ROM_VALUE_MISSING;
+ model = ud->flags & UNIT_DIRECTORY_MODEL_ID ?
+ ud->model_id : SBP2_ROM_VALUE_MISSING;
csr1212_for_each_dir_entry(ud->ne->csr, kv, ud->ud_kv, dentry) {
switch (kv->key.id) {
@@ -1388,9 +1400,9 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
sbp2_workarounds_table[i].firmware_revision !=
(firmware_revision & 0xffff00))
continue;
- if (sbp2_workarounds_table[i].model_id !=
+ if (sbp2_workarounds_table[i].model !=
SBP2_ROM_VALUE_WILDCARD &&
- sbp2_workarounds_table[i].model_id != ud->model_id)
+ sbp2_workarounds_table[i].model != model)
continue;
workarounds |= sbp2_workarounds_table[i].workarounds;
break;
@@ -1403,7 +1415,7 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid),
workarounds, firmware_revision,
ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id,
- ud->model_id);
+ model);
/* We would need one SCSI host template for each target to adjust
* max_sectors on the fly, therefore warn only. */
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 35561689ff38..ea2638b41982 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
if INPUT_KEYBOARD
config KEYBOARD_ATKBD
- tristate "AT keyboard" if EMBEDDED || !X86_PC
+ tristate "AT keyboard" if EMBEDDED || !X86
default y
select SERIO
select SERIO_LIBPS2
- select SERIO_I8042 if X86_PC
+ select SERIO_I8042 if X86
select SERIO_GSCPS2 if GSC
help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index c3c8b9bc40ae..45470f18d7e9 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -839,7 +839,7 @@ static void atkbd_disconnect(struct serio *serio)
*/
static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
{
- const unsigned int forced_release_keys[] = {
+ static const unsigned int forced_release_keys[] = {
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
};
int i;
@@ -856,7 +856,7 @@ static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
*/
static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
{
- const unsigned int forced_release_keys[] = {
+ static const unsigned int forced_release_keys[] = {
0x94,
};
int i;
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index 19284016e0f4..ee855c5202e8 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -209,8 +209,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
goto out;
}
- if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT ||
- !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) {
+ if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
+ !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
printk(KERN_ERR DRV_NAME
": Invalid Debounce/Columdrive Time from pdata\n");
bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index c8ed065ea0cb..634af6a8e6b3 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -21,8 +21,6 @@
#include <linux/slab.h>
#include <mach/corgi.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
#include <asm/hardware/scoop.h>
@@ -288,7 +286,7 @@ static int corgikbd_resume(struct platform_device *dev)
#define corgikbd_resume NULL
#endif
-static int __init corgikbd_probe(struct platform_device *pdev)
+static int __devinit corgikbd_probe(struct platform_device *pdev)
{
struct corgikbd *corgikbd;
struct input_dev *input_dev;
@@ -368,7 +366,7 @@ static int __init corgikbd_probe(struct platform_device *pdev)
return err;
}
-static int corgikbd_remove(struct platform_device *pdev)
+static int __devexit corgikbd_remove(struct platform_device *pdev)
{
int i;
struct corgikbd *corgikbd = platform_get_drvdata(pdev);
@@ -388,7 +386,7 @@ static int corgikbd_remove(struct platform_device *pdev)
static struct platform_driver corgikbd_driver = {
.probe = corgikbd_probe,
- .remove = corgikbd_remove,
+ .remove = __devexit_p(corgikbd_remove),
.suspend = corgikbd_suspend,
.resume = corgikbd_resume,
.driver = {
@@ -397,7 +395,7 @@ static struct platform_driver corgikbd_driver = {
},
};
-static int __devinit corgikbd_init(void)
+static int __init corgikbd_init(void)
{
return platform_driver_register(&corgikbd_driver);
}
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 3f3d1198cdb1..058fa8b02c21 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -279,7 +279,7 @@ static int omap_kp_resume(struct platform_device *dev)
#define omap_kp_resume NULL
#endif
-static int __init omap_kp_probe(struct platform_device *pdev)
+static int __devinit omap_kp_probe(struct platform_device *pdev)
{
struct omap_kp *omap_kp;
struct input_dev *input_dev;
@@ -422,7 +422,7 @@ err1:
return -EINVAL;
}
-static int omap_kp_remove(struct platform_device *pdev)
+static int __devexit omap_kp_remove(struct platform_device *pdev)
{
struct omap_kp *omap_kp = platform_get_drvdata(pdev);
@@ -454,7 +454,7 @@ static int omap_kp_remove(struct platform_device *pdev)
static struct platform_driver omap_kp_driver = {
.probe = omap_kp_probe,
- .remove = omap_kp_remove,
+ .remove = __devexit_p(omap_kp_remove),
.suspend = omap_kp_suspend,
.resume = omap_kp_resume,
.driver = {
@@ -463,7 +463,7 @@ static struct platform_driver omap_kp_driver = {
},
};
-static int __devinit omap_kp_init(void)
+static int __init omap_kp_init(void)
{
printk(KERN_INFO "OMAP Keypad Driver\n");
return platform_driver_register(&omap_kp_driver);
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index c48b76a46a58..13967422658c 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -21,8 +21,6 @@
#include <linux/slab.h>
#include <mach/spitz.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
#define KB_ROWS 7
@@ -343,7 +341,7 @@ static int spitzkbd_resume(struct platform_device *dev)
#define spitzkbd_resume NULL
#endif
-static int __init spitzkbd_probe(struct platform_device *dev)
+static int __devinit spitzkbd_probe(struct platform_device *dev)
{
struct spitzkbd *spitzkbd;
struct input_dev *input_dev;
@@ -444,7 +442,7 @@ static int __init spitzkbd_probe(struct platform_device *dev)
return err;
}
-static int spitzkbd_remove(struct platform_device *dev)
+static int __devexit spitzkbd_remove(struct platform_device *dev)
{
int i;
struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
@@ -470,7 +468,7 @@ static int spitzkbd_remove(struct platform_device *dev)
static struct platform_driver spitzkbd_driver = {
.probe = spitzkbd_probe,
- .remove = spitzkbd_remove,
+ .remove = __devexit_p(spitzkbd_remove),
.suspend = spitzkbd_suspend,
.resume = spitzkbd_resume,
.driver = {
@@ -479,7 +477,7 @@ static struct platform_driver spitzkbd_driver = {
},
};
-static int __devinit spitzkbd_init(void)
+static int __init spitzkbd_init(void)
{
return platform_driver_register(&spitzkbd_driver);
}
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 093c8c1bca74..4f38e6f7dfdd 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -17,7 +17,7 @@ config MOUSE_PS2
default y
select SERIO
select SERIO_LIBPS2
- select SERIO_I8042 if X86_PC
+ select SERIO_I8042 if X86
select SERIO_GSCPS2 if GSC
help
Say Y here if you have a PS/2 mouse connected to your system. This
@@ -70,7 +70,7 @@ config MOUSE_PS2_SYNAPTICS
config MOUSE_PS2_LIFEBOOK
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
default y
- depends on MOUSE_PS2
+ depends on MOUSE_PS2 && X86
help
Say Y here if you have a Fujitsu B-series Lifebook PS/2
TouchScreen connected to your system.
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c
index d297accf9a7f..1e827ad0afbe 100644
--- a/drivers/input/mouse/pxa930_trkball.c
+++ b/drivers/input/mouse/pxa930_trkball.c
@@ -83,7 +83,7 @@ static int write_tbcr(struct pxa930_trkball *trkball, int v)
__raw_writel(v, trkball->mmio_base + TBCR);
- while (i--) {
+ while (--i) {
if (__raw_readl(trkball->mmio_base + TBCR) == v)
break;
msleep(1);
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index b10ffae7c39b..e29cdc13a199 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -57,7 +57,7 @@ static int amba_kmi_write(struct serio *io, unsigned char val)
struct amba_kmi_port *kmi = io->port_data;
unsigned int timeleft = 10000; /* timeout in 100ms */
- while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--)
+ while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && --timeleft)
udelay(10);
if (timeleft)
@@ -129,8 +129,8 @@ static int amba_kmi_probe(struct amba_device *dev, void *id)
io->write = amba_kmi_write;
io->open = amba_kmi_open;
io->close = amba_kmi_close;
- strlcpy(io->name, dev->dev.bus_id, sizeof(io->name));
- strlcpy(io->phys, dev->dev.bus_id, sizeof(io->phys));
+ strlcpy(io->name, dev_name(&dev->dev), sizeof(io->name));
+ strlcpy(io->phys, dev_name(&dev->dev), sizeof(io->phys));
io->port_data = kmi;
io->dev.parent = &dev->dev;
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index adc3bd6e7f7b..bd0f92d9f40f 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -359,7 +359,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
- strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+ strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
serio->id.type = SERIO_8042;
serio->write = gscps2_write;
serio->open = gscps2_open;
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 2ad88780a170..57953c0eb82f 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -246,8 +246,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev)
serio->write = ps2_write;
serio->open = ps2_open;
serio->close = ps2_close;
- strlcpy(serio->name, dev->dev.bus_id, sizeof(serio->name));
- strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
+ strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name));
+ strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
serio->port_data = ps2if;
serio->dev.parent = &dev->dev;
ps2if->io = serio;
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index a89a6a8f05e6..055969e8be13 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -236,7 +236,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
ts_dev->bufferedmeasure = 0;
snprintf(ts_dev->phys, sizeof(ts_dev->phys),
- "%s/input0", pdev->dev.bus_id);
+ "%s/input0", dev_name(&pdev->dev));
input_dev->name = "atmel touch screen controller";
input_dev->phys = ts_dev->phys;
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 65202c9f63ff..94a1919d439d 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -21,7 +21,6 @@
#include <mach/sharpsl.h>
#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
@@ -268,7 +267,7 @@ static int corgits_resume(struct platform_device *dev)
#define corgits_resume NULL
#endif
-static int __init corgits_probe(struct platform_device *pdev)
+static int __devinit corgits_probe(struct platform_device *pdev)
{
struct corgi_ts *corgi_ts;
struct input_dev *input_dev;
@@ -343,7 +342,7 @@ static int __init corgits_probe(struct platform_device *pdev)
return err;
}
-static int corgits_remove(struct platform_device *pdev)
+static int __devexit corgits_remove(struct platform_device *pdev)
{
struct corgi_ts *corgi_ts = platform_get_drvdata(pdev);
@@ -352,12 +351,13 @@ static int corgits_remove(struct platform_device *pdev)
corgi_ts->machinfo->put_hsync();
input_unregister_device(corgi_ts->input);
kfree(corgi_ts);
+
return 0;
}
static struct platform_driver corgits_driver = {
.probe = corgits_probe,
- .remove = corgits_remove,
+ .remove = __devexit_p(corgits_remove),
.suspend = corgits_suspend,
.resume = corgits_resume,
.driver = {
@@ -366,7 +366,7 @@ static struct platform_driver corgits_driver = {
},
};
-static int __devinit corgits_init(void)
+static int __init corgits_init(void)
{
return platform_driver_register(&corgits_driver);
}
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index b75dc2990574..4ab070246892 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -289,7 +289,8 @@ static int tsc2007_probe(struct i2c_client *client,
pdata->init_platform_hw();
- snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id);
+ snprintf(ts->phys, sizeof(ts->phys),
+ "%s/input0", dev_name(&client->dev));
input_dev->name = "TSC2007 Touchscreen";
input_dev->phys = ts->phys;
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 5080b26ba160..6d27a1d661e6 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -60,6 +60,10 @@ static int swap_xy;
module_param(swap_xy, bool, 0644);
MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
+static int hwcalib_xy;
+module_param(hwcalib_xy, bool, 0644);
+MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available");
+
/* device specifc data/functions */
struct usbtouch_usb;
struct usbtouch_device_info {
@@ -260,8 +264,13 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{
- dev->x = (pkt[8] << 8) | pkt[7];
- dev->y = (pkt[10] << 8) | pkt[9];
+ if (hwcalib_xy) {
+ dev->x = (pkt[4] << 8) | pkt[3];
+ dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]);
+ } else {
+ dev->x = (pkt[8] << 8) | pkt[7];
+ dev->y = (pkt[10] << 8) | pkt[9];
+ }
dev->touch = (pkt[2] & 0x40) ? 1 : 0;
return 1;
@@ -294,6 +303,12 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
return ret;
}
+ /* Default min/max xy are the raw values, override if using hw-calib */
+ if (hwcalib_xy) {
+ input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0);
+ input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0);
+ }
+
return 0;
}
#endif
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index ac245e7e96a5..3071a52467ed 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -389,8 +389,7 @@ static void gigaset_freecshw(struct cardstate *cs)
static void gigaset_device_release(struct device *dev)
{
- struct platform_device *pdev =
- container_of(dev, struct platform_device, dev);
+ struct platform_device *pdev = to_platform_device(dev);
/* adapted from platform_device_release() in drivers/base/platform.c */
//FIXME is this actually necessary?
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 595ba8eb4a07..0b28141e43bf 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -4599,6 +4599,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
printk(KERN_ERR "%s: no memory for coeffs\n",
__func__);
ret = -ENOMEM;
+ kfree(bch);
goto free_chan;
}
bch->nr = ch;
@@ -4767,6 +4768,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
printk(KERN_ERR "%s: no memory for coeffs\n",
__func__);
ret = -ENOMEM;
+ kfree(bch);
goto free_chan;
}
bch->nr = ch + 1;
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index a3551dd0324d..aa30b5cb3513 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -431,6 +431,7 @@ set_arg(void __user *b, void *val,int len)
return 0;
}
+#ifdef CONFIG_IPPP_FILTER
static int get_filter(void __user *arg, struct sock_filter **p)
{
struct sock_fprog uprog;
@@ -465,6 +466,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)
*p = code;
return uprog.len;
}
+#endif /* CONFIG_IPPP_FILTER */
/*
* ippp device ioctl
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c
index 712220cef139..7f16d75d2d89 100644
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -54,7 +54,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
- pr_debug("%s: copying %d bytes from %#lx to %#lx\n",
+ pr_debug("%s: copying %zu bytes from %#lx to %#lx\n",
sc_adapter[card]->devicename, n,
(unsigned long) src,
sc_adapter[card]->rambase + ((unsigned long) dest %0x4000));
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 90663e01a56e..60156dfdc608 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -224,7 +224,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
break;
/* If the Guest asked to be stopped, we sleep. The Guest's
- * clock timer or LHCALL_BREAK from the Waker will wake us. */
+ * clock timer or LHREQ_BREAK from the Waker will wake us. */
if (cpu->halted) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 34bc017b8b3c..b8ee103eed5f 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -307,9 +307,8 @@ static int close(struct inode *inode, struct file *file)
* kmalloc()ed string, either of which is ok to hand to kfree(). */
if (!IS_ERR(lg->dead))
kfree(lg->dead);
- /* We clear the entire structure, which also marks it as free for the
- * next user. */
- memset(lg, 0, sizeof(*lg));
+ /* Free the memory allocated to the lguest_struct */
+ kfree(lg);
/* Release lock and exit. */
mutex_unlock(&lguest_lock);
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 82607add69a9..c0621d50c8a0 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -498,8 +498,8 @@ static ssize_t store_##name(struct device *dev, struct device_attribute *attr, c
#define BUILD_STORE_FUNC_INT(name, data) \
static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
{ \
- u32 val; \
- val = simple_strtoul(buf, NULL, 10); \
+ int val; \
+ val = simple_strtol(buf, NULL, 10); \
if (val < 0 || val > 255) \
return -EINVAL; \
printk(KERN_INFO "Setting specified fan speed to %d\n", val); \
diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
index ef2dbfe74714..ada5ebbaa255 100644
--- a/drivers/mca/mca-bus.c
+++ b/drivers/mca/mca-bus.c
@@ -110,7 +110,7 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev)
mca_dev->dev.parent = &mca_bus->dev;
mca_dev->dev.bus = &mca_bus_type;
- sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot);
+ dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot);
mca_dev->dma_mask = mca_bus->default_dma_mask;
mca_dev->dev.dma_mask = &mca_dev->dma_mask;
mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask;
@@ -151,7 +151,7 @@ struct mca_bus * __devinit mca_attach_bus(int bus)
if (!mca_bus)
return NULL;
- sprintf(mca_bus->dev.bus_id,"mca%d",bus);
+ dev_set_name(&mca_bus->dev, "mca%d", bus);
sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
if (device_register(&mca_bus->dev)) {
kfree(mca_bus);
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index a34338567a2a..36e2b5e46a6b 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -292,6 +292,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
(PAGE_SIZE >> SECTOR_SHIFT));
num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev),
num_bvecs);
+ if (unlikely(num_bvecs > BIO_MAX_PAGES))
+ num_bvecs = BIO_MAX_PAGES;
bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
bio->bi_sector = where->sector + (where->count - remaining);
bio->bi_bdev = where->bdev;
@@ -328,7 +330,7 @@ static void dispatch_io(int rw, unsigned int num_regions,
struct dpages old_pages = *dp;
if (sync)
- rw |= (1 << BIO_RW_SYNC);
+ rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
/*
* For multiple regions we need to be careful to rewind
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 54d0588fc1f6..f01096549a93 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -704,7 +704,8 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
char *new_name = (char *) param + param->data_start;
if (new_name < param->data ||
- invalid_str(new_name, (void *) param + param_size)) {
+ invalid_str(new_name, (void *) param + param_size) ||
+ strlen(new_name) > DM_NAME_LEN - 1) {
DMWARN("Invalid new logical volume name supplied.");
return -EINVAL;
}
@@ -1063,7 +1064,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
r = populate_table(t, param, param_size);
if (r) {
- dm_table_put(t);
+ dm_table_destroy(t);
goto out;
}
@@ -1071,7 +1072,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
hc = dm_get_mdptr(md);
if (!hc || hc->md != md) {
DMWARN("device has been removed from the dev hash table.");
- dm_table_put(t);
+ dm_table_destroy(t);
up_write(&_hash_lock);
r = -ENXIO;
goto out;
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index 3073618269ea..0a225da21272 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -344,7 +344,7 @@ static int run_io_job(struct kcopyd_job *job)
{
int r;
struct dm_io_request io_req = {
- .bi_rw = job->rw | (1 << BIO_RW_SYNC),
+ .bi_rw = job->rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG),
.mem.type = DM_IO_PAGE_LIST,
.mem.ptr.pl = job->pages,
.mem.offset = job->offset,
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 7decf10006e4..04feccf2a997 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -14,45 +14,34 @@
#define DM_MSG_PREFIX "target"
-struct tt_internal {
- struct target_type tt;
-
- struct list_head list;
- long use;
-};
-
static LIST_HEAD(_targets);
static DECLARE_RWSEM(_lock);
#define DM_MOD_NAME_SIZE 32
-static inline struct tt_internal *__find_target_type(const char *name)
+static inline struct target_type *__find_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
- list_for_each_entry (ti, &_targets, list)
- if (!strcmp(name, ti->tt.name))
- return ti;
+ list_for_each_entry(tt, &_targets, list)
+ if (!strcmp(name, tt->name))
+ return tt;
return NULL;
}
-static struct tt_internal *get_target_type(const char *name)
+static struct target_type *get_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- ti = __find_target_type(name);
- if (ti) {
- if ((ti->use == 0) && !try_module_get(ti->tt.module))
- ti = NULL;
- else
- ti->use++;
- }
+ tt = __find_target_type(name);
+ if (tt && !try_module_get(tt->module))
+ tt = NULL;
up_read(&_lock);
- return ti;
+ return tt;
}
static void load_module(const char *name)
@@ -62,92 +51,59 @@ static void load_module(const char *name)
struct target_type *dm_get_target_type(const char *name)
{
- struct tt_internal *ti = get_target_type(name);
+ struct target_type *tt = get_target_type(name);
- if (!ti) {
+ if (!tt) {
load_module(name);
- ti = get_target_type(name);
+ tt = get_target_type(name);
}
- return ti ? &ti->tt : NULL;
+ return tt;
}
-void dm_put_target_type(struct target_type *t)
+void dm_put_target_type(struct target_type *tt)
{
- struct tt_internal *ti = (struct tt_internal *) t;
-
down_read(&_lock);
- if (--ti->use == 0)
- module_put(ti->tt.module);
-
- BUG_ON(ti->use < 0);
+ module_put(tt->module);
up_read(&_lock);
-
- return;
-}
-
-static struct tt_internal *alloc_target(struct target_type *t)
-{
- struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
-
- if (ti)
- ti->tt = *t;
-
- return ti;
}
-
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- list_for_each_entry (ti, &_targets, list)
- iter_func(&ti->tt, param);
+ list_for_each_entry(tt, &_targets, list)
+ iter_func(tt, param);
up_read(&_lock);
return 0;
}
-int dm_register_target(struct target_type *t)
+int dm_register_target(struct target_type *tt)
{
int rv = 0;
- struct tt_internal *ti = alloc_target(t);
-
- if (!ti)
- return -ENOMEM;
down_write(&_lock);
- if (__find_target_type(t->name))
+ if (__find_target_type(tt->name))
rv = -EEXIST;
else
- list_add(&ti->list, &_targets);
+ list_add(&tt->list, &_targets);
up_write(&_lock);
- if (rv)
- kfree(ti);
return rv;
}
-void dm_unregister_target(struct target_type *t)
+void dm_unregister_target(struct target_type *tt)
{
- struct tt_internal *ti;
-
down_write(&_lock);
- if (!(ti = __find_target_type(t->name))) {
- DMCRIT("Unregistering unrecognised target: %s", t->name);
- BUG();
- }
-
- if (ti->use) {
- DMCRIT("Attempt to unregister target still in use: %s",
- t->name);
+ if (!__find_target_type(tt->name)) {
+ DMCRIT("Unregistering unrecognised target: %s", tt->name);
BUG();
}
- list_del(&ti->list);
- kfree(ti);
+ list_del(&tt->list);
up_write(&_lock);
}
@@ -156,17 +112,17 @@ void dm_unregister_target(struct target_type *t)
* io-err: always fails an io, useful for bringing
* up LVs that have holes in them.
*/
-static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
+static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
{
return 0;
}
-static void io_err_dtr(struct dm_target *ti)
+static void io_err_dtr(struct dm_target *tt)
{
/* empty */
}
-static int io_err_map(struct dm_target *ti, struct bio *bio,
+static int io_err_map(struct dm_target *tt, struct bio *bio,
union map_info *map_context)
{
return -EIO;
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 20194e000c5a..b48397c0abbd 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -60,7 +60,7 @@ int dm_table_barrier_ok(struct dm_table *t);
int dm_target_init(void);
void dm_target_exit(void);
struct target_type *dm_get_target_type(const char *name);
-void dm_put_target_type(struct target_type *t);
+void dm_put_target_type(struct target_type *tt);
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 1e3aea9eecf1..09658b218474 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -25,13 +25,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
{
dev_info_t *hash;
linear_conf_t *conf = mddev_to_conf(mddev);
+ sector_t idx = sector >> conf->sector_shift;
/*
* sector_div(a,b) returns the remainer and sets a to a/b
*/
- sector >>= conf->sector_shift;
- (void)sector_div(sector, conf->spacing);
- hash = conf->hash_table[sector];
+ (void)sector_div(idx, conf->spacing);
+ hash = conf->hash_table[idx];
while (sector >= hash->num_sectors + hash->start_sector)
hash++;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 41e2509bf896..03b4cd0a6344 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -474,7 +474,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
* causes ENOTSUPP, we allocate a spare bio...
*/
struct bio *bio = bio_alloc(GFP_NOIO, 1);
- int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
+ int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG);
bio->bi_bdev = rdev->bdev;
bio->bi_sector = sector;
@@ -531,7 +531,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size,
struct completion event;
int ret;
- rw |= (1 << BIO_RW_SYNC);
+ rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
bio->bi_bdev = bdev;
bio->bi_sector = sector;
@@ -1481,6 +1481,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (find_rdev_nr(mddev, rdev->desc_nr))
return -EBUSY;
}
+ if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) {
+ printk(KERN_WARNING "md: %s: array is limited to %d devices\n",
+ mdname(mddev), mddev->max_disks);
+ return -EBUSY;
+ }
bdevname(rdev->bdev,b);
while ( (s=strchr(b, '/')) != NULL)
*s = '!';
@@ -2441,6 +2446,15 @@ static void analyze_sbs(mddev_t * mddev)
i = 0;
rdev_for_each(rdev, tmp, mddev) {
+ if (rdev->desc_nr >= mddev->max_disks ||
+ i > mddev->max_disks) {
+ printk(KERN_WARNING
+ "md: %s: %s: only %d devices permitted\n",
+ mdname(mddev), bdevname(rdev->bdev, b),
+ mddev->max_disks);
+ kick_rdev_from_array(rdev);
+ continue;
+ }
if (rdev != freshest)
if (super_types[mddev->major_version].
validate_super(mddev, rdev)) {
@@ -4614,13 +4628,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
* noticed in interrupt contexts ...
*/
- if (rdev->desc_nr == mddev->max_disks) {
- printk(KERN_WARNING "%s: can not hot-add to full array!\n",
- mdname(mddev));
- err = -EBUSY;
- goto abort_unbind_export;
- }
-
rdev->raid_disk = -1;
md_update_sb(mddev, 1);
@@ -4634,9 +4641,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
md_new_event(mddev);
return 0;
-abort_unbind_export:
- unbind_rdev_from_array(rdev);
-
abort_export:
export_rdev(rdev);
return err;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 7b4f5f7155d8..e2466425d9ca 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error)
update_head_pos(mirror, r1_bio);
if (atomic_dec_and_test(&r1_bio->remaining)) {
- md_done_sync(mddev, r1_bio->sectors, uptodate);
+ sector_t s = r1_bio->sectors;
put_buf(r1_bio);
+ md_done_sync(mddev, s, uptodate);
}
}
@@ -1640,7 +1641,8 @@ static void raid1d(mddev_t *mddev)
}
bio = r1_bio->bios[r1_bio->read_disk];
- if ((disk=read_balance(conf, r1_bio)) == -1) {
+ if ((disk=read_balance(conf, r1_bio)) == -1 ||
+ disk == r1_bio->read_disk) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
" read error for block %llu\n",
bdevname(bio->bi_bdev,b),
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 6736d6dff981..7301631abe04 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error)
/* for reconstruct, we always reschedule after a read.
* for resync, only after all reads
*/
+ rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
if (test_bit(R10BIO_IsRecover, &r10_bio->state) ||
atomic_dec_and_test(&r10_bio->remaining)) {
/* we have read all the blocks,
@@ -1243,7 +1244,6 @@ static void end_sync_read(struct bio *bio, int error)
*/
reschedule_retry(r10_bio);
}
- rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev);
}
static void end_sync_write(struct bio *bio, int error)
@@ -1264,11 +1264,13 @@ static void end_sync_write(struct bio *bio, int error)
update_head_pos(i, r10_bio);
+ rdev_dec_pending(conf->mirrors[d].rdev, mddev);
while (atomic_dec_and_test(&r10_bio->remaining)) {
if (r10_bio->master_bio == NULL) {
/* the primary of several recovery bios */
- md_done_sync(mddev, r10_bio->sectors, 1);
+ sector_t s = r10_bio->sectors;
put_buf(r10_bio);
+ md_done_sync(mddev, s, 1);
break;
} else {
r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio;
@@ -1276,7 +1278,6 @@ static void end_sync_write(struct bio *bio, int error)
r10_bio = r10_bio2;
}
}
- rdev_dec_pending(conf->mirrors[d].rdev, mddev);
}
/*
@@ -1749,8 +1750,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
if (!go_faster && conf->nr_waiting)
msleep_interruptible(1000);
- bitmap_cond_end_sync(mddev->bitmap, sector_nr);
-
/* Again, very different code for resync and recovery.
* Both must result in an r10bio with a list of bios that
* have bi_end_io, bi_sector, bi_bdev set,
@@ -1886,6 +1885,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* resync. Schedule a read for every block at this virt offset */
int count = 0;
+ bitmap_cond_end_sync(mddev->bitmap, sector_nr);
+
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, mddev->degraded) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
@@ -2010,13 +2011,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
/* There is nowhere to write, so all non-sync
* drives must be failed, so try the next chunk...
*/
- {
- sector_t sec = max_sector - sector_nr;
- sectors_skipped += sec;
+ if (sector_nr + max_sync < max_sector)
+ max_sector = sector_nr + max_sync;
+
+ sectors_skipped += (max_sector - sector_nr);
chunks_skipped ++;
sector_nr = max_sector;
goto skipped;
- }
}
static int run(mddev_t *mddev)
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 93ea201f426c..223c36ede5ae 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -117,7 +117,7 @@ source "drivers/media/dvb/Kconfig"
config DAB
boolean "DAB adapters"
---help---
- Allow selecting support for for Digital Audio Broadcasting (DAB)
+ Allow selecting support for Digital Audio Broadcasting (DAB)
Receiver adapters.
if DAB
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index d8229a0e9a9c..97e78f71c60d 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -153,6 +153,65 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a);
+/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
+IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = {
+ [0x00] = KEY_POWER,
+ [0x01] = KEY_TUNER, /* TV/FM */
+ [0x03] = KEY_TEXT, /* Teletext */
+ [0x04] = KEY_EPG,
+ [0x05] = KEY_1,
+ [0x06] = KEY_2,
+ [0x07] = KEY_3,
+ [0x08] = KEY_AUDIO,
+ [0x09] = KEY_4,
+ [0x0a] = KEY_5,
+ [0x0b] = KEY_6,
+ [0x0c] = KEY_ZOOM, /* Full screen */
+ [0x0d] = KEY_7,
+ [0x0e] = KEY_8,
+ [0x0f] = KEY_9,
+ [0x10] = KEY_PAGEUP, /* 16-CH PREV */
+ [0x11] = KEY_0,
+ [0x12] = KEY_INFO,
+ [0x13] = KEY_AGAIN, /* CH RTN - channel return */
+ [0x14] = KEY_MUTE,
+ [0x15] = KEY_EDIT, /* Autoscan */
+ [0x17] = KEY_SAVE, /* Screenshot */
+ [0x18] = KEY_PLAYPAUSE,
+ [0x19] = KEY_RECORD,
+ [0x1a] = KEY_PLAY,
+ [0x1b] = KEY_STOP,
+ [0x1c] = KEY_FASTFORWARD,
+ [0x1d] = KEY_REWIND,
+ [0x1e] = KEY_VOLUMEDOWN,
+ [0x1f] = KEY_VOLUMEUP,
+ [0x22] = KEY_SLEEP, /* Sleep */
+ [0x23] = KEY_ZOOM, /* Aspect */
+ [0x26] = KEY_SCREEN, /* Pos */
+ [0x27] = KEY_ANGLE, /* Size */
+ [0x28] = KEY_SELECT, /* Select */
+ [0x29] = KEY_BLUE, /* Blue/Picture */
+ [0x2a] = KEY_BACKSPACE, /* Back */
+ [0x2b] = KEY_MEDIA, /* PIP (Picture-in-picture) */
+ [0x2c] = KEY_DOWN,
+ [0x2e] = KEY_DOT,
+ [0x2f] = KEY_TV, /* Live TV */
+ [0x32] = KEY_LEFT,
+ [0x33] = KEY_CLEAR, /* Clear */
+ [0x35] = KEY_RED, /* Red/TV */
+ [0x36] = KEY_UP,
+ [0x37] = KEY_HOME, /* Home */
+ [0x39] = KEY_GREEN, /* Green/Video */
+ [0x3d] = KEY_YELLOW, /* Yellow/Music */
+ [0x3e] = KEY_OK, /* Ok */
+ [0x3f] = KEY_RIGHT,
+ [0x40] = KEY_NEXT, /* Next */
+ [0x41] = KEY_PREVIOUS, /* Previous */
+ [0x42] = KEY_CHANNELDOWN, /* Channel down */
+ [0x43] = KEY_CHANNELUP /* Channel up */
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus);
+
/* Attila Kondoros <attila.kondoros@chello.hu> */
IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
@@ -2452,6 +2511,55 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog);
+/* Kaiomy TVnPC U2
+ Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = {
+ [0x43] = KEY_POWER2,
+ [0x01] = KEY_LIST,
+ [0x0b] = KEY_ZOOM,
+ [0x03] = KEY_POWER,
+
+ [0x04] = KEY_1,
+ [0x08] = KEY_2,
+ [0x02] = KEY_3,
+
+ [0x0f] = KEY_4,
+ [0x05] = KEY_5,
+ [0x06] = KEY_6,
+
+ [0x0c] = KEY_7,
+ [0x0d] = KEY_8,
+ [0x0a] = KEY_9,
+
+ [0x11] = KEY_0,
+
+ [0x09] = KEY_CHANNELUP,
+ [0x07] = KEY_CHANNELDOWN,
+
+ [0x0e] = KEY_VOLUMEUP,
+ [0x13] = KEY_VOLUMEDOWN,
+
+ [0x10] = KEY_HOME,
+ [0x12] = KEY_ENTER,
+
+ [0x14] = KEY_RECORD,
+ [0x15] = KEY_STOP,
+ [0x16] = KEY_PLAY,
+ [0x17] = KEY_MUTE,
+
+ [0x18] = KEY_UP,
+ [0x19] = KEY_DOWN,
+ [0x1a] = KEY_LEFT,
+ [0x1b] = KEY_RIGHT,
+
+ [0x1c] = KEY_RED,
+ [0x1d] = KEY_GREEN,
+ [0x1e] = KEY_YELLOW,
+ [0x1f] = KEY_BLUE,
+};
+EXPORT_SYMBOL_GPL(ir_codes_kaiomy);
+
IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
[0x20] = KEY_LIST,
[0x00] = KEY_POWER,
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index d599d360da3f..982f000a57ff 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -452,8 +452,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
dev->ext = ext;
- pci_set_drvdata(pci, dev);
-
mutex_init(&dev->lock);
spin_lock_init(&dev->int_slock);
spin_lock_init(&dev->slock);
@@ -477,8 +475,12 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
if (ext->attach(dev, pci_ext)) {
DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));
- goto err_unprobe;
+ goto err_free_i2c;
}
+ /* V4L extensions will set the pci drvdata to the v4l2_device in the
+ attach() above. So for those cards that do not use V4L we have to
+ set it explicitly. */
+ pci_set_drvdata(pci, &dev->v4l2_dev);
INIT_LIST_HEAD(&dev->item);
list_add_tail(&dev->item,&saa7146_devices);
@@ -488,8 +490,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
out:
return err;
-err_unprobe:
- pci_set_drvdata(pci, NULL);
err_free_i2c:
pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
dev->d_i2c.dma_handle);
@@ -514,7 +514,8 @@ err_free:
static void saa7146_remove_one(struct pci_dev *pdev)
{
- struct saa7146_dev* dev = pci_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
+ struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
struct {
void *addr;
dma_addr_t dma;
@@ -528,6 +529,8 @@ static void saa7146_remove_one(struct pci_dev *pdev)
DEB_EE(("dev:%p\n",dev));
dev->ext->detach(dev);
+ /* Zero the PCI drvdata after use. */
+ pci_set_drvdata(pdev, NULL);
/* shut down all video dma transfers */
saa7146_write(dev, MC1, 0x00ff0000);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index cf06f4d10ad4..620f655fa9c5 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -308,14 +308,6 @@ static int fops_release(struct file *file)
return 0;
}
-static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-/*
- DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg));
-*/
- return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl);
-}
-
static int fops_mmap(struct file *file, struct vm_area_struct * vma)
{
struct saa7146_fh *fh = file->private_data;
@@ -425,7 +417,7 @@ static const struct v4l2_file_operations video_fops =
.write = fops_write,
.poll = fops_poll,
.mmap = fops_mmap,
- .ioctl = fops_ioctl,
+ .ioctl = video_ioctl2,
};
static void vv_callback(struct saa7146_dev *dev, unsigned long status)
@@ -452,19 +444,22 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
}
}
-static struct video_device device_template =
-{
- .fops = &video_fops,
- .minor = -1,
-};
-
int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
{
- struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
- if( NULL == vv ) {
+ struct saa7146_vv *vv;
+ int err;
+
+ err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
+ if (err)
+ return err;
+
+ vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
+ if (vv == NULL) {
ERR(("out of memory. aborting.\n"));
- return -1;
+ return -ENOMEM;
}
+ ext_vv->ops = saa7146_video_ioctl_ops;
+ ext_vv->core_ops = &saa7146_video_ioctl_ops;
DEB_EE(("dev:%p\n",dev));
@@ -507,6 +502,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
DEB_EE(("dev:%p\n",dev));
+ v4l2_device_unregister(&dev->v4l2_dev);
pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
kfree(vv);
dev->vv_data = NULL;
@@ -521,6 +517,8 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
{
struct saa7146_vv *vv = dev->vv_data;
struct video_device *vfd;
+ int err;
+ int i;
DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
@@ -529,16 +527,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
if (vfd == NULL)
return -ENOMEM;
- memcpy(vfd, &device_template, sizeof(struct video_device));
- strlcpy(vfd->name, name, sizeof(vfd->name));
+ vfd->fops = &video_fops;
+ vfd->ioctl_ops = &dev->ext_vv_data->ops;
vfd->release = video_device_release;
+ vfd->tvnorms = 0;
+ for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+ vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
+ strlcpy(vfd->name, name, sizeof(vfd->name));
video_set_drvdata(vfd, dev);
- // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
- if (video_register_device(vfd, type, -1) < 0) {
+ err = video_register_device(vfd, type, -1);
+ if (err < 0) {
ERR(("cannot register v4l2 device. skipping.\n"));
video_device_release(vfd);
- return -1;
+ return err;
}
if( VFL_TYPE_GRABBER == type ) {
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index c11da4d09cd0..76229f992275 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -390,7 +390,8 @@ out:
/* utility functions */
static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
{
- struct saa7146_dev* dev = i2c_get_adapdata(adapter);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+ struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
/* use helper function to transfer data */
return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
@@ -417,9 +418,8 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c
dev->i2c_bitrate = bitrate;
saa7146_i2c_reset(dev);
- if( NULL != i2c_adapter ) {
- BUG_ON(!i2c_adapter->class);
- i2c_set_adapdata(i2c_adapter,dev);
+ if (i2c_adapter) {
+ i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev);
i2c_adapter->dev.parent = &dev->pci->dev;
i2c_adapter->algo = &saa7146_algo;
i2c_adapter->algo_data = NULL;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 6098b626811f..8d8cb7ff3478 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1,4 +1,5 @@
#include <media/saa7146_vv.h>
+#include <media/v4l2-chip-ident.h>
static int max_memory = 32;
@@ -97,172 +98,13 @@ struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
return NULL;
}
-static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- DEB_EE(("dev:%p, fh:%p\n",dev,fh));
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- f->fmt.pix = fh->video_fmt;
- return 0;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- f->fmt.win = fh->ov.win;
- return 0;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- {
- f->fmt.vbi = fh->vbi_fmt;
- return 0;
- }
- default:
- DEB_D(("invalid format type '%d'.\n",f->type));
- return -EINVAL;
- }
-}
-
-static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
-{
- struct saa7146_vv *vv = dev->vv_data;
- enum v4l2_field field;
- int maxw, maxh;
-
- DEB_EE(("dev:%p\n",dev));
-
- if (NULL == vv->ov_fb.base) {
- DEB_D(("no fb base set.\n"));
- return -EINVAL;
- }
- if (NULL == vv->ov_fmt) {
- DEB_D(("no fb fmt set.\n"));
- return -EINVAL;
- }
- if (win->w.width < 48 || win->w.height < 32) {
- DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height));
- return -EINVAL;
- }
- if (win->clipcount > 16) {
- DEB_D(("clipcount too big.\n"));
- return -EINVAL;
- }
-
- field = win->field;
- maxw = vv->standard->h_max_out;
- maxh = vv->standard->v_max_out;
-
- if (V4L2_FIELD_ANY == field) {
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- case V4L2_FIELD_ALTERNATE:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default: {
- DEB_D(("no known field mode '%d'.\n",field));
- return -EINVAL;
- }
- }
-
- win->field = field;
- if (win->w.width > maxw)
- win->w.width = maxw;
- if (win->w.height > maxh)
- win->w.height = maxh;
-
- return 0;
-}
-
-static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
- int err;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- {
- struct saa7146_format *fmt;
- enum v4l2_field field;
- int maxw, maxh;
- int calc_bpl;
-
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
-
- fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat);
- if (NULL == fmt) {
- return -EINVAL;
- }
-
- field = f->fmt.pix.field;
- maxw = vv->standard->h_max_out;
- maxh = vv->standard->v_max_out;
-
- if (V4L2_FIELD_ANY == field) {
- field = (f->fmt.pix.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_BOTTOM;
- }
- switch (field) {
- case V4L2_FIELD_ALTERNATE: {
- vv->last_field = V4L2_FIELD_TOP;
- maxh = maxh / 2;
- break;
- }
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- vv->last_field = V4L2_FIELD_INTERLACED;
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- vv->last_field = V4L2_FIELD_INTERLACED;
- break;
- default: {
- DEB_D(("no known field mode '%d'.\n",field));
- return -EINVAL;
- }
- }
-
- f->fmt.pix.field = field;
- if (f->fmt.pix.width > maxw)
- f->fmt.pix.width = maxw;
- if (f->fmt.pix.height > maxh)
- f->fmt.pix.height = maxh;
-
- calc_bpl = (f->fmt.pix.width * fmt->depth)/8;
-
- if (f->fmt.pix.bytesperline < calc_bpl)
- f->fmt.pix.bytesperline = calc_bpl;
-
- if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
- f->fmt.pix.bytesperline = calc_bpl;
-
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
- DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
-
- return 0;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
- err = try_win(dev,&f->fmt.win);
- if (0 != err) {
- return err;
- }
- return 0;
- default:
- DEB_EE(("unknown format type '%d'\n",f->type));
- return -EINVAL;
- }
-}
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
int saa7146_start_preview(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
struct saa7146_vv *vv = dev->vv_data;
+ struct v4l2_format fmt;
int ret = 0, err = 0;
DEB_EE(("dev:%p, fh:%p\n",dev,fh));
@@ -294,12 +136,13 @@ int saa7146_start_preview(struct saa7146_fh *fh)
return -EBUSY;
}
- err = try_win(dev,&fh->ov.win);
+ fmt.fmt.win = fh->ov.win;
+ err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
if (0 != err) {
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
return -EBUSY;
}
-
+ fh->ov.win = fmt.fmt.win;
vv->ov_data = &fh->ov;
DEB_D(("%dx%d+%d+%d %s field=%s\n",
@@ -355,58 +198,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
}
EXPORT_SYMBOL_GPL(saa7146_stop_preview);
-static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- int err;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_EE(("streaming capture is active\n"));
- return -EBUSY;
- }
- err = try_fmt(fh,f);
- if (0 != err)
- return err;
- fh->video_fmt = f->fmt.pix;
- DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat));
- return 0;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
- err = try_win(dev,&f->fmt.win);
- if (0 != err)
- return err;
- mutex_lock(&dev->lock);
- fh->ov.win = f->fmt.win;
- fh->ov.nclips = f->fmt.win.clipcount;
- if (fh->ov.nclips > 16)
- fh->ov.nclips = 16;
- if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
- mutex_unlock(&dev->lock);
- return -EFAULT;
- }
-
- /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
- fh->ov.fh = fh;
-
- mutex_unlock(&dev->lock);
-
- /* check if our current overlay is active */
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- saa7146_stop_preview(fh);
- saa7146_start_preview(fh);
- }
- return 0;
- default:
- DEB_D(("unknown format type '%d'\n",f->type));
- return -EINVAL;
- }
-}
-
/********************************************************************************/
/* device controls */
@@ -419,6 +210,7 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 128,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_CONTRAST,
.name = "Contrast",
@@ -427,6 +219,7 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 64,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_SATURATION,
.name = "Saturation",
@@ -435,15 +228,16 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 64,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_VFLIP,
- .name = "Vertical flip",
+ .name = "Vertical Flip",
.minimum = 0,
.maximum = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
},{
.id = V4L2_CID_HFLIP,
- .name = "Horizontal flip",
+ .name = "Horizontal Flip",
.minimum = 0,
.maximum = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -463,131 +257,6 @@ static struct v4l2_queryctrl* ctrl_by_id(int id)
return NULL;
}
-static int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- const struct v4l2_queryctrl* ctrl;
- u32 value = 0;
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl)
- return -EINVAL;
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0xff & (value >> 24);
- DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value));
- break;
- case V4L2_CID_CONTRAST:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0x7f & (value >> 16);
- DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value));
- break;
- case V4L2_CID_SATURATION:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0x7f & (value >> 0);
- DEB_D(("V4L2_CID_SATURATION: %d\n",c->value));
- break;
- case V4L2_CID_VFLIP:
- c->value = vv->vflip;
- DEB_D(("V4L2_CID_VFLIP: %d\n",c->value));
- break;
- case V4L2_CID_HFLIP:
- c->value = vv->hflip;
- DEB_D(("V4L2_CID_HFLIP: %d\n",c->value));
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- const struct v4l2_queryctrl* ctrl;
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl) {
- DEB_D(("unknown control %d\n",c->id));
- return -EINVAL;
- }
-
- mutex_lock(&dev->lock);
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER:
- if (c->value < ctrl->minimum)
- c->value = ctrl->minimum;
- if (c->value > ctrl->maximum)
- c->value = ctrl->maximum;
- break;
- default:
- /* nothing */;
- };
-
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0x00ffffff;
- value |= (c->value << 24);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_CONTRAST: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0xff00ffff;
- value |= (c->value << 16);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_SATURATION: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0xffffff00;
- value |= (c->value << 0);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_HFLIP:
- /* fixme: we can support changing VFLIP and HFLIP here... */
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
- vv->hflip = c->value;
- break;
- case V4L2_CID_VFLIP:
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
- vv->vflip = c->value;
- break;
- default: {
- return -EINVAL;
- }
- }
- mutex_unlock(&dev->lock);
-
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- saa7146_stop_preview(fh);
- saa7146_start_preview(fh);
- }
- return 0;
-}
-
/********************************************************************************/
/* common pagetable functions */
@@ -828,231 +497,451 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
return 0;
}
-/*
- * This function is _not_ called directly, but from
- * video_generic_ioctl (and maybe others). userspace
- * copying is done already, arg is a kernel pointer.
- */
+static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+
+ strcpy((char *)cap->driver, "saa7146 v4l2");
+ strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
+ sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
+ cap->version = SAA7146_VERSION_CODE;
+ cap->capabilities =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OVERLAY |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING;
+ cap->capabilities |= dev->ext_vv_data->capabilities;
+ return 0;
+}
-long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
{
- struct saa7146_fh *fh = file->private_data;
- struct saa7146_dev *dev = fh->dev;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ *fb = vv->ov_fb;
+ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+ return 0;
+}
+
+static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct saa7146_vv *vv = dev->vv_data;
+ struct saa7146_format *fmt;
- long err = 0;
- int result = 0, ee = 0;
+ DEB_EE(("VIDIOC_S_FBUF\n"));
- struct saa7146_use_ops *ops;
- struct videobuf_queue *q;
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+ return -EPERM;
- /* check if extension handles the command */
- for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) {
- if( cmd == dev->ext_vv_data->ioctls[ee].cmd )
- break;
+ /* check args */
+ fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
+ if (NULL == fmt)
+ return -EINVAL;
+
+ /* planar formats are not allowed for overlay video, clipping and video dma would clash */
+ if (fmt->flags & FORMAT_IS_PLANAR)
+ DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",
+ (char *)&fmt->pixelformat));
+
+ /* check if overlay is running */
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ if (vv->video_fh != fh) {
+ DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
+ return -EBUSY;
+ }
}
- if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
- DEB_D(("extension handles ioctl exclusive.\n"));
- result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- return result;
+ mutex_lock(&dev->lock);
+
+ /* ok, accept it */
+ vv->ov_fb = *fb;
+ vv->ov_fmt = fmt;
+ if (0 == vv->ov_fb.fmt.bytesperline)
+ vv->ov_fb.fmt.bytesperline =
+ vv->ov_fb.fmt.width * fmt->depth / 8;
+
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+ if (f->index >= NUM_FORMATS)
+ return -EINVAL;
+ strlcpy((char *)f->description, formats[f->index].name,
+ sizeof(f->description));
+ f->pixelformat = formats[f->index].pixelformat;
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+ return vidioc_enum_fmt_vid_cap(file, fh, f);
+}
+
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
+{
+ const struct v4l2_queryctrl *ctrl;
+
+ if ((c->id < V4L2_CID_BASE ||
+ c->id >= V4L2_CID_LASTP1) &&
+ (c->id < V4L2_CID_PRIVATE_BASE ||
+ c->id >= V4L2_CID_PRIVATE_LASTP1))
+ return -EINVAL;
+
+ ctrl = ctrl_by_id(c->id);
+ if (ctrl == NULL)
+ return -EINVAL;
+
+ DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id));
+ *c = *ctrl;
+ return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ const struct v4l2_queryctrl *ctrl;
+ u32 value = 0;
+
+ ctrl = ctrl_by_id(c->id);
+ if (NULL == ctrl)
+ return -EINVAL;
+ switch (c->id) {
+ case V4L2_CID_BRIGHTNESS:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0xff & (value >> 24);
+ DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value));
+ break;
+ case V4L2_CID_CONTRAST:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0x7f & (value >> 16);
+ DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value));
+ break;
+ case V4L2_CID_SATURATION:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0x7f & (value >> 0);
+ DEB_D(("V4L2_CID_SATURATION: %d\n", c->value));
+ break;
+ case V4L2_CID_VFLIP:
+ c->value = vv->vflip;
+ DEB_D(("V4L2_CID_VFLIP: %d\n", c->value));
+ break;
+ case V4L2_CID_HFLIP:
+ c->value = vv->hflip;
+ DEB_D(("V4L2_CID_HFLIP: %d\n", c->value));
+ break;
+ default:
+ return -EINVAL;
}
- if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
- DEB_D(("extension handles ioctl before.\n"));
- result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- if( -EAGAIN != result ) {
- return result;
- }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ const struct v4l2_queryctrl *ctrl;
+
+ ctrl = ctrl_by_id(c->id);
+ if (NULL == ctrl) {
+ DEB_D(("unknown control %d\n", c->id));
+ return -EINVAL;
}
- /* fixme: add handle "after" case (is it still needed?) */
+ mutex_lock(&dev->lock);
+
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_INTEGER:
+ if (c->value < ctrl->minimum)
+ c->value = ctrl->minimum;
+ if (c->value > ctrl->maximum)
+ c->value = ctrl->maximum;
+ break;
+ default:
+ /* nothing */;
+ }
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- ops = &saa7146_video_uops;
- q = &fh->video_q;
+ switch (c->id) {
+ case V4L2_CID_BRIGHTNESS: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0x00ffffff;
+ value |= (c->value << 24);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_CONTRAST: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0xff00ffff;
+ value |= (c->value << 16);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_SATURATION: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0xffffff00;
+ value |= (c->value << 0);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
break;
+ }
+ case V4L2_CID_HFLIP:
+ /* fixme: we can support changing VFLIP and HFLIP here... */
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
+ mutex_unlock(&dev->lock);
+ return -EBUSY;
}
- case V4L2_BUF_TYPE_VBI_CAPTURE: {
- ops = &saa7146_vbi_uops;
- q = &fh->vbi_q;
+ vv->hflip = c->value;
break;
+ case V4L2_CID_VFLIP:
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
+ mutex_unlock(&dev->lock);
+ return -EBUSY;
}
+ vv->vflip = c->value;
+ break;
default:
- BUG();
- return 0;
+ mutex_unlock(&dev->lock);
+ return -EINVAL;
}
+ mutex_unlock(&dev->lock);
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
- memset(cap,0,sizeof(*cap));
-
- DEB_EE(("VIDIOC_QUERYCAP\n"));
-
- strcpy((char *)cap->driver, "saa7146 v4l2");
- strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
- sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci));
- cap->version = SAA7146_VERSION_CODE;
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VIDEO_OVERLAY |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- cap->capabilities |= dev->ext_vv_data->capabilities;
- return 0;
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ saa7146_stop_preview(fh);
+ saa7146_start_preview(fh);
}
- case VIDIOC_G_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
+ return 0;
+}
- DEB_EE(("VIDIOC_G_FBUF\n"));
+static int vidioc_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *parm)
+{
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ parm->parm.capture.readbuffers = 1;
+ /* fixme: only for PAL! */
+ parm->parm.capture.timeperframe.numerator = 1;
+ parm->parm.capture.timeperframe.denominator = 25;
+ return 0;
+}
- *fb = vv->ov_fb;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
- return 0;
- }
- case VIDIOC_S_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
- struct saa7146_format *fmt;
+static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
+ return 0;
+}
- DEB_EE(("VIDIOC_S_FBUF\n"));
+static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
+ return 0;
+}
- if(!capable(CAP_SYS_ADMIN) &&
- !capable(CAP_SYS_RAWIO))
- return -EPERM;
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
+ return 0;
+}
- /* check args */
- fmt = format_by_fourcc(dev,fb->fmt.pixelformat);
- if (NULL == fmt) {
- return -EINVAL;
- }
+static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ struct saa7146_format *fmt;
+ enum v4l2_field field;
+ int maxw, maxh;
+ int calc_bpl;
- /* planar formats are not allowed for overlay video, clipping and video dma would clash */
- if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
- DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
- }
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
- /* check if overlay is running */
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- if (vv->video_fh != fh) {
- DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
- return -EBUSY;
- }
- }
+ fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
+ if (NULL == fmt)
+ return -EINVAL;
+
+ field = f->fmt.pix.field;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
+
+ if (V4L2_FIELD_ANY == field) {
+ field = (f->fmt.pix.height > maxh / 2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_BOTTOM;
+ }
+ switch (field) {
+ case V4L2_FIELD_ALTERNATE:
+ vv->last_field = V4L2_FIELD_TOP;
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ vv->last_field = V4L2_FIELD_INTERLACED;
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ vv->last_field = V4L2_FIELD_INTERLACED;
+ break;
+ default:
+ DEB_D(("no known field mode '%d'.\n", field));
+ return -EINVAL;
+ }
- mutex_lock(&dev->lock);
+ f->fmt.pix.field = field;
+ if (f->fmt.pix.width > maxw)
+ f->fmt.pix.width = maxw;
+ if (f->fmt.pix.height > maxh)
+ f->fmt.pix.height = maxh;
- /* ok, accept it */
- vv->ov_fb = *fb;
- vv->ov_fmt = fmt;
- if (0 == vv->ov_fb.fmt.bytesperline)
- vv->ov_fb.fmt.bytesperline =
- vv->ov_fb.fmt.width*fmt->depth/8;
+ calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
- mutex_unlock(&dev->lock);
+ if (f->fmt.pix.bytesperline < calc_bpl)
+ f->fmt.pix.bytesperline = calc_bpl;
- return 0;
- }
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *f = arg;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (f->index >= NUM_FORMATS)
- return -EINVAL;
- strlcpy((char *)f->description, formats[f->index].name,
- sizeof(f->description));
- f->pixelformat = formats[f->index].pixelformat;
- f->flags = 0;
- memset(f->reserved, 0, sizeof(f->reserved));
- break;
- default:
- return -EINVAL;
- }
+ if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
+ f->fmt.pix.bytesperline = calc_bpl;
- DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- const struct v4l2_queryctrl *ctrl;
- struct v4l2_queryctrl *c = arg;
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
+ DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width,
+ f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage));
- if ((c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1) &&
- (c->id < V4L2_CID_PRIVATE_BASE ||
- c->id >= V4L2_CID_PRIVATE_LASTP1))
- return -EINVAL;
+ return 0;
+}
- ctrl = ctrl_by_id(c->id);
- if( NULL == ctrl ) {
- return -EINVAL;
-/*
- c->flags = V4L2_CTRL_FLAG_DISABLED;
- return 0;
-*/
- }
- DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id));
- *c = *ctrl;
- return 0;
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ struct v4l2_window *win = &f->fmt.win;
+ enum v4l2_field field;
+ int maxw, maxh;
+
+ DEB_EE(("dev:%p\n", dev));
+
+ if (NULL == vv->ov_fb.base) {
+ DEB_D(("no fb base set.\n"));
+ return -EINVAL;
}
- case VIDIOC_G_CTRL: {
- DEB_EE(("VIDIOC_G_CTRL\n"));
- return get_control(fh,arg);
+ if (NULL == vv->ov_fmt) {
+ DEB_D(("no fb fmt set.\n"));
+ return -EINVAL;
}
- case VIDIOC_S_CTRL:
- {
- DEB_EE(("VIDIOC_S_CTRL\n"));
- err = set_control(fh,arg);
- return err;
+ if (win->w.width < 48 || win->w.height < 32) {
+ DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height));
+ return -EINVAL;
}
- case VIDIOC_G_PARM:
- {
- struct v4l2_streamparm *parm = arg;
- if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
- return -EINVAL;
- }
- memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
- parm->parm.capture.readbuffers = 1;
- // fixme: only for PAL!
- parm->parm.capture.timeperframe.numerator = 1;
- parm->parm.capture.timeperframe.denominator = 25;
- return 0;
+ if (win->clipcount > 16) {
+ DEB_D(("clipcount too big.\n"));
+ return -EINVAL;
}
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_G_FMT\n"));
- return g_fmt(fh,f);
+
+ field = win->field;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
+
+ if (V4L2_FIELD_ANY == field) {
+ field = (win->w.height > maxh / 2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_TOP;
+ }
+ switch (field) {
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_ALTERNATE:
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ break;
+ default:
+ DEB_D(("no known field mode '%d'.\n", field));
+ return -EINVAL;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_S_FMT\n"));
- return s_fmt(fh,f);
+
+ win->field = field;
+ if (win->w.width > maxw)
+ win->w.width = maxw;
+ if (win->w.height > maxh)
+ win->w.height = maxh;
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_EE(("streaming capture is active\n"));
+ return -EBUSY;
}
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_TRY_FMT\n"));
- return try_fmt(fh,f);
+ err = vidioc_try_fmt_vid_cap(file, fh, f);
+ if (0 != err)
+ return err;
+ fh->video_fmt = f->fmt.pix;
+ DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat));
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh));
+ err = vidioc_try_fmt_vid_overlay(file, fh, f);
+ if (0 != err)
+ return err;
+ mutex_lock(&dev->lock);
+ fh->ov.win = f->fmt.win;
+ fh->ov.nclips = f->fmt.win.clipcount;
+ if (fh->ov.nclips > 16)
+ fh->ov.nclips = 16;
+ if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
+ sizeof(struct v4l2_clip) * fh->ov.nclips)) {
+ mutex_unlock(&dev->lock);
+ return -EFAULT;
}
- case VIDIOC_G_STD:
- {
- v4l2_std_id *id = arg;
- DEB_EE(("VIDIOC_G_STD\n"));
- *id = vv->standard->id;
- return 0;
+
+ /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
+ fh->ov.fh = fh;
+
+ mutex_unlock(&dev->lock);
+
+ /* check if our current overlay is active */
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ saa7146_stop_preview(fh);
+ saa7146_start_preview(fh);
}
+ return 0;
+}
+
+static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ *norm = vv->standard->id;
+ return 0;
+}
+
/* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
PAL / NTSC / SECAM. if your hardware does not (or does more)
-- override this function in your extension */
+/*
case VIDIOC_ENUMSTD:
{
struct v4l2_standard *e = arg;
@@ -1065,162 +954,245 @@ long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
}
return -EINVAL;
}
- case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg;
- int found = 0;
- int i;
+ */
- DEB_EE(("VIDIOC_S_STD\n"));
-
- if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
- DEB_D(("cannot change video standard while streaming capture is active\n"));
- return -EBUSY;
- }
+static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int found = 0;
+ int err, i;
- if ((vv->video_status & STATUS_OVERLAY) != 0) {
- vv->ov_suspend = vv->video_fh;
- err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
- if (0 != err) {
- DEB_D(("suspending video failed. aborting\n"));
- return err;
- }
- }
+ DEB_EE(("VIDIOC_S_STD\n"));
- mutex_lock(&dev->lock);
+ if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
+ DEB_D(("cannot change video standard while streaming capture is active\n"));
+ return -EBUSY;
+ }
- for(i = 0; i < dev->ext_vv_data->num_stds; i++)
- if (*id & dev->ext_vv_data->stds[i].id)
- break;
- if (i != dev->ext_vv_data->num_stds) {
- vv->standard = &dev->ext_vv_data->stds[i];
- if( NULL != dev->ext_vv_data->std_callback )
- dev->ext_vv_data->std_callback(dev, vv->standard);
- found = 1;
+ if ((vv->video_status & STATUS_OVERLAY) != 0) {
+ vv->ov_suspend = vv->video_fh;
+ err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
+ if (0 != err) {
+ DEB_D(("suspending video failed. aborting\n"));
+ return err;
}
+ }
- mutex_unlock(&dev->lock);
+ mutex_lock(&dev->lock);
- if (vv->ov_suspend != NULL) {
- saa7146_start_preview(vv->ov_suspend);
- vv->ov_suspend = NULL;
- }
+ for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+ if (*id & dev->ext_vv_data->stds[i].id)
+ break;
+ if (i != dev->ext_vv_data->num_stds) {
+ vv->standard = &dev->ext_vv_data->stds[i];
+ if (NULL != dev->ext_vv_data->std_callback)
+ dev->ext_vv_data->std_callback(dev, vv->standard);
+ found = 1;
+ }
- if( 0 == found ) {
- DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
- return -EINVAL;
- }
+ mutex_unlock(&dev->lock);
- DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name));
- return 0;
+ if (vv->ov_suspend != NULL) {
+ saa7146_start_preview(vv->ov_suspend);
+ vv->ov_suspend = NULL;
}
- case VIDIOC_OVERLAY:
- {
- int on = *(int *)arg;
- DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
- if (on != 0) {
- err = saa7146_start_preview(fh);
- } else {
- err = saa7146_stop_preview(fh);
- }
- return err;
- }
- case VIDIOC_REQBUFS: {
- struct v4l2_requestbuffers *req = arg;
- DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
- return videobuf_reqbufs(q,req);
- }
- case VIDIOC_QUERYBUF: {
- struct v4l2_buffer *buf = arg;
- DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
- return videobuf_querybuf(q,buf);
- }
- case VIDIOC_QBUF: {
- struct v4l2_buffer *buf = arg;
- int ret = 0;
- ret = videobuf_qbuf(q,buf);
- DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
- return ret;
- }
- case VIDIOC_DQBUF: {
- struct v4l2_buffer *buf = arg;
- int ret = 0;
- ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK);
- DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
- return ret;
+ if (!found) {
+ DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
+ return -EINVAL;
}
- case VIDIOC_STREAMON: {
- int *type = arg;
- DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
- err = video_begin(fh);
- if( 0 != err) {
- return err;
- }
- err = videobuf_streamon(q);
- return err;
- }
- case VIDIOC_STREAMOFF: {
- int *type = arg;
+ DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name));
+ return 0;
+}
- DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
+static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
+{
+ int err;
- /* ugly: we need to copy some checks from video_end(),
- because videobuf_streamoff() relies on the capture running.
- check and fix this */
- if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
- DEB_S(("not capturing.\n"));
- return 0;
- }
+ DEB_D(("VIDIOC_OVERLAY on:%d\n", on));
+ if (on)
+ err = saa7146_start_preview(fh);
+ else
+ err = saa7146_stop_preview(fh);
+ return err;
+}
- if (vv->video_fh != fh) {
- DEB_S(("capturing, but in another open.\n"));
- return -EBUSY;
- }
+static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
+{
+ struct saa7146_fh *fh = __fh;
- err = videobuf_streamoff(q);
- if (0 != err) {
- DEB_D(("warning: videobuf_streamoff() failed.\n"));
- video_end(fh, file);
- } else {
- err = video_end(fh, file);
- }
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_reqbufs(&fh->video_q, b);
+ if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_reqbufs(&fh->vbi_q, b);
+ return -EINVAL;
+}
+
+static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_querybuf(&fh->video_q, buf);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_querybuf(&fh->vbi_q, buf);
+ return -EINVAL;
+}
+
+static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_qbuf(&fh->video_q, buf);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_qbuf(&fh->vbi_q, buf);
+ return -EINVAL;
+}
+
+static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
+ return -EINVAL;
+}
+
+static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct saa7146_fh *fh = __fh;
+ int err;
+
+ DEB_D(("VIDIOC_STREAMON, type:%d\n", type));
+
+ err = video_begin(fh);
+ if (err)
return err;
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_streamon(&fh->video_q);
+ if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_streamon(&fh->vbi_q);
+ return -EINVAL;
+}
+
+static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type));
+
+ /* ugly: we need to copy some checks from video_end(),
+ because videobuf_streamoff() relies on the capture running.
+ check and fix this */
+ if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
+ DEB_S(("not capturing.\n"));
+ return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGMBUF:
- {
- struct video_mbuf *mbuf = arg;
- int i;
- /* fixme: number of capture buffers and sizes for v4l apps */
- int gbuffers = 2;
- int gbufsize = 768*576*4;
+ if (vv->video_fh != fh) {
+ DEB_S(("capturing, but in another open.\n"));
+ return -EBUSY;
+ }
- DEB_D(("VIDIOCGMBUF \n"));
+ err = -EINVAL;
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ err = videobuf_streamoff(&fh->video_q);
+ else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ err = videobuf_streamoff(&fh->vbi_q);
+ if (0 != err) {
+ DEB_D(("warning: videobuf_streamoff() failed.\n"));
+ video_end(fh, file);
+ } else {
+ err = video_end(fh, file);
+ }
+ return err;
+}
- q = &fh->video_q;
- err = videobuf_mmap_setup(q,gbuffers,gbufsize,
- V4L2_MEMORY_MMAP);
- if (err < 0)
- return err;
+static int vidioc_g_chip_ident(struct file *file, void *__fh,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
- gbuffers = err;
- memset(mbuf,0,sizeof(*mbuf));
- mbuf->frames = gbuffers;
- mbuf->size = gbuffers * gbufsize;
- for (i = 0; i < gbuffers; i++)
- mbuf->offsets[i] = i * gbufsize;
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
+ chip->ident = V4L2_IDENT_SAA7146;
return 0;
}
-#endif
- default:
- return v4l_compat_translate_ioctl(file, cmd, arg,
- saa7146_video_do_ioctl);
- }
+ return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
+ core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
+{
+ struct saa7146_fh *fh = __fh;
+ struct videobuf_queue *q = &fh->video_q;
+ int err, i;
+
+ /* fixme: number of capture buffers and sizes for v4l apps */
+ int gbuffers = 2;
+ int gbufsize = 768 * 576 * 4;
+
+ DEB_D(("VIDIOCGMBUF \n"));
+
+ q = &fh->video_q;
+ err = videobuf_mmap_setup(q, gbuffers, gbufsize,
+ V4L2_MEMORY_MMAP);
+ if (err < 0)
+ return err;
+
+ gbuffers = err;
+ memset(mbuf, 0, sizeof(*mbuf));
+ mbuf->frames = gbuffers;
+ mbuf->size = gbuffers * gbufsize;
+ for (i = 0; i < gbuffers; i++)
+ mbuf->offsets[i] = i * gbufsize;
return 0;
}
+#endif
+
+const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
+ .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
+ .vidioc_g_chip_ident = vidioc_g_chip_ident,
+
+ .vidioc_overlay = vidioc_overlay,
+ .vidioc_g_fbuf = vidioc_g_fbuf,
+ .vidioc_s_fbuf = vidioc_s_fbuf,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_g_std = vidioc_g_std,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_parm = vidioc_g_parm,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidiocgmbuf,
+#endif
+};
/*********************************************************************************/
/* buffer handling functions */
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 6f92beaa5ac8..7969b695cb50 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -29,6 +29,7 @@ config MEDIA_TUNER
select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMIZE
menuconfig MEDIA_TUNER_CUSTOMIZE
bool "Customize analog and hybrid tuner modules to build"
@@ -164,4 +165,11 @@ config MEDIA_TUNER_MXL5007T
help
A driver for the silicon tuner MxL5007T from MaxLinear.
+config MEDIA_TUNER_MC44S803
+ tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
+ depends on VIDEO_MEDIA && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the Freescale MC44S803 based tuners
+
endif # MEDIA_TUNER_CUSTOMIZE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 4dfbe5b8264f..4132b2be79e5 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
+obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/common/tuners/mc44s803.c
new file mode 100644
index 000000000000..20c4485ce16a
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803.c
@@ -0,0 +1,371 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mc44s803.h"
+#include "mc44s803_priv.h"
+
+#define mc_printk(level, format, arg...) \
+ printk(level "mc44s803: " format , ## arg)
+
+/* Writes a single register */
+static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
+{
+ u8 buf[3];
+ struct i2c_msg msg = {
+ .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
+ };
+
+ buf[0] = (val & 0xff0000) >> 16;
+ buf[1] = (val & 0xff00) >> 8;
+ buf[2] = (val & 0xff);
+
+ if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+ mc_printk(KERN_WARNING, "I2C write failed\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+/* Reads a single register */
+static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
+{
+ u32 wval;
+ u8 buf[3];
+ int ret;
+ struct i2c_msg msg[] = {
+ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+ .buf = buf, .len = 3 },
+ };
+
+ wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
+ MC44S803_REG_SM(reg, MC44S803_D);
+
+ ret = mc44s803_writereg(priv, wval);
+ if (ret)
+ return ret;
+
+ if (i2c_transfer(priv->i2c, msg, 1) != 1) {
+ mc_printk(KERN_WARNING, "I2C read failed\n");
+ return -EREMOTEIO;
+ }
+
+ *val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
+
+ return 0;
+}
+
+static int mc44s803_release(struct dvb_frontend *fe)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(priv);
+
+ return 0;
+}
+
+static int mc44s803_init(struct dvb_frontend *fe)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ u32 val;
+ int err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+/* Reset chip */
+ val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_RS);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Power Up and Start Osc */
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+ MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
+ MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
+ MC44S803_REG_SM(0x200, MC44S803_POWER);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ msleep(10);
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+ MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
+ MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ msleep(20);
+
+/* Setup Mixer */
+
+ val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
+ MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup Cirquit Adjust */
+
+ val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_G1) |
+ MC44S803_REG_SM(1, MC44S803_G3) |
+ MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+ MC44S803_REG_SM(1, MC44S803_G6) |
+ MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+ MC44S803_REG_SM(0x3, MC44S803_LP) |
+ MC44S803_REG_SM(1, MC44S803_CLRF) |
+ MC44S803_REG_SM(1, MC44S803_CLIF);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_G1) |
+ MC44S803_REG_SM(1, MC44S803_G3) |
+ MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+ MC44S803_REG_SM(1, MC44S803_G6) |
+ MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+ MC44S803_REG_SM(0x3, MC44S803_LP);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup Digtune */
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(3, MC44S803_XOD);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup AGC */
+
+ val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_AT1) |
+ MC44S803_REG_SM(1, MC44S803_AT2) |
+ MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
+ MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
+ MC44S803_REG_SM(1, MC44S803_LNA0);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ return 0;
+
+exit:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ mc_printk(KERN_WARNING, "I/O Error\n");
+ return err;
+}
+
+static int mc44s803_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ u32 r1, r2, n1, n2, lo1, lo2, freq, val;
+ int err;
+
+ priv->frequency = params->frequency;
+
+ r1 = MC44S803_OSC / 1000000;
+ r2 = MC44S803_OSC / 100000;
+
+ n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000;
+ freq = MC44S803_OSC / r1 * n1;
+ lo1 = ((60 * n1) + (r1 / 2)) / r1;
+ freq = freq - params->frequency;
+
+ n2 = (freq - MC44S803_IF2 + 50000) / 100000;
+ lo2 = ((60 * n2) + (r2 / 2)) / r2;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
+ MC44S803_REG_SM(r1-1, MC44S803_R1) |
+ MC44S803_REG_SM(r2-1, MC44S803_R2) |
+ MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
+ MC44S803_REG_SM(n1-2, MC44S803_LO1);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
+ MC44S803_REG_SM(n2-2, MC44S803_LO2);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_DA) |
+ MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
+ MC44S803_REG_SM(1, MC44S803_AT);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(2, MC44S803_DA) |
+ MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
+ MC44S803_REG_SM(1, MC44S803_AT);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+
+exit:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ mc_printk(KERN_WARNING, "I/O Error\n");
+ return err;
+}
+
+static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ *frequency = priv->frequency;
+ return 0;
+}
+
+static const struct dvb_tuner_ops mc44s803_tuner_ops = {
+ .info = {
+ .name = "Freescale MC44S803",
+ .frequency_min = 48000000,
+ .frequency_max = 1000000000,
+ .frequency_step = 100000,
+ },
+
+ .release = mc44s803_release,
+ .init = mc44s803_init,
+ .set_params = mc44s803_set_params,
+ .get_frequency = mc44s803_get_frequency
+};
+
+/* This functions tries to identify a MC44S803 tuner by reading the ID
+ register. This is hasty. */
+struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+ struct mc44s803_priv *priv;
+ u32 reg;
+ u8 id;
+ int ret;
+
+ reg = 0;
+
+ priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->cfg = cfg;
+ priv->i2c = i2c;
+ priv->fe = fe;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
+ if (ret)
+ goto error;
+
+ id = MC44S803_REG_MS(reg, MC44S803_ID);
+
+ if (id != 0x14) {
+ mc_printk(KERN_ERR, "unsupported ID "
+ "(%x should be 0x14)\n", id);
+ goto error;
+ }
+
+ mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
+ memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ fe->tuner_priv = priv;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return fe;
+
+error:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ kfree(priv);
+ return NULL;
+}
+EXPORT_SYMBOL(mc44s803_attach);
+
+MODULE_AUTHOR("Jochen Friedrich");
+MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mc44s803.h b/drivers/media/common/tuners/mc44s803.h
new file mode 100644
index 000000000000..34f3892d3f6d
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803.h
@@ -0,0 +1,46 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MC44S803_H
+#define MC44S803_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mc44s803_config {
+ u8 i2c_address;
+ u8 dig_out;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
+ (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg);
+#else
+static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
+
+#endif
diff --git a/drivers/media/common/tuners/mc44s803_priv.h b/drivers/media/common/tuners/mc44s803_priv.h
new file mode 100644
index 000000000000..14a92780906d
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803_priv.h
@@ -0,0 +1,208 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MC44S803_PRIV_H
+#define MC44S803_PRIV_H
+
+/* This driver is based on the information available in the datasheet
+ http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
+
+ SPI or I2C Address : 0xc0-0xc6
+
+ Reg.No | Function
+ -------------------------------------------
+ 00 | Power Down
+ 01 | Reference Oszillator
+ 02 | Reference Dividers
+ 03 | Mixer and Reference Buffer
+ 04 | Reset/Serial Out
+ 05 | LO 1
+ 06 | LO 2
+ 07 | Circuit Adjust
+ 08 | Test
+ 09 | Digital Tune
+ 0A | LNA AGC
+ 0B | Data Register Address
+ 0C | Regulator Test
+ 0D | VCO Test
+ 0E | LNA Gain/Input Power
+ 0F | ID Bits
+
+*/
+
+#define MC44S803_OSC 26000000 /* 26 MHz */
+#define MC44S803_IF1 1086000000 /* 1086 MHz */
+#define MC44S803_IF2 36125000 /* 36.125 MHz */
+
+#define MC44S803_REG_POWER 0
+#define MC44S803_REG_REFOSC 1
+#define MC44S803_REG_REFDIV 2
+#define MC44S803_REG_MIXER 3
+#define MC44S803_REG_RESET 4
+#define MC44S803_REG_LO1 5
+#define MC44S803_REG_LO2 6
+#define MC44S803_REG_CIRCADJ 7
+#define MC44S803_REG_TEST 8
+#define MC44S803_REG_DIGTUNE 9
+#define MC44S803_REG_LNAAGC 0x0A
+#define MC44S803_REG_DATAREG 0x0B
+#define MC44S803_REG_REGTEST 0x0C
+#define MC44S803_REG_VCOTEST 0x0D
+#define MC44S803_REG_LNAGAIN 0x0E
+#define MC44S803_REG_ID 0x0F
+
+/* Register definitions */
+#define MC44S803_ADDR 0x0F
+#define MC44S803_ADDR_S 0
+/* REG_POWER */
+#define MC44S803_POWER 0xFFFFF0
+#define MC44S803_POWER_S 4
+/* REG_REFOSC */
+#define MC44S803_REFOSC 0x1FF0
+#define MC44S803_REFOSC_S 4
+#define MC44S803_OSCSEL 0x2000
+#define MC44S803_OSCSEL_S 13
+/* REG_REFDIV */
+#define MC44S803_R2 0x1FF0
+#define MC44S803_R2_S 4
+#define MC44S803_REFBUF_EN 0x2000
+#define MC44S803_REFBUF_EN_S 13
+#define MC44S803_R1 0x7C000
+#define MC44S803_R1_S 14
+/* REG_MIXER */
+#define MC44S803_R3 0x70
+#define MC44S803_R3_S 4
+#define MC44S803_MUX3 0x80
+#define MC44S803_MUX3_S 7
+#define MC44S803_MUX4 0x100
+#define MC44S803_MUX4_S 8
+#define MC44S803_OSC_SCR 0x200
+#define MC44S803_OSC_SCR_S 9
+#define MC44S803_TRI_STATE 0x400
+#define MC44S803_TRI_STATE_S 10
+#define MC44S803_BUF_GAIN 0x800
+#define MC44S803_BUF_GAIN_S 11
+#define MC44S803_BUF_IO 0x1000
+#define MC44S803_BUF_IO_S 12
+#define MC44S803_MIXER_RES 0xFE000
+#define MC44S803_MIXER_RES_S 13
+/* REG_RESET */
+#define MC44S803_RS 0x10
+#define MC44S803_RS_S 4
+#define MC44S803_SO 0x20
+#define MC44S803_SO_S 5
+/* REG_LO1 */
+#define MC44S803_LO1 0xFFF0
+#define MC44S803_LO1_S 4
+/* REG_LO2 */
+#define MC44S803_LO2 0x7FFF0
+#define MC44S803_LO2_S 4
+/* REG_CIRCADJ */
+#define MC44S803_G1 0x20
+#define MC44S803_G1_S 5
+#define MC44S803_G3 0x80
+#define MC44S803_G3_S 7
+#define MC44S803_CIRCADJ_RES 0x300
+#define MC44S803_CIRCADJ_RES_S 8
+#define MC44S803_G6 0x400
+#define MC44S803_G6_S 10
+#define MC44S803_G7 0x800
+#define MC44S803_G7_S 11
+#define MC44S803_S1 0x1000
+#define MC44S803_S1_S 12
+#define MC44S803_LP 0x7E000
+#define MC44S803_LP_S 13
+#define MC44S803_CLRF 0x80000
+#define MC44S803_CLRF_S 19
+#define MC44S803_CLIF 0x100000
+#define MC44S803_CLIF_S 20
+/* REG_TEST */
+/* REG_DIGTUNE */
+#define MC44S803_DA 0xF0
+#define MC44S803_DA_S 4
+#define MC44S803_XOD 0x300
+#define MC44S803_XOD_S 8
+#define MC44S803_RST 0x10000
+#define MC44S803_RST_S 16
+#define MC44S803_LO_REF 0x1FFF00
+#define MC44S803_LO_REF_S 8
+#define MC44S803_AT 0x200000
+#define MC44S803_AT_S 21
+#define MC44S803_MT 0x400000
+#define MC44S803_MT_S 22
+/* REG_LNAAGC */
+#define MC44S803_G 0x3F0
+#define MC44S803_G_S 4
+#define MC44S803_AT1 0x400
+#define MC44S803_AT1_S 10
+#define MC44S803_AT2 0x800
+#define MC44S803_AT2_S 11
+#define MC44S803_HL_GR_EN 0x8000
+#define MC44S803_HL_GR_EN_S 15
+#define MC44S803_AGC_AN_DIG 0x10000
+#define MC44S803_AGC_AN_DIG_S 16
+#define MC44S803_ATTEN_EN 0x20000
+#define MC44S803_ATTEN_EN_S 17
+#define MC44S803_AGC_READ_EN 0x40000
+#define MC44S803_AGC_READ_EN_S 18
+#define MC44S803_LNA0 0x80000
+#define MC44S803_LNA0_S 19
+#define MC44S803_AGC_SEL 0x100000
+#define MC44S803_AGC_SEL_S 20
+#define MC44S803_AT0 0x200000
+#define MC44S803_AT0_S 21
+#define MC44S803_B 0xC00000
+#define MC44S803_B_S 22
+/* REG_DATAREG */
+#define MC44S803_D 0xF0
+#define MC44S803_D_S 4
+/* REG_REGTEST */
+/* REG_VCOTEST */
+/* REG_LNAGAIN */
+#define MC44S803_IF_PWR 0x700
+#define MC44S803_IF_PWR_S 8
+#define MC44S803_RF_PWR 0x3800
+#define MC44S803_RF_PWR_S 11
+#define MC44S803_LNA_GAIN 0xFC000
+#define MC44S803_LNA_GAIN_S 14
+/* REG_ID */
+#define MC44S803_ID 0x3E00
+#define MC44S803_ID_S 9
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define MC44S803_REG_SM(_val, _reg) \
+ (((_val) << _reg##_S) & (_reg))
+
+/* First mask, then shift */
+#define MC44S803_REG_MS(_val, _reg) \
+ (((_val) & (_reg)) >> _reg##_S)
+
+struct mc44s803_priv {
+ struct mc44s803_config *cfg;
+ struct i2c_adapter *i2c;
+ struct dvb_frontend *fe;
+
+ u32 frequency;
+};
+
+#endif
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c
index 12206d75dd4e..c7abe3d8f90e 100644
--- a/drivers/media/common/tuners/mt2060.c
+++ b/drivers/media/common/tuners/mt2060.c
@@ -278,7 +278,7 @@ static void mt2060_calibrate(struct mt2060_priv *priv)
while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
msleep(20);
- if (i < 10) {
+ if (i <= 10) {
mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
dprintk("calibration was successful: %d", (int)priv->fmfreq);
} else
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 64379f2bf237..3ec28945c26f 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -657,7 +657,7 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
{
struct mxl5007t_state *state = fe->tuner_priv;
int rf_locked, ref_locked;
- s32 rf_input_level;
+ s32 rf_input_level = 0;
int ret;
if (fe->ops.i2c_gate_ctrl)
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c
index f4d931f14fad..8cd55a83b381 100644
--- a/drivers/media/common/tuners/tda827x.c
+++ b/drivers/media/common/tuners/tda827x.c
@@ -132,11 +132,31 @@ static const struct tda827x_data tda827x_table[] = {
{ .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
};
+static int tuner_transfer(struct dvb_frontend *fe,
+ struct i2c_msg *msg,
+ const int size)
+{
+ int rc;
+ struct tda827x_priv *priv = fe->tuner_priv;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ rc = i2c_transfer(priv->i2c_adap, msg, size);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (rc >= 0 && rc != size)
+ return -EIO;
+
+ return rc;
+}
+
static int tda827xo_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct tda827x_priv *priv = fe->tuner_priv;
u8 buf[14];
+ int rc;
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
@@ -183,27 +203,29 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
buf[13] = 0x40;
msg.len = 14;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
+
msleep(500);
/* correct CP value */
buf[0] = 0x30;
buf[1] = 0x50 + tda827x_table[i].cp;
msg.len = 2;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
priv->frequency = params->frequency;
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
return 0;
+
+err:
+ printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+ __func__, priv->i2c_addr << 1);
+ return rc;
}
static int tda827xo_sleep(struct dvb_frontend *fe)
@@ -214,9 +236,7 @@ static int tda827xo_sleep(struct dvb_frontend *fe)
.buf = buf, .len = sizeof(buf) };
dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
if (priv->cfg && priv->cfg->sleep)
priv->cfg->sleep(fe);
@@ -266,44 +286,44 @@ static int tda827xo_set_analog_params(struct dvb_frontend *fe,
msg.buf = tuner_reg;
msg.len = 8;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.buf = reg2;
msg.len = 2;
reg2[0] = 0x80;
reg2[1] = 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x60;
reg2[1] = 0xbf;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4] + 0x80;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4] + 4;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4];
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(550);
reg2[0] = 0x30;
reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x60;
reg2[1] = 0x3f;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x80;
reg2[1] = 0x08; /* Vsync en */
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
priv->frequency = params->frequency;
@@ -317,7 +337,7 @@ static void tda827xo_agcf(struct dvb_frontend *fe)
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = data, .len = 2};
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
}
/* ------------------------------------------------------------------ */
@@ -398,13 +418,8 @@ static int tda827xa_sleep(struct dvb_frontend *fe)
.buf = buf, .len = sizeof(buf) };
dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
+ tuner_transfer(fe, &msg, 1);
if (priv->cfg && priv->cfg->sleep)
priv->cfg->sleep(fe);
@@ -455,7 +470,7 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
buf[1] = high ? 0 : 1;
if (priv->cfg->config == 2)
buf[1] = high ? 1 : 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
break;
case 3: /* switch with GPIO of saa713x */
if (fe->callback)
@@ -474,7 +489,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
- int i, tuner_freq, if_freq;
+ int i, tuner_freq, if_freq, rc;
u32 N;
dprintk("%s:\n", __func__);
@@ -516,35 +531,32 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
buf[9] = 0x24;
buf[10] = 0x00;
msg.len = 11;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
+
buf[0] = 0x90;
buf[1] = 0xff;
buf[2] = 0x60;
buf[3] = 0x00;
buf[4] = 0x59; // lpsel, for 6MHz + 2
msg.len = 5;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
buf[0] = 0xa0;
buf[1] = 0x40;
msg.len = 2;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(11);
msg.flags = I2C_M_RD;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msg.flags = 0;
buf[1] >>= 4;
@@ -553,49 +565,55 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
tda827xa_lna_gain(fe, 0, NULL);
buf[0] = 0x60;
buf[1] = 0x0c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
}
buf[0] = 0xc0;
buf[1] = 0x99; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
buf[0] = 0x60;
buf[1] = 0x3c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
/* correct CP value */
buf[0] = 0x30;
buf[1] = 0x10 + tda827xa_dvbt[i].scr;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(163);
buf[0] = 0xc0;
buf[1] = 0x39; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(3);
/* freeze AGC1 */
buf[0] = 0x50;
buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
priv->frequency = params->frequency;
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+
return 0;
+
+err:
+ printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+ __func__, priv->i2c_addr << 1);
+ return rc;
}
@@ -643,7 +661,7 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
tuner_reg[9] = 0x20;
tuner_reg[10] = 0x00;
msg.len = 11;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x90;
tuner_reg[1] = 0xff;
@@ -651,19 +669,19 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
tuner_reg[3] = 0;
tuner_reg[4] = 0x99 + (priv->lpsel << 1);
msg.len = 5;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xa0;
tuner_reg[1] = 0xc0;
msg.len = 2;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x30;
tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.flags = I2C_M_RD;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.flags = 0;
tuner_reg[1] >>= 4;
dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
@@ -673,24 +691,24 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
msleep(100);
tuner_reg[0] = 0x60;
tuner_reg[1] = 0x3c;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(163);
tuner_reg[0] = 0x50;
tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x80;
tuner_reg[1] = 0x28;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xb0;
tuner_reg[1] = 0x01;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xc0;
tuner_reg[1] = 0x19 + (priv->lpsel << 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
priv->frequency = params->frequency;
@@ -703,7 +721,7 @@ static void tda827xa_agcf(struct dvb_frontend *fe)
unsigned char data[] = {0x80, 0x2c};
struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
.buf = data, .len = 2};
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
}
/* ------------------------------------------------------------------ */
@@ -792,16 +810,19 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = {
};
static int tda827x_probe_version(struct dvb_frontend *fe)
-{ u8 data;
+{
+ u8 data;
+ int rc;
struct tda827x_priv *priv = fe->tuner_priv;
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
.buf = &data, .len = 1 };
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
+
+ rc = tuner_transfer(fe, &msg, 1);
+
+ if (rc < 0) {
printk("%s: could not read from tuner at addr: 0x%02x\n",
__func__, msg.addr << 1);
- return -EIO;
+ return rc;
}
if ((data & 0x3c) == 0) {
dprintk("tda827x tuner found\n");
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 4b8662edb7cb..39697fa59256 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -566,8 +566,11 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
u8 data;
struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
- if (NULL == analog_ops->i2c_gate_ctrl)
+ if (!analog_ops->i2c_gate_ctrl) {
+ printk(KERN_ERR "tda8290: no gate control were provided!\n");
+
return -EINVAL;
+ }
analog_ops->i2c_gate_ctrl(fe, 1);
@@ -615,6 +618,7 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
if (ret != 1) {
tuner_warn("tuner access failed!\n");
+ analog_ops->i2c_gate_ctrl(fe, 0);
return -EREMOTEIO;
}
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index de7adaf5fa5b..78412c9c424a 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -318,7 +318,6 @@ static int simple_std_setup(struct dvb_frontend *fe,
u8 *config, u8 *cb)
{
struct tuner_simple_priv *priv = fe->tuner_priv;
- u8 tuneraddr;
int rc;
/* tv norm specific stuff for multi-norm tuners */
@@ -387,6 +386,7 @@ static int simple_std_setup(struct dvb_frontend *fe,
case TUNER_PHILIPS_TUV1236D:
{
+ struct tuner_i2c_props i2c = priv->i2c_props;
/* 0x40 -> ATSC antenna input 1 */
/* 0x48 -> ATSC antenna input 2 */
/* 0x00 -> NTSC antenna input 1 */
@@ -398,17 +398,15 @@ static int simple_std_setup(struct dvb_frontend *fe,
buffer[1] = 0x04;
}
/* set to the correct mode (analog or digital) */
- tuneraddr = priv->i2c_props.addr;
- priv->i2c_props.addr = 0x0a;
- rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2);
+ i2c.addr = 0x0a;
+ rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d "
"(should be 2)\n", rc);
- rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2);
+ rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2);
if (2 != rc)
tuner_warn("i2c i/o error: rc == %d "
"(should be 2)\n", rc);
- priv->i2c_props.addr = tuneraddr;
break;
}
}
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 40ebde53b3ce..b0198691892a 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -51,6 +51,10 @@ comment "Supported SDMC DM1105 Adapters"
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/dm1105/Kconfig"
+comment "Supported FireWire (IEEE 1394) Adapters"
+ depends on DVB_CORE && IEEE1394
+source "drivers/media/dvb/firewire/Kconfig"
+
comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index f91e9eb15e52..6092a5bb5a7d 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -3,3 +3,5 @@
#
obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
+
+obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 0258451423ad..6c68f02c1709 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -682,7 +682,7 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t
return 0;
}
-static struct file_operations dst_ca_fops = {
+static const struct file_operations dst_ca_fops = {
.owner = THIS_MODULE,
.ioctl = dst_ca_ioctl,
.open = dst_ca_open,
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 0c733c66a441..c35fbb8d8f4a 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -364,16 +364,15 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
enum dmx_success success)
{
struct dmxdev_filter *dmxdevfilter = filter->priv;
- unsigned long flags;
int ret;
if (dmxdevfilter->buffer.error) {
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
- spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ spin_lock(&dmxdevfilter->dev->lock);
if (dmxdevfilter->state != DMXDEV_STATE_GO) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
return 0;
}
del_timer(&dmxdevfilter->timer);
@@ -392,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
}
if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
dmxdevfilter->state = DMXDEV_STATE_DONE;
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
@@ -404,12 +403,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
- unsigned long flags;
int ret;
- spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+ spin_lock(&dmxdevfilter->dev->lock);
if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
return 0;
}
@@ -419,7 +417,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
else
buffer = &dmxdevfilter->dev->dvr_buffer;
if (buffer->error) {
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
}
@@ -430,7 +428,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
dvb_ringbuffer_flush(buffer);
buffer->error = ret;
}
- spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
}
@@ -1026,7 +1024,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_demux_fops = {
+static const struct file_operations dvb_demux_fops = {
.owner = THIS_MODULE,
.read = dvb_demux_read,
.ioctl = dvb_demux_ioctl,
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 98ee16773ff2..cb22da53bfb0 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -93,6 +93,9 @@ struct dvb_ca_slot {
/* current state of the CAM */
int slot_state;
+ /* mutex used for serializing access to one CI slot */
+ struct mutex slot_lock;
+
/* Number of CAMCHANGES that have occurred since last processing */
atomic_t camchange_count;
@@ -711,14 +714,20 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
dprintk("%s\n", __func__);
- // sanity check
+ /* sanity check */
if (bytes_write > ca->slot_info[slot].link_buf_size)
return -EINVAL;
- /* check if interface is actually waiting for us to read from it, or if a read is in progress */
+ /* it is possible we are dealing with a single buffer implementation,
+ thus if there is data available for read or if there is even a read
+ already in progress, we do nothing but awake the kernel thread to
+ process the data if necessary. */
if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
goto exitnowrite;
if (status & (STATUSREG_DA | STATUSREG_RE)) {
+ if (status & STATUSREG_DA)
+ dvb_ca_en50221_thread_wakeup(ca);
+
status = -EAGAIN;
goto exitnowrite;
}
@@ -987,6 +996,8 @@ static int dvb_ca_en50221_thread(void *data)
/* go through all the slots processing them */
for (slot = 0; slot < ca->slot_count; slot++) {
+ mutex_lock(&ca->slot_info[slot].slot_lock);
+
// check the cam status + deal with CAMCHANGEs
while (dvb_ca_en50221_check_camstatus(ca, slot)) {
/* clear down an old CI slot if necessary */
@@ -1122,7 +1133,7 @@ static int dvb_ca_en50221_thread(void *data)
case DVB_CA_SLOTSTATE_RUNNING:
if (!ca->open)
- continue;
+ break;
// poll slots for data
pktcount = 0;
@@ -1146,6 +1157,8 @@ static int dvb_ca_en50221_thread(void *data)
}
break;
}
+
+ mutex_unlock(&ca->slot_info[slot].slot_lock);
}
}
@@ -1181,6 +1194,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case CA_RESET:
for (slot = 0; slot < ca->slot_count; slot++) {
+ mutex_lock(&ca->slot_info[slot].slot_lock);
if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) {
dvb_ca_en50221_slot_shutdown(ca, slot);
if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)
@@ -1188,6 +1202,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file,
slot,
DVB_CA_EN50221_CAMCHANGE_INSERTED);
}
+ mutex_unlock(&ca->slot_info[slot].slot_lock);
}
ca->next_read_slot = 0;
dvb_ca_en50221_thread_wakeup(ca);
@@ -1308,7 +1323,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
goto exit;
}
+ mutex_lock(&ca->slot_info[slot].slot_lock);
status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2);
+ mutex_unlock(&ca->slot_info[slot].slot_lock);
if (status == (fraglen + 2)) {
written = 1;
break;
@@ -1590,7 +1607,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
EXPORT_SYMBOL(dvb_ca_en50221_init);
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_en50221_io_read,
.write = dvb_ca_en50221_io_write,
@@ -1664,6 +1681,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
atomic_set(&ca->slot_info[i].camchange_count, 0);
ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
+ mutex_init(&ca->slot_info[i].slot_lock);
}
if (signal_pending(current)) {
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
index 8467e63ddc0d..7df2e141187a 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h
@@ -45,8 +45,10 @@ struct dvb_ca_en50221 {
/* the module owning this structure */
struct module* owner;
- /* NOTE: the read_*, write_* and poll_slot_status functions must use locks as
- * they may be called from several threads at once */
+ /* NOTE: the read_*, write_* and poll_slot_status functions will be
+ * called for different slots concurrently and need to use locks where
+ * and if appropriate. There will be no concurrent access to one slot.
+ */
/* functions for accessing attribute memory on the CAM */
int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index a2c1fd5d2f67..e2eca0b1fe7c 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -399,9 +399,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count)
{
- unsigned long flags;
-
- spin_lock_irqsave(&demux->lock, flags);
+ spin_lock(&demux->lock);
while (count--) {
if (buf[0] == 0x47)
@@ -409,17 +407,16 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
buf += 188;
}
- spin_unlock_irqrestore(&demux->lock, flags);
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- unsigned long flags;
int p = 0, i, j;
- spin_lock_irqsave(&demux->lock, flags);
+ spin_lock(&demux->lock);
if (demux->tsbufp) {
i = demux->tsbufp;
@@ -452,18 +449,17 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
}
bailout:
- spin_unlock_irqrestore(&demux->lock, flags);
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- unsigned long flags;
int p = 0, i, j;
u8 tmppack[188];
- spin_lock_irqsave(&demux->lock, flags);
+ spin_lock(&demux->lock);
if (demux->tsbufp) {
i = demux->tsbufp;
@@ -504,7 +500,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
}
bailout:
- spin_unlock_irqrestore(&demux->lock, flags);
+ spin_unlock(&demux->lock);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_204);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 843407785083..d5ee89d7f374 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1874,7 +1874,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_frontend_fops = {
+static const struct file_operations dvb_frontend_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.poll = dvb_frontend_poll,
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index f6ba8468858e..8280f8d66a38 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1459,7 +1459,7 @@ static int dvb_net_close(struct inode *inode, struct file *file)
}
-static struct file_operations dvb_net_fops = {
+static const struct file_operations dvb_net_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 6a32680dbb1b..a454ee8f1e43 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -228,8 +228,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->fops = dvbdevfops;
init_waitqueue_head (&dvbdev->wait_queue);
- memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
- dvbdev->fops->owner = adap->module;
+ memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
+ dvbdevfops->owner = adap->module;
list_add_tail (&dvbdev->list_head, &adap->device_list);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index dca49cf962e8..79927305e84d 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -71,7 +71,7 @@ struct dvb_adapter {
struct dvb_device {
struct list_head list_head;
- struct file_operations *fops;
+ const struct file_operations *fops;
struct dvb_adapter *adapter;
int type;
int minor;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 49f7b20c25d6..bbddc9fb6b64 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -297,5 +297,6 @@ config DVB_USB_AF9015
select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c
index b1a9c4cdec93..199ece0d4883 100644
--- a/drivers/media/dvb/dvb-usb/af9005-fe.c
+++ b/drivers/media/dvb/dvb-usb/af9005-fe.c
@@ -220,7 +220,7 @@ static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
u16 * abort_count)
{
u32 loc_cw_count = 0, loc_err_count;
- u16 loc_abort_count;
+ u16 loc_abort_count = 0;
int ret;
ret =
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index e1e9aa5c6b84..f0ba8b07b84f 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -27,9 +27,7 @@
#include "qt1010.h"
#include "tda18271.h"
#include "mxl5005s.h"
-#if 0
-#include "mc44s80x.h"
-#endif
+#include "mc44s803.h"
static int dvb_usb_af9015_debug;
module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -37,9 +35,6 @@ MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
static int dvb_usb_af9015_remote;
module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
MODULE_PARM_DESC(remote, "select remote");
-static int dvb_usb_af9015_dual_mode;
-module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644);
-MODULE_PARM_DESC(dual_mode, "enable dual mode");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static DEFINE_MUTEX(af9015_usb_mutex);
@@ -283,6 +278,21 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate.
req.data = &msg[i+1].buf[0];
ret = af9015_ctrl_msg(d, &req);
i += 2;
+ } else if (msg[i].flags & I2C_M_RD) {
+ ret = -EINVAL;
+ if (msg[i].addr ==
+ af9015_af9013_config[0].demod_address)
+ goto error;
+ else
+ req.cmd = READ_I2C;
+ req.i2c_addr = msg[i].addr;
+ req.addr = addr;
+ req.mbox = mbox;
+ req.addr_len = addr_len;
+ req.data_len = msg[i].len;
+ req.data = &msg[i].buf[0];
+ ret = af9015_ctrl_msg(d, &req);
+ i += 1;
} else {
if (msg[i].addr ==
af9015_af9013_config[0].demod_address)
@@ -694,7 +704,12 @@ static int af9015_read_config(struct usb_device *udev)
/* IR remote controller */
req.addr = AF9015_EEPROM_IR_MODE;
- ret = af9015_rw_udev(udev, &req);
+ /* first message will timeout often due to possible hw bug */
+ for (i = 0; i < 4; i++) {
+ ret = af9015_rw_udev(udev, &req);
+ if (!ret)
+ break;
+ }
if (ret)
goto error;
deb_info("%s: IR mode:%d\n", __func__, val);
@@ -743,6 +758,16 @@ static int af9015_read_config(struct usb_device *udev)
af9015_config.ir_table_size =
ARRAY_SIZE(af9015_ir_table_digittrade);
break;
+ case AF9015_REMOTE_AVERMEDIA_KS:
+ af9015_properties[i].rc_key_map =
+ af9015_rc_keys_avermedia;
+ af9015_properties[i].rc_key_map_size =
+ ARRAY_SIZE(af9015_rc_keys_avermedia);
+ af9015_config.ir_table =
+ af9015_ir_table_avermedia_ks;
+ af9015_config.ir_table_size =
+ ARRAY_SIZE(af9015_ir_table_avermedia_ks);
+ break;
}
} else {
switch (le16_to_cpu(udev->descriptor.idVendor)) {
@@ -831,22 +856,20 @@ static int af9015_read_config(struct usb_device *udev)
goto error;
af9015_config.dual_mode = val;
deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
- /* disable dual mode by default because it is buggy */
- if (!dvb_usb_af9015_dual_mode)
- af9015_config.dual_mode = 0;
- /* set buffer size according to USB port speed */
+ /* Set adapter0 buffer size according to USB port speed, adapter1 buffer
+ size can be static because it is enabled only USB2.0 */
for (i = 0; i < af9015_properties_count; i++) {
/* USB1.1 set smaller buffersize and disable 2nd adapter */
if (udev->speed == USB_SPEED_FULL) {
- af9015_properties[i].adapter->stream.u.bulk.buffersize =
- TS_USB11_MAX_PACKET_SIZE;
+ af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+ = TS_USB11_MAX_PACKET_SIZE;
/* disable 2nd adapter because we don't have
PID-filters */
af9015_config.dual_mode = 0;
} else {
- af9015_properties[i].adapter->stream.u.bulk.buffersize =
- TS_USB20_MAX_PACKET_SIZE;
+ af9015_properties[i].adapter[0].stream.u.bulk.buffersize
+ = TS_USB20_MAX_PACKET_SIZE;
}
}
@@ -929,7 +952,6 @@ static int af9015_read_config(struct usb_device *udev)
switch (val) {
case AF9013_TUNER_ENV77H11D5:
case AF9013_TUNER_MT2060:
- case AF9013_TUNER_MC44S803:
case AF9013_TUNER_QT1010:
case AF9013_TUNER_UNKNOWN:
case AF9013_TUNER_MT2060_2:
@@ -942,6 +964,10 @@ static int af9015_read_config(struct usb_device *udev)
case AF9013_TUNER_MXL5005R:
af9015_af9013_config[i].rf_spec_inv = 0;
break;
+ case AF9013_TUNER_MC44S803:
+ af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+ af9015_af9013_config[i].rf_spec_inv = 1;
+ break;
default:
warn("tuner id:%d not supported, please report!", val);
return -ENODEV;
@@ -1129,6 +1155,11 @@ static struct mxl5005s_config af9015_mxl5005_config = {
.AgcMasterByte = 0x00,
};
+static struct mc44s803_config af9015_mc44s803_config = {
+ .i2c_address = 0xc0,
+ .dig_out = 1,
+};
+
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
{
struct af9015_state *state = adap->dev->priv;
@@ -1173,15 +1204,8 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_MC44S803:
-#if 0
- ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap)
- == NULL ? -ENODEV : 0;
-#else
- ret = -ENODEV;
- info("Freescale MC44S803 tuner found but no driver for that" \
- "tuner. Look at the Linuxtv.org for tuner driver" \
- "status.");
-#endif
+ ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
+ &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_UNKNOWN:
default:
@@ -1212,6 +1236,7 @@ static struct usb_device_id af9015_usb_table[] = {
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
+ {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1254,6 +1279,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x85,
+ .u = {
+ .bulk = {
+ .buffersize =
+ TS_USB20_MAX_PACKET_SIZE,
+ }
+ }
},
}
},
@@ -1353,6 +1384,12 @@ static struct dvb_usb_device_properties af9015_properties[] = {
.type = USB_BULK,
.count = 6,
.endpoint = 0x85,
+ .u = {
+ .bulk = {
+ .buffersize =
+ TS_USB20_MAX_PACKET_SIZE,
+ }
+ }
},
}
},
@@ -1399,7 +1436,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
{
.name = "KWorld USB DVB-T TV Stick II " \
"(VS-DVB-T 395U)",
- .cold_ids = {&af9015_usb_table[16], NULL},
+ .cold_ids = {&af9015_usb_table[16],
+ &af9015_usb_table[17], NULL},
.warm_ids = {NULL},
},
}
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 21c7782f4889..00e25714662a 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -124,6 +124,7 @@ enum af9015_remote {
AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
AF9015_REMOTE_MYGICTV_U718,
AF9015_REMOTE_DIGITTRADE_DVB_T,
+ AF9015_REMOTE_AVERMEDIA_KS,
};
/* Leadtek WinFast DTV Dongle Gold */
@@ -597,6 +598,36 @@ static u8 af9015_ir_table_avermedia[] = {
0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
};
+static u8 af9015_ir_table_avermedia_ks[] = {
+ 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00,
+ 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00,
+ 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00,
+ 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00,
+ 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00,
+ 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00,
+ 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00,
+ 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00,
+ 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00,
+ 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00,
+ 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00,
+ 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00,
+ 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00,
+ 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00,
+ 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00,
+ 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00,
+ 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00,
+ 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00,
+ 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00,
+ 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00,
+ 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00,
+ 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00,
+ 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00,
+ 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00,
+ 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00,
+ 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00,
+ 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00
+};
+
/* Digittrade DVB-T USB Stick */
static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
{ 0x01, 0x0f, KEY_LAST }, /* RETURN */
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 200b215f4d8b..db7f7f79a66c 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -158,6 +158,10 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
err("i2c read error (status = %d)\n", result);
break;
}
+
+ deb_data("<<< ");
+ debug_dump(msg[i].buf, msg[i].len, deb_data);
+
} else {
/* Write request */
buf[0] = REQUEST_NEW_I2C_WRITE;
@@ -169,6 +173,9 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
/* The Actual i2c payload */
memcpy(&buf[4], msg[i].buf, msg[i].len);
+ deb_data(">>> ");
+ debug_dump(buf, msg[i].len + 4, deb_data);
+
result = usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev, 0),
REQUEST_NEW_I2C_WRITE,
@@ -211,7 +218,8 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
/* special thing in the current firmware: when length is zero the read-failed */
if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) {
- deb_info("I2C read failed on address %x\n", msg[i].addr);
+ deb_info("I2C read failed on address 0x%02x\n",
+ msg[i].addr);
break;
}
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 391732788911..f291fb55f1be 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -262,7 +262,12 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -284,7 +289,12 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -421,8 +431,12 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
msleep(10);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &stk7700ph_dib7700_xc3028_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &stk7700ph_dib7700_xc3028_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&stk7700ph_dib7700_xc3028_config);
@@ -1187,8 +1201,12 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &dib7070p_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &dib7070p_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&dib7070p_dib7000p_config);
@@ -1244,7 +1262,12 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7070pd_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
return adap->fe == NULL ? -ENODEV : 0;
@@ -1393,6 +1416,9 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
+ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
+ { USB_DEVICE(USB_VID_TERRATEC,
+ USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1537,7 +1563,8 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "DiBcom STK7700D reference design",
{ &dib0700_usb_id_table[14], NULL },
{ NULL },
- }
+ },
+
},
.rc_interval = DEFAULT_RC_INTERVAL,
@@ -1557,7 +1584,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 2,
+ .num_device_descs = 3,
.devices = {
{ "ASUS My Cinema U3000 Mini DVBT Tuner",
{ &dib0700_usb_id_table[23], NULL },
@@ -1566,6 +1593,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Yuan EC372S",
{ &dib0700_usb_id_table[31], NULL },
{ NULL },
+ },
+ { "Terratec Cinergy T Express",
+ { &dib0700_usb_id_table[42], NULL },
+ { NULL },
}
},
@@ -1653,7 +1684,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}
},
- .num_device_descs = 4,
+ .num_device_descs = 5,
.devices = {
{ "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL },
@@ -1670,8 +1701,16 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Hauppauge Nova-TD-500 (84xxx)",
{ &dib0700_usb_id_table[36], NULL },
{ NULL },
+ },
+ { "Terratec Cinergy DT USB XS Diversity",
+ { &dib0700_usb_id_table[43], NULL },
+ { NULL },
}
- }
+ },
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index a4fca3fca5ee..4ab5ec9a0de0 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -97,6 +97,7 @@
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_395U 0xe396
+#define USB_PID_KWORLD_395U_2 0xe39b
#define USB_PID_KWORLD_PC160_2T 0xc160
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
@@ -162,8 +163,10 @@
#define USB_PID_AVERMEDIA_A309 0xa309
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
+#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
+#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
#define USB_PID_PINNACLE_PCTV2000E 0x022c
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig
new file mode 100644
index 000000000000..69028253e984
--- /dev/null
+++ b/drivers/media/dvb/firewire/Kconfig
@@ -0,0 +1,22 @@
+config DVB_FIREDTV
+ tristate "FireDTV and FloppyDTV"
+ depends on DVB_CORE && IEEE1394
+ help
+ Support for DVB receivers from Digital Everywhere
+ which are connected via IEEE 1394 (FireWire).
+
+ These devices don't have an MPEG decoder built in,
+ so you need an external software decoder to watch TV.
+
+ To compile this driver as a module, say M here:
+ the module will be called firedtv.
+
+if DVB_FIREDTV
+
+config DVB_FIREDTV_IEEE1394
+ def_bool IEEE1394
+
+config DVB_FIREDTV_INPUT
+ def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
+
+endif # DVB_FIREDTV
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile
new file mode 100644
index 000000000000..2034695ba194
--- /dev/null
+++ b/drivers/media/dvb/firewire/Makefile
@@ -0,0 +1,8 @@
+obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
+
+firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o
+firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
+firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
+
+ccflags-y += -Idrivers/media/dvb/dvb-core
+ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
new file mode 100644
index 000000000000..4e207658c5d9
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-1394.c
@@ -0,0 +1,285 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <dma.h>
+#include <csr1212.h>
+#include <highlevel.h>
+#include <hosts.h>
+#include <ieee1394.h>
+#include <iso.h>
+#include <nodemgr.h>
+
+#include "firedtv.h"
+
+static LIST_HEAD(node_list);
+static DEFINE_SPINLOCK(node_list_lock);
+
+#define FIREWIRE_HEADER_SIZE 4
+#define CIP_HEADER_SIZE 8
+
+static void rawiso_activity_cb(struct hpsb_iso *iso)
+{
+ struct firedtv *f, *fdtv = NULL;
+ unsigned int i, num, packet;
+ unsigned char *buf;
+ unsigned long flags;
+ int count;
+
+ spin_lock_irqsave(&node_list_lock, flags);
+ list_for_each_entry(f, &node_list, list)
+ if (f->backend_data == iso) {
+ fdtv = f;
+ break;
+ }
+ spin_unlock_irqrestore(&node_list_lock, flags);
+
+ packet = iso->first_packet;
+ num = hpsb_iso_n_ready(iso);
+
+ if (!fdtv) {
+ dev_err(fdtv->device, "received at unknown iso channel\n");
+ goto out;
+ }
+
+ for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
+ buf = dma_region_i(&iso->data_buf, unsigned char,
+ iso->infos[packet].offset + CIP_HEADER_SIZE);
+ count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
+ (188 + FIREWIRE_HEADER_SIZE);
+
+ /* ignore empty packet */
+ if (iso->infos[packet].len <= CIP_HEADER_SIZE)
+ continue;
+
+ while (count--) {
+ if (buf[FIREWIRE_HEADER_SIZE] == 0x47)
+ dvb_dmx_swfilter_packets(&fdtv->demux,
+ &buf[FIREWIRE_HEADER_SIZE], 1);
+ else
+ dev_err(fdtv->device,
+ "skipping invalid packet\n");
+ buf += 188 + FIREWIRE_HEADER_SIZE;
+ }
+ }
+out:
+ hpsb_iso_recv_release_packets(iso, num);
+}
+
+static inline struct node_entry *node_of(struct firedtv *fdtv)
+{
+ return container_of(fdtv->device, struct unit_directory, device)->ne;
+}
+
+static int node_lock(struct firedtv *fdtv, u64 addr, void *data, __be32 arg)
+{
+ return hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, data,
+ (__force quadlet_t)arg);
+}
+
+static int node_read(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+ return hpsb_node_read(node_of(fdtv), addr, data, len);
+}
+
+static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
+{
+ return hpsb_node_write(node_of(fdtv), addr, data, len);
+}
+
+#define FDTV_ISO_BUFFER_PACKETS 256
+#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200)
+
+static int start_iso(struct firedtv *fdtv)
+{
+ struct hpsb_iso *iso_handle;
+ int ret;
+
+ iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host,
+ FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS,
+ fdtv->isochannel, HPSB_ISO_DMA_DEFAULT,
+ -1, /* stat.config.irq_interval */
+ rawiso_activity_cb);
+ if (iso_handle == NULL) {
+ dev_err(fdtv->device, "cannot initialize iso receive\n");
+ return -ENOMEM;
+ }
+ fdtv->backend_data = iso_handle;
+
+ ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0);
+ if (ret != 0) {
+ dev_err(fdtv->device, "cannot start iso receive\n");
+ hpsb_iso_shutdown(iso_handle);
+ fdtv->backend_data = NULL;
+ }
+ return ret;
+}
+
+static void stop_iso(struct firedtv *fdtv)
+{
+ struct hpsb_iso *iso_handle = fdtv->backend_data;
+
+ if (iso_handle != NULL) {
+ hpsb_iso_stop(iso_handle);
+ hpsb_iso_shutdown(iso_handle);
+ }
+ fdtv->backend_data = NULL;
+}
+
+static const struct firedtv_backend fdtv_1394_backend = {
+ .lock = node_lock,
+ .read = node_read,
+ .write = node_write,
+ .start_iso = start_iso,
+ .stop_iso = stop_iso,
+};
+
+static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
+ int cts, u8 *data, size_t length)
+{
+ struct firedtv *f, *fdtv = NULL;
+ unsigned long flags;
+ int su;
+
+ if (length == 0 || (data[0] & 0xf0) != 0)
+ return;
+
+ su = data[1] & 0x7;
+
+ spin_lock_irqsave(&node_list_lock, flags);
+ list_for_each_entry(f, &node_list, list)
+ if (node_of(f)->host == host &&
+ node_of(f)->nodeid == nodeid &&
+ (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
+ fdtv = f;
+ break;
+ }
+ spin_unlock_irqrestore(&node_list_lock, flags);
+
+ if (fdtv)
+ avc_recv(fdtv, data, length);
+}
+
+static int node_probe(struct device *dev)
+{
+ struct unit_directory *ud =
+ container_of(dev, struct unit_directory, device);
+ struct firedtv *fdtv;
+ int kv_len, err;
+ void *kv_str;
+
+ kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t);
+ kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
+
+ fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
+ if (!fdtv)
+ return -ENOMEM;
+
+ /*
+ * Work around a bug in udev's path_id script: Use the fw-host's dev
+ * instead of the unit directory's dev as parent of the input device.
+ */
+ err = fdtv_register_rc(fdtv, dev->parent->parent);
+ if (err)
+ goto fail_free;
+
+ spin_lock_irq(&node_list_lock);
+ list_add_tail(&fdtv->list, &node_list);
+ spin_unlock_irq(&node_list_lock);
+
+ err = avc_identify_subunit(fdtv);
+ if (err)
+ goto fail;
+
+ err = fdtv_dvb_register(fdtv);
+ if (err)
+ goto fail;
+
+ avc_register_remote_control(fdtv);
+ return 0;
+fail:
+ spin_lock_irq(&node_list_lock);
+ list_del(&fdtv->list);
+ spin_unlock_irq(&node_list_lock);
+ fdtv_unregister_rc(fdtv);
+fail_free:
+ kfree(fdtv);
+ return err;
+}
+
+static int node_remove(struct device *dev)
+{
+ struct firedtv *fdtv = dev->driver_data;
+
+ fdtv_dvb_unregister(fdtv);
+
+ spin_lock_irq(&node_list_lock);
+ list_del(&fdtv->list);
+ spin_unlock_irq(&node_list_lock);
+
+ cancel_work_sync(&fdtv->remote_ctrl_work);
+ fdtv_unregister_rc(fdtv);
+
+ kfree(fdtv);
+ return 0;
+}
+
+static int node_update(struct unit_directory *ud)
+{
+ struct firedtv *fdtv = ud->device.driver_data;
+
+ if (fdtv->isochannel >= 0)
+ cmp_establish_pp_connection(fdtv, fdtv->subunit,
+ fdtv->isochannel);
+ return 0;
+}
+
+static struct hpsb_protocol_driver fdtv_driver = {
+ .name = "firedtv",
+ .update = node_update,
+ .driver = {
+ .probe = node_probe,
+ .remove = node_remove,
+ },
+};
+
+static struct hpsb_highlevel fdtv_highlevel = {
+ .name = "firedtv",
+ .fcp_request = fcp_request,
+};
+
+int __init fdtv_1394_init(struct ieee1394_device_id id_table[])
+{
+ int ret;
+
+ hpsb_register_highlevel(&fdtv_highlevel);
+ fdtv_driver.id_table = id_table;
+ ret = hpsb_register_protocol(&fdtv_driver);
+ if (ret) {
+ printk(KERN_ERR "firedtv: failed to register protocol\n");
+ hpsb_unregister_highlevel(&fdtv_highlevel);
+ }
+ return ret;
+}
+
+void __exit fdtv_1394_exit(void)
+{
+ hpsb_unregister_protocol(&fdtv_driver);
+ hpsb_unregister_highlevel(&fdtv_highlevel);
+}
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
new file mode 100644
index 000000000000..b55d9ccaf33e
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -0,0 +1,1315 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bug.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/stringify.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include "firedtv.h"
+
+#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
+
+#define AVC_CTYPE_CONTROL 0x0
+#define AVC_CTYPE_STATUS 0x1
+#define AVC_CTYPE_NOTIFY 0x3
+
+#define AVC_RESPONSE_ACCEPTED 0x9
+#define AVC_RESPONSE_STABLE 0xc
+#define AVC_RESPONSE_CHANGED 0xd
+#define AVC_RESPONSE_INTERIM 0xf
+
+#define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3)
+#define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3)
+
+#define AVC_OPCODE_VENDOR 0x00
+#define AVC_OPCODE_READ_DESCRIPTOR 0x09
+#define AVC_OPCODE_DSIT 0xc8
+#define AVC_OPCODE_DSD 0xcb
+
+#define DESCRIPTOR_TUNER_STATUS 0x80
+#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
+
+#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */
+#define SFE_VENDOR_DE_COMPANYID_1 0x12
+#define SFE_VENDOR_DE_COMPANYID_2 0x87
+
+#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a
+#define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
+#define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */
+
+#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00
+#define SFE_VENDOR_OPCODE_HOST2CA 0x56
+#define SFE_VENDOR_OPCODE_CA2HOST 0x57
+#define SFE_VENDOR_OPCODE_CISTATUS 0x59
+#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */
+
+#define SFE_VENDOR_TAG_CA_RESET 0x00
+#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
+#define SFE_VENDOR_TAG_CA_PMT 0x02
+#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
+#define SFE_VENDOR_TAG_CA_MMI 0x05
+#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
+
+#define EN50221_LIST_MANAGEMENT_ONLY 0x03
+#define EN50221_TAG_APP_INFO 0x9f8021
+#define EN50221_TAG_CA_INFO 0x9f8031
+
+struct avc_command_frame {
+ int length;
+ u8 ctype;
+ u8 subunit;
+ u8 opcode;
+ u8 operand[509];
+};
+
+struct avc_response_frame {
+ int length;
+ u8 response;
+ u8 subunit;
+ u8 opcode;
+ u8 operand[509];
+};
+
+#define AVC_DEBUG_FCP_SUBACTIONS 1
+#define AVC_DEBUG_FCP_PAYLOADS 2
+
+static int avc_debug;
+module_param_named(debug, avc_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
+ ", FCP subactions = " __stringify(AVC_DEBUG_FCP_SUBACTIONS)
+ ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS)
+ ", or all = -1)");
+
+static const char *debug_fcp_ctype(unsigned int ctype)
+{
+ static const char *ctypes[] = {
+ [0x0] = "CONTROL", [0x1] = "STATUS",
+ [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY",
+ [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED",
+ [0x9] = "ACCEPTED", [0xa] = "REJECTED",
+ [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE",
+ [0xd] = "CHANGED", [0xf] = "INTERIM",
+ };
+ const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL;
+
+ return ret ? ret : "?";
+}
+
+static const char *debug_fcp_opcode(unsigned int opcode,
+ const u8 *data, size_t length)
+{
+ switch (opcode) {
+ case AVC_OPCODE_VENDOR: break;
+ case AVC_OPCODE_READ_DESCRIPTOR: return "ReadDescriptor";
+ case AVC_OPCODE_DSIT: return "DirectSelectInfo.Type";
+ case AVC_OPCODE_DSD: return "DirectSelectData";
+ default: return "?";
+ }
+
+ if (length < 7 ||
+ data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
+ data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
+ data[5] != SFE_VENDOR_DE_COMPANYID_2)
+ return "Vendor";
+
+ switch (data[6]) {
+ case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC";
+ case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl";
+ case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK";
+ case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA";
+ case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host";
+ }
+ return "Vendor";
+}
+
+static void debug_fcp(const u8 *data, size_t length)
+{
+ unsigned int subunit_type, subunit_id, op;
+ const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
+
+ if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) {
+ subunit_type = data[1] >> 3;
+ subunit_id = data[1] & 7;
+ op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
+ printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
+ prefix, subunit_type, subunit_id, length,
+ debug_fcp_ctype(data[0]),
+ debug_fcp_opcode(op, data, length));
+ }
+
+ if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
+ print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1,
+ data, length, false);
+}
+
+static int __avc_write(struct firedtv *fdtv,
+ const struct avc_command_frame *c, struct avc_response_frame *r)
+{
+ int err, retry;
+
+ if (r)
+ fdtv->avc_reply_received = false;
+
+ for (retry = 0; retry < 6; retry++) {
+ if (unlikely(avc_debug))
+ debug_fcp(&c->ctype, c->length);
+
+ err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER,
+ (void *)&c->ctype, c->length);
+ if (err) {
+ fdtv->avc_reply_received = true;
+ dev_err(fdtv->device, "FCP command write failed\n");
+ return err;
+ }
+
+ if (!r)
+ return 0;
+
+ /*
+ * AV/C specs say that answers should be sent within 150 ms.
+ * Time out after 200 ms.
+ */
+ if (wait_event_timeout(fdtv->avc_wait,
+ fdtv->avc_reply_received,
+ msecs_to_jiffies(200)) != 0) {
+ r->length = fdtv->response_length;
+ memcpy(&r->response, fdtv->response, r->length);
+
+ return 0;
+ }
+ }
+ dev_err(fdtv->device, "FCP response timed out\n");
+ return -ETIMEDOUT;
+}
+
+static int avc_write(struct firedtv *fdtv,
+ const struct avc_command_frame *c, struct avc_response_frame *r)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = __avc_write(fdtv, c, r);
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+int avc_recv(struct firedtv *fdtv, void *data, size_t length)
+{
+ struct avc_response_frame *r =
+ data - offsetof(struct avc_response_frame, response);
+
+ if (unlikely(avc_debug))
+ debug_fcp(data, length);
+
+ if (length >= 8 &&
+ r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
+ r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
+ r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
+ r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
+ if (r->response == AVC_RESPONSE_CHANGED) {
+ fdtv_handle_rc(fdtv,
+ r->operand[4] << 8 | r->operand[5]);
+ schedule_work(&fdtv->remote_ctrl_work);
+ } else if (r->response != AVC_RESPONSE_INTERIM) {
+ dev_info(fdtv->device,
+ "remote control result = %d\n", r->response);
+ }
+ return 0;
+ }
+
+ if (fdtv->avc_reply_received) {
+ dev_err(fdtv->device, "out-of-order AVC response, ignored\n");
+ return -EIO;
+ }
+
+ memcpy(fdtv->response, data, length);
+ fdtv->response_length = length;
+
+ fdtv->avc_reply_received = true;
+ wake_up(&fdtv->avc_wait);
+
+ return 0;
+}
+
+/*
+ * tuning command for setting the relative LNB frequency
+ * (not supported by the AVC standard)
+ */
+static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
+ struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
+
+ c->operand[4] = (params->frequency >> 24) & 0xff;
+ c->operand[5] = (params->frequency >> 16) & 0xff;
+ c->operand[6] = (params->frequency >> 8) & 0xff;
+ c->operand[7] = params->frequency & 0xff;
+
+ c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff;
+ c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff;
+
+ switch (params->u.qpsk.fec_inner) {
+ case FEC_1_2: c->operand[10] = 0x1; break;
+ case FEC_2_3: c->operand[10] = 0x2; break;
+ case FEC_3_4: c->operand[10] = 0x3; break;
+ case FEC_5_6: c->operand[10] = 0x4; break;
+ case FEC_7_8: c->operand[10] = 0x5; break;
+ case FEC_4_5:
+ case FEC_8_9:
+ case FEC_AUTO:
+ default: c->operand[10] = 0x0;
+ }
+
+ if (fdtv->voltage == 0xff)
+ c->operand[11] = 0xff;
+ else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */
+ c->operand[11] = 0;
+ else
+ c->operand[11] = 1;
+
+ if (fdtv->tone == 0xff)
+ c->operand[12] = 0xff;
+ else if (fdtv->tone == SEC_TONE_ON) /* band */
+ c->operand[12] = 1;
+ else
+ c->operand[12] = 0;
+
+ if (fdtv->type == FIREDTV_DVB_S2) {
+ c->operand[13] = 0x1;
+ c->operand[14] = 0xff;
+ c->operand[15] = 0xff;
+ c->length = 20;
+ } else {
+ c->length = 16;
+ }
+}
+
+static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x11; /* system_specific_multiplex selection_length */
+
+ /* multiplex_valid_flags, high byte */
+ c->operand[5] = 0 << 7 /* reserved */
+ | 0 << 6 /* Polarisation */
+ | 0 << 5 /* Orbital_Pos */
+ | 1 << 4 /* Frequency */
+ | 1 << 3 /* Symbol_Rate */
+ | 0 << 2 /* FEC_outer */
+ | (params->u.qam.fec_inner != FEC_AUTO ? 1 << 1 : 0)
+ | (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0);
+
+ /* multiplex_valid_flags, low byte */
+ c->operand[6] = 0 << 7 /* NetworkID */
+ | 0 << 0 /* reserved */ ;
+
+ c->operand[7] = 0x00;
+ c->operand[8] = 0x00;
+ c->operand[9] = 0x00;
+ c->operand[10] = 0x00;
+
+ c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6);
+ c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff;
+ c->operand[13] = (params->frequency / 4000) & 0xff;
+ c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff;
+ c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff;
+ c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0;
+ c->operand[17] = 0x00;
+
+ switch (params->u.qpsk.fec_inner) {
+ case FEC_1_2: c->operand[18] = 0x1; break;
+ case FEC_2_3: c->operand[18] = 0x2; break;
+ case FEC_3_4: c->operand[18] = 0x3; break;
+ case FEC_5_6: c->operand[18] = 0x4; break;
+ case FEC_7_8: c->operand[18] = 0x5; break;
+ case FEC_8_9: c->operand[18] = 0x6; break;
+ case FEC_4_5: c->operand[18] = 0x8; break;
+ case FEC_AUTO:
+ default: c->operand[18] = 0x0;
+ }
+
+ switch (params->u.qam.modulation) {
+ case QAM_16: c->operand[19] = 0x08; break;
+ case QAM_32: c->operand[19] = 0x10; break;
+ case QAM_64: c->operand[19] = 0x18; break;
+ case QAM_128: c->operand[19] = 0x20; break;
+ case QAM_256: c->operand[19] = 0x28; break;
+ case QAM_AUTO:
+ default: c->operand[19] = 0x00;
+ }
+
+ c->operand[20] = 0x00;
+ c->operand[21] = 0x00;
+ /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
+ c->operand[22] = 0x00;
+
+ c->length = 28;
+}
+
+static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
+ struct avc_command_frame *c)
+{
+ struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
+
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */
+
+ /* multiplex_valid_flags, high byte */
+ c->operand[5] =
+ 0 << 7 /* reserved */
+ | 1 << 6 /* CenterFrequency */
+ | (ofdm->bandwidth != BANDWIDTH_AUTO ? 1 << 5 : 0)
+ | (ofdm->constellation != QAM_AUTO ? 1 << 4 : 0)
+ | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0)
+ | (ofdm->code_rate_HP != FEC_AUTO ? 1 << 2 : 0)
+ | (ofdm->code_rate_LP != FEC_AUTO ? 1 << 1 : 0)
+ | (ofdm->guard_interval != GUARD_INTERVAL_AUTO ? 1 << 0 : 0);
+
+ /* multiplex_valid_flags, low byte */
+ c->operand[6] =
+ 0 << 7 /* NetworkID */
+ | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0)
+ | 0 << 5 /* OtherFrequencyFlag */
+ | 0 << 0 /* reserved */ ;
+
+ c->operand[7] = 0x0;
+ c->operand[8] = (params->frequency / 10) >> 24;
+ c->operand[9] = ((params->frequency / 10) >> 16) & 0xff;
+ c->operand[10] = ((params->frequency / 10) >> 8) & 0xff;
+ c->operand[11] = (params->frequency / 10) & 0xff;
+
+ switch (ofdm->bandwidth) {
+ case BANDWIDTH_7_MHZ: c->operand[12] = 0x20; break;
+ case BANDWIDTH_8_MHZ:
+ case BANDWIDTH_6_MHZ: /* not defined by AVC spec */
+ case BANDWIDTH_AUTO:
+ default: c->operand[12] = 0x00;
+ }
+
+ switch (ofdm->constellation) {
+ case QAM_16: c->operand[13] = 1 << 6; break;
+ case QAM_64: c->operand[13] = 2 << 6; break;
+ case QPSK:
+ default: c->operand[13] = 0x00;
+ }
+
+ switch (ofdm->hierarchy_information) {
+ case HIERARCHY_1: c->operand[13] |= 1 << 3; break;
+ case HIERARCHY_2: c->operand[13] |= 2 << 3; break;
+ case HIERARCHY_4: c->operand[13] |= 3 << 3; break;
+ case HIERARCHY_AUTO:
+ case HIERARCHY_NONE:
+ default: break;
+ }
+
+ switch (ofdm->code_rate_HP) {
+ case FEC_2_3: c->operand[13] |= 1; break;
+ case FEC_3_4: c->operand[13] |= 2; break;
+ case FEC_5_6: c->operand[13] |= 3; break;
+ case FEC_7_8: c->operand[13] |= 4; break;
+ case FEC_1_2:
+ default: break;
+ }
+
+ switch (ofdm->code_rate_LP) {
+ case FEC_2_3: c->operand[14] = 1 << 5; break;
+ case FEC_3_4: c->operand[14] = 2 << 5; break;
+ case FEC_5_6: c->operand[14] = 3 << 5; break;
+ case FEC_7_8: c->operand[14] = 4 << 5; break;
+ case FEC_1_2:
+ default: c->operand[14] = 0x00; break;
+ }
+
+ switch (ofdm->guard_interval) {
+ case GUARD_INTERVAL_1_16: c->operand[14] |= 1 << 3; break;
+ case GUARD_INTERVAL_1_8: c->operand[14] |= 2 << 3; break;
+ case GUARD_INTERVAL_1_4: c->operand[14] |= 3 << 3; break;
+ case GUARD_INTERVAL_1_32:
+ case GUARD_INTERVAL_AUTO:
+ default: break;
+ }
+
+ switch (ofdm->transmission_mode) {
+ case TRANSMISSION_MODE_8K: c->operand[14] |= 1 << 1; break;
+ case TRANSMISSION_MODE_2K:
+ case TRANSMISSION_MODE_AUTO:
+ default: break;
+ }
+
+ c->operand[15] = 0x00; /* network_ID[0] */
+ c->operand[16] = 0x00; /* network_ID[1] */
+ /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
+ c->operand[17] = 0x00;
+
+ c->length = 24;
+}
+
+int avc_tuner_dsd(struct firedtv *fdtv,
+ struct dvb_frontend_parameters *params)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+
+ switch (fdtv->type) {
+ case FIREDTV_DVB_S:
+ case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
+ case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break;
+ case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break;
+ default:
+ BUG();
+ }
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(500);
+#if 0
+ /* FIXME: */
+ /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */
+ if (status)
+ *status = r->operand[2];
+#endif
+ return 0;
+}
+
+int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+ int pos, k;
+
+ if (pidc > 16 && pidc != 0xff)
+ return -EINVAL;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_DSD;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0x20; /* system id = DVB */
+ c->operand[3] = 0x00; /* antenna number */
+ c->operand[4] = 0x00; /* system_specific_multiplex selection_length */
+ c->operand[5] = pidc; /* Nr_of_dsd_sel_specs */
+
+ pos = 6;
+ if (pidc != 0xff)
+ for (k = 0; k < pidc; k++) {
+ c->operand[pos++] = 0x13; /* flowfunction relay */
+ c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
+ c->operand[pos++] = (pid[k] >> 8) & 0x1f;
+ c->operand[pos++] = pid[k] & 0xff;
+ c->operand[pos++] = 0x00; /* tableID */
+ c->operand[pos++] = 0x00; /* filter_length */
+ }
+
+ c->length = ALIGN(3 + pos, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(50);
+ return 0;
+}
+
+int avc_tuner_get_ts(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+ int sl;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_DSIT;
+
+ sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11;
+
+ c->operand[0] = 0; /* source plug */
+ c->operand[1] = 0xd2; /* subfunction replace */
+ c->operand[2] = 0xff; /* status */
+ c->operand[3] = 0x20; /* system id = DVB */
+ c->operand[4] = 0x00; /* antenna number */
+ c->operand[5] = 0x0; /* system_specific_search_flags */
+ c->operand[6] = sl; /* system_specific_multiplex selection_length */
+ c->operand[7] = 0x00; /* valid_flags [0] */
+ c->operand[8] = 0x00; /* valid_flags [1] */
+ c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */
+
+ c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ msleep(250);
+ return 0;
+}
+
+int avc_identify_subunit(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
+
+ c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER;
+ c->operand[1] = 0xff;
+ c->operand[2] = 0x00;
+ c->operand[3] = 0x00; /* length highbyte */
+ c->operand[4] = 0x08; /* length lowbyte */
+ c->operand[5] = 0x00; /* offset highbyte */
+ c->operand[6] = 0x0d; /* offset lowbyte */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if ((r->response != AVC_RESPONSE_STABLE &&
+ r->response != AVC_RESPONSE_ACCEPTED) ||
+ (r->operand[3] << 8) + r->operand[4] != 8) {
+ dev_err(fdtv->device, "cannot read subunit identifier\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+#define SIZEOF_ANTENNA_INPUT_INFO 22
+
+int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int length;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_READ_DESCRIPTOR;
+
+ c->operand[0] = DESCRIPTOR_TUNER_STATUS;
+ c->operand[1] = 0xff; /* read_result_status */
+ c->operand[2] = 0x00; /* reserved */
+ c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */
+ c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */
+ c->operand[5] = 0x00;
+ c->operand[6] = 0x00;
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_STABLE &&
+ r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device, "cannot read tuner status\n");
+ return -EINVAL;
+ }
+
+ length = r->operand[9];
+ if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) {
+ dev_err(fdtv->device, "got invalid tuner status\n");
+ return -EINVAL;
+ }
+
+ stat->active_system = r->operand[10];
+ stat->searching = r->operand[11] >> 7 & 1;
+ stat->moving = r->operand[11] >> 6 & 1;
+ stat->no_rf = r->operand[11] >> 5 & 1;
+ stat->input = r->operand[12] >> 7 & 1;
+ stat->selected_antenna = r->operand[12] & 0x7f;
+ stat->ber = r->operand[13] << 24 |
+ r->operand[14] << 16 |
+ r->operand[15] << 8 |
+ r->operand[16];
+ stat->signal_strength = r->operand[17];
+ stat->raster_frequency = r->operand[18] >> 6 & 2;
+ stat->rf_frequency = (r->operand[18] & 0x3f) << 16 |
+ r->operand[19] << 8 |
+ r->operand[20];
+ stat->man_dep_info_length = r->operand[21];
+ stat->front_end_error = r->operand[22] >> 4 & 1;
+ stat->antenna_error = r->operand[22] >> 3 & 1;
+ stat->front_end_power_status = r->operand[22] >> 1 & 1;
+ stat->power_supply = r->operand[22] & 1;
+ stat->carrier_noise_ratio = r->operand[23] << 8 |
+ r->operand[24];
+ stat->power_supply_voltage = r->operand[27];
+ stat->antenna_voltage = r->operand[28];
+ stat->firewire_bus_voltage = r->operand[29];
+ stat->ca_mmi = r->operand[30] & 1;
+ stat->ca_pmt_reply = r->operand[31] >> 7 & 1;
+ stat->ca_date_time_request = r->operand[31] >> 6 & 1;
+ stat->ca_application_info = r->operand[31] >> 5 & 1;
+ stat->ca_module_present_status = r->operand[31] >> 4 & 1;
+ stat->ca_dvb_flag = r->operand[31] >> 3 & 1;
+ stat->ca_error_flag = r->operand[31] >> 2 & 1;
+ stat->ca_initialization_status = r->operand[31] >> 1 & 1;
+
+ return 0;
+}
+
+int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
+ char conttone, char nrdiseq,
+ struct dvb_diseqc_master_cmd *diseqcmd)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int i, j, k;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;
+
+ c->operand[4] = voltage;
+ c->operand[5] = nrdiseq;
+
+ i = 6;
+
+ for (j = 0; j < nrdiseq; j++) {
+ c->operand[i++] = diseqcmd[j].msg_len;
+
+ for (k = 0; k < diseqcmd[j].msg_len; k++)
+ c->operand[i++] = diseqcmd[j].msg[k];
+ }
+
+ c->operand[i++] = burst;
+ c->operand[i++] = conttone;
+
+ c->length = ALIGN(3 + i, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device, "LNB control failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int avc_register_remote_control(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_NOTIFY;
+ c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
+
+ c->length = 8;
+
+ return avc_write(fdtv, c, NULL);
+}
+
+void avc_remote_ctrl_work(struct work_struct *work)
+{
+ struct firedtv *fdtv =
+ container_of(work, struct firedtv, remote_ctrl_work);
+
+ /* Should it be rescheduled in failure cases? */
+ avc_register_remote_control(fdtv);
+}
+
+#if 0 /* FIXME: unused */
+int avc_tuner_host2ca(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+#endif
+
+static int get_ca_object_pos(struct avc_response_frame *r)
+{
+ int length = 1;
+
+ /* Check length of length field */
+ if (r->operand[7] & 0x80)
+ length = (r->operand[7] & 0x7f) + 1;
+ return length + 7;
+}
+
+static int get_ca_object_length(struct avc_response_frame *r)
+{
+#if 0 /* FIXME: unused */
+ int size = 0;
+ int i;
+
+ if (r->operand[7] & 0x80)
+ for (i = 0; i < (r->operand[7] & 0x7f); i++) {
+ size <<= 8;
+ size += r->operand[8 + i];
+ }
+#endif
+ return r->operand[7];
+}
+
+int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int pos;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ pos = get_ca_object_pos(r);
+ app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff;
+ app_info[1] = (EN50221_TAG_APP_INFO >> 8) & 0xff;
+ app_info[2] = (EN50221_TAG_APP_INFO >> 0) & 0xff;
+ app_info[3] = 6 + r->operand[pos + 4];
+ app_info[4] = 0x01;
+ memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]);
+ *len = app_info[3] + 4;
+
+ return 0;
+}
+
+int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int pos;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ pos = get_ca_object_pos(r);
+ app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
+ app_info[1] = (EN50221_TAG_CA_INFO >> 8) & 0xff;
+ app_info[2] = (EN50221_TAG_CA_INFO >> 0) & 0xff;
+ app_info[3] = 2;
+ app_info[4] = r->operand[pos + 0];
+ app_info[5] = r->operand[pos + 1];
+ *len = app_info[3] + 4;
+
+ return 0;
+}
+
+int avc_ca_reset(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 1; /* length */
+ c->operand[8] = 0; /* force hardware reset */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+ int list_management;
+ int program_info_length;
+ int pmt_cmd_id;
+ int read_pos;
+ int write_pos;
+ int es_info_length;
+ int crc32_csum;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_CONTROL;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) {
+ dev_info(fdtv->device, "forcing list_management to ONLY\n");
+ msg[0] = EN50221_LIST_MANAGEMENT_ONLY;
+ }
+ /* We take the cmd_id from the programme level only! */
+ list_management = msg[0];
+ program_info_length = ((msg[4] & 0x0f) << 8) + msg[5];
+ if (program_info_length > 0)
+ program_info_length--; /* Remove pmt_cmd_id */
+ pmt_cmd_id = msg[6];
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ /* c->operand[7] = XXXprogram_info_length + 17; */ /* length */
+ c->operand[8] = list_management;
+ c->operand[9] = 0x01; /* pmt_cmd=OK_descramble */
+
+ /* TS program map table */
+
+ c->operand[10] = 0x02; /* Table id=2 */
+ c->operand[11] = 0x80; /* Section syntax + length */
+ /* c->operand[12] = XXXprogram_info_length + 12; */
+ c->operand[13] = msg[1]; /* Program number */
+ c->operand[14] = msg[2];
+ c->operand[15] = 0x01; /* Version number=0 + current/next=1 */
+ c->operand[16] = 0x00; /* Section number=0 */
+ c->operand[17] = 0x00; /* Last section number=0 */
+ c->operand[18] = 0x1f; /* PCR_PID=1FFF */
+ c->operand[19] = 0xff;
+ c->operand[20] = (program_info_length >> 8); /* Program info length */
+ c->operand[21] = (program_info_length & 0xff);
+
+ /* CA descriptors at programme level */
+ read_pos = 6;
+ write_pos = 22;
+ if (program_info_length > 0) {
+ pmt_cmd_id = msg[read_pos++];
+ if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
+ dev_err(fdtv->device,
+ "invalid pmt_cmd_id %d\n", pmt_cmd_id);
+
+ memcpy(&c->operand[write_pos], &msg[read_pos],
+ program_info_length);
+ read_pos += program_info_length;
+ write_pos += program_info_length;
+ }
+ while (read_pos < length) {
+ c->operand[write_pos++] = msg[read_pos++];
+ c->operand[write_pos++] = msg[read_pos++];
+ c->operand[write_pos++] = msg[read_pos++];
+ es_info_length =
+ ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1];
+ read_pos += 2;
+ if (es_info_length > 0)
+ es_info_length--; /* Remove pmt_cmd_id */
+ c->operand[write_pos++] = es_info_length >> 8;
+ c->operand[write_pos++] = es_info_length & 0xff;
+ if (es_info_length > 0) {
+ pmt_cmd_id = msg[read_pos++];
+ if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
+ dev_err(fdtv->device, "invalid pmt_cmd_id %d "
+ "at stream level\n", pmt_cmd_id);
+
+ memcpy(&c->operand[write_pos], &msg[read_pos],
+ es_info_length);
+ read_pos += es_info_length;
+ write_pos += es_info_length;
+ }
+ }
+
+ /* CRC */
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+ c->operand[write_pos++] = 0x00;
+
+ c->operand[7] = write_pos - 8;
+ c->operand[12] = write_pos - 13;
+
+ crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1);
+ c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
+ c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
+ c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff;
+ c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff;
+
+ c->length = ALIGN(3 + write_pos, 4);
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ if (r->response != AVC_RESPONSE_ACCEPTED) {
+ dev_err(fdtv->device,
+ "CA PMT failed with response 0x%x\n", r->response);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ *interval = r->operand[get_ca_object_pos(r)];
+
+ return 0;
+}
+
+int avc_ca_enter_menu(struct firedtv *fdtv)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ return 0;
+}
+
+int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
+{
+ char buffer[sizeof(struct avc_command_frame)];
+ struct avc_command_frame *c = (void *)buffer;
+ struct avc_response_frame *r = (void *)buffer;
+
+ memset(c, 0, sizeof(*c));
+
+ c->ctype = AVC_CTYPE_STATUS;
+ c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
+ c->opcode = AVC_OPCODE_VENDOR;
+
+ c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
+ c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
+ c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
+ c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
+ c->operand[4] = 0; /* slot */
+ c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
+ c->operand[6] = 0; /* more/last */
+ c->operand[7] = 0; /* length */
+
+ c->length = 12;
+
+ if (avc_write(fdtv, c, r) < 0)
+ return -EIO;
+
+ /* FIXME: check response code and validate response data */
+
+ *len = get_ca_object_length(r);
+ memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len);
+
+ return 0;
+}
+
+#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
+
+static int cmp_read(struct firedtv *fdtv, void *buf, u64 addr, size_t len)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = fdtv->backend->read(fdtv, addr, buf, len);
+ if (ret < 0)
+ dev_err(fdtv->device, "CMP: read I/O error\n");
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+static int cmp_lock(struct firedtv *fdtv, void *data, u64 addr, __be32 arg)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&fdtv->avc_mutex))
+ return -EINTR;
+
+ ret = fdtv->backend->lock(fdtv, addr, data, arg);
+ if (ret < 0)
+ dev_err(fdtv->device, "CMP: lock I/O error\n");
+
+ mutex_unlock(&fdtv->avc_mutex);
+ return ret;
+}
+
+static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift)
+{
+ return (be32_to_cpu(opcr) >> shift) & mask;
+}
+
+static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
+{
+ *opcr &= ~cpu_to_be32(mask << shift);
+ *opcr |= cpu_to_be32((value & mask) << shift);
+}
+
+#define get_opcr_online(v) get_opcr((v), 0x1, 31)
+#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
+#define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
+
+#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
+#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
+#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
+#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
+
+int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
+{
+ __be32 old_opcr, opcr;
+ u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
+ int attempts = 0;
+ int ret;
+
+ ret = cmp_read(fdtv, &opcr, opcr_address, 4);
+ if (ret < 0)
+ return ret;
+
+repeat:
+ if (!get_opcr_online(opcr)) {
+ dev_err(fdtv->device, "CMP: output offline\n");
+ return -EBUSY;
+ }
+
+ old_opcr = opcr;
+
+ if (get_opcr_p2p_connections(opcr)) {
+ if (get_opcr_channel(opcr) != channel) {
+ dev_err(fdtv->device, "CMP: cannot change channel\n");
+ return -EBUSY;
+ }
+ dev_info(fdtv->device, "CMP: overlaying connection\n");
+
+ /* We don't allocate isochronous resources. */
+ } else {
+ set_opcr_channel(&opcr, channel);
+ set_opcr_data_rate(&opcr, 2); /* S400 */
+
+ /* FIXME: this is for the worst case - optimize */
+ set_opcr_overhead_id(&opcr, 0);
+
+ /*
+ * FIXME: allocate isochronous channel and bandwidth at IRM
+ * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
+ */
+ }
+
+ set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
+
+ ret = cmp_lock(fdtv, &opcr, opcr_address, old_opcr);
+ if (ret < 0)
+ return ret;
+
+ if (old_opcr != opcr) {
+ /*
+ * FIXME: if old_opcr.P2P_Connections > 0,
+ * deallocate isochronous channel and bandwidth at IRM
+ * if (...)
+ * fdtv->backend->dealloc_resources(fdtv, channel, bw);
+ */
+
+ if (++attempts < 6) /* arbitrary limit */
+ goto repeat;
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
+{
+ __be32 old_opcr, opcr;
+ u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
+ int attempts = 0;
+
+ if (cmp_read(fdtv, &opcr, opcr_address, 4) < 0)
+ return;
+
+repeat:
+ if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
+ get_opcr_channel(opcr) != channel) {
+ dev_err(fdtv->device, "CMP: no connection to break\n");
+ return;
+ }
+
+ old_opcr = opcr;
+ set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
+
+ if (cmp_lock(fdtv, &opcr, opcr_address, old_opcr) < 0)
+ return;
+
+ if (old_opcr != opcr) {
+ /*
+ * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
+ * owner, deallocate isochronous channel and bandwidth at IRM
+ * if (...)
+ * fdtv->backend->dealloc_resources(fdtv, channel, bw);
+ */
+
+ if (++attempts < 6) /* arbitrary limit */
+ goto repeat;
+ }
+}
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c
new file mode 100644
index 000000000000..eeb80d0ea3ff
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-ci.c
@@ -0,0 +1,260 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/dvb/ca.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+
+#include <dvbdev.h>
+
+#include "firedtv.h"
+
+#define EN50221_TAG_APP_INFO_ENQUIRY 0x9f8020
+#define EN50221_TAG_CA_INFO_ENQUIRY 0x9f8030
+#define EN50221_TAG_CA_PMT 0x9f8032
+#define EN50221_TAG_ENTER_MENU 0x9f8022
+
+static int fdtv_ca_ready(struct firedtv_tuner_status *stat)
+{
+ return stat->ca_initialization_status == 1 &&
+ stat->ca_error_flag == 0 &&
+ stat->ca_dvb_flag == 1 &&
+ stat->ca_module_present_status == 1;
+}
+
+static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat)
+{
+ int flags = 0;
+
+ if (stat->ca_module_present_status == 1)
+ flags |= CA_CI_MODULE_PRESENT;
+ if (stat->ca_initialization_status == 1 &&
+ stat->ca_error_flag == 0 &&
+ stat->ca_dvb_flag == 1)
+ flags |= CA_CI_MODULE_READY;
+ return flags;
+}
+
+static int fdtv_ca_reset(struct firedtv *fdtv)
+{
+ return avc_ca_reset(fdtv) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_caps(void *arg)
+{
+ struct ca_caps *cap = arg;
+
+ cap->slot_num = 1;
+ cap->slot_type = CA_CI;
+ cap->descr_num = 1;
+ cap->descr_type = CA_ECD;
+ return 0;
+}
+
+static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg)
+{
+ struct firedtv_tuner_status stat;
+ struct ca_slot_info *slot = arg;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EFAULT;
+
+ if (slot->num != 0)
+ return -EFAULT;
+
+ slot->type = CA_CI;
+ slot->flags = fdtv_get_ca_flags(&stat);
+ return 0;
+}
+
+static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_info(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *reply = arg;
+
+ return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg)
+{
+ struct firedtv_tuner_status stat;
+ int err;
+
+ switch (fdtv->ca_last_command) {
+ case EN50221_TAG_APP_INFO_ENQUIRY:
+ err = fdtv_ca_app_info(fdtv, arg);
+ break;
+ case EN50221_TAG_CA_INFO_ENQUIRY:
+ err = fdtv_ca_info(fdtv, arg);
+ break;
+ default:
+ if (avc_tuner_status(fdtv, &stat))
+ err = -EFAULT;
+ else if (stat.ca_mmi == 1)
+ err = fdtv_ca_get_mmi(fdtv, arg);
+ else {
+ dev_info(fdtv->device, "unhandled CA message 0x%08x\n",
+ fdtv->ca_last_command);
+ err = -EFAULT;
+ }
+ }
+ fdtv->ca_last_command = 0;
+ return err;
+}
+
+static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *msg = arg;
+ int data_pos;
+ int data_length;
+ int i;
+
+ data_pos = 4;
+ if (msg->msg[3] & 0x80) {
+ data_length = 0;
+ for (i = 0; i < (msg->msg[3] & 0x7f); i++)
+ data_length = (data_length << 8) + msg->msg[data_pos++];
+ } else {
+ data_length = msg->msg[3];
+ }
+
+ return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0;
+}
+
+static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg)
+{
+ struct ca_msg *msg = arg;
+ int err;
+
+ /* Do we need a semaphore for this? */
+ fdtv->ca_last_command =
+ (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2];
+ switch (fdtv->ca_last_command) {
+ case EN50221_TAG_CA_PMT:
+ err = fdtv_ca_pmt(fdtv, arg);
+ break;
+ case EN50221_TAG_APP_INFO_ENQUIRY:
+ /* handled in ca_get_msg */
+ err = 0;
+ break;
+ case EN50221_TAG_CA_INFO_ENQUIRY:
+ /* handled in ca_get_msg */
+ err = 0;
+ break;
+ case EN50221_TAG_ENTER_MENU:
+ err = avc_ca_enter_menu(fdtv);
+ break;
+ default:
+ dev_err(fdtv->device, "unhandled CA message 0x%08x\n",
+ fdtv->ca_last_command);
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int fdtv_ca_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct firedtv *fdtv = dvbdev->priv;
+ struct firedtv_tuner_status stat;
+ int err;
+
+ switch (cmd) {
+ case CA_RESET:
+ err = fdtv_ca_reset(fdtv);
+ break;
+ case CA_GET_CAP:
+ err = fdtv_ca_get_caps(arg);
+ break;
+ case CA_GET_SLOT_INFO:
+ err = fdtv_ca_get_slot_info(fdtv, arg);
+ break;
+ case CA_GET_MSG:
+ err = fdtv_ca_get_msg(fdtv, arg);
+ break;
+ case CA_SEND_MSG:
+ err = fdtv_ca_send_msg(fdtv, arg);
+ break;
+ default:
+ dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd);
+ err = -EOPNOTSUPP;
+ }
+
+ /* FIXME Is this necessary? */
+ avc_tuner_status(fdtv, &stat);
+
+ return err;
+}
+
+static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
+{
+ return POLLIN;
+}
+
+static struct file_operations fdtv_ca_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = dvb_generic_ioctl,
+ .open = dvb_generic_open,
+ .release = dvb_generic_release,
+ .poll = fdtv_ca_io_poll,
+};
+
+static struct dvb_device fdtv_ca = {
+ .users = 1,
+ .readers = 1,
+ .writers = 1,
+ .fops = &fdtv_ca_fops,
+ .kernel_ioctl = fdtv_ca_ioctl,
+};
+
+int fdtv_ca_register(struct firedtv *fdtv)
+{
+ struct firedtv_tuner_status stat;
+ int err;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ if (!fdtv_ca_ready(&stat))
+ return -EFAULT;
+
+ err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
+ &fdtv_ca, fdtv, DVB_DEVICE_CA);
+
+ if (stat.ca_application_info == 0)
+ dev_err(fdtv->device, "CaApplicationInfo is not set\n");
+ if (stat.ca_date_time_request == 1)
+ avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval);
+
+ return err;
+}
+
+void fdtv_ca_release(struct firedtv *fdtv)
+{
+ if (fdtv->cadev)
+ dvb_unregister_device(fdtv->cadev);
+}
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
new file mode 100644
index 000000000000..9d308dd32a5c
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -0,0 +1,364 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvbdev.h>
+#include <dvb_frontend.h>
+
+#include "firedtv.h"
+
+static int alloc_channel(struct firedtv *fdtv)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ if (!__test_and_set_bit(i, &fdtv->channel_active))
+ break;
+ return i;
+}
+
+static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
+{
+ int i, n;
+
+ for (i = 0, n = 0; i < 16; i++)
+ if (test_bit(i, &fdtv->channel_active))
+ pid[n++] = fdtv->channel_pid[i];
+ *pidc = n;
+}
+
+static inline void dealloc_channel(struct firedtv *fdtv, int i)
+{
+ __clear_bit(i, &fdtv->channel_active);
+}
+
+int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct firedtv *fdtv = dvbdmxfeed->demux->priv;
+ int pidc, c, ret;
+ u16 pids[16];
+
+ switch (dvbdmxfeed->type) {
+ case DMX_TYPE_TS:
+ case DMX_TYPE_SEC:
+ break;
+ default:
+ dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
+ dvbdmxfeed->type);
+ return -EINVAL;
+ }
+
+ if (mutex_lock_interruptible(&fdtv->demux_mutex))
+ return -EINTR;
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS) {
+ switch (dvbdmxfeed->pes_type) {
+ case DMX_TS_PES_VIDEO:
+ case DMX_TS_PES_AUDIO:
+ case DMX_TS_PES_TELETEXT:
+ case DMX_TS_PES_PCR:
+ case DMX_TS_PES_OTHER:
+ c = alloc_channel(fdtv);
+ break;
+ default:
+ dev_err(fdtv->device,
+ "can't start dmx feed: invalid pes type %u\n",
+ dvbdmxfeed->pes_type);
+ ret = -EINVAL;
+ goto out;
+ }
+ } else {
+ c = alloc_channel(fdtv);
+ }
+
+ if (c > 15) {
+ dev_err(fdtv->device, "can't start dmx feed: busy\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
+ fdtv->channel_pid[c] = dvbdmxfeed->pid;
+ collect_channels(fdtv, &pidc, pids);
+
+ if (dvbdmxfeed->pid == 8192) {
+ ret = avc_tuner_get_ts(fdtv);
+ if (ret) {
+ dealloc_channel(fdtv, c);
+ dev_err(fdtv->device, "can't get TS\n");
+ goto out;
+ }
+ } else {
+ ret = avc_tuner_set_pids(fdtv, pidc, pids);
+ if (ret) {
+ dealloc_channel(fdtv, c);
+ dev_err(fdtv->device, "can't set PIDs\n");
+ goto out;
+ }
+ }
+out:
+ mutex_unlock(&fdtv->demux_mutex);
+
+ return ret;
+}
+
+int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ struct dvb_demux *demux = dvbdmxfeed->demux;
+ struct firedtv *fdtv = demux->priv;
+ int pidc, c, ret;
+ u16 pids[16];
+
+ if (dvbdmxfeed->type == DMX_TYPE_TS &&
+ !((dvbdmxfeed->ts_type & TS_PACKET) &&
+ (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
+
+ if (dvbdmxfeed->ts_type & TS_DECODER) {
+ if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
+ !demux->pesfilter[dvbdmxfeed->pes_type])
+ return -EINVAL;
+
+ demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
+ demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
+ }
+
+ if (!(dvbdmxfeed->ts_type & TS_DECODER &&
+ dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
+ return 0;
+ }
+
+ if (mutex_lock_interruptible(&fdtv->demux_mutex))
+ return -EINTR;
+
+ c = (unsigned long)dvbdmxfeed->priv;
+ dealloc_channel(fdtv, c);
+ collect_channels(fdtv, &pidc, pids);
+
+ ret = avc_tuner_set_pids(fdtv, pidc, pids);
+
+ mutex_unlock(&fdtv->demux_mutex);
+
+ return ret;
+}
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+int fdtv_dvb_register(struct firedtv *fdtv)
+{
+ int err;
+
+ err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type],
+ THIS_MODULE, fdtv->device, adapter_nr);
+ if (err < 0)
+ goto fail_log;
+
+ /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
+ fdtv->demux.dmx.capabilities = 0;
+
+ fdtv->demux.priv = fdtv;
+ fdtv->demux.filternum = 16;
+ fdtv->demux.feednum = 16;
+ fdtv->demux.start_feed = fdtv_start_feed;
+ fdtv->demux.stop_feed = fdtv_stop_feed;
+ fdtv->demux.write_to_decoder = NULL;
+
+ err = dvb_dmx_init(&fdtv->demux);
+ if (err)
+ goto fail_unreg_adapter;
+
+ fdtv->dmxdev.filternum = 16;
+ fdtv->dmxdev.demux = &fdtv->demux.dmx;
+ fdtv->dmxdev.capabilities = 0;
+
+ err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
+ if (err)
+ goto fail_dmx_release;
+
+ fdtv->frontend.source = DMX_FRONTEND_0;
+
+ err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+ if (err)
+ goto fail_dmxdev_release;
+
+ err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
+ &fdtv->frontend);
+ if (err)
+ goto fail_rem_frontend;
+
+ dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
+
+ fdtv_frontend_init(fdtv);
+ err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
+ if (err)
+ goto fail_net_release;
+
+ err = fdtv_ca_register(fdtv);
+ if (err)
+ dev_info(fdtv->device,
+ "Conditional Access Module not enabled\n");
+ return 0;
+
+fail_net_release:
+ dvb_net_release(&fdtv->dvbnet);
+ fdtv->demux.dmx.close(&fdtv->demux.dmx);
+fail_rem_frontend:
+ fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+fail_dmxdev_release:
+ dvb_dmxdev_release(&fdtv->dmxdev);
+fail_dmx_release:
+ dvb_dmx_release(&fdtv->demux);
+fail_unreg_adapter:
+ dvb_unregister_adapter(&fdtv->adapter);
+fail_log:
+ dev_err(fdtv->device, "DVB initialization failed\n");
+ return err;
+}
+
+void fdtv_dvb_unregister(struct firedtv *fdtv)
+{
+ fdtv_ca_release(fdtv);
+ dvb_unregister_frontend(&fdtv->fe);
+ dvb_net_release(&fdtv->dvbnet);
+ fdtv->demux.dmx.close(&fdtv->demux.dmx);
+ fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
+ dvb_dmxdev_release(&fdtv->dmxdev);
+ dvb_dmx_release(&fdtv->demux);
+ dvb_unregister_adapter(&fdtv->adapter);
+}
+
+const char *fdtv_model_names[] = {
+ [FIREDTV_UNKNOWN] = "unknown type",
+ [FIREDTV_DVB_S] = "FireDTV S/CI",
+ [FIREDTV_DVB_C] = "FireDTV C/CI",
+ [FIREDTV_DVB_T] = "FireDTV T/CI",
+ [FIREDTV_DVB_S2] = "FireDTV S2 ",
+};
+
+struct firedtv *fdtv_alloc(struct device *dev,
+ const struct firedtv_backend *backend,
+ const char *name, size_t name_len)
+{
+ struct firedtv *fdtv;
+ int i;
+
+ fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
+ if (!fdtv)
+ return NULL;
+
+ dev->driver_data = fdtv;
+ fdtv->device = dev;
+ fdtv->isochannel = -1;
+ fdtv->voltage = 0xff;
+ fdtv->tone = 0xff;
+ fdtv->backend = backend;
+
+ mutex_init(&fdtv->avc_mutex);
+ init_waitqueue_head(&fdtv->avc_wait);
+ fdtv->avc_reply_received = true;
+ mutex_init(&fdtv->demux_mutex);
+ INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
+
+ for (i = ARRAY_SIZE(fdtv_model_names); --i; )
+ if (strlen(fdtv_model_names[i]) <= name_len &&
+ strncmp(name, fdtv_model_names[i], name_len) == 0)
+ break;
+ fdtv->type = i;
+
+ return fdtv;
+}
+
+#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
+ IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
+
+#define DIGITAL_EVERYWHERE_OUI 0x001287
+#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
+#define AVC_SW_VERSION_ENTRY 0x010001
+
+static struct ieee1394_device_id fdtv_id_table[] = {
+ {
+ /* FloppyDTV S/CI and FloppyDTV S2 */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000024,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FloppyDTV T/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000025,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FloppyDTV C/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000026,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV S/CI and FloppyDTV S2 */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000034,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV T/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000035,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {
+ /* FireDTV C/CI */
+ .match_flags = MATCH_FLAGS,
+ .vendor_id = DIGITAL_EVERYWHERE_OUI,
+ .model_id = 0x000036,
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
+ .version = AVC_SW_VERSION_ENTRY,
+ }, {}
+};
+MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
+
+static int __init fdtv_init(void)
+{
+ return fdtv_1394_init(fdtv_id_table);
+}
+
+static void __exit fdtv_exit(void)
+{
+ fdtv_1394_exit();
+}
+
+module_init(fdtv_init);
+module_exit(fdtv_exit);
+
+MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
+MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
+MODULE_DESCRIPTION("FireDTV DVB Driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c
new file mode 100644
index 000000000000..7ba43630a25d
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-fe.c
@@ -0,0 +1,247 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <dvb_frontend.h>
+
+#include "firedtv.h"
+
+static int fdtv_dvb_init(struct dvb_frontend *fe)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ int err;
+
+ /* FIXME - allocate free channel at IRM */
+ fdtv->isochannel = fdtv->adapter.num;
+
+ err = cmp_establish_pp_connection(fdtv, fdtv->subunit,
+ fdtv->isochannel);
+ if (err) {
+ dev_err(fdtv->device,
+ "could not establish point to point connection\n");
+ return err;
+ }
+
+ return fdtv->backend->start_iso(fdtv);
+}
+
+static int fdtv_sleep(struct dvb_frontend *fe)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->backend->stop_iso(fdtv);
+ cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
+ fdtv->isochannel = -1;
+ return 0;
+}
+
+#define LNBCONTROL_DONTCARE 0xff
+
+static int fdtv_diseqc_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ return avc_lnb_control(fdtv, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE,
+ LNBCONTROL_DONTCARE, 1, cmd);
+}
+
+static int fdtv_diseqc_send_burst(struct dvb_frontend *fe,
+ fe_sec_mini_cmd_t minicmd)
+{
+ return 0;
+}
+
+static int fdtv_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->tone = tone;
+ return 0;
+}
+
+static int fdtv_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ fdtv->voltage = voltage;
+ return 0;
+}
+
+static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ if (stat.no_rf)
+ *status = 0;
+ else
+ *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
+ FE_HAS_CARRIER | FE_HAS_LOCK;
+ return 0;
+}
+
+static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ *ber = stat.ber;
+ return 0;
+}
+
+static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ *strength = stat.signal_strength << 8;
+ return 0;
+}
+
+static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+ struct firedtv_tuner_status stat;
+
+ if (avc_tuner_status(fdtv, &stat))
+ return -EINVAL;
+
+ /* C/N[dB] = -10 * log10(snr / 65535) */
+ *snr = stat.carrier_noise_ratio * 257;
+ return 0;
+}
+
+static int fdtv_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ return -EOPNOTSUPP;
+}
+
+#define ACCEPTED 0x9
+
+static int fdtv_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct firedtv *fdtv = fe->sec_priv;
+
+ /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
+ if (avc_tuner_dsd(fdtv, params) != ACCEPTED)
+ return -EINVAL;
+ else
+ return 0; /* not sure of this... */
+}
+
+static int fdtv_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ return -EOPNOTSUPP;
+}
+
+void fdtv_frontend_init(struct firedtv *fdtv)
+{
+ struct dvb_frontend_ops *ops = &fdtv->fe.ops;
+ struct dvb_frontend_info *fi = &ops->info;
+
+ ops->init = fdtv_dvb_init;
+ ops->sleep = fdtv_sleep;
+
+ ops->set_frontend = fdtv_set_frontend;
+ ops->get_frontend = fdtv_get_frontend;
+
+ ops->read_status = fdtv_read_status;
+ ops->read_ber = fdtv_read_ber;
+ ops->read_signal_strength = fdtv_read_signal_strength;
+ ops->read_snr = fdtv_read_snr;
+ ops->read_ucblocks = fdtv_read_uncorrected_blocks;
+
+ ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd;
+ ops->diseqc_send_burst = fdtv_diseqc_send_burst;
+ ops->set_tone = fdtv_set_tone;
+ ops->set_voltage = fdtv_set_voltage;
+
+ switch (fdtv->type) {
+ case FIREDTV_DVB_S:
+ case FIREDTV_DVB_S2:
+ fi->type = FE_QPSK;
+
+ fi->frequency_min = 950000;
+ fi->frequency_max = 2150000;
+ fi->frequency_stepsize = 125;
+ fi->symbol_rate_min = 1000000;
+ fi->symbol_rate_max = 40000000;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 |
+ FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK;
+ break;
+
+ case FIREDTV_DVB_C:
+ fi->type = FE_QAM;
+
+ fi->frequency_min = 47000000;
+ fi->frequency_max = 866000000;
+ fi->frequency_stepsize = 62500;
+ fi->symbol_rate_min = 870000;
+ fi->symbol_rate_max = 6900000;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_QAM_16 |
+ FE_CAN_QAM_32 |
+ FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 |
+ FE_CAN_QAM_256 |
+ FE_CAN_QAM_AUTO;
+ break;
+
+ case FIREDTV_DVB_T:
+ fi->type = FE_OFDM;
+
+ fi->frequency_min = 49000000;
+ fi->frequency_max = 861000000;
+ fi->frequency_stepsize = 62500;
+
+ fi->caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO;
+ break;
+
+ default:
+ dev_err(fdtv->device, "no frontend for model type %d\n",
+ fdtv->type);
+ }
+ strcpy(fi->name, fdtv_model_names[fdtv->type]);
+
+ fdtv->fe.dvb = &fdtv->adapter;
+ fdtv->fe.sec_priv = fdtv;
+}
diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c
new file mode 100644
index 000000000000..46a6324d7b73
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv-rc.c
@@ -0,0 +1,190 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "firedtv.h"
+
+/* fixed table with older keycodes, geared towards MythTV */
+const static u16 oldtable[] = {
+
+ /* code from device: 0x4501...0x451f */
+
+ KEY_ESC,
+ KEY_F9,
+ KEY_1,
+ KEY_2,
+ KEY_3,
+ KEY_4,
+ KEY_5,
+ KEY_6,
+ KEY_7,
+ KEY_8,
+ KEY_9,
+ KEY_I,
+ KEY_0,
+ KEY_ENTER,
+ KEY_RED,
+ KEY_UP,
+ KEY_GREEN,
+ KEY_F10,
+ KEY_SPACE,
+ KEY_F11,
+ KEY_YELLOW,
+ KEY_DOWN,
+ KEY_BLUE,
+ KEY_Z,
+ KEY_P,
+ KEY_PAGEDOWN,
+ KEY_LEFT,
+ KEY_W,
+ KEY_RIGHT,
+ KEY_P,
+ KEY_M,
+
+ /* code from device: 0x4540...0x4542 */
+
+ KEY_R,
+ KEY_V,
+ KEY_C,
+};
+
+/* user-modifiable table for a remote as sold in 2008 */
+const static u16 keytable[] = {
+
+ /* code from device: 0x0300...0x031f */
+
+ [0x00] = KEY_POWER,
+ [0x01] = KEY_SLEEP,
+ [0x02] = KEY_STOP,
+ [0x03] = KEY_OK,
+ [0x04] = KEY_RIGHT,
+ [0x05] = KEY_1,
+ [0x06] = KEY_2,
+ [0x07] = KEY_3,
+ [0x08] = KEY_LEFT,
+ [0x09] = KEY_4,
+ [0x0a] = KEY_5,
+ [0x0b] = KEY_6,
+ [0x0c] = KEY_UP,
+ [0x0d] = KEY_7,
+ [0x0e] = KEY_8,
+ [0x0f] = KEY_9,
+ [0x10] = KEY_DOWN,
+ [0x11] = KEY_TITLE, /* "OSD" - fixme */
+ [0x12] = KEY_0,
+ [0x13] = KEY_F20, /* "16:9" - fixme */
+ [0x14] = KEY_SCREEN, /* "FULL" - fixme */
+ [0x15] = KEY_MUTE,
+ [0x16] = KEY_SUBTITLE,
+ [0x17] = KEY_RECORD,
+ [0x18] = KEY_TEXT,
+ [0x19] = KEY_AUDIO,
+ [0x1a] = KEY_RED,
+ [0x1b] = KEY_PREVIOUS,
+ [0x1c] = KEY_REWIND,
+ [0x1d] = KEY_PLAYPAUSE,
+ [0x1e] = KEY_NEXT,
+ [0x1f] = KEY_VOLUMEUP,
+
+ /* code from device: 0x0340...0x0354 */
+
+ [0x20] = KEY_CHANNELUP,
+ [0x21] = KEY_F21, /* "4:3" - fixme */
+ [0x22] = KEY_TV,
+ [0x23] = KEY_DVD,
+ [0x24] = KEY_VCR,
+ [0x25] = KEY_AUX,
+ [0x26] = KEY_GREEN,
+ [0x27] = KEY_YELLOW,
+ [0x28] = KEY_BLUE,
+ [0x29] = KEY_CHANNEL, /* "CH.LIST" */
+ [0x2a] = KEY_VENDOR, /* "CI" - fixme */
+ [0x2b] = KEY_VOLUMEDOWN,
+ [0x2c] = KEY_CHANNELDOWN,
+ [0x2d] = KEY_LAST,
+ [0x2e] = KEY_INFO,
+ [0x2f] = KEY_FORWARD,
+ [0x30] = KEY_LIST,
+ [0x31] = KEY_FAVORITES,
+ [0x32] = KEY_MENU,
+ [0x33] = KEY_EPG,
+ [0x34] = KEY_EXIT,
+};
+
+int fdtv_register_rc(struct firedtv *fdtv, struct device *dev)
+{
+ struct input_dev *idev;
+ int i, err;
+
+ idev = input_allocate_device();
+ if (!idev)
+ return -ENOMEM;
+
+ fdtv->remote_ctrl_dev = idev;
+ idev->name = "FireDTV remote control";
+ idev->dev.parent = dev;
+ idev->evbit[0] = BIT_MASK(EV_KEY);
+ idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
+ if (!idev->keycode) {
+ err = -ENOMEM;
+ goto fail;
+ }
+ idev->keycodesize = sizeof(keytable[0]);
+ idev->keycodemax = ARRAY_SIZE(keytable);
+
+ for (i = 0; i < ARRAY_SIZE(keytable); i++)
+ set_bit(keytable[i], idev->keybit);
+
+ err = input_register_device(idev);
+ if (err)
+ goto fail_free_keymap;
+
+ return 0;
+
+fail_free_keymap:
+ kfree(idev->keycode);
+fail:
+ input_free_device(idev);
+ return err;
+}
+
+void fdtv_unregister_rc(struct firedtv *fdtv)
+{
+ kfree(fdtv->remote_ctrl_dev->keycode);
+ input_unregister_device(fdtv->remote_ctrl_dev);
+}
+
+void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
+{
+ u16 *keycode = fdtv->remote_ctrl_dev->keycode;
+
+ if (code >= 0x0300 && code <= 0x031f)
+ code = keycode[code - 0x0300];
+ else if (code >= 0x0340 && code <= 0x0354)
+ code = keycode[code - 0x0320];
+ else if (code >= 0x4501 && code <= 0x451f)
+ code = oldtable[code - 0x4501];
+ else if (code >= 0x4540 && code <= 0x4542)
+ code = oldtable[code - 0x4521];
+ else {
+ printk(KERN_DEBUG "firedtv: invalid key code 0x%04x "
+ "from remote control\n", code);
+ return;
+ }
+
+ input_report_key(fdtv->remote_ctrl_dev, code, 1);
+ input_report_key(fdtv->remote_ctrl_dev, code, 0);
+}
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
new file mode 100644
index 000000000000..d48530b81e61
--- /dev/null
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -0,0 +1,182 @@
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef _FIREDTV_H
+#define _FIREDTV_H
+
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/frontend.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <demux.h>
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
+#include <dvb_net.h>
+#include <dvbdev.h>
+
+struct firedtv_tuner_status {
+ unsigned active_system:8;
+ unsigned searching:1;
+ unsigned moving:1;
+ unsigned no_rf:1;
+ unsigned input:1;
+ unsigned selected_antenna:7;
+ unsigned ber:32;
+ unsigned signal_strength:8;
+ unsigned raster_frequency:2;
+ unsigned rf_frequency:22;
+ unsigned man_dep_info_length:8;
+ unsigned front_end_error:1;
+ unsigned antenna_error:1;
+ unsigned front_end_power_status:1;
+ unsigned power_supply:1;
+ unsigned carrier_noise_ratio:16;
+ unsigned power_supply_voltage:8;
+ unsigned antenna_voltage:8;
+ unsigned firewire_bus_voltage:8;
+ unsigned ca_mmi:1;
+ unsigned ca_pmt_reply:1;
+ unsigned ca_date_time_request:1;
+ unsigned ca_application_info:1;
+ unsigned ca_module_present_status:1;
+ unsigned ca_dvb_flag:1;
+ unsigned ca_error_flag:1;
+ unsigned ca_initialization_status:1;
+};
+
+enum model_type {
+ FIREDTV_UNKNOWN = 0,
+ FIREDTV_DVB_S = 1,
+ FIREDTV_DVB_C = 2,
+ FIREDTV_DVB_T = 3,
+ FIREDTV_DVB_S2 = 4,
+};
+
+struct device;
+struct input_dev;
+struct firedtv;
+
+struct firedtv_backend {
+ int (*lock)(struct firedtv *fdtv, u64 addr, void *data, __be32 arg);
+ int (*read)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+ int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
+ int (*start_iso)(struct firedtv *fdtv);
+ void (*stop_iso)(struct firedtv *fdtv);
+};
+
+struct firedtv {
+ struct device *device;
+ struct list_head list;
+
+ struct dvb_adapter adapter;
+ struct dmxdev dmxdev;
+ struct dvb_demux demux;
+ struct dmx_frontend frontend;
+ struct dvb_net dvbnet;
+ struct dvb_frontend fe;
+
+ struct dvb_device *cadev;
+ int ca_last_command;
+ int ca_time_interval;
+
+ struct mutex avc_mutex;
+ wait_queue_head_t avc_wait;
+ bool avc_reply_received;
+ struct work_struct remote_ctrl_work;
+ struct input_dev *remote_ctrl_dev;
+
+ enum model_type type;
+ char subunit;
+ char isochannel;
+ fe_sec_voltage_t voltage;
+ fe_sec_tone_mode_t tone;
+
+ const struct firedtv_backend *backend;
+ void *backend_data;
+
+ struct mutex demux_mutex;
+ unsigned long channel_active;
+ u16 channel_pid[16];
+
+ size_t response_length;
+ u8 response[512];
+};
+
+/* firedtv-1394.c */
+#ifdef CONFIG_DVB_FIREDTV_IEEE1394
+int fdtv_1394_init(struct ieee1394_device_id id_table[]);
+void fdtv_1394_exit(void);
+#else
+static inline int fdtv_1394_init(struct ieee1394_device_id it[]) { return 0; }
+static inline void fdtv_1394_exit(void) {}
+#endif
+
+/* firedtv-avc.c */
+int avc_recv(struct firedtv *fdtv, void *data, size_t length);
+int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat);
+struct dvb_frontend_parameters;
+int avc_tuner_dsd(struct firedtv *fdtv, struct dvb_frontend_parameters *params);
+int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]);
+int avc_tuner_get_ts(struct firedtv *fdtv);
+int avc_identify_subunit(struct firedtv *fdtv);
+struct dvb_diseqc_master_cmd;
+int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
+ char conttone, char nrdiseq,
+ struct dvb_diseqc_master_cmd *diseqcmd);
+void avc_remote_ctrl_work(struct work_struct *work);
+int avc_register_remote_control(struct firedtv *fdtv);
+int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
+int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len);
+int avc_ca_reset(struct firedtv *fdtv);
+int avc_ca_pmt(struct firedtv *fdtv, char *app_info, int length);
+int avc_ca_get_time_date(struct firedtv *fdtv, int *interval);
+int avc_ca_enter_menu(struct firedtv *fdtv);
+int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len);
+int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel);
+void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel);
+
+/* firedtv-ci.c */
+int fdtv_ca_register(struct firedtv *fdtv);
+void fdtv_ca_release(struct firedtv *fdtv);
+
+/* firedtv-dvb.c */
+int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
+int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
+int fdtv_dvb_register(struct firedtv *fdtv);
+void fdtv_dvb_unregister(struct firedtv *fdtv);
+struct firedtv *fdtv_alloc(struct device *dev,
+ const struct firedtv_backend *backend,
+ const char *name, size_t name_len);
+extern const char *fdtv_model_names[];
+
+/* firedtv-fe.c */
+void fdtv_frontend_init(struct firedtv *fdtv);
+
+/* firedtv-rc.c */
+#ifdef CONFIG_DVB_FIREDTV_INPUT
+int fdtv_register_rc(struct firedtv *fdtv, struct device *dev);
+void fdtv_unregister_rc(struct firedtv *fdtv);
+void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code);
+#else
+static inline int fdtv_register_rc(struct firedtv *fdtv,
+ struct device *dev) { return 0; }
+static inline void fdtv_unregister_rc(struct firedtv *fdtv) {}
+static inline void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) {}
+#endif
+
+#endif /* _FIREDTV_H */
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index 28ad609e73f4..ba1e24c82272 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -15,6 +15,9 @@
September, 9th 2008
Fixed locking on high symbol rates (>30000).
Implement MPEG initialization parameter.
+ January, 17th 2009
+ Fill set_voltage with actually control voltage code.
+ Correct set tone to not affect voltage.
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
@@ -146,7 +149,7 @@ enum cmds {
CMD_GETAGC = 0x19,
CMD_LNBCONFIG = 0x20,
CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
- CMD_SET_TONEPRE = 0x22,
+ CMD_LNBDCLEVEL = 0x22,
CMD_SET_TONE = 0x23,
CMD_UPDFWVERS = 0x35,
CMD_TUNERSLEEP = 0x36,
@@ -667,16 +670,6 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
return 0;
}
-static int cx24116_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
-{
- /* The isl6421 module will override this function in the fops. */
- dprintk("%s() This should never appear if the isl6421 module "
- "is loaded correctly\n", __func__);
-
- return -EOPNOTSUPP;
-}
-
static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct cx24116_state *state = fe->demodulator_priv;
@@ -837,6 +830,34 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
return -ETIMEDOUT; /* -EBUSY ? */
}
+static int cx24116_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct cx24116_cmd cmd;
+ int ret;
+
+ dprintk("%s: %s\n", __func__,
+ voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+ voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+ /* Wait for LNB ready */
+ ret = cx24116_wait_for_lnb(fe);
+ if (ret != 0)
+ return ret;
+
+ /* Wait for voltage/min repeat delay */
+ msleep(100);
+
+ cmd.args[0x00] = CMD_LNBDCLEVEL;
+ cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
+ cmd.len = 0x02;
+
+ /* Min delay time before DiSEqC send */
+ msleep(15);
+
+ return cx24116_cmd_execute(fe, &cmd);
+}
+
static int cx24116_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t tone)
{
@@ -857,14 +878,6 @@ static int cx24116_set_tone(struct dvb_frontend *fe,
/* Min delay time after DiSEqC send */
msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
- /* This is always done before the tone is set */
- cmd.args[0x00] = CMD_SET_TONEPRE;
- cmd.args[0x01] = 0x00;
- cmd.len = 0x02;
- ret = cx24116_cmd_execute(fe, &cmd);
- if (ret != 0)
- return ret;
-
/* Now we set the tone */
cmd.args[0x00] = CMD_SET_TONE;
cmd.args[0x01] = 0x00;
@@ -1154,7 +1167,12 @@ static int cx24116_initfe(struct dvb_frontend *fe)
if (ret != 0)
return ret;
- return cx24116_diseqc_init(fe);
+ ret = cx24116_diseqc_init(fe);
+ if (ret != 0)
+ return ret;
+
+ /* HVR-4000 needs this */
+ return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
}
/*
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index ec4e08dbc699..1e81e713df63 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -646,7 +646,7 @@ static int drx_tune(struct drx397xD_state *s,
u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
- int rc, df_tuner;
+ int rc, df_tuner = 0;
int a, b, c, d;
pr_debug("%s %d\n", __func__, s->config.d60);
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 8fe094bd9689..b8745887492c 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -28,14 +28,14 @@
#define _LNBP21_H
/* system register bits */
-#define LNBP21_OLF 0x01
-#define LNBP21_OTF 0x02
-#define LNBP21_EN 0x04
-#define LNBP21_VSEL 0x08
-#define LNBP21_LLC 0x10
-#define LNBP21_TEN 0x20
-#define LNBP21_ISEL 0x40
-#define LNBP21_PCL 0x80
+#define LNBP21_OLF 0x01 /* [R-only] 0=OK; 1=over current limit flag*/
+#define LNBP21_OTF 0x02 /* [R-only] 0=OK; 1=over temperature flag (150degC typ) */
+#define LNBP21_EN 0x04 /* [RW] 0=disable LNB power, enable loopthrough; 1=enable LNB power, disable loopthrough*/
+#define LNBP21_VSEL 0x08 /* [RW] 0=low voltage (13/14V, vert pol); 1=high voltage (18/19V,horiz pol) */
+#define LNBP21_LLC 0x10 /* [RW] increase LNB voltage by 1V: 0=13/18V; 1=14/19V */
+#define LNBP21_TEN 0x20 /* [RW] 0=tone controlled by DSQIN pin; 1=tone enable, disable DSQIN */
+#define LNBP21_ISEL 0x40 /* [RW] current limit select 0:Iout=500-650mA,Isc=300mA ; 1:Iout=400-550mA,Isc=200mA*/
+#define LNBP21_PCL 0x80 /* [RW] short-circuit prot: 0=pulsed (dynamic) curr limiting; 1=static curr limiting*/
#include <linux/dvb/frontend.h>
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index cf4d8936bb83..3e08d985d6e5 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -545,9 +545,6 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
s5h1409_enable_modulation(fe, p->u.vsb.modulation);
- /* Allow the demod to settle */
- msleep(100);
-
if (fe->ops.tuner_ops.set_params) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -562,6 +559,10 @@ static int s5h1409_set_frontend(struct dvb_frontend *fe,
s5h1409_set_qam_interleave_mode(fe);
}
+ /* Issue a reset to the demod so it knows to resync against the
+ newly tuned frequency */
+ s5h1409_softreset(fe);
+
return 0;
}
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
index 83dc7e12d5f0..a67d1775a43c 100644
--- a/drivers/media/dvb/frontends/stb0899_algo.c
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -31,6 +31,8 @@ inline u32 stb0899_do_div(u64 n, u32 d)
return n;
}
+#if 0
+/* These functions are currently unused */
/*
* stb0899_calc_srate
* Compute symbol rate
@@ -63,6 +65,7 @@ static u32 stb0899_get_srate(struct stb0899_state *state)
return stb0899_calc_srate(internal->master_clk, sfr);
}
+#endif
/*
* stb0899_set_srate
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 1465ff77b0cb..4981cef8b444 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
if (ret != 2) {
dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
ret);
- return -1;
+ return -EINVAL;
}
dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
@@ -481,16 +481,18 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
static int tda10046_fwupload(struct dvb_frontend* fe)
{
struct tda1004x_state* state = fe->demodulator_priv;
- int ret;
+ int ret, confc4;
const struct firmware *fw;
/* reset + wake up chip */
if (state->config->xtal_freq == TDA10046_XTAL_4M) {
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+ confc4 = 0;
} else {
dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+ confc4 = 0x80;
}
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
/* set GPIO 1 and 3 */
if (state->config->gpio_config != TDA10046_GPTRI) {
@@ -508,13 +510,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /*
+ For i2c normal work, we need to slow down the bus speed.
+ However, the slow down breaks the eeprom firmware load.
+ So, use normal speed for eeprom booting and then restore the
+ i2c speed after that. Tested with MSI TV @nyware A/D board,
+ that comes with firmware version 29 inside their eeprom.
+
+ It should also be noticed that no other I2C transfer should
+ be in course while booting from eeprom, otherwise, tda10046
+ goes into an instable state. So, proper locking are needed
+ at the i2c bus master.
+ */
printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
- tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
msleep(300);
- /* don't re-upload unless necessary */
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
+ /* Checks if eeprom firmware went without troubles */
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /* eeprom firmware didn't work. Load one manually. */
+
if (state->config->request_firmware != NULL) {
/* request the firmware, this will block until someone uploads it */
printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 4307e4e8aa34..79f5715c01fd 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -46,6 +46,8 @@ struct usb_device_id smsusb_id_table[] = {
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
{ USB_DEVICE(0x2040, 0x2010),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2011),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
{ USB_DEVICE(0x2040, 0x2019),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
{ USB_DEVICE(0x2040, 0x5500),
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index aa1ff524256e..4624cee93e74 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -725,7 +725,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file,
}
-static struct file_operations dvb_osd_fops = {
+static const struct file_operations dvb_osd_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index bdc62acf2099..e4d0900d5121 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -1456,7 +1456,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file)
* driver registration
******************************************************************************/
-static struct file_operations dvb_video_fops = {
+static const struct file_operations dvb_video_fops = {
.owner = THIS_MODULE,
.write = dvb_video_write,
.ioctl = dvb_generic_ioctl,
@@ -1474,7 +1474,7 @@ static struct dvb_device dvbdev_video = {
.kernel_ioctl = dvb_video_ioctl,
};
-static struct file_operations dvb_audio_fops = {
+static const struct file_operations dvb_audio_fops = {
.owner = THIS_MODULE,
.write = dvb_audio_write,
.ioctl = dvb_generic_ioctl,
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index 261135ded481..c7a65b1544a3 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -345,7 +345,7 @@ static ssize_t dvb_ca_read(struct file *file, char __user *buf,
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
}
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_read,
.write = dvb_ca_write,
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index c5b9c70563dc..2210cff738e6 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -316,253 +316,261 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
return 0;
}
-static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
{
- struct saa7146_dev *dev = fh->dev;
- struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
- dprintk(4, "saa7146_dev: %p\n", dev);
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 stereo_det;
+ s8 stereo;
- switch (cmd) {
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- u16 stereo_det;
- s8 stereo;
+ dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
- dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
+ if (!av7110->analog_tuner_flags || t->index != 0)
+ return -EINVAL;
- if (!av7110->analog_tuner_flags || t->index != 0)
- return -EINVAL;
+ memset(t, 0, sizeof(*t));
+ strcpy((char *)t->name, "Television");
+
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+ t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
+ t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
+ /* FIXME: add the real signal strength here */
+ t->signal = 0xffff;
+ t->afc = 0;
+
+ /* FIXME: standard / stereo detection is still broken */
+ msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
+ msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
+ stereo = (s8)(stereo_det >> 8);
+ if (stereo > 0x10) {
+ /* stereo */
+ t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ } else if (stereo < -0x10) {
+ /* bilingual */
+ t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+ t->audmode = V4L2_TUNER_MODE_LANG1;
+ } else /* mono */
+ t->rxsubchans = V4L2_TUNER_SUB_MONO;
- memset(t, 0, sizeof(*t));
- strcpy((char *)t->name, "Television");
-
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
- t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
- /* FIXME: add the real signal strength here */
- t->signal = 0xffff;
- t->afc = 0;
-
- // FIXME: standard / stereo detection is still broken
- msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
- dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
- msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
- dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
- stereo = (s8)(stereo_det >> 8);
- if (stereo > 0x10) {
- /* stereo */
- t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
- t->audmode = V4L2_TUNER_MODE_STEREO;
- }
- else if (stereo < -0x10) {
- /* bilingual */
- t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- t->audmode = V4L2_TUNER_MODE_LANG1;
- }
- else /* mono */
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
- u16 fm_matrix, src;
- dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 fm_matrix, src;
+ dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- switch (t->audmode) {
- case V4L2_TUNER_MODE_STEREO:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
- fm_matrix = 0x3001; // stereo
- src = 0x0020;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
- fm_matrix = 0x3000; // bilingual
- src = 0x0020;
- break;
- case V4L2_TUNER_MODE_LANG1:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
- fm_matrix = 0x3000; // mono
- src = 0x0000;
- break;
- case V4L2_TUNER_MODE_LANG2:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
- fm_matrix = 0x3000; // mono
- src = 0x0010;
- break;
- default: /* case V4L2_TUNER_MODE_MONO: */
- dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
- fm_matrix = 0x3000; // mono
- src = 0x0030;
- break;
- }
- msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
- msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
- msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
- msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
- return 0;
+ switch (t->audmode) {
+ case V4L2_TUNER_MODE_STEREO:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
+ fm_matrix = 0x3001; /* stereo */
+ src = 0x0020;
+ break;
+ case V4L2_TUNER_MODE_LANG1_LANG2:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
+ fm_matrix = 0x3000; /* bilingual */
+ src = 0x0020;
+ break;
+ case V4L2_TUNER_MODE_LANG1:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0000;
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0010;
+ break;
+ default: /* case V4L2_TUNER_MODE_MONO: */
+ dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0030;
+ break;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
+ msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
+ return 0;
+}
- dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
- memset(f, 0, sizeof(*f));
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = av7110->current_freq;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
+ memset(f, 0, sizeof(*f));
+ f->type = V4L2_TUNER_ANALOG_TV;
+ f->frequency = av7110->current_freq;
+ return 0;
+}
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+ dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- /* tune in desired frequency */
- if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
- ves1820_set_tv_freq(dev, f->frequency);
- } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
- stv0297_set_tv_freq(dev, f->frequency);
- }
- av7110->current_freq = f->frequency;
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
- msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
- return 0;
- }
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
- dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+ /* tune in desired frequency */
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
+ ves1820_set_tv_freq(dev, f->frequency);
+ else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
+ stv0297_set_tv_freq(dev, f->frequency);
+ av7110->current_freq = f->frequency;
- if (av7110->analog_tuner_flags) {
- if (i->index < 0 || i->index >= 4)
- return -EINVAL;
- } else {
- if (i->index != 0)
- return -EINVAL;
- }
+ msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
+ return 0;
+}
- memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- return 0;
+ dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+
+ if (av7110->analog_tuner_flags) {
+ if (i->index < 0 || i->index >= 4)
+ return -EINVAL;
+ } else {
+ if (i->index != 0)
+ return -EINVAL;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = av7110->current_input;
- dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+
+ memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ *input = av7110->current_input;
+ dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+
+ if (!av7110->analog_tuner_flags)
return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+ if (input < 0 || input >= 4)
+ return -EINVAL;
- if (!av7110->analog_tuner_flags)
- return 0;
+ av7110->current_input = input;
+ return av7110_dvb_c_switch(fh);
+}
- if (input < 0 || input >= 4)
- return -EINVAL;
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
+ if (a->index != 0)
+ return -EINVAL;
+ memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
+ return 0;
+}
- av7110->current_input = input;
- return av7110_dvb_c_switch(fh);
- }
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
+ return 0;
+}
- dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
- if (a->index != 0)
- return -EINVAL;
- memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
- break;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *a = arg;
- dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
- break;
- }
- case VIDIOC_G_SLICED_VBI_CAP:
- {
- struct v4l2_sliced_vbi_cap *cap = arg;
- dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
- memset(cap, 0, sizeof *cap);
- if (FW_VERSION(av7110->arm_app) >= 0x2623) {
- cap->service_set = V4L2_SLICED_WSS_625;
- cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
- }
- break;
- }
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
- dprintk(2, "VIDIOC_G_FMT:\n");
- if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
- FW_VERSION(av7110->arm_app) < 0x2623)
- return -EAGAIN; /* handled by core driver */
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- if (av7110->wssMode) {
- f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
- f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
- f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
- }
- break;
+static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_sliced_vbi_cap *cap)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
+ if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+ return -EINVAL;
+ if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+ cap->service_set = V4L2_SLICED_WSS_625;
+ cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
- dprintk(2, "VIDIOC_S_FMT\n");
- if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
- FW_VERSION(av7110->arm_app) < 0x2623)
- return -EAGAIN; /* handled by core driver */
- if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
- f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- /* WSS controlled by firmware */
- av7110->wssMode = 0;
- av7110->wssData = 0;
- return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
- SetWSSConfig, 1, 0);
- } else {
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
- f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
- f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
- /* WSS controlled by userspace */
- av7110->wssMode = 1;
- av7110->wssData = 0;
- }
- break;
+ return 0;
+}
+
+static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_FMT:\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+ if (av7110->wssMode) {
+ f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
}
- default:
- printk("no such ioctl\n");
- return -ENOIOCTLCMD;
+ return 0;
+}
+
+static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_FMT\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
+ f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
+ memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+ /* WSS controlled by firmware */
+ av7110->wssMode = 0;
+ av7110->wssData = 0;
+ return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
+ SetWSSConfig, 1, 0);
+ } else {
+ memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+ f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
+ /* WSS controlled by userspace */
+ av7110->wssMode = 1;
+ av7110->wssData = 0;
}
return 0;
}
@@ -609,22 +617,6 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size
* INITIALIZATION
****************************************************************************/
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FMT, SAA7146_BEFORE },
- { VIDIOC_S_FMT, SAA7146_BEFORE },
- { 0, 0 }
-};
-
static u8 saa7113_init_regs[] = {
0x02, 0xd0,
0x03, 0x23,
@@ -788,20 +780,34 @@ int av7110_init_analog_module(struct av7110 *av7110)
int av7110_init_v4l(struct av7110 *av7110)
{
struct saa7146_dev* dev = av7110->dev;
+ struct saa7146_ext_vv *vv_data;
int ret;
/* special case DVB-C: these cards have an analog tuner
plus need some special handling, so we have separate
saa7146_ext_vv data for these... */
if (av7110->analog_tuner_flags)
- ret = saa7146_vv_init(dev, &av7110_vv_data_c);
+ vv_data = &av7110_vv_data_c;
else
- ret = saa7146_vv_init(dev, &av7110_vv_data_st);
+ vv_data = &av7110_vv_data_st;
+ ret = saa7146_vv_init(dev, vv_data);
if (ret) {
ERR(("cannot init capture device. skipping.\n"));
return -ENODEV;
}
+ vv_data->ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data->ops.vidioc_g_input = vidioc_g_input;
+ vv_data->ops.vidioc_s_input = vidioc_s_input;
+ vv_data->ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data->ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data->ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data->ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data->ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data->ops.vidioc_s_audio = vidioc_s_audio;
+ vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
+ vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
+ vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
ERR(("cannot register capture device. skipping.\n"));
@@ -900,9 +906,6 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = av7110_ioctl,
-
.vbi_fops.open = av7110_vbi_reset,
.vbi_fops.release = av7110_vbi_reset,
.vbi_fops.write = av7110_vbi_write,
@@ -918,9 +921,6 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = av7110_ioctl,
-
.vbi_fops.open = av7110_vbi_reset,
.vbi_fops.release = av7110_vbi_reset,
.vbi_fops.write = av7110_vbi_write,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 4182121d7e5d..855fe74b640b 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1404,6 +1404,41 @@ static int budget_av_detach(struct saa7146_dev *dev)
return err;
}
+#define KNC1_INPUTS 2
+static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
+ {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+ {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+};
+
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
+ if (i->index < 0 || i->index >= KNC1_INPUTS)
+ return -EINVAL;
+ memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ *i = budget_av->cur_input;
+
+ dprintk(1, "VIDIOC_G_INPUT %d.\n", *i);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
+ return saa7113_setinput(budget_av, input);
+}
+
static struct saa7146_ext_vv vv_data;
static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
@@ -1442,6 +1477,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
ERR(("cannot init vv subsystem.\n"));
return err;
}
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
/* fixme: proper cleanup here */
@@ -1480,54 +1518,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
return 0;
}
-#define KNC1_INPUTS 2
-static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
- {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
- {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
-};
-
-static struct saa7146_extension_ioctls ioctls[] = {
- {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
- {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
- {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
- {0, 0}
-};
-
-static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
-
- switch (cmd) {
- case VIDIOC_ENUMINPUT:{
- struct v4l2_input *i = arg;
-
- dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
- if (i->index < 0 || i->index >= KNC1_INPUTS) {
- return -EINVAL;
- }
- memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
- }
- case VIDIOC_G_INPUT:{
- int *input = (int *) arg;
-
- *input = budget_av->cur_input;
-
- dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
- return 0;
- }
- case VIDIOC_S_INPUT:{
- int input = *(int *) arg;
- dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
- return saa7113_setinput(budget_av, input);
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static struct saa7146_standard standard[] = {
{.name = "PAL",.id = V4L2_STD_PAL,
.v_offset = 0x17,.v_field = 288,
@@ -1546,8 +1536,6 @@ static struct saa7146_ext_vv vv_data = {
.flags = 0,
.stds = &standard[0],
.num_stds = ARRAY_SIZE(standard),
- .ioctls = &ioctls[0],
- .ioctl = av_ioctl,
};
static struct saa7146_extension budget_extension;
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 1638e1d9f538..83e9e7750c8c 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -470,6 +470,7 @@ static void frontend_init(struct budget *budget)
budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap);
if (budget->dvb_frontend) {
budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params;
+ budget->dvb_frontend->tuner_priv = NULL;
break;
}
break;
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 0aa96df80fc2..d91e0638448f 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1384,7 +1384,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
static int ttusb_dec_init_stb(struct ttusb_dec *dec)
{
int result;
- unsigned int mode, model, version;
+ unsigned int mode = 0, model = 0, version = 0;
dprintk("%s\n", __func__);
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 2014ebc4e984..cc54ed4efc48 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -390,9 +390,11 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct dsbr100_device *radio = video_drvdata(file);
+
strlcpy(v->driver, "dsbr100", sizeof(v->driver));
strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "USB");
+ usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER;
return 0;
@@ -450,7 +452,10 @@ static int vidioc_s_frequency(struct file *file, void *priv,
if (radio->removed)
return -EIO;
+ mutex_lock(&radio->lock);
radio->curfreq = f->frequency;
+ mutex_unlock(&radio->lock);
+
retval = dsbr100_setfreq(radio, radio->curfreq);
if (retval < 0)
dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
@@ -601,7 +606,10 @@ static int usb_dsbr100_close(struct file *file)
if (!radio)
return -ENODEV;
+ mutex_lock(&radio->lock);
radio->users = 0;
+ mutex_unlock(&radio->lock);
+
if (!radio->removed) {
retval = dsbr100_stop(radio);
if (retval < 0) {
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index 0747dc8862b0..ded25bfb366e 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -22,7 +22,7 @@
*/
/*
- * Big thanks to authors of dsbr100.c and radio-si470x.c
+ * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c
*
* When work was looked pretty good, i discover this:
* http://av-usbradio.sourceforge.net/index.php
@@ -30,18 +30,23 @@
* Latest release of theirs project was in 2005.
* Probably, this driver could be improved trough using their
* achievements (specifications given).
- * So, we have smth to begin with.
+ * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
+ * in 2007. He allowed to use his driver to improve current mr800 radio driver.
+ * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492
*
- * History:
* Version 0.01: First working version.
* It's required to blacklist AverMedia USB Radio
* in usbhid/hid-quirks.c
+ * Version 0.10: A lot of cleanups and fixes: unpluging the device,
+ * few mutex locks were added, codinstyle issues, etc.
+ * Added stereo support. Thanks to
+ * Douglas Schilling Landgraf <dougsland@gmail.com> and
+ * David Ellingsworth <david@identd.dyndns.org>
+ * for discussion, help and support.
*
* Many things to do:
* - Correct power managment of device (suspend & resume)
- * - Make x86 independance (little-endian and big-endian stuff)
* - Add code for scanning and smooth tuning
- * - Checked and add stereo&mono stuff
* - Add code for sensitivity value
* - Correct mistakes
* - In Japan another FREQ_MIN and FREQ_MAX
@@ -62,8 +67,8 @@
/* driver and module definitions */
#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
-#define DRIVER_VERSION "0.01"
-#define RADIO_VERSION KERNEL_VERSION(0, 0, 1)
+#define DRIVER_VERSION "0.10"
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 0)
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -87,6 +92,22 @@ devices, that would be 76 and 91. */
#define FREQ_MAX 108.0
#define FREQ_MUL 16000
+/*
+ * Commands that device should understand
+ * List isnt full and will be updated with implementation of new functions
+ */
+#define AMRADIO_SET_FREQ 0xa4
+#define AMRADIO_SET_MUTE 0xab
+#define AMRADIO_SET_MONO 0xae
+
+/* Comfortable defines for amradio_set_mute */
+#define AMRADIO_START 0x00
+#define AMRADIO_STOP 0x01
+
+/* Comfortable defines for amradio_set_stereo */
+#define WANT_STEREO 0x00
+#define WANT_MONO 0x01
+
/* module parameter */
static int radio_nr = -1;
module_param(radio_nr, int, 0);
@@ -169,43 +190,48 @@ static struct usb_driver usb_amradio_driver = {
.supports_autosuspend = 0,
};
-/* switch on radio. Send 8 bytes to device. */
-static int amradio_start(struct amradio_device *radio)
+/* switch on/off the radio. Send 8 bytes to device */
+static int amradio_set_mute(struct amradio_device *radio, char argument)
{
int retval;
int size;
+ /* safety check */
+ if (radio->removed)
+ return -EIO;
+
mutex_lock(&radio->lock);
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
radio->buffer[3] = 0x00;
- radio->buffer[4] = 0xab;
- radio->buffer[5] = 0x00;
+ radio->buffer[4] = AMRADIO_SET_MUTE;
+ radio->buffer[5] = argument;
radio->buffer[6] = 0x00;
radio->buffer[7] = 0x00;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
mutex_unlock(&radio->lock);
return retval;
}
- mutex_unlock(&radio->lock);
+ radio->muted = argument;
- radio->muted = 0;
+ mutex_unlock(&radio->lock);
return retval;
}
-/* switch off radio */
-static int amradio_stop(struct amradio_device *radio)
+/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
+static int amradio_setfreq(struct amradio_device *radio, int freq)
{
int retval;
int size;
+ unsigned short freq_send = 0x10 + (freq >> 3) / 25;
/* safety check */
if (radio->removed)
@@ -216,33 +242,46 @@ static int amradio_stop(struct amradio_device *radio)
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
- radio->buffer[3] = 0x00;
- radio->buffer[4] = 0xab;
- radio->buffer[5] = 0x01;
+ radio->buffer[3] = 0x03;
+ radio->buffer[4] = AMRADIO_SET_FREQ;
+ radio->buffer[5] = 0x00;
radio->buffer[6] = 0x00;
+ radio->buffer[7] = 0x08;
+
+ retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
+ (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
+
+ if (retval < 0 || size != BUFFER_LENGTH) {
+ mutex_unlock(&radio->lock);
+ return retval;
+ }
+
+ /* frequency is calculated from freq_send and placed in first 2 bytes */
+ radio->buffer[0] = (freq_send >> 8) & 0xff;
+ radio->buffer[1] = freq_send & 0xff;
+ radio->buffer[2] = 0x01;
+ radio->buffer[3] = 0x00;
+ radio->buffer[4] = 0x00;
+ /* 5 and 6 bytes of buffer already = 0x00 */
radio->buffer[7] = 0x00;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
mutex_unlock(&radio->lock);
return retval;
}
mutex_unlock(&radio->lock);
- radio->muted = 1;
-
return retval;
}
-/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
-static int amradio_setfreq(struct amradio_device *radio, int freq)
+static int amradio_set_stereo(struct amradio_device *radio, char argument)
{
int retval;
int size;
- unsigned short freq_send = 0x13 + (freq >> 3) / 25;
/* safety check */
if (radio->removed)
@@ -253,50 +292,33 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
- radio->buffer[3] = 0x03;
- radio->buffer[4] = 0xa4;
- radio->buffer[5] = 0x00;
- radio->buffer[6] = 0x00;
- radio->buffer[7] = 0x08;
-
- retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
- (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
-
- if (retval) {
- mutex_unlock(&radio->lock);
- return retval;
- }
-
- /* frequency is calculated from freq_send and placed in first 2 bytes */
- radio->buffer[0] = (freq_send >> 8) & 0xff;
- radio->buffer[1] = freq_send & 0xff;
- radio->buffer[2] = 0x01;
radio->buffer[3] = 0x00;
- radio->buffer[4] = 0x00;
- /* 5 and 6 bytes of buffer already = 0x00 */
+ radio->buffer[4] = AMRADIO_SET_MONO;
+ radio->buffer[5] = argument;
+ radio->buffer[6] = 0x00;
radio->buffer[7] = 0x00;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
+ radio->stereo = -1;
mutex_unlock(&radio->lock);
return retval;
}
- mutex_unlock(&radio->lock);
+ radio->stereo = 1;
- radio->stereo = 0;
+ mutex_unlock(&radio->lock);
return retval;
}
-/* USB subsystem interface begins here */
-
-/* handle unplugging of the device, release data structures
-if nothing keeps us from doing it. If something is still
-keeping us busy, the release callback of v4l will take care
-of releasing it. */
+/* Handle unplugging the device.
+ * We call video_unregister_device in any case.
+ * The last function called in this procedure is
+ * usb_amradio_device_release.
+ */
static void usb_amradio_disconnect(struct usb_interface *intf)
{
struct amradio_device *radio = usb_get_intfdata(intf);
@@ -313,9 +335,11 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct amradio_device *radio = video_drvdata(file);
+
strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "USB");
+ usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER;
return 0;
@@ -326,6 +350,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -337,7 +362,16 @@ static int vidioc_g_tuner(struct file *file, void *priv,
/* TODO: Add function which look is signal stereo or not
* amradio_getstat(radio);
*/
- radio->stereo = -1;
+
+/* we call amradio_set_stereo to set radio->stereo
+ * Honestly, amradio_getstat should cover this in future and
+ * amradio_set_stereo shouldn't be here
+ */
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+
strcpy(v->name, "FM");
v->type = V4L2_TUNER_RADIO;
v->rangelow = FREQ_MIN * FREQ_MUL;
@@ -358,6 +392,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -365,6 +400,25 @@ static int vidioc_s_tuner(struct file *file, void *priv,
if (v->index > 0)
return -EINVAL;
+
+ /* mono/stereo selector */
+ switch (v->audmode) {
+ case V4L2_TUNER_MODE_MONO:
+ retval = amradio_set_stereo(radio, WANT_MONO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set mono failed\n");
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+ break;
+ default:
+ return -EINVAL;
+ }
+
return 0;
}
@@ -373,13 +427,18 @@ static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
return -EIO;
+ mutex_lock(&radio->lock);
radio->curfreq = f->frequency;
- if (amradio_setfreq(radio, radio->curfreq) < 0)
+ mutex_unlock(&radio->lock);
+
+ retval = amradio_setfreq(radio, radio->curfreq);
+ if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"set frequency failed\n");
return 0;
@@ -438,6 +497,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -446,13 +506,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value) {
- if (amradio_stop(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"amradio_stop failed\n");
return -1;
}
} else {
- if (amradio_start(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"amradio_start failed\n");
return -1;
@@ -503,20 +565,29 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
static int usb_amradio_open(struct file *file)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
lock_kernel();
radio->users = 1;
radio->muted = 1;
- if (amradio_start(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"radio did not start up properly\n");
radio->users = 0;
unlock_kernel();
return -EIO;
}
- if (amradio_setfreq(radio, radio->curfreq) < 0)
+
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+
+ retval = amradio_setfreq(radio, radio->curfreq);
+ if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"set frequency failed\n");
@@ -533,10 +604,12 @@ static int usb_amradio_close(struct file *file)
if (!radio)
return -ENODEV;
+ mutex_lock(&radio->lock);
radio->users = 0;
+ mutex_unlock(&radio->lock);
if (!radio->removed) {
- retval = amradio_stop(radio);
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"amradio_stop failed\n");
@@ -549,8 +622,10 @@ static int usb_amradio_close(struct file *file)
static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
{
struct amradio_device *radio = usb_get_intfdata(intf);
+ int retval;
- if (amradio_stop(radio) < 0)
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
+ if (retval < 0)
dev_warn(&intf->dev, "amradio_stop failed\n");
dev_info(&intf->dev, "going into suspend..\n");
@@ -562,8 +637,10 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
static int usb_amradio_resume(struct usb_interface *intf)
{
struct amradio_device *radio = usb_get_intfdata(intf);
+ int retval;
- if (amradio_start(radio) < 0)
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0)
dev_warn(&intf->dev, "amradio_start failed\n");
dev_info(&intf->dev, "coming out of suspend..\n");
@@ -614,28 +691,32 @@ static struct video_device amradio_videodev_template = {
.release = usb_amradio_device_release,
};
-/* check if the device is present and register with v4l and
-usb if it is */
+/* check if the device is present and register with v4l and usb if it is */
static int usb_amradio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct amradio_device *radio;
+ int retval;
radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL);
- if (!(radio))
+ if (!radio) {
+ dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
return -ENOMEM;
+ }
radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
- if (!(radio->buffer)) {
+ if (!radio->buffer) {
+ dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
kfree(radio);
return -ENOMEM;
}
radio->videodev = video_device_alloc();
- if (!(radio->videodev)) {
+ if (!radio->videodev) {
+ dev_err(&intf->dev, "video_device_alloc failed\n");
kfree(radio->buffer);
kfree(radio);
return -ENOMEM;
@@ -648,12 +729,14 @@ static int usb_amradio_probe(struct usb_interface *intf,
radio->users = 0;
radio->usbdev = interface_to_usbdev(intf);
radio->curfreq = 95.16 * FREQ_MUL;
+ radio->stereo = -1;
mutex_init(&radio->lock);
video_set_drvdata(radio->videodev, radio);
- if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
- dev_warn(&intf->dev, "could not register video device\n");
+ retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+ if (retval < 0) {
+ dev_err(&intf->dev, "could not register video device\n");
video_device_release(radio->videodev);
kfree(radio->buffer);
kfree(radio);
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 67cbce82cb91..9827445086aa 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -5,8 +5,9 @@
* - Silicon Labs USB FM Radio Reference Design
* - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
* - KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
+ * - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
*
- * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +30,7 @@
* 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.0
* - First working version
- * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.1
* - Improved error handling, every function now returns errno
* - Improved multi user access (start/mute/stop)
@@ -98,21 +99,27 @@
* - blacklisted KWorld radio in hid-core.c and hid-ids.h
* 2008-12-03 Mark Lord <mlord@pobox.com>
* - add support for DealExtreme USB Radio
+ * 2009-01-31 Bob Ross <pigiron@gmx.com>
+ * - correction of stereo detection/setting
+ * - correction of signal strength indicator scaling
+ * 2009-01-31 Rick Bronson <rick@efn.org>
+ * Tobias Lorenz <tobias.lorenz@gmx.net>
+ * - add LED status output
+ * - get HW/SW version from scratchpad
*
* ToDo:
* - add firmware download/update support
* - RDS support: interrupt mode, instead of polling
- * - add LED status output (check if that's not already done in firmware)
*/
/* driver definitions */
#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
#define DRIVER_NAME "radio-si470x"
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9)
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.8"
+#define DRIVER_VERSION "1.0.9"
/* kernel includes */
@@ -140,7 +147,7 @@ static struct usb_device_id si470x_usb_driver_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
/* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
- /* DealExtreme USB Radio */
+ /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
/* Terminating entry */
{ }
@@ -340,7 +347,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
/* Report 19: stream */
#define STREAM_REPORT_SIZE 3
-#define STREAM_REPORT 19
+#define STREAM_REPORT 19
/* Report 20: scratch */
#define SCRATCH_PAGE_SIZE 63
@@ -348,9 +355,13 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
#define SCRATCH_REPORT 20
/* Reports 19-22: flash upgrade of the C8051F321 */
+#define WRITE_REPORT_SIZE 4
#define WRITE_REPORT 19
+#define FLASH_REPORT_SIZE 64
#define FLASH_REPORT 20
+#define CRC_REPORT_SIZE 3
#define CRC_REPORT 21
+#define RESPONSE_REPORT_SIZE 2
#define RESPONSE_REPORT 22
/* Report 23: currently unused, but can accept 60 byte reports on the HID */
@@ -409,7 +420,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
/* bootloader commands */
#define GET_SW_VERSION_COMMAND 0x00
-#define SET_PAGE_COMMAND 0x01
+#define SET_PAGE_COMMAND 0x01
#define ERASE_PAGE_COMMAND 0x02
#define WRITE_PAGE_COMMAND 0x03
#define CRC_ON_PAGE_COMMAND 0x04
@@ -423,12 +434,6 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
#define COMMAND_FAILED 0x02
#define COMMAND_PENDING 0x03
-/* buffer sizes */
-#define COMMAND_BUFFER_SIZE 4
-#define RESPONSE_BUFFER_SIZE 2
-#define FLASH_BUFFER_SIZE 64
-#define CRC_BUFFER_SIZE 3
-
/**************************************************************************
@@ -460,6 +465,10 @@ struct si470x_device {
unsigned int buf_size;
unsigned int rd_index;
unsigned int wr_index;
+
+ /* scratch page */
+ unsigned char software_version;
+ unsigned char hardware_version;
};
@@ -475,7 +484,7 @@ struct si470x_device {
/**************************************************************************
- * General Driver Functions
+ * General Driver Functions - REGISTER_REPORTs
**************************************************************************/
/*
@@ -561,60 +570,6 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
/*
- * si470x_get_all_registers - read entire registers
- */
-static int si470x_get_all_registers(struct si470x_device *radio)
-{
- unsigned char buf[ENTIRE_REPORT_SIZE];
- int retval;
- unsigned char regnr;
-
- buf[0] = ENTIRE_REPORT;
-
- retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
-
- if (retval >= 0)
- for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
- radio->registers[regnr] = get_unaligned_be16(
- &buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
- return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
- * si470x_get_rds_registers - read rds registers
- */
-static int si470x_get_rds_registers(struct si470x_device *radio)
-{
- unsigned char buf[RDS_REPORT_SIZE];
- int retval;
- int size;
- unsigned char regnr;
-
- buf[0] = RDS_REPORT;
-
- retval = usb_interrupt_msg(radio->usbdev,
- usb_rcvintpipe(radio->usbdev, 1),
- (void *) &buf, sizeof(buf), &size, usb_timeout);
- if (size != sizeof(buf))
- printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
- "return size differs: %d != %zu\n", size, sizeof(buf));
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
- "usb_interrupt_msg returned %d\n", retval);
-
- if (retval >= 0)
- for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
- radio->registers[STATUSRSSI + regnr] =
- get_unaligned_be16(
- &buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
- return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
* si470x_set_chan - set the channel
*/
static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
@@ -882,6 +837,123 @@ static int si470x_rds_on(struct si470x_device *radio)
/**************************************************************************
+ * General Driver Functions - ENTIRE_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_all_registers - read entire registers
+ */
+static int si470x_get_all_registers(struct si470x_device *radio)
+{
+ unsigned char buf[ENTIRE_REPORT_SIZE];
+ int retval;
+ unsigned char regnr;
+
+ buf[0] = ENTIRE_REPORT;
+
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+ if (retval >= 0)
+ for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
+ radio->registers[regnr] = get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - RDS_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_rds_registers - read rds registers
+ */
+static int si470x_get_rds_registers(struct si470x_device *radio)
+{
+ unsigned char buf[RDS_REPORT_SIZE];
+ int retval;
+ int size;
+ unsigned char regnr;
+
+ buf[0] = RDS_REPORT;
+
+ retval = usb_interrupt_msg(radio->usbdev,
+ usb_rcvintpipe(radio->usbdev, 1),
+ (void *) &buf, sizeof(buf), &size, usb_timeout);
+ if (size != sizeof(buf))
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ "return size differs: %d != %zu\n", size, sizeof(buf));
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ "usb_interrupt_msg returned %d\n", retval);
+
+ if (retval >= 0)
+ for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
+ radio->registers[STATUSRSSI + regnr] =
+ get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - LED_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_set_led_state - sets the led state
+ */
+static int si470x_set_led_state(struct si470x_device *radio,
+ unsigned char led_state)
+{
+ unsigned char buf[LED_REPORT_SIZE];
+ int retval;
+
+ buf[0] = LED_REPORT;
+ buf[1] = LED_COMMAND;
+ buf[2] = led_state;
+
+ retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - SCRATCH_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_scratch_versions - gets the scratch page and version infos
+ */
+static int si470x_get_scratch_page_versions(struct si470x_device *radio)
+{
+ unsigned char buf[SCRATCH_REPORT_SIZE];
+ int retval;
+
+ buf[0] = SCRATCH_REPORT;
+
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: "
+ "si470x_get_report returned %d\n", retval);
+ else {
+ radio->software_version = buf[1];
+ radio->hardware_version = buf[2];
+ }
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
* RDS Driver Functions
**************************************************************************/
@@ -1095,6 +1167,7 @@ static int si470x_fops_open(struct file *file)
}
if (radio->users == 1) {
+ /* start radio */
retval = si470x_start(radio);
if (retval < 0)
usb_autopm_put_interface(radio->intf);
@@ -1136,6 +1209,7 @@ static int si470x_fops_release(struct file *file)
/* cancel read processes */
wake_up_interruptible(&radio->read_queue);
+ /* stop radio */
retval = si470x_stop(radio);
usb_autopm_put_interface(radio->intf);
}
@@ -1197,9 +1271,11 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
static int si470x_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *capability)
{
+ struct si470x_device *radio = video_drvdata(file);
+
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
- sprintf(capability->bus_info, "USB");
+ usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info));
capability->version = DRIVER_KERNEL_VERSION;
capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
V4L2_CAP_TUNER | V4L2_CAP_RADIO;
@@ -1385,20 +1461,22 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
};
/* stereo indicator == stereo (instead of mono) */
- if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1)
- tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- else
+ if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+ else
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
/* mono/stereo selector */
- if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1)
- tuner->audmode = V4L2_TUNER_MODE_MONO;
- else
+ if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
tuner->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ tuner->audmode = V4L2_TUNER_MODE_MONO;
/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
- tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI)
- * 0x0101;
+ /* measured in units of dbµV in 1 db increments (max at ~75 dbµV) */
+ tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
+ /* the ideal factor is 0xffff/75 = 873,8 */
+ tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
/* automatic frequency control: -1: freq to low, 1 freq to high */
/* AFCRL does only indicate that freq. differs, not if too low/high */
@@ -1605,7 +1683,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
sizeof(si470x_viddev_template));
video_set_drvdata(radio->videodev, radio);
- /* show some infos about the specific device */
+ /* show some infos about the specific si470x device */
if (si470x_get_all_registers(radio) < 0) {
retval = -EIO;
goto err_all;
@@ -1613,7 +1691,16 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
radio->registers[DEVICEID], radio->registers[CHIPID]);
- /* check if firmware is current */
+ /* get software and hardware versions */
+ if (si470x_get_scratch_page_versions(radio) < 0) {
+ retval = -EIO;
+ goto err_all;
+ }
+ printk(KERN_INFO DRIVER_NAME
+ ": software version %d, hardware version %d\n",
+ radio->software_version, radio->hardware_version);
+
+ /* check if device and firmware is current */
if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
< RADIO_SW_VERSION_CURRENT) {
printk(KERN_WARNING DRIVER_NAME
@@ -1632,6 +1719,9 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
/* set initial frequency */
si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+ /* set led to connect state */
+ si470x_set_led_state(radio, BLINK_GREEN_LED);
+
/* rds buffer allocation */
radio->buf_size = rds_buf * 3;
radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
@@ -1715,6 +1805,9 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
cancel_delayed_work_sync(&radio->work);
usb_set_intfdata(intf, NULL);
if (radio->users == 0) {
+ /* set led to disconnect state */
+ si470x_set_led_state(radio, BLINK_ORANGE_LED);
+
video_unregister_device(radio->videodev);
kfree(radio->buffer);
kfree(radio);
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 4d35308fc1ff..393623818ade 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -298,7 +298,8 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
strlcpy(v->card, dev->name, sizeof(v->card));
- snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id);
+ snprintf(v->bus_info, sizeof(v->bus_info),
+ "I2C:%s", dev_name(&dev->dev));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index d24dcc025e37..fd1ab7a15cd4 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -73,6 +73,8 @@ static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
static void geovision_muxsel(struct bttv *btv, unsigned int input);
+static void phytec_muxsel(struct bttv *btv, unsigned int input);
+
static int terratec_active_radio_upgrade(struct bttv *btv);
static int tea5757_read(struct bttv *btv);
static int tea5757_write(struct bttv *btv, int value);
@@ -246,6 +248,10 @@ static struct CARD {
{ 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xf0500000, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500001, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500002, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500003, BTTV_BOARD_IVCE8784, "IVCE-8784" },
{ 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
{ 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
@@ -316,59 +322,50 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_UNKNOWN] = {
.name = " *** UNKNOWN/GENERIC *** ",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MIRO] = {
.name = "MIRO PCTV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_HAUPPAUGE] = {
.name = "Hauppauge (bt848)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_STB] = {
.name = "STB, Gateway P/N 6000699 (bt848)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 4, 0, 2, 3 },
.gpiomute = 1,
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -377,202 +374,177 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_INTEL] = {
.name = "Intel Create and Share PCI/ Smart Video Recorder III",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_DIAMOND] = {
.name = "Diamond DTV2000",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0, 1, 0, 1 },
.gpiomute = 3,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AVERMEDIA] = {
.name = "AVerMedia TVPhone",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0x0f,
.gpiomux = { 0x0c, 0x04, 0x08, 0x04 },
/* 0x04 for some cards ?? */
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= avermedia_tvphone_audio,
.has_remote = 1,
},
[BTTV_BOARD_MATRIX_VISION] = {
.name = "MATRIX-Vision MV-Delta",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x08 ---------------------------------- */
[BTTV_BOARD_FLYVIDEO] = {
.name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0xc00, 0x800, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TURBOTV] = {
.name = "IMS/IXmicro TurboTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 2, 3 },
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_HAUPPAUGE878] = {
.name = "Hauppauge (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0f, /* old: 7 */
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MIROPRO] = {
.name = "MIRO PCTV pro",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3014f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20001,0x10001, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x0c ---------------------------------- */
[BTTV_BOARD_ADSTECH_TV] = {
.name = "ADS Technologies Channel Surfer TV (bt848)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 14, 11, 7 },
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AVERMEDIA98] = {
.name = "AVerMedia TVCapture 98",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 14, 11, 7 },
.needs_tvaudio = 1,
.msp34xx_alt = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= avermedia_tv_stereo_audio,
.no_gpioirq = 1,
},
[BTTV_BOARD_VHX] = {
.name = "Aimslab Video Highway Xtreme (VHX)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ZOLTRIX] = {
.name = "Zoltrix TV-Max",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 1, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x10 ---------------------------------- */
[BTTV_BOARD_PIXVIEWPLAYTV] = {
.name = "Prolink Pixelview PlayTV (bt878)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
/* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
.gpiomute = 0x002000,
@@ -580,194 +552,170 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_WINVIEW_601] = {
.name = "Leadtek WinView 601",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x8300f8,
- .muxsel = { 2, 3, 1, 1,0 },
+ .muxsel = MUXSEL(2, 3, 1, 1, 0),
.gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
.gpiomute = 0xcfa007,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.volume_gpio = winview_volume,
.has_radio = 1,
},
[BTTV_BOARD_AVEC_INTERCAP] = {
.name = "AVEC Intercapture",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0, 0, 0 },
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_LIFE_FLYKIT] = {
.name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x8dff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.no_msp34xx = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x14 ---------------------------------- */
[BTTV_BOARD_CEI_RAFFLES] = {
.name = "CEI Raffles Card",
.video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_CONFERENCETV] = {
.name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
.video_inputs = 4,
- .audio_inputs = 2, /* tuner, line in */
- .tuner = 0,
+ /* .audio_inputs= 2, tuner, line in */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_PHOEBE_TVMAS] = {
.name = "Askey CPH050/ Phoebe Tv Master + FM",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 0x800, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MODTEC_205] = {
.name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
+ .has_dig_in = 1,
.gpiomask = 7,
- .muxsel = { 2, 3, -1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
+ .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
.gpiomux = { 0, 0, 0, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSBB5_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x18 ---------------------------------- */
[BTTV_BOARD_MAGICTVIEW061] = {
.name = "Askey CPH05X/06X (bt878) [many vendors]",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = {0x400, 0x400, 0x400, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_VOBIS_BOOSTAR] = {
.name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
.gpiomute = 0x40000,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
},
[BTTV_BOARD_HAUPPAUG_WCAM] = {
.name = "Hauppauge WinCam newer (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 7,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MAXI] = {
.name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
.video_inputs = 4,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_SECAM,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x1c ---------------------------------- */
[BTTV_BOARD_TERRATV] = {
.name = "Terratec TerraTV+ Version 1.1 (bt878)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 },
.gpiomute = 0x40000,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
/* GPIO wiring:
External 20 pin connector (for Active Radio Upgrade board)
@@ -805,87 +753,77 @@ struct tvcard bttv_tvcards[] = {
/* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
.name = "Imagenation PXC200",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1, /* was: 4 */
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0},
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = PXC200_muxsel,
},
[BTTV_BOARD_FLYVIDEO_98] = {
.name = "Lifeview FlyVideo 98 LR50",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1800, /* 0x8dfe00 */
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x0800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_IPROTV] = {
.name = "Formac iProTV, Formac ProTV I (bt848)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 1,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0, 0, 0 },
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x20 ---------------------------------- */
[BTTV_BOARD_INTEL_C_S_PCI] = {
.name = "Intel Create and Share PCI/ Smart Video Recorder III",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVALUE] = {
.name = "Terratec TerraTValue Version Bt878",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x500, 0, 0x300, 0x900 },
.gpiomute = 0x900,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_WINFAST2000] = {
.name = "Leadtek WinFast 2000/ WinFast 2000 XP",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */
+ /* TV, CVid, SVid, CVid over SVid connector */
+ .muxsel = MUXSEL(2, 3, 1, 1, 0),
/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
.gpiomask = 0xb33000,
.gpiomux = { 0x122000,0x1000,0x0000,0x620000 },
@@ -906,217 +844,191 @@ struct tvcard bttv_tvcards[] = {
.has_radio = 1,
.tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= winfast2000_audio,
.has_remote = 1,
},
[BTTV_BOARD_CHRONOS_VS2] = {
.name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x24 ---------------------------------- */
[BTTV_BOARD_TYPHOON_TVIEW] = {
.name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_PXELVWPLTVPRO] = {
.name = "Prolink PixelView PlayTV pro",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
.gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MAGICTVIEW063] = {
.name = "Askey CPH06X TView99",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x551e00,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0x551400, 0x551200, 0, 0 },
.gpiomute = 0x551c00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_PINNACLE] = {
.name = "Pinnacle PCTV Studio/Rave",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0xd0001, 0, 0 },
.gpiomute = 1,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x28 ---------------------------------- */
[BTTV_BOARD_STB2] = {
.name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 4, 0, 2, 3 },
.gpiomute = 1,
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
[BTTV_BOARD_AVPHONE98] = {
.name = "AVerMedia TVPhone 98",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 4, 11, 7 },
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.audio_mode_gpio= avermedia_tvphone_audio,
},
[BTTV_BOARD_PV951] = {
.name = "ProVideo PV951", /* pic16c54 */
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0, 0},
.needs_tvaudio = 1,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ONAIR_TV] = {
.name = "Little OnAir TV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00b,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
.gpiomute = 0xff3ffc,
.no_msp34xx = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x2c ---------------------------------- */
[BTTV_BOARD_SIGMA_TVII_FM] = {
.name = "Sigma TVII-FM",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 0, 2 },
.gpiomute = 3,
.no_msp34xx = 1,
.pll = PLL_NONE,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MATRIX_VISION2] = {
.name = "MATRIX-Vision MV-Delta 2",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ZOLTRIX_GENIE] = {
.name = "Zoltrix Genie TV/FM",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xbcf03f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
.gpiomute = 0xbcb03f,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4039FR5_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVRADIO] = {
.name = "Terratec TV/Radio+",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x70000,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
.gpiomute = 0x40000,
.needs_tvaudio = 1,
@@ -1124,7 +1036,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_35,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
@@ -1132,51 +1043,46 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_DYNALINK] = {
.name = "Askey CPH03x/ Dynalink Magic TView",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = {2,0,0,0 },
.gpiomute = 1,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GVBCTV3PCI] = {
.name = "IODATA GV-BCTV3/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = {0x10000, 0, 0x10000, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSHC6_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv3pci_audio,
},
[BTTV_BOARD_PXELVWPLTVPAK] = {
.name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
+ .has_dig_in = 1,
.gpiomask = 0xAA0000,
- .muxsel = { 2,3,1,1,-1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
+ .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
.gpiomux = { 0x20000, 0, 0x80000, 0x80000 },
.gpiomute = 0xa8000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring: (different from Rev.4C !)
GPIO17: U4.A0 (first hef4052bt)
@@ -1191,17 +1097,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_EAGLE] = {
.name = "Eagle Wireless Capricorn2 (bt878A)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.pll = PLL_28,
.tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x34 ---------------------------------- */
@@ -1209,11 +1113,10 @@ struct tvcard bttv_tvcards[] = {
/* David Härdeman <david@2gen.com> */
.name = "Pinnacle PCTV Studio Pro",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0xd0001, 0, 0 },
.gpiomute = 10,
/* sound path (5 sources):
@@ -1229,25 +1132,22 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TVIEW_RDS_FM] = {
/* Claas Langbehn <claas@bigfoot.com>,
Sven Grothklags <sven@upb.de> */
.name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1c,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0x10, 8 },
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_LIFETEC_9415] = {
@@ -1258,11 +1158,10 @@ struct tvcard bttv_tvcards[] = {
options tuner type=5 */
.name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x18e0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
.gpiomute = 0x18e0,
/* For cards with tda9820/tda9821:
@@ -1272,25 +1171,22 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_BESTBUY_EASYTV] = {
/* Miguel Angel Alvarez <maacruz@navegalia.com>
old Easy TV BT848 version (model CPH031) */
.name = "Askey CPH031/ BESTBUY Easy TV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xF,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x38 ---------------------------------- */
@@ -1298,17 +1194,15 @@ struct tvcard bttv_tvcards[] = {
/* Gordon Heydon <gjheydon@bigfoot.com ('98) */
.name = "Lifeview FlyVideo 98FM LR50",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* This is the ultimate cheapo capture card
* just a BT848A on a small PCB!
@@ -1316,51 +1210,45 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_GRANDTEC] = {
.name = "GrandTec 'Grand Video Capture' (Bt848)",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
.gpiomask = 0,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_35,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ASKEY_CPH060] = {
/* Daniel Herrington <daniel.herrington@home.com> */
.name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x400, 0x400, 0x400, 0x400 },
.gpiomute = 0x800,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4036FY5_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ASKEY_CPH03X] = {
/* Matti Mottus <mottus@physic.ut.ee> */
.name = "Askey CPH03x TV Capturer",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x3c ---------------------------------- */
@@ -1368,34 +1256,30 @@ struct tvcard bttv_tvcards[] = {
/* Philip Blundell <philb@gnu.org> */
.name = "Modular Technology MM100PCTV",
.video_inputs = 2,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 2, */
+ .svhs = NO_SVHS,
.gpiomask = 11,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 1 },
.gpiomute = 8,
.pll = PLL_35,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GMV1] = {
/* Adrian Cox <adrian@humboldt.co.uk */
.name = "AG Electronics GMV1",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
.gpiomask = 0xF,
- .muxsel = { 2, 2 },
+ .muxsel = MUXSEL(2, 2),
.gpiomux = { },
.no_msp34xx = 1,
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_BESTBUY_EASYTV2] = {
/* Miguel Angel Alvarez <maacruz@navegalia.com>
@@ -1403,34 +1287,30 @@ struct tvcard bttv_tvcards[] = {
special thanks to Informatica Mieres for providing the card */
.name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 1, 0, 4, 4 },
.gpiomute = 9,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ATI_TVWONDER] = {
/* Lukas Gebauer <geby@volny.cz> */
.name = "ATI TV-Wonder",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xf03f,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0xbffe, 0, 0xbfff, 0 },
.gpiomute = 0xbffe,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x40 ---------------------------------- */
@@ -1438,27 +1318,24 @@ struct tvcard bttv_tvcards[] = {
/* Lukas Gebauer <geby@volny.cz> */
.name = "ATI TV-Wonder VE",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 1,
- .muxsel = { 2, 3, 0, 1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.gpiomux = { 0, 0, 1, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_FLYVIDEO2000] = {
/* DeeJay <deejay@westel900.net (2000S) */
.name = "Lifeview FlyVideo 2000S LR90",
.video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x18e0,
- .muxsel = { 2, 3, 0, 1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
/* Radio changed from 1e80 to 0x800 to make
FlyVideo2000S in .hu happy (gm)*/
/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
@@ -1471,40 +1348,35 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVALUER] = {
.name = "Terratec TValueRadio",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x500, 0x500, 0x300, 0x900 },
.gpiomute = 0x900,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_GVBCTV4PCI] = {
/* TANAKA Kei <peg00625@nifty.com> */
.name = "IODATA GV-BCTV4/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = {0x10000, 0, 0x10000, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv3pci_audio,
},
@@ -1514,9 +1386,8 @@ struct tvcard bttv_tvcards[] = {
/* try "insmod msp3400 simple=0" if you have
* sound problems with this card. */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x4f8a00,
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1524,10 +1395,9 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = { 2, 3 ,0 ,1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.tuner_type = TUNER_MT2032,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1536,9 +1406,8 @@ struct tvcard bttv_tvcards[] = {
/* try "insmod msp3400 simple=0" if you have
* sound problems with this card. */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x4f8a00,
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1546,10 +1415,9 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = { 2, 3 ,0 ,1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.tuner_type = TUNER_MT2032,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1557,31 +1425,27 @@ struct tvcard bttv_tvcards[] = {
/* Philip Blundell <pb@nexus.co.uk> */
.name = "Active Imaging AIMMS",
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
- .muxsel = { 2 },
+ .muxsel = MUXSEL(2),
.gpiomask = 0
},
[BTTV_BOARD_PV_BT878P_PLUS] = {
/* Tomasz Pyra <hellfire@sedez.iq.pl> */
.name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
.gpiomute = 13,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_LG_PAL_I_FM,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring:
GPIO0: U4.A0 (hef4052bt)
@@ -1594,15 +1458,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_FLYVIDEO98EZ] = {
.name = "Lifeview FlyVideo 98EZ (capture only) LR51",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */
+ /* AV1, AV2, SVHS, CVid adapter on SVHS */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.pll = PLL_28,
.no_msp34xx = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x48 ---------------------------------- */
@@ -1610,11 +1473,10 @@ struct tvcard bttv_tvcards[] = {
/* Dariusz Kowalewski <darekk@automex.pl> */
.name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x01, 0x00, 0x03, 0x03 },
.gpiomute = 0x09,
.needs_tvaudio = 1,
@@ -1623,7 +1485,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */
.has_radio = 1, /* Note: not all cards have radio */
.has_remote = 1,
@@ -1640,49 +1501,42 @@ struct tvcard bttv_tvcards[] = {
/* you must jumper JP5 for the card to work */
.name = "Sensoray 311",
.video_inputs = 5,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 4,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_RV605] = {
/* Miguel Freitas <miguel@cetuc.puc-rio.br> */
.name = "RemoteVision MX (RV605)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x00,
.gpiomask2 = 0x07ff,
- .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
- 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = rv605_muxsel,
},
[BTTV_BOARD_POWERCLR_MTV878] = {
.name = "Powercolor MTV878/ MTV878R/ MTV878F",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
- .muxsel = { 2, 1, 1, },
+ .muxsel = MUXSEL(2, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 4,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1692,42 +1546,38 @@ struct tvcard bttv_tvcards[] = {
/* Masaki Suzuki <masaki@btree.org> */
.name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x140007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= windvr_audio,
},
[BTTV_BOARD_GRANDTEC_MULTI] = {
.name = "GrandTec Multi Capture Card (Bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_KWORLD] = {
.name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio!
* This card lacks external Audio In, so we mute it on Ext. & Int.
* The PCB can take a sbx1637/sbx1673, wiring unknown.
@@ -1741,7 +1591,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
radio signal strength indicators work fine. */
.has_radio = 1,
@@ -1759,27 +1608,24 @@ struct tvcard bttv_tvcards[] = {
/* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
.name = "DSP Design TCVIDEO",
.video_inputs = 4,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x50 ---------------------------------- */
[BTTV_BOARD_HAUPPAUGEPVR] = {
.name = "Hauppauge WinTV PVR",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask = 7,
.gpiomux = {7},
@@ -1787,32 +1633,28 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_GVBCTV5PCI] = {
.name = "IODATA GV-BCTV5/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0f0f80,
- .muxsel = {2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x030000, 0x010000, 0, 0 },
.gpiomute = 0x020000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv5pci_audio,
.has_radio = 1,
},
[BTTV_BOARD_OSPREY1x0] = {
.name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
.video_inputs = 4, /* id-inputs-clock */
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 3,
- .muxsel = { 3, 2, 0, 1 },
+ .muxsel = MUXSEL(3, 2, 0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1820,14 +1662,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x0_848] = {
.name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
.video_inputs = 3,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1837,14 +1677,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY101_848] = {
.name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1852,14 +1690,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x1] = {
.name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1867,14 +1703,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x1_SVID] = {
.name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 0, 1 },
+ .muxsel = MUXSEL(0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1882,14 +1716,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2xx] = {
.name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
.video_inputs = 1,
- .audio_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0 },
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1899,14 +1731,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2x0_SVID] = {
.name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 0, 1 },
+ .muxsel = MUXSEL(0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1914,14 +1744,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2x0] = {
.name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1929,14 +1757,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY500] = {
.name = "Osprey 500", /* 500 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1944,12 +1770,10 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY540] = {
.name = "Osprey 540", /* 540 */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1959,14 +1783,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2000] = {
.name = "Osprey 2000", /* 2000 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
@@ -1975,14 +1797,12 @@ struct tvcard bttv_tvcards[] = {
/* M G Berberich <berberic@forwiss.uni-passau.de> */
.name = "IDS Eagle",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 0, 1, 2, 3 },
+ .muxsel = MUXSEL(2, 2, 2, 2),
.muxsel_hook = eagle_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -1991,16 +1811,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PINNACLESAT] = {
.name = "Pinnacle PCTV Sat",
.video_inputs = 2,
- .audio_inputs = 0,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.pll = PLL_28,
.no_gpioirq = 1,
.has_dvb = 1,
@@ -2008,18 +1826,16 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_FORMAC_PROTV] = {
.name = "Formac ProTV II (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 2,
/* TV, Comp1, Composite over SVID con, SVID */
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 2, 0, 0 },
.pll = PLL_28,
.has_radio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* sound routing:
GPIO=0x00,0x01,0x03: mute (?)
0x02: both TV and radio (tuner: FM1216/I)
@@ -2033,62 +1849,55 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_MACHTV] = {
.name = "MachTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3},
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
[BTTV_BOARD_EURESYS_PICOLO] = {
.name = "Euresys Picolo",
.video_inputs = 3,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = { 2, 0, 1},
+ .muxsel = MUXSEL(2, 0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_PV150] = {
/* Luc Van Hoeylandt <luc@e-magic.be> */
.name = "ProVideo PV150", /* 0x4f */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AD_TVK503] = {
/* Hiroshi Takekawa <sian@big.or.jp> */
/* This card lacks subsystem ID */
.name = "AD-TVK503", /* 0x63 */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x001e8007,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
/* Tuner, Radio, external, internal, off, on */
.gpiomux = { 0x08, 0x0f, 0x0a, 0x08 },
.gpiomute = 0x0f,
@@ -2097,7 +1906,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= adtvk503_audio,
},
@@ -2105,17 +1913,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_HERCULES_SM_TV] = {
.name = "Hercules Smart TV Stereo",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.needs_tvaudio = 1,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* Notes:
- card lacks subsystem ID
- stereo variant w/ daughter board with tda9874a @0xb0
@@ -2129,16 +1935,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PACETV] = {
.name = "Pace TV & Radio Card",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */
+ /* Tuner, CVid, SVid, CVid over SVid connector */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.pll = PLL_28,
/* Bt878, Bt832, FI1246 tuner; no pci subsystem id
@@ -2152,27 +1957,34 @@ struct tvcard bttv_tvcards[] = {
/* Chris Willing <chris@vislab.usyd.edu.au> */
.name = "IVC-200",
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0xdf,
- .muxsel = { 2 },
+ .muxsel = MUXSEL(2),
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_IVCE8784] = {
+ .name = "IVCE-8784",
+ .video_inputs = 1,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = NO_SVHS,
+ .gpiomask = 0xdf,
+ .muxsel = MUXSEL(2),
.pll = PLL_28,
},
[BTTV_BOARD_XGUARD] = {
.name = "Grand X-Guard / Trust 814PCI",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask2 = 0xff,
- .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
+ .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
.muxsel_hook = xguard_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -2184,16 +1996,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_NEBULA_DIGITV] = {
.name = "Nebula Electronics DigiTV",
.video_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
.has_remote = 1,
.gpiomask = 0x1b,
@@ -2203,118 +2013,101 @@ struct tvcard bttv_tvcards[] = {
/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
.name = "ProVideo PV143",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009X1_VD011_MINIDIN] = {
/* M.Klahr@phytec.de */
.name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009X1_VD011_COMBI] = {
.name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x6c ---------------------------------- */
[BTTV_BOARD_VD009_MINIDIN] = {
.name = "PHYTEC VD-009 MiniDIN (bt878)",
.video_inputs = 10,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 9,
.gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
+ .gpiomask2 = 0x03, /* used for external vodeo mux */
+ .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0),
+ .muxsel_hook = phytec_muxsel,
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009_COMBI] = {
.name = "PHYTEC VD-009 Combi (bt878)",
.video_inputs = 10,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 9,
.gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
+ .gpiomask2 = 0x03, /* used for external vodeo mux */
+ .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),
+ .muxsel_hook = phytec_muxsel,
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_IVC100] = {
.name = "IVC-100",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0xdf,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.pll = PLL_28,
},
[BTTV_BOARD_IVC120] = {
/* IVC-120G - Alan Garfield <alan@fromorbit.com> */
.name = "IVC-120G",
.video_inputs = 16,
- .audio_inputs = 0, /* card has no audio */
- .tuner = UNSET, /* card has no tuner */
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET, /* card has no svhs */
+ .svhs = NO_SVHS, /* card has no svhs */
.needs_tvaudio = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.gpiomask = 0x00,
- .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
+ .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
.muxsel_hook = ivc120_muxsel,
.pll = PLL_28,
},
@@ -2323,13 +2116,11 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PC_HDTV] = {
.name = "pcHDTV HD-2000 TV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_PHILIPS_FCV1236D,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
},
[BTTV_BOARD_TWINHAN_DST] = {
@@ -2339,38 +2130,34 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_video = 1,
.has_dvb = 1,
},
[BTTV_BOARD_WINFASTVC100] = {
.name = "Winfast VC100",
.video_inputs = 3,
- .audio_inputs = 0,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .tuner = UNSET,
- .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */
+ /* Vid In, SVid In, Vid over SVid in connector */
+ .muxsel = MUXSEL(3, 1, 1, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
[BTTV_BOARD_TEV560] = {
.name = "Teppro TEV-560/InterVision IV-560",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 1, 1 },
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_35,
},
@@ -2378,14 +2165,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_SIMUS_GVC1100] = {
.name = "SIMUS GVC1100",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
- .muxsel = { 2, 2, 2, 2 },
+ .muxsel = MUXSEL(2, 2, 2, 2),
.gpiomask = 0x3F,
.muxsel_hook = gvc1100_muxsel,
},
@@ -2393,47 +2178,41 @@ struct tvcard bttv_tvcards[] = {
/* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
.name = "NGS NGSTV+",
.video_inputs = 3,
- .tuner = 0,
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = { 0, 0, 0, 0 },
.gpiomute = 0x000003,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_LMLBT4] = {
/* http://linuxmedialabs.com */
.name = "LMLBT4",
.video_inputs = 4, /* IN1,IN2,IN3,IN4 */
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.needs_tvaudio = 0,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TEKRAM_M205] = {
/* Helmroos Harri <harri.helmroos@pp.inet.fi> */
.name = "Tekram M205 PRO",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.svhs = 2,
.needs_tvaudio = 0,
.gpiomask = 0x68,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomux = { 0x68, 0x68, 0x61, 0x61 },
.pll = PLL_28,
},
@@ -2444,18 +2223,16 @@ struct tvcard bttv_tvcards[] = {
/* bt878 TV + FM without subsystem ID */
.name = "Conceptronic CONTVFMi",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 3,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
},
@@ -2466,37 +2243,34 @@ struct tvcard bttv_tvcards[] = {
/*0x79 in bttv.h*/
.name = "Euresys Picolo Tetra",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
.gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
+ /*878A input is always MUX0, see above.*/
+ .muxsel = MUXSEL(2, 2, 2, 2),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.pll = PLL_28,
.needs_tvaudio = 0,
.muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_SPIRIT_TV] = {
/* Spirit TV Tuner from http://spiritmodems.com.au */
/* Stafford Goodsell <surge@goliath.homeunix.org> */
.name = "Spirit TV Tuner",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0000000f,
- .muxsel = { 2, 1, 1 },
+ .muxsel = MUXSEL(2, 1, 1),
.gpiomux = { 0x02, 0x00, 0x00, 0x00 },
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
},
@@ -2505,11 +2279,9 @@ struct tvcard bttv_tvcards[] = {
.name = "AVerMedia AVerTV DVB-T 771",
.video_inputs = 2,
.svhs = 1,
- .tuner = UNSET,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .muxsel = { 3 , 3 },
+ .muxsel = MUXSEL(3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -2524,54 +2296,47 @@ struct tvcard bttv_tvcards[] = {
/* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
.name = "AverMedia AverTV DVB-T 761",
.video_inputs = 2,
- .tuner = UNSET,
.svhs = 1,
- .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */
+ .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
.no_gpioirq = 1,
.has_remote = 1,
},
[BTTV_BOARD_MATRIX_VISIONSQ] = {
/* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SQ",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3 },
- .muxsel_hook = sigmaSQ_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "MATRIX Vision Sigma-SQ",
+ .video_inputs = 16,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3),
+ .muxsel_hook = sigmaSQ_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_MATRIX_VISIONSLC] = {
/* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SLC",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2 },
- .muxsel_hook = sigmaSLC_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "MATRIX Vision Sigma-SLC",
+ .video_inputs = 4,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .muxsel_hook = sigmaSLC_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
/* BTTV_BOARD_APAC_VIEWCOMP */
[BTTV_BOARD_APAC_VIEWCOMP] = {
@@ -2579,18 +2344,16 @@ struct tvcard bttv_tvcards[] = {
/* bt878 TV + FM 0x00000000 subsystem ID */
.name = "APAC Viewcomp 878(AMAX)",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
.has_radio = 1, /* not every card has radio */
},
@@ -2599,46 +2362,40 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_DVICO_DVBT_LITE] = {
/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
.name = "DViCO FusionHDTV DVB-T Lite",
- .tuner = UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.no_video = 1,
.has_dvb = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VGEAR_MYVCD] = {
/* Steven <photon38@pchome.com.tw> */
.name = "V-Gear MyVCD",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = {2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x31, 0x31, 0x31, 0x31 },
.gpiomute = 0x31,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 0,
},
[BTTV_BOARD_SUPER_TV] = {
/* Rick C <cryptdragoon@gmail.com> */
.name = "Super TV Tuner",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask = 0x008007,
.gpiomux = { 0, 0x000001,0,0 },
.needs_tvaudio = 1,
@@ -2648,17 +2405,15 @@ struct tvcard bttv_tvcards[] = {
/* Chris Fanning <video4linux@haydon.net> */
.name = "Tibet Systems 'Progress DVR' CS16",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = tibetCS16_muxsel,
},
[BTTV_BOARD_KODICOM_4400R] = {
@@ -2675,12 +2430,10 @@ struct tvcard bttv_tvcards[] = {
*/
.name = "Kodicom 4400R (master)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
/* GPIO bits 0-9 used for analog switch:
* 00 - 03: camera selector
* 04 - 06: channel (controller) selector
@@ -2691,7 +2444,7 @@ struct tvcard bttv_tvcards[] = {
*/
.gpiomask = 0x0003ff,
.no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
@@ -2707,15 +2460,13 @@ struct tvcard bttv_tvcards[] = {
*/
.name = "Kodicom 4400R (slave)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0x010000,
.no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
@@ -2728,27 +2479,23 @@ struct tvcard bttv_tvcards[] = {
/* Adlink RTV24 with special unlock codes */
.name = "Adlink RTV24",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
/* ---- card 0x87---------------------------------- */
[BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
/* Michael Krufky <mkrufky@m1k.net> */
.name = "DViCO FusionHDTV 5 Lite",
- .tuner = 0,
.tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.video_inputs = 3,
- .audio_inputs = 1,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
@@ -2762,75 +2509,68 @@ struct tvcard bttv_tvcards[] = {
/* Mauro Carvalho Chehab <mchehab@infradead.org> */
.name = "Acorp Y878F",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
.gpiomute = 0x002000,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
.tuner_addr = 0xc1 >>1,
- .radio_addr = 0xc1 >>1,
.has_radio = 1,
},
/* ---- card 0x89 ---------------------------------- */
[BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
.name = "Conceptronic CTVFMi v2",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x001c0007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 3,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TENA_9533_DI,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
},
/* ---- card 0x8a ---------------------------------- */
[BTTV_BOARD_PV_BT878P_2E] = {
- .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
- .video_inputs = 5,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 0x01fe00,
- .muxsel = { 2,3,1,1,-1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
- .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
- .gpiomute = 0x12400,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_LG_PAL_FM,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .has_remote = 1,
+ .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
+ .video_inputs = 5,
+ /* .audio_inputs= 1, */
+ .svhs = 3,
+ .has_dig_in = 1,
+ .gpiomask = 0x01fe00,
+ .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
+ .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
+ .gpiomute = 0x12400,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_LG_PAL_FM,
+ .tuner_addr = ADDR_UNSET,
+ .has_remote = 1,
},
/* ---- card 0x8b ---------------------------------- */
[BTTV_BOARD_PV_M4900] = {
/* Sérgio Fortier <sergiofortier@yahoo.com.br> */
.name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
.gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF_5533MF,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.has_remote = 1,
},
@@ -2850,17 +2590,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY440] = {
.name = "Osprey 440",
.video_inputs = 4,
- .audio_inputs = 2, /* this is meaningless */
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */
+ /* .audio_inputs= 2, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */
.gpiomask = 0x303,
.gpiomute = 0x000, /* int + 32kHz */
.gpiomux = { 0, 0, 0x000, 0x100},
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -2869,28 +2607,25 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_ASOUND_SKYEYE] = {
.name = "Asound Skyeye PCTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 1,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x8e ---------------------------------- */
[BTTV_BOARD_SABRENT_TVFM] = {
.name = "Sabrent TV-FM (bttv version)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x108007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 100000, 100002, 100002, 100000 },
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -2904,17 +2639,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
.name = "Hauppauge ImpactVCB (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x0f, /* old: 7 */
- .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */
+ .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MACHTV_MAGICTV] = {
/* Julian Calaby <julian.calaby@gmail.com>
@@ -2926,16 +2659,14 @@ struct tvcard bttv_tvcards[] = {
.name = "MagicTV", /* rebranded MachTV */
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.tuner_type = TUNER_TEMIC_4009FR5_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -2943,36 +2674,30 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_SSAI_SECURITY] = {
.name = "SSAI Security Video Interface",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0, 1, 2, 3 },
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0, 1, 2, 3),
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_SSAI_ULTRASOUND] = {
.name = "SSAI Ultrasound Video Interface",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 2, 0, 1, 3 },
- .tuner_type = UNSET,
+ .muxsel = MUXSEL(2, 0, 1, 3),
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x94---------------------------------- */
[BTTV_BOARD_DVICO_FUSIONHDTV_2] = {
.name = "DViCO FusionHDTV 2",
- .tuner = 0,
.tuner_type = TUNER_PHILIPS_FCV1236D,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.video_inputs = 3,
- .audio_inputs = 1,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
@@ -2984,36 +2709,31 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_TYPHOON_TVTUNERPCI] = {
.name = "Typhoon TV-Tuner PCI (50684)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3014f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20001,0x10001, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GEOVISION_GV600] = {
/* emhn@usb.ve */
- .name = "Geovision GV-600",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2 },
- .muxsel_hook = geovision_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "Geovision GV-600",
+ .video_inputs = 16,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
+ .muxsel_hook = geovision_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_KOZUMI_KTV_01C] = {
/* Mauro Lacy <mauro@lacy.com.ar>
@@ -3021,17 +2741,15 @@ struct tvcard bttv_tvcards[] = {
.name = "Kozumi KTV-01C",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */
.gpiomute = 3, /* CONTVFMi */
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -3041,8 +2759,7 @@ struct tvcard bttv_tvcards[] = {
Mauro Carvalho Chehab <mchehab@infradead.org */
.name = "Encore ENL TV-FM-2",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
/* bit 6 -> IR disabled
bit 18/17 = 00 -> mute
@@ -3051,12 +2768,11 @@ struct tvcard bttv_tvcards[] = {
11 -> internal audio input
*/
.gpiomask = 0x060040,
- .muxsel = { 2, 3, 3 },
+ .muxsel = MUXSEL(2, 3, 3),
.gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 },
.gpiomute = 0,
.tuner_type = TUNER_TCL_MF02GIP_5N,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -3065,49 +2781,43 @@ struct tvcard bttv_tvcards[] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
- .svhs = UNSET, /* card has no s-video */
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x00,
- .muxsel = { 0, 2, 3, 1 },
+ .muxsel = MUXSEL(0, 2, 3, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD012_X1] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X1 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD012_X2] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X2 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 3, 2, 1 },
+ .muxsel = MUXSEL(3, 2, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
}
};
@@ -3403,8 +3113,7 @@ static void init_ids_eagle(struct bttv *btv)
* has its own multiplexer */
static void eagle_muxsel(struct bttv *btv, unsigned int input)
{
- btaor((2)<<5, ~(3<<5), BT848_IFORM);
- gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
+ gpio_bits(3, input & 3);
/* composite */
/* set chroma ADC to sleep */
@@ -3670,13 +3379,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
addr = bttv_tvcards[btv->c.type].tuner_addr;
if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
- if(UNSET == btv->tuner_type)
+ if (UNSET == btv->tuner_type)
btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
if (UNSET != tuner[btv->c.nr])
btv->tuner_type = tuner[btv->c.nr];
- if (btv->tuner_type == TUNER_ABSENT ||
- bttv_tvcards[btv->c.type].tuner == UNSET)
+ if (btv->tuner_type == TUNER_ABSENT)
printk(KERN_INFO "bttv%d: tuner absent\n", btv->c.nr);
else if(btv->tuner_type == UNSET)
printk(KERN_WARNING "bttv%d: tuner type unset\n", btv->c.nr);
@@ -3684,13 +3392,23 @@ void __devinit bttv_init_card2(struct bttv *btv)
printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr,
btv->tuner_type);
- if (btv->tuner_type != UNSET) {
+ if (UNSET == btv->tuner_type)
+ btv->tuner_type = TUNER_ABSENT;
+
+ if (btv->tuner_type != TUNER_ABSENT) {
struct tuner_setup tun_setup;
+ /* Load tuner module before issuing tuner config call! */
+ if (autoload)
+ request_module("tuner");
+
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
tun_setup.type = btv->tuner_type;
tun_setup.addr = addr;
+ if (bttv_tvcards[btv->c.type].has_radio)
+ tun_setup.mode_mask |= T_RADIO;
+
bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
}
@@ -3703,7 +3421,10 @@ void __devinit bttv_init_card2(struct bttv *btv)
bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
}
- btv->svhs = bttv_tvcards[btv->c.type].svhs;
+ btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
+ bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET;
+ btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ?
+ UNSET : bttv_tvcards[btv->c.type].svhs;
if (svhs[btv->c.nr] != UNSET)
btv->svhs = svhs[btv->c.nr];
if (remote[btv->c.nr] != UNSET)
@@ -3723,7 +3444,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (!autoload)
return;
- if (bttv_tvcards[btv->c.type].tuner == UNSET)
+ if (btv->tuner_type == TUNER_ABSENT)
return; /* no tuner or related drivers to load */
/* try to detect audio/fader chips */
@@ -3745,9 +3466,6 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (bttv_tvcards[btv->c.type].needs_tvaudio)
request_module("tvaudio");
-
- if (btv->tuner_type != UNSET && btv->tuner_type != TUNER_ABSENT)
- request_module("tuner");
}
@@ -4067,27 +3785,26 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
btv->has_remote ? "yes" : "no");
}
-/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
-void bttv_tda9880_setnorm(struct bttv *btv, int norm)
+/*
+ * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880
+ * analog demod, which is not I2C controlled like the newer and more common
+ * TDA9887 series. Instead is has two tri-state input pins, S0 and S1,
+ * that control the IF for the video and audio. Apparently, bttv GPIO
+ * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I
+ * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
+ */
+u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits)
{
- /* fix up our card entry */
- if(norm==V4L2_STD_NTSC) {
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x957fff;
- dprintk("bttv_tda9880_setnorm to NTSC\n");
- }
- else {
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x947fff;
- dprintk("bttv_tda9880_setnorm to PAL\n");
+
+ if (btv->audio == TVAUDIO_INPUT_TUNER) {
+ if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN)
+ gpiobits |= 0x10000;
+ else
+ gpiobits &= ~0x10000;
}
- /* set GPIO according */
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
- bttv_tvcards[btv->c.type].gpiomux[btv->audio]);
+
+ gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits);
+ return gpiobits;
}
@@ -4463,6 +4180,11 @@ void tea5757_set_freq(struct bttv *btv, unsigned short freq)
*/
static void rv605_muxsel(struct bttv *btv, unsigned int input)
{
+ static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0,
+ 0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa };
+
+ gpio_bits(0x07f, muxgpio[input]);
+
/* reset all conections */
gpio_bits(0x200,0x200);
mdelay(1);
@@ -4470,7 +4192,6 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input)
mdelay(1);
/* create a new connection */
- gpio_bits(0x480,0x080);
gpio_bits(0x480,0x480);
mdelay(1);
gpio_bits(0x480,0x080);
@@ -4729,8 +4450,7 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */
- /* Selects MUX0 for input on the 878 */
- btaor((0)<<5, ~(3<<5), BT848_IFORM);
+ /* 878's MUX0 is already selected for input via muxsel values */
}
@@ -4814,6 +4534,16 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux);
}
+static void phytec_muxsel(struct bttv *btv, unsigned int input)
+{
+ unsigned int mux = input % 4;
+
+ if (input == btv->svhs)
+ mux = 0;
+
+ gpio_bits(0x3, mux);
+}
+
/* ----------------------------------------------------------------------- */
/* motherboard chipset specific stuff */
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index c71f394fc0ea..826ca60b42e6 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -58,7 +58,7 @@
unsigned int bttv_num; /* number of Bt848s in use */
-struct bttv bttvs[BTTV_MAX];
+struct bttv *bttvs[BTTV_MAX];
unsigned int bttv_debug;
unsigned int bttv_verbose = 1;
@@ -1040,7 +1040,7 @@ static void bt848A_set_timing(struct bttv *btv)
int table_idx = bttv_tvnorms[btv->tvnorm].sram;
int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
- if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
+ if (btv->input == btv->dig) {
dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
btv->c.nr,table_idx);
@@ -1142,7 +1142,7 @@ video_mux(struct bttv *btv, unsigned int input)
btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
}
- mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
+ mux = bttv_muxsel(btv, input);
btaor(mux<<5, ~(3<<5), BT848_IFORM);
dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
btv->c.nr,input,mux);
@@ -1180,7 +1180,16 @@ audio_mux(struct bttv *btv, int input, int mute)
else
gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+ switch (btv->c.type) {
+ case BTTV_BOARD_VOODOOTV_FM:
+ case BTTV_BOARD_VOODOOTV_200:
+ gpio_val = bttv_tda9880_setnorm(btv, gpio_val);
+ break;
+
+ default:
+ gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+ }
+
if (bttv_gpio)
bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
if (in_interrupt())
@@ -1277,7 +1286,7 @@ bttv_crop_calc_limits(struct bttv_crop *c)
}
static void
-bttv_crop_reset(struct bttv_crop *c, int norm)
+bttv_crop_reset(struct bttv_crop *c, unsigned int norm)
{
c->rect = bttv_tvnorms[norm].cropcap.defrect;
bttv_crop_calc_limits(c);
@@ -1290,16 +1299,13 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
const struct bttv_tvnorm *tvnorm;
v4l2_std_id id;
- if (norm < 0 || norm >= BTTV_TVNORMS)
- return -EINVAL;
+ BUG_ON(norm >= BTTV_TVNORMS);
+ BUG_ON(btv->tvnorm >= BTTV_TVNORMS);
tvnorm = &bttv_tvnorms[norm];
- if (btv->tvnorm < 0 ||
- btv->tvnorm >= BTTV_TVNORMS ||
- 0 != memcmp(&bttv_tvnorms[btv->tvnorm].cropcap,
- &tvnorm->cropcap,
- sizeof (tvnorm->cropcap))) {
+ if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
+ sizeof (tvnorm->cropcap))) {
bttv_crop_reset(&btv->crop[0], norm);
btv->crop[1] = btv->crop[0]; /* current = default */
@@ -1322,7 +1328,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
switch (btv->c.type) {
case BTTV_BOARD_VOODOOTV_FM:
case BTTV_BOARD_VOODOOTV_200:
- bttv_tda9880_setnorm(btv,norm);
+ bttv_tda9880_setnorm(btv, gpio_read());
break;
}
id = tvnorm->v4l2_id;
@@ -1350,8 +1356,8 @@ set_input(struct bttv *btv, unsigned int input, unsigned int norm)
} else {
video_mux(btv,input);
}
- audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
- TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
+ audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ?
+ TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN);
set_tvnorm(btv, norm);
}
@@ -1901,7 +1907,7 @@ static int bttv_enum_input(struct file *file, void *priv,
i->type = V4L2_INPUT_TYPE_CAMERA;
i->audioset = 1;
- if (i->index == bttv_tvcards[btv->c.type].tuner) {
+ if (btv->tuner_type != TUNER_ABSENT && i->index == 0) {
sprintf(i->name, "Television");
i->type = V4L2_INPUT_TYPE_TUNER;
i->tuner = 0;
@@ -1965,7 +1971,7 @@ static int bttv_s_tuner(struct file *file, void *priv,
if (0 != err)
return err;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
@@ -2659,8 +2665,7 @@ static int bttv_querycap(struct file *file, void *priv,
if (no_overlay <= 0)
cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
- if (bttv_tvcards[btv->c.type].tuner != UNSET &&
- bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
+ if (btv->tuner_type != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER;
return 0;
}
@@ -2943,7 +2948,7 @@ static int bttv_g_tuner(struct file *file, void *priv,
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
@@ -3212,29 +3217,19 @@ err:
static int bttv_open(struct file *file)
{
int minor = video_devdata(file)->minor;
- struct bttv *btv = NULL;
+ struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
enum v4l2_buf_type type = 0;
- unsigned int i;
dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
lock_kernel();
- for (i = 0; i < bttv_num; i++) {
- if (bttvs[i].video_dev &&
- bttvs[i].video_dev->minor == minor) {
- btv = &bttvs[i];
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- }
- if (bttvs[i].vbi_dev &&
- bttvs[i].vbi_dev->minor == minor) {
- btv = &bttvs[i];
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- }
- }
- if (NULL == btv) {
+ if (btv->video_dev->minor == minor) {
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ } else if (btv->vbi_dev->minor == minor) {
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ } else {
+ WARN_ON(1);
unlock_kernel();
return -ENODEV;
}
@@ -3424,20 +3419,14 @@ static struct video_device bttv_video_template = {
static int radio_open(struct file *file)
{
int minor = video_devdata(file)->minor;
- struct bttv *btv = NULL;
+ struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
- unsigned int i;
dprintk("bttv: open minor=%d\n",minor);
lock_kernel();
- for (i = 0; i < bttv_num; i++) {
- if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
- btv = &bttvs[i];
- break;
- }
- }
- if (NULL == btv) {
+ WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor);
+ if (!btv->radio_dev || btv->radio_dev->minor != minor) {
unlock_kernel();
return -ENODEV;
}
@@ -3503,7 +3492,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
@@ -4198,6 +4187,7 @@ static struct video_device *vdev_init(struct bttv *btv,
vfd->parent = &btv->c.pci->dev;
vfd->release = video_device_release;
vfd->debug = bttv_debug;
+ video_set_drvdata(vfd, btv);
snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
type_name, bttv_tvcards[btv->c.type].name);
@@ -4307,8 +4297,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
if (bttv_num == BTTV_MAX)
return -ENOMEM;
printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
- btv=&bttvs[bttv_num];
- memset(btv,0,sizeof(*btv));
+ bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL);
btv->c.nr = bttv_num;
sprintf(btv->c.name,"bttv%d",btv->c.nr);
@@ -4512,6 +4501,9 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
pci_resource_len(btv->c.pci,0));
pci_set_drvdata(pci_dev, NULL);
+ bttvs[btv->c.nr] = NULL;
+ kfree(btv);
+
return;
}
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index bcd2cd240a16..511d2bf176f1 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -286,12 +286,10 @@ static int attach_inform(struct i2c_client *client)
btv->i2c_msp34xx_client = client;
if (client->driver->id == I2C_DRIVERID_TVAUDIO)
btv->i2c_tvaudio_client = client;
- if (btv->tuner_type != UNSET) {
+ if (btv->tuner_type != TUNER_ABSENT) {
struct tuner_setup tun_setup;
- if ((addr==ADDR_UNSET) ||
- (addr==client->addr)) {
-
+ if (addr == ADDR_UNSET || addr == client->addr) {
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
tun_setup.type = btv->tuner_type;
tun_setup.addr = addr;
diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bt8xx/bttv-if.c
index ecf07988cd33..a6a540dc9e4b 100644
--- a/drivers/media/video/bt8xx/bttv-if.c
+++ b/drivers/media/video/bt8xx/bttv-if.c
@@ -47,7 +47,10 @@ struct pci_dev* bttv_get_pcidev(unsigned int card)
{
if (card >= bttv_num)
return NULL;
- return bttvs[card].c.pci;
+ if (!bttvs[card])
+ return NULL;
+
+ return bttvs[card]->c.pci;
}
@@ -59,7 +62,10 @@ int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
+
gpio_inout(mask,data);
if (bttv_gpio)
bttv_gpio_tracking(btv,"extern enable");
@@ -74,7 +80,9 @@ int bttv_read_gpio(unsigned int card, unsigned long *data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
if(btv->shutdown) {
return -ENODEV;
@@ -94,7 +102,9 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
/* prior setting BT848_GPIO_REG_INP is (probably) not needed
because direct input is set on init */
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 5b1b8e4c78ba..d16af2836379 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -341,7 +341,7 @@ bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
int totalwidth = tvnorm->totalwidth;
int scaledtwidth = tvnorm->scaledtwidth;
- if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+ if (btv->input == btv->dig) {
swidth = 720;
totalwidth = 858;
scaledtwidth = 858;
@@ -391,7 +391,7 @@ bttv_calc_geo (struct bttv * btv,
&& crop->width == tvnorm->cropcap.defrect.width
&& crop->height == tvnorm->cropcap.defrect.height
&& width <= tvnorm->swidth /* see PAL-Nc et al */)
- || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+ || btv->input == btv->dig) {
bttv_calc_geo_old(btv, geo, width, height,
both_fields, tvnorm);
return;
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index 6819e21a3773..e79a402fa6cd 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -411,7 +411,7 @@ int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
return 0;
}
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm)
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
{
const struct bttv_tvnorm *tvnorm;
unsigned int real_samples_per_line;
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 529bf6cf634d..ead6e749372a 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -180,6 +180,7 @@
#define BTTV_BOARD_VD012 0x99
#define BTTV_BOARD_VD012_X1 0x9a
#define BTTV_BOARD_VD012_X2 0x9b
+#define BTTV_BOARD_IVCE8784 0x9c
/* more card-specific defines */
@@ -191,10 +192,6 @@
#define WINVIEW_PT2254_DATA 0x20
#define WINVIEW_PT2254_STROBE 0x80
-/* digital_mode */
-#define DIGITAL_MODE_VIDEO 1
-#define DIGITAL_MODE_CAMERA 2
-
struct bttv_core {
/* device structs */
struct pci_dev *pci;
@@ -209,21 +206,30 @@ struct bttv_core {
struct bttv;
-
-struct tvcard
-{
+struct tvcard {
char *name;
- unsigned int video_inputs;
- unsigned int audio_inputs;
- unsigned int tuner;
- unsigned int svhs;
- unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
+ void (*volume_gpio)(struct bttv *btv, __u16 volume);
+ void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
+ void (*muxsel_hook)(struct bttv *btv, unsigned int input);
+
+ /* MUX bits for each input, two bits per input starting with the LSB */
+ u32 muxsel; /* Use MUXSEL() to set */
+
u32 gpiomask;
- u32 muxsel[16];
u32 gpiomux[4]; /* Tuner, Radio, external, internal */
u32 gpiomute; /* GPIO mute setting */
u32 gpiomask2; /* GPIO MUX mask */
+ unsigned int tuner_type;
+ u8 tuner_addr;
+ u8 video_inputs; /* Number of inputs */
+ unsigned int svhs:4; /* Which input is s-video */
+#define NO_SVHS 15
+ unsigned int pll:2;
+#define PLL_NONE 0
+#define PLL_28 1
+#define PLL_35 2
+
/* i2c audio flags */
unsigned int no_msp34xx:1;
unsigned int no_tda9875:1;
@@ -231,32 +237,41 @@ struct tvcard
unsigned int needs_tvaudio:1;
unsigned int msp34xx_alt:1;
- /* flag: video pci function is unused */
- unsigned int no_video:1;
+ unsigned int no_video:1; /* video pci function is unused */
unsigned int has_dvb:1;
unsigned int has_remote:1;
+ unsigned int has_radio:1;
+ unsigned int has_dig_in:1; /* Has digital input (always last input) */
unsigned int no_gpioirq:1;
-
- /* other settings */
- unsigned int pll;
-#define PLL_NONE 0
-#define PLL_28 1
-#define PLL_35 2
-
- unsigned int tuner_type;
- unsigned int tuner_addr;
- unsigned int radio_addr;
-
- unsigned int has_radio;
-
- void (*volume_gpio)(struct bttv *btv, __u16 volume);
- void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-
- void (*muxsel_hook)(struct bttv *btv, unsigned int input);
};
extern struct tvcard bttv_tvcards[];
+/*
+ * This bit of cpp voodoo is used to create a macro with a variable number of
+ * arguments (1 to 16). It will pack each argument into a word two bits at a
+ * time. It can't be a function because it needs to be compile time constant to
+ * initialize structures. Since each argument must fit in two bits, it's ok
+ * that they are changed to octal. One should not use hex number, macros, or
+ * anything else with this macro. Just use plain integers from 0 to 3.
+ */
+#define _MUXSELf(a) 0##a << 30
+#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b)
+#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b)
+#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b)
+#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b)
+#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b)
+#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b)
+#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b)
+#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b)
+#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b)
+#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b)
+#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b)
+#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b)
+#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b)
+#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b)
+#define MUXSEL(a, b...) (a | _MUXSEL1(b))
+
/* identification / initialization of the card */
extern void bttv_idcard(struct bttv *btv);
extern void bttv_init_card1(struct bttv *btv);
@@ -264,7 +279,7 @@ extern void bttv_init_card2(struct bttv *btv);
/* card-specific funtions */
extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
+extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits);
/* extra tweaks for some chipsets */
extern void bttv_check_chipset(void);
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 199a4d225caf..b8274d233fd0 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -135,7 +135,7 @@ struct bttv_buffer {
/* bttv specific */
const struct bttv_format *fmt;
- int tvnorm;
+ unsigned int tvnorm;
int btformat;
int btswap;
struct bttv_geometry geo;
@@ -154,7 +154,7 @@ struct bttv_buffer_set {
};
struct bttv_overlay {
- int tvnorm;
+ unsigned int tvnorm;
struct v4l2_rect w;
enum v4l2_field field;
struct v4l2_clip *clips;
@@ -174,7 +174,7 @@ struct bttv_vbi_fmt {
};
/* bttv-vbi.c */
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm);
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm);
struct bttv_crop {
/* A cropping rectangle in struct bttv_tvnorm.cropcap units. */
@@ -329,7 +329,7 @@ struct bttv {
unsigned int cardid; /* pci subsystem id (bt878 based ones) */
unsigned int tuner_type; /* tuner chip type */
unsigned int tda9887_conf;
- unsigned int svhs;
+ unsigned int svhs, dig;
struct bttv_pll_info pll;
int triton1;
int gpioirq;
@@ -378,7 +378,8 @@ struct bttv {
unsigned int audio;
unsigned int mute;
unsigned long freq;
- int tvnorm,hue,contrast,bright,saturation;
+ unsigned int tvnorm;
+ int hue, contrast, bright, saturation;
struct v4l2_framebuffer fbuf;
unsigned int field_count;
@@ -461,7 +462,13 @@ struct bttv {
/* our devices */
#define BTTV_MAX 32
extern unsigned int bttv_num;
-extern struct bttv bttvs[BTTV_MAX];
+extern struct bttv *bttvs[BTTV_MAX];
+
+static inline unsigned int bttv_muxsel(const struct bttv *btv,
+ unsigned int input)
+{
+ return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3;
+}
#endif
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 14bebf8a116f..87e91072627a 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -18,7 +18,6 @@
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 7292a6316e63..2f33abd2e01c 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -218,7 +218,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cs53l32a",
- .driverid = I2C_DRIVERID_CS53L32A,
.command = cs53l32a_command,
.remove = cs53l32a_remove,
.probe = cs53l32a_probe,
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 57beddf0af4d..d19bd778c6ac 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -64,8 +64,7 @@ int cx18_audio_set_io(struct cx18 *cx)
val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
(audio_input << 4);
- cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE);
- cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
+ cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 0b1c84b4ddd6..a3bd2c95f582 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -169,9 +169,14 @@ static void cx18_av_initialize(struct cx18 *cx)
/* Set VGA_TRACK_RANGE to 0x20 */
cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
- /* Enable VBI capture */
- cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
- /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
+ /*
+ * Initial VBI setup
+ * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
+ * don't clamp raw samples when codes are in use, 1 byte user D-words,
+ * IDID0 has line #, RP code V bit transition on VBLANK, data during
+ * blanking intervals
+ */
+ cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
/* Set the video input.
The setting in MODE_CTRL gets lost when we do the above setup */
@@ -213,6 +218,7 @@ void cx18_av_std_setup(struct cx18 *cx)
cx18_av_write(cx, 0x49f, 0x14);
if (std & V4L2_STD_625_50) {
+ /* FIXME - revisit these for Sliced VBI */
hblank = 132;
hactive = 720;
burst = 93;
@@ -236,13 +242,34 @@ void cx18_av_std_setup(struct cx18 *cx)
sc = 672351;
}
} else {
+ /*
+ * The following relationships of half line counts should hold:
+ * 525 = vsync + vactive + vblank656
+ * 12 = vblank656 - vblank
+ *
+ * vsync: always 6 half-lines of vsync pulses
+ * vactive: half lines of active video
+ * vblank656: half lines, after line 3, of blanked video
+ * vblank: half lines, after line 9, of blanked video
+ *
+ * vblank656 starts counting from the falling edge of the first
+ * vsync pulse (start of line 4)
+ * vblank starts counting from the after the 6 vsync pulses and
+ * 6 equalization pulses (start of line 10)
+ *
+ * For 525 line systems the driver will extract VBI information
+ * from lines 10 through 21. To avoid the EAV RP code from
+ * toggling at the start of hblank at line 22, where sliced VBI
+ * data from line 21 is stuffed, also treat line 22 as blanked.
+ */
+ vblank656 = 38; /* lines 4 through 22 */
+ vblank = 26; /* lines 10 through 22 */
+ vactive = 481; /* lines 23 through 262.5 */
+
hactive = 720;
hblank = 122;
- vactive = 487;
luma_lpf = 1;
uv_lpf = 1;
- vblank = 26;
- vblank656 = 26;
src_decimation = 0x21f;
if (std == V4L2_STD_PAL_60) {
@@ -325,14 +352,14 @@ void cx18_av_std_setup(struct cx18 *cx)
cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
- /* Sets VBI parameters */
if (std & V4L2_STD_625_50) {
- cx18_av_write(cx, 0x47f, 0x01);
- state->vbi_line_offset = 5;
+ state->slicer_line_delay = 1;
+ state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
} else {
- cx18_av_write(cx, 0x47f, 0x00);
- state->vbi_line_offset = 8;
+ state->slicer_line_delay = 0;
+ state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
}
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
}
/* ----------------------------------------------------------------------- */
@@ -548,7 +575,7 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
CX18_ERR("invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -680,19 +707,45 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
/* ----------------------------------------------------------------------- */
+static int valid_av_cmd(unsigned int cmd)
+{
+ switch (cmd) {
+ /* All commands supported by cx18_av_cmd() */
+ case VIDIOC_INT_DECODE_VBI_LINE:
+ case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+ case VIDIOC_STREAMON:
+ case VIDIOC_STREAMOFF:
+ case VIDIOC_LOG_STATUS:
+ case VIDIOC_G_CTRL:
+ case VIDIOC_S_CTRL:
+ case VIDIOC_QUERYCTRL:
+ case VIDIOC_G_STD:
+ case VIDIOC_S_STD:
+ case AUDC_SET_RADIO:
+ case VIDIOC_INT_G_VIDEO_ROUTING:
+ case VIDIOC_INT_S_VIDEO_ROUTING:
+ case VIDIOC_INT_G_AUDIO_ROUTING:
+ case VIDIOC_INT_S_AUDIO_ROUTING:
+ case VIDIOC_S_FREQUENCY:
+ case VIDIOC_G_TUNER:
+ case VIDIOC_S_TUNER:
+ case VIDIOC_G_FMT:
+ case VIDIOC_S_FMT:
+ case VIDIOC_INT_RESET:
+ return 1;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
{
struct cx18_av_state *state = &cx->av_state;
struct v4l2_tuner *vt = arg;
struct v4l2_routing *route = arg;
- /* ignore these commands */
- switch (cmd) {
- case TUNER_SET_TYPE_ADDR:
- return 0;
- }
-
- if (!state->is_initialized) {
+ if (!state->is_initialized && valid_av_cmd(cmd)) {
CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
/* initialize on first use */
state->is_initialized = 1;
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index cf68a6039091..d83760cae540 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -79,11 +79,28 @@ struct cx18_av_state {
enum cx18_av_audio_input aud_input;
u32 audclk_freq;
int audmode;
- int vbi_line_offset;
int default_volume;
u32 id;
u32 rev;
int is_initialized;
+
+ /*
+ * The VBI slicer starts operating and counting lines, begining at
+ * slicer line count of 1, at D lines after the deassertion of VRESET
+ * This staring field line, S, is 6 or 10 for 625 or 525 line systems.
+ * Sliced ancillary data captured on VBI slicer line M is sent at the
+ * beginning of the next VBI slicer line, VBI slicer line count N = M+1.
+ * Thus when the VBI slicer reports a VBI slicer line number with
+ * ancillary data, the IDID0 byte indicates VBI slicer line N.
+ * The actual field line that the captured data comes from is
+ * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
+ *
+ * D is the slicer_line_delay value programmed into register 0x47f.
+ * (S+D-2) is the slicer_line_offset used to convert slicer reported
+ * line counts to actual field lines.
+ */
+ int slicer_line_delay;
+ int slicer_line_offset;
};
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index c64fd0a05a97..940ea9352115 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -36,7 +36,7 @@ int cx18_av_loadfw(struct cx18 *cx)
int i;
int retries1 = 0;
- if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
+ if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
CX18_ERR("unable to open firmware %s\n", FWFILE);
return -EINVAL;
}
@@ -115,9 +115,9 @@ int cx18_av_loadfw(struct cx18 *cx)
are generated) */
cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
- /* set alt I2s master clock to /16 and enable alt divider i2s
+ /* set alt I2s master clock to /0x16 and enable alt divider i2s
passthrough */
- cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
+ cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);
cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
0x3F00FFFF);
@@ -131,7 +131,8 @@ int cx18_av_loadfw(struct cx18 *cx)
v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
/* If bit 11 is 1, clear bit 10 */
if (v & 0x800)
- cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE);
+ cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
+ 0, 0x400);
/* Enable WW auto audio standard detection */
v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 1527ea4f6b06..43267d1afb92 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -24,6 +24,52 @@
#include "cx18-driver.h"
+/*
+ * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
+ * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
+ * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
+ * (should!) look like:
+ * 4 byte EAV code: 0xff 0x00 0x00 0xRP
+ * unknown number of possible idle bytes
+ * 3 byte Anc data preamble: 0x00 0xff 0xff
+ * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
+ * 1 byte secondary data id: nessssss (parity bits, SDID bits)
+ * 1 byte data word count: necccccc (parity bits, NN Dword count)
+ * 2 byte Internal DID: VBI-line-# 0x80
+ * NN data bytes
+ * 1 byte checksum
+ * Fill bytes needed to fil out to 4*NN bytes of payload
+ *
+ * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
+ * in the vertical blanking interval are:
+ * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
+ * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
+ *
+ * Since the V bit is only allowed to toggle in the EAV RP code, just
+ * before the first active region line and for active lines, they are:
+ * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
+ * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
+ *
+ * The user application DID bytes we care about are:
+ * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
+ * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
+ *
+ */
+static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
+
+struct vbi_anc_data {
+ /* u8 eav[4]; */
+ /* u8 idle[]; Variable number of idle bytes */
+ u8 preamble[3];
+ u8 did;
+ u8 sdid;
+ u8 data_count;
+ u8 idid[2];
+ u8 payload[1]; /* data_count of payload */
+ /* u8 checksum; */
+ /* u8 fill[]; Variable number of fill bytes */
+};
+
static int odd_parity(u8 c)
{
c ^= (c >> 4);
@@ -96,7 +142,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
0, V4L2_SLICED_WSS_625, 0, /* 4 */
V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 - unlike cx25840 */
0, 0, 0, 0
};
int is_pal = !(state->std & V4L2_STD_525_60);
@@ -136,7 +182,6 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
case VIDIOC_S_FMT:
{
int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
int i, x;
u8 lcr[24];
@@ -153,7 +198,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
cx18_av_std_setup(cx);
/* VBI Offset */
- cx18_av_write(cx, 0x47f, vbi_offset);
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
cx18_av_write(cx, 0x404, 0x2e);
break;
}
@@ -167,8 +212,9 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
/* Sliced VBI */
cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
cx18_av_write(cx, 0x406, 0x13);
- cx18_av_write(cx, 0x47f, vbi_offset);
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+ /* Force impossible lines to 0 */
if (is_pal) {
for (i = 0; i <= 6; i++)
svbi->service_lines[0][i] =
@@ -183,6 +229,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
svbi->service_lines[1][i] = 0;
}
+ /* Build register values for requested service lines */
for (i = 7; i <= 23; i++) {
for (x = 0; x <= 1; x++) {
switch (svbi->service_lines[1-x][i]) {
@@ -196,7 +243,7 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
lcr[i] |= 6 << (4 * x);
break;
case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
+ lcr[i] |= 7 << (4 * x); /*'840 differs*/
break;
}
}
@@ -213,54 +260,61 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
}
cx18_av_write(cx, 0x43c, 0x16);
- cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
+ /* FIXME - should match vblank set in cx18_av_std_setup() */
+ cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
break;
}
case VIDIOC_INT_DECODE_VBI_LINE:
{
struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
-
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
+ u8 *p;
+ struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p;
+ int did, sdid, l, err = 0;
+
+ /*
+ * Check for the ancillary data header for sliced VBI
+ */
+ if (anc->preamble[0] ||
+ anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
+ (anc->did != sliced_vbi_did[0] &&
+ anc->did != sliced_vbi_did[1])) {
vbi->line = vbi->type = 0;
break;
}
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += state->vbi_line_offset;
- p += 4;
+ did = anc->did;
+ sdid = anc->sdid & 0xf;
+ l = anc->idid[0] & 0x3f;
+ l += state->slicer_line_offset;
+ p = anc->payload;
- switch (id2) {
+ /* Decode the SDID set by the slicer */
+ switch (sdid) {
case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
+ sdid = V4L2_SLICED_TELETEXT_B;
break;
case 4:
- id2 = V4L2_SLICED_WSS_625;
+ sdid = V4L2_SLICED_WSS_625;
break;
case 6:
- id2 = V4L2_SLICED_CAPTION_525;
+ sdid = V4L2_SLICED_CAPTION_525;
err = !odd_parity(p[0]) || !odd_parity(p[1]);
break;
- case 9:
- id2 = V4L2_SLICED_VPS;
+ case 7: /* Differs from cx25840 */
+ sdid = V4L2_SLICED_VPS;
if (decode_vps(p, p) != 0)
err = 1;
break;
default:
- id2 = 0;
+ sdid = 0;
err = 1;
break;
}
- vbi->type = err ? 0 : id2;
+ vbi->type = err ? 0 : sdid;
vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
+ vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
vbi->p = p;
break;
}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index e274043657dd..6e2105ac2bc4 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -51,7 +51,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
static const struct cx18_card cx18_card_hvr1600_esmt = {
.type = CX18_CARD_HVR_1600_ESMT,
.name = "Hauppauge HVR-1600",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Simultaneous Digital and Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_muxer = CX18_HW_CS5345,
@@ -97,7 +97,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
static const struct cx18_card cx18_card_hvr1600_samsung = {
.type = CX18_CARD_HVR_1600_SAMSUNG,
.name = "Hauppauge HVR-1600 (Preproduction)",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Simultaneous Digital and Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_muxer = CX18_HW_CS5345,
@@ -152,7 +152,7 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
static const struct cx18_card cx18_card_h900 = {
.type = CX18_CARD_COMPRO_H900,
.name = "Compro VideoMate H900",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_all = CX18_HW_TUNER,
@@ -249,7 +249,7 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
static const struct cx18_card cx18_card_cnxt_raptor_pal = {
.type = CX18_CARD_CNXT_RAPTOR_PAL,
.name = "Conexant Raptor PAL/SECAM",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_muxer = CX18_HW_GPIO,
@@ -339,13 +339,14 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
/* Leadtek WinFast PVR2100 */
static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 },
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
{ 0, 0, 0 }
};
static const struct cx18_card cx18_card_leadtek_pvr2100 = {
.type = CX18_CARD_LEADTEK_PVR2100,
- .name = "Leadtek WinFast PVR2100",
+ .name = "Leadtek WinFast PVR2100/DVR3100 H",
.comment = "Experimenters and photos needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 6fa7bcb42dde..f8ee29f102d4 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -49,8 +49,7 @@
/* V4L2 capability aliases */
#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
- V4L2_CAP_VBI_CAPTURE)
-/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
+ V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
struct cx18_card_video_input {
u8 video_type; /* video input type */
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 17edf305d649..10a4e07b7aca 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -30,6 +30,7 @@
#include "cx18-mailbox.h"
#include "cx18-controls.h"
+/* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -178,8 +179,8 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt
int i;
for (i = 0; i < CX18_VBI_FRAMES; i++) {
- /* Yuck, hardcoded. Needs to be a define */
- cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
+ cx->vbi.sliced_mpeg_data[i] =
+ kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
if (cx->vbi.sliced_mpeg_data[i] == NULL) {
while (--i >= 0) {
kfree(cx->vbi.sliced_mpeg_data[i]);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index f50cf2167adc..2a45bbc757e8 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -159,7 +159,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t 4 = Yuan MPC718\n"
"\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
"\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
- "\t\t\t 7 = Leadtek WinFast PVR2100\n"
+ "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -448,34 +448,38 @@ static void cx18_process_options(struct cx18 *cx)
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
- /* Except for VBI ensure stream_buffers & stream_buf_size are valid */
+ /* Ensure stream_buffers & stream_buf_size are valid */
for (i = 0; i < CX18_MAX_STREAMS; i++) {
- /* User said to use 0 buffers */
- if (cx->stream_buffers[i] == 0) {
- cx->options.megabytes[i] = 0;
- cx->stream_buf_size[i] = 0;
- continue;
- }
- /* User said to use 0 MB total */
- if (cx->options.megabytes[i] <= 0) {
+ if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
+ cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
+ cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
cx->options.megabytes[i] = 0;
cx->stream_buffers[i] = 0;
cx->stream_buf_size[i] = 0;
continue;
}
- /* VBI is computed later or user said buffer has size 0 */
- if (cx->stream_buf_size[i] <= 0) {
- if (i != CX18_ENC_STREAM_TYPE_VBI) {
- cx->options.megabytes[i] = 0;
- cx->stream_buffers[i] = 0;
- cx->stream_buf_size[i] = 0;
+ /*
+ * VBI is a special case where the stream_buf_size is fixed
+ * and already in bytes
+ */
+ if (i == CX18_ENC_STREAM_TYPE_VBI) {
+ if (cx->stream_buffers[i] < 0) {
+ cx->stream_buffers[i] =
+ cx->options.megabytes[i] * 1024 * 1024
+ / cx->stream_buf_size[i];
+ } else {
+ /* N.B. This might round down to 0 */
+ cx->options.megabytes[i] =
+ cx->stream_buffers[i]
+ * cx->stream_buf_size[i]/(1024 * 1024);
}
continue;
}
+ /* All other streams have stream_buf_size in kB at this point */
if (cx->stream_buffers[i] < 0) {
cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
/ cx->stream_buf_size[i];
@@ -502,7 +506,7 @@ static void cx18_process_options(struct cx18 *cx)
else if (cx->options.cardtype != 0)
CX18_ERR("Unknown user specified type, trying to autodetect card\n");
if (cx->card == NULL) {
- if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
+ if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_INFO("Autodetected Hauppauge card\n");
}
@@ -512,13 +516,13 @@ static void cx18_process_options(struct cx18 *cx)
if (cx->card->pci_list == NULL)
continue;
for (j = 0; cx->card->pci_list[j].device; j++) {
- if (cx->dev->device !=
+ if (cx->pci_dev->device !=
cx->card->pci_list[j].device)
continue;
- if (cx->dev->subsystem_vendor !=
+ if (cx->pci_dev->subsystem_vendor !=
cx->card->pci_list[j].subsystem_vendor)
continue;
- if (cx->dev->subsystem_device !=
+ if (cx->pci_dev->subsystem_device !=
cx->card->pci_list[j].subsystem_device)
continue;
CX18_INFO("Autodetected %s card\n", cx->card->name);
@@ -531,9 +535,10 @@ done:
if (cx->card == NULL) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- cx->dev->vendor, cx->dev->device);
+ cx->pci_dev->vendor, cx->pci_dev->device);
CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- cx->dev->subsystem_vendor, cx->dev->subsystem_device);
+ cx->pci_dev->subsystem_vendor,
+ cx->pci_dev->subsystem_device);
CX18_ERR("Defaulting to %s card\n", cx->card->name);
CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
@@ -553,7 +558,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
{
int i;
- cx->base_addr = pci_resource_start(cx->dev, 0);
+ cx->base_addr = pci_resource_start(cx->pci_dev, 0);
mutex_init(&cx->serialize_lock);
mutex_init(&cx->i2c_bus_lock[0]);
@@ -562,8 +567,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->epu2apu_mb_lock);
mutex_init(&cx->epu2cpu_mb_lock);
- spin_lock_init(&cx->lock);
-
cx->work_queue = create_singlethread_workqueue(cx->name);
if (cx->work_queue == NULL) {
CX18_ERR("Unable to create work hander thread\n");
@@ -587,7 +590,8 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
(cx->params.video_temporal_filter_mode << 1) |
(cx->params.video_median_filter_type << 2);
cx->params.port = CX2341X_PORT_MEMORY;
- cx->params.capabilities = CX2341X_CAP_HAS_TS;
+ cx->params.capabilities =
+ CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3 | CX2341X_CAP_HAS_SLICED_VBI;
init_waitqueue_head(&cx->cap_w);
init_waitqueue_head(&cx->mb_apu_waitq);
init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -597,49 +601,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
- /*
- * The VBI line sizes depend on the pixel clock and the horiz rate
- *
- * (1/Fh)*(2*Fp) = Samples/line
- * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
- *
- * Sliced VBI is sent as ancillary data during horizontal blanking
- * Raw VBI is sent as active video samples during vertcal blanking
- *
- * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
- * length of 720 pixels @ 4:2:2 sampling. Thus...
- *
- * For systems that use a 15.734 kHz horizontal rate, such as
- * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
- *
- * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
- * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- * For systems that use a 15.625 kHz horizontal rate, such as
- * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
- *
- * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
- * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- */
-
- /* FIXME: init these based on tuner std & modify when std changes */
- /* CX18-AV-Core number of VBI samples output per horizontal line */
- cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */
- cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */
-
- /* CX18-AV-Core VBI samples/line possibly rounded up */
- cx->vbi.raw_size = 1444; /* Real max size is 1444 */
- cx->vbi.sliced_size = 284; /* Real max size is 284 */
-
- /*
- * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode
- * Task Field VerticalBlank HorizontalBlank 0 0 0 0
- */
- cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */
- cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */
- cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */
- cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */
return 0;
}
@@ -672,11 +633,12 @@ static void __devinit cx18_init_struct2(struct cx18 *cx)
cx->av_state.aud_input = CX18_AV_AUDIO8;
cx->av_state.audclk_freq = 48000;
cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
- /* FIXME - 8 is NTSC value, investigate */
- cx->av_state.vbi_line_offset = 8;
+ cx->av_state.slicer_line_delay = 0;
+ cx->av_state.slicer_line_offset =
+ (10 + cx->av_state.slicer_line_delay - 2);
}
-static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
+static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
u16 cmd;
@@ -684,11 +646,11 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
CX18_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(dev)) {
+ if (pci_enable_device(pci_dev)) {
CX18_ERR("Can't enable device %d!\n", cx->num);
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
+ if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
return -EIO;
}
@@ -698,25 +660,25 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
}
/* Enable bus mastering and memory mapped IO for the CX23418 */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_read_config_word(pci_dev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev);
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < 64 && cx18_pci_latency) {
CX18_INFO("Unreasonably low latency timer, "
"setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64);
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
}
CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
"irq: %d, latency: %d, memory: 0x%lx\n",
- cx->dev->device, cx->card_rev, dev->bus->number,
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
- cx->dev->irq, pci_latency, (unsigned long)cx->base_addr);
+ cx->pci_dev->device, cx->card_rev, pci_dev->bus->number,
+ PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn),
+ cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr);
return 0;
}
@@ -727,7 +689,7 @@ static u32 cx18_request_module(struct cx18 *cx, u32 hw,
{
if ((hw & id) == 0)
return hw;
- if (request_module(name) != 0) {
+ if (request_module("%s", name) != 0) {
CX18_ERR("Failed to load module %s\n", name);
return hw & ~id;
}
@@ -771,12 +733,11 @@ static void cx18_load_and_init_modules(struct cx18 *cx)
hw = cx->hw_flags;
}
-static int __devinit cx18_probe(struct pci_dev *dev,
+static int __devinit cx18_probe(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
int retval = 0;
int i;
- int vbi_buf_size;
u32 devtype;
struct cx18 *cx;
@@ -796,33 +757,37 @@ static int __devinit cx18_probe(struct pci_dev *dev,
return -ENOMEM;
}
cx18_cards[cx18_cards_active] = cx;
- cx->dev = dev;
cx->num = cx18_cards_active++;
snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
CX18_INFO("Initializing card #%d\n", cx->num);
spin_unlock(&cx18_cards_lock);
+ cx->pci_dev = pci_dev;
+ retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
+ if (retval) {
+ CX18_ERR("Call to v4l2_device_register() failed\n");
+ goto err;
+ }
+ CX18_DEBUG_INFO("registered v4l2_device name: %s\n", cx->v4l2_dev.name);
+
cx18_process_options(cx);
if (cx->options.cardtype == -1) {
retval = -ENODEV;
- goto err;
+ goto unregister_v4l2;
}
if (cx18_init_struct1(cx)) {
retval = -ENOMEM;
- goto err;
+ goto unregister_v4l2;
}
CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
/* PCI Device Setup */
- retval = cx18_setup_pci(cx, dev, pci_id);
+ retval = cx18_setup_pci(cx, pci_dev, pci_id);
if (retval != 0)
goto free_workqueue;
- /* save cx in the pci struct for later use */
- pci_set_drvdata(dev, cx);
-
/* map io memory */
CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
@@ -881,7 +846,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
cx18_init_scb(cx);
/* Register IRQ */
- retval = request_irq(cx->dev->irq, cx18_irq_handler,
+ retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
if (retval) {
CX18_ERR("Failed to register irq %d\n", retval);
@@ -928,23 +893,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
}
cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
- /*
- * FIXME: setting the buffer size based on the tuner standard is
- * suboptimal, as the CVBS and SVideo inputs could use a different std
- * and the buffer could end up being too small in that case.
- */
- vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
-
- if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
- / vbi_buf_size;
- else
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
- / (1024 * 1024);
-
if (cx->options.radio > 0)
cx->v4l2_cap |= V4L2_CAP_RADIO;
@@ -992,7 +940,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
free_streams:
cx18_streams_cleanup(cx, 1);
free_irq:
- free_irq(cx->dev->irq, (void *)cx);
+ free_irq(cx->pci_dev->irq, (void *)cx);
free_i2c:
exit_cx18_i2c(cx);
free_map:
@@ -1001,6 +949,8 @@ free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueue:
destroy_workqueue(cx->work_queue);
+unregister_v4l2:
+ v4l2_device_unregister(&cx->v4l2_dev);
err:
if (retval == 0)
retval = -ENODEV;
@@ -1043,8 +993,21 @@ int cx18_init_on_first_open(struct cx18 *cx)
}
set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
- /* Init the firmware twice to work around a silicon bug
- * transport related. */
+ /*
+ * Init the firmware twice to work around a silicon bug
+ * with the digital TS.
+ *
+ * The second firmware load requires us to normalize the APU state,
+ * or the audio for the first analog capture will be badly incorrect.
+ *
+ * I can't seem to call APU_RESETAI and have it succeed without the
+ * APU capturing audio, so we start and stop it here to do the reset
+ */
+
+ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+ cx18_vapi(cx, CX18_APU_RESETAI, 0);
+ cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
fw_retry_count = 3;
while (--fw_retry_count > 0) {
@@ -1060,6 +1023,19 @@ int cx18_init_on_first_open(struct cx18 *cx)
return -ENXIO;
}
+ /*
+ * The second firmware load requires us to normalize the APU state,
+ * or the audio for the first analog capture will be badly incorrect.
+ *
+ * I can't seem to call APU_RESETAI and have it succeed without the
+ * APU capturing audio, so we start and stop it here to do the reset
+ */
+
+ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+ cx18_vapi(cx, CX18_APU_RESETAI, 0);
+ cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
+
vf.tuner = 0;
vf.type = V4L2_TUNER_ANALOG_TV;
vf.frequency = 6400; /* the tuner 'baseline' frequency */
@@ -1092,7 +1068,8 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx)
static void cx18_remove(struct pci_dev *pci_dev)
{
- struct cx18 *cx = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct cx18 *cx = container_of(v4l2_dev, struct cx18, v4l2_dev);
CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
@@ -1115,13 +1092,15 @@ static void cx18_remove(struct pci_dev *pci_dev)
exit_cx18_i2c(cx);
- free_irq(cx->dev->irq, (void *)cx);
+ free_irq(cx->pci_dev->irq, (void *)cx);
cx18_iounmap(cx);
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
- pci_disable_device(cx->dev);
+ pci_disable_device(cx->pci_dev);
+
+ v4l2_device_unregister(v4l2_dev);
CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
}
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 0d2edebc39b4..7fc914c521f7 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -48,6 +48,7 @@
#include <linux/dvb/audio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include "cx18-mailbox.h"
#include "cx18-av-core.h"
@@ -79,7 +80,7 @@
#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
-#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
+#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */
#define CX18_CARD_LAST 6
#define CX18_ENC_STREAM_TYPE_MPG 0
@@ -279,7 +280,7 @@ struct cx18_epu_work_order {
struct cx18_stream {
/* These first four fields are always set, even if the stream
is not actually created. */
- struct video_device *v4l2dev; /* NULL when stream not created */
+ struct video_device *video_dev; /* NULL when stream not created */
struct cx18 *cx; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
@@ -292,7 +293,6 @@ struct cx18_stream {
int dma; /* can be PCI_DMA_TODEVICE,
PCI_DMA_FROMDEVICE or
PCI_DMA_NONE */
- u64 dma_pts;
wait_queue_head_t waitq;
/* Buffer Stats */
@@ -318,59 +318,121 @@ struct cx18_open_id {
/* forward declaration of struct defined in cx18-cards.h */
struct cx18_card;
+/*
+ * A note about "sliced" VBI data as implemented in this driver:
+ *
+ * Currently we collect the sliced VBI in the form of Ancillary Data
+ * packets, inserted by the AV core decoder/digitizer/slicer in the
+ * horizontal blanking region of the VBI lines, in "raw" mode as far as
+ * the Encoder is concerned. We don't ever tell the Encoder itself
+ * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
+ *
+ * We then process the ancillary data ourselves to send the sliced data
+ * to the user application directly or build up MPEG-2 private stream 1
+ * packets to splice into (only!) MPEG-2 PS streams for the user app.
+ *
+ * (That's how ivtv essentially does it.)
+ *
+ * The Encoder should be able to extract certain sliced VBI data for
+ * us and provide it in a separate stream or splice it into any type of
+ * MPEG PS or TS stream, but this isn't implemented yet.
+ */
+
+/*
+ * Number of "raw" VBI samples per horizontal line we tell the Encoder to
+ * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
+ * It depends on the pixel clock and the horiz rate:
+ *
+ * (1/Fh)*(2*Fp) = Samples/line
+ * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
+ *
+ * Sliced VBI data is sent as ancillary data during horizontal blanking
+ * Raw VBI is sent as active video samples during vertcal blanking
+ *
+ * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
+ * length of 720 pixels @ 4:2:2 sampling. Thus...
+ *
+ * For systems that use a 15.734 kHz horizontal rate, such as
+ * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
+ *
+ * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
+ * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
+ *
+ * For systems that use a 15.625 kHz horizontal rate, such as
+ * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
+ *
+ * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
+ * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
+ */
+static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
+static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
+static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
#define CX18_VBI_FRAMES 32
-/* VBI data */
struct vbi_info {
- u32 enc_size;
- u32 frame;
- u8 cc_data_odd[256];
- u8 cc_data_even[256];
- int cc_pos;
- u8 cc_no_update;
- u8 vps[5];
- u8 vps_found;
- int wss;
- u8 wss_found;
- u8 wss_no_update;
- u32 raw_decoder_line_size;
- u8 raw_decoder_sav_odd_field;
- u8 raw_decoder_sav_even_field;
- u32 sliced_decoder_line_size;
- u8 sliced_decoder_sav_odd_field;
- u8 sliced_decoder_sav_even_field;
+ /* Current state of v4l2 VBI settings for this device */
struct v4l2_format in;
- /* convenience pointer to sliced struct in vbi_in union */
- struct v4l2_sliced_vbi_format *sliced_in;
- u32 service_set_in;
- int insert_mpeg;
+ struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
+ u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
+ u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
- /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
- One for /dev/vbi0 and one for /dev/vbi8 */
- struct v4l2_sliced_vbi_data sliced_data[36];
+ u32 frame; /* Count of VBI buffers/frames received from Encoder */
- /* Buffer for VBI data inserted into MPEG stream.
- The first byte is a dummy byte that's never used.
- The next 16 bytes contain the MPEG header for the VBI data,
- the remainder is the actual VBI data.
- The max size accepted by the MPEG VBI reinsertion turns out
- to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
- where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
- a single line header byte and 2 * 18 is the number of VBI lines per frame.
+ /*
+ * Vars for creation and insertion of MPEG Private Stream 1 packets
+ * of sliced VBI data into an MPEG PS
+ */
- However, it seems that the data must be 1K aligned, so we have to
- pad the data until the 1 or 2 K boundary.
+ /* Boolean: create and insert Private Stream 1 packets into the PS */
+ int insert_mpeg;
- This pointer array will allocate 2049 bytes to store each VBI frame. */
+ /*
+ * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
+ * Used in cx18-vbi.c only for collecting sliced data, and as a source
+ * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
+ * We don't need to save state here, but the array may have been a bit
+ * too big (2304 bytes) to alloc from the stack.
+ */
+ struct v4l2_sliced_vbi_data sliced_data[36];
+
+ /*
+ * A ring buffer of driver-generated MPEG-2 PS
+ * Program Pack/Private Stream 1 packets for sliced VBI data insertion
+ * into the MPEG PS stream.
+ *
+ * In each sliced_mpeg_data[] buffer is:
+ * 16 byte MPEG-2 PS Program Pack Header
+ * 16 byte MPEG-2 Private Stream 1 PES Header
+ * 4 byte magic number: "itv0" or "ITV0"
+ * 4 byte first field line mask, if "itv0"
+ * 4 byte second field line mask, if "itv0"
+ * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
+ *
+ * Each line in the payload is
+ * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
+ * 42 bytes of line data
+ *
+ * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
+ * which is the payload size a PVR-350 (CX23415) MPEG decoder will
+ * accept for VBI data. So, including the headers, it's a maximum 1584
+ * bytes total.
+ */
+#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
+ /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
+#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
u32 sliced_mpeg_size[CX18_VBI_FRAMES];
- struct cx18_buffer sliced_mpeg_buf;
+
+ /* Count of Program Pack/Program Stream 1 packets inserted into PS */
u32 inserted_frame;
- u32 start[2], count;
- u32 raw_size;
- u32 sliced_size;
+ /*
+ * A dummy driver stream transfer buffer with a copy of the next
+ * sliced_mpeg_data[] buffer for output to userland apps.
+ * Only used in cx18-fileops.c, but its state needs to persist at times.
+ */
+ struct cx18_buffer sliced_mpeg_buf;
};
/* Per cx23418, per I2C bus private algo callback data */
@@ -385,7 +447,9 @@ struct cx18_i2c_algo_callback_data {
struct cx18 {
int num; /* board number, -1 during init! */
char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
- struct pci_dev *dev; /* PCI device */
+ struct pci_dev *pci_dev;
+ struct v4l2_device v4l2_dev;
+
const struct cx18_card *card; /* card information */
const char *card_name; /* full name of the card */
const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
@@ -413,10 +477,7 @@ struct cx18 {
/* dualwatch */
unsigned long dualwatch_jiffies;
- u16 dualwatch_stereo_mode;
-
- /* Digitizer type */
- int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
+ u32 dualwatch_stereo_mode;
struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
struct cx18_options options; /* User options */
@@ -426,7 +487,6 @@ struct cx18 {
unsigned long i_flags; /* global cx18 flags */
atomic_t ana_capturing; /* count number of active analog capture streams */
atomic_t tot_capturing; /* total count number of active capture streams */
- spinlock_t lock; /* lock access to this struct */
int search_pack_header;
int open_id; /* incremented each time an open occurs, used as
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index bd5e6f3fd4d0..3b86f57cd15a 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -167,7 +167,7 @@ int cx18_dvb_register(struct cx18_stream *stream)
ret = dvb_register_adapter(&dvb->dvb_adapter,
CX18_DRIVER_NAME,
- THIS_MODULE, &cx->dev->dev, adapter_nr);
+ THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
if (ret < 0)
goto err_out;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 055f6e004b2d..68dd50ac4bfe 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -128,10 +128,10 @@ static void cx18_release_stream(struct cx18_stream *s)
static void cx18_dualwatch(struct cx18 *cx)
{
struct v4l2_tuner vt;
- u16 new_bitmap;
- u16 new_stereo_mode;
- const u16 stereo_mask = 0x0300;
- const u16 dual = 0x0200;
+ u32 new_bitmap;
+ u32 new_stereo_mode;
+ const u32 stereo_mask = 0x0300;
+ const u32 dual = 0x0200;
u32 h;
new_stereo_mode = cx->params.audio_properties & stereo_mask;
@@ -176,6 +176,8 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
*err = 0;
while (1) {
if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
+ /* Process pending program info updates and pending
+ VBI data */
if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
cx->dualwatch_jiffies = jiffies;
@@ -186,7 +188,6 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
/* byteswap and process VBI data */
cx18_process_vbi_data(cx, buf,
- s_vbi->dma_pts,
s_vbi->type);
cx18_stream_put_buf_fw(s_vbi, buf);
}
@@ -207,8 +208,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
cx18_buf_swap(buf);
else {
/* byteswap and process VBI data */
- cx18_process_vbi_data(cx, buf,
- s->dma_pts, s->type);
+ cx18_process_vbi_data(cx, buf, s->type);
}
return buf;
}
@@ -260,6 +260,20 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
len = ucount;
if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
!cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
+ /*
+ * Try to find a good splice point in the PS, just before
+ * an MPEG-2 Program Pack start code, and provide only
+ * up to that point to the user, so it's easy to insert VBI data
+ * the next time around.
+ */
+ /* FIXME - This only works for an MPEG-2 PS, not a TS */
+ /*
+ * An MPEG-2 Program Stream (PS) is a series of
+ * MPEG-2 Program Packs terminated by an
+ * MPEG Program End Code after the last Program Pack.
+ * A Program Pack may hold a PS System Header packet and any
+ * number of Program Elementary Stream (PES) Packets
+ */
const char *start = buf->buf + buf->readpos;
const char *p = start + 1;
const u8 *q;
@@ -267,38 +281,54 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
int stuffing, i;
while (start + len > p) {
+ /* Scan for a 0 to find a potential MPEG-2 start code */
q = memchr(p, 0, start + len - p);
if (q == NULL)
break;
p = q + 1;
+ /*
+ * Keep looking if not a
+ * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba
+ * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
+ */
if ((char *)q + 15 >= buf->buf + buf->bytesused ||
q[1] != 0 || q[2] != 1 || q[3] != ch)
continue;
+
+ /* If expecting the primary video PES */
if (!cx->search_pack_header) {
+ /* Continue if it couldn't be a PES packet */
if ((q[6] & 0xc0) != 0x80)
continue;
- if (((q[7] & 0xc0) == 0x80 &&
- (q[9] & 0xf0) == 0x20) ||
- ((q[7] & 0xc0) == 0xc0 &&
- (q[9] & 0xf0) == 0x30)) {
- ch = 0xba;
+ /* Check if a PTS or PTS & DTS follow */
+ if (((q[7] & 0xc0) == 0x80 && /* PTS only */
+ (q[9] & 0xf0) == 0x20) || /* PTS only */
+ ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */
+ (q[9] & 0xf0) == 0x30)) { /* DTS follows */
+ /* Assume we found the video PES hdr */
+ ch = 0xba; /* next want a Program Pack*/
cx->search_pack_header = 1;
- p = q + 9;
+ p = q + 9; /* Skip this video PES hdr */
}
continue;
}
+
+ /* We may have found a Program Pack start code */
+
+ /* Get the count of stuffing bytes & verify them */
stuffing = q[13] & 7;
/* all stuffing bytes must be 0xff */
for (i = 0; i < stuffing; i++)
if (q[14 + i] != 0xff)
break;
- if (i == stuffing &&
- (q[4] & 0xc4) == 0x44 &&
- (q[12] & 3) == 3 &&
- q[14 + stuffing] == 0 &&
+ if (i == stuffing && /* right number of stuffing bytes*/
+ (q[4] & 0xc4) == 0x44 && /* marker check */
+ (q[12] & 3) == 3 && /* marker check */
+ q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
q[15 + stuffing] == 0 &&
q[16 + stuffing] == 1) {
- cx->search_pack_header = 0;
+ /* We declare we actually found a Program Pack*/
+ cx->search_pack_header = 0; /* expect vid PES */
len = (char *)q - start;
cx18_setup_sliced_vbi_buf(cx);
break;
@@ -665,7 +695,7 @@ int cx18_v4l2_open(struct file *filp)
if (cx18_cards[x] == NULL)
continue;
s = &cx18_cards[x]->streams[y];
- if (s->v4l2dev && s->v4l2dev->minor == minor) {
+ if (s->video_dev && s->video_dev->minor == minor) {
cx = cx18_cards[x];
break;
}
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 1fa95da1575e..aa89bee65af0 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -107,7 +107,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
u32 __iomem *dst = (u32 __iomem *)mem;
const u32 *src;
- if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("Unable to open firmware %s\n", fn);
CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
@@ -151,7 +151,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
u32 apu_version = 0;
int sz;
- if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("unable to open firmware %s\n", fn);
CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
cx18_setup_page(cx, 0);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 83e1c6333126..200d9257a926 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -366,7 +366,7 @@ int init_cx18_i2c(struct cx18 *cx)
sprintf(cx->i2c_client[i].name +
strlen(cx->i2c_client[i].name), "%d", i);
cx->i2c_client[i].adapter = &cx->i2c_adap[i];
- cx->i2c_adap[i].dev.parent = &cx->dev->dev;
+ cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
}
if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 7086aaba77d6..5c8e9cb244f9 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -58,12 +58,21 @@ u16 cx18_service2vbi(int type)
}
}
+/* Check if VBI services are allowed on the (field, line) for the video std */
static int valid_service_line(int field, int line, int is_pal)
{
- return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
+ return (is_pal && line >= 6 &&
+ ((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
(!is_pal && line >= 10 && line < 22);
}
+/*
+ * For a (field, line, std) and inbound potential set of services for that line,
+ * return the first valid service of those passed in the incoming set for that
+ * line in priority order:
+ * CC, VPS, or WSS over TELETEXT for well known lines
+ * TELETEXT, before VPS, before CC, before WSS, for other lines
+ */
static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
{
u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
@@ -90,6 +99,10 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
return 0;
}
+/*
+ * Expand the service_set of *fmt into valid service_lines for the std,
+ * and clear the passed in fmt->service_set
+ */
void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
{
u16 set = fmt->service_set;
@@ -102,7 +115,25 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
}
}
+/*
+ * Sanitize the service_lines in *fmt per the video std, and return 1
+ * if any service_line is left as valid after santization
+ */
+static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+{
+ int f, l;
+ u16 set = 0;
+ for (f = 0; f < 2; f++) {
+ for (l = 0; l < 24; l++) {
+ fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
+ set |= fmt->service_lines[f][l];
+ }
+ }
+ return set != 0;
+}
+
+/* Compute the service_set from the assumed valid service_lines of *fmt */
u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
{
int f, l;
@@ -129,10 +160,8 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
pixfmt->priv = 0;
if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- pixfmt->height * pixfmt->width +
- pixfmt->height * (pixfmt->width / 2);
+ /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+ pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
pixfmt->bytesperline = 720;
} else {
pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -149,8 +178,8 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
vbifmt->sampling_rate = 27000000;
- vbifmt->offset = 248;
- vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4;
+ vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
+ vbifmt->samples_per_line = vbi_active_samples - 4;
vbifmt->sample_format = V4L2_PIX_FMT_GREY;
vbifmt->start[0] = cx->vbi.start[0];
vbifmt->start[1] = cx->vbi.start[1];
@@ -164,7 +193,30 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ /* sane, V4L2 spec compliant, defaults */
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
+ vbifmt->service_set = 0;
+
+ /*
+ * Fetch the configured service_lines and total service_set from the
+ * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
+ * fmt->fmt.sliced under valid calling conditions
+ */
+ if (cx18_av_cmd(cx, VIDIOC_G_FMT, fmt))
+ return -EINVAL;
+
+ /* Ensure V4L2 spec compliant output */
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ vbifmt->service_set = cx18_get_service_set(vbifmt);
+ return 0;
}
static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
@@ -174,11 +226,18 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
struct cx18 *cx = id->cx;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
+ int min_h = 2;
w = min(w, 720);
- w = max(w, 1);
+ w = max(w, 2);
+ if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
+ /* YUV height must be a multiple of 32 */
+ h &= ~0x1f;
+ min_h = 32;
+ }
h = min(h, cx->is_50hz ? 576 : 480);
- h = max(h, 2);
+ h = max(h, min_h);
+
cx18_g_fmt_vid_cap(file, fh, fmt);
fmt->fmt.pix.width = w;
fmt->fmt.pix.height = h;
@@ -194,7 +253,20 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+
+ /* If given a service set, expand it validly & clear passed in set */
+ if (vbifmt->service_set)
+ cx18_expand_service_set(vbifmt, cx->is_50hz);
+ /* Sanitize the service_lines, and compute the new set if any valid */
+ if (check_service_set(vbifmt, cx->is_50hz))
+ vbifmt->service_set = cx18_get_service_set(vbifmt);
+ return 0;
}
static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
@@ -238,19 +310,62 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
if (ret)
return ret;
+ /*
+ * Changing the Encoder's Raw VBI parameters won't have any effect
+ * if any analog capture is ongoing
+ */
if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
return -EBUSY;
+ /*
+ * Set the digitizer registers for raw active VBI.
+ * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid
+ * calling conditions
+ */
+ ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+ if (ret)
+ return ret;
+
+ /* Store our new v4l2 (non-)sliced VBI state */
cx->vbi.sliced_in->service_set = 0;
cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+
return cx18_g_fmt_vbi_cap(file, fh, fmt);
}
static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
+
+ cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
+
+ /*
+ * Changing the Encoder's Raw VBI parameters won't have any effect
+ * if any analog capture is ongoing
+ */
+ if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
+ return -EBUSY;
+
+ /*
+ * Set the service_lines requested in the digitizer/slicer registers.
+ * Note, cx18_av_vbi() wipes some "impossible" service lines in the
+ * passed in fmt->fmt.sliced under valid calling conditions
+ */
+ ret = cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+ if (ret)
+ return ret;
+ /* Store our current v4l2 sliced VBI settings */
+ cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
+ return 0;
}
static int cx18_g_chip_ident(struct file *file, void *fh,
@@ -335,7 +450,8 @@ static int cx18_querycap(struct file *file, void *fh,
strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev));
+ snprintf(vcap->bus_info, sizeof(vcap->bus_info),
+ "PCI:%s", pci_name(cx->pci_dev));
vcap->version = CX18_DRIVER_VERSION; /* version */
vcap->capabilities = cx->v4l2_cap; /* capabilities */
return 0;
@@ -547,7 +663,6 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
cx->vbi.count = cx->is_50hz ? 18 : 12;
cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
- cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
CX18_DEBUG_INFO("Switching standard to %llx.\n",
(unsigned long long) cx->std);
@@ -598,7 +713,30 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_sliced_vbi_cap *cap)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
+ int f, l;
+
+ if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+
+ cap->service_set = 0;
+ for (f = 0; f < 2; f++) {
+ for (l = 0; l < 24; l++) {
+ if (valid_service_line(f, l, cx->is_50hz)) {
+ /*
+ * We can find all v4l2 supported vbi services
+ * for the standard, on a valid line for the std
+ */
+ cap->service_lines[f][l] = set;
+ cap->service_set |= set;
+ } else
+ cap->service_lines[f][l] = 0;
+ }
+ }
+ for (f = 0; f < 3; f++)
+ cap->reserved[f] = 0;
+ return 0;
}
static int cx18_g_enc_index(struct file *file, void *fh,
@@ -708,7 +846,9 @@ static int cx18_log_status(struct file *file, void *fh)
struct v4l2_audio audin;
int i;
- CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
+ CX18_INFO("================= START STATUS CARD #%d "
+ "=================\n", cx->num);
+ CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
if (cx->hw_flags & CX18_HW_TVEEPROM) {
struct tveeprom tv;
@@ -730,7 +870,7 @@ static int cx18_log_status(struct file *file, void *fh)
for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev == NULL || s->buffers == 0)
+ if (s->video_dev == NULL || s->buffers == 0)
continue;
CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
s->name, s->s_flags,
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index de5e723fdf44..2226e5791e99 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -83,6 +83,8 @@ static const struct cx18_api_info api_info[] = {
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
+ API_ENTRY(APU, CX18_APU_START, 0),
+ API_ENTRY(APU, CX18_APU_STOP, 0),
API_ENTRY(APU, CX18_APU_RESETAI, 0),
API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
API_ENTRY(0, 0, 0),
@@ -98,21 +100,30 @@ static const struct cx18_api_info *find_api_info(u32 cmd)
return NULL;
}
-static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+/* Call with buf of n*11+1 bytes */
+static char *u32arr2hex(u32 data[], int n, char *buf)
{
- char argstr[MAX_MB_ARGUMENTS*11+1];
char *p;
int i;
+ for (i = 0, p = buf; i < n; i++, p += 11) {
+ /* kernel snprintf() appends '\0' always */
+ snprintf(p, 12, " %#010x", data[i]);
+ }
+ *p = '\0';
+ return buf;
+}
+
+static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+{
+ char argstr[MAX_MB_ARGUMENTS*11+1];
+
if (!(cx18_debug & CX18_DBGFLG_API))
return;
- for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) {
- /* kernel snprintf() appends '\0' always */
- snprintf(p, 12, " %#010x", mb->args[i]);
- }
CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
- "\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr);
+ "\n", name, mb->request, mb->ack, mb->cmd, mb->error,
+ u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr));
}
@@ -439,7 +450,8 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
"incoming %s to EPU mailbox (sequence no. %u)"
"\n",
rpu_str[rpu], rpu_str[rpu], order_mb->request);
- dump_mb(cx, order_mb, "incoming");
+ if (cx18_debug & CX18_DBGFLG_WARN)
+ dump_mb(cx, order_mb, "incoming");
order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
}
@@ -468,16 +480,24 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
struct mutex *mb_lock;
long int timeout, ret;
int i;
+ char argstr[MAX_MB_ARGUMENTS*11+1];
if (info == NULL) {
CX18_WARN("unknown cmd %x\n", cmd);
return -EINVAL;
}
- if (cmd == CX18_CPU_DE_SET_MDL)
- CX18_DEBUG_HI_API("%s\n", info->name);
- else
- CX18_DEBUG_API("%s\n", info->name);
+ if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
+ if (cmd == CX18_CPU_DE_SET_MDL) {
+ if (cx18_debug & CX18_DBGFLG_HIGHVOL)
+ CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
+ info->name, cmd,
+ u32arr2hex(data, args, argstr));
+ } else
+ CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
+ info->name, cmd,
+ u32arr2hex(data, args, argstr));
+ }
switch (info->rpu) {
case APU:
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 8d9441e88c4e..3046b8e74345 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -204,7 +204,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
}
buf->id = cx->buffer_id++;
INIT_LIST_HEAD(&buf->list);
- buf->dma_handle = pci_map_single(s->cx->dev,
+ buf->dma_handle = pci_map_single(s->cx->pci_dev,
buf->buf, s->buf_size, s->dma);
cx18_buf_sync_for_cpu(s, buf);
cx18_enqueue(s, buf, &s->q_free);
@@ -227,7 +227,7 @@ void cx18_stream_free(struct cx18_stream *s)
/* empty q_free */
while ((buf = cx18_dequeue(s, &s->q_free))) {
- pci_unmap_single(s->cx->dev, buf->dma_handle,
+ pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
kfree(buf->buf);
kfree(buf);
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 456cec3bc28f..4de06269d88f 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -29,14 +29,14 @@
static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
struct cx18_buffer *buf)
{
- pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
+ pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
}
static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
struct cx18_buffer *buf)
{
- pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
+ pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
}
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 89c1ec94f335..778aa0c0f9b5 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -101,11 +101,11 @@ static struct {
static void cx18_stream_init(struct cx18 *cx, int type)
{
struct cx18_stream *s = &cx->streams[type];
- struct video_device *dev = s->v4l2dev;
+ struct video_device *video_dev = s->video_dev;
- /* we need to keep v4l2dev, so restore it afterwards */
+ /* we need to keep video_dev, so restore it afterwards */
memset(s, 0, sizeof(*s));
- s->v4l2dev = dev;
+ s->video_dev = video_dev;
/* initialize cx18_stream fields */
s->cx = cx;
@@ -132,10 +132,10 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
int num_offset = cx18_stream_info[type].num_offset;
int num = cx->num + cx18_first_minor + num_offset;
- /* These four fields are always initialized. If v4l2dev == NULL, then
+ /* These four fields are always initialized. If video_dev == NULL, then
this stream is not in use. In that case no other fields but these
four can be used. */
- s->v4l2dev = NULL;
+ s->video_dev = NULL;
s->cx = cx;
s->type = type;
s->name = cx18_stream_info[type].name;
@@ -163,22 +163,22 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
return 0;
/* allocate and initialize the v4l2 video device structure */
- s->v4l2dev = video_device_alloc();
- if (s->v4l2dev == NULL) {
+ s->video_dev = video_device_alloc();
+ if (s->video_dev == NULL) {
CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
s->name);
return -ENOMEM;
}
- snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
+ snprintf(s->video_dev->name, sizeof(s->video_dev->name), "cx18-%d",
cx->num);
- s->v4l2dev->num = num;
- s->v4l2dev->parent = &cx->dev->dev;
- s->v4l2dev->fops = &cx18_v4l2_enc_fops;
- s->v4l2dev->release = video_device_release;
- s->v4l2dev->tvnorms = V4L2_STD_ALL;
- cx18_set_funcs(s->v4l2dev);
+ s->video_dev->num = num;
+ s->video_dev->parent = &cx->pci_dev->dev;
+ s->video_dev->fops = &cx18_v4l2_enc_fops;
+ s->video_dev->release = video_device_release;
+ s->video_dev->tvnorms = V4L2_STD_ALL;
+ cx18_set_funcs(s->video_dev);
return 0;
}
@@ -227,28 +227,29 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
}
}
- if (s->v4l2dev == NULL)
+ if (s->video_dev == NULL)
return 0;
- num = s->v4l2dev->num;
+ num = s->video_dev->num;
/* card number + user defined offset + device offset */
if (type != CX18_ENC_STREAM_TYPE_MPG) {
struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
- if (s_mpg->v4l2dev)
- num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset;
+ if (s_mpg->video_dev)
+ num = s_mpg->video_dev->num
+ + cx18_stream_info[type].num_offset;
}
/* Register device. First try the desired minor, then any free one. */
- ret = video_register_device(s->v4l2dev, vfl_type, num);
+ ret = video_register_device(s->video_dev, vfl_type, num);
if (ret < 0) {
CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
s->name, num);
- video_device_release(s->v4l2dev);
- s->v4l2dev = NULL;
+ video_device_release(s->video_dev);
+ s->video_dev = NULL;
return ret;
}
- num = s->v4l2dev->num;
+ num = s->video_dev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
@@ -312,9 +313,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
cx->streams[type].dvb.enabled = false;
}
- vdev = cx->streams[type].v4l2dev;
+ vdev = cx->streams[type].video_dev;
- cx->streams[type].v4l2dev = NULL;
+ cx->streams[type].video_dev = NULL;
if (vdev == NULL)
continue;
@@ -348,44 +349,87 @@ static void cx18_vbi_setup(struct cx18_stream *s)
/* setup VBI registers */
cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
- /* determine number of lines and total number of VBI bytes.
- A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720
- A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
- header, 42 data bytes + checksum (to be confirmed) */
+ /*
+ * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
+ * VBI when the first analog capture channel starts, as once it starts
+ * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
+ * (i.e. for the VBI capture channels). We also send it for each
+ * analog capture channel anyway just to make sure we get the proper
+ * behavior
+ */
if (raw) {
lines = cx->vbi.count * 2;
} else {
- lines = cx->is_60hz ? 24 : 38;
- if (cx->is_60hz)
- lines += 2;
+ /*
+ * For 525/60 systems, according to the VIP 2 & BT.656 std:
+ * The EAV RP code's Field bit toggles on line 4, a few lines
+ * after the Vertcal Blank bit has already toggled.
+ * Tell the encoder to capture 21-4+1=18 lines per field,
+ * since we want lines 10 through 21.
+ *
+ * FIXME - revisit for 625/50 systems
+ */
+ lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38;
}
- cx->vbi.enc_size = lines *
- (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
-
data[0] = s->handle;
/* Lines per field */
data[1] = (lines / 2) | ((lines / 2) << 16);
/* bytes per line */
- data[2] = (raw ? cx->vbi.raw_decoder_line_size
- : cx->vbi.sliced_decoder_line_size);
+ data[2] = (raw ? vbi_active_samples
+ : (cx->is_60hz ? vbi_hblank_samples_60Hz
+ : vbi_hblank_samples_50Hz));
/* Every X number of frames a VBI interrupt arrives
(frames as in 25 or 30 fps) */
data[3] = 1;
- /* Setup VBI for the cx25840 digitizer */
+ /*
+ * Set the SAV/EAV RP codes to look for as start/stop points
+ * when in VIP-1.1 mode
+ */
if (raw) {
+ /*
+ * Start codes for beginning of "active" line in vertical blank
+ * 0x20 ( VerticalBlank )
+ * 0x60 ( EvenField VerticalBlank )
+ */
data[4] = 0x20602060;
+ /*
+ * End codes for end of "active" raw lines and regular lines
+ * 0x30 ( VerticalBlank HorizontalBlank)
+ * 0x70 ( EvenField VerticalBlank HorizontalBlank)
+ * 0x90 (Task HorizontalBlank)
+ * 0xd0 (Task EvenField HorizontalBlank)
+ */
data[5] = 0x307090d0;
} else {
+ /*
+ * End codes for active video, we want data in the hblank region
+ * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
+ * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
+ *
+ * Since the V bit is only allowed to toggle in the EAV RP code,
+ * just before the first active region line, these two
+ * are problematic:
+ * 0x90 (Task HorizontalBlank)
+ * 0xd0 (Task EvenField HorizontalBlank)
+ *
+ * We have set the digitzer to consider the first active line
+ * as part of VerticalBlank as well so we don't have to look for
+ * these problem codes nor lose the last line of sliced data.
+ */
data[4] = 0xB0F0B0F0;
+ /*
+ * Start codes for beginning of active line in vertical blank
+ * 0xa0 (Task VerticalBlank )
+ * 0xe0 (Task EvenField VerticalBlank )
+ */
data[5] = 0xA0E0A0E0;
}
CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
data[0], data[1], data[2], data[3], data[4], data[5]);
- if (s->type == CX18_ENC_STREAM_TYPE_VBI)
- cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
+ cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
}
struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
@@ -434,10 +478,10 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
u32 data[MAX_MB_ARGUMENTS];
struct cx18 *cx = s->cx;
struct cx18_buffer *buf;
- int ts = 0;
int captype = 0;
+ struct cx18_api_func_private priv;
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
return -EINVAL;
CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -453,7 +497,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
case CX18_ENC_STREAM_TYPE_TS:
captype = CAPTURE_CHANNEL_TYPE_TS;
- ts = 1;
break;
case CX18_ENC_STREAM_TYPE_YUV:
captype = CAPTURE_CHANNEL_TYPE_YUV;
@@ -462,8 +505,16 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
captype = CAPTURE_CHANNEL_TYPE_PCM;
break;
case CX18_ENC_STREAM_TYPE_VBI:
+#ifdef CX18_ENCODER_PARSES_SLICED
captype = cx18_raw_vbi(cx) ?
CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
+#else
+ /*
+ * Currently we set things up so that Sliced VBI from the
+ * digitizer is handled as Raw VBI by the encoder
+ */
+ captype = CAPTURE_CHANNEL_TYPE_VBI;
+#endif
cx->vbi.frame = 0;
cx->vbi.inserted_frame = 0;
memset(cx->vbi.sliced_mpeg_size,
@@ -473,10 +524,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
return -EINVAL;
}
- /* mute/unmute video */
- cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
- s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
-
/* Clear Streamoff flags in case left from last capture */
clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
@@ -484,31 +531,63 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
s->handle = data[0];
cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
- if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
- struct cx18_api_func_private priv;
-
- /* Stuff from Windows, we don't know what it is */
+ /*
+ * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
+ * set up all the parameters, as it is not obvious which parameters the
+ * firmware shares across capture channel types and which it does not.
+ *
+ * Some of the cx18_vapi() calls below apply to only certain capture
+ * channel types. We're hoping there's no harm in calling most of them
+ * anyway, as long as the values are all consistent. Setting some
+ * shared parameters will have no effect once an analog capture channel
+ * has started streaming.
+ */
+ if (captype != CAPTURE_CHANNEL_TYPE_TS) {
cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
+ /*
+ * Audio related reset according to
+ * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+ */
+ if (atomic_read(&cx->ana_capturing) == 0)
+ cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
+ s->handle, 12);
+
+ /*
+ * Number of lines for Field 1 & Field 2 according to
+ * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+ * Field 1 is 312 for 625 line systems in BT.656
+ * Field 2 is 313 for 625 line systems in BT.656
+ */
cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
- s->handle, cx->digitizer, cx->digitizer);
+ s->handle, 312, 313);
- /* Setup VBI */
if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
cx18_vbi_setup(s);
- /* assign program index info.
- Mask 7: select I/P/B, Num_req: 400 max */
+ /*
+ * assign program index info.
+ * Mask 7: select I/P/B, Num_req: 400 max
+ * FIXME - currently we have this hardcoded as disabled
+ */
cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
- /* Setup API for Stream */
+ /* Call out to the common CX2341x API setup for user controls */
priv.cx = cx;
priv.s = s;
cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
+
+ /*
+ * When starting a capture and we're set for radio,
+ * ensure the video is muted, despite the user control.
+ */
+ if (!cx->params.video_mute &&
+ test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
+ cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
+ (cx->params.video_mute_yuv << 8) | 1);
}
if (atomic_read(&cx->tot_capturing) == 0) {
@@ -552,7 +631,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
}
/* you're live! sit back and await interrupts :) */
- if (!ts)
+ if (captype != CAPTURE_CHANNEL_TYPE_TS)
atomic_inc(&cx->ana_capturing);
atomic_inc(&cx->tot_capturing);
return 0;
@@ -565,7 +644,7 @@ void cx18_stop_all_captures(struct cx18 *cx)
for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
continue;
if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
cx18_stop_v4l2_encode_stream(s, 0);
@@ -577,7 +656,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
struct cx18 *cx = s->cx;
unsigned long then;
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
return -EINVAL;
/* This function assumes that you are allowed to stop the capture
@@ -629,7 +708,7 @@ u32 cx18_find_handle(struct cx18 *cx)
for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE))
+ if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
return s->handle;
}
return CX18_INVALID_TASK_HANDLE;
@@ -647,7 +726,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
s = &cx->streams[i];
if (s->handle != handle)
continue;
- if (s->v4l2dev || s->dvb.enabled)
+ if (s->video_dev || s->dvb.enabled)
return s;
}
return NULL;
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index fb595bd548e8..8e6f4d4aff9a 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -27,6 +27,16 @@
#include "cx18-queue.h"
#include "cx18-av-core.h"
+/*
+ * Raster Reference/Protection (RP) bytes, used in Start/End Active
+ * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
+ * of VBI sample or VBI ancilliary data regions in the digitial ratser line.
+ *
+ * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
+ */
+static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */
+static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
+
static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
{
int line = 0;
@@ -34,10 +44,17 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
u32 linemask[2] = { 0, 0 };
unsigned short size;
static const u8 mpeg_hdr_data[] = {
- 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
- 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
- 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
- 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
+ /* MPEG-2 Program Pack */
+ 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */
+ 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
+ 0x01, 0xd1, 0xd3, /* Mux Rate, markers */
+ 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */
+ /* MPEG-2 Private Stream 1 PES Packet */
+ 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
+ 0x00, 0x1a, /* length */
+ 0x84, 0x80, 0x07, /* flags, hdr data len */
+ 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
+ 0xff, 0xff /* stuffing */
};
const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
int idx = cx->vbi.frame % CX18_VBI_FRAMES;
@@ -71,7 +88,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
memcpy(dst + sd + 4, dst + sd + 12, line * 43);
size = 4 + ((43 * line + 3) & ~3);
} else {
- memcpy(dst + sd, "cx0", 4);
+ memcpy(dst + sd, "itv0", 4);
memcpy(dst + sd + 4, &linemask[0], 8);
size = 12 + ((43 * line + 3) & ~3);
}
@@ -86,14 +103,13 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
}
/* Compress raw VBI format, removes leading SAV codes and surplus space
- after the field.
- Returns new compressed size. */
+ after the frame. Returns new compressed size. */
static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
{
- u32 line_size = cx->vbi.raw_decoder_line_size;
- u32 lines = cx->vbi.count;
- u8 sav1 = cx->vbi.raw_decoder_sav_odd_field;
- u8 sav2 = cx->vbi.raw_decoder_sav_even_field;
+ u32 line_size = vbi_active_samples;
+ u32 lines = cx->vbi.count * 2;
+ u8 sav1 = raw_vbi_sav_rp[0];
+ u8 sav2 = raw_vbi_sav_rp[1];
u8 *q = buf;
u8 *p;
int i;
@@ -115,15 +131,16 @@ static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
/* Compressed VBI format, all found sliced blocks put next to one another
Returns new compressed size */
static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
- u32 size, u8 sav)
+ u32 size, u8 eav)
{
- u32 line_size = cx->vbi.sliced_decoder_line_size;
struct v4l2_decode_vbi_line vbi;
int i;
+ u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
+ : vbi_hblank_samples_50Hz;
/* find the first valid line */
for (i = 0; i < size; i++, buf++) {
- if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
+ if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == eav)
break;
}
@@ -133,8 +150,8 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
for (i = 0; i < size / line_size; i++) {
u8 *p = buf + i * line_size;
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] || p[3] != sav)
+ /* Look for EAV code */
+ if (p[0] != 0xff || p[1] || p[2] || p[3] != eav)
continue;
vbi.p = p + 4;
cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
@@ -150,51 +167,78 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
}
void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
- u64 pts_stamp, int streamtype)
+ int streamtype)
{
u8 *p = (u8 *) buf->buf;
+ u32 *q = (u32 *) buf->buf;
u32 size = buf->bytesused;
+ u32 pts;
int lines;
if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
return;
+ /*
+ * The CX23418 sends us data that is 32 bit LE swapped, but we want
+ * the raw VBI bytes in the order they were in the raster line
+ */
+ cx18_buf_swap(buf);
+
+ /*
+ * The CX23418 provides a 12 byte header in it's raw VBI buffers to us:
+ * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp?]
+ */
+
/* Raw VBI data */
if (cx18_raw_vbi(cx)) {
u8 type;
- cx18_buf_swap(buf);
-
- /* Skip 12 bytes of header that gets stuffed in */
+ /*
+ * We've set up to get a frame's worth of VBI data at a time.
+ * Skip 12 bytes of header prefixing the first field.
+ */
size -= 12;
memcpy(p, &buf->buf[12], size);
type = p[3];
+ /* Extrapolate the last 12 bytes of the frame's last line */
+ memset(&p[size], (int) p[size - 1], 12);
+ size += 12;
+
size = buf->bytesused = compress_raw_buf(cx, p, size);
- /* second field of the frame? */
- if (type == cx->vbi.raw_decoder_sav_even_field) {
- /* Dirty hack needed for backwards
- compatibility of old VBI software. */
- p += size - 4;
- memcpy(p, &cx->vbi.frame, 4);
- cx->vbi.frame++;
- }
+ /*
+ * Hack needed for compatibility with old VBI software.
+ * Write the frame # at the last 4 bytes of the frame
+ */
+ p += size - 4;
+ memcpy(p, &cx->vbi.frame, 4);
+ cx->vbi.frame++;
return;
}
/* Sliced VBI data with data insertion */
- cx18_buf_swap(buf);
+
+ pts = (be32_to_cpu(q[0] == 0x3fffffff)) ? be32_to_cpu(q[2]) : 0;
+
+ /*
+ * For calls to compress_sliced_buf(), ensure there are an integral
+ * number of lines by shifting the real data up over the 12 bytes header
+ * that got stuffed in.
+ * FIXME - there's a smarter way to do this with pointers, but for some
+ * reason I can't get it to work correctly right now.
+ */
+ memcpy(p, &buf->buf[12], size-12);
/* first field */
- lines = compress_sliced_buf(cx, 0, p, size / 2,
- cx->vbi.sliced_decoder_sav_odd_field);
- /* second field */
- /* experimentation shows that the second half does not always
- begin at the exact address. So start a bit earlier
- (hence 32). */
+ lines = compress_sliced_buf(cx, 0, p, size / 2, sliced_vbi_eav_rp[0]);
+ /*
+ * second field
+ * In case the second half does not always begin at the exact address,
+ * start a bit earlier (hence 32).
+ */
lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
- size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field);
+ size / 2 + 32, sliced_vbi_eav_rp[1]);
/* always return at least one empty line */
if (lines == 0) {
cx->vbi.sliced_data[0].id = 0;
@@ -206,6 +250,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
memcpy(p, &cx->vbi.sliced_data[0], size);
if (cx->vbi.insert_mpeg)
- copy_vbi_data(cx, lines, pts_stamp);
+ copy_vbi_data(cx, lines, pts);
cx->vbi.frame++;
}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
index c56ff7d28f20..e7e1ae427f34 100644
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -22,5 +22,5 @@
*/
void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
- u64 pts_stamp, int streamtype);
+ int streamtype);
int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 601f3a2ab742..9956abf576c5 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -56,6 +56,22 @@
#define APU_CMD_MASK 0x10000000
#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
+#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28)
+#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28)
+
+/* Description: Command APU to start audio
+ IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?)
+ IN[1] - caller buffer address, or 0
+ ReturnCode - ??? */
+#define CX18_APU_START (APU_CMD_MASK | 0x01)
+
+/* Description: Command APU to stop audio
+ IN[0] - encoding method to stop
+ ReturnCode - ??? */
+#define CX18_APU_STOP (APU_CMD_MASK | 0x02)
+
+/* Description: Command APU to reset the AI
+ ReturnCode - ??? */
#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
/* Description: This command indicates that a Memory Descriptor List has been
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index cbbe47fb87b7..b36f522d2c55 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -1,5 +1,5 @@
/*
- * cx2341x - generic code for cx23415/6 based devices
+ * cx2341x - generic code for cx23415/6/8 based devices
*
* Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
*
@@ -30,7 +30,7 @@
#include <media/cx2341x.h>
#include <media/v4l2-common.h>
-MODULE_DESCRIPTION("cx23415/6 driver");
+MODULE_DESCRIPTION("cx23415/6/8 driver");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL");
@@ -38,6 +38,7 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+/* Must be sorted from low to high control ID! */
const u32 cx2341x_mpeg_ctrls[] = {
V4L2_CID_MPEG_CLASS,
V4L2_CID_MPEG_STREAM_TYPE,
@@ -50,6 +51,7 @@ const u32 cx2341x_mpeg_ctrls[] = {
V4L2_CID_MPEG_AUDIO_EMPHASIS,
V4L2_CID_MPEG_AUDIO_CRC,
V4L2_CID_MPEG_AUDIO_MUTE,
+ V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
V4L2_CID_MPEG_VIDEO_ENCODING,
V4L2_CID_MPEG_VIDEO_ASPECT,
V4L2_CID_MPEG_VIDEO_B_FRAMES,
@@ -94,6 +96,7 @@ static const struct cx2341x_mpeg_params default_params = {
.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+ .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
@@ -148,6 +151,9 @@ static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
ctrl->value = params->audio_l2_bitrate;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ ctrl->value = params->audio_ac3_bitrate;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
ctrl->value = params->audio_mode;
break;
@@ -256,6 +262,12 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
params->audio_sampling_freq = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (busy)
+ return -EBUSY;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3)
+ if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
+ return -ERANGE;
params->audio_encoding = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
@@ -263,6 +275,13 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
return -EBUSY;
params->audio_l2_bitrate = ctrl->value;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (busy)
+ return -EBUSY;
+ if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
+ return -EINVAL;
+ params->audio_ac3_bitrate = ctrl->value;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
params->audio_mode = ctrl->value;
break;
@@ -482,21 +501,55 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
switch (qctrl->id) {
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ /*
+ * The state of L2 & AC3 bitrate controls can change
+ * when this control changes, but v4l2_ctrl_query_fill()
+ * already sets V4L2_CTRL_FLAG_UPDATE for
+ * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
+ */
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
+ default_params.audio_encoding);
+ }
+
return v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
default_params.audio_encoding);
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
+ err = v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_L2_BITRATE_192K,
V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
default_params.audio_l2_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
+ params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
return -EINVAL;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
+ default_params.audio_ac3_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ if (params->audio_encoding !=
+ V4L2_MPEG_AUDIO_ENCODING_AC3)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ } else
+ qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ return 0;
+
case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
err = v4l2_ctrl_query_fill_std(qctrl);
if (err == 0 &&
@@ -671,6 +724,15 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
NULL
};
+ static const char *mpeg_audio_encoding_l2_ac3[] = {
+ "",
+ "MPEG-1/2 Layer II",
+ "",
+ "",
+ "AC-3",
+ NULL
+ };
+
static const char *cx2341x_video_spatial_filter_mode_menu[] = {
"Manual",
"Auto",
@@ -711,6 +773,9 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
case V4L2_CID_MPEG_STREAM_TYPE:
return (p->capabilities & CX2341X_CAP_HAS_TS) ?
mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
+ mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
return NULL;
@@ -730,16 +795,34 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
}
EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
+/* definitions for audio properties bits 29-28 */
+#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
+#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
+#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
+
static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
{
- params->audio_properties = (params->audio_sampling_freq << 0) |
- ((3 - params->audio_encoding) << 2) |
- ((1 + params->audio_l2_bitrate) << 4) |
+ params->audio_properties =
+ (params->audio_sampling_freq << 0) |
(params->audio_mode << 8) |
(params->audio_mode_extension << 10) |
(((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
? 3 : params->audio_emphasis) << 12) |
(params->audio_crc << 14);
+
+ if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
+ params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
+ params->audio_properties |=
+ /* Not sure if this MPEG Layer II setting is required */
+ ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
+ (params->audio_ac3_bitrate << 4) |
+ (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
+ } else {
+ /* Assuming MPEG Layer II */
+ params->audio_properties |=
+ ((3 - params->audio_encoding) << 2) |
+ ((1 + params->audio_l2_bitrate) << 4);
+ }
}
int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
@@ -1022,7 +1105,10 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
prefix,
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
+ cx2341x_menu_item(p,
+ p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
+ ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
+ : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
p->audio_mute ? " (muted)" : "");
if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 8f1db57bd1dd..bfe25841dbf4 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1586,7 +1586,8 @@ static int mpeg_open(struct file *file)
lock_kernel();
list_for_each(list, &cx23885_devlist) {
h = list_entry(list, struct cx23885_dev, devlist);
- if (h->v4l_device->minor == minor) {
+ if (h->v4l_device &&
+ h->v4l_device->minor == minor) {
dev = h;
break;
}
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index caa098beeecf..7ff339a2e3f2 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -162,6 +162,18 @@ struct cx23885_board cx23885_boards[] = {
.name = "Compro VideoMate E650F",
.portc = CX23885_MPEG_DVB,
},
+ [CX23885_BOARD_TBS_6920] = {
+ .name = "TurboSight TBS 6920",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_TEVII_S470] = {
+ .name = "TeVii S470",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_DVBWORLD_2005] = {
+ .name = "DVBWorld DVB-S2 2005",
+ .portb = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -245,6 +257,18 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x185b,
.subdevice = 0xe800,
.card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
+ }, {
+ .subvendor = 0x6920,
+ .subdevice = 0x8888,
+ .card = CX23885_BOARD_TBS_6920,
+ }, {
+ .subvendor = 0xd470,
+ .subdevice = 0x9022,
+ .card = CX23885_BOARD_TEVII_S470,
+ }, {
+ .subvendor = 0x0001,
+ .subdevice = 0x2005,
+ .card = CX23885_BOARD_DVBWORLD_2005,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -552,6 +576,12 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
mdelay(20);
cx_set(GP0_IO, 0x00040004);
break;
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_TEVII_S470:
+ cx_write(MC417_CTL, 0x00000036);
+ cx_write(MC417_OEN, 0x00001000);
+ cx_write(MC417_RWD, 0x00001800);
+ break;
}
}
@@ -632,6 +662,13 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break;
+ case CX23885_BOARD_TEVII_S470:
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_DVBWORLD_2005:
+ ts1->gen_ctrl_val = 0x5; /* Parallel */
+ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ break;
case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_HAUPPAUGE_HVR1500:
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 1c454128a9df..14a6540b826c 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -43,6 +43,7 @@
#include "dib7000p.h"
#include "dibx000_common.h"
#include "zl10353.h"
+#include "cx24116.h"
static unsigned int debug;
@@ -308,6 +309,32 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = {
.no_tuner = 1,
};
+static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ if (voltage == SEC_VOLTAGE_18)
+ cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
+ else if (voltage == SEC_VOLTAGE_13)
+ cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
+ else
+ cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
+ return 0;
+}
+
+static struct cx24116_config tbs_cx24116_config = {
+ .demod_address = 0x05,
+};
+
+static struct cx24116_config tevii_cx24116_config = {
+ .demod_address = 0x55,
+};
+
+static struct cx24116_config dvbworld_cx24116_config = {
+ .demod_address = 0x05,
+};
+
static int dvb_register(struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
@@ -526,6 +553,33 @@ static int dvb_register(struct cx23885_tsport *port)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
+ case CX23885_BOARD_TBS_6920:
+ i2c_bus = &dev->i2c_bus[0];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tbs_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_TEVII_S470:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tevii_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_DVBWORLD_2005:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &dvbworld_cx24116_config,
+ &i2c_bus->i2c_adap);
+ break;
default:
printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
" isn't supported yet\n",
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 2d81c4d04340..c2ed2505b725 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -244,6 +244,7 @@ static struct cx23885_ctrl cx23885_ctls[] = {
};
static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls);
+/* Must be sorted from low to high control ID! */
static const u32 cx23885_user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -730,12 +731,13 @@ static int video_open(struct file *file)
lock_kernel();
list_for_each(list, &cx23885_devlist) {
h = list_entry(list, struct cx23885_dev, devlist);
- if (h->video_dev->minor == minor) {
+ if (h->video_dev &&
+ h->video_dev->minor == minor) {
dev = h;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
}
if (h->vbi_dev &&
- h->vbi_dev->minor == minor) {
+ h->vbi_dev->minor == minor) {
dev = h;
type = V4L2_BUF_TYPE_VBI_CAPTURE;
}
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 67828029fc69..37a88b1683c3 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -67,6 +67,9 @@
#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11
#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12
#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13
+#define CX23885_BOARD_TBS_6920 14
+#define CX23885_BOARD_TEVII_S470 15
+#define CX23885_BOARD_DVBWORLD_2005 16
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 88f2fd32bfe3..d4059ecaa58e 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -763,7 +763,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l_err(client, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -1101,6 +1101,16 @@ static void log_audio_status(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
+/* This init operation must be called to load the driver's firmware.
+ Without this the audio standard detection will fail and you will
+ only get mono.
+
+ Since loading the firmware is often problematic when the driver is
+ compiled into the kernel I recommend postponing calling this function
+ until the first open of the video device. Another reason for
+ postponing it is that loading this firmware takes a long time (seconds)
+ due to the slow i2c bus speed. So it will speed up the boot process if
+ you can avoid loading the fw as long as the video device isn't used. */
static int cx25840_init(struct v4l2_subdev *sd, u32 val)
{
struct cx25840_state *state = to_state(sd);
@@ -1382,6 +1392,14 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
{
+ /* ignore this command */
+ if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
+ return 0;
+
+ /* Old-style drivers rely on initialization on first use, so
+ call the init whenever a command is issued to this driver.
+ New-style drivers using v4l2_subdev should call init explicitly. */
+ cx25840_init(i2c_get_clientdata(client), 0);
return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
}
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 613dfea4ff3e..aef5297534af 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -614,34 +614,41 @@ static struct stv0288_config tevii_tuner_earda_config = {
.set_ts_params = cx24116_set_ts_param,
};
-static int dvb_register(struct cx8802_dev *dev)
+static int cx8802_alloc_frontends(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
- struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
- int mfe_shared = 0; /* bus not shared by default */
+ struct videobuf_dvb_frontend *fe = NULL;
int i;
- if (0 != core->i2c_rc) {
- printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
- goto frontend_detach;
- }
-
- if (!core->board.num_frontends)
- return -EINVAL;
-
mutex_init(&dev->frontends.lock);
INIT_LIST_HEAD(&dev->frontends.felist);
+ if (!core->board.num_frontends)
+ return -ENODEV;
+
printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
core->board.num_frontends);
for (i = 1; i <= core->board.num_frontends; i++) {
- fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, i);
- if (!fe0) {
+ fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
+ if (!fe) {
printk(KERN_ERR "%s() failed to alloc\n", __func__);
videobuf_dvb_dealloc_frontends(&dev->frontends);
- goto frontend_detach;
+ return -ENOMEM;
}
}
+ return 0;
+}
+
+static int dvb_register(struct cx8802_dev *dev)
+{
+ struct cx88_core *core = dev->core;
+ struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+ int mfe_shared = 0; /* bus not shared by default */
+
+ if (0 != core->i2c_rc) {
+ printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
+ goto frontend_detach;
+ }
/* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
@@ -1243,6 +1250,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
struct cx88_core *core = drv->core;
struct cx8802_dev *dev = drv->core->dvbdev;
int err;
+ struct videobuf_dvb_frontend *fe;
+ int i;
dprintk( 1, "%s\n", __func__);
dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1258,39 +1267,34 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
/* If vp3054 isn't enabled, a stub will just return 0 */
err = vp3054_i2c_probe(dev);
if (0 != err)
- goto fail_probe;
+ goto fail_core;
/* dvb stuff */
printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
dev->ts_gen_cntrl = 0x0c;
+ err = cx8802_alloc_frontends(dev);
+ if (err)
+ goto fail_core;
+
err = -ENODEV;
- if (core->board.num_frontends) {
- struct videobuf_dvb_frontend *fe;
- int i;
-
- for (i = 1; i <= core->board.num_frontends; i++) {
- fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
- if (fe == NULL) {
- printk(KERN_ERR "%s() failed to get frontend(%d)\n",
+ for (i = 1; i <= core->board.num_frontends; i++) {
+ fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+ if (fe == NULL) {
+ printk(KERN_ERR "%s() failed to get frontend(%d)\n",
__func__, i);
- goto fail_probe;
- }
- videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
+ goto fail_probe;
+ }
+ videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_TOP,
sizeof(struct cx88_buffer),
dev);
- /* init struct videobuf_dvb */
- fe->dvb.name = dev->core->name;
- }
- } else {
- /* no frontends allocated */
- printk(KERN_ERR "%s/2 .num_frontends should be non-zero\n",
- core->name);
- goto fail_core;
+ /* init struct videobuf_dvb */
+ fe->dvb.name = dev->core->name;
}
+
err = dvb_register(dev);
if (err)
/* frontends/adapter de-allocated in dvb_register */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 791e69d804f9..5ed1c5a52cdd 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -298,6 +298,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
};
static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
+/* Must be sorted from low to high control ID! */
const u32 cx88_user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 60a8b3187f14..6025fdd23344 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -336,8 +336,8 @@ struct cx88_core {
/* config info -- dvb */
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
int (*prev_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
- void (*gate_ctrl)(struct cx88_core *core, int open);
#endif
+ void (*gate_ctrl)(struct cx88_core *core, int open);
/* state info */
struct task_struct *kthread;
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 298810d5262b..f40c676489a4 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -189,17 +189,20 @@ static void dabusb_iso_complete (struct urb *purb)
dst += len;
}
else
- err("dabusb_iso_complete: invalid len %d", len);
+ dev_err(&purb->dev->dev,
+ "dabusb_iso_complete: invalid len %d\n", len);
}
else
dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
if (dst != purb->actual_length)
- err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
+ dev_err(&purb->dev->dev,
+ "dst!=purb->actual_length:%d!=%d\n",
+ dst, purb->actual_length);
}
if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
s->overruns++;
- err("overrun (%d)", s->overruns);
+ dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
}
wake_up (&s->wait);
}
@@ -220,13 +223,14 @@ static int dabusb_alloc_buffers (pdabusb_t s)
while (transfer_len < (s->total_buffer_size << 10)) {
b = kzalloc(sizeof (buff_t), GFP_KERNEL);
if (!b) {
- err("kzalloc(sizeof(buff_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kzalloc(sizeof(buff_t))==NULL\n");
goto err;
}
b->s = s;
b->purb = usb_alloc_urb(packets, GFP_KERNEL);
if (!b->purb) {
- err("usb_alloc_urb == NULL");
+ dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
kfree (b);
goto err;
}
@@ -235,7 +239,8 @@ static int dabusb_alloc_buffers (pdabusb_t s)
if (!b->purb->transfer_buffer) {
kfree (b->purb);
kfree (b);
- err("kmalloc(%d)==NULL", transfer_buffer_length);
+ dev_err(&s->usbdev->dev,
+ "kmalloc(%d)==NULL\n", transfer_buffer_length);
goto err;
}
@@ -279,10 +284,11 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
if(ret<0) {
- err("dabusb: usb_bulk_msg failed(%d)",ret);
+ dev_err(&s->usbdev->dev,
+ "usb_bulk_msg failed(%d)\n", ret);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
@@ -291,7 +297,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
if( ret == -EPIPE ) {
dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
- err("request failed");
+ dev_err(&s->usbdev->dev, "request failed\n");
}
pb->size = actual_length;
@@ -305,7 +311,8 @@ static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data,
unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL);
if (!transfer_buffer) {
- err("dabusb_writemem: kmalloc(%d) failed.", len);
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem: kmalloc(%d) failed.\n", len);
return -ENOMEM;
}
@@ -333,7 +340,8 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/firmware.fw\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
goto out;
}
ret = dabusb_8051_reset (s, 1);
@@ -346,9 +354,10 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
be16_to_cpu(rec->len));
if (ret < 0) {
- err("dabusb_writemem failed (%d %04X %p %d)", ret,
- be32_to_cpu(rec->addr), rec->data,
- be16_to_cpu(rec->len));
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem failed (%d %04X %p %d)\n",
+ ret, be32_to_cpu(rec->addr),
+ rec->data, be16_to_cpu(rec->len));
break;
}
}
@@ -396,13 +405,15 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
dbg("Enter dabusb_fpga_download (internal)");
if (!b) {
- err("kmalloc(sizeof(bulk_transfer_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
return -ENOMEM;
}
ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
kfree(b);
return ret;
}
@@ -425,7 +436,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
memcpy (b->data + 4, fw->data + 74 + n, 60);
ret = dabusb_bulk (s, b);
if (ret < 0) {
- err("dabusb_bulk failed.");
+ dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
break;
}
mdelay (1);
@@ -478,9 +489,11 @@ static int dabusb_startrek (pdabusb_t s)
ret = usb_submit_urb (end->purb, GFP_KERNEL);
if (ret) {
- err("usb_submit_urb returned:%d", ret);
+ dev_err(&s->usbdev->dev,
+ "usb_submit_urb returned:%d\n", ret);
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("startrek: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "startrek: dabusb_add_buf_tail failed\n");
break;
}
else
@@ -523,7 +536,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
spin_unlock_irqrestore(&s->lock, flags);
- err("error: rec_buf_list is empty");
+ dev_err(&s->usbdev->dev,
+ "error: rec_buf_list is empty\n");
goto err;
}
@@ -552,7 +566,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (list_empty (&s->rec_buff_list)) {
spin_unlock_irqrestore(&s->lock, flags);
- err("error: still no buffer available.");
+ dev_err(&s->usbdev->dev,
+ "error: still no buffer available.\n");
goto err;
}
spin_unlock_irqrestore(&s->lock, flags);
@@ -573,7 +588,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
- err("read: copy_to_user failed");
+ dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
if (!ret)
ret = -EFAULT;
goto err;
@@ -587,7 +602,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (s->readptr == purb->actual_length) {
// finished, take next buffer
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("read: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "read: dabusb_add_buf_tail failed\n");
s->readptr = 0;
}
}
@@ -623,7 +639,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
}
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
mutex_unlock(&s->mutex);
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
s->opened = 1;
@@ -648,7 +664,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
if (!s->remove_pending) {
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
}
else
wake_up (&s->remove_ok);
@@ -764,7 +780,7 @@ static int dabusb_probe (struct usb_interface *intf,
s->devnum = intf->minor;
if (usb_reset_configuration (usbdev) < 0) {
- err("reset_configuration failed");
+ dev_err(&intf->dev, "reset_configuration failed\n");
goto reject;
}
if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
@@ -775,7 +791,7 @@ static int dabusb_probe (struct usb_interface *intf,
dabusb_fpga_download (s, NULL);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
- err("set_interface failed");
+ dev_err(&intf->dev, "set_interface failed\n");
goto reject;
}
}
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 94378ccb7505..91bbf08664bb 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -56,15 +56,22 @@ MODULE_PARM_DESC(debug, "activates debug info");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int em28xx_isoc_audio_deinit(struct em28xx *dev)
+static int em28xx_deinit_isoc_audio(struct em28xx *dev)
{
int i;
dprintk("Stopping isoc\n");
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
- usb_unlink_urb(dev->adev.urb[i]);
+ if (!irqs_disabled())
+ usb_kill_urb(dev->adev.urb[i]);
+ else
+ usb_unlink_urb(dev->adev.urb[i]);
+
usb_free_urb(dev->adev.urb[i]);
dev->adev.urb[i] = NULL;
+
+ kfree(dev->adev.transfer_buffer[i]);
+ dev->adev.transfer_buffer[i] = NULL;
}
return 0;
@@ -81,6 +88,20 @@ static void em28xx_audio_isocirq(struct urb *urb)
unsigned int stride;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dprintk("urb completition error %d.\n", urb->status);
+ break;
+ }
+
if (dev->adev.capture_pcm_substream) {
substream = dev->adev.capture_pcm_substream;
runtime = substream->runtime;
@@ -131,9 +152,6 @@ static void em28xx_audio_isocirq(struct urb *urb)
}
urb->status = 0;
- if (dev->adev.shutdown)
- return;
-
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status < 0) {
em28xx_errdev("resubmit of audio urb failed (error=%i)\n",
@@ -191,8 +209,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
if (errCode) {
- em28xx_isoc_audio_deinit(dev);
-
+ em28xx_deinit_isoc_audio(dev);
return errCode;
}
}
@@ -207,14 +224,16 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg)
switch (cmd) {
case EM28XX_CAPTURE_STREAM_EN:
- if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
+ if (dev->adev.capture_stream == STREAM_OFF &&
+ arg == EM28XX_START_AUDIO) {
dev->adev.capture_stream = STREAM_ON;
em28xx_init_audio_isoc(dev);
- } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
+ } else if (dev->adev.capture_stream == STREAM_ON &&
+ arg == EM28XX_STOP_AUDIO) {
dev->adev.capture_stream = STREAM_OFF;
- em28xx_isoc_audio_deinit(dev);
+ em28xx_deinit_isoc_audio(dev);
} else {
- printk(KERN_ERR "An underrun very likely occurred. "
+ em28xx_errdev("An underrun very likely occurred. "
"Ignoring it.\n");
}
return 0;
@@ -228,7 +247,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
{
struct snd_pcm_runtime *runtime = subs->runtime;
- dprintk("Alocating vbuffer\n");
+ dprintk("Allocating vbuffer\n");
if (runtime->dma_area) {
if (runtime->dma_bytes > size)
return 0;
@@ -296,7 +315,9 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
dprintk("changing alternate number to 7\n");
}
+ mutex_lock(&dev->lock);
dev->adev.users++;
+ mutex_unlock(&dev->lock);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
dev->adev.capture_pcm_substream = substream;
@@ -311,22 +332,15 @@ err:
static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
{
struct em28xx *dev = snd_pcm_substream_chip(substream);
- dev->adev.users--;
dprintk("closing device\n");
dev->mute = 1;
mutex_lock(&dev->lock);
+ dev->adev.users--;
em28xx_audio_analog_set(dev);
mutex_unlock(&dev->lock);
- if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
- dprintk("audio users: %d\n", dev->adev.users);
- dprintk("disabling audio stream!\n");
- dev->adev.shutdown = 0;
- dprintk("released lock\n");
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
- }
return 0;
}
@@ -357,7 +371,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
dprintk("Stop capture, if needed\n");
if (dev->adev.capture_stream == STREAM_ON)
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
return 0;
}
@@ -371,29 +385,40 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct em28xx *dev = snd_pcm_substream_chip(substream);
+ int retval;
- dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)?
- "start": "stop");
+ dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
+ "start" : "stop");
+
+ spin_lock(&dev->adev.slock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);
- return 0;
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO);
+ retval = 0;
+ break;
case SNDRV_PCM_TRIGGER_STOP:
- dev->adev.shutdown = 1;
- return 0;
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
+ retval = 0;
+ break;
default:
- return -EINVAL;
+ retval = -EINVAL;
}
+
+ spin_unlock(&dev->adev.slock);
+ return retval;
}
static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
*substream)
{
+ unsigned long flags;
struct em28xx *dev;
-
snd_pcm_uframes_t hwptr_done;
+
dev = snd_pcm_substream_chip(substream);
+ spin_lock_irqsave(&dev->adev.slock, flags);
hwptr_done = dev->adev.hwptr_done_capture;
+ spin_unlock_irqrestore(&dev->adev.slock, flags);
return hwptr_done;
}
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ef9bf008a924..615cf362e79c 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -102,6 +102,18 @@ static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
/* Board - EM2870 Kworld 355u
Analog - No input analog */
+static struct em28xx_reg_seq kworld_330u_analog[] = {
+ {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10},
+ {EM2880_R04_GPO, 0x00, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq kworld_330u_digital[] = {
+ {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10},
+ {EM2880_R04_GPO, 0x08, 0xff, 10},
+ { -1, -1, -1, -1},
+};
+
/* Callback for the most boards */
static struct em28xx_reg_seq default_tuner_gpio[] = {
{EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10},
@@ -171,6 +183,25 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_LINE_IN,
} },
},
+ [EM2820_BOARD_GADMEI_TVR200] = {
+ .name = "Gadmei TVR200",
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA711X,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
[EM2820_BOARD_TERRATEC_CINERGY_250] = {
.name = "Terratec Cinergy 250 USB",
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
@@ -213,7 +244,7 @@ struct em28xx_board em28xx_boards[] = {
.name = "Hauppauge WinTV USB 2",
.tuner_type = TUNER_PHILIPS_FM1236_MK3,
.tda9887_conf = TDA9887_PRESENT |
- TDA9887_PORT1_ACTIVE|
+ TDA9887_PORT1_ACTIVE |
TDA9887_PORT2_ACTIVE,
.decoder = EM28XX_TVP5150,
.has_msp34xx = 1,
@@ -486,7 +517,7 @@ struct em28xx_board em28xx_boards[] = {
},
[EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
.name = "Yakumo MovieMixer",
- .tuner_type = TUNER_ABSENT, /* Capture only device */
+ .tuner_type = TUNER_ABSENT, /* Capture only device */
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -830,11 +861,11 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2800_BOARD_GRABBEEX_USB2800] = {
- .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
- .is_em2800 = 1,
- .decoder = EM28XX_SAA711X,
- .tuner_type = TUNER_ABSENT, /* capture only board */
- .input = { {
+ .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
+ .is_em2800 = 1,
+ .decoder = EM28XX_SAA711X,
+ .tuner_type = TUNER_ABSENT, /* capture only board */
+ .input = { {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = SAA7115_COMPOSITE0,
.amux = EM28XX_AMUX_LINE_IN,
@@ -885,7 +916,7 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2820_BOARD_PINNACLE_DVC_90] = {
- .name = "Pinnacle Dazzle DVC 90/DVC 100",
+ .name = "Pinnacle Dazzle DVC 90/DVC 100/DVC 101/DVC 107",
.tuner_type = TUNER_ABSENT, /* capture only board */
.decoder = EM28XX_SAA711X,
.input = { {
@@ -1177,29 +1208,35 @@ struct em28xx_board em28xx_boards[] = {
.gpio = hauppauge_wintv_hvr_900_analog,
} },
},
- [EM2883_BOARD_KWORLD_HYBRID_A316] = {
+ [EM2883_BOARD_KWORLD_HYBRID_330U] = {
.name = "Kworld PlusTV HD Hybrid 330",
.tuner_type = TUNER_XC2028,
.tuner_gpio = default_tuner_gpio,
.decoder = EM28XX_TVP5150,
.mts_firmware = 1,
.has_dvb = 1,
- .dvb_gpio = default_digital,
+ .dvb_gpio = kworld_330u_digital,
+ .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
+ EM28XX_I2C_EEPROM_ON_BOARD |
+ EM28XX_I2C_EEPROM_KEY_VALID,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
.amux = EM28XX_AMUX_VIDEO,
- .gpio = default_analog,
+ .gpio = kworld_330u_analog,
+ .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
}, {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = TVP5150_COMPOSITE1,
.amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
+ .gpio = kworld_330u_analog,
+ .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO,
}, {
.type = EM28XX_VMUX_SVIDEO,
.vmux = TVP5150_SVIDEO,
.amux = EM28XX_AMUX_LINE_IN,
- .gpio = hauppauge_wintv_hvr_900_analog,
+ .gpio = kworld_330u_analog,
} },
},
[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
@@ -1217,11 +1254,74 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_LINE_IN,
} },
},
+ [EM2860_BOARD_KAIOMY_TVNPC_U2] = {
+ .name = "Kaiomy TVnPC U2",
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .tuner_addr = 0x61,
+ .mts_firmware = 1,
+ .decoder = EM28XX_TVP5150,
+ .tuner_gpio = default_tuner_gpio,
+ .ir_codes = ir_codes_kaiomy,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ .radio = {
+ .type = EM28XX_RADIO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }
+ },
+ [EM2860_BOARD_EASYCAP] = {
+ .name = "Easy Cap Capture DC-60",
+ .vchannels = 2,
+ .tuner_type = TUNER_ABSENT,
+ .decoder = EM28XX_SAA711X,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
+ [EM2820_BOARD_IODATA_GVMVP_SZ] = {
+ .name = "IO-DATA GV-MVP/SZ",
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .tuner_gpio = default_tuner_gpio,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+ }, { /* Composite has not been tested yet */
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = EM28XX_AMUX_VIDEO,
+ }, { /* S-video has not been tested yet */
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_VIDEO,
+ } },
+ },
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
/* table of devices that work with this driver */
-struct usb_device_id em28xx_id_table [] = {
+struct usb_device_id em28xx_id_table[] = {
{ USB_DEVICE(0xeb1a, 0x2750),
.driver_info = EM2750_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2751),
@@ -1244,12 +1344,14 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0xe300),
.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
+ { USB_DEVICE(0xeb1a, 0xe303),
+ .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 },
{ USB_DEVICE(0xeb1a, 0xe305),
.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
{ USB_DEVICE(0xeb1a, 0xe310),
.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD },
{ USB_DEVICE(0xeb1a, 0xa316),
- .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 },
+ .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U },
{ USB_DEVICE(0xeb1a, 0xe320),
.driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II },
{ USB_DEVICE(0xeb1a, 0xe323),
@@ -1314,6 +1416,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
{ USB_DEVICE(0x093b, 0xa005),
.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
+ { USB_DEVICE(0x04bb, 0x0515),
+ .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
{ },
};
MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -1321,7 +1425,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table);
/*
* EEPROM hash table for devices with generic USB IDs
*/
-static struct em28xx_hash_table em28xx_eeprom_hash [] = {
+static struct em28xx_hash_table em28xx_eeprom_hash[] = {
/* P/N: SA 60002070465 Tuner: TVF7533-MF */
{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
@@ -1333,6 +1437,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
{0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
+ {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
};
int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
@@ -1352,7 +1457,7 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
}
EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
-static void inline em28xx_set_model(struct em28xx *dev)
+static inline void em28xx_set_model(struct em28xx *dev)
{
memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
@@ -1488,6 +1593,34 @@ void em28xx_pre_card_setup(struct em28xx *dev)
/* enables audio for that devices */
em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
break;
+
+ case EM2860_BOARD_KAIOMY_TVNPC_U2:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ em28xx_write_regs(dev, 0x0d, "\x42", 1);
+ em28xx_write_regs(dev, 0x08, "\xfd", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\xff", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x7f", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x6b", 1);
+
+ break;
+ case EM2860_BOARD_EASYCAP:
+ em28xx_write_regs(dev, 0x08, "\xf8", 1);
+ break;
+
+ case EM2820_BOARD_IODATA_GVMVP_SZ:
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+ msleep(70);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+ msleep(10);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ msleep(70);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+ msleep(70);
+ break;
}
em28xx_gpio_set(dev, dev->board.tuner_gpio);
@@ -1526,6 +1659,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
/* FIXME: Better to specify the needed IF */
ctl->demod = XC3028_FE_DEFAULT;
break;
+ case EM2883_BOARD_KWORLD_HYBRID_330U:
+ ctl->demod = XC3028_FE_CHINA;
+ ctl->fname = XC2028_DEFAULT_FIRMWARE;
+ break;
default:
ctl->demod = XC3028_FE_OREN538;
}
@@ -1590,7 +1727,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("If the board were missdetected, "
"please email this log to:\n");
em28xx_errdev("\tV4L Mailing List "
- " <video4linux-list@redhat.com>\n");
+ " <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board detected as %s\n",
em28xx_boards[dev->model].name);
@@ -1622,7 +1759,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("If the board were missdetected, "
"please email this log to:\n");
em28xx_errdev("\tV4L Mailing List "
- " <video4linux-list@redhat.com>\n");
+ " <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board detected as %s\n",
em28xx_boards[dev->model].name);
@@ -1635,7 +1772,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("You may try to use card=<n> insmod option to "
"workaround that.\n");
em28xx_errdev("Please send an email with this log to:\n");
- em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
+ em28xx_errdev("\tV4L Mailing List <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index eb5fb05fab22..eee8d015b249 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -33,8 +33,8 @@
/* #define ENABLE_DEBUG_ISOC_FRAMES */
static unsigned int core_debug;
-module_param(core_debug,int,0644);
-MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
+module_param(core_debug, int, 0644);
+MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
#define em28xx_coredbg(fmt, arg...) do {\
if (core_debug) \
@@ -42,8 +42,8 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
dev->name, __func__ , ##arg); } while (0)
static unsigned int reg_debug;
-module_param(reg_debug,int,0644);
-MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
+module_param(reg_debug, int, 0644);
+MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
#define em28xx_regdbg(fmt, arg...) do {\
if (reg_debug) \
@@ -77,7 +77,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
return -EINVAL;
if (reg_debug) {
- printk( KERN_DEBUG "(pipe 0x%08x): "
+ printk(KERN_DEBUG "(pipe 0x%08x): "
"IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
pipe,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -154,7 +154,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
if (reg_debug) {
int byte;
- printk( KERN_DEBUG "(pipe 0x%08x): "
+ printk(KERN_DEBUG "(pipe 0x%08x): "
"OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
pipe,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -424,7 +424,7 @@ int em28xx_audio_analog_set(struct em28xx *dev)
xclk = dev->board.xclk & 0x7f;
if (!dev->mute)
- xclk |= 0x80;
+ xclk |= EM28XX_XCLK_AUDIO_UNMUTE;
ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
if (ret < 0)
@@ -438,6 +438,10 @@ int em28xx_audio_analog_set(struct em28xx *dev)
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
int vol;
+ em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200);
+ em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031);
+ em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80);
+
/* LSB: left channel - both channels with the same level */
vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
@@ -454,6 +458,16 @@ int em28xx_audio_analog_set(struct em28xx *dev)
em28xx_warn("couldn't setup AC97 register %d\n",
outputs[i].reg);
}
+
+ if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
+ int sel = ac97_return_record_select(dev->ctl_aoutput);
+
+ /* Use the same input for both left and right
+ channels */
+ sel |= (sel << 8);
+
+ em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
+ }
}
return ret;
@@ -685,7 +699,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
/* it seems that both H and V scalers must be active
to work correctly */
- mode = (h || v)? 0x30: 0x00;
+ mode = (h || v) ? 0x30 : 0x00;
}
return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
}
@@ -814,6 +828,19 @@ static void em28xx_irq_callback(struct urb *urb)
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
int rc, i;
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ em28xx_isocdbg("urb completition error %d.\n", urb->status);
+ break;
+ }
+
/* Copy data from URB */
spin_lock(&dev->slock);
rc = dev->isoc_ctl.isoc_copy(dev, urb);
@@ -847,8 +874,11 @@ void em28xx_uninit_isoc(struct em28xx *dev)
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
urb = dev->isoc_ctl.urb[i];
if (urb) {
- usb_kill_urb(urb);
- usb_unlink_urb(urb);
+ if (!irqs_disabled())
+ usb_kill_urb(urb);
+ else
+ usb_unlink_urb(urb);
+
if (dev->isoc_ctl.transfer_buffer[i]) {
usb_buffer_free(dev->udev,
urb->transfer_buffer_length,
@@ -929,7 +959,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
em28xx_err("unable to allocate %i bytes for transfer"
" buffer %i%s\n",
sb_size, i,
- in_interrupt()?" while in int":"");
+ in_interrupt() ? " while in int" : "");
em28xx_uninit_isoc(dev);
return -ENOMEM;
}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index d38cb21834d9..9ad8527b3fda 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -28,6 +28,7 @@
#include "lgdt330x.h"
#include "zl10353.h"
+#include "s5h1409.h"
#ifdef EM28XX_DRX397XD_SUPPORT
#include "drx397xD.h"
#endif
@@ -232,6 +233,15 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = {
.if2 = 45600,
};
+static struct s5h1409_config em28xx_s5h1409_with_xc3028 = {
+ .demod_address = 0x32 >> 1,
+ .output_mode = S5H1409_PARALLEL_OUTPUT,
+ .gpio = S5H1409_GPIO_OFF,
+ .inversion = S5H1409_INVERSION_OFF,
+ .status_mode = S5H1409_DEMODLOCKING,
+ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
+};
+
#ifdef EM28XX_DRX397XD_SUPPORT
/* [TODO] djh - not sure yet what the device config needs to contain */
static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
@@ -412,7 +422,6 @@ static int dvb_init(struct em28xx *dev)
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
- case EM2883_BOARD_KWORLD_HYBRID_A316:
case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
dvb->frontend = dvb_attach(lgdt330x_attach,
&em2880_lgdt3303_dev,
@@ -433,6 +442,15 @@ static int dvb_init(struct em28xx *dev)
goto out_free;
}
break;
+ case EM2883_BOARD_KWORLD_HYBRID_330U:
+ dvb->frontend = dvb_attach(s5h1409_attach,
+ &em28xx_s5h1409_with_xc3028,
+ &dev->i2c_adap);
+ if (attach_xc3028(0x61, dev) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
#ifdef EM28XX_DRX397XD_SUPPORT
/* We don't have the config structure properly populated, so
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index d69f0efcc9aa..2dab43d22da2 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -402,10 +402,12 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
dev->name);
break;
case 2:
- printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name);
+ printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n",
+ dev->name);
break;
case 3:
- printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name);
+ printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n",
+ dev->name);
break;
}
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 416b691c33c1..efd641587e04 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -186,7 +186,8 @@ static void em28xx_copy_video(struct em28xx *dev,
em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
((char *)startwrite + lencopy) -
((char *)outp + buf->vb.size));
- lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ lencopy = remain;
}
if (lencopy <= 0)
return;
@@ -202,7 +203,8 @@ static void em28xx_copy_video(struct em28xx *dev,
else
lencopy = bytesperline;
- if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+ if ((char *)startwrite + lencopy > (char *)outp +
+ buf->vb.size) {
em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
((char *)startwrite + lencopy) -
((char *)outp + buf->vb.size));
@@ -347,7 +349,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
}
if (p[0] == 0x22 && p[1] == 0x5a) {
em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
- len, (p[2] & 1)? "odd" : "even");
+ len, (p[2] & 1) ? "odd" : "even");
if (!(p[2] & 1)) {
if (buf != NULL)
@@ -476,7 +478,9 @@ fail:
static void
buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf = container_of(vb,
+ struct em28xx_buffer,
+ vb);
struct em28xx_fh *fh = vq->priv_data;
struct em28xx *dev = fh->dev;
struct em28xx_dmaqueue *vidq = &dev->vidq;
@@ -489,7 +493,9 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
static void buffer_release(struct videobuf_queue *vq,
struct videobuf_buffer *vb)
{
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf = container_of(vb,
+ struct em28xx_buffer,
+ vb);
struct em28xx_fh *fh = vq->priv_data;
struct em28xx *dev = (struct em28xx *)fh->dev;
@@ -557,7 +563,7 @@ static int res_get(struct em28xx_fh *fh)
static int res_check(struct em28xx_fh *fh)
{
- return (fh->stream_on);
+ return fh->stream_on;
}
static void res_free(struct em28xx_fh *fh)
@@ -791,7 +797,7 @@ out:
return rc;
}
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
{
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
@@ -886,10 +892,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
if (0 == INPUT(i)->type)
return -EINVAL;
- mutex_lock(&dev->lock);
-
- video_mux(dev, i);
+ dev->ctl_input = i;
+ mutex_lock(&dev->lock);
+ video_mux(dev, dev->ctl_input);
mutex_unlock(&dev->lock);
return 0;
}
@@ -939,6 +945,12 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
+
+ if (a->index >= MAX_EM28XX_INPUT)
+ return -EINVAL;
+ if (0 == INPUT(a->index)->type)
+ return -EINVAL;
+
mutex_lock(&dev->lock);
dev->ctl_ainput = INPUT(a->index)->amux;
@@ -1002,8 +1014,13 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
if (dev->board.has_msp34xx)
em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
- else
+ else {
rc = em28xx_get_ctrl(dev, ctrl);
+ if (rc < 0) {
+ em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ rc = 0;
+ }
+ }
mutex_unlock(&dev->lock);
return rc;
@@ -1339,7 +1356,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
@@ -1425,7 +1442,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
if (rc < 0)
return rc;
- return (videobuf_reqbufs(&fh->vb_vidq, rb));
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
}
static int vidioc_querybuf(struct file *file, void *priv,
@@ -1439,7 +1456,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
if (rc < 0)
return rc;
- return (videobuf_querybuf(&fh->vb_vidq, b));
+ return videobuf_querybuf(&fh->vb_vidq, b);
}
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1452,7 +1469,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
if (rc < 0)
return rc;
- return (videobuf_qbuf(&fh->vb_vidq, b));
+ return videobuf_qbuf(&fh->vb_vidq, b);
}
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1465,8 +1482,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
if (rc < 0)
return rc;
- return (videobuf_dqbuf(&fh->vb_vidq, b,
- file->f_flags & O_NONBLOCK));
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
}
#ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1490,7 +1506,7 @@ static int radio_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
cap->capabilities = V4L2_CAP_TUNER;
@@ -1775,7 +1791,7 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
* em28xx_v4l2_poll()
* will allocate buffers when called for the first time
*/
-static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
+static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
{
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;
@@ -1928,8 +1944,8 @@ static struct video_device em28xx_radio_template = {
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
- const struct video_device *template,
- const char *type_name)
+ const struct video_device *template,
+ const char *type_name)
{
struct video_device *vfd;
@@ -1950,6 +1966,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
int em28xx_register_analog_devices(struct em28xx *dev)
{
+ u8 val;
int ret;
printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n",
@@ -1957,34 +1974,35 @@ int em28xx_register_analog_devices(struct em28xx *dev)
(EM28XX_VERSION_CODE >> 16) & 0xff,
(EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
+ /* set default norm */
+ dev->norm = em28xx_video_template.current_norm;
+ dev->width = norm_maxw(dev);
+ dev->height = norm_maxh(dev);
+ dev->interlaced = EM28XX_INTERLACED_DEFAULT;
+ dev->hscale = 0;
+ dev->vscale = 0;
+ dev->ctl_input = 0;
+
/* Analog specific initialization */
dev->format = &format[0];
- video_mux(dev, 0);
+ video_mux(dev, dev->ctl_input);
+
+ /* Audio defaults */
+ dev->mute = 1;
+ dev->volume = 0x1f;
/* enable vbi capturing */
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
-/* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */
+ val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+ em28xx_write_reg(dev, EM28XX_R0F_XCLK,
+ (EM28XX_XCLK_AUDIO_UNMUTE | val));
em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
- dev->mute = 1; /* maybe not the right place... */
- dev->volume = 0x1f;
-
em28xx_set_outfmt(dev);
em28xx_colorlevels_set_default(dev);
em28xx_compression_disable(dev);
- /* set default norm */
- dev->norm = em28xx_video_template.current_norm;
- dev->width = norm_maxw(dev);
- dev->height = norm_maxh(dev);
- dev->interlaced = EM28XX_INTERLACED_DEFAULT;
- dev->hscale = 0;
- dev->vscale = 0;
-
- /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */
- dev->ctl_input = 2;
-
/* allocate and fill video video_device struct */
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
if (!dev->vdev) {
@@ -2013,7 +2031,8 @@ int em28xx_register_analog_devices(struct em28xx *dev)
}
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
- dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
+ dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
+ "radio");
if (!dev->radio_dev) {
em28xx_errdev("cannot allocate video_device.\n");
return -ENODEV;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 6c6b94aa05b2..3e82d818c0cd 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -94,10 +94,14 @@
#define EM2882_BOARD_KWORLD_VS_DVBT 54
#define EM2882_BOARD_TERRATEC_HYBRID_XS 55
#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56
-#define EM2883_BOARD_KWORLD_HYBRID_A316 57
+#define EM2883_BOARD_KWORLD_HYBRID_330U 57
#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61
+#define EM2820_BOARD_GADMEI_TVR200 62
+#define EM2860_BOARD_KAIOMY_TVNPC_U2 63
+#define EM2860_BOARD_EASYCAP 64
+#define EM2820_BOARD_IODATA_GVMVP_SZ 65
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -110,6 +114,10 @@
#define EM28XX_BOARD_NOT_VALIDATED 1
#define EM28XX_BOARD_VALIDATED 0
+/* Params for em28xx_cmd() audio */
+#define EM28XX_START_AUDIO 1
+#define EM28XX_STOP_AUDIO 0
+
/* maximum number of em28xx boards */
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
@@ -154,7 +162,8 @@
*/
/* time to wait when stopping the isoc transfer */
-#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
+#define EM28XX_URB_TIMEOUT \
+ msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
/* time in msecs to wait for i2c writes to finish */
#define EM2800_I2C_WRITE_TIMEOUT 20
@@ -300,13 +309,32 @@ enum em28xx_amux {
};
enum em28xx_aout {
+ /* AC97 outputs */
EM28XX_AOUT_MASTER = 1 << 0,
EM28XX_AOUT_LINE = 1 << 1,
EM28XX_AOUT_MONO = 1 << 2,
EM28XX_AOUT_LFE = 1 << 3,
EM28XX_AOUT_SURR = 1 << 4,
+
+ /* PCM IN Mixer - used by AC97_RECORD_SELECT register */
+ EM28XX_AOUT_PCM_IN = 1 << 7,
+
+ /* Bits 10-8 are used to indicate the PCM IN record select */
+ EM28XX_AOUT_PCM_MIC_PCM = 0 << 8,
+ EM28XX_AOUT_PCM_CD = 1 << 8,
+ EM28XX_AOUT_PCM_VIDEO = 2 << 8,
+ EM28XX_AOUT_PCM_AUX = 3 << 8,
+ EM28XX_AOUT_PCM_LINE = 4 << 8,
+ EM28XX_AOUT_PCM_STEREO = 5 << 8,
+ EM28XX_AOUT_PCM_MONO = 6 << 8,
+ EM28XX_AOUT_PCM_PHONE = 7 << 8,
};
+static inline int ac97_return_record_select(int a_out)
+{
+ return (a_out & 0x700) >> 8;
+}
+
struct em28xx_reg_seq {
int reg;
unsigned char val, mask;
@@ -401,7 +429,7 @@ struct em28xx_audio {
unsigned int hwptr_done_capture;
struct snd_card *sndcard;
- int users, shutdown;
+ int users;
enum em28xx_stream_state capture_stream;
spinlock_t slock;
};
@@ -504,7 +532,8 @@ struct em28xx {
int num_alt; /* Number of alternative settings */
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
- char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
+ char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
+ transfer */
char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
/* helper funcs that call usb_control_msg */
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index ee6a691dff22..11c5d2fc20de 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -56,6 +56,15 @@ config USB_GSPCA_MARS
To compile this driver as a module, choose M here: the
module will be called gspca_mars.
+config USB_GSPCA_MR97310A
+ tristate "Mars-Semi MR97310A USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the MR97310A chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_mr97310a.
+
config USB_GSPCA_OV519
tristate "OV519 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index bd8d9ee40504..b3cbcc1764f4 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,50 +1,52 @@
-obj-$(CONFIG_USB_GSPCA) += gspca_main.o
-obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
-obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
-obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
-obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
-obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
-obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
-obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
-obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
-obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
-obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
-obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
-obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
-obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
-obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
-obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
-obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
-obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
-obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
-obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
-obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
-obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
-obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
+obj-$(CONFIG_USB_GSPCA) += gspca_main.o
+obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
+obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
+obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
+obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
+obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
+obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
+obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
+obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
+obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
+obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
+obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
+obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
+obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
+obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
+obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
+obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
+obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
+obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
+obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
+obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
+obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
+obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
+obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
-gspca_main-objs := gspca.o
-gspca_conex-objs := conex.o
-gspca_etoms-objs := etoms.o
-gspca_finepix-objs := finepix.o
-gspca_mars-objs := mars.o
-gspca_ov519-objs := ov519.o
-gspca_ov534-objs := ov534.o
-gspca_pac207-objs := pac207.o
-gspca_pac7311-objs := pac7311.o
-gspca_sonixb-objs := sonixb.o
-gspca_sonixj-objs := sonixj.o
-gspca_spca500-objs := spca500.o
-gspca_spca501-objs := spca501.o
-gspca_spca505-objs := spca505.o
-gspca_spca506-objs := spca506.o
-gspca_spca508-objs := spca508.o
-gspca_spca561-objs := spca561.o
-gspca_stk014-objs := stk014.o
-gspca_sunplus-objs := sunplus.o
-gspca_t613-objs := t613.o
-gspca_tv8532-objs := tv8532.o
-gspca_vc032x-objs := vc032x.o
-gspca_zc3xx-objs := zc3xx.o
+gspca_main-objs := gspca.o
+gspca_conex-objs := conex.o
+gspca_etoms-objs := etoms.o
+gspca_finepix-objs := finepix.o
+gspca_mars-objs := mars.o
+gspca_mr97310a-objs := mr97310a.o
+gspca_ov519-objs := ov519.o
+gspca_ov534-objs := ov534.o
+gspca_pac207-objs := pac207.o
+gspca_pac7311-objs := pac7311.o
+gspca_sonixb-objs := sonixb.o
+gspca_sonixj-objs := sonixj.o
+gspca_spca500-objs := spca500.o
+gspca_spca501-objs := spca501.o
+gspca_spca505-objs := spca505.o
+gspca_spca506-objs := spca506.o
+gspca_spca508-objs := spca508.o
+gspca_spca561-objs := spca561.o
+gspca_stk014-objs := stk014.o
+gspca_sunplus-objs := sunplus.o
+gspca_t613-objs := t613.o
+gspca_tv8532-objs := tv8532.o
+gspca_vc032x-objs := vc032x.o
+gspca_zc3xx-objs := zc3xx.o
-obj-$(CONFIG_USB_M5602) += m5602/
-obj-$(CONFIG_USB_STV06XX) += stv06xx/
+obj-$(CONFIG_USB_M5602) += m5602/
+obj-$(CONFIG_USB_STV06XX) += stv06xx/
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 1753f5bb3544..de2e608bf5ba 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -23,6 +23,7 @@
#include "gspca.h"
#define CONEX_CAM 1 /* special JPEG header */
+#define QUANT_VAL 0 /* quantization table */
#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -36,8 +37,6 @@ struct sd {
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
-
- unsigned char qindex;
};
/* V4L2 controls supported by the driver */
@@ -815,11 +814,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
- sd->qindex = 0; /* set the quantization */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
@@ -883,9 +880,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ jpeg_put_header(gspca_dev, frame, 0x22);
data += 2;
len -= 2;
}
@@ -1029,8 +1024,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index f3cd8ff5cc92..2c20d06a03e8 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -472,19 +472,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_w_val(gspca_dev, ET_O_RED + i, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int brightness = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_O_RED + i, 1);
- brightness += gspca_dev->usb_buf[0];
- }
- sd->brightness = brightness >> 3;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -495,19 +482,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, ET_G_RED, RGBG, 6);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int contrast = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_G_RED + i, 1);
- contrast += gspca_dev->usb_buf[0];
- }
- sd->contrast = contrast >> 2;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -658,7 +632,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 1;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAS106) {
cam->cam_mode = sif_mode;
@@ -821,7 +794,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -840,7 +812,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -859,7 +830,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -928,8 +898,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index afc8b2dd307b..dc65c363aa87 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -259,7 +259,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = fpix_mode;
cam->nmodes = 1;
- cam->epaddr = 0x01; /* todo: correct for all cams? */
cam->bulk_size = FPIX_MAX_TRANSFER;
/* gspca_dev->nbalt = 1; * use bulk transfer */
@@ -335,8 +334,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* Read the result of the command. Ignore the result, for it
* varies with the device. */
ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr),
+ gspca_dev->urb[0]->pipe,
gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret,
FPIX_TIMEOUT);
if (ret != 0) {
@@ -363,7 +361,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
/* Again, reset bulk in endpoint */
- usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
+ usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
/* Allocate a control URB */
dev->control_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -456,8 +454,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 5e36b9a4ae3e..8aac7a1e8f33 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -38,15 +38,16 @@
#include "gspca.h"
/* global values */
-#define DEF_NURBS 2 /* default number of URBs */
+#define DEF_NURBS 3 /* default number of URBs */
+#if DEF_NURBS > MAX_NURBS
+#error "DEF_NURBS too big"
+#endif
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
-
-static int video_nr = -1;
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -126,16 +127,18 @@ static void fill_frame(struct gspca_dev *gspca_dev,
struct urb *urb)
{
struct gspca_frame *frame;
- __u8 *data; /* address of data in the iso message */
+ u8 *data; /* address of data in the iso message */
int i, len, st;
cam_pkt_op pkt_scan;
if (urb->status != 0) {
+ if (urb->status == -ESHUTDOWN)
+ return; /* disconnection */
#ifdef CONFIG_PM
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
pkt_scan = gspca_dev->sd_desc->pkt_scan;
for (i = 0; i < urb->number_of_packets; i++) {
@@ -166,7 +169,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
/* let the packet be analyzed by the subdriver */
PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
i, urb->iso_frame_desc[i].offset, len);
- data = (__u8 *) urb->transfer_buffer
+ data = (u8 *) urb->transfer_buffer
+ urb->iso_frame_desc[i].offset;
pkt_scan(gspca_dev, frame, data, len);
}
@@ -182,8 +185,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
*
* Analyse each packet and call the subdriver for copy to the frame buffer.
*/
-static void isoc_irq(struct urb *urb
-)
+static void isoc_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
@@ -196,8 +198,7 @@ static void isoc_irq(struct urb *urb
/*
* bulk message interrupt from the USB device
*/
-static void bulk_irq(struct urb *urb
-)
+static void bulk_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
struct gspca_frame *frame;
@@ -209,6 +210,8 @@ static void bulk_irq(struct urb *urb
switch (urb->status) {
case 0:
break;
+ case -ESHUTDOWN:
+ return; /* disconnection */
case -ECONNRESET:
urb->status = 0;
break;
@@ -217,7 +220,7 @@ static void bulk_irq(struct urb *urb
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
/* check the availability of the frame buffer */
@@ -322,6 +325,7 @@ static int gspca_is_compressed(__u32 format)
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_SPCA561:
case V4L2_PIX_FMT_PAC207:
+ case V4L2_PIX_FMT_MR97310A:
return 1;
}
return 0;
@@ -437,22 +441,16 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
* look for an input transfer endpoint in an alternate setting
*/
static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
- __u8 epaddr,
__u8 xfer)
{
struct usb_host_endpoint *ep;
int i, attr;
- epaddr |= USB_DIR_IN;
for (i = 0; i < alt->desc.bNumEndpoints; i++) {
ep = &alt->endpoint[i];
- if (ep->desc.bEndpointAddress == epaddr) {
- attr = ep->desc.bmAttributes
- & USB_ENDPOINT_XFERTYPE_MASK;
- if (attr == xfer)
- return ep;
- break;
- }
+ attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ if (attr == xfer)
+ return ep;
}
return NULL;
}
@@ -478,7 +476,6 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
/* try isoc */
while (--i > 0) { /* alt 0 is unusable */
ep = alt_xfer(&intf->altsetting[i],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_ISOC);
if (ep)
break;
@@ -487,7 +484,6 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
/* if no isoc, try bulk */
if (ep == NULL) {
ep = alt_xfer(&intf->altsetting[0],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_BULK);
if (ep == NULL) {
err("no transfer endpoint found");
@@ -599,6 +595,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
+
/* set the higher alternate setting and
* loop until urb submit succeeds */
gspca_dev->alt = gspca_dev->nbalt;
@@ -616,8 +617,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
/* clear the bulk endpoint */
if (gspca_dev->alt == 0) /* if bulk transfer */
usb_clear_halt(gspca_dev->dev,
- usb_rcvintpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr));
+ gspca_dev->urb[0]->pipe);
/* start the cam */
ret = gspca_dev->sd_desc->start(gspca_dev);
@@ -669,11 +669,14 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
static void gspca_stream_off(struct gspca_dev *gspca_dev)
{
gspca_dev->streaming = 0;
- if (gspca_dev->present
- && gspca_dev->sd_desc->stopN)
- gspca_dev->sd_desc->stopN(gspca_dev);
- destroy_urbs(gspca_dev);
- gspca_set_alt0(gspca_dev);
+ if (gspca_dev->present) {
+ if (gspca_dev->sd_desc->stopN)
+ gspca_dev->sd_desc->stopN(gspca_dev);
+ destroy_urbs(gspca_dev);
+ gspca_set_alt0(gspca_dev);
+ }
+
+ /* always call stop0 to free the subdriver's resources */
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
PDEBUG(D_STREAM, "stream off OK");
@@ -955,8 +958,17 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct gspca_dev *gspca_dev = priv;
+ int ret;
memset(cap, 0, sizeof *cap);
+
+ /* protect the access to the usb device */
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
if (gspca_dev->dev->product != NULL) {
strncpy(cap->card, gspca_dev->dev->product,
@@ -967,13 +979,15 @@ static int vidioc_querycap(struct file *file, void *priv,
le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
}
- strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
- sizeof cap->bus_info);
+ usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
| V4L2_CAP_READWRITE;
- return 0;
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
}
static int vidioc_queryctrl(struct file *file, void *priv,
@@ -1036,7 +1050,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->set(gspca_dev, ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->set(gspca_dev, ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1060,7 +1077,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->get(gspca_dev, &ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->get(gspca_dev, &ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1222,10 +1242,7 @@ static int vidioc_streamon(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
- if (!gspca_dev->present) {
- ret = -ENODEV;
- goto out;
- }
+
if (gspca_dev->nframes == 0
|| !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
ret = -EINVAL;
@@ -1293,7 +1310,10 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1308,7 +1328,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1327,7 +1350,11 @@ static int vidioc_g_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1352,7 +1379,11 @@ static int vidioc_s_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1526,7 +1557,8 @@ static int frame_wait(struct gspca_dev *gspca_dev,
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->sd_desc->dq_callback(gspca_dev);
+ if (gspca_dev->present)
+ gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
return j;
@@ -1548,6 +1580,9 @@ static int vidioc_dqbuf(struct file *file, void *priv,
if (v4l2_buf->memory != gspca_dev->memory)
return -EINVAL;
+ if (!gspca_dev->present)
+ return -ENODEV;
+
/* if not streaming, be sure the application will not loop forever */
if (!(file->f_flags & O_NONBLOCK)
&& !gspca_dev->streaming && gspca_dev->users == 1)
@@ -1698,8 +1733,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
PDEBUG(D_FRAM, "poll");
poll_wait(file, &gspca_dev->wq, wait);
- if (!gspca_dev->present)
- return POLLERR;
/* if reqbufs is not done, the user would use read() */
if (gspca_dev->nframes == 0) {
@@ -1712,10 +1745,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
return POLLERR;
- if (!gspca_dev->present) {
- ret = POLLERR;
- goto out;
- }
/* check the next incoming buffer */
i = gspca_dev->fr_o;
@@ -1724,8 +1753,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
ret = POLLIN | POLLRDNORM; /* something to read */
else
ret = 0;
-out:
mutex_unlock(&gspca_dev->queue_lock);
+ if (!gspca_dev->present)
+ return POLLHUP;
return ret;
}
@@ -1923,7 +1953,7 @@ int gspca_dev_probe(struct usb_interface *intf,
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
VFL_TYPE_GRABBER,
- video_nr);
+ -1);
if (ret < 0) {
err("video_register_device err %d", ret);
goto out;
@@ -1949,8 +1979,17 @@ void gspca_disconnect(struct usb_interface *intf)
{
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+ mutex_lock(&gspca_dev->usb_lock);
gspca_dev->present = 0;
- gspca_dev->streaming = 0;
+
+ if (gspca_dev->streaming) {
+ destroy_urbs(gspca_dev);
+ wake_up_interruptible(&gspca_dev->wq);
+ }
+
+ /* the device is freed at exit of this function */
+ gspca_dev->dev = NULL;
+ mutex_unlock(&gspca_dev->usb_lock);
usb_set_intfdata(intf, NULL);
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index c90af9cb1e07..6f172e9e5fe9 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -33,19 +33,13 @@ extern int gspca_debug;
#endif
#undef err
#define err(fmt, args...) \
- do {\
- printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args)
#undef info
#define info(fmt, args...) \
- do {\
- printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args)
#undef warn
#define warn(fmt, args...) \
- do {\
- printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args)
#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
/* image transfers */
@@ -62,7 +56,6 @@ struct cam {
* - cannot be > MAX_NURBS
* - when 0 and bulk_size != 0 means
* 1 URB and submit done by subdriver */
- __u8 epaddr;
};
struct gspca_dev;
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h
index d823b47bd4e6..7d2df9720025 100644
--- a/drivers/media/video/gspca/jpeg.h
+++ b/drivers/media/video/gspca/jpeg.h
@@ -24,171 +24,207 @@
*
*/
-/* start of jpeg frame + quantization table */
-static const unsigned char quant[][0x88] = {
-/* index 0 - Q40*/
- {
+/*
+ * generation options
+ * CONEX_CAM Conexant if present
+ * QUANT_VAL quantization table (0..8)
+ */
+
+/*
+ * JPEG header:
+ * - start of jpeg frame
+ * - quantization table
+ * - huffman table
+ * - start of SOF0
+ */
+static const u8 jpeg_head[] = {
0xff, 0xd8, /* jpeg */
0xff, 0xdb, 0x00, 0x84, /* DQT */
+#if QUANT_VAL == 0
+/* index 0 - Q40*/
0, /* quantization table part 1 */
- 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50,
- 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64,
- 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101,
- 109,
- 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115,
- 126, 129, 124,
+ 0x14, 0x0e, 0x0f, 0x12, 0x0f, 0x0d, 0x14, 0x12,
+ 0x10, 0x12, 0x17, 0x15, 0x14, 0x18, 0x1e, 0x32,
+ 0x21, 0x1e, 0x1c, 0x1c, 0x1e, 0x3d, 0x2c, 0x2e,
+ 0x24, 0x32, 0x49, 0x40, 0x4c, 0x4b, 0x47, 0x40,
+ 0x46, 0x45, 0x50, 0x5a, 0x73, 0x62, 0x50, 0x55,
+ 0x6d, 0x56, 0x45, 0x46, 0x64, 0x88, 0x65, 0x6d,
+ 0x77, 0x7b, 0x81, 0x82, 0x81, 0x4e, 0x60, 0x8d,
+ 0x97, 0x8c, 0x7d, 0x96, 0x73, 0x7e, 0x81, 0x7c,
1, /* quantization table part 2 */
- 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124},
+ 0x15, 0x17, 0x17, 0x1e, 0x1a, 0x1e, 0x3b, 0x21,
+ 0x21, 0x3b, 0x7c, 0x53, 0x46, 0x53, 0x7c, 0x0c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+ 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
+#elif QUANT_VAL == 1
/* index 1 - Q50 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
- 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
- 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87,
- 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101,
- 103, 99,
+ 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+ 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+ 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+ 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+ 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+ 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+ 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+ 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
1,
- 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
+ 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+ 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+#elif QUANT_VAL == 2
/* index 2 Q60 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32,
- 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41,
- 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70,
- 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79,
+ 0x0d, 0x09, 0x0a, 0x0b, 0x0a, 0x08, 0x0d, 0x0b,
+ 0x0a, 0x0b, 0x0e, 0x0e, 0x0d, 0x0f, 0x13, 0x20,
+ 0x15, 0x13, 0x12, 0x12, 0x13, 0x27, 0x1c, 0x1e,
+ 0x17, 0x20, 0x2e, 0x29, 0x31, 0x30, 0x2e, 0x29,
+ 0x2d, 0x2c, 0x33, 0x3a, 0x4a, 0x3e, 0x33, 0x36,
+ 0x46, 0x37, 0x2c, 0x2d, 0x40, 0x57, 0x41, 0x46,
+ 0x4c, 0x4e, 0x52, 0x53, 0x52, 0x32, 0x3e, 0x5a,
+ 0x61, 0x5a, 0x50, 0x60, 0x4a, 0x51, 0x52, 0x4f,
1,
- 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
+ 0x0e, 0x0e, 0x0e, 0x13, 0x11, 0x13, 0x26, 0x15,
+ 0x15, 0x26, 0x4f, 0x35, 0x2d, 0x35, 0x4f, 0x4f,
+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
+ 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
+#elif QUANT_VAL == 3
/* index 3 - Q70 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24,
- 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31,
- 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52,
- 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59,
+ 0x0a, 0x07, 0x07, 0x08, 0x07, 0x06, 0x0a, 0x08,
+ 0x08, 0x08, 0x0b, 0x0a, 0x0a, 0x0b, 0x0e, 0x18,
+ 0x10, 0x0e, 0x0d, 0x0d, 0x0e, 0x1d, 0x15, 0x16,
+ 0x11, 0x18, 0x23, 0x1f, 0x25, 0x24, 0x22, 0x1f,
+ 0x22, 0x21, 0x26, 0x2b, 0x37, 0x2f, 0x26, 0x29,
+ 0x34, 0x29, 0x21, 0x22, 0x30, 0x41, 0x31, 0x34,
+ 0x39, 0x3b, 0x3e, 0x3e, 0x3e, 0x25, 0x2e, 0x44,
+ 0x49, 0x43, 0x3c, 0x48, 0x37, 0x3d, 0x3e, 0x3b,
1,
- 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59},
+ 0x0a, 0x0b, 0x0b, 0x0e, 0x0d, 0x0e, 0x1c, 0x10,
+ 0x10, 0x1c, 0x3b, 0x28, 0x22, 0x28, 0x3b, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+ 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+#elif QUANT_VAL == 4
/* index 4 - Q80 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16,
- 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20,
- 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35,
- 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40,
+ 0x06, 0x04, 0x05, 0x06, 0x05, 0x04, 0x06, 0x06,
+ 0x05, 0x06, 0x07, 0x07, 0x06, 0x08, 0x0a, 0x10,
+ 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e, 0x0f,
+ 0x0c, 0x10, 0x17, 0x14, 0x18, 0x18, 0x17, 0x14,
+ 0x16, 0x16, 0x1a, 0x1d, 0x25, 0x1f, 0x1a, 0x1b,
+ 0x23, 0x1c, 0x16, 0x16, 0x20, 0x2c, 0x20, 0x23,
+ 0x26, 0x27, 0x29, 0x2a, 0x29, 0x19, 0x1f, 0x2d,
+ 0x30, 0x2d, 0x28, 0x30, 0x25, 0x28, 0x29, 0x28,
1,
- 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
+ 0x07, 0x07, 0x07, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
+ 0x0a, 0x13, 0x28, 0x1a, 0x16, 0x1a, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+#elif QUANT_VAL == 5
/* index 5 - Q85 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12,
- 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15,
- 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26,
- 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30,
+ 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04,
+ 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c,
+ 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b,
+ 0x09, 0x0c, 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f,
+ 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14,
+ 0x1a, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1a,
+ 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22,
+ 0x24, 0x22, 0x1e, 0x24, 0x1c, 0x1e, 0x1f, 0x1e,
1,
- 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
+ 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0e, 0x08,
+ 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+#elif QUANT_VAL == 6
/* index 6 - 86 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B,
- 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A,
- 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E,
- 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13,
- 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18,
- 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20,
- 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C,
+ 0x07, 0x07, 0x06, 0x06, 0x07, 0x0e, 0x0a, 0x0a,
+ 0x08, 0x0B, 0x10, 0x0e, 0x11, 0x11, 0x10, 0x0e,
+ 0x10, 0x0f, 0x12, 0x14, 0x1a, 0x16, 0x12, 0x13,
+ 0x18, 0x13, 0x0f, 0x10, 0x16, 0x1f, 0x17, 0x18,
+ 0x1b, 0x1b, 0x1d, 0x1d, 0x1d, 0x11, 0x16, 0x20,
+ 0x22, 0x1f, 0x1c, 0x22, 0x1a, 0x1c, 0x1d, 0x1c,
1,
0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07,
- 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- },
+ 0x07, 0x0D, 0x1c, 0x12, 0x10, 0x12, 0x1c, 0x1c,
+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
+ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
+#elif QUANT_VAL == 7
/* index 7 - 88 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A,
+ 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0a,
0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09,
- 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C,
- 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10,
- 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15,
- 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B,
- 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18,
+ 0x07, 0x0a, 0x0e, 0x0c, 0x0f, 0x0e, 0x0e, 0x0c,
+ 0x0d, 0x0d, 0x0f, 0x11, 0x16, 0x13, 0x0f, 0x10,
+ 0x15, 0x11, 0x0d, 0x0d, 0x13, 0x1a, 0x13, 0x15,
+ 0x17, 0x18, 0x19, 0x19, 0x19, 0x0f, 0x12, 0x1b,
+ 0x1d, 0x1b, 0x18, 0x1d, 0x16, 0x18, 0x19, 0x18,
1,
0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06,
- 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18,
+ 0x06, 0x0B, 0x18, 0x10, 0x0d, 0x10, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-},
+#elif QUANT_VAL == 8
/* index 8 - ?? */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05,
0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05,
0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06,
- 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09,
- 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B,
- 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E,
- 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C,
+ 0x07, 0x07, 0x08, 0x09, 0x0c, 0x0a, 0x08, 0x09,
+ 0x0B, 0x09, 0x07, 0x07, 0x0a, 0x0e, 0x0a, 0x0b,
+ 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x08, 0x0a, 0x0e,
+ 0x0f, 0x0e, 0x0d, 0x0f, 0x0c, 0x0d, 0x0d, 0x0c,
1,
0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03,
- 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C
-}
-};
+ 0x03, 0x06, 0x0c, 0x08, 0x07, 0x08, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+#else
+#error "Invalid quantization table"
+#endif
-/* huffman table + start of SOF0 */
-static unsigned char huffman[] = {
+/* huffman table */
0xff, 0xc4, 0x01, 0xa2,
0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -260,7 +296,7 @@ static unsigned char huffman[] = {
*/
/* end of header */
-static unsigned char eoh[] = {
+static u8 eoh[] = {
0x00, /* quant Y */
0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
0x03, 0x11, 0x01,
@@ -273,17 +309,14 @@ static unsigned char eoh[] = {
/* -- output the JPEG header -- */
static void jpeg_put_header(struct gspca_dev *gspca_dev,
struct gspca_frame *frame,
- int qindex,
int samplesY)
{
#ifndef CONEX_CAM
- unsigned char tmpbuf[8];
+ u8 tmpbuf[8];
#endif
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- (unsigned char *) quant[qindex], sizeof quant[0]);
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- (unsigned char *) huffman, sizeof huffman);
+ jpeg_head, sizeof jpeg_head);
#ifndef CONEX_CAM
tmpbuf[0] = gspca_dev->height >> 8;
tmpbuf[1] = gspca_dev->height & 0xff;
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index ed906fe31287..b35e4838a6e5 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -332,7 +332,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
int err;
cam = &gspca_dev->cam;
- cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
sd->desc = &sd_desc;
if (dump_bridge)
@@ -374,8 +373,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init mod_m5602_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 3d2090e67a63..7f605ce3a7e5 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -22,6 +22,7 @@
#define MODULE_NAME "mars"
#include "gspca.h"
+#define QUANT_VAL 1 /* quantization table */
#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -32,17 +33,85 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- char qindex;
+ u8 brightness;
+ u8 colors;
+ u8 gamma;
+ u8 sharpness;
};
/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+
static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 30,
+ .step = 1,
+#define BRIGHTNESS_DEF 15
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 220,
+ .step = 1,
+#define COLOR_DEF 190
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+#define GAMMA_DEF 1
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+#define SHARPNESS_DEF 1
+ .default_value = SHARPNESS_DEF,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
};
static const struct v4l2_pix_format vga_mode[] = {
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 589,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 2},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -52,65 +121,45 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 1},
};
-/* MI Register table //elvis */
-enum {
- REG_HW_MI_0,
- REG_HW_MI_1,
- REG_HW_MI_2,
- REG_HW_MI_3,
- REG_HW_MI_4,
- REG_HW_MI_5,
- REG_HW_MI_6,
- REG_HW_MI_7,
- REG_HW_MI_9 = 0x09,
- REG_HW_MI_B = 0x0B,
- REG_HW_MI_C,
- REG_HW_MI_D,
- REG_HW_MI_1E = 0x1E,
- REG_HW_MI_20 = 0x20,
- REG_HW_MI_2B = 0x2B,
- REG_HW_MI_2C,
- REG_HW_MI_2D,
- REG_HW_MI_2E,
- REG_HW_MI_35 = 0x35,
- REG_HW_MI_5F = 0x5f,
- REG_HW_MI_60,
- REG_HW_MI_61,
- REG_HW_MI_62,
- REG_HW_MI_63,
- REG_HW_MI_64,
- REG_HW_MI_F1 = 0xf1,
- ATTR_TOTAL_MI_REG = 0xf2
+static const __u8 mi_data[0x20] = {
+/* 01 02 03 04 05 06 07 08 */
+ 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
+/* 09 0a 0b 0c 0d 0e 0f 10 */
+ 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
+/* 11 12 13 14 15 16 17 18 */
+ 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
+/* 19 1a 1b 1c 1d 1e 1f 20 */
+ 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
};
-/* the bytes to write are in gspca_dev->usb_buf */
+/* write <len> bytes from gspca_dev->usb_buf */
static int reg_w(struct gspca_dev *gspca_dev,
- __u16 index, int len)
+ int len)
{
- int rc;
-
- rc = usb_control_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 4),
- 0x12,
- 0xc8, /* ?? */
- 0, /* value */
- index, gspca_dev->usb_buf, len, 500);
- if (rc < 0)
- PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
- return rc;
+ int alen, ret;
+
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf,
+ len,
+ &alen,
+ 500); /* timeout in milliseconds */
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], ret);
+ return ret;
}
-static void bulk_w(struct gspca_dev *gspca_dev,
- __u16 *pch,
- __u16 Address)
+static void mi_w(struct gspca_dev *gspca_dev,
+ u8 addr,
+ u8 value)
{
gspca_dev->usb_buf[0] = 0x1f;
gspca_dev->usb_buf[1] = 0; /* control byte */
- gspca_dev->usb_buf[2] = Address;
- gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */
- gspca_dev->usb_buf[4] = *pch; /* low byte */
+ gspca_dev->usb_buf[2] = addr;
+ gspca_dev->usb_buf[3] = value;
- reg_w(gspca_dev, Address, 5);
+ reg_w(gspca_dev, 4);
}
/* this function is called at probe time */
@@ -121,10 +170,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- sd->qindex = 1; /* set the quantization table */
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->colors = COLOR_DEF;
+ sd->gamma = GAMMA_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ gspca_dev->nbalt = 9; /* use the altsetting 08 */
return 0;
}
@@ -136,24 +188,16 @@ static int sd_init(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int err_code;
- __u8 *data;
- __u16 *MI_buf;
- int h_size, v_size;
- int intpipe;
-
- PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
- err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8);
- if (err_code < 0) {
- PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
- return err_code;
- }
+ u8 *data;
+ int i, val;
data = gspca_dev->usb_buf;
+
data[0] = 0x01; /* address */
data[1] = 0x01;
-
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -163,30 +207,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
data[0] = 0x00; /* address */
data[1] = 0x0c | 0x01; /* reg 0 */
data[2] = 0x01; /* reg 1 */
- h_size = gspca_dev->width;
- v_size = gspca_dev->height;
- data[3] = h_size / 8; /* h_size , reg 2 */
- data[4] = v_size / 8; /* v_size , reg 3 */
+ data[3] = gspca_dev->width / 8; /* h_size , reg 2 */
+ data[4] = gspca_dev->height / 8; /* v_size , reg 3 */
data[5] = 0x30; /* reg 4, MI, PAS5101 :
* 0x30 for 24mhz , 0x28 for 12mhz */
- data[6] = 4; /* reg 5, H start */
- data[7] = 0xc0; /* reg 6, gamma 1.5 */
- data[8] = 3; /* reg 7, V start */
+ data[6] = 0x02; /* reg 5, H start - was 0x04 */
+ data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */
+ data[8] = 0x01; /* reg 7, V start - was 0x03 */
/* if (h_size == 320 ) */
/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
/* else */
data[9] = 0x52; /* reg 8, 24MHz, no scale down */
- data[10] = 0x5d; /* reg 9, I2C device address
- * [for PAS5101 (0x40)] [for MI (0x5d)] */
+/*jfm: from win trace*/
+ data[10] = 0x18;
- err_code = reg_w(gspca_dev, data[0], 11);
+ err_code = reg_w(gspca_dev, 11);
if (err_code < 0)
return err_code;
data[0] = 0x23; /* address */
data[1] = 0x09; /* reg 35, append frame header */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -197,137 +239,55 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* else */
data[1] = 50; /* 50 reg 60, pc-cam frame size
* (unit: 4KB) 200KB */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
- if (0) { /* fixed dark-gain */
- data[1] = 0; /* reg 94, Y Gain (1.75) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- data[4] = 0; /* reg 97, set fixed dark level */
- data[5] = 0; /* reg 98, don't care */
- } else { /* auto dark-gain */
- data[1] = 0; /* reg 94, Y Gain (auto) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- switch (gspca_dev->width) {
-/* case 1280: */
-/* data[4] = 154;
- * reg 97, %3 shadow point (unit: 256 pixel) */
-/* data[5] = 51;
- * reg 98, %1 highlight point
- * (uint: 256 pixel) */
-/* break; */
- default:
-/* case 640: */
- data[4] = 36; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 12; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- case 320:
- data[4] = 9; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 3; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- }
- }
/* auto dark-gain */
data[0] = 0x5e; /* address */
-
- err_code = reg_w(gspca_dev, data[0], 6);
+ data[1] = 0; /* reg 94, Y Gain (auto) */
+/*jfm: from win trace*/
+ val = sd->colors * 0x40 + 0x400;
+ data[2] = val; /* reg 0x5f/0x60 (LE) = saturation */
+ data[3] = val >> 8;
+ data[4] = sd->brightness; /* reg 0x61 = brightness */
+ data[5] = 0x00;
+
+ err_code = reg_w(gspca_dev, 6);
if (err_code < 0)
return err_code;
data[0] = 0x67;
- data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
- err_code = reg_w(gspca_dev, data[0], 2);
+/*jfm: from win trace*/
+ data[1] = sd->sharpness * 4 + 3;
+ data[2] = 0x14;
+ err_code = reg_w(gspca_dev, 3);
if (err_code < 0)
return err_code;
- /*
- * initialize the value of MI sensor...
- */
- MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
- MI_buf[REG_HW_MI_1] = 0x000a;
- MI_buf[REG_HW_MI_2] = 0x000c;
- MI_buf[REG_HW_MI_3] = 0x0405;
- MI_buf[REG_HW_MI_4] = 0x0507;
- /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */
- MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */
- MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */
- /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */
- MI_buf[REG_HW_MI_7] = 0x0002;
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */
- MI_buf[REG_HW_MI_9] = 0x0374;
- MI_buf[REG_HW_MI_B] = 0x0000;
- MI_buf[REG_HW_MI_C] = 0x0000;
- MI_buf[REG_HW_MI_D] = 0x0000;
- MI_buf[REG_HW_MI_1E] = 0x8000;
-/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */
- MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */
- MI_buf[REG_HW_MI_2B] = 0x0008;
-/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */
- MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */
- MI_buf[REG_HW_MI_2D] = 0x0008;
- MI_buf[REG_HW_MI_2E] = 0x0008;
- MI_buf[REG_HW_MI_35] = 0x0051;
- MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */
- MI_buf[REG_HW_MI_60] = 0x0000;
- MI_buf[REG_HW_MI_61] = 0x0000;
- MI_buf[REG_HW_MI_62] = 0x0498;
- MI_buf[REG_HW_MI_63] = 0x0000;
- MI_buf[REG_HW_MI_64] = 0x0000;
- MI_buf[REG_HW_MI_F1] = 0x0001;
- /* changing while setting up the different value of dx/dy */
-
- if (gspca_dev->width != 1280) {
- MI_buf[0x01] = 0x010a;
- MI_buf[0x02] = 0x014c;
- MI_buf[0x03] = 0x01e5;
- MI_buf[0x04] = 0x0287;
- }
- MI_buf[0x20] = 0x1104;
-
- bulk_w(gspca_dev, MI_buf + 1, 1);
- bulk_w(gspca_dev, MI_buf + 2, 2);
- bulk_w(gspca_dev, MI_buf + 3, 3);
- bulk_w(gspca_dev, MI_buf + 4, 4);
- bulk_w(gspca_dev, MI_buf + 5, 5);
- bulk_w(gspca_dev, MI_buf + 6, 6);
- bulk_w(gspca_dev, MI_buf + 7, 7);
- bulk_w(gspca_dev, MI_buf + 9, 9);
- bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
- bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
- bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
- bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
- bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
- bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
- bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
- bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
- bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
- bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
- bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
- bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
- bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
- bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
- bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
- bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
- bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
- kfree(MI_buf);
-
- intpipe = usb_sndintpipe(gspca_dev->dev, 0);
- err_code = usb_clear_halt(gspca_dev->dev, intpipe);
+ data[0] = 0x69;
+ data[1] = 0x2f;
+ data[2] = 0x28;
+ data[3] = 0x42;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x63;
+ data[1] = 0x07;
+ err_code = reg_w(gspca_dev, 2);
+/*jfm: win trace - many writes here to reg 0x64*/
+ if (err_code < 0)
+ return err_code;
+
+ /* initialize the MI sensor */
+ for (i = 0; i < sizeof mi_data; i++)
+ mi_w(gspca_dev, i + 1, mi_data[i]);
data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */
- reg_w(gspca_dev, data[0], 2);
- return err_code;
+ reg_w(gspca_dev, 2);
+ return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -336,7 +296,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0] = 1;
gspca_dev->usb_buf[1] = 0;
- result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
+ result = reg_w(gspca_dev, 2);
if (result < 0)
PDEBUG(D_ERR, "Camera Stop failed");
}
@@ -346,7 +306,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- struct sd *sd = (struct sd *) gspca_dev;
int p;
if (len < 6) {
@@ -363,16 +322,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|| data[5 + p] == 0x65
|| data[5 + p] == 0x66
|| data[5 + p] == 0x67) {
- PDEBUG(D_PACK, "sof offset: %d leng: %d",
+ PDEBUG(D_PACK, "sof offset: %d len: %d",
p, len);
frame = gspca_frame_add(gspca_dev, LAST_PACKET,
- frame, data, 0);
+ frame, data, p);
/* put the JPEG header */
- jpeg_put_header(gspca_dev, frame,
- sd->qindex, 0x21);
- data += 16;
- len -= 16;
+ jpeg_put_header(gspca_dev, frame, 0x21);
+ data += p + 16;
+ len -= p + 16;
break;
}
}
@@ -380,6 +338,92 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x61;
+ gspca_dev->usb_buf[1] = val;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming) {
+ val = val * 0x40 + 0x400;
+ gspca_dev->usb_buf[0] = 0x5f;
+ gspca_dev->usb_buf[1] = val;
+ gspca_dev->usb_buf[2] = val >> 8;
+ reg_w(gspca_dev, 3);
+ }
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x06;
+ gspca_dev->usb_buf[1] = val * 0x40;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x67;
+ gspca_dev->usb_buf[1] = val * 4 + 3;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -421,8 +465,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
new file mode 100644
index 000000000000..5ec5ce6e3ed9
--- /dev/null
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -0,0 +1,378 @@
+/*
+ * Mars MR97310A library
+ *
+ * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * 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
+ */
+
+#define MODULE_NAME "mr97310a"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
+MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ u8 sof_read;
+ u8 header_read;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+ {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 3},
+ {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static int reg_w(struct gspca_dev *gspca_dev, int len)
+{
+ int rc;
+
+ rc = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf, len, NULL, 500);
+ if (rc < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], rc);
+ return rc;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ return 0;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
+
+ sd->sof_read = 0;
+
+ /* Note: register descriptions guessed from MR97113A driver */
+
+ data[0] = 0x01;
+ data[1] = 0x01;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x0d;
+ data[2] = 0x01;
+ data[5] = 0x2b;
+ data[7] = 0x00;
+ data[9] = 0x50; /* reg 8, no scale down */
+ data[10] = 0xc0;
+
+ switch (gspca_dev->width) {
+ case 160:
+ data[9] |= 0x0c; /* reg 8, 4:1 scale down */
+ /* fall thru */
+ case 320:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 640:
+ default:
+ data[3] = 0x50; /* reg 2, H size */
+ data[4] = 0x78; /* reg 3, V size */
+ data[6] = 0x04; /* reg 5, H start */
+ data[8] = 0x03; /* reg 7, V start */
+ break;
+
+ case 176:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 352:
+ data[3] = 0x2c; /* reg 2, H size */
+ data[4] = 0x48; /* reg 3, V size */
+ data[6] = 0x94; /* reg 5, H start */
+ data[8] = 0x63; /* reg 7, V start */
+ break;
+ }
+
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x0a;
+ data[1] = 0x80;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x14;
+ data[1] = 0x0a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1b;
+ data[1] = 0x00;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x15;
+ data[1] = 0x16;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x16;
+ data[1] = 0x10;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x17;
+ data[1] = 0x3a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x18;
+ data[1] = 0x68;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x02;
+ data[3] = 0x06;
+ data[4] = 0x59;
+ data[5] = 0x0c;
+ data[6] = 0x16;
+ data[7] = 0x00;
+ data[8] = 0x07;
+ data[9] = 0x00;
+ data[10] = 0x01;
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x0a;
+ data[3] = 0x00;
+ data[4] = 0x01;
+ data[5] = 0x00;
+ data[6] = 0x00;
+ data[7] = 0x01;
+ data[8] = 0x00;
+ data[9] = 0x0a;
+ err_code = reg_w(gspca_dev, 10);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x12;
+ data[3] = 0x00;
+ data[4] = 0x63;
+ data[5] = 0x00;
+ data[6] = 0x70;
+ data[7] = 0x00;
+ data[8] = 0x00;
+ err_code = reg_w(gspca_dev, 9);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x4d; /* ISOC transfering enable... */
+ err_code = reg_w(gspca_dev, 2);
+ return err_code;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ int result;
+
+ gspca_dev->usb_buf[0] = 1;
+ gspca_dev->usb_buf[1] = 0;
+ result = reg_w(gspca_dev, 2);
+ if (result < 0)
+ PDEBUG(D_ERR, "Camera Stop failed");
+}
+
+/* Include pac common sof detection functions */
+#include "pac_common.h"
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned char *sof;
+
+ sof = pac_find_sof(gspca_dev, data, len);
+ if (sof) {
+ int n;
+
+ /* finish decoding current frame */
+ n = sof - data;
+ if (n > sizeof pac_sof_marker)
+ n -= sizeof pac_sof_marker;
+ else
+ n = 0;
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, n);
+ sd->header_read = 0;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
+ len -= sof - data;
+ data = sof;
+ }
+ if (sd->header_read < 7) {
+ int needed;
+
+ /* skip the rest of the header */
+ needed = 7 - sd->header_read;
+ if (len <= needed) {
+ sd->header_read += len;
+ return;
+ }
+ data += needed;
+ len -= needed;
+ sd->header_read = 7;
+ }
+
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x08ca, 0x0111)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index ee232956c812..1fff37b79891 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1360,7 +1360,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = OV511_ENDPOINT_ADDRESS;
if (!sd->sif) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -2177,8 +2176,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 3bf15e401693..054bdf02c386 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -379,7 +379,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -556,8 +555,6 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */
- {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */
{USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */
{}
};
@@ -585,8 +582,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index c90ac852bac0..95a97ab684cd 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -256,7 +256,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
@@ -536,6 +535,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2470)},
{USB_DEVICE(0x093a, 0x2471)},
{USB_DEVICE(0x093a, 0x2472)},
+ {USB_DEVICE(0x093a, 0x2474)},
{USB_DEVICE(0x093a, 0x2476)},
{USB_DEVICE(0x145f, 0x013a)},
{USB_DEVICE(0x2001, 0xf115)},
@@ -565,8 +565,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index a9c95cba710e..e1e3a3a50484 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -498,7 +498,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAC7302) {
@@ -1097,8 +1096,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index b3e4e0677b68..153d0a91d4b5 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -870,7 +870,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
if (!(sensor_data[sd->sensor].flags & F_SIF)) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1272,8 +1271,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 3373b8d9d2a8..882d5e9b436a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -22,6 +22,7 @@
#define MODULE_NAME "sonixj"
#include "gspca.h"
+#define QUANT_VAL 4 /* quantization table */
#include "jpeg.h"
#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
@@ -35,36 +36,38 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
atomic_t avg_lum;
- unsigned int exposure;
-
- __u16 brightness;
- __u8 contrast;
- __u8 colors;
- __u8 autogain;
- __u8 blue;
- __u8 red;
- __u8 vflip; /* ov7630 only */
- __u8 infrared; /* mi0360 only */
-
- __s8 ag_cnt;
+ u32 exposure;
+
+ u16 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 blue;
+ u8 red;
+ u8 gamma;
+ u8 vflip; /* ov7630 only */
+ u8 infrared; /* mt9v111 only */
+
+ s8 ag_cnt;
#define AG_CNT_START 13
- __u8 qindex;
- __u8 bridge;
+ u8 bridge;
#define BRIDGE_SN9C102P 0
#define BRIDGE_SN9C105 1
#define BRIDGE_SN9C110 2
#define BRIDGE_SN9C120 3
#define BRIDGE_SN9C325 4
- __u8 sensor; /* Type of image sensor chip */
+ u8 sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
#define SENSOR_MO4000 2
-#define SENSOR_OM6802 3
-#define SENSOR_OV7630 4
-#define SENSOR_OV7648 5
-#define SENSOR_OV7660 6
- __u8 i2c_base;
+#define SENSOR_MT9V111 3
+#define SENSOR_OM6802 4
+#define SENSOR_OV7630 5
+#define SENSOR_OV7648 6
+#define SENSOR_OV7660 7
+#define SENSOR_SP80708 8
+ u8 i2c_base;
};
/* V4L2 controls supported by the driver */
@@ -78,6 +81,8 @@ static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -158,6 +163,20 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setred_balance,
.get = sd_getred_balance,
},
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 40,
+ .step = 1,
+#define GAMMA_DEF 20
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
#define AUTOGAIN_IDX 5
{
{
@@ -189,7 +208,7 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setvflip,
.get = sd_getvflip,
},
-/* mi0360 only */
+/* mt9v111 only */
#define INFRARED_IDX 7
{
{
@@ -211,18 +230,22 @@ static struct ctrl sd_ctrls[] = {
static __u32 ctrl_dis[] = {
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_HV7131R 0 */
- (1 << VFLIP_IDX),
+ (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MI0360 1 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MO4000 2 */
+ 0,
+ /* SENSOR_MT9V111 3 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OM6802 3 */
+ /* SENSOR_OM6802 4 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
- /* SENSOR_OV7630 4 */
+ /* SENSOR_OV7630 5 */
+ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
+ /* SENSOR_OV7648 6 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7648 5 */
+ /* SENSOR_OV7660 7 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7660 6 */
+ /* SENSOR_SP80708 8 */
};
static const struct v4l2_pix_format vga_mode[] = {
@@ -243,196 +266,228 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
-/*Data from sn9c102p+hv71331r */
-static const __u8 sn_hv7131[] = {
+/*Data from sn9c102p+hv7131r */
+static const u8 sn_hv7131[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0a, 0x00, 0x00, 0x00
};
-static const __u8 sn_mi0360[] = {
+static const u8 sn_mi0360[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
};
-static const __u8 sn_mo4000[] = {
+static const u8 sn_mo4000[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
+ 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x08, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_mt9v111[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
};
-static const __u8 sn_om6802[] = {
+static const u8 sn_om6802[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
- 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
- 0xf7
+/* reg18 reg19 reg1a reg1b */
+ 0x05, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7630[] = {
+static const u8 sn_ov7630[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7648[] = {
+static const u8 sn_ov7648[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7660[] = {
+static const u8 sn_ov7660[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_sp80708[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
};
/* sequence specific to the sensors - !! index = SENSOR_xxx */
-static const __u8 *sn_tb[] = {
+static const u8 *sn_tb[] = {
sn_hv7131,
sn_mi0360,
sn_mo4000,
+ sn_mt9v111,
sn_om6802,
sn_ov7630,
sn_ov7648,
- sn_ov7660
+ sn_ov7660,
+ sn_sp80708
};
-static const __u8 gamma_def[] = {
+/* default gamma table */
+static const u8 gamma_def[17] = {
0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
};
+/* gamma for sensors HV7131R and MT9V111 */
+static const u8 gamma_spec_1[17] = {
+ 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
+ 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
+};
+/* gamma for sensor SP80708 */
+static const u8 gamma_spec_2[17] = {
+ 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
+ 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
+};
/* color matrix and offsets */
-static const __u8 reg84[] = {
+static const u8 reg84[] = {
0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
0x00, 0x00, 0x00 /* YUV offsets */
};
-static const __u8 hv7131r_sensor_init[][8] = {
- {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
- {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
- {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+static const u8 hv7131r_sensor_init[][8] = {
+ {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
+/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+ {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
+/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
+ {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
{}
};
-static const __u8 mi0360_sensor_init[][8] = {
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
- {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
- {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
- {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
- {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
- {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
- {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
- {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
-
- {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
-
- {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
- {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
-
- {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
- {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+static const u8 mi0360_sensor_init[][8] = {
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+ {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
+ {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+ {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
+ {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+ {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
+ {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+ {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
+ {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+
+ {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
+
+ {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
+ {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+
+ {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
+ {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
{}
};
-static const __u8 mo4000_sensor_init[][8] = {
+static const u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -455,7 +510,49 @@ static const __u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
{}
};
-static __u8 om6802_sensor_init[][8] = {
+static const u8 mt9v111_sensor_init[][8] = {
+ {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
+ /* delay 20 ms */
+ {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
+ {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
+ {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
+ {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
+ {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
+ {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
+ {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
+ {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
+ {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
+ {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ /*******/
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
+ {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
+ {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
+ /*******/
+ {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
+ {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
+ {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
+ {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
+ {}
+};
+static const u8 om6802_sensor_init[][8] = {
{0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
@@ -489,7 +586,7 @@ static __u8 om6802_sensor_init[][8] = {
/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
{}
};
-static const __u8 ov7630_sensor_init[][8] = {
+static const u8 ov7630_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
/* win: delay 20ms */
@@ -543,7 +640,7 @@ static const __u8 ov7630_sensor_init[][8] = {
{}
};
-static const __u8 ov7648_sensor_init[][8] = {
+static const u8 ov7648_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -589,7 +686,7 @@ static const __u8 ov7648_sensor_init[][8] = {
{}
};
-static const __u8 ov7660_sensor_init[][8] = {
+static const u8 ov7660_sensor_init[][8] = {
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
/* (delay 20ms) */
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
@@ -678,28 +775,111 @@ static const __u8 ov7660_sensor_init[][8] = {
{}
};
-static const __u8 qtable4[] = {
- 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
- 0x06, 0x08, 0x0A, 0x11,
- 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
- 0x19, 0x19, 0x17, 0x15,
- 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
- 0x21, 0x2E, 0x21, 0x23,
- 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
- 0x25, 0x29, 0x2C, 0x29,
- 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
- 0x17, 0x1B, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29
+static const u8 sp80708_sensor_init[][8] = {
+ {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
+ /********/
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
+ {}
+};
+
+static const u8 qtable4[] = {
+ 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
+ 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
+ 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
+ 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
+ 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
+ 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
+ 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
+ 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
+ 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
+ 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
};
/* read <len> bytes to gspca_dev->usb_buf */
static void reg_r(struct gspca_dev *gspca_dev,
- __u16 value, int len)
+ u16 value, int len)
{
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -718,10 +898,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w1(struct gspca_dev *gspca_dev,
- __u16 value,
- __u8 data)
+ u16 value,
+ u8 data)
{
- PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
+ PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
gspca_dev->usb_buf[0] = data;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -733,11 +913,11 @@ static void reg_w1(struct gspca_dev *gspca_dev,
500);
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 value,
- const __u8 *buffer,
+ u16 value,
+ const u8 *buffer,
int len)
{
- PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
+ PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
value, buffer[0], buffer[1]);
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -756,7 +936,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
/* I2C write 1 byte */
-static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
+static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -781,7 +961,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
/* I2C write 8 bytes */
static void i2c_w8(struct gspca_dev *gspca_dev,
- const __u8 *buffer)
+ const u8 *buffer)
{
memcpy(gspca_dev->usb_buf, buffer, 8);
usb_control_msg(gspca_dev->dev,
@@ -795,10 +975,10 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
}
/* read 5 bytes in gspca_dev->usb_buf */
-static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
+static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 mode[8];
+ u8 mode[8];
mode[0] = 0x81 | 0x10;
mode[1] = sd->i2c_base;
@@ -817,7 +997,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
reg_r(gspca_dev, 0x0a, 5);
}
-static int probesensor(struct gspca_dev *gspca_dev)
+static int hv7131r_probe(struct gspca_dev *gspca_dev)
{
i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
msleep(10);
@@ -839,16 +1019,66 @@ static int probesensor(struct gspca_dev *gspca_dev)
return -ENODEV;
}
+static void mi0360_probe(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, j;
+ u16 val = 0;
+ static const u8 probe_tb[][4][8] = {
+ { /* mi0360 */
+ {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
+ },
+ { /* mt9v111 */
+ {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {}
+ },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
+ reg_w1(gspca_dev, 0x17, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x08);
+ for (j = 0; j < 3; j++)
+ i2c_w8(gspca_dev, probe_tb[i][j]);
+ msleep(2);
+ reg_r(gspca_dev, 0x0a, 5);
+ val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
+ if (probe_tb[i][3][0] != 0)
+ i2c_w8(gspca_dev, probe_tb[i][3]);
+ reg_w1(gspca_dev, 0x01, 0x29);
+ reg_w1(gspca_dev, 0x17, 0x42);
+ if (val != 0xffff)
+ break;
+ }
+ switch (val) {
+ case 0x823a:
+ PDEBUG(D_PROBE, "Sensor mt9v111");
+ sd->sensor = SENSOR_MT9V111;
+ sd->i2c_base = 0x5c;
+ break;
+ case 0x8243:
+ PDEBUG(D_PROBE, "Sensor mi0360");
+ break;
+ default:
+ PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
+ break;
+ }
+}
+
static int configure_gpio(struct gspca_dev *gspca_dev,
- const __u8 *sn9c1xx)
+ const u8 *sn9c1xx)
{
struct sd *sd = (struct sd *) gspca_dev;
- const __u8 *reg9a;
- static const __u8 reg9a_def[] =
+ const u8 *reg9a;
+ static const u8 reg9a_def[] =
{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
- static const __u8 reg9a_sn9c325[] =
+ static const u8 reg9a_sn9c325[] =
{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
- static const __u8 regd4[] = {0x60, 0x00, 0x00};
+ static const u8 regd4[] = {0x60, 0x00, 0x00};
reg_w1(gspca_dev, 0xf1, 0x00);
reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -872,6 +1102,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x01, 0x61);
+ reg_w1(gspca_dev, 0x17, 0x61);
+ reg_w1(gspca_dev, 0x01, 0x60);
+ reg_w1(gspca_dev, 0x01, 0x40);
+ break;
case SENSOR_OM6802:
reg_w1(gspca_dev, 0x02, 0x71);
reg_w1(gspca_dev, 0x01, 0x42);
@@ -900,12 +1136,20 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
break;
}
/* fall thru */
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x01, 0x63);
+ reg_w1(gspca_dev, 0x17, 0x20);
+ reg_w1(gspca_dev, 0x01, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x42);
+ mdelay(100);
+ reg_w1(gspca_dev, 0x02, 0x62);
+ break;
default:
reg_w1(gspca_dev, 0x01, 0x43);
reg_w1(gspca_dev, 0x17, 0x61);
reg_w1(gspca_dev, 0x01, 0x42);
if (sd->sensor == SENSOR_HV7131R) {
- if (probesensor(gspca_dev) < 0)
+ if (hv7131r_probe(gspca_dev) < 0)
return -ENODEV;
}
break;
@@ -916,7 +1160,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
- static const __u8 SetSensorClk[] = /* 0x08 Mclk */
+ static const u8 SetSensorClk[] = /* 0x08 Mclk */
{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
while (hv7131r_sensor_init[i][0]) {
@@ -946,6 +1190,19 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ msleep(20);
+ while (mt9v111_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ }
+}
+
static void om6802_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
@@ -1010,6 +1267,19 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
+ i++;
+ msleep(20);
+ while (sp80708_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]);
+ i++;
+ }
+}
+
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -1018,7 +1288,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1026,12 +1295,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info >> 8;
sd->i2c_base = id->driver_info;
- sd->qindex = 4; /* set the quantization table */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
sd->blue = BLUE_BALANCE_DEF;
sd->red = RED_BALANCE_DEF;
+ sd->gamma = GAMMA_DEF;
sd->autogain = AUTOGAIN_DEF;
sd->ag_cnt = -1;
sd->vflip = VFLIP_DEF;
@@ -1045,8 +1314,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 regGpio[] = { 0x29, 0x74 };
- __u8 regF1;
+ u8 regGpio[] = { 0x29, 0x74 };
+ u8 regF1;
/* setup a selector by bridge */
reg_w1(gspca_dev, 0xf1, 0x01);
@@ -1064,11 +1333,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
case BRIDGE_SN9C105:
if (regF1 != 0x11)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
case BRIDGE_SN9C120:
if (regF1 != 0x12)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
regGpio[1] = 0x70;
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
@@ -1086,20 +1359,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-static unsigned int setexposure(struct gspca_dev *gspca_dev,
- unsigned int expo)
+static u32 setexposure(struct gspca_dev *gspca_dev,
+ u32 expo)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 doit[] = /* update sensor */
- { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
- static const __u8 sensorgo[] = /* sensor on */
- { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
- static const __u8 gainMo[] =
- { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
switch (sd->sensor) {
case SENSOR_HV7131R: {
- __u8 Expodoit[] =
+ u8 Expodoit[] =
{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
Expodoit[3] = expo >> 16;
@@ -1109,8 +1376,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MI0360: {
- __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
+ u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+ static const u8 doit[] = /* update sensor */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
+ static const u8 sensorgo[] = /* sensor on */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
if (expo > 0x0635)
expo = 0x0635;
@@ -1124,10 +1395,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MO4000: {
- __u8 expoMof[] =
+ u8 expoMof[] =
{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 expoMo10[] =
+ u8 expoMo10[] =
{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+ static const u8 gainMo[] =
+ { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
if (expo > 0x1fff)
expo = 0x1fff;
@@ -1139,14 +1412,27 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
| ((expo & 0x0003) << 4);
i2c_w8(gspca_dev, expoMo10);
i2c_w8(gspca_dev, gainMo);
- PDEBUG(D_CONF, "set exposure %d",
+ PDEBUG(D_FRAM, "set exposure %d",
((expoMo10[3] & 0x07) << 10)
| (expoMof[3] << 2)
| ((expoMo10[3] & 0x30) >> 4));
break;
}
+ case SENSOR_MT9V111: {
+ u8 expo_c1[] =
+ { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
+
+ if (expo > 0x0280)
+ expo = 0x0280;
+ else if (expo < 0x0040)
+ expo = 0x0040;
+ expo_c1[3] = expo >> 8;
+ expo_c1[4] = expo;
+ i2c_w8(gspca_dev, expo_c1);
+ break;
+ }
case SENSOR_OM6802: {
- __u8 gainOm[] =
+ u8 gainOm[] =
{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
if (expo > 0x03ff)
@@ -1156,7 +1442,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
gainOm[3] = expo >> 2;
i2c_w8(gspca_dev, gainOm);
reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
- PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
+ PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
break;
}
}
@@ -1167,7 +1453,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int expo;
- __u8 k2;
+ u8 k2;
k2 = ((int) sd->brightness - 0x8000) >> 10;
switch (sd->sensor) {
@@ -1184,6 +1470,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
expo = sd->brightness >> 4;
sd->exposure = setexposure(gspca_dev, expo);
break;
+ case SENSOR_MT9V111:
+ expo = sd->brightness >> 8;
+ sd->exposure = setexposure(gspca_dev, expo);
+ break;
case SENSOR_OM6802:
expo = sd->brightness >> 6;
sd->exposure = setexposure(gspca_dev, expo);
@@ -1191,14 +1481,15 @@ static void setbrightness(struct gspca_dev *gspca_dev)
break;
}
- reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
+ if (sd->sensor != SENSOR_MT9V111)
+ reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
}
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 k2;
- __u8 contrast[6];
+ u8 k2;
+ u8 contrast[6];
k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
contrast[0] = (k2 + 1) / 2; /* red */
@@ -1214,8 +1505,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, v;
- __u8 reg8a[12]; /* U & V gains */
- static __s16 uv[6] = { /* same as reg84 in signed decimal */
+ u8 reg8a[12]; /* U & V gains */
+ static s16 uv[6] = { /* same as reg84 in signed decimal */
-24, -38, 64, /* UR UG UB */
62, -51, -9 /* VR VG VB */
};
@@ -1236,6 +1527,36 @@ static void setredblue(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x06, sd->blue);
}
+static void setgamma(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ u8 gamma[17];
+ const u8 *gamma_base;
+ static const u8 delta[17] = {
+ 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
+ 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
+ };
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ case SENSOR_MT9V111:
+ gamma_base = gamma_spec_1;
+ break;
+ case SENSOR_SP80708:
+ gamma_base = gamma_spec_2;
+ break;
+ default:
+ gamma_base = gamma_def;
+ break;
+ }
+
+ for (i = 0; i < sizeof gamma; i++)
+ gamma[i] = gamma_base[i]
+ + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
+ reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
+}
+
static void setautogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1267,13 +1588,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 reg1, reg17, reg18;
- const __u8 *sn9c1xx;
+ u8 reg1, reg17, reg18;
+ const u8 *sn9c1xx;
int mode;
- static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
- static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
- static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
- static const __u8 CE_ov76xx[] =
+ static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
+ static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
+ static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
+ static const u8 CE_ov76xx[] =
{ 0x32, 0xdd, 0x32, 0xdd };
sn9c1xx = sn_tb[(int) sd->sensor];
@@ -1292,6 +1613,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0xc9, 0x3c);
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg17 = 0xe0;
+ break;
case SENSOR_OV7630:
reg17 = 0xe2;
break;
@@ -1315,14 +1639,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
- reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
+
+ setgamma(gspca_dev);
+
for (i = 0; i < 8; i++)
reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x9a, 0x07);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7648:
reg_w1(gspca_dev, 0x9a, 0x0a);
reg_w1(gspca_dev, 0x99, 0x60);
break;
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x9a, 0x05);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7660:
if (sd->bridge == BRIDGE_SN9C120) {
reg_w1(gspca_dev, 0x9a, 0x05);
@@ -1358,6 +1692,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* reg1 = 0x06; * 640 clk 24Mz (done) */
}
break;
+ case SENSOR_MT9V111:
+ mt9v111_InitSensor(gspca_dev);
+ if (mode) {
+ reg1 = 0x04; /* 320 clk 48Mhz */
+ } else {
+/* reg1 = 0x06; * 640 clk 24Mz (done) */
+ reg17 = 0xc2;
+ }
+ break;
case SENSOR_OM6802:
om6802_InitSensor(gspca_dev);
reg17 = 0x64; /* 640 MCKSIZE */
@@ -1373,8 +1716,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg17 = 0x21;
/* reg1 = 0x42; * 42 - 46? */
break;
- default:
-/* case SENSOR_OV7660: */
+ case SENSOR_OV7660:
ov7660_InitSensor(gspca_dev);
if (sd->bridge == BRIDGE_SN9C120) {
if (mode) { /* 320x240 - 160x120 */
@@ -1387,6 +1729,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
* inverse power down */
}
break;
+ default:
+/* case SENSOR_SP80708: */
+ sp80708_InitSensor(gspca_dev);
+ if (mode) {
+/*?? reg1 = 0x04; * 320 clk 48Mhz */
+ } else {
+ reg1 = 0x46; /* 640 clk 48Mz */
+ reg17 = 0xa2;
+ }
+ break;
}
reg_w(gspca_dev, 0xc0, C0, 6);
reg_w(gspca_dev, 0xca, CA, 4);
@@ -1406,17 +1758,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg18 = sn9c1xx[0x18] | (mode << 4);
reg_w1(gspca_dev, 0x18, reg18 | 0x40);
- reg_w(gspca_dev, 0x100, qtable4, 0x40);
- reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
+ reg_w(gspca_dev, 0x0100, qtable4, 0x40);
+ reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
reg_w1(gspca_dev, 0x18, reg18);
reg_w1(gspca_dev, 0x17, reg17);
reg_w1(gspca_dev, 0x01, reg1);
switch (sd->sensor) {
- case SENSOR_MI0360:
- setinfrared(sd);
- break;
case SENSOR_OV7630:
setvflip(sd);
break;
@@ -1430,14 +1779,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 stophv7131[] =
+ static const u8 stophv7131[] =
{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopmi0360[] =
+ static const u8 stopmi0360[] =
{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopov7648[] =
+ static const u8 stopov7648[] =
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 data;
- const __u8 *sn9c1xx;
+ u8 data;
+ const u8 *sn9c1xx;
data = 0x0b;
switch (sd->sensor) {
@@ -1452,6 +1801,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
case SENSOR_OV7648:
i2c_w8(gspca_dev, stopov7648);
/* fall thru */
+ case SENSOR_MT9V111:
case SENSOR_OV7630:
data = 0x29;
break;
@@ -1473,8 +1823,8 @@ static void do_autogain(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int delta;
int expotimes;
- __u8 luma_mean = 130;
- __u8 luma_delta = 20;
+ u8 luma_mean = 130;
+ u8 luma_delta = 20;
/* Thanks S., without your advice, autobright should not work :) */
if (sd->ag_cnt < 0)
@@ -1499,6 +1849,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
default:
/* case SENSOR_MO4000: */
/* case SENSOR_MI0360: */
+/* case SENSOR_MT9V111: */
/* case SENSOR_OM6802: */
expotimes = sd->exposure;
expotimes += (luma_mean - delta) >> 6;
@@ -1516,7 +1867,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
/* This function is run at interrupt level. */
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1550,7 +1901,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (gspca_dev->last_packet_type == LAST_PACKET) {
/* put the JPEG 422 header */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
+ jpeg_put_header(gspca_dev, frame, 0x21);
}
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1645,6 +1996,24 @@ static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming)
+ setgamma(gspca_dev);
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1767,7 +2136,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
#endif
- {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
+ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1794,8 +2163,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 942f04cd44dd..f44613095d2e 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -22,6 +22,7 @@
#define MODULE_NAME "spca500"
#include "gspca.h"
+#define QUANT_VAL 5 /* quantization table */
#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -39,7 +40,6 @@ struct sd {
unsigned char contrast;
unsigned char colors;
- char qindex;
char subtype;
#define AgfaCl20 0
#define AiptekPocketDV 1
@@ -629,7 +629,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->subtype = id->driver_info;
if (sd->subtype != LogitechClickSmart310) {
cam->cam_mode = vga_mode;
@@ -638,7 +637,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 5;
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
@@ -713,7 +711,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
write_vector(gspca_dev, spca500_visual_defaults);
spca500_setmode(gspca_dev, xmult, ymult);
/* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ if (err < 0)
PDEBUG(D_ERR, "failed to enable drop packet");
reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev,
@@ -901,7 +900,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
+ jpeg_put_header(gspca_dev, frame, 0x22);
data += SPCA500_OFFSET_DATA;
len -= SPCA500_OFFSET_DATA;
@@ -937,16 +936,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
(__u8) (sd->brightness - 128));
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
- if (ret >= 0)
- sd->brightness = ret + 128;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -954,16 +943,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
- if (ret >= 0)
- sd->contrast = ret;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -971,16 +950,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
- if (ret >= 0)
- sd->colors = ret;
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -995,7 +964,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1014,7 +982,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1033,7 +1000,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -1093,8 +1059,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 82e3e3e2ada1..d48b27c648ca 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1883,10 +1883,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1897,10 +1893,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
sd->contrast & 0xff);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1908,10 +1900,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-}
-
static void setblue_balance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1934,7 +1922,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->subtype = id->driver_info;
@@ -2084,7 +2071,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -2103,7 +2089,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -2122,7 +2107,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -2211,8 +2195,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 2a33a29010ee..2acec58b1b97 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -31,9 +31,9 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
+ u8 brightness;
- char subtype;
+ u8 subtype;
#define IntelPCCameraPro 0
#define Nxultra 1
};
@@ -43,7 +43,6 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -52,7 +51,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 255,
.step = 1,
- .default_value = 127,
+#define BRIGHTNESS_DEF 127
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
@@ -64,12 +64,12 @@ static const struct v4l2_pix_format vga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 5},
+ .priv = 4},
{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 176,
.sizeimage = 176 * 144 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
+ .priv = 3},
{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 2,
@@ -93,6 +93,7 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_USB_CTRL 0x00 /* spca505 */
#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
+
#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */
#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
@@ -101,230 +102,230 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */
+/* Image format and compression control */
+#define SPCA50X_REG_COMPRESS 0x04
+
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505_init_data[][3] = {
- /* line bmRequest,value,index */
- /* 1819 */
+static const u8 spca505_init_data[][3] = {
+ /* bmRequest,value,index */
{SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
/* Sensor reset */
- /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
- /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
/* Block USB reset */
- /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL,
- SPCA50X_GLOBAL_MISC0},
+ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
- /* 1831 */ {0x5, 0x01, 0x10},
+ {0x05, 0x01, 0x10},
/* Maybe power down some stuff */
- /* 1834 */ {0x5, 0x0f, 0x11},
+ {0x05, 0x0f, 0x11},
/* Setup internal CCD ? */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
{}
};
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505_open_data_ccd[][3] = {
- /* line bmRequest,value,index */
+static const u8 spca505_open_data_ccd[][3] = {
+ /* bmRequest,value,index */
/* Internal CCD data set */
- /* 1891 */ {0x3, 0x04, 0x01},
+ {0x03, 0x04, 0x01},
/* This could be a reset */
- /* 1894 */ {0x3, 0x00, 0x01},
+ {0x03, 0x00, 0x01},
/* Setup compression and image registers. 0x6 and 0x7 seem to be
related to H&V hold, and are resolution mode specific */
- /* 1897 */ {0x4, 0x10, 0x01},
+ {0x04, 0x10, 0x01},
/* DIFF(0x50), was (0x10) */
- /* 1900 */ {0x4, 0x00, 0x04},
- /* 1903 */ {0x4, 0x00, 0x05},
- /* 1906 */ {0x4, 0x20, 0x06},
- /* 1909 */ {0x4, 0x20, 0x07},
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x20, 0x06},
+ {0x04, 0x20, 0x07},
- /* 1912 */ {0x8, 0x0a, 0x00},
+ {0x08, 0x0a, 0x00},
/* DIFF (0x4a), was (0xa) */
- /* 1915 */ {0x5, 0x00, 0x10},
- /* 1918 */ {0x5, 0x00, 0x11},
- /* 1921 */ {0x5, 0x00, 0x00},
+ {0x05, 0x00, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x00, 0x00},
/* DIFF not written */
- /* 1924 */ {0x5, 0x00, 0x01},
+ {0x05, 0x00, 0x01},
/* DIFF not written */
- /* 1927 */ {0x5, 0x00, 0x02},
+ {0x05, 0x00, 0x02},
/* DIFF not written */
- /* 1930 */ {0x5, 0x00, 0x03},
+ {0x05, 0x00, 0x03},
/* DIFF not written */
- /* 1933 */ {0x5, 0x00, 0x04},
+ {0x05, 0x00, 0x04},
/* DIFF not written */
- /* 1936 */ {0x5, 0x80, 0x05},
+ {0x05, 0x80, 0x05},
/* DIFF not written */
- /* 1939 */ {0x5, 0xe0, 0x06},
+ {0x05, 0xe0, 0x06},
/* DIFF not written */
- /* 1942 */ {0x5, 0x20, 0x07},
+ {0x05, 0x20, 0x07},
/* DIFF not written */
- /* 1945 */ {0x5, 0xa0, 0x08},
+ {0x05, 0xa0, 0x08},
/* DIFF not written */
- /* 1948 */ {0x5, 0x0, 0x12},
+ {0x05, 0x0, 0x12},
/* DIFF not written */
- /* 1951 */ {0x5, 0x02, 0x0f},
+ {0x05, 0x02, 0x0f},
/* DIFF not written */
- /* 1954 */ {0x5, 0x10, 0x46},
+ {0x05, 0x10, 0x46},
/* DIFF not written */
- /* 1957 */ {0x5, 0x8, 0x4a},
+ {0x05, 0x8, 0x4a},
/* DIFF not written */
- /* 1960 */ {0x3, 0x08, 0x03},
+ {0x03, 0x08, 0x03},
/* DIFF (0x3,0x28,0x3) */
- /* 1963 */ {0x3, 0x08, 0x01},
- /* 1966 */ {0x3, 0x0c, 0x03},
+ {0x03, 0x08, 0x01},
+ {0x03, 0x0c, 0x03},
/* DIFF not written */
- /* 1969 */ {0x3, 0x21, 0x00},
+ {0x03, 0x21, 0x00},
/* DIFF (0x39) */
/* Extra block copied from init to hopefully ensure CCD is in a sane state */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
/* End of extra block */
- /* 1972 */ {0x6, 0x3f, 0x1},
+ {0x06, 0x3f, 0x1},
/* Block skipped */
- /* 1975 */ {0x6, 0x10, 0x02},
- /* 1978 */ {0x6, 0x64, 0x07},
- /* 1981 */ {0x6, 0x10, 0x08},
- /* 1984 */ {0x6, 0x00, 0x09},
- /* 1987 */ {0x6, 0x00, 0x0a},
- /* 1990 */ {0x6, 0x00, 0x0b},
- /* 1993 */ {0x6, 0x10, 0x0c},
- /* 1996 */ {0x6, 0x00, 0x0d},
- /* 1999 */ {0x6, 0x00, 0x0e},
- /* 2002 */ {0x6, 0x00, 0x0f},
- /* 2005 */ {0x6, 0x10, 0x10},
- /* 2008 */ {0x6, 0x02, 0x11},
- /* 2011 */ {0x6, 0x00, 0x12},
- /* 2014 */ {0x6, 0x04, 0x13},
- /* 2017 */ {0x6, 0x02, 0x14},
- /* 2020 */ {0x6, 0x8a, 0x51},
- /* 2023 */ {0x6, 0x40, 0x52},
- /* 2026 */ {0x6, 0xb6, 0x53},
- /* 2029 */ {0x6, 0x3d, 0x54},
- /* 2032 */ {0x6, 0x60, 0x57},
- /* 2035 */ {0x6, 0x20, 0x58},
- /* 2038 */ {0x6, 0x15, 0x59},
- /* 2041 */ {0x6, 0x05, 0x5a},
-
- /* 2044 */ {0x5, 0x01, 0xc0},
- /* 2047 */ {0x5, 0x10, 0xcb},
- /* 2050 */ {0x5, 0x80, 0xc1},
+ {0x06, 0x10, 0x02},
+ {0x06, 0x64, 0x07},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
+ {0x06, 0x60, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x15, 0x59},
+ {0x06, 0x05, 0x5a},
+
+ {0x05, 0x01, 0xc0},
+ {0x05, 0x10, 0xcb},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2053 */ {0x5, 0x0, 0xc2},
+ {0x05, 0x0, 0xc2},
/* 4 was 0 */
- /* 2056 */ {0x5, 0x00, 0xca},
- /* 2059 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2062 */ {0x5, 0x04, 0xc2},
- /* 2065 */ {0x5, 0x00, 0xca},
- /* 2068 */ {0x5, 0x0, 0xc1},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x0, 0xc1},
/* */
- /* 2071 */ {0x5, 0x00, 0xc2},
- /* 2074 */ {0x5, 0x00, 0xca},
- /* 2077 */ {0x5, 0x40, 0xc1},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x40, 0xc1},
/* */
- /* 2080 */ {0x5, 0x17, 0xc2},
- /* 2083 */ {0x5, 0x00, 0xca},
- /* 2086 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x17, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2089 */ {0x5, 0x06, 0xc2},
- /* 2092 */ {0x5, 0x00, 0xca},
- /* 2095 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x06, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2098 */ {0x5, 0x04, 0xc2},
- /* 2101 */ {0x5, 0x00, 0xca},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2104 */ {0x3, 0x4c, 0x3},
- /* 2107 */ {0x3, 0x18, 0x1},
+ {0x03, 0x4c, 0x3},
+ {0x03, 0x18, 0x1},
- /* 2110 */ {0x6, 0x70, 0x51},
- /* 2113 */ {0x6, 0xbe, 0x53},
- /* 2116 */ {0x6, 0x71, 0x57},
- /* 2119 */ {0x6, 0x20, 0x58},
- /* 2122 */ {0x6, 0x05, 0x59},
- /* 2125 */ {0x6, 0x15, 0x5a},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
+ {0x06, 0x71, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x05, 0x59},
+ {0x06, 0x15, 0x5a},
- /* 2128 */ {0x4, 0x00, 0x08},
+ {0x04, 0x00, 0x08},
/* Compress = OFF (0x1 to turn on) */
- /* 2131 */ {0x4, 0x12, 0x09},
- /* 2134 */ {0x4, 0x21, 0x0a},
- /* 2137 */ {0x4, 0x10, 0x0b},
- /* 2140 */ {0x4, 0x21, 0x0c},
- /* 2143 */ {0x4, 0x05, 0x00},
+ {0x04, 0x12, 0x09},
+ {0x04, 0x21, 0x0a},
+ {0x04, 0x10, 0x0b},
+ {0x04, 0x21, 0x0c},
+ {0x04, 0x05, 0x00},
/* was 5 (Image Type ? ) */
- /* 2146 */ {0x4, 0x00, 0x01},
-
- /* 2149 */ {0x6, 0x3f, 0x01},
-
- /* 2152 */ {0x4, 0x00, 0x04},
- /* 2155 */ {0x4, 0x00, 0x05},
- /* 2158 */ {0x4, 0x40, 0x06},
- /* 2161 */ {0x4, 0x40, 0x07},
-
- /* 2164 */ {0x6, 0x1c, 0x17},
- /* 2167 */ {0x6, 0xe2, 0x19},
- /* 2170 */ {0x6, 0x1c, 0x1b},
- /* 2173 */ {0x6, 0xe2, 0x1d},
- /* 2176 */ {0x6, 0xaa, 0x1f},
- /* 2179 */ {0x6, 0x70, 0x20},
-
- /* 2182 */ {0x5, 0x01, 0x10},
- /* 2185 */ {0x5, 0x00, 0x11},
- /* 2188 */ {0x5, 0x01, 0x00},
- /* 2191 */ {0x5, 0x05, 0x01},
- /* 2194 */ {0x5, 0x00, 0xc1},
+ {0x04, 0x00, 0x01},
+
+ {0x06, 0x3f, 0x01},
+
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x40, 0x06},
+ {0x04, 0x40, 0x07},
+
+ {0x06, 0x1c, 0x17},
+ {0x06, 0xe2, 0x19},
+ {0x06, 0x1c, 0x1b},
+ {0x06, 0xe2, 0x1d},
+ {0x06, 0xaa, 0x1f},
+ {0x06, 0x70, 0x20},
+
+ {0x05, 0x01, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x01, 0x00},
+ {0x05, 0x05, 0x01},
+ {0x05, 0x00, 0xc1},
/* */
- /* 2197 */ {0x5, 0x00, 0xc2},
- /* 2200 */ {0x5, 0x00, 0xca},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2203 */ {0x6, 0x70, 0x51},
- /* 2206 */ {0x6, 0xbe, 0x53},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
{}
};
/*
- Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
+ * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
* SPCA505b chip based cameras initialization data
- *
*/
/* jfm */
#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */
@@ -332,7 +333,7 @@ static const __u16 spca505_open_data_ccd[][3] = {
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505b_init_data[][3] = {
+static const u8 spca505b_init_data[][3] = {
/* start */
{0x02, 0x00, 0x00}, /* init */
{0x02, 0x00, 0x01},
@@ -396,7 +397,7 @@ static const __u16 spca505b_init_data[][3] = {
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505b_open_data_ccd[][3] = {
+static const u8 spca505b_open_data_ccd[][3] = {
/* {0x02,0x00,0x00}, */
{0x03, 0x04, 0x01}, /* rst */
@@ -426,7 +427,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0x00, 0x12},
{0x05, 0x6f, 0x00},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x00, 0x02},
{0x05, 0x01, 0x03},
{0x05, 0x00, 0x04},
@@ -436,7 +437,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0xa0, 0x08},
{0x05, 0x00, 0x12},
{0x05, 0x02, 0x0f},
- {0x05, 128, 0x14}, /* max exposure off (0=on) */
+ {0x05, 0x80, 0x14}, /* max exposure off (0=on) */
{0x05, 0x01, 0xb0},
{0x05, 0x01, 0xbf},
{0x03, 0x02, 0x06},
@@ -560,26 +561,26 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x06, 0x32, 0x20},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x06, 0xc1},
{0x05, 0x58, 0xc2},
- {0x05, 0x0, 0xca},
- {0x05, 0x0, 0x11},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x00, 0x11},
{}
};
static int reg_write(struct usb_device *dev,
- __u16 reg, __u16 index, __u16 value)
+ u16 req, u16 index, u16 value)
{
int ret;
ret = usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
- reg,
+ req,
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x",
- reg, index, value, ret);
+ PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
+ req, index, value, ret);
if (ret < 0)
PDEBUG(D_ERR, "reg write: error %d", ret);
return ret;
@@ -587,42 +588,34 @@ static int reg_write(struct usb_device *dev,
/* returns: negative is error, pos or zero is data */
static int reg_read(struct gspca_dev *gspca_dev,
- __u16 reg, /* bRequest */
- __u16 index, /* wIndex */
- __u16 length) /* wLength (1 or 2 only) */
+ u16 req, /* bRequest */
+ u16 index) /* wIndex */
{
int ret;
- gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- reg,
+ req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- (__u16) 0, /* value */
- (__u16) index,
- gspca_dev->usb_buf, length,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, 2,
500); /* timeout */
- if (ret < 0) {
- PDEBUG(D_ERR, "reg_read err %d", ret);
- return -1;
- }
+ if (ret < 0)
+ return ret;
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u8 data[][3])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
- while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ while (data[i][0] != 0) {
ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
- if (ret < 0) {
- PDEBUG(D_ERR,
- "Register write failed for 0x%x,0x%x,0x%x",
- data[i][0], data[i][1], data[i][2]);
+ if (ret < 0)
return ret;
- }
i++;
}
return 0;
@@ -636,14 +629,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
sd->subtype = id->driver_info;
if (sd->subtype != IntelPCCameraPro)
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
else /* no 640x480 for IntelPCCameraPro */
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1;
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
+ sd->brightness = BRIGHTNESS_DEF;
if (sd->subtype == Nxultra) {
if (write_vector(gspca_dev, spca505b_init_data))
@@ -658,81 +650,71 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
struct sd *sd = (struct sd *) gspca_dev;
- int ret;
+ u8 brightness = sd->brightness;
+
+ reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6);
+ reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2);
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, mode;
+ static u8 mode_tb[][3] = {
+ /* r00 r06 r07 */
+ {0x00, 0x10, 0x10}, /* 640x480 */
+ {0x01, 0x1a, 0x1a}, /* 352x288 */
+ {0x02, 0x1c, 0x1d}, /* 320x240 */
+ {0x04, 0x34, 0x34}, /* 176x144 */
+ {0x05, 0x40, 0x40} /* 160x120 */
+ };
- PDEBUG(D_STREAM, "Initializing SPCA505");
if (sd->subtype == Nxultra)
write_vector(gspca_dev, spca505b_open_data_ccd);
else
write_vector(gspca_dev, spca505_open_data_ccd);
- ret = reg_read(gspca_dev, 6, 0x16, 2);
+ ret = reg_read(gspca_dev, 0x06, 0x16);
if (ret < 0) {
- PDEBUG(D_ERR|D_STREAM,
- "register read failed for after vector read err = %d",
+ PDEBUG(D_ERR|D_CONF,
+ "register read failed err: %d",
ret);
- return -EIO;
+ return ret;
}
- PDEBUG(D_STREAM,
- "After vector read returns : 0x%x should be 0x0101",
- ret & 0xffff);
-
- ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a);
- if (ret < 0) {
- PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d",
- ret);
- return -EIO;
+ if (ret != 0x0101) {
+ PDEBUG(D_ERR|D_CONF,
+ "After vector read returns 0x%04x should be 0x0101",
+ ret);
}
- reg_write(gspca_dev->dev, 5, 0xc2, 18);
- return 0;
-}
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
+ ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a);
+ if (ret < 0)
+ return ret;
+ reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12);
/* necessary because without it we can see stream
* only once after loading module */
/* stopping usb registers Tomasz change */
- reg_write(dev, 0x02, 0x0, 0x0);
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 0:
- reg_write(dev, 0x04, 0x00, 0x00);
- reg_write(dev, 0x04, 0x06, 0x10);
- reg_write(dev, 0x04, 0x07, 0x10);
- break;
- case 1:
- reg_write(dev, 0x04, 0x00, 0x01);
- reg_write(dev, 0x04, 0x06, 0x1a);
- reg_write(dev, 0x04, 0x07, 0x1a);
- break;
- case 2:
- reg_write(dev, 0x04, 0x00, 0x02);
- reg_write(dev, 0x04, 0x06, 0x1c);
- reg_write(dev, 0x04, 0x07, 0x1d);
- break;
- case 4:
- reg_write(dev, 0x04, 0x00, 0x04);
- reg_write(dev, 0x04, 0x06, 0x34);
- reg_write(dev, 0x04, 0x07, 0x34);
- break;
- default:
-/* case 5: */
- reg_write(dev, 0x04, 0x00, 0x05);
- reg_write(dev, 0x04, 0x06, 0x40);
- reg_write(dev, 0x04, 0x07, 0x40);
- break;
- }
-/* Enable ISO packet machine - should we do this here or in ISOC init ? */
+ reg_write(dev, 0x02, 0x00, 0x00);
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
+
ret = reg_write(dev, SPCA50X_REG_USB,
SPCA50X_USB_CTRL,
SPCA50X_CUSB_ENABLE);
-/* reg_write(dev, 0x5, 0x0, 0x0); */
-/* reg_write(dev, 0x5, 0x0, 0x1); */
-/* reg_write(dev, 0x5, 0x11, 0x2); */
+ setbrightness(gspca_dev);
+
return ret;
}
@@ -750,15 +732,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
/* This maybe reset or power control */
reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
- reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
- reg_write(gspca_dev->dev, 0x03, 0x00, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x10, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
+ reg_write(gspca_dev->dev, 0x03, 0x01, 0x00);
+ reg_write(gspca_dev->dev, 0x03, 0x00, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x10, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f);
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
switch (data[0]) {
@@ -771,7 +753,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, len);
break;
case 0xff: /* drop */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
break;
default:
data += 1;
@@ -782,24 +763,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
}
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- __u8 brightness = sd->brightness;
- reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6);
- reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2);
-
-}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = 255
- - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2)
- + (reg_read(gspca_dev, 5, 0x0, 1) << 6));
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -814,7 +777,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -863,8 +825,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 96e2512e0621..3a0c893f942d 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -193,24 +193,6 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
}
}
-static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg)
-{
- int retry = 60;
-
- reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
- reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
- reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002);
- while (--retry) {
- reg_r(gspca_dev, 0x07, 0x0003, 2);
- if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
- break;
- }
- if (retry == 0)
- return -1;
- reg_r(gspca_dev, 0x07, 0x0000, 1);
- return gspca_dev->usb_buf[0];
-}
-
static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
__u16 norme,
__u16 channel)
@@ -303,7 +285,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
@@ -596,13 +577,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright);
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -612,13 +586,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast);
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -628,13 +595,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation);
-}
-
static void sethue(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -644,13 +604,6 @@ static void sethue(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void gethue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -665,7 +618,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -684,7 +636,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -703,7 +654,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -722,7 +672,6 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- gethue(gspca_dev);
*val = sd->hue;
return 0;
}
@@ -772,8 +721,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index be5d740a315d..adacf8437661 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -101,8 +101,7 @@ static const struct v4l2_pix_format sif_mode[] = {
* Initialization data: this is the first set-up data written to the
* device (before the open data).
*/
-static const __u16 spca508_init_data[][3] =
-#define IGN(x) /* nothing */
+static const u16 spca508_init_data[][2] =
{
/* line URB value, index */
/* 44274 1804 */ {0x0000, 0x870b},
@@ -589,11 +588,10 @@ static const __u16 spca508_init_data[][3] =
{}
};
-
/*
* Initialization data for Intel EasyPC Camera CS110
*/
-static const __u16 spca508cs110_init_data[][3] = {
+static const u16 spca508cs110_init_data[][2] = {
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
{0x0000, 0x8111}, /* Normal operation on reset */
@@ -677,7 +675,7 @@ static const __u16 spca508cs110_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam_init_data[][3] = {
+static const u16 spca508_sightcam_init_data[][2] = {
/* This line seems to setup the frame/canvas */
/*368 */ {0x000f, 0x8402},
@@ -760,7 +758,7 @@ static const __u16 spca508_sightcam_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam2_init_data[][3] = {
+static const u16 spca508_sightcam2_init_data[][2] = {
/* 35 */ {0x0020, 0x8112},
/* 36 */ {0x000f, 0x8402},
@@ -1107,7 +1105,7 @@ static const __u16 spca508_sightcam2_init_data[][3] = {
/*
* Initialization data for Creative Webcam Vista
*/
-static const __u16 spca508_vista_init_data[][3] = {
+static const u16 spca508_vista_init_data[][2] = {
{0x0008, 0x8200}, /* Clear register */
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0020, 0x8112}, /* Video Drop packet enable */
@@ -1309,18 +1307,18 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0050, 0x8703},
{0x0002, 0x8704}, /* External input CKIx1 */
- {0x0001, 0x870C}, /* Select CKOx2 output */
- {0x009A, 0x8600}, /* Line memory Read Counter (L) */
+ {0x0001, 0x870c}, /* Select CKOx2 output */
+ {0x009a, 0x8600}, /* Line memory Read Counter (L) */
{0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
{0x0023, 0x8601},
{0x0010, 0x8602},
- {0x000A, 0x8603},
+ {0x000a, 0x8603},
{0x009A, 0x8600},
- {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */
- {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */
- {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */
- {0x0048, 0x865E}, /* Vertical valid lines window (L) */
- {0x0000, 0x865F},
+ {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
+ {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */
+ {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */
+ {0x0048, 0x865e}, /* Vertical valid lines window (L) */
+ {0x0000, 0x865f},
{0x0006, 0x8660},
/* Enable nibble data input, select nibble input order */
@@ -1328,63 +1326,63 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0013, 0x8608}, /* A11 Coeficients for color correction */
{0x0028, 0x8609},
/* Note: these values are confirmed at the end of array */
- {0x0005, 0x860A}, /* ... */
- {0x0025, 0x860B},
- {0x00E1, 0x860C},
- {0x00FA, 0x860D},
- {0x00F4, 0x860E},
- {0x00E8, 0x860F},
+ {0x0005, 0x860a}, /* ... */
+ {0x0025, 0x860b},
+ {0x00e1, 0x860c},
+ {0x00fa, 0x860D},
+ {0x00f4, 0x860e},
+ {0x00e8, 0x860f},
{0x0025, 0x8610}, /* A33 Coef. */
- {0x00FC, 0x8611}, /* White balance offset: R */
+ {0x00fc, 0x8611}, /* White balance offset: R */
{0x0001, 0x8612}, /* White balance offset: Gr */
- {0x00FE, 0x8613}, /* White balance offset: B */
+ {0x00fe, 0x8613}, /* White balance offset: B */
{0x0000, 0x8614}, /* White balance offset: Gb */
{0x0064, 0x8651}, /* R gain for white balance (L) */
{0x0040, 0x8652}, /* Gr gain for white balance (L) */
{0x0066, 0x8653}, /* B gain for white balance (L) */
{0x0040, 0x8654}, /* Gb gain for white balance (L) */
- {0x0001, 0x863F}, /* Enable fixed gamma correction */
+ {0x0001, 0x863f}, /* Enable fixed gamma correction */
- {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
+ {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
/* UV division: UV no change, Enable New edge enhancement */
{0x0018, 0x8657}, /* Edge gain high threshold */
{0x0020, 0x8658}, /* Edge gain low threshold */
{0x000A, 0x8659}, /* Edge bandwidth high threshold */
- {0x0005, 0x865A}, /* Edge bandwidth low threshold */
+ {0x0005, 0x865a}, /* Edge bandwidth low threshold */
{0x0064, 0x8607}, /* UV filter enable */
{0x0016, 0x8660},
- {0x0000, 0x86B0}, /* Bad pixels compensation address */
- {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */
- {0x0000, 0x86B2},
- {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */
- {0x0000, 0x86B4},
-
- {0x0001, 0x86B0},
- {0x00F5, 0x86B1},
- {0x0000, 0x86B2},
- {0x00C6, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0002, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D7, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0003, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0004, 0x86B0},
- {0x001D, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
- {0x001E, 0x8660},
+ {0x0000, 0x86b0}, /* Bad pixels compensation address */
+ {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */
+ {0x0000, 0x86b2},
+ {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */
+ {0x0000, 0x86b4},
+
+ {0x0001, 0x86b0},
+ {0x00f5, 0x86b1},
+ {0x0000, 0x86b2},
+ {0x00c6, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0002, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d7, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0003, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0004, 0x86b0},
+ {0x001d, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+ {0x001e, 0x8660},
/* READ { 0, 0x0000, 0x8608 } ->
0000: 13 */
@@ -1449,7 +1447,7 @@ static int reg_read(struct gspca_dev *gspca_dev,
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u16 data[][2])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
@@ -1487,7 +1485,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -1593,13 +1590,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, 0x8654, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = reg_read(gspca_dev, 0x8651);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1614,7 +1604,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1666,8 +1655,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 3c9288019e96..c99c5e34e211 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -141,38 +141,38 @@ static const struct v4l2_pix_format sif_072a_mode[] = {
#define SPCA561_OFFSET_WIN1GBAVE 14
#define SPCA561_OFFSET_FREQ 15
#define SPCA561_OFFSET_VSYNC 16
-#define SPCA561_OFFSET_DATA 1
#define SPCA561_INDEX_I2C_BASE 0x8800
#define SPCA561_SNAPBIT 0x20
#define SPCA561_SNAPCTRL 0x40
-static const __u16 rev72a_init_data1[][2] = {
+static const u16 rev72a_reset[][2] = {
{0x0000, 0x8114}, /* Software GPIO output data */
{0x0001, 0x8114}, /* Software GPIO output data */
{0x0000, 0x8112}, /* Some kind of reset */
+ {}
+};
+static const __u16 rev72a_init_data1[][2] = {
{0x0003, 0x8701}, /* PCLK clock delay adjustment */
{0x0001, 0x8703}, /* HSYNC from cmos inverted */
{0x0011, 0x8118}, /* Enable and conf sensor */
{0x0001, 0x8118}, /* Conf sensor */
{0x0092, 0x8804}, /* I know nothing about these */
{0x0010, 0x8802}, /* 0x88xx registers, so I won't */
- {0x000d, 0x8805}, /* sensor default setting */
{}
};
-static const __u16 rev72a_init_sensor1[][2] = {
- /* ms-win values */
- {0x0001, 0x0018}, /* 0x01 <- 0x0d */
- {0x0002, 0x0065}, /* 0x02 <- 0x18 */
- {0x0004, 0x0121}, /* 0x04 <- 0x0165 */
- {0x0005, 0x00aa}, /* 0x05 <- 0x21 */
- {0x0007, 0x0004}, /* 0x07 <- 0xaa */
- {0x0020, 0x1502}, /* 0x20 <- 0x1504 */
- {0x0039, 0x0010}, /* 0x39 <- 0x02 */
- {0x0035, 0x0049}, /* 0x35 <- 0x10 */
- {0x0009, 0x100b}, /* 0x09 <- 0x1049 */
- {0x0028, 0x000f}, /* 0x28 <- 0x0b */
- {0x003b, 0x003c}, /* 0x3b <- 0x0f */
- {0x003c, 0x0000}, /* 0x3c <- 0x00 */
+static const u16 rev72a_init_sensor1[][2] = {
+ {0x0001, 0x000d},
+ {0x0002, 0x0018},
+ {0x0004, 0x0165},
+ {0x0005, 0x0021},
+ {0x0007, 0x00aa},
+ {0x0020, 0x1504},
+ {0x0039, 0x0002},
+ {0x0035, 0x0010},
+ {0x0009, 0x1049},
+ {0x0028, 0x000b},
+ {0x003b, 0x000f},
+ {0x003c, 0x0000},
{}
};
static const __u16 rev72a_init_data2[][2] = {
@@ -190,15 +190,10 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
{0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
{0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */
- {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
- {0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0010, 0x8660}, /* Compensation memory stuff */
- {0x0018, 0x8660}, /* Compensation memory stuff */
-
- {0x0004, 0x8611}, /* R offset for white balance */
- {0x0004, 0x8612}, /* Gr offset for white balance */
- {0x0007, 0x8613}, /* B offset for white balance */
+/* from ms-win */
+ {0x0000, 0x8611}, /* R offset for white balance */
+ {0x00fd, 0x8612}, /* Gr offset for white balance */
+ {0x0003, 0x8613}, /* B offset for white balance */
{0x0000, 0x8614}, /* Gb offset for white balance */
/* from ms-win */
{0x0035, 0x8651}, /* R gain for white balance */
@@ -206,8 +201,8 @@ static const __u16 rev72a_init_data2[][2] = {
{0x005f, 0x8653}, /* B gain for white balance */
{0x0040, 0x8654}, /* Gb gain for white balance */
{0x0002, 0x8502}, /* Maximum average bit rate stuff */
-
{0x0011, 0x8802},
+
{0x0087, 0x8700}, /* Set master clock (96Mhz????) */
{0x0081, 0x8702}, /* Master clock output enable */
@@ -218,104 +213,15 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0003, 0x865c}, /* Vertical offset for valid lines */
{}
};
-static const __u16 rev72a_init_sensor2[][2] = {
- /* ms-win values */
- {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */
- {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */
- {0x0005, 0x002f}, /* 0x05 <- 0x2f */
- {0x0006, 0x0000}, /* 0x06 <- 0 */
- {0x000a, 0x0002}, /* 0x0a <- 2 */
- {0x0009, 0x1061}, /* 0x09 <- 0x1061 */
- {0x0035, 0x0014}, /* 0x35 <- 0x14 */
- {}
-};
-static const __u16 rev72a_init_data3[][2] = {
- {0x0030, 0x8112}, /* ISO and drop packet enable */
-/*fixme: should stop here*/
- {0x0000, 0x8112}, /* Some kind of reset ???? */
- {0x0009, 0x8118}, /* Enable sensor and set standby */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0001, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8112}, /* Some kind of reset ??? */
- {0x0003, 0x8701},
- {0x0001, 0x8703},
- {0x0011, 0x8118},
- {0x0001, 0x8118},
- /***************/
- {0x0092, 0x8804},
- {0x0010, 0x8802},
- {0x000d, 0x8805},
- {0x0001, 0x8801},
- {0x0000, 0x8800},
- {0x0018, 0x8805},
- {0x0002, 0x8801},
- {0x0000, 0x8800},
- {0x0065, 0x8805},
- {0x0004, 0x8801},
- {0x0001, 0x8800},
- {0x0021, 0x8805},
- {0x0005, 0x8801},
- {0x0000, 0x8800},
- {0x00aa, 0x8805},
- {0x0007, 0x8801}, /* mode 0xaa */
- {0x0000, 0x8800},
- {0x0004, 0x8805},
- {0x0020, 0x8801},
- {0x0015, 0x8800}, /* mode 0x0415 */
- {0x0002, 0x8805},
- {0x0039, 0x8801},
- {0x0000, 0x8800},
- {0x0010, 0x8805},
- {0x0035, 0x8801},
- {0x0000, 0x8800},
- {0x0049, 0x8805},
- {0x0009, 0x8801},
- {0x0010, 0x8800},
- {0x000b, 0x8805},
- {0x0028, 0x8801},
- {0x0000, 0x8800},
- {0x000f, 0x8805},
- {0x003b, 0x8801},
- {0x0000, 0x8800},
- {0x0000, 0x8805},
- {0x003c, 0x8801},
- {0x0000, 0x8800},
- {0x0002, 0x8502},
- {0x0039, 0x8801},
- {0x0000, 0x8805},
- {0x0000, 0x8800},
-
- {0x0087, 0x8700}, /* overwrite by start */
- {0x0081, 0x8702},
- {0x0000, 0x8500},
-/* {0x0010, 0x8500}, -- Previous line was this */
- {0x0002, 0x865b},
- {0x0003, 0x865c},
- /***************/
- {0x0003, 0x8801}, /* 0x121-> 289 */
- {0x0021, 0x8805},
- {0x0001, 0x8800},
- {0x0004, 0x8801}, /* 0x165 -> 357 */
- {0x0065, 0x8805},
- {0x0001, 0x8800},
- {0x0005, 0x8801}, /* 0x2f //blanking control colonne */
- {0x002f, 0x8805},
- {0x0000, 0x8800},
- {0x0006, 0x8801}, /* 0x00 //blanking mode row */
- {0x0000, 0x8805},
- {0x0000, 0x8800},
- {0x000a, 0x8801}, /* 0x01 //0x02 */
- {0x0001, 0x8805},
- {0x0000, 0x8800},
- {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock
+static const u16 rev72a_init_sensor2[][2] = {
+ {0x0003, 0x0121},
+ {0x0004, 0x0165},
+ {0x0005, 0x002f}, /* blanking control column */
+ {0x0006, 0x0000}, /* blanking mode row*/
+ {0x000a, 0x0002},
+ {0x0009, 0x1061}, /* setexposure times && pixel clock
* 0001 0 | 000 0110 0001 */
- {0x0061, 0x8805}, /* 61 31 */
- {0x0008, 0x8800}, /* 08 */
- {0x0035, 0x8801}, /* 0x14 - set gain general */
- {0x001f, 0x8805}, /* 0x14 */
- {0x0000, 0x8800},
- {0x000e, 0x8112}, /* white balance - was 30 */
+ {0x0035, 0x0014},
{}
};
@@ -460,6 +366,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
reg_r(gspca_dev, 0x8803, 1);
if (!gspca_dev->usb_buf[0])
return;
+ msleep(10);
} while (--retry);
}
@@ -479,6 +386,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
reg_r(gspca_dev, 0x8805, 1);
return ((int) value << 8) | gspca_dev->usb_buf[0];
}
+ msleep(10);
} while (--retry);
return -1;
}
@@ -541,7 +449,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
sd->chip_revision = id->driver_info;
@@ -572,11 +479,13 @@ static int sd_init_12a(struct gspca_dev *gspca_dev)
static int sd_init_72a(struct gspca_dev *gspca_dev)
{
PDEBUG(D_STREAM, "Chip revision: 072a");
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
write_vector(gspca_dev, rev72a_init_data1);
write_sensor_72a(gspca_dev, rev72a_init_sensor1);
write_vector(gspca_dev, rev72a_init_data2);
write_sensor_72a(gspca_dev, rev72a_init_sensor2);
- write_vector(gspca_dev, rev72a_init_data3);
+ reg_w_val(gspca_dev->dev, 0x8112, 0x30);
return 0;
}
@@ -731,11 +640,18 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
int Clck;
int mode;
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
+ write_vector(gspca_dev, rev72a_init_data1);
+ write_sensor_72a(gspca_dev, rev72a_init_sensor1);
+
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
switch (mode) {
default:
-/* case 0:
- case 1: */
+ case 0:
+ Clck = 0x27; /* ms-win 0x87 */
+ break;
+ case 1:
Clck = 0x25;
break;
case 2:
@@ -745,13 +661,14 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
Clck = 0x21;
break;
}
- reg_w_val(dev, 0x8500, mode); /* mode */
reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
- reg_w_val(dev, 0x8112, 0x10 | 0x20);
+ reg_w_val(dev, 0x8702, 0x81);
+ reg_w_val(dev, 0x8500, mode); /* mode */
+ write_sensor_72a(gspca_dev, rev72a_init_sensor2);
setcontrast(gspca_dev);
/* setbrightness(gspca_dev); * fixme: bad values */
- setwhite(gspca_dev);
setautogain(gspca_dev);
+ reg_w_val(dev, 0x8112, 0x10 | 0x20);
return 0;
}
@@ -867,12 +784,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
- switch (data[0]) { /* sequence number */
+ len--;
+ switch (*data++) { /* sequence number */
case 0: /* start of frame */
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
- data += SPCA561_OFFSET_DATA;
- len -= SPCA561_OFFSET_DATA;
if (data[1] & 0x10) {
/* compressed bayer */
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -893,8 +809,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
case 0xff: /* drop (empty mpackets) */
return;
}
- data++;
- len--;
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1197,8 +1111,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 60de9af87fbb..d1d54edd80bd 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -21,6 +21,8 @@
#define MODULE_NAME "stk014"
#include "gspca.h"
+#define QUANT_VAL 7 /* quantization table */
+ /* <= 4 KO - 7: good (enough!) */
#include "jpeg.h"
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
@@ -37,9 +39,6 @@ struct sd {
unsigned char lightfreq;
};
-/* global parameters */
-static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */
-
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
@@ -180,7 +179,7 @@ static int rcv_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5);
ret = usb_bulk_msg(dev,
- usb_rcvbulkpipe(dev, 5),
+ usb_rcvbulkpipe(dev, 0x05),
gspca_dev->usb_buf,
4, /* length */
&alen,
@@ -294,9 +293,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
sd->brightness = BRIGHTNESS_DEF;
@@ -420,7 +417,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG 411 header */
- jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
+ jpeg_put_header(gspca_dev, frame, 0x22);
/* beginning of the frame */
#define STKHDRSZ 12
@@ -562,8 +559,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
@@ -575,6 +574,3 @@ static void __exit sd_mod_exit(void)
module_init(sd_mod_init);
module_exit(sd_mod_exit);
-
-module_param_named(quant, sd_quant, int, 0644);
-MODULE_PARM_DESC(quant, "Quantization index (0..8)");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 13a021e3cbb7..9dff2e65b116 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -429,7 +429,6 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Configuring camera");
cam = &gspca_dev->cam;
- cam->epaddr = STV_ISOC_ENDPOINT_ADDR;
sd->desc = sd_desc;
gspca_dev->sd_desc = &sd->desc;
@@ -501,8 +500,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index 14335a9e4bb5..b16903814203 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -30,6 +30,66 @@
#include "stv06xx_hdcs.h"
+static const struct ctrl hdcs1x00_ctrl[] = {
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0xffff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_EXPOSURE,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_exposure,
+ .get = hdcs_get_exposure
+ }, {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_GAIN,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_gain,
+ .get = hdcs_get_gain
+ }
+};
+
+static struct v4l2_pix_format hdcs1x00_mode[] = {
+ {
+ HDCS_1X00_DEF_WIDTH,
+ HDCS_1X00_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
+ .bytesperline = HDCS_1X00_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
+static const struct ctrl hdcs1020_ctrl[] = {};
+
+static struct v4l2_pix_format hdcs1020_mode[] = {
+ {
+ HDCS_1020_DEF_WIDTH,
+ HDCS_1020_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
+ .bytesperline = HDCS_1020_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
enum hdcs_power_state {
HDCS_STATE_SLEEP,
HDCS_STATE_IDLE,
@@ -353,10 +413,10 @@ static int hdcs_probe_1x00(struct sd *sd)
info("HDCS-1000/1100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
+ sd->desc.ctrls = hdcs1x00_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
@@ -412,10 +472,10 @@ static int hdcs_probe_1020(struct sd *sd)
info("HDCS-1020 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
+ sd->desc.ctrls = hdcs1020_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 9c7279a4cd88..412f06cf3d5c 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -152,53 +152,6 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
.stop = hdcs_stop,
.disconnect = hdcs_disconnect,
.dump = hdcs_dump,
-
- .nctrls = 2,
- .ctrls = {
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xffff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_EXPOSURE,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_exposure,
- .get = hdcs_get_exposure
- },
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_gain,
- .get = hdcs_get_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1X00_DEF_WIDTH,
- HDCS_1X00_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
- .bytesperline = HDCS_1X00_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
@@ -207,29 +160,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
- .nctrls = 0,
- .ctrls = {},
-
.init = hdcs_init,
.probe = hdcs_probe_1020,
.start = hdcs_start,
.stop = hdcs_stop,
.dump = hdcs_dump,
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1020_DEF_WIDTH,
- HDCS_1020_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
- .bytesperline = HDCS_1020_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
static const u16 stv_bridge_init[][2] = {
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index d0a0f8596454..285221e6b390 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -46,6 +46,132 @@
#include "stv06xx_pb0100.h"
+static const struct ctrl pb0100_ctrl[] = {
+#define GAIN_IDX 0
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_gain,
+ .get = pb0100_get_gain
+ },
+#define RED_BALANCE_IDX 1
+ {
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Red Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_red_balance,
+ .get = pb0100_get_red_balance
+ },
+#define BLUE_BALANCE_IDX 2
+ {
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Blue Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_blue_balance,
+ .get = pb0100_get_blue_balance
+ },
+#define EXPOSURE_IDX 3
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = 0,
+ .maximum = 511,
+ .step = 1,
+ .default_value = 12
+ },
+ .set = pb0100_set_exposure,
+ .get = pb0100_get_exposure
+ },
+#define AUTOGAIN_IDX 4
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Automatic Gain and Exposure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_autogain,
+ .get = pb0100_get_autogain
+ },
+#define AUTOGAIN_TARGET_IDX 5
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1000,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Automatic Gain Target",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_autogain_target,
+ .get = pb0100_get_autogain_target
+ },
+#define NATURAL_IDX 6
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1001,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Natural Light Source",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_natural,
+ .get = pb0100_get_natural
+ }
+};
+
+static struct v4l2_pix_format pb0100_mode[] = {
+/* low res / subsample modes disabled as they are only half res horizontal,
+ halving the vertical resolution does not seem to work */
+ {
+ 320,
+ 240,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 320 * 240,
+ .bytesperline = 320,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = PB0100_CROP_TO_VGA
+ },
+ {
+ 352,
+ 288,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 352 * 288,
+ .bytesperline = 352,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
static int pb0100_probe(struct sd *sd)
{
u16 sensor;
@@ -59,20 +185,19 @@ static int pb0100_probe(struct sd *sd)
if ((sensor >> 8) == 0x64) {
sensor_settings = kmalloc(
- stv06xx_sensor_pb0100.nctrls * sizeof(s32),
+ ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
GFP_KERNEL);
if (!sensor_settings)
return -ENOMEM;
info("Photobit pb0100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
- sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
- sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
- for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
- sensor_settings[i] = stv06xx_sensor_pb0100.
- ctrls[i].qctrl.default_value;
+ sd->gspca_dev.cam.cam_mode = pb0100_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
+ sd->desc.ctrls = pb0100_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
sd->sensor_priv = sensor_settings;
return 0;
@@ -143,6 +268,12 @@ out:
return (err < 0) ? err : 0;
}
+static void pb0100_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
/* FIXME: Sort the init commands out and put them into tables,
this is only for getting the camera to work */
/* FIXME: No error handling for now,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
index 5ea21a1154c4..4de4fa5ebc57 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -114,6 +114,7 @@ static int pb0100_start(struct sd *sd);
static int pb0100_init(struct sd *sd);
static int pb0100_stop(struct sd *sd);
static int pb0100_dump(struct sd *sd);
+static void pb0100_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -137,139 +138,12 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
.i2c_addr = 0xba,
.i2c_len = 2,
- .nctrls = 7,
- .ctrls = {
-#define GAIN_IDX 0
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_gain,
- .get = pb0100_get_gain
- },
-#define RED_BALANCE_IDX 1
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_red_balance,
- .get = pb0100_get_red_balance
- },
-#define BLUE_BALANCE_IDX 2
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_blue_balance,
- .get = pb0100_get_blue_balance
- },
-#define EXPOSURE_IDX 3
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 0,
- .maximum = 511,
- .step = 1,
- .default_value = 12
- },
- .set = pb0100_set_exposure,
- .get = pb0100_get_exposure
- },
-#define AUTOGAIN_IDX 4
- {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Automatic Gain and Exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_autogain,
- .get = pb0100_get_autogain
- },
-#define AUTOGAIN_TARGET_IDX 5
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Automatic Gain Target",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_autogain_target,
- .get = pb0100_get_autogain_target
- },
-#define NATURAL_IDX 6
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1001,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Natural Light Source",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_natural,
- .get = pb0100_get_natural
- },
- },
-
.init = pb0100_init,
.probe = pb0100_probe,
.start = pb0100_start,
.stop = pb0100_stop,
.dump = pb0100_dump,
-
- .nmodes = 2,
- .modes = {
-/* low res / subsample modes disabled as they are only half res horizontal,
- halving the vertical resolution does not seem to work */
- {
- 320,
- 240,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 320 * 240,
- .bytesperline = 320,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = PB0100_CROP_TO_VGA
- },
- {
- 352,
- 288,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 352 * 288,
- .bytesperline = 352,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- }
+ .disconnect = pb0100_disconnect,
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index c726dacefa1f..e88c42f7d2f8 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -41,8 +41,6 @@ extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
-#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-
struct stv06xx_sensor {
/* Defines the name of a sensor */
char name[32];
@@ -81,12 +79,6 @@ struct stv06xx_sensor {
/* Instructs the sensor to dump all its contents */
int (*dump)(struct sd *sd);
-
- int nctrls;
- struct ctrl ctrls[STV06XX_MAX_CTRLS];
-
- char nmodes;
- struct v4l2_pix_format modes[];
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 1ca91f2a6dee..69c77c932fc0 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -29,26 +29,92 @@
#include "stv06xx_vv6410.h"
+static struct v4l2_pix_format vv6410_mode[] = {
+ {
+ 356,
+ 292,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 356 * 292,
+ .bytesperline = 356,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+static const struct ctrl vv6410_ctrl[] = {
+#define HFLIP_IDX 0
+ {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_hflip,
+ .get = vv6410_get_hflip
+ },
+#define VFLIP_IDX 1
+ {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_vflip,
+ .get = vv6410_get_vflip
+ },
+#define GAIN_IDX 2
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "analog gain",
+ .minimum = 0,
+ .maximum = 15,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_analog_gain,
+ .get = vv6410_get_analog_gain
+ }
+};
+
static int vv6410_probe(struct sd *sd)
{
u16 data;
- int err;
+ int err, i;
+ s32 *sensor_settings;
err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
-
if (err < 0)
return -ENODEV;
if (data == 0x19) {
info("vv6410 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes;
- sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls;
- sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls;
+ sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32),
+ GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
+ sd->gspca_dev.cam.cam_mode = vv6410_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode);
+ sd->desc.ctrls = vv6410_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl);
+
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
return 0;
}
-
return -ENODEV;
}
@@ -80,6 +146,12 @@ static int vv6410_init(struct sd *sd)
return (err < 0) ? err : 0;
}
+static void vv6410_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
static int vv6410_start(struct sd *sd)
{
int err;
@@ -156,17 +228,13 @@ static int vv6410_dump(struct sd *sd)
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_HFLIP) ? 1 : 0;
-
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -174,6 +242,9 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[HFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -191,17 +262,13 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_VFLIP) ? 1 : 0;
-
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -209,6 +276,9 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[VFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -226,24 +296,23 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data);
-
- *val = i2c_data & 0xf;
+ *val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read analog gain %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ sensor_settings[GAIN_IDX] = val;
PDEBUG(D_V4L2, "Set analog gain to %d", val);
err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 3ff8c4ea3362..95ac55891bd4 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -178,6 +178,7 @@ static int vv6410_start(struct sd *sd);
static int vv6410_init(struct sd *sd);
static int vv6410_stop(struct sd *sd);
static int vv6410_dump(struct sd *sd);
+static void vv6410_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -197,62 +198,7 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.start = vv6410_start,
.stop = vv6410_stop,
.dump = vv6410_dump,
-
- .nctrls = 3,
- .ctrls = {
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_hflip,
- .get = vv6410_get_hflip
- }, {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_vflip,
- .get = vv6410_get_vflip
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "analog gain",
- .minimum = 0,
- .maximum = 15,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_analog_gain,
- .get = vv6410_get_analog_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- 356,
- 292,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 356 * 292,
- .bytesperline = 356,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
- }
+ .disconnect = vv6410_disconnect,
};
/* If NULL, only single value to write, stored in len */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 6d904d5e4c74..9d08a66fe23d 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -22,6 +22,7 @@
#define MODULE_NAME "sunplus"
#include "gspca.h"
+#define QUANT_VAL 5 /* quantization table */
#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
@@ -40,7 +41,6 @@ struct sd {
unsigned char colors;
unsigned char autogain;
- char qindex;
char bridge;
#define BRIDGE_SPCA504 0
#define BRIDGE_SPCA504B 1
@@ -812,7 +812,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->bridge = id->driver_info >> 8;
sd->subtype = id->driver_info;
@@ -850,7 +849,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
break;
}
- sd->qindex = 5; /* set the quantization table */
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
@@ -1155,9 +1153,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ jpeg_put_header(gspca_dev, frame, 0x22);
}
/* add 0x00 after 0xff */
@@ -1198,26 +1194,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
}
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u16 brightness = 0;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
- break;
- case BRIDGE_SPCA536:
- brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
- break;
- }
- sd->brightness = ((brightness & 0xff) - 128) % 255;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1237,24 +1213,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
}
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
- break;
- case BRIDGE_SPCA536:
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
- break;
- }
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1274,24 +1232,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
}
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
- break;
- case BRIDGE_SPCA536:
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
- break;
- }
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1306,7 +1246,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1325,7 +1264,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1344,7 +1282,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -1465,8 +1402,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 6ee111a3cbd1..95c120a506d3 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -37,20 +37,21 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
- unsigned char contrast;
- unsigned char colors;
- unsigned char autogain;
- unsigned char gamma;
- unsigned char sharpness;
- unsigned char freq;
- unsigned char whitebalance;
- unsigned char mirror;
- unsigned char effect;
-
- __u8 sensor;
-#define SENSOR_TAS5130A 0
-#define SENSOR_OM6802 1
+ u8 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 gamma;
+ u8 sharpness;
+ u8 freq;
+ u8 whitebalance;
+ u8 mirror;
+ u8 effect;
+
+ u8 sensor;
+#define SENSOR_OM6802 0
+#define SENSOR_OTHER 1
+#define SENSOR_TAS5130A 2
};
/* V4L2 controls supported by the driver */
@@ -78,7 +79,6 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -87,12 +87,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 14,
.step = 1,
- .default_value = 8,
+#define BRIGHTNESS_DEF 8
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
{
{
.id = V4L2_CID_CONTRAST,
@@ -101,12 +101,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0d,
.step = 1,
- .default_value = 0x07,
+#define CONTRAST_DEF 0x07
+ .default_value = CONTRAST_DEF,
},
.set = sd_setcontrast,
.get = sd_getcontrast,
},
-#define SD_COLOR 2
{
{
.id = V4L2_CID_SATURATION,
@@ -115,7 +115,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0f,
.step = 1,
- .default_value = 0x05,
+#define COLORS_DEF 0x05
+ .default_value = COLORS_DEF,
},
.set = sd_setcolors,
.get = sd_getcolors,
@@ -135,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setgamma,
.get = sd_getgamma,
},
-#define SD_AUTOGAIN 4
{
{
.id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
@@ -146,12 +146,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0x01,
+#define AUTOGAIN_DEF 0x01
+ .default_value = AUTOGAIN_DEF,
},
.set = sd_setlowlight,
.get = sd_getlowlight,
},
-#define SD_MIRROR 5
{
{
.id = V4L2_CID_HFLIP,
@@ -160,12 +160,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define MIRROR_DEF 0
+ .default_value = MIRROR_DEF,
},
.set = sd_setflip,
.get = sd_getflip
},
-#define SD_LIGHTFREQ 6
{
{
.id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -174,12 +174,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 1, /* 1 -> 0x50, 2->0x60 */
.maximum = 2,
.step = 1,
- .default_value = 1,
+#define FREQ_DEF 1
+ .default_value = FREQ_DEF,
},
.set = sd_setfreq,
.get = sd_getfreq},
-#define SD_WHITE_BALANCE 7
{
{
.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
@@ -188,12 +188,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define WHITE_BALANCE_DEF 0
+ .default_value = WHITE_BALANCE_DEF,
},
.set = sd_setwhitebalance,
.get = sd_getwhitebalance
},
-#define SD_SHARPNESS 8 /* (aka definition on win) */
{
{
.id = V4L2_CID_SHARPNESS,
@@ -202,12 +202,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 15,
.step = 1,
- .default_value = 0x06,
+#define SHARPNESS_DEF 0x06
+ .default_value = SHARPNESS_DEF,
},
.set = sd_setsharpness,
.get = sd_getsharpness,
},
-#define SD_EFFECTS 9
{
{
.id = V4L2_CID_EFFECTS,
@@ -216,7 +216,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 4,
.step = 1,
- .default_value = 0,
+#define EFFECTS_DEF 0
+ .default_value = EFFECTS_DEF,
},
.set = sd_seteffect,
.get = sd_geteffect
@@ -263,28 +264,50 @@ static const struct v4l2_pix_format vga_mode_t16[] = {
/* sensor specific data */
struct additional_sensor_data {
- const __u8 data1[20];
- const __u8 data2[18];
- const __u8 data3[18];
- const __u8 data4[4];
- const __u8 data5[6];
- const __u8 stream[4];
+ const u8 data1[10];
+ const u8 data2[9];
+ const u8 data3[9];
+ const u8 data4[4];
+ const u8 data5[6];
+ const u8 stream[4];
};
-const static struct additional_sensor_data sensor_data[] = {
+static const struct additional_sensor_data sensor_data[] = {
+ { /* OM6802 */
+ .data1 =
+ {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
+ 0xb3, 0xfc},
+ .data2 =
+ {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
+ 0xff},
+ .data4 = /*Freq (50/60Hz). Splitted for test purpose */
+ {0x66, 0xca, 0xa8, 0xf0},
+ .data5 = /* this could be removed later */
+ {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x78},
+ },
+ { /* OTHER */
+ .data1 =
+ {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
+ 0xe8, 0xfc},
+ .data2 =
+ {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
+ 0xd9},
+ .data4 =
+ {0x66, 0x00, 0xa8, 0xa8},
+ .data5 =
+ {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x00},
+ },
{ /* TAS5130A */
.data1 =
- {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
- 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
- 0xd8, 0xc8, 0xd9, 0xfc},
+ {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
+ 0xc8, 0xfc},
.data2 =
- {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
- 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
- 0xe8, 0xe0},
- .data3 =
- {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
- 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
- 0xcf, 0xe0},
+ {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
+ 0xe0},
.data4 = /* Freq (50/60Hz). Splitted for test purpose */
{0x66, 0x00, 0xa8, 0xe8},
.data5 =
@@ -292,32 +315,12 @@ const static struct additional_sensor_data sensor_data[] = {
.stream =
{0x0b, 0x04, 0x0a, 0x40},
},
- { /* OM6802 */
- .data1 =
- {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
- 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
- 0xd8, 0xb3, 0xd9, 0xfc},
- .data2 =
- {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
- 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
- 0xe8, 0xff},
- .data3 =
- {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
- 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
- 0xcf, 0xff},
- .data4 = /*Freq (50/60Hz). Splitted for test purpose */
- {0x66, 0xca, 0xa8, 0xf0 },
- .data5 = /* this could be removed later */
- {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
- .stream =
- {0x0b, 0x04, 0x0a, 0x78},
- }
};
#define MAX_EFFECTS 7
/* easily done by soft, this table could be removed,
* i keep it here just in case */
-static const __u8 effects_table[MAX_EFFECTS][6] = {
+static const u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
@@ -327,90 +330,58 @@ static const __u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
};
-static const __u8 gamma_table[GAMMA_MAX][34] = {
- {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
- 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
- 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
- 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
- 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
- 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
- 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
- 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
- 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
- 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
- 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
- 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
- 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
- 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
- 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
- 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
- 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
- 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
- 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
- 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
- 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
- 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
- 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
- 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
- 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
- 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
- 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
- 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
- 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
- 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
- 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
- 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
- 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
- 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
- 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
- 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
- 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
- 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
- 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
- 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
- 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
- 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
- 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
- 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
- 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
- 0xa0, 0xff}
+static const u8 gamma_table[GAMMA_MAX][17] = {
+ {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
+ 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
+ 0xff},
+ {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
+ 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
+ 0xff},
+ {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
+ 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
+ 0xff},
+ {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
+ 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
+ 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
+ 0xff},
+ {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
+ 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
+ 0xff},
+ {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
+ 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
+ 0xff},
+ {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
+ 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
+ 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
+ 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
+ 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
+ 0xff},
+ {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */
+ 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
+ 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
+ 0xff},
+ {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
+ 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
+ 0xff},
+ {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
+ 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
+ 0xff},
+ {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
+ 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
+ 0xff}
};
-static const __u8 tas5130a_sensor_init[][8] = {
+static const u8 tas5130a_sensor_init[][8] = {
{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
@@ -418,11 +389,11 @@ static const __u8 tas5130a_sensor_init[][8] = {
{},
};
-static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
/* read 1 byte */
-static int reg_r(struct gspca_dev *gspca_dev,
- __u16 index)
+static u8 reg_r(struct gspca_dev *gspca_dev,
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -435,7 +406,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 index)
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -446,7 +417,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
static void reg_w_buf(struct gspca_dev *gspca_dev,
- const __u8 *buffer, __u16 len)
+ const u8 *buffer, u16 len)
{
if (len <= USB_BUF_SZ) {
memcpy(gspca_dev->usb_buf, buffer, len);
@@ -457,7 +428,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
0x01, 0,
gspca_dev->usb_buf, len, 500);
} else {
- __u8 *tmpbuf;
+ u8 *tmpbuf;
tmpbuf = kmalloc(len, GFP_KERNEL);
memcpy(tmpbuf, buffer, len);
@@ -471,14 +442,41 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
}
}
+/* write values to consecutive registers */
+static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
+ u8 reg,
+ const u8 *buffer, u16 len)
+{
+ int i;
+ u8 *p, *tmpbuf;
+
+ if (len * 2 <= USB_BUF_SZ)
+ p = tmpbuf = gspca_dev->usb_buf;
+ else
+ p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
+ i = len;
+ while (--i >= 0) {
+ *p++ = reg++;
+ *p++ = *buffer++;
+ }
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x01, 0,
+ tmpbuf, len * 2, 500);
+ if (len * 2 > USB_BUF_SZ)
+ kfree(tmpbuf);
+}
+
/* Reported as OM6802*/
static void om6802_sensor_init(struct gspca_dev *gspca_dev)
{
int i;
- const __u8 *p;
- __u8 byte;
- __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
- static const __u8 sensor_init[] = {
+ const u8 *p;
+ u8 byte;
+ u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
+ static const u8 sensor_init[] = {
0xdf, 0x6d,
0xdd, 0x18,
0x5a, 0xe0,
@@ -538,20 +536,20 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode_t16;
cam->nmodes = ARRAY_SIZE(vga_mode_t16);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
- sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLORS_DEF;
sd->gamma = GAMMA_DEF;
- sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
- sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
- sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
- sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
- sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
+ sd->autogain = AUTOGAIN_DEF;
+ sd->mirror = MIRROR_DEF;
+ sd->freq = FREQ_DEF;
+ sd->whitebalance = WHITE_BALANCE_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ sd->effect = EFFECTS_DEF;
return 0;
}
@@ -559,7 +557,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int brightness;
- __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+ u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
brightness = sd->brightness;
if (brightness < 7) {
@@ -576,7 +574,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int contrast = sd->contrast;
- __u16 reg_to_write;
+ u16 reg_to_write;
if (contrast < 7)
reg_to_write = 0x8ea9 - contrast * 0x200;
@@ -589,7 +587,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
reg_w(gspca_dev, reg_to_write);
@@ -600,14 +598,15 @@ static void setgamma(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
- reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+ reg_w_ixbuf(gspca_dev, 0x90,
+ gamma_table[sd->gamma], sizeof gamma_table[0]);
}
static void setwhitebalance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 white_balance[8] =
+ u8 white_balance[8] =
{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
if (sd->whitebalance)
@@ -619,7 +618,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
static void setsharpness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
@@ -635,18 +634,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
* to see the initial parameters.*/
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 byte, test_byte;
+ u16 sensor_id;
+ u8 test_byte = 0;
+ u16 reg80, reg8e;
- static const __u8 read_indexs[] =
+ static const u8 read_indexs[] =
{ 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
- 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
- static const __u8 n1[] =
+ 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
+ static const u8 n1[] =
{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
- static const __u8 n2[] =
+ static const u8 n2[] =
{0x08, 0x00};
- static const __u8 n3[] =
+ static const u8 n3[6] =
{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
- static const __u8 n4[] =
+ static const u8 n3_other[6] =
+ {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
+ static const u8 n4[] =
{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
@@ -656,40 +659,61 @@ static int sd_init(struct gspca_dev *gspca_dev)
0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
- static const __u8 nset9[4] =
- { 0x0b, 0x04, 0x0a, 0x78 };
- static const __u8 nset8[6] =
+ static const u8 n4_other[] =
+ {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
+ 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
+ 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
+ 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
+ 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
+ 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
+ 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
+ 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
+ static const u8 nset8[6] =
{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
+ static const u8 nset8_other[6] =
+ { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
+ static const u8 nset9[4] =
+ { 0x0b, 0x04, 0x0a, 0x78 };
+ static const u8 nset9_other[4] =
+ { 0x0b, 0x04, 0x0a, 0x00 };
- byte = reg_r(gspca_dev, 0x06);
- test_byte = reg_r(gspca_dev, 0x07);
- if (byte == 0x08 && test_byte == 0x07) {
- PDEBUG(D_CONF, "sensor om6802");
- sd->sensor = SENSOR_OM6802;
- } else if (byte == 0x08 && test_byte == 0x01) {
+ sensor_id = (reg_r(gspca_dev, 0x06) << 8)
+ | reg_r(gspca_dev, 0x07);
+ switch (sensor_id) {
+ case 0x0801:
PDEBUG(D_CONF, "sensor tas5130a");
sd->sensor = SENSOR_TAS5130A;
- } else {
- PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
- sd->sensor = SENSOR_TAS5130A;
+ break;
+ case 0x0803:
+ PDEBUG(D_CONF, "sensor om6802");
+ sd->sensor = SENSOR_OTHER;
+ break;
+ case 0x0807:
+ PDEBUG(D_CONF, "sensor om6802");
+ sd->sensor = SENSOR_OM6802;
+ break;
+ default:
+ PDEBUG(D_CONF, "unknown sensor %04x", sensor_id);
+ return -EINVAL;
}
- reg_w_buf(gspca_dev, n1, sizeof n1);
- test_byte = 0;
- i = 5;
- while (--i >= 0) {
- reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- test_byte = reg_r(gspca_dev, 0x0063);
- msleep(100);
- if (test_byte == 0x17)
- break; /* OK */
- }
- if (i < 0) {
- err("Bad sensor reset %02x", test_byte);
-/* return -EIO; */
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n1, sizeof n1);
+ i = 5;
+ while (--i >= 0) {
+ reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+ test_byte = reg_r(gspca_dev, 0x0063);
+ msleep(100);
+ if (test_byte == 0x17)
+ break; /* OK */
+ }
+ if (i < 0) {
+ err("Bad sensor reset %02x", test_byte);
+/* return -EIO; */
/*fixme: test - continue */
+ }
+ reg_w_buf(gspca_dev, n2, sizeof n2);
}
- reg_w_buf(gspca_dev, n2, sizeof n2);
i = 0;
while (read_indexs[i] != 0x00) {
@@ -699,21 +723,31 @@ static int sd_init(struct gspca_dev *gspca_dev)
i++;
}
- reg_w_buf(gspca_dev, n3, sizeof n3);
- reg_w_buf(gspca_dev, n4, sizeof n4);
- reg_r(gspca_dev, 0x0080);
- reg_w(gspca_dev, 0x2c80);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n3, sizeof n3);
+ reg_w_buf(gspca_dev, n4, sizeof n4);
+ reg_r(gspca_dev, 0x0080);
+ reg_w(gspca_dev, 0x2c80);
+ reg80 = 0x3880;
+ reg8e = 0x338e;
+ } else {
+ reg_w_buf(gspca_dev, n3_other, sizeof n3_other);
+ reg_w_buf(gspca_dev, n4_other, sizeof n4_other);
+ sd->gamma = 5;
+ reg80 = 0xac80;
+ reg8e = 0xb88e;
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x338e);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg8e);
setbrightness(gspca_dev);
setcontrast(gspca_dev);
@@ -730,16 +764,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
sizeof sensor_data[sd->sensor].data4);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
sizeof sensor_data[sd->sensor].data5);
- reg_w_buf(gspca_dev, nset8, sizeof nset8);
- reg_w_buf(gspca_dev, nset9, sizeof nset9);
-
- reg_w(gspca_dev, 0x2880);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, nset8, sizeof nset8);
+ reg_w_buf(gspca_dev, nset9, sizeof nset9);
+ reg_w(gspca_dev, 0x2880);
+ } else {
+ reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other);
+ reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other);
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
return 0;
@@ -748,7 +786,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 flipcmd[8] =
+ u8 flipcmd[8] =
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
if (sd->mirror)
@@ -778,7 +816,7 @@ static void seteffect(struct gspca_dev *gspca_dev)
static void setlightfreq(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
+ u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
if (sd->freq == 2) /* 60hz */
freq[1] = 0x00;
@@ -791,22 +829,22 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
static void poll_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 poll1[] =
+ static const u8 poll1[] =
{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
0x60, 0x14};
- static const __u8 poll2[] =
+ static const u8 poll2[] =
{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
- static const __u8 poll3[] =
+ static const u8 poll3[] =
{0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
- static const __u8 poll4[] =
+ static const u8 poll4[] =
{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
0xc2, 0x80, 0xc3, 0x10};
- if (sd->sensor != SENSOR_TAS5130A) {
+ if (sd->sensor == SENSOR_OM6802) {
PDEBUG(D_STREAM, "[Sensor requires polling]");
reg_w_buf(gspca_dev, poll1, sizeof poll1);
reg_w_buf(gspca_dev, poll2, sizeof poll2);
@@ -819,13 +857,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, mode;
- __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
- static const __u8 t3[] =
- { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
- 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
+ u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
+ static const u8 t3[] =
+ { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
switch (mode) {
+ case 0: /* 640x480 (0x00) */
+ break;
case 1: /* 352x288 */
t2[1] = 0x40;
break;
@@ -835,14 +874,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
case 3: /* 176x144 */
t2[1] = 0x50;
break;
- case 4: /* 160x120 */
+ default:
+/* case 4: * 160x120 */
t2[1] = 0x20;
break;
- default: /* 640x480 (0x00) */
- break;
}
- if (sd->sensor == SENSOR_TAS5130A) {
+ switch (sd->sensor) {
+ case SENSOR_OM6802:
+ om6802_sensor_init(gspca_dev);
+ break;
+ case SENSOR_OTHER:
+ break;
+ default:
+/* case SENSOR_TAS5130A: */
i = 0;
while (tas5130a_sensor_init[i][0] != 0) {
reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
@@ -854,14 +899,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
sizeof tas5130a_sensor_init[0]);
reg_w(gspca_dev, 0x3c80);
- } else {
- om6802_sensor_init(gspca_dev);
+ break;
}
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
sizeof sensor_data[sd->sensor].data4);
reg_r(gspca_dev, 0x0012);
reg_w_buf(gspca_dev, t2, sizeof t2);
- reg_w_buf(gspca_dev, t3, sizeof t3);
+ reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
reg_w(gspca_dev, 0x0013);
msleep(15);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
@@ -885,16 +929,18 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
msleep(20);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
sizeof sensor_data[sd->sensor].stream);
- msleep(20);
- reg_w(gspca_dev, 0x0309);
+ if (sd->sensor != SENSOR_OTHER) {
+ msleep(20);
+ reg_w(gspca_dev, 0x0309);
+ }
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- static __u8 ffd9[] = { 0xff, 0xd9 };
+ static u8 ffd9[] = { 0xff, 0xd9 };
if (data[0] == 0x5a) {
/* Control Packet, after this came the header again,
@@ -1172,8 +1218,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 94163cceb28a..9f243d7e3110 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -31,7 +31,6 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
__u16 brightness;
- __u16 contrast;
__u8 packet;
};
@@ -39,38 +38,22 @@ struct sd {
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Brightness",
.minimum = 1,
- .maximum = 0x2ff,
+ .maximum = 0x15f, /* = 352 - 1 */
.step = 1,
- .default_value = 0x18f,
+#define BRIGHTNESS_DEF 0x14c
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 0xffff,
- .step = 1,
- .default_value = 0x7fff,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
};
static const struct v4l2_pix_format sif_mode[] = {
@@ -86,78 +69,64 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-/*
- * Initialization data: this is the first set-up data written to the
- * device (before the open data).
- */
-#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */
-#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */
-#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */
-#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */
-#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */
-#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */
-#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */
-#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */
-#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */
-#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */
-#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */
-#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */
-#define EXPOL 0x8f /* reg 0x1c -> 0x8f */
-#define EXPOH 0x01 /* reg 0x1d -> 0x01 */
-#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */
-#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */
-#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */
-#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */
-#define TV8532_CMD_UPDATE 0x84
-
-#define TV8532_EEprom_Add 0x03
-#define TV8532_EEprom_DataL 0x04
-#define TV8532_EEprom_DataM 0x05
-#define TV8532_EEprom_DataH 0x06
-#define TV8532_EEprom_TableLength 0x07
-#define TV8532_EEprom_Write 0x08
-#define TV8532_PART_CTRL 0x00
-#define TV8532_CTRL 0x01
-#define TV8532_CMD_EEprom_Open 0x30
-#define TV8532_CMD_EEprom_Close 0x29
-#define TV8532_UDP_UPDATE 0x31
-#define TV8532_GPIO 0x39
-#define TV8532_GPIO_OE 0x3B
-#define TV8532_REQ_RegWrite 0x02
-#define TV8532_REQ_RegRead 0x03
-
-#define TV8532_ADWIDTH_L 0x0C
-#define TV8532_ADWIDTH_H 0x0D
-#define TV8532_ADHEIGHT_L 0x0E
-#define TV8532_ADHEIGHT_H 0x0F
-#define TV8532_EXPOSURE 0x1C
-#define TV8532_QUANT_COMP 0x28
-#define TV8532_MODE_PACKET 0x29
-#define TV8532_SETCLK 0x2C
-#define TV8532_POINT_L 0x2D
-#define TV8532_POINT_H 0x2E
-#define TV8532_POINTB_L 0x2F
-#define TV8532_POINTB_H 0x30
-#define TV8532_BUDGET_L 0x2A
-#define TV8532_BUDGET_H 0x2B
-#define TV8532_VID_L 0x34
-#define TV8532_VID_H 0x35
-#define TV8532_PID_L 0x36
-#define TV8532_PID_H 0x37
-#define TV8532_DeviceID 0x83
-#define TV8532_AD_SLOPE 0x91
-#define TV8532_AD_BITCTRL 0x94
-#define TV8532_AD_COLBEGIN_L 0x10
-#define TV8532_AD_COLBEGIN_H 0x11
-#define TV8532_AD_ROWBEGIN_L 0x14
-#define TV8532_AD_ROWBEGIN_H 0x15
-
-static const __u32 tv_8532_eeprom_data[] = {
-/* add dataL dataM dataH */
- 0x00010001, 0x01018011, 0x02050014, 0x0305001c,
- 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b,
- 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9,
- 0x0c0509f1, 0
+/* TV-8532A (ICM532A) registers (LE) */
+#define R00_PART_CONTROL 0x00
+#define LATENT_CHANGE 0x80
+#define EXPO_CHANGE 0x04
+#define R01_TIMING_CONTROL_LOW 0x01
+#define CMD_EEprom_Open 0x30
+#define CMD_EEprom_Close 0x29
+#define R03_TABLE_ADDR 0x03
+#define R04_WTRAM_DATA_L 0x04
+#define R05_WTRAM_DATA_M 0x05
+#define R06_WTRAM_DATA_H 0x06
+#define R07_TABLE_LEN 0x07
+#define R08_RAM_WRITE_ACTION 0x08
+#define R0C_AD_WIDTHL 0x0c
+#define R0D_AD_WIDTHH 0x0d
+#define R0E_AD_HEIGHTL 0x0e
+#define R0F_AD_HEIGHTH 0x0f
+#define R10_AD_COL_BEGINL 0x10
+#define R11_AD_COL_BEGINH 0x11
+#define MIRROR 0x04 /* [10] */
+#define R14_AD_ROW_BEGINL 0x14
+#define R15_AD_ROWBEGINH 0x15
+#define R1C_AD_EXPOSE_TIMEL 0x1c
+#define R28_QUANT 0x28
+#define R29_LINE 0x29
+#define R2C_POLARITY 0x2c
+#define R2D_POINT 0x2d
+#define R2E_POINTH 0x2e
+#define R2F_POINTB 0x2f
+#define R30_POINTBH 0x30
+#define R31_UPD 0x31
+#define R2A_HIGH_BUDGET 0x2a
+#define R2B_LOW_BUDGET 0x2b
+#define R34_VID 0x34
+#define R35_VIDH 0x35
+#define R36_PID 0x36
+#define R37_PIDH 0x37
+#define R39_Test1 0x39 /* GPIO */
+#define R3B_Test3 0x3B /* GPIO */
+#define R83_AD_IDH 0x83
+#define R91_AD_SLOPEREG 0x91
+#define R94_AD_BITCONTROL 0x94
+
+static const u8 eeprom_data[][3] = {
+/* dataH dataM dataL */
+ {0x01, 0x00, 0x01},
+ {0x01, 0x80, 0x11},
+ {0x05, 0x00, 0x14},
+ {0x05, 0x00, 0x1c},
+ {0x0d, 0x00, 0x1e},
+ {0x05, 0x00, 0x1f},
+ {0x05, 0x05, 0x19},
+ {0x05, 0x01, 0x1b},
+ {0x05, 0x09, 0x1e},
+ {0x0d, 0x89, 0x2e},
+ {0x05, 0x89, 0x2f},
+ {0x05, 0x0d, 0xd9},
+ {0x05, 0x09, 0xf1},
};
static int reg_r(struct gspca_dev *gspca_dev,
@@ -165,7 +134,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegRead,
+ 0x03,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1,
@@ -174,27 +143,27 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
/* write 1 byte */
-static void reg_w_1(struct gspca_dev *gspca_dev,
+static void reg_w1(struct gspca_dev *gspca_dev,
__u16 index, __u8 value)
{
gspca_dev->usb_buf[0] = value;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1, 500);
}
/* write 2 bytes */
-static void reg_w_2(struct gspca_dev *gspca_dev,
- __u16 index, __u8 val1, __u8 val2)
+static void reg_w2(struct gspca_dev *gspca_dev,
+ u16 index, u16 value)
{
- gspca_dev->usb_buf[0] = val1;
- gspca_dev->usb_buf[1] = val2;
+ gspca_dev->usb_buf[0] = value;
+ gspca_dev->usb_buf[1] = value >> 8;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 2, 500);
@@ -202,32 +171,18 @@ static void reg_w_2(struct gspca_dev *gspca_dev,
static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
{
- int i = 0;
- __u8 reg, data0, data1, data2;
-
- reg_w_1(gspca_dev, TV8532_GPIO, 0xb0);
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open);
-/* msleep(1); */
- while (tv_8532_eeprom_data[i]) {
- reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24;
- reg_w_1(gspca_dev, TV8532_EEprom_Add, reg);
- /* msleep(1); */
- data0 = (tv_8532_eeprom_data[i] & 0x000000ff);
- reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0);
- /* msleep(1); */
- data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8;
- reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1);
- /* msleep(1); */
- data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16;
- reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2);
- /* msleep(1); */
- reg_w_1(gspca_dev, TV8532_EEprom_Write, 0);
- /* msleep(10); */
- i++;
+ int i;
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open);
+ for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) {
+ reg_w1(gspca_dev, R03_TABLE_ADDR, i);
+ reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]);
+ reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]);
+ reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]);
+ reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0);
}
- reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i);
-/* msleep(1); */
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close);
+ reg_w1(gspca_dev, R07_TABLE_LEN, i);
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
msleep(10);
}
@@ -238,79 +193,76 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- tv_8532WriteEEprom(gspca_dev);
-
cam = &gspca_dev->cam;
- cam->epaddr = 1;
cam->cam_mode = sif_mode;
- cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ cam->nmodes = ARRAY_SIZE(sif_mode);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
return 0;
}
static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
{
- __u8 data;
-
- data = reg_r(gspca_dev, 0x0001);
- PDEBUG(D_USBI, "register 0x01-> %x", data);
- data = reg_r(gspca_dev, 0x0002);
- PDEBUG(D_USBI, "register 0x02-> %x", data);
- reg_r(gspca_dev, TV8532_ADWIDTH_L);
- reg_r(gspca_dev, TV8532_ADWIDTH_H);
- reg_r(gspca_dev, TV8532_QUANT_COMP);
- reg_r(gspca_dev, TV8532_MODE_PACKET);
- reg_r(gspca_dev, TV8532_SETCLK);
- reg_r(gspca_dev, TV8532_POINT_L);
- reg_r(gspca_dev, TV8532_POINT_H);
- reg_r(gspca_dev, TV8532_POINTB_L);
- reg_r(gspca_dev, TV8532_POINTB_H);
- reg_r(gspca_dev, TV8532_BUDGET_L);
- reg_r(gspca_dev, TV8532_BUDGET_H);
- reg_r(gspca_dev, TV8532_VID_L);
- reg_r(gspca_dev, TV8532_VID_H);
- reg_r(gspca_dev, TV8532_PID_L);
- reg_r(gspca_dev, TV8532_PID_H);
- reg_r(gspca_dev, TV8532_DeviceID);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_H);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H);
+ int i;
+ static u8 reg_tb[] = {
+ R0C_AD_WIDTHL,
+ R0D_AD_WIDTHH,
+ R28_QUANT,
+ R29_LINE,
+ R2C_POLARITY,
+ R2D_POINT,
+ R2E_POINTH,
+ R2F_POINTB,
+ R30_POINTBH,
+ R2A_HIGH_BUDGET,
+ R2B_LOW_BUDGET,
+ R34_VID,
+ R35_VIDH,
+ R36_PID,
+ R37_PIDH,
+ R83_AD_IDH,
+ R10_AD_COL_BEGINL,
+ R11_AD_COL_BEGINH,
+ R14_AD_ROW_BEGINL,
+ R15_AD_ROWBEGINH,
+ 0
+ };
+
+ i = 0;
+ do {
+ reg_r(gspca_dev, reg_tb[i]);
+ i++;
+ } while (reg_tb[i] != 0);
}
static void tv_8532_setReg(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
-
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
+
+ reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */
/******************************************************/
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L,
- ADRBEGINL); /* 0x14 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */
-
- reg_w_1(gspca_dev, TV8532_CTRL,
- TV8532_CMD_EEprom_Close); /* 0x01 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90);
+ reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02);
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
}
static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
@@ -319,54 +271,55 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
/* strange polling from tgc */
for (i = 0; i < 10; i++) {
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ reg_w1(gspca_dev, R00_PART_CONTROL,
+ LATENT_CHANGE | EXPO_CHANGE);
+ reg_w1(gspca_dev, R31_UPD, 0x01);
}
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ tv_8532WriteEEprom(gspca_dev);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,
- ADHEIGHH); /* 401d 0x0169; 0e */
- reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,
- EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8);
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/*******************************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* no compress - fixed Q - quant 0 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* 0x84; // CIF | 4 packet 0x29 */
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ /* 0x48; //0x08; 0x2c */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ /* 0x38; 0x2d */
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ /* 0x04; 0x2e */
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ /* 0x04; 0x2f */
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ /* 0x04; 0x30 */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x00<-0x84 */
/*************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
@@ -377,11 +330,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int brightness = sd->brightness;
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- brightness >> 8, brightness); /* 1c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x84 */
}
/* -- start the camera -- */
@@ -389,57 +341,50 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,
- ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */
-/* reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); * 350d 0x014c; 1c */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
setbrightness(gspca_dev);
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* 0x72 compressed mode 0x28 */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
/* 176x144 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x41);
+ /* CIF - 2 lines/packet */
} else {
/* 352x288 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* CIF - 2 lines/packet */
}
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
/************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
tv_8532_PollReg(gspca_dev);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
gspca_dev->empty_packet = 0; /* check the empty packets */
sd->packet = 0; /* ignore the first packets */
@@ -449,7 +394,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -473,9 +418,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* each packet contains:
* - header 2 bytes
- * - RG line
+ * - RGRG line
* - 4 bytes
- * - GB line
+ * - GBGB line
* - 4 bytes
*/
gspca_frame_add(gspca_dev, packet_type0,
@@ -484,10 +429,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
frame, data + gspca_dev->width + 6, gspca_dev->width);
}
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -506,24 +447,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -570,8 +493,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 0525ea51a6de..9f3d9f104e6e 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -149,6 +149,11 @@ static const struct v4l2_pix_format vc0323_mode[] = {
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 0},
+ {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi1310_soc only */
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
};
static const struct v4l2_pix_format svga_mode[] = {
@@ -400,92 +405,208 @@ static const __u8 mi0360_initQVGA_JPG[][4] = {
static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xb0, 0x03, 0x19, 0xcc},
{0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
{0xb3, 0x08, 0x01, 0xcc},
{0xb3, 0x09, 0x0c, 0xcc},
{0xb3, 0x34, 0x02, 0xcc},
{0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
{0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
{0xb3, 0x20, 0x00, 0xcc},
{0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
{0xb3, 0x14, 0x00, 0xcc},
{0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
{0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
{0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb},
- {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb},
- {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb},
- {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb},
- {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb},
- {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb},
- {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
{0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb},
- {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb},
- {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb},
- {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb},
- {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb},
- {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc},
- {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
{0xb6, 0x00, 0x00, 0xcc},
{0xb6, 0x03, 0x02, 0xcc},
{0xb6, 0x02, 0x80, 0xcc},
{0xb6, 0x05, 0x01, 0xcc},
{0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x25, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
{0xb6, 0x18, 0x02, 0xcc},
{0xb6, 0x17, 0x58, 0xcc},
{0xb6, 0x16, 0x00, 0xcc},
{0xb6, 0x22, 0x12, 0xcc},
{0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
{0xbf, 0xc0, 0x39, 0xcc},
{0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {},
+};
+static const __u8 mi1310_socinitQVGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc},
+ {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc},
+ {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc},
+ {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
{0xbc, 0x02, 0x18, 0xcc},
{0xbc, 0x03, 0x50, 0xcc},
{0xbc, 0x04, 0x18, 0xcc},
@@ -496,131 +617,123 @@ static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xbc, 0x0a, 0x10, 0xcc},
{0xbc, 0x0b, 0x00, 0xcc},
{0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb},
- {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb},
- {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb},
- {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb},
- {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb},
- {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb},
- {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb},
- {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb},
- {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb},
- {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb},
- {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb},
- {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb},
- {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb},
- {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb},
- {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb},
- {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb},
- {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb},
- {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb},
- {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x34, 0x0c, 0x50, 0xbb},
{0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
{0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
{},
};
-static const __u8 mi1310_socinitQVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb},
- {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
- {0x03, 0x03, 0xc0, 0xbb},
- {},
+static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb8, 0x06, 0x00, 0xcc},
+ {0xb8, 0x07, 0x05, 0xcc},
+ {0xb8, 0x08, 0x00, 0xcc},
+ {0xb8, 0x09, 0x04, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x11, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc},
+ {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc},
+ {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc},
+ {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x14, 0xcc},
+ {0xb9, 0x14, 0x14, 0xcc},
+ {0xb9, 0x15, 0x14, 0xcc},
+ {0xb9, 0x16, 0x14, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x1e, 0xcc},
+ {0xb9, 0x1a, 0x1e, 0xcc},
+ {0xb9, 0x1b, 0x1e, 0xcc},
+ {0xb9, 0x1c, 0x1e, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {}
};
static const __u8 mi1320_gamma[17] = {
@@ -1814,44 +1927,40 @@ static void reg_w(struct usb_device *dev,
500);
}
-static void read_sensor_register(struct gspca_dev *gspca_dev,
- __u16 address, __u16 *value)
+static u16 read_sensor_register(struct gspca_dev *gspca_dev,
+ u16 address)
{
struct usb_device *dev = gspca_dev->dev;
__u8 ldata, mdata, hdata;
int retry = 50;
- *value = 0;
-
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
- /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */
if (!(gspca_dev->usb_buf[0] & 0x02)) {
- PDEBUG(D_ERR, "I2c Bus Busy Wait %d",
- gspca_dev->usb_buf[0] & 0x02);
- return;
+ PDEBUG(D_ERR, "I2c Bus Busy Wait %02x",
+ gspca_dev->usb_buf[0]);
+ return 0;
}
reg_w(dev, 0xa0, address, 0xb33a);
reg_w(dev, 0xa0, 0x02, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- while (retry-- && gspca_dev->usb_buf[0]) {
+ do {
+ msleep(8);
reg_r(gspca_dev, 0xa1, 0xb33b, 1);
-/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */
- msleep(1);
- }
+ } while (retry-- && gspca_dev->usb_buf[0]);
+
reg_r(gspca_dev, 0xa1, 0xb33e, 1);
ldata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33d, 1);
mdata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33c, 1);
hdata = gspca_dev->usb_buf[0];
- PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
- hdata, mdata, ldata);
+ if (hdata != 0 && mdata != 0 && ldata != 0)
+ PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
+ hdata, mdata, ldata);
reg_r(gspca_dev, 0xa1, 0xb334, 1);
if (gspca_dev->usb_buf[0] == 0x02)
- *value = (hdata << 8) + mdata;
- else
- *value = hdata;
+ return (hdata << 8) + mdata;
+ return hdata;
}
static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
@@ -1872,7 +1981,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
reg_w(dev, 0xa0, 0x0c, 0xb309);
reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
- read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
+ value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd);
if (value == ptsensor_info->VpId)
return ptsensor_info->sensorId;
@@ -1884,13 +1993,16 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
return -1;
}
-static __u8 i2c_write(struct gspca_dev *gspca_dev,
+static void i2c_write(struct gspca_dev *gspca_dev,
__u8 reg, const __u8 *val, __u8 size)
{
struct usb_device *dev = gspca_dev->dev;
+ int retry;
+#ifdef GSPCA_DEBUG
if (size > 3 || size < 1)
- return -EINVAL;
+ return;
+#endif
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
reg_w(dev, 0xa0, size, 0xb334);
reg_w(dev, 0xa0, reg, 0xb33a);
@@ -1902,18 +2014,23 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev,
reg_w(dev, 0xa0, val[0], 0xb336);
reg_w(dev, 0xa0, val[1], 0xb337);
break;
- case 3:
+ default:
+/* case 3: */
reg_w(dev, 0xa0, val[0], 0xb336);
reg_w(dev, 0xa0, val[1], 0xb337);
reg_w(dev, 0xa0, val[2], 0xb338);
break;
- default:
- reg_w(dev, 0xa0, 0x01, 0xb334);
- return -EINVAL;
}
reg_w(dev, 0xa0, 0x01, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- return gspca_dev->usb_buf[0] == 0;
+ retry = 4;
+ do {
+ reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+ if (gspca_dev->usb_buf[0] == 0)
+ break;
+ msleep(20);
+ } while (--retry > 0);
+ if (retry <= 0)
+ PDEBUG(D_ERR, "i2c_write failed");
}
static void put_tab_to_reg(struct gspca_dev *gspca_dev,
@@ -1938,7 +2055,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
return;
case 0xcc: /* normal write */
reg_w(dev, 0xa0, data[i][2],
- ((data[i][0])<<8) | data[i][1]);
+ (data[i][0]) << 8 | data[i][1]);
break;
case 0xaa: /* i2c op */
i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
@@ -1955,19 +2072,6 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
/*not reached*/
}
-/*
- "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff
- "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66
- */
-
-static void vc0321_reset(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301);
- msleep(100);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003);
- msleep(100);
-}
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
@@ -1979,10 +2083,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
sd->bridge = id->driver_info;
-
- vc0321_reset(gspca_dev);
sensor = vc032x_probe_sensor(gspca_dev);
switch (sensor) {
case -1:
@@ -2022,7 +2123,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
} else {
if (sensor != SENSOR_PO1200) {
cam->cam_mode = vc0323_mode;
- cam->nmodes = ARRAY_SIZE(vc0323_mode);
+ if (sd->sensor != SENSOR_MI1310_SOC)
+ cam->nmodes = ARRAY_SIZE(vc0323_mode);
+ else /* no SXGA */
+ cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1;
} else {
cam->cam_mode = svga_mode;
cam->nmodes = ARRAY_SIZE(svga_mode);
@@ -2061,7 +2165,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0;
}
-/* this function is called at probe and time */
+/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
return 0;
@@ -2124,6 +2228,7 @@ static void setsharpness(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ const __u8 (*init)[4];
const __u8 *GammaT = NULL;
const __u8 *MatrixT = NULL;
int mode;
@@ -2141,115 +2246,82 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_HV7131R:
GammaT = hv7131r_gamma;
MatrixT = hv7131r_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, hv7131r_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, hv7131r_initVGA_data);
- }
+ if (mode)
+ init = hv7131r_initQVGA_data; /* 320x240 */
+ else
+ init = hv7131r_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7660:
GammaT = ov7660_gamma;
MatrixT = ov7660_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7660_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7660_initVGA_data);
- }
+ if (mode)
+ init = ov7660_initQVGA_data; /* 320x240 */
+ else
+ init = ov7660_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7670:
/*GammaT = ov7660_gamma; */
/*MatrixT = ov7660_matrix; */
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7670_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7670_initVGA_JPG);
- }
+ if (mode)
+ init = ov7670_initQVGA_JPG; /* 320x240 */
+ else
+ init = ov7670_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI0360:
GammaT = mi1320_gamma;
MatrixT = mi0360_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi0360_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi0360_initVGA_JPG);
- }
+ if (mode)
+ init = mi0360_initQVGA_JPG; /* 320x240 */
+ else
+ init = mi0360_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI1310_SOC:
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1310_socinitVGA_JPG);
+ GammaT = mi1320_gamma;
+ MatrixT = mi0360_matrix;
+ switch (mode) {
+ case 1:
+ init = mi1310_socinitQVGA_JPG; /* 320x240 */
+ break;
+ case 0:
+ init = mi1310_socinitVGA_JPG; /* 640x480 */
+ break;
+ default:
+ init = mi1310_soc_InitSXGA_JPG; /* 1280xq024 */
+ break;
}
break;
case SENSOR_MI1320:
GammaT = mi1320_gamma;
MatrixT = mi1320_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1320_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1320_initVGA_data);
- }
+ if (mode)
+ init = mi1320_initQVGA_data; /* 320x240 */
+ else
+ init = mi1320_initVGA_data; /* 640x480 */
break;
case SENSOR_PO3130NC:
GammaT = po3130_gamma;
MatrixT = po3130_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, po3130_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, po3130_initVGA_data);
- }
- usb_exchange(gspca_dev, po3130_rundata);
+ if (mode)
+ init = po3130_initQVGA_data; /* 320x240 */
+ else
+ init = po3130_initVGA_data; /* 640x480 */
+ usb_exchange(gspca_dev, init);
+ init = po3130_rundata;
break;
- case SENSOR_PO1200:
+ default:
+/* case SENSOR_PO1200: */
GammaT = po1200_gamma;
MatrixT = po1200_matrix;
- usb_exchange(gspca_dev, po1200_initVGA_data);
+ init = po1200_initVGA_data;
break;
- default:
- PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
- return -EMEDIUMTYPE;
}
+ usb_exchange(gspca_dev, init);
if (GammaT && MatrixT) {
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
- /* Seem SHARPNESS */
- /*
- reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e);
- */
- /* all 0x40 ??? do nothing
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824);
- */
- /* Only works for HV7131R ??
- reg_r (gspca_dev, 0xa1, 0xb881, 1);
- reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881);
- reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801);
- */
- /* only hv7131r et ov7660
- reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80
- reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
- */
/* set the led on 0x0892 0x0896 */
if (sd->sensor != SENSOR_PO1200) {
reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
@@ -2399,7 +2471,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
strcpy((char *) menu->name, "50 Hz");
return 0;
- case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ default:
+/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
strcpy((char *) menu->name, "60 Hz");
return 0;
}
@@ -2424,6 +2497,7 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
@@ -2460,8 +2534,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index ec2a53d53fe2..e6a6cb946a21 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -31,6 +31,7 @@ MODULE_LICENSE("GPL");
static int force_sensor = -1;
+#define QUANT_VAL 1 /* quantization table */
#include "jpeg.h"
#include "zc3xx-reg.h"
@@ -45,28 +46,28 @@ struct sd {
__u8 lightfreq;
__u8 sharpness;
- char qindex;
signed char sensor; /* Type of image sensor chip */
/* !! values used in different tables */
-#define SENSOR_CS2102 0
-#define SENSOR_CS2102K 1
-#define SENSOR_GC0305 2
-#define SENSOR_HDCS2020b 3
-#define SENSOR_HV7131B 4
-#define SENSOR_HV7131C 5
-#define SENSOR_ICM105A 6
-#define SENSOR_MC501CB 7
-#define SENSOR_OV7620 8
-/*#define SENSOR_OV7648 8 - same values */
-#define SENSOR_OV7630C 9
-#define SENSOR_PAS106 10
-#define SENSOR_PAS202B 11
-#define SENSOR_PB0330 12
-#define SENSOR_PO2030 13
-#define SENSOR_TAS5130CK 14
-#define SENSOR_TAS5130CXX 15
-#define SENSOR_TAS5130C_VF0250 16
-#define SENSOR_MAX 17
+#define SENSOR_ADCM2700 0
+#define SENSOR_CS2102 1
+#define SENSOR_CS2102K 2
+#define SENSOR_GC0305 3
+#define SENSOR_HDCS2020b 4
+#define SENSOR_HV7131B 5
+#define SENSOR_HV7131C 6
+#define SENSOR_ICM105A 7
+#define SENSOR_MC501CB 8
+#define SENSOR_OV7620 9
+/*#define SENSOR_OV7648 9 - same values */
+#define SENSOR_OV7630C 10
+#define SENSOR_PAS106 11
+#define SENSOR_PAS202B 12
+#define SENSOR_PB0330 13
+#define SENSOR_PO2030 14
+#define SENSOR_TAS5130CK 15
+#define SENSOR_TAS5130CXX 16
+#define SENSOR_TAS5130C_VF0250 17
+#define SENSOR_MAX 18
unsigned short chip_revision;
};
@@ -206,6 +207,213 @@ struct usb_action {
__u16 idx;
};
+static const struct usb_action adcm2700_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+/*mswin+*/
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xfe, 0x0002},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xb4, 0xcd37},
+ {0xaa, 0xa4, 0x0004},
+ {0xaa, 0xa8, 0x0007},
+ {0xaa, 0xac, 0x0004},
+/*mswin-*/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+ /*******/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_50HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */
+ {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */
+ {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_60HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */
+ {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_NoFliker[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */
+ {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
static const struct usb_action cs2102_Initial[] = {
{0xa1, 0x01, 0x0008},
{0xa1, 0x01, 0x0008},
@@ -877,7 +1085,7 @@ static const struct usb_action cs2102K_Initial[] = {
};
static const struct usb_action cs2102K_InitialScale[] = {
- {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
{0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -894,6 +1102,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
{0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+/*fixme: next sequence = i2c exchanges*/
{0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
@@ -1077,207 +1286,6 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x60, ZC3XX_R116_RGAIN},
{0xa0, 0x40, ZC3XX_R117_GGAIN},
{0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x01, 0x01b1},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
@@ -1334,6 +1342,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+/*fixme:what does the next sequence?*/
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
@@ -6237,7 +6246,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
{}
};
-static int reg_r_i(struct gspca_dev *gspca_dev,
+static u8 reg_r_i(struct gspca_dev *gspca_dev,
__u16 index)
{
usb_control_msg(gspca_dev->dev,
@@ -6250,10 +6259,10 @@ static int reg_r_i(struct gspca_dev *gspca_dev,
return gspca_dev->usb_buf[0];
}
-static int reg_r(struct gspca_dev *gspca_dev,
+static u8 reg_r(struct gspca_dev *gspca_dev,
__u16 index)
{
- int ret;
+ u8 ret;
ret = reg_r_i(gspca_dev, index);
PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
@@ -6286,8 +6295,8 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
__u8 retbyte;
__u16 retval;
- reg_w_i(gspca_dev->dev, reg, 0x92);
- reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */
+ reg_w_i(gspca_dev->dev, reg, 0x0092);
+ reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
msleep(25);
retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
@@ -6332,6 +6341,12 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
action->idx & 0xff, /* valL */
action->idx >> 8); /* valH */
break;
+ case 0xbb:
+ i2c_write(gspca_dev,
+ action->idx >> 8, /* reg */
+ action->idx & 0xff, /* valL */
+ action->val); /* valH */
+ break;
default:
/* case 0xdd: * delay */
msleep(action->val / 64 + 10);
@@ -6347,6 +6362,10 @@ static void setmatrix(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int i;
const __u8 *matrix;
+ static const u8 adcm2700_matrix[9] =
+/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
+/*ms-win*/
+ {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
static const __u8 gc0305_matrix[9] =
{0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
static const __u8 ov7620_matrix[9] =
@@ -6358,23 +6377,24 @@ static void setmatrix(struct gspca_dev *gspca_dev)
static const __u8 vf0250_matrix[9] =
{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
static const __u8 *matrix_tb[SENSOR_MAX] = {
- NULL, /* SENSOR_CS2102 0 */
- NULL, /* SENSOR_CS2102K 1 */
- gc0305_matrix, /* SENSOR_GC0305 2 */
- NULL, /* SENSOR_HDCS2020b 3 */
- NULL, /* SENSOR_HV7131B 4 */
- NULL, /* SENSOR_HV7131C 5 */
- NULL, /* SENSOR_ICM105A 6 */
- NULL, /* SENSOR_MC501CB 7 */
- ov7620_matrix, /* SENSOR_OV7620 8 */
- NULL, /* SENSOR_OV7630C 9 */
- NULL, /* SENSOR_PAS106 10 */
- pas202b_matrix, /* SENSOR_PAS202B 11 */
- NULL, /* SENSOR_PB0330 12 */
- po2030_matrix, /* SENSOR_PO2030 13 */
- NULL, /* SENSOR_TAS5130CK 14 */
- NULL, /* SENSOR_TAS5130CXX 15 */
- vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */
+ adcm2700_matrix, /* SENSOR_ADCM2700 0 */
+ NULL, /* SENSOR_CS2102 1 */
+ NULL, /* SENSOR_CS2102K 2 */
+ gc0305_matrix, /* SENSOR_GC0305 3 */
+ NULL, /* SENSOR_HDCS2020b 4 */
+ NULL, /* SENSOR_HV7131B 5 */
+ NULL, /* SENSOR_HV7131C 6 */
+ NULL, /* SENSOR_ICM105A 7 */
+ NULL, /* SENSOR_MC501CB 8 */
+ ov7620_matrix, /* SENSOR_OV7620 9 */
+ NULL, /* SENSOR_OV7630C 10 */
+ NULL, /* SENSOR_PAS106 11 */
+ pas202b_matrix, /* SENSOR_PAS202B 12 */
+ NULL, /* SENSOR_PB0330 13 */
+ po2030_matrix, /* SENSOR_PO2030 14 */
+ NULL, /* SENSOR_TAS5130CK 15 */
+ NULL, /* SENSOR_TAS5130CXX 16 */
+ vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */
};
matrix = matrix_tb[sd->sensor];
@@ -6398,8 +6418,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/*fixme: is it really write to 011d and 018d for all other sensors? */
brightness = sd->brightness;
reg_w(gspca_dev->dev, brightness, 0x011d);
- if (sd->sensor == SENSOR_HV7131B)
+ switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ case SENSOR_HV7131B:
return;
+ }
if (brightness < 0x70)
brightness += 0x10;
else
@@ -6536,10 +6559,10 @@ static void setquality(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
- __u8 quality;
__u8 frxt;
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_OV7620:
@@ -6547,26 +6570,18 @@ static void setquality(struct gspca_dev *gspca_dev)
return;
}
/*fixme: is it really 0008 0007 0018 for all other sensors? */
- quality = sd->qindex;
- reg_w(dev, quality, 0x0008);
+ reg_w(dev, QUANT_VAL, 0x0008);
frxt = 0x30;
reg_w(dev, frxt, 0x0007);
- switch (quality) {
- case 0:
- case 1:
- case 2:
- frxt = 0xff;
- break;
- case 3:
- frxt = 0xf0;
- break;
- case 4:
- frxt = 0xe0;
- break;
- case 5:
- frxt = 0x20;
- break;
- }
+#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
+ frxt = 0xff;
+#elif QUANT_VAL == 3
+ frxt = 0xf0;
+#elif QUANT_VAL == 4
+ frxt = 0xe0;
+#else
+ frxt = 0x20;
+#endif
reg_w(dev, frxt, 0x0018);
}
@@ -6583,71 +6598,75 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
int i, mode;
const struct usb_action *zc3_freq;
static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
-/* SENSOR_CS2102 0 */
+/* SENSOR_ADCM2700 0 */
+ {adcm2700_NoFliker, adcm2700_NoFliker,
+ adcm2700_50HZ, adcm2700_50HZ,
+ adcm2700_60HZ, adcm2700_60HZ},
+/* SENSOR_CS2102 1 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
cs2102_50HZ, cs2102_50HZScale,
cs2102_60HZ, cs2102_60HZScale},
-/* SENSOR_CS2102K 1 */
+/* SENSOR_CS2102K 2 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
NULL, NULL, /* currently disabled */
NULL, NULL},
-/* SENSOR_GC0305 2 */
+/* SENSOR_GC0305 3 */
{gc0305_NoFliker, gc0305_NoFliker,
gc0305_50HZ, gc0305_50HZ,
gc0305_60HZ, gc0305_60HZ},
-/* SENSOR_HDCS2020b 3 */
+/* SENSOR_HDCS2020b 4 */
{hdcs2020b_NoFliker, hdcs2020b_NoFliker,
hdcs2020b_50HZ, hdcs2020b_50HZ,
hdcs2020b_60HZ, hdcs2020b_60HZ},
-/* SENSOR_HV7131B 4 */
+/* SENSOR_HV7131B 5 */
{hv7131b_NoFlikerScale, hv7131b_NoFliker,
hv7131b_50HZScale, hv7131b_50HZ,
hv7131b_60HZScale, hv7131b_60HZ},
-/* SENSOR_HV7131C 5 */
+/* SENSOR_HV7131C 6 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_ICM105A 6 */
+/* SENSOR_ICM105A 7 */
{icm105a_NoFliker, icm105a_NoFlikerScale,
icm105a_50HZ, icm105a_50HZScale,
icm105a_60HZ, icm105a_60HZScale},
-/* SENSOR_MC501CB 7 */
+/* SENSOR_MC501CB 8 */
{MC501CB_NoFliker, MC501CB_NoFlikerScale,
MC501CB_50HZ, MC501CB_50HZScale,
MC501CB_60HZ, MC501CB_60HZScale},
-/* SENSOR_OV7620 8 */
+/* SENSOR_OV7620 9 */
{OV7620_NoFliker, OV7620_NoFliker,
OV7620_50HZ, OV7620_50HZ,
OV7620_60HZ, OV7620_60HZ},
-/* SENSOR_OV7630C 9 */
+/* SENSOR_OV7630C 10 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_PAS106 10 */
+/* SENSOR_PAS106 11 */
{pas106b_NoFliker, pas106b_NoFliker,
pas106b_50HZ, pas106b_50HZ,
pas106b_60HZ, pas106b_60HZ},
-/* SENSOR_PAS202B 11 */
+/* SENSOR_PAS202B 12 */
{pas202b_NoFlikerScale, pas202b_NoFliker,
pas202b_50HZScale, pas202b_50HZ,
pas202b_60HZScale, pas202b_60HZ},
-/* SENSOR_PB0330 12 */
+/* SENSOR_PB0330 13 */
{pb0330_NoFliker, pb0330_NoFlikerScale,
pb0330_50HZ, pb0330_50HZScale,
pb0330_60HZ, pb0330_60HZScale},
-/* SENSOR_PO2030 13 */
+/* SENSOR_PO2030 14 */
{PO2030_NoFliker, PO2030_NoFliker,
PO2030_50HZ, PO2030_50HZ,
PO2030_60HZ, PO2030_60HZ},
-/* SENSOR_TAS5130CK 14 */
+/* SENSOR_TAS5130CK 15 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130CXX 15 */
+/* SENSOR_TAS5130CXX 16 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130C_VF0250 16 */
+/* SENSOR_TAS5130C_VF0250 17 */
{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6701,6 +6720,7 @@ static void send_unknown(struct usb_device *dev, int sensor)
reg_w(dev, 0x0c, 0x003b);
reg_w(dev, 0x08, 0x0038);
break;
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PB0330:
@@ -6743,26 +6763,25 @@ static int sif_probe(struct gspca_dev *gspca_dev)
static int vga_2wr_probe(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 retbyte;
- __u16 checkword;
+ u16 retword;
start_2wr_probe(dev, 0x00); /* HV7131B */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x00; /* HV7131B */
start_2wr_probe(dev, 0x04); /* CS2102 */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x04; /* CS2102 */
start_2wr_probe(dev, 0x06); /* OmniVision */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x11);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x11);
+ if (retword != 0) {
/* (should have returned 0xaa) --> Omnivision? */
/* reg_r 0x10 -> 0x06 --> */
goto ov_check;
@@ -6770,40 +6789,40 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
start_2wr_probe(dev, 0x08); /* HDCS2020 */
i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x08; /* HDCS2020 */
start_2wr_probe(dev, 0x0a); /* PB0330 */
i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
- retbyte = i2c_read(gspca_dev, 0x07);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x07);
+ if (retword != 0)
return 0x0a; /* PB0330 */
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
- retbyte = i2c_read(gspca_dev, 0x04);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x04);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
start_2wr_probe(dev, 0x0c); /* ICM105A */
i2c_write(gspca_dev, 0x01, 0x11, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x0c; /* ICM105A */
start_2wr_probe(dev, 0x0e); /* PAS202BCB */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
msleep(500);
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0e; /* PAS202BCB */
start_2wr_probe(dev, 0x02); /* ?? */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x02; /* ?? */
ov_check:
reg_r(gspca_dev, 0x0010); /* ?? */
@@ -6817,12 +6836,10 @@ ov_check:
msleep(500);
reg_w(dev, 0x01, 0x0012);
i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
- retbyte = i2c_read(gspca_dev, 0x0a);
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0b);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword);
- switch (checkword) {
+ retword = i2c_read(gspca_dev, 0x0a) << 8;
+ retword |= i2c_read(gspca_dev, 0x0b);
+ PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
+ switch (retword) {
case 0x7631: /* OV7630C */
reg_w(dev, 0x06, 0x0010);
break;
@@ -6832,7 +6849,7 @@ ov_check:
default:
return -1; /* not OmniVision */
}
- return checkword;
+ return retword;
}
struct sensor_by_chipset_revision {
@@ -6845,6 +6862,7 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
{0x8001, 0x13},
{0x8000, 0x14}, /* CS2102K */
{0x8400, 0x15}, /* TAS5130K */
+ {0x4001, 0x16}, /* ADCM2700 */
};
static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6853,7 +6871,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
struct usb_device *dev = gspca_dev->dev;
int i;
__u8 retbyte;
- __u16 checkword;
+ u16 retword;
/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
reg_w(dev, 0x02, 0x0010);
@@ -6865,27 +6883,25 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x14);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x14);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x16);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x16);
+ if (retword != 0)
return 0x11; /* HV7131R */
reg_w(dev, 0x02, 0x0010);
- retbyte = reg_r(gspca_dev, 0x000b);
- checkword = retbyte << 8;
- retbyte = reg_r(gspca_dev, 0x000a);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
+ retword = reg_r(gspca_dev, 0x000b) << 8;
+ retword |= reg_r(gspca_dev, 0x000a);
+ PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
reg_r(gspca_dev, 0x0010);
/* this is tested only once anyway */
for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
- if (chipset_revision_sensor[i].revision == checkword) {
- sd->chip_revision = checkword;
+ if (chipset_revision_sensor[i].revision == retword) {
+ sd->chip_revision = retword;
send_unknown(dev, SENSOR_PB0330);
return chipset_revision_sensor[i].internal_sensor_id;
}
@@ -6897,8 +6913,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x0a, 0x0010);
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
return 0x0a; /* ?? */
}
@@ -6910,14 +6926,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
msleep(2);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
- if (retbyte == 0x11) /* VF0250 */
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
+ if (retword == 0x0011) /* VF0250 */
return 0x0250;
- if (retbyte == 0x29) /* gc0305 */
+ if (retword == 0x0029) /* gc0305 */
send_unknown(dev, SENSOR_GC0305);
- return retbyte;
+ return retword;
}
reg_w(dev, 0x01, 0x0000); /* check OmniVision */
@@ -6927,8 +6943,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x06, 0x0010);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */
- && i2c_read(gspca_dev, 0x1d) == 0xa2) {
+ if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */
+ && i2c_read(gspca_dev, 0x1d) == 0x00a2) {
send_unknown(dev, SENSOR_OV7620);
return 0x06; /* OmniVision confirm ? */
}
@@ -6942,16 +6958,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
/* msleep(150); */
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
- if (checkword == 0x2030) {
+ retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
+ retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
+ PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
+ if (retword == 0x2030) {
retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
send_unknown(dev, SENSOR_PO2030);
- return checkword;
+ return retword;
}
reg_w(dev, 0x01, 0x0000);
@@ -6962,10 +6976,10 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0001);
reg_w(dev, 0xd3, 0x008b);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
- return 0x0a; /* ?? */
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
+ return retword;
}
return -1;
}
@@ -7009,23 +7023,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
int vga = 1; /* 1: vga, 0: sif */
static const __u8 gamma[SENSOR_MAX] = {
- 5, /* SENSOR_CS2102 0 */
- 5, /* SENSOR_CS2102K 1 */
- 4, /* SENSOR_GC0305 2 */
- 4, /* SENSOR_HDCS2020b 3 */
- 4, /* SENSOR_HV7131B 4 */
- 4, /* SENSOR_HV7131C 5 */
- 4, /* SENSOR_ICM105A 6 */
- 4, /* SENSOR_MC501CB 7 */
- 3, /* SENSOR_OV7620 8 */
- 4, /* SENSOR_OV7630C 9 */
- 4, /* SENSOR_PAS106 10 */
- 4, /* SENSOR_PAS202B 11 */
- 4, /* SENSOR_PB0330 12 */
- 4, /* SENSOR_PO2030 13 */
- 4, /* SENSOR_TAS5130CK 14 */
- 4, /* SENSOR_TAS5130CXX 15 */
- 3, /* SENSOR_TAS5130C_VF0250 16 */
+ 4, /* SENSOR_ADCM2700 0 */
+ 5, /* SENSOR_CS2102 1 */
+ 5, /* SENSOR_CS2102K 2 */
+ 4, /* SENSOR_GC0305 3 */
+ 4, /* SENSOR_HDCS2020b 4 */
+ 4, /* SENSOR_HV7131B 5 */
+ 4, /* SENSOR_HV7131C 6 */
+ 4, /* SENSOR_ICM105A 7 */
+ 4, /* SENSOR_MC501CB 8 */
+ 3, /* SENSOR_OV7620 9 */
+ 4, /* SENSOR_OV7630C 10 */
+ 4, /* SENSOR_PAS106 11 */
+ 4, /* SENSOR_PAS202B 12 */
+ 4, /* SENSOR_PB0330 13 */
+ 4, /* SENSOR_PO2030 14 */
+ 4, /* SENSOR_TAS5130CK 15 */
+ 4, /* SENSOR_TAS5130CXX 16 */
+ 3, /* SENSOR_TAS5130C_VF0250 17 */
};
/* define some sensors from the vendor/product */
@@ -7033,7 +7048,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info;
sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0)
- PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
+ PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
if ((unsigned) force_sensor < SENSOR_MAX) {
sd->sensor = force_sensor;
PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
@@ -7112,6 +7127,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->chip_revision);
sd->sensor = SENSOR_TAS5130CK;
break;
+ case 0x16:
+ PDEBUG(D_PROBE, "Find Sensor ADCM2700");
+ sd->sensor = SENSOR_ADCM2700;
+ break;
case 0x29:
PDEBUG(D_PROBE, "Find Sensor GC0305");
sd->sensor = SENSOR_GC0305;
@@ -7134,7 +7153,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = SENSOR_OV7620; /* same sensor (?) */
break;
default:
- PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor);
+ PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor);
return -EINVAL;
}
}
@@ -7147,7 +7166,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
/*fixme:test*/
gspca_dev->nbalt--;
if (vga) {
@@ -7157,7 +7175,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 1;
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->gamma = gamma[(int) sd->sensor];
@@ -7196,25 +7213,26 @@ static int sd_start(struct gspca_dev *gspca_dev)
const struct usb_action *zc3_init;
int mode;
static const struct usb_action *init_tb[SENSOR_MAX][2] = {
- {cs2102_InitialScale, cs2102_Initial}, /* 0 */
- {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
- {gc0305_Initial, gc0305_InitialScale}, /* 2 */
- {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */
- {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */
- {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */
- {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */
- {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */
- {OV7620_mode0, OV7620_mode1}, /* 8 */
- {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */
- {pas106b_InitialScale, pas106b_Initial}, /* 10 */
- {pas202b_Initial, pas202b_InitialScale}, /* 11 */
- {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */
+ {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */
+ {cs2102_InitialScale, cs2102_Initial}, /* 1 */
+ {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */
+ {gc0305_Initial, gc0305_InitialScale}, /* 3 */
+ {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */
+ {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */
+ {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */
+ {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */
+ {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */
+ {OV7620_mode0, OV7620_mode1}, /* 9 */
+ {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */
+ {pas106b_InitialScale, pas106b_Initial}, /* 11 */
+ {pas202b_Initial, pas202b_InitialScale}, /* 12 */
+ {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */
/* or {pb03303x_InitialScale, pb03303x_Initial}, */
- {PO2030_mode0, PO2030_mode1}, /* 13 */
- {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */
- {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */
+ {PO2030_mode0, PO2030_mode1}, /* 14 */
+ {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */
+ {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */
{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
- /* 16 */
+ /* 17 */
};
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -7243,11 +7261,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
usb_exchange(gspca_dev, zc3_init);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PO2030:
case SENSOR_TAS5130C_VF0250:
- msleep(100); /* ?? */
+/* msleep(100); * ?? */
reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7260,6 +7279,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
setmatrix(gspca_dev);
setbrightness(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_OV7620:
reg_r(gspca_dev, 0x0008);
reg_w(dev, 0x00, 0x0008);
@@ -7301,6 +7321,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
setlightfreq(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
+ reg_w(dev, 0x15, 0x01ae);
+ reg_w(dev, 0x02, 0x0180);
+ /* ms-win + */
+ reg_w(dev, 0x40, 0x0117);
+ break;
case SENSOR_GC0305:
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7323,19 +7350,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
setautogain(gspca_dev);
switch (sd->sensor) {
- case SENSOR_PAS202B:
- reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- break;
case SENSOR_PO2030:
msleep(500);
reg_r(gspca_dev, 0x0008);
reg_r(gspca_dev, 0x0007);
+ /*fall thru*/
+ case SENSOR_PAS202B:
reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- reg_w(dev, 0x02, 0x0008);
+ reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
break;
}
- if (sd->sensor == SENSOR_PAS202B)
- reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
return 0;
}
@@ -7359,9 +7383,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x21);
+ jpeg_put_header(gspca_dev, frame, 0x21);
/* remove the webcam's header:
* ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp
* - 'ss ss' is the frame sequence number (BE)
@@ -7565,9 +7587,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
{USB_DEVICE(0x0ac8, 0x0302)},
{USB_DEVICE(0x0ac8, 0x301b)},
-#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
{USB_DEVICE(0x0ac8, 0x303b)},
-#endif
{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
{USB_DEVICE(0x0ac8, 0x307b)},
{USB_DEVICE(0x10fd, 0x0128)},
@@ -7600,8 +7620,10 @@ static struct usb_driver sd_driver = {
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 79393d1772e4..8e1463ee1b64 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -56,17 +56,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { 0, 0 }
-};
-
#define HEXIUM_CONTROLS 1
static struct v4l2_queryctrl hexium_controls[] = {
{ V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -231,6 +220,132 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+ return 0;
+}
+
+/* the saa7146 provides some controls (brightness, contrast, saturation)
+ which gets registered *after* this function. because of this we have
+ to return with a value != 0 even if the function succeded.. */
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == qc->id) {
+ *qc = hexium_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
+ }
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE) {
+ vc->value = hexium->cur_bw;
+ DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i = 0;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE)
+ hexium->cur_bw = vc->value;
+
+ DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
+
+ if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_secam);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
+ /* fixme: is there no bw secam mode? */
+ return -EINVAL;
+
+ return -EINVAL;
+}
+
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -279,6 +394,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
hexium->cur_input = 0;
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -306,153 +427,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
- struct saa7146_vv *vv = dev->vv_data;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == qc->id) {
- *qc = hexium_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- vc->value = hexium->cur_bw;
- DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
- return 0;
- }
- }
- return -EINVAL;
- }
-
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- hexium->cur_bw = vc->value;
- break;
- }
- }
-
- DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
-
- if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_secam);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- /* fixme: is there no bw secam mode? */
- return -EINVAL;
- }
-
- return -EINVAL;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -514,8 +488,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension hexium_extension = {
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 074bec711fe0..2bc39f628455 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -57,14 +57,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { 0, 0 }
-};
-
struct hexium
{
int type;
@@ -329,6 +321,44 @@ static int hexium_set_input(struct hexium *hexium, int input)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+
+ return 0;
+}
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -339,6 +369,9 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
DEB_EE((".\n"));
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -370,58 +403,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
- struct saa7146_vv *vv = dev->vv_data;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
return 0;
@@ -479,8 +460,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index d4658c56eddc..2ee49b7ddcf0 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -16,6 +16,8 @@
* Henry Wong <henry@stuffedcow.net>
* Mark Schultz <n9xmj@yahoo.com>
* Brian Rogers <brian_rogers@comcast.net>
+ * modified for AVerMedia Cardbus by
+ * Oldrich Jedlicka <oldium.pro@seznam.cz>
*
* 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
@@ -216,6 +218,46 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
+static int get_key_avermedia_cardbus(struct IR_i2c *ir,
+ u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char subaddr, key, keygroup;
+ struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+ .buf = &subaddr, .len = 1},
+ { .addr = ir->c.addr, .flags = I2C_M_RD,
+ .buf = &key, .len = 1} };
+ subaddr = 0x0d;
+ if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ dprintk(1, "read error\n");
+ return -EIO;
+ }
+
+ if (key == 0xff)
+ return 0;
+
+ subaddr = 0x0b;
+ msg[1].buf = &keygroup;
+ if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ dprintk(1, "read error\n");
+ return -EIO;
+ }
+
+ if (keygroup == 0xff)
+ return 0;
+
+ dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup);
+ if (keygroup < 2 || keygroup > 3) {
+ /* Only a warning */
+ dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n",
+ keygroup, key);
+ }
+ key |= (keygroup & 1) << 6;
+
+ *ir_key = key;
+ *ir_raw = key;
+ return 1;
+}
+
/* ----------------------------------------------------------------------- */
static void ir_key_poll(struct IR_i2c *ir)
@@ -360,6 +402,12 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir_type = IR_TYPE_OTHER;
}
break;
+ case 0x40:
+ name = "AVerMedia Cardbus remote";
+ ir->get_key = get_key_avermedia_cardbus;
+ ir_type = IR_TYPE_OTHER;
+ ir_codes = ir_codes_avermedia_cardbus;
+ break;
default:
/* shouldn't happen */
printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
@@ -524,6 +572,22 @@ static int ir_probe(struct i2c_adapter *adap)
ir_attach(adap, msg.addr, 0, 0);
}
+ /* Special case for AVerMedia Cardbus remote */
+ if (adap->id == I2C_HW_SAA7134) {
+ unsigned char subaddr, data;
+ struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
+ .buf = &subaddr, .len = 1},
+ { .addr = 0x40, .flags = I2C_M_RD,
+ .buf = &data, .len = 1} };
+ subaddr = 0x0d;
+ rc = i2c_transfer(adap, msg, 2);
+ dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
+ msg[0].addr, subaddr, adap->name,
+ (2 == rc) ? "yes" : "no");
+ if (2 == rc)
+ ir_attach(adap, msg[0].addr, 0, 0);
+ }
+
return 0;
}
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 62aa06f5d168..84995bcf4a75 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -26,6 +26,7 @@
#include "ivtv-mailbox.h"
#include "ivtv-controls.h"
+/* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e8e5921cdc34..eca8bf92a225 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -357,7 +357,7 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
static void ivtv_process_eeprom(struct ivtv *itv)
{
struct tveeprom tv;
- int pci_slot = PCI_SLOT(itv->dev->devfn);
+ int pci_slot = PCI_SLOT(itv->pdev->devfn);
ivtv_read_eeprom(itv, &tv);
@@ -604,7 +604,7 @@ static void ivtv_process_options(struct ivtv *itv)
itv->std = ivtv_parse_std(itv);
if (itv->std == 0 && tunertype >= 0)
itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN);
- itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15);
+ itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15);
chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
if (itv->options.cardtype == -1) {
IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);
@@ -617,9 +617,9 @@ static void ivtv_process_options(struct ivtv *itv)
IVTV_ERR("Unknown user specified type, trying to autodetect card\n");
}
if (itv->card == NULL) {
- if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
- itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
- itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
+ if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
+ itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
+ itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);
IVTV_INFO("Autodetected Hauppauge card (%s based)\n",
chipname);
@@ -630,13 +630,13 @@ static void ivtv_process_options(struct ivtv *itv)
if (itv->card->pci_list == NULL)
continue;
for (j = 0; itv->card->pci_list[j].device; j++) {
- if (itv->dev->device !=
+ if (itv->pdev->device !=
itv->card->pci_list[j].device)
continue;
- if (itv->dev->subsystem_vendor !=
+ if (itv->pdev->subsystem_vendor !=
itv->card->pci_list[j].subsystem_vendor)
continue;
- if (itv->dev->subsystem_device !=
+ if (itv->pdev->subsystem_device !=
itv->card->pci_list[j].subsystem_device)
continue;
IVTV_INFO("Autodetected %s card (%s based)\n",
@@ -650,9 +650,9 @@ done:
if (itv->card == NULL) {
itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- itv->dev->vendor, itv->dev->device);
+ itv->pdev->vendor, itv->pdev->device);
IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- itv->dev->subsystem_vendor, itv->dev->subsystem_device);
+ itv->pdev->subsystem_vendor, itv->pdev->subsystem_device);
IVTV_ERR(" %s based\n", chipname);
IVTV_ERR("Defaulting to %s card\n", itv->card->name);
IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
@@ -671,7 +671,7 @@ done:
*/
static int __devinit ivtv_init_struct1(struct ivtv *itv)
{
- itv->base_addr = pci_resource_start(itv->dev, 0);
+ itv->base_addr = pci_resource_start(itv->pdev, 0);
itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
@@ -682,7 +682,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
spin_lock_init(&itv->lock);
spin_lock_init(&itv->dma_reg_lock);
- itv->irq_work_queues = create_singlethread_workqueue(itv->device.name);
+ itv->irq_work_queues = create_singlethread_workqueue(itv->v4l2_dev.name);
if (itv->irq_work_queues == NULL) {
IVTV_ERR("Could not create ivtv workqueue\n");
return -1;
@@ -766,7 +766,7 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv)
itv->audio_input = itv->card->video_inputs[i].audio_index;
}
-static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
+static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
u16 cmd;
@@ -775,11 +775,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
IVTV_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(dev)) {
+ if (pci_enable_device(pdev)) {
IVTV_ERR("Can't enable device!\n");
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
+ if (pci_set_dma_mask(pdev, 0xffffffff)) {
IVTV_ERR("No suitable DMA available.\n");
return -EIO;
}
@@ -805,11 +805,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
}
/* Check for bus mastering */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");
- pci_set_master(dev);
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_set_master(pdev);
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_ERR("Bus Mastering is not enabled\n");
return -ENXIO;
@@ -817,26 +817,26 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
}
IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev);
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < 64 && ivtv_pci_latency) {
IVTV_INFO("Unreasonably low latency timer, "
"setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
}
/* This config space value relates to DMA latencies. The
default value 0x8080 is too low however and will lead
to DMA errors. 0xffff is the max value which solves
these problems. */
- pci_write_config_dword(dev, 0x40, 0xffff);
+ pci_write_config_dword(pdev, 0x40, 0xffff);
IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
"irq: %d, latency: %d, memory: 0x%lx\n",
- itv->dev->device, card_rev, dev->bus->number,
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
- itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);
+ pdev->device, card_rev, pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+ pdev->irq, pci_latency, (unsigned long)itv->base_addr);
return 0;
}
@@ -935,7 +935,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
}
}
-static int __devinit ivtv_probe(struct pci_dev *dev,
+static int __devinit ivtv_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
int retval = 0;
@@ -945,15 +945,17 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
if (itv == NULL)
return -ENOMEM;
- itv->dev = dev;
+ itv->pdev = pdev;
itv->instance = atomic_inc_return(&ivtv_instance) - 1;
- retval = v4l2_device_register(&dev->dev, &itv->device);
- if (retval)
+ retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
+ if (retval) {
+ kfree(itv);
return retval;
+ }
/* "ivtv + PCI ID" is a bit of a mouthful, so use
"ivtv + instance" instead. */
- snprintf(itv->device.name, sizeof(itv->device.name),
+ snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name),
"ivtv%d", itv->instance);
IVTV_INFO("Initializing card %d\n", itv->instance);
@@ -970,12 +972,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
/* PCI Device Setup */
- if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
- if (retval == -EIO)
- goto free_workqueue;
- else if (retval == -ENXIO)
- goto free_mem;
- }
+ retval = ivtv_setup_pci(itv, pdev, pci_id);
+ if (retval == -EIO)
+ goto free_workqueue;
+ if (retval == -ENXIO)
+ goto free_mem;
/* map io memory */
IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -1152,8 +1153,8 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
ivtv_set_irq_mask(itv, 0xffffffff);
/* Register IRQ */
- retval = request_irq(itv->dev->irq, ivtv_irq_handler,
- IRQF_SHARED | IRQF_DISABLED, itv->device.name, (void *)itv);
+ retval = request_irq(itv->pdev->irq, ivtv_irq_handler,
+ IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv);
if (retval) {
IVTV_ERR("Failed to register irq %d\n", retval);
goto free_i2c;
@@ -1175,7 +1176,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
free_streams:
ivtv_streams_cleanup(itv, 1);
free_irq:
- free_irq(itv->dev->irq, (void *)itv);
+ free_irq(itv->pdev->irq, (void *)itv);
free_i2c:
exit_ivtv_i2c(itv);
free_io:
@@ -1192,7 +1193,7 @@ err:
retval = -ENODEV;
IVTV_ERR("Error %d on initialization\n", retval);
- v4l2_device_unregister(&itv->device);
+ v4l2_device_unregister(&itv->v4l2_dev);
kfree(itv);
return retval;
}
@@ -1290,10 +1291,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
return 0;
}
-static void ivtv_remove(struct pci_dev *pci_dev)
+static void ivtv_remove(struct pci_dev *pdev)
{
- struct v4l2_device *dev = dev_get_drvdata(&pci_dev->dev);
- struct ivtv *itv = to_ivtv(dev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct ivtv *itv = to_ivtv(v4l2_dev);
int i;
IVTV_DEBUG_INFO("Removing card\n");
@@ -1334,11 +1335,9 @@ static void ivtv_remove(struct pci_dev *pci_dev)
ivtv_streams_cleanup(itv, 1);
ivtv_udma_free(itv);
- v4l2_device_unregister(&itv->device);
-
exit_ivtv_i2c(itv);
- free_irq(itv->dev->irq, (void *)itv);
+ free_irq(itv->pdev->irq, (void *)itv);
ivtv_iounmap(itv);
release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
@@ -1346,11 +1345,13 @@ static void ivtv_remove(struct pci_dev *pci_dev)
if (itv->has_cx23415)
release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- pci_disable_device(itv->dev);
+ pci_disable_device(itv->pdev);
for (i = 0; i < IVTV_VBI_FRAMES; i++)
kfree(itv->vbi.sliced_mpeg_data[i]);
printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
+
+ v4l2_device_unregister(&itv->v4l2_dev);
kfree(itv);
}
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index ce8d9b74357e..440f7328a7ed 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -133,7 +133,7 @@ extern int ivtv_debug;
#define IVTV_DEBUG(x, type, fmt, args...) \
do { \
if ((x) & ivtv_debug) \
- v4l2_info(&itv->device, " " type ": " fmt , ##args); \
+ v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
} while (0)
#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -149,7 +149,7 @@ extern int ivtv_debug;
#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
do { \
if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
- v4l2_info(&itv->device, " " type ": " fmt , ##args); \
+ v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
} while (0)
#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -163,9 +163,9 @@ extern int ivtv_debug;
#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
/* Standard kernel messages */
-#define IVTV_ERR(fmt, args...) v4l2_err(&itv->device, fmt , ## args)
-#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->device, fmt , ## args)
-#define IVTV_INFO(fmt, args...) v4l2_info(&itv->device, fmt , ## args)
+#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args)
/* output modes (cx23415 only) */
#define OUT_NONE 0
@@ -315,7 +315,7 @@ struct ivtv; /* forward reference */
struct ivtv_stream {
/* These first four fields are always set, even if the stream
is not actually created. */
- struct video_device *v4l2dev; /* NULL when stream not created */
+ struct video_device *vdev; /* NULL when stream not created */
struct ivtv *itv; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
@@ -592,7 +592,7 @@ struct ivtv_card;
/* Struct to hold info about ivtv cards */
struct ivtv {
/* General fixed card data */
- struct pci_dev *dev; /* PCI device */
+ struct pci_dev *pdev; /* PCI device */
const struct ivtv_card *card; /* card information */
const char *card_name; /* full name of the card */
const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
@@ -612,7 +612,7 @@ struct ivtv {
volatile void __iomem *reg_mem; /* pointer to mapped registers */
struct ivtv_options options; /* user options */
- struct v4l2_device device;
+ struct v4l2_device v4l2_dev;
struct v4l2_subdev sd_gpio; /* GPIO sub-device */
u16 instance;
@@ -696,7 +696,7 @@ struct ivtv {
u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */
u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */
unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
- u16 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
+ u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
/* VBI state info */
@@ -719,9 +719,9 @@ struct ivtv {
struct osd_info *osd_info; /* ivtvfb private OSD info */
};
-static inline struct ivtv *to_ivtv(struct v4l2_device *dev)
+static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
{
- return container_of(dev, struct ivtv, device);
+ return container_of(v4l2_dev, struct ivtv, v4l2_dev);
}
/* Globals */
@@ -788,7 +788,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
/* Call the specified callback for all subdevs matching hw (if 0, then
match them all). Ignore any errors. */
#define ivtv_call_hw(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+ __v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
@@ -796,7 +796,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
match them all). If the callback returns an error other than 0 or
-ENOIOCTLCMD, then return with that error code. */
#define ivtv_call_hw_err(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs_until_err(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+ __v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index d594bc29f07f..cfaacf6096d0 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -148,10 +148,10 @@ void ivtv_release_stream(struct ivtv_stream *s)
static void ivtv_dualwatch(struct ivtv *itv)
{
struct v4l2_tuner vt;
- u16 new_bitmap;
- u16 new_stereo_mode;
- const u16 stereo_mask = 0x0300;
- const u16 dual = 0x0200;
+ u32 new_bitmap;
+ u32 new_stereo_mode;
+ const u32 stereo_mask = 0x0300;
+ const u32 dual = 0x0200;
new_stereo_mode = itv->params.audio_properties & stereo_mask;
memset(&vt, 0, sizeof(vt));
@@ -991,7 +991,7 @@ int ivtv_v4l2_open(struct file *filp)
mutex_lock(&itv->serialize_lock);
if (ivtv_init_on_first_open(itv)) {
IVTV_ERR("Failed to initialize on minor %d\n",
- s->v4l2dev->minor);
+ vdev->minor);
mutex_unlock(&itv->serialize_lock);
return -ENXIO;
}
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index 6dba55b7e25a..c1b7ec475c27 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -52,7 +52,7 @@ static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv
int retries = 3;
retry:
- if (retries && request_firmware(&fw, fn, &itv->dev->dev) == 0) {
+ if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) {
int i;
volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
const u32 *src = (const u32 *)fw->data;
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index dc2850e87a7e..3321983d89e5 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -384,7 +384,7 @@ int ivtv_gpio_init(struct ivtv *itv)
write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
- snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->device.name);
+ snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
itv->sd_gpio.grp_id = IVTV_HW_GPIO;
- return v4l2_device_register_subdev(&itv->device, &itv->sd_gpio);
+ return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
}
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index ca1d9557945e..e73a196ecc7a 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -194,14 +194,14 @@ struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
struct v4l2_subdev *result = NULL;
struct v4l2_subdev *sd;
- spin_lock(&itv->device.lock);
- v4l2_device_for_each_subdev(sd, &itv->device) {
+ spin_lock(&itv->v4l2_dev.lock);
+ v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) {
if (sd->grp_id == hw) {
result = sd;
break;
}
}
- spin_unlock(&itv->device.lock);
+ spin_unlock(&itv->v4l2_dev.lock);
return result;
}
@@ -472,8 +472,8 @@ static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data,
intervening stop condition */
static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
{
- struct v4l2_device *drv = i2c_get_adapdata(i2c_adap);
- struct ivtv *itv = to_ivtv(drv);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
+ struct ivtv *itv = to_ivtv(v4l2_dev);
int retval;
int i;
@@ -604,12 +604,12 @@ int init_ivtv_i2c(struct ivtv *itv)
sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
itv->instance);
- i2c_set_adapdata(&itv->i2c_adap, &itv->device);
+ i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev);
memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
sizeof(struct i2c_client));
itv->i2c_client.adapter = &itv->i2c_adap;
- itv->i2c_adap.dev.parent = &itv->dev->dev;
+ itv->i2c_adap.dev.parent = &itv->pdev->dev;
IVTV_DEBUG_I2C("setting scl and sda to 1\n");
ivtv_setscl(itv, 1);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index f6b3ef6e691b..9a0424298af1 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -345,10 +345,8 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
pixfmt->priv = 0;
if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- pixfmt->height * pixfmt->width +
- pixfmt->height * (pixfmt->width / 2);
+ /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+ pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
pixfmt->bytesperline = 720;
} else {
pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -393,7 +391,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
return 0;
}
- v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
+ v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt);
vbifmt->service_set = ivtv_get_service_set(vbifmt);
return 0;
}
@@ -469,11 +467,17 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
struct ivtv *itv = id->itv;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
+ int min_h = 2;
w = min(w, 720);
w = max(w, 2);
+ if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
+ /* YUV height must be a multiple of 32 */
+ h &= ~0x1f;
+ min_h = 32;
+ }
h = min(h, itv->is_50hz ? 576 : 480);
- h = max(h, 2);
+ h = max(h, min_h);
ivtv_g_fmt_vid_cap(file, fh, fmt);
fmt->fmt.pix.width = w;
fmt->fmt.pix.height = h;
@@ -766,7 +770,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev));
+ snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
vcap->version = IVTV_DRIVER_VERSION; /* version */
vcap->capabilities = itv->v4l2_cap; /* capabilities */
return 0;
@@ -1513,12 +1517,12 @@ static int ivtv_log_status(struct file *file, void *fh)
}
IVTV_INFO("Tuner: %s\n",
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
- cx2341x_log_status(&itv->params, itv->device.name);
+ cx2341x_log_status(&itv->params, itv->v4l2_dev.name);
IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
struct ivtv_stream *s = &itv->streams[i];
- if (s->v4l2dev == NULL || s->buffers == 0)
+ if (s->vdev == NULL || s->buffers == 0)
continue;
IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
(s->buffers - s->q_free.buffers) * 100 / s->buffers,
@@ -1748,6 +1752,18 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
break;
}
+ case IVTV_IOC_DMA_FRAME:
+ case VIDEO_GET_PTS:
+ case VIDEO_GET_FRAME_COUNT:
+ case VIDEO_GET_EVENT:
+ case VIDEO_PLAY:
+ case VIDEO_STOP:
+ case VIDEO_FREEZE:
+ case VIDEO_CONTINUE:
+ case VIDEO_COMMAND:
+ case VIDEO_TRY_COMMAND:
+ return ivtv_decoder_ioctls(file, cmd, (void *)arg);
+
default:
return -EINVAL;
}
@@ -1790,18 +1806,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
return 0;
- case IVTV_IOC_DMA_FRAME:
- case VIDEO_GET_PTS:
- case VIDEO_GET_FRAME_COUNT:
- case VIDEO_GET_EVENT:
- case VIDEO_PLAY:
- case VIDEO_STOP:
- case VIDEO_FREEZE:
- case VIDEO_CONTINUE:
- case VIDEO_COMMAND:
- case VIDEO_TRY_COMMAND:
- return ivtv_decoder_ioctls(filp, cmd, (void *)arg);
-
default:
break;
}
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index f5d00ec5da73..01c14d2b381a 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -46,7 +46,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv)
IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
- s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+ s->vdev == NULL || !ivtv_use_pio(s)) {
itv->cur_pio_stream = -1;
/* trigger PIO complete user interrupt */
write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
@@ -109,7 +109,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
int rc;
/* sanity checks */
- if (s->v4l2dev == NULL) {
+ if (s->vdev == NULL) {
IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
return -1;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index 71bd13e22e2e..ff7b7deded4f 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -230,7 +230,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
return -ENOMEM;
}
if (ivtv_might_use_dma(s)) {
- s->sg_handle = pci_map_single(itv->dev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
+ s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
ivtv_stream_sync_for_cpu(s);
}
@@ -248,7 +248,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
}
INIT_LIST_HEAD(&buf->list);
if (ivtv_might_use_dma(s)) {
- buf->dma_handle = pci_map_single(s->itv->dev,
+ buf->dma_handle = pci_map_single(s->itv->pdev,
buf->buf, s->buf_size + 256, s->dma);
ivtv_buf_sync_for_cpu(s, buf);
}
@@ -271,7 +271,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* empty q_free */
while ((buf = ivtv_dequeue(s, &s->q_free))) {
if (ivtv_might_use_dma(s))
- pci_unmap_single(s->itv->dev, buf->dma_handle,
+ pci_unmap_single(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
kfree(buf->buf);
kfree(buf);
@@ -280,7 +280,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* Free SG Array/Lists */
if (s->sg_dma != NULL) {
if (s->sg_handle != IVTV_DMA_UNMAPPED) {
- pci_unmap_single(s->itv->dev, s->sg_handle,
+ pci_unmap_single(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
s->sg_handle = IVTV_DMA_UNMAPPED;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
index 476556afd39a..91233839a26c 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -53,14 +53,14 @@ static inline int ivtv_use_dma(struct ivtv_stream *s)
static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
+ pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
+ pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
@@ -82,14 +82,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->dev, s->sg_handle,
+ pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
}
static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->dev, s->sg_handle,
+ pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 854a950af78c..15da01710efc 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -137,11 +137,11 @@ static struct {
static void ivtv_stream_init(struct ivtv *itv, int type)
{
struct ivtv_stream *s = &itv->streams[type];
- struct video_device *dev = s->v4l2dev;
+ struct video_device *vdev = s->vdev;
- /* we need to keep v4l2dev, so restore it afterwards */
+ /* we need to keep vdev, so restore it afterwards */
memset(s, 0, sizeof(*s));
- s->v4l2dev = dev;
+ s->vdev = vdev;
/* initialize ivtv_stream fields */
s->itv = itv;
@@ -172,10 +172,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
int num_offset = ivtv_stream_info[type].num_offset;
int num = itv->instance + ivtv_first_minor + num_offset;
- /* These four fields are always initialized. If v4l2dev == NULL, then
+ /* These four fields are always initialized. If vdev == NULL, then
this stream is not in use. In that case no other fields but these
four can be used. */
- s->v4l2dev = NULL;
+ s->vdev = NULL;
s->itv = itv;
s->type = type;
s->name = ivtv_stream_info[type].name;
@@ -197,21 +197,21 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
ivtv_stream_init(itv, type);
/* allocate and initialize the v4l2 video device structure */
- s->v4l2dev = video_device_alloc();
- if (s->v4l2dev == NULL) {
+ s->vdev = video_device_alloc();
+ if (s->vdev == NULL) {
IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
return -ENOMEM;
}
- snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "%s %s",
- itv->device.name, s->name);
+ snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s",
+ itv->v4l2_dev.name, s->name);
- s->v4l2dev->num = num;
- s->v4l2dev->v4l2_dev = &itv->device;
- s->v4l2dev->fops = ivtv_stream_info[type].fops;
- s->v4l2dev->release = video_device_release;
- s->v4l2dev->tvnorms = V4L2_STD_ALL;
- ivtv_set_funcs(s->v4l2dev);
+ s->vdev->num = num;
+ s->vdev->v4l2_dev = &itv->v4l2_dev;
+ s->vdev->fops = ivtv_stream_info[type].fops;
+ s->vdev->release = video_device_release;
+ s->vdev->tvnorms = V4L2_STD_ALL;
+ ivtv_set_funcs(s->vdev);
return 0;
}
@@ -226,7 +226,7 @@ int ivtv_streams_setup(struct ivtv *itv)
if (ivtv_prep_dev(itv, type))
break;
- if (itv->streams[type].v4l2dev == NULL)
+ if (itv->streams[type].vdev == NULL)
continue;
/* Allocate Stream */
@@ -247,28 +247,28 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
int vfl_type = ivtv_stream_info[type].vfl_type;
int num;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return 0;
- num = s->v4l2dev->num;
+ num = s->vdev->num;
/* card number + user defined offset + device offset */
if (type != IVTV_ENC_STREAM_TYPE_MPG) {
struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
- if (s_mpg->v4l2dev)
- num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset;
+ if (s_mpg->vdev)
+ num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset;
}
- video_set_drvdata(s->v4l2dev, s);
+ video_set_drvdata(s->vdev, s);
/* Register device. First try the desired minor, then any free one. */
- if (video_register_device(s->v4l2dev, vfl_type, num)) {
+ if (video_register_device(s->vdev, vfl_type, num)) {
IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
s->name, num);
- video_device_release(s->v4l2dev);
- s->v4l2dev = NULL;
+ video_device_release(s->vdev);
+ s->vdev = NULL;
return -ENOMEM;
}
- num = s->v4l2dev->num;
+ num = s->vdev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
@@ -316,9 +316,9 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
/* Teardown all streams */
for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- struct video_device *vdev = itv->streams[type].v4l2dev;
+ struct video_device *vdev = itv->streams[type].vdev;
- itv->streams[type].v4l2dev = NULL;
+ itv->streams[type].vdev = NULL;
if (vdev == NULL)
continue;
@@ -449,7 +449,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
int captype = 0, subtype = 0;
int enable_passthrough = 0;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -611,7 +611,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
struct cx2341x_mpeg_params *p = &itv->params;
int datatype;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
@@ -657,7 +657,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
{
struct ivtv *itv = s->itv;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
@@ -705,7 +705,7 @@ void ivtv_stop_all_captures(struct ivtv *itv)
for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
struct ivtv_stream *s = &itv->streams[i];
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
continue;
if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
ivtv_stop_v4l2_encode_stream(s, 0);
@@ -720,7 +720,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
int cap_type;
int stopmode;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
/* This function assumes that you are allowed to stop the capture
@@ -834,7 +834,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
{
struct ivtv *itv = s->itv;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
@@ -895,7 +895,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable)
struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
- if (yuv_stream->v4l2dev == NULL || dec_stream->v4l2dev == NULL)
+ if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index 460db03b0ba0..d07ad6c39024 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -93,7 +93,7 @@ void ivtv_udma_alloc(struct ivtv *itv)
{
if (itv->udma.SG_handle == 0) {
/* Map DMA Page Array Buffer */
- itv->udma.SG_handle = pci_map_single(itv->dev, itv->udma.SGarray,
+ itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
ivtv_udma_sync_for_cpu(itv);
}
@@ -147,7 +147,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
}
/* Map SG List */
- dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
@@ -172,7 +172,7 @@ void ivtv_udma_unmap(struct ivtv *itv)
/* Unmap Scatterlist */
if (dma->SG_length) {
- pci_unmap_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
dma->SG_length = 0;
}
/* sync DMA */
@@ -191,13 +191,13 @@ void ivtv_udma_free(struct ivtv *itv)
/* Unmap SG Array */
if (itv->udma.SG_handle) {
- pci_unmap_single(itv->dev, itv->udma.SG_handle,
+ pci_unmap_single(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
/* Unmap Scatterlist */
if (itv->udma.SG_length) {
- pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
+ pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
}
for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) {
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/video/ivtv/ivtv-udma.h
index df727e23be0a..ee3c9efb5b72 100644
--- a/drivers/media/video/ivtv/ivtv-udma.h
+++ b/drivers/media/video/ivtv/ivtv-udma.h
@@ -35,13 +35,13 @@ void ivtv_udma_start(struct ivtv *itv);
static inline void ivtv_udma_sync_for_device(struct ivtv *itv)
{
- pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+ pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
{
- pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+ pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index ee91107376c7..7912ed6b72ee 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -103,7 +103,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
dma->page_count = 0;
return -ENOMEM;
}
- dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
@@ -910,7 +910,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
if (yi->blanking_ptr) {
- yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
+ yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
} else {
yi->blanking_dmaptr = 0;
IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
@@ -1237,7 +1237,7 @@ void ivtv_yuv_close(struct ivtv *itv)
if (yi->blanking_ptr) {
kfree(yi->blanking_ptr);
yi->blanking_ptr = NULL;
- pci_unmap_single(itv->dev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
+ pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
}
/* Invalidate the old dimension information */
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 36abd2aef6f1..66e6eb513076 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -1192,12 +1192,12 @@ static int ivtvfb_init_card(struct ivtv *itv)
static int __init ivtvfb_callback_init(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+ struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (ivtvfb_init_card(itv) == 0) {
IVTVFB_INFO("Framebuffer registered on %s\n",
- itv->device.name);
+ itv->v4l2_dev.name);
(*(int *)p)++;
}
}
@@ -1207,7 +1207,7 @@ static int __init ivtvfb_callback_init(struct device *dev, void *p)
static int ivtvfb_callback_cleanup(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+ struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index de397ef57b44..41988072b973 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -210,7 +210,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "m52790",
- .driverid = I2C_DRIVERID_M52790,
.command = m52790_command,
.probe = m52790_probe,
.remove = m52790_remove,
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index e3cbe14c349a..996011f2aba5 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -32,9 +32,14 @@
#include "mxb.h"
#include "tea6415c.h"
#include "tea6420.h"
-#include "tda9840.h"
-#define I2C_SAA7111 0x24
+#define I2C_SAA5246A 0x11
+#define I2C_SAA7111A 0x24
+#define I2C_TDA9840 0x42
+#define I2C_TEA6415C 0x43
+#define I2C_TEA6420_1 0x4c
+#define I2C_TEA6420_2 0x4d
+#define I2C_TUNER 0x60
#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
@@ -79,57 +84,35 @@ static struct {
static int video_audio_connect[MXB_INPUTS] =
{ 0, 1, 3, 3 };
-/* these are the necessary input-output-pins for bringing one audio source
-(see above) to the CD-output */
-static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
- {
- {{1,1,0},{1,1,0}}, /* Tuner */
- {{5,1,0},{6,1,0}}, /* AUX 1 */
- {{4,1,0},{6,1,0}}, /* AUX 2 */
- {{3,1,0},{6,1,0}}, /* AUX 3 */
- {{1,1,0},{3,1,0}}, /* Radio */
- {{1,1,0},{2,1,0}}, /* CD-Rom */
- {{6,1,0},{6,1,0}} /* Mute */
- };
-
-/* these are the necessary input-output-pins for bringing one audio source
-(see above) to the line-output */
-static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
- {
- {{2,3,0},{1,2,0}},
- {{5,3,0},{6,2,0}},
- {{4,3,0},{6,2,0}},
- {{3,3,0},{6,2,0}},
- {{2,3,0},{3,2,0}},
- {{2,3,0},{2,2,0}},
- {{6,3,0},{6,2,0}} /* Mute */
- };
+/* These are the necessary input-output-pins for bringing one audio source
+ (see above) to the CD-output. Note that gain is set to 0 in this table. */
+static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
+ { { 1, 1 }, { 1, 1 } }, /* Tuner */
+ { { 5, 1 }, { 6, 1 } }, /* AUX 1 */
+ { { 4, 1 }, { 6, 1 } }, /* AUX 2 */
+ { { 3, 1 }, { 6, 1 } }, /* AUX 3 */
+ { { 1, 1 }, { 3, 1 } }, /* Radio */
+ { { 1, 1 }, { 2, 1 } }, /* CD-Rom */
+ { { 6, 1 }, { 6, 1 } } /* Mute */
+};
+
+/* These are the necessary input-output-pins for bringing one audio source
+ (see above) to the line-output. Note that gain is set to 0 in this table. */
+static struct v4l2_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
+ { { 2, 3 }, { 1, 2 } },
+ { { 5, 3 }, { 6, 2 } },
+ { { 4, 3 }, { 6, 2 } },
+ { { 3, 3 }, { 6, 2 } },
+ { { 2, 3 }, { 3, 2 } },
+ { { 2, 3 }, { 2, 2 } },
+ { { 6, 3 }, { 6, 2 } } /* Mute */
+};
#define MAXCONTROLS 1
static struct v4l2_queryctrl mxb_controls[] = {
{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE },
- { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
- { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
- { 0, 0 }
-};
-
struct mxb
{
struct video_device *video_dev;
@@ -137,12 +120,12 @@ struct mxb
struct i2c_adapter i2c_adapter;
- struct i2c_client *saa7111a;
- struct i2c_client *tda9840;
- struct i2c_client *tea6415c;
- struct i2c_client *tuner;
- struct i2c_client *tea6420_1;
- struct i2c_client *tea6420_2;
+ struct v4l2_subdev *saa7111a;
+ struct v4l2_subdev *tda9840;
+ struct v4l2_subdev *tea6415c;
+ struct v4l2_subdev *tuner;
+ struct v4l2_subdev *tea6420_1;
+ struct v4l2_subdev *tea6420_2;
int cur_mode; /* current audio mode (mono, stereo, ...) */
int cur_input; /* current input */
@@ -150,84 +133,51 @@ struct mxb
struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
};
-static struct saa7146_extension extension;
-
-static int mxb_check_clients(struct device *dev, void *data)
-{
- struct mxb *mxb = data;
- struct i2c_client *client = i2c_verify_client(dev);
-
- if (!client)
- return 0;
-
- if (I2C_ADDR_TEA6420_1 == client->addr)
- mxb->tea6420_1 = client;
- if (I2C_ADDR_TEA6420_2 == client->addr)
- mxb->tea6420_2 = client;
- if (I2C_TEA6415C_2 == client->addr)
- mxb->tea6415c = client;
- if (I2C_ADDR_TDA9840 == client->addr)
- mxb->tda9840 = client;
- if (I2C_SAA7111 == client->addr)
- mxb->saa7111a = client;
- if (0x60 == client->addr)
- mxb->tuner = client;
+#define saa7111a_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
+#define tea6420_1_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6420_1, o, f, ##args)
+#define tea6420_2_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6420_2, o, f, ##args)
+#define tda9840_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tda9840, o, f, ##args)
+#define tea6415c_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
+#define tuner_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tuner, o, f, ##args)
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
- return 0;
-}
+static struct saa7146_extension extension;
-static int mxb_probe(struct saa7146_dev* dev)
+static int mxb_probe(struct saa7146_dev *dev)
{
- struct mxb* mxb = NULL;
- int result;
-
- result = request_module("saa7115");
- if (result < 0) {
- printk("mxb: saa7111 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tea6420");
- if (result < 0) {
- printk("mxb: tea6420 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tea6415c");
- if (result < 0) {
- printk("mxb: tea6415c i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tda9840");
- if (result < 0) {
- printk("mxb: tda9840 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tuner");
- if (result < 0) {
- printk("mxb: tuner i2c module not available.\n");
- return -ENODEV;
- }
+ struct mxb *mxb = NULL;
mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
- if( NULL == mxb ) {
+ if (mxb == NULL) {
DEB_D(("not enough kernel memory.\n"));
return -ENOMEM;
}
- mxb->i2c_adapter = (struct i2c_adapter) {
- .class = I2C_CLASS_TV_ANALOG,
- };
-
snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
- if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
+ if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
DEB_S(("cannot register i2c-device. skipping.\n"));
kfree(mxb);
return -EFAULT;
}
- /* loop through all i2c-devices on the bus and look who is there */
- device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
+ mxb->saa7111a = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa7115", "saa7111", I2C_SAA7111A);
+ mxb->tea6420_1 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_1);
+ mxb->tea6420_2 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_2);
+ mxb->tea6415c = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6415c", "tea6415c", I2C_TEA6415C);
+ mxb->tda9840 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tda9840", "tda9840", I2C_TDA9840);
+ mxb->tuner = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tuner", "tuner", I2C_TUNER);
+ if (v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa5246a", "saa5246a", I2C_SAA5246A)) {
+ printk(KERN_INFO "mxb: found teletext decoder\n");
+ }
/* check if all devices are present */
if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
@@ -315,47 +265,45 @@ static int mxb_init_done(struct saa7146_dev* dev)
struct v4l2_routing route;
int i = 0, err = 0;
- struct tea6415c_multiplex vm;
/* select video mode in saa7111a */
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, tuner, s_std, std);
/* select tuner-output on saa7111a */
i = 0;
route.input = SAA7115_COMPOSITE0;
route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ saa7111a_call(mxb, video, s_routing, &route);
/* select a tuner type */
tun_setup.mode_mask = T_ANALOG_TV;
tun_setup.addr = ADDR_UNSET;
tun_setup.type = TUNER_PHILIPS_PAL;
- mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup);
+ tuner_call(mxb, tuner, s_type_addr, &tun_setup);
/* tune in some frequency on tuner */
mxb->cur_freq.tuner = 0;
mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
mxb->cur_freq.frequency = freq;
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
- &mxb->cur_freq);
+ tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
/* set a default video standard */
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ tuner_call(mxb, tuner, s_std, std);
/* mute audio on tea6420s */
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]);
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
- /* switch to tuner-channel on tea6415c*/
- vm.out = 17;
- vm.in = 3;
- mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+ /* switch to tuner-channel on tea6415c */
+ route.input = 3;
+ route.output = 17;
+ tea6415c_call(mxb, video, s_routing, &route);
- /* select tuner-output on multicable on tea6415c*/
- vm.in = 3;
- vm.out = 13;
- mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+ /* select tuner-output on multicable on tea6415c */
+ route.input = 3;
+ route.output = 13;
+ tea6415c_call(mxb, video, s_routing, &route);
/* the rest for mxb */
mxb->cur_input = 0;
@@ -424,395 +372,414 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
}
*/
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
{
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- DEB_EE(("dev:%p\n", dev));
-
- /* checking for i2c-devices can be omitted here, because we
- already did this in "mxb_vl42_probe" */
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
- saa7146_vv_init(dev, &vv_data);
- if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
- ERR(("cannot register capture v4l2 device. skipping.\n"));
- return -1;
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == qc->id) {
+ *qc = mxb_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
}
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
- /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
- if (MXB_BOARD_CAN_DO_VBI(dev)) {
- if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
- ERR(("cannot register vbi v4l2 device. skipping.\n"));
- }
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i;
+
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
}
- i2c_use_client(mxb->tea6420_1);
- i2c_use_client(mxb->tea6420_2);
- i2c_use_client(mxb->tea6415c);
- i2c_use_client(mxb->tda9840);
- i2c_use_client(mxb->saa7111a);
- i2c_use_client(mxb->tuner);
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
- printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ vc->value = mxb->cur_mute;
+ DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
+ return 0;
+ }
- mxb_num++;
- mxb_init_done(dev);
+ DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
return 0;
}
-static int mxb_detach(struct saa7146_dev *dev)
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i = 0;
- DEB_EE(("dev:%p\n", dev));
-
- i2c_release_client(mxb->tea6420_1);
- i2c_release_client(mxb->tea6420_2);
- i2c_release_client(mxb->tea6415c);
- i2c_release_client(mxb->tda9840);
- i2c_release_client(mxb->saa7111a);
- i2c_release_client(mxb->tuner);
-
- saa7146_unregister_device(&mxb->video_dev,dev);
- if (MXB_BOARD_CAN_DO_VBI(dev))
- saa7146_unregister_device(&mxb->vbi_dev, dev);
- saa7146_vv_release(dev);
-
- mxb_num--;
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
+ }
- i2c_del_adapter(&mxb->i2c_adapter);
- kfree(mxb);
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ mxb->cur_mute = vc->value;
+ if (!vc->value) {
+ /* switch the audio-source */
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
+ } else {
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[6][1]);
+ }
+ DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ }
+ return 0;
+}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+ if (i->index < 0 || i->index >= MXB_INPUTS)
+ return -EINVAL;
+ memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
return 0;
}
-static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
{
- struct saa7146_dev *dev = fh->dev;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- struct saa7146_vv *vv = dev->vv_data;
+ *i = mxb->cur_input;
- switch(cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
+ DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
+ return 0;
+}
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
- if (i->index < 0 || i->index >= MXB_INPUTS)
- return -EINVAL;
- memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == qc->id) {
- *qc = mxb_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct v4l2_routing route;
+ int i = 0;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
- }
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
- if (i < 0)
- return -EAGAIN;
+ if (input < 0 || input >= MXB_INPUTS)
+ return -EINVAL;
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- vc->value = mxb->cur_mute;
- DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ mxb->cur_input = input;
- DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
+ input_port_selection[input].hps_sync);
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
+ /* prepare switching of tea6415c and saa7111a;
+ have a look at the 'background'-file for further informations */
+ switch (input) {
+ case TUNER:
+ i = SAA7115_COMPOSITE0;
+ route.input = 3;
+ route.output = 17;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
+ if (tea6415c_call(mxb, video, s_routing, &route)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
+ return -EFAULT;
}
+ /* connect tuner-output always to multicable */
+ route.input = 3;
+ route.output = 13;
+ break;
+ case AUX3_YC:
+ /* nothing to be done here. aux3_yc is
+ directly connected to the saa711a */
+ i = SAA7115_SVIDEO1;
+ break;
+ case AUX3:
+ /* nothing to be done here. aux3 is
+ directly connected to the saa711a */
+ i = SAA7115_COMPOSITE1;
+ break;
+ case AUX1:
+ i = SAA7115_COMPOSITE0;
+ route.input = 1;
+ route.output = 17;
+ break;
+ }
- if (i < 0)
- return -EAGAIN;
-
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- mxb->cur_mute = vc->value;
- if (!vc->value) {
- /* switch the audio-source */
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
- } else {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[6][1]);
- }
- DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ /* switch video in tea6415c only if necessary */
+ switch (input) {
+ case TUNER:
+ case AUX1:
+ if (tea6415c_call(mxb, video, s_routing, &route)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
+ return -EFAULT;
}
- return 0;
+ break;
+ default:
+ break;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = mxb->cur_input;
- DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
- return 0;
+ /* switch video in saa7111a */
+ route.input = i;
+ route.output = 0;
+ if (saa7111a_call(mxb, video, s_routing, &route))
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
+
+ /* switch the audio-source only if necessary */
+ if (0 == mxb->cur_mute) {
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[input]][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[input]][1]);
}
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- struct tea6415c_multiplex vm;
- struct v4l2_routing route;
- int i = 0;
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+ return 0;
+}
- if (input < 0 || input >= MXB_INPUTS)
- return -EINVAL;
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- mxb->cur_input = input;
+ if (t->index) {
+ DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
- input_port_selection[input].hps_sync);
+ DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
- /* prepare switching of tea6415c and saa7111a;
- have a look at the 'background'-file for further informations */
- switch (input) {
- case TUNER:
- i = SAA7115_COMPOSITE0;
- vm.in = 3;
- vm.out = 17;
+ memset(t, 0, sizeof(*t));
+ strlcpy(t->name, "TV Tuner", sizeof(t->name));
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+ t->audmode = mxb->cur_mode;
+ return call_all(dev, tuner, g_tuner, t);
+}
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
- return -EFAULT;
- }
- /* connect tuner-output always to multicable */
- vm.in = 3;
- vm.out = 13;
- break;
- case AUX3_YC:
- /* nothing to be done here. aux3_yc is
- directly connected to the saa711a */
- i = SAA7115_SVIDEO1;
- break;
- case AUX3:
- /* nothing to be done here. aux3 is
- directly connected to the saa711a */
- i = SAA7115_COMPOSITE1;
- break;
- case AUX1:
- i = SAA7115_COMPOSITE0;
- vm.in = 1;
- vm.out = 17;
- break;
- }
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- /* switch video in tea6415c only if necessary */
- switch (input) {
- case TUNER:
- case AUX1:
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
- return -EFAULT;
- }
- break;
- default:
- break;
- }
+ if (t->index) {
+ DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- /* switch video in saa7111a */
- route.input = i;
- route.output = 0;
- if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
- printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
-
- /* switch the audio-source only if necessary */
- if( 0 == mxb->cur_mute ) {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][1]);
- }
+ mxb->cur_mode = t->audmode;
+ return call_all(dev, tuner, s_tuner, t);
+}
- return 0;
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
+ mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- if (t->index) {
- DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
- return -EINVAL;
- }
+ *f = mxb->cur_freq;
- DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
+ DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ return 0;
+}
- memset(t, 0, sizeof(*t));
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct saa7146_vv *vv = dev->vv_data;
- strlcpy(t->name, "TV Tuner", sizeof(t->name));
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->audmode = mxb->cur_mode;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
+ if (f->tuner)
+ return -EINVAL;
- if (t->index) {
- DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
- return -EINVAL;
- }
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- mxb->cur_mode = t->audmode;
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
- mxb->cur_input));
- return -EINVAL;
- }
+ mxb->cur_freq = *f;
+ DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
- *f = mxb->cur_freq;
+ /* tune in desired frequency */
+ tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
- DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
- return 0;
+ /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
+ spin_lock(&dev->slock);
+ vv->vbi_fieldcount = 0;
+ spin_unlock(&dev->slock);
+
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (a->index < 0 || a->index > MXB_INPUTS) {
+ DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
+ return -EINVAL;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (f->tuner)
- return -EINVAL;
+ DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
+ memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+ return 0;
+}
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
+ return 0;
+}
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
- return -EINVAL;
- }
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- mxb->cur_freq = *f;
- DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ return call_all(dev, core, g_register, reg);
+}
- /* tune in desired frequency */
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
+static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
- spin_lock(&dev->slock);
- vv->vbi_fieldcount = 0;
- spin_unlock(&dev->slock);
+ return call_all(dev, core, s_register, reg);
+}
+#endif
- return 0;
- }
+static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ switch (cmd) {
case MXB_S_AUDIO_CD:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
+ DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
return -EINVAL;
}
- DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
+ DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
- mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[i][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[i][1]);
return 0;
}
case MXB_S_AUDIO_LINE:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
+ DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
return -EINVAL;
}
- DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
- mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
+ DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[i][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[i][1]);
return 0;
}
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ default:
+/*
+ DEB2(printk("does not handle this ioctl.\n"));
+*/
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
- if (a->index < 0 || a->index > MXB_INPUTS) {
- DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
- return -EINVAL;
- }
+static struct saa7146_ext_vv vv_data;
- DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
- memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+/* this function only gets called when the probing was successful */
+static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- return 0;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ DEB_EE(("dev:%p\n", dev));
- DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
- return 0;
- }
+ /* checking for i2c-devices can be omitted here, because we
+ already did this in "mxb_vl42_probe" */
+
+ saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
+ vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data.ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data.ops.vidioc_s_audio = vidioc_s_audio;
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_DBG_S_REGISTER:
- case VIDIOC_DBG_G_REGISTER:
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ vv_data.ops.vidioc_g_register = vidioc_g_register;
+ vv_data.ops.vidioc_s_register = vidioc_s_register;
#endif
- default:
-/*
- DEB2(printk("does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
+ vv_data.ops.vidioc_default = vidioc_default;
+ if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
+ ERR(("cannot register capture v4l2 device. skipping.\n"));
+ return -1;
}
+
+ /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
+ if (MXB_BOARD_CAN_DO_VBI(dev)) {
+ if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
+ ERR(("cannot register vbi v4l2 device. skipping.\n"));
+ }
+ }
+
+ printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+
+ mxb_num++;
+ mxb_init_done(dev);
+ return 0;
+}
+
+static int mxb_detach(struct saa7146_dev *dev)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ DEB_EE(("dev:%p\n", dev));
+
+ saa7146_unregister_device(&mxb->video_dev,dev);
+ if (MXB_BOARD_CAN_DO_VBI(dev))
+ saa7146_unregister_device(&mxb->vbi_dev, dev);
+ saa7146_vv_release(dev);
+
+ mxb_num--;
+
+ i2c_del_adapter(&mxb->i2c_adapter);
+ kfree(mxb);
+
return 0;
}
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
{
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- int zero = 0;
- int one = 1;
if (V4L2_STD_PAL_I == standard->id) {
v4l2_std_id std = V4L2_STD_PAL_I;
@@ -821,8 +788,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* set the 7146 gpio register -- I don't know what this does exactly */
saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* unset the 7111 gpio register -- I don't know what this does exactly */
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero);
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, core, s_gpio, 0);
+ tuner_call(mxb, tuner, s_std, std);
} else {
v4l2_std_id std = V4L2_STD_PAL_BG;
@@ -830,8 +797,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* set the 7146 gpio register -- I don't know what this does exactly */
saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* set the 7111 gpio register -- I don't know what this does exactly */
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one);
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, core, s_gpio, 1);
+ tuner_call(mxb, tuner, s_std, std);
}
return 0;
}
@@ -885,8 +852,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &standard[0],
.num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = mxb_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index de7ee7264be6..d96f0f51076e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -195,8 +195,20 @@ struct pvr2_hdw {
struct mutex big_lock_mutex;
int big_lock_held; /* For debugging */
+ /* This is a simple string which identifies the instance of this
+ driver. It is unique within the set of existing devices, but
+ there is no attempt to keep the name consistent with the same
+ physical device each time. */
char name[32];
+ /* This is a simple string which identifies the physical device
+ instance itself - if possible. (If not possible, then it is
+ based on the specific driver instance, similar to name above.)
+ The idea here is that userspace might hopefully be able to use
+ this recognize specific tuners. It will encode a serial number,
+ if available. */
+ char identifier[32];
+
/* I2C stuff */
struct i2c_adapter i2c_adap;
struct i2c_algorithm i2c_algo;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index fa304e5f252a..ed8a4561e086 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1283,6 +1283,12 @@ const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
}
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw)
+{
+ return hdw->identifier;
+}
+
+
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
{
return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -2024,6 +2030,19 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
hdw->std_mask_eeprom = V4L2_STD_ALL;
}
+ if (hdw->serial_number) {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "sn-%lu", hdw->serial_number);
+ } else if (hdw->unit_number >= 0) {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "unit-%c",
+ hdw->unit_number + 'a');
+ } else {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "unit-??");
+ }
+ hdw->identifier[idx] = 0;
+
pvr2_hdw_setup_std(hdw);
if (!get_default_tuner_type(hdw)) {
@@ -2393,10 +2412,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->usb_intf = intf;
hdw->usb_dev = interface_to_usbdev(intf);
- scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
- "usb %s address %d",
- dev_name(&hdw->usb_dev->dev),
- hdw->usb_dev->devnum);
+ usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info));
ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_interface(hdw->usb_dev,ifnum,0);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 1b4fec337c6b..7b6940554e9a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -132,6 +132,9 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
/* Retrieve bus location info of device */
const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
+/* Retrieve per-instance string identifier for this specific device */
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *);
+
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
@@ -236,8 +239,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
enum pvr2_v4l_type index,int);
/* Direct read/write access to chip's registers:
- match_type - how to interpret match_chip (e.g. driver ID, i2c address)
- match_chip - chip match value (e.g. I2C_DRIVERD_xxxx)
+ match - specify criteria to identify target chip (this is a v4l dbg struct)
reg_id - register number to access
setFl - true to set the register, false to read it
val_ptr - storage location for source / result. */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index 94a47718e88e..4cf980c49d01 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -31,17 +31,19 @@
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
-#define OP_STANDARD 0
-#define OP_AUDIOMODE 1
-#define OP_BCSH 2
-#define OP_VOLUME 3
-#define OP_FREQ 4
-#define OP_AUDIORATE 5
-#define OP_CROP 6
-#define OP_SIZE 7
-#define OP_LOG 8
+#define OP_INIT 0 /* MUST come first so it is run first */
+#define OP_STANDARD 1
+#define OP_AUDIOMODE 2
+#define OP_BCSH 3
+#define OP_VOLUME 4
+#define OP_FREQ 5
+#define OP_AUDIORATE 6
+#define OP_CROP 7
+#define OP_SIZE 8
+#define OP_LOG 9
static const struct pvr2_i2c_op * const ops[] = {
+ [OP_INIT] = &pvr2_i2c_op_v4l2_init,
[OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
[OP_AUDIOMODE] = &pvr2_i2c_op_v4l2_audiomode,
[OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh,
@@ -56,7 +58,8 @@ void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
{
int id;
id = cp->client->driver->id;
- cp->ctl_mask = ((1 << OP_STANDARD) |
+ cp->ctl_mask = ((1 << OP_INIT) |
+ (1 << OP_STANDARD) |
(1 << OP_AUDIOMODE) |
(1 << OP_BCSH) |
(1 << OP_VOLUME) |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
index 16bb11902a52..0f2885440f2f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -25,6 +25,20 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+static void execute_init(struct pvr2_hdw *hdw)
+{
+ u32 dummy = 0;
+ pvr2_trace(PVR2_TRACE_CHIPS, "i2c v4l2 init");
+ pvr2_i2c_core_cmd(hdw, VIDIOC_INT_INIT, &dummy);
+}
+
+
+const struct pvr2_i2c_op pvr2_i2c_op_v4l2_init = {
+ .update = execute_init,
+ .name = "v4l2_init",
+};
+
+
static void set_standard(struct pvr2_hdw *hdw)
{
pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_standard");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
index eb744a20610d..69a63f2a8a7b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
@@ -24,6 +24,7 @@
#include "pvrusb2-i2c-core.h"
+extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_init;
extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio;
extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index d6a35401fefb..57a024737722 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -763,7 +763,7 @@ int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
if (!(msk & pm)) continue;
pm &= ~msk;
opf = pvr2_i2c_get_op(idx);
- if (!opf) continue;
+ if (!(opf && opf->check)) continue;
if (opf->check(hdw)) {
sm |= msk;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 9b3c874d96d6..8689ddb54420 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -137,10 +137,10 @@ static int __init pvr_init(void)
ret = usb_register(&pvr_driver);
if (ret == 0)
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":"
DRIVER_DESC "\n");
if (pvrusb2_debug)
- printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n",
+ printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n",
pvrusb2_debug,pvrusb2_debug);
pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index e641cd971453..e20ba1e6e0ea 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -627,16 +627,8 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
class_dev->class = &class_ptr->class;
- if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
- dev_set_name(class_dev, "sn-%lu",
- pvr2_hdw_get_sn(sfp->channel.hdw));
- } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
- dev_set_name(class_dev, "unit-%c",
- pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
- } else {
- kfree(class_dev);
- return;
- }
+ dev_set_name(class_dev, "%s",
+ pvr2_hdw_get_device_identifier(sfp->channel.hdw));
class_dev->parent = &usb_dev->dev;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 878fd52a73b3..b7caf135ed55 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -91,7 +91,7 @@ static struct v4l2_capability pvr_capability ={
.card = "Hauppauge WinTV pvr-usb2",
.bus_info = "usb",
.version = KERNEL_VERSION(0,8,0),
- .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
+ .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
V4L2_CAP_READWRITE),
.reserved = {0,0,0,0}
@@ -1268,8 +1268,9 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->minor_type = pvr2_v4l_type_video;
nr_ptr = video_nr;
if (!dip->stream) {
- err("Failed to set up pvrusb2 v4l video dev"
- " due to missing stream instance");
+ pr_err(KBUILD_MODNAME
+ ": Failed to set up pvrusb2 v4l video dev"
+ " due to missing stream instance\n");
return;
}
break;
@@ -1286,8 +1287,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
break;
default:
/* Bail out (this should be impossible) */
- err("Failed to set up pvrusb2 v4l dev"
- " due to unrecognized config");
+ pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
+ " due to unrecognized config\n");
return;
}
@@ -1303,7 +1304,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->v4l_type, mindevnum) < 0) &&
(video_register_device(&dip->devbase,
dip->v4l_type, -1) < 0)) {
- err("Failed to register pvrusb2 v4l device");
+ pr_err(KBUILD_MODNAME
+ ": Failed to register pvrusb2 v4l device\n");
}
printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 7298cf2e1650..8b9f0aa844a1 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -35,3 +35,13 @@ config USB_PWC_DEBUG
Say Y here in order to have the pwc driver generate verbose debugging
messages.
A special module options 'trace' is used to control the verbosity.
+
+config USB_PWC_INPUT_EVDEV
+ bool "USB Philips Cameras input events device support"
+ default y
+ depends on USB_PWC && INPUT
+ ---help---
+ This option makes USB Philips cameras register the snapshot button as
+ an input device to report button events.
+
+ If you are in doubt, say Y.
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 39fbc970f43d..a7c2e7284c20 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -53,6 +53,7 @@
- Xavier Roche: QuickCam Pro 4000 ID
- Jens Knudsen: QuickCam Zoom ID
- J. Debert: QuickCam for Notebooks ID
+ - Pham Thanh Nam: webcam snapshot button as an event input device
*/
#include <linux/errno.h>
@@ -61,8 +62,10 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/usb/input.h>
+#endif
#include <linux/vmalloc.h>
-#include <linux/version.h>
#include <asm/io.h>
#include "pwc.h"
@@ -587,6 +590,23 @@ static void pwc_frame_dumped(struct pwc_device *pdev)
pdev->vframe_count);
}
+static void pwc_snapshot_button(struct pwc_device *pdev, int down)
+{
+ if (down) {
+ PWC_TRACE("Snapshot button pressed.\n");
+ pdev->snapshot_button_status = 1;
+ } else {
+ PWC_TRACE("Snapshot button released.\n");
+ }
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ if (pdev->button_dev) {
+ input_report_key(pdev->button_dev, BTN_0, down);
+ input_sync(pdev->button_dev);
+ }
+#endif
+}
+
static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf)
{
int awake = 0;
@@ -604,13 +624,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
pdev->vframes_error++;
}
if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- if (ptr[0] & 0x01) {
- pdev->snapshot_button_status = 1;
- PWC_TRACE("Snapshot button pressed.\n");
- }
- else {
- PWC_TRACE("Snapshot button released.\n");
- }
+ pwc_snapshot_button(pdev, ptr[0] & 0x01);
}
if ((ptr[0] ^ pdev->vmirror) & 0x02) {
if (ptr[0] & 0x02)
@@ -634,12 +648,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
else if (pdev->type == 740 || pdev->type == 720) {
unsigned char *ptr = (unsigned char *)fbuf->data;
if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- if (ptr[0] & 0x01) {
- pdev->snapshot_button_status = 1;
- PWC_TRACE("Snapshot button pressed.\n");
- }
- else
- PWC_TRACE("Snapshot button released.\n");
+ pwc_snapshot_button(pdev, ptr[0] & 0x01);
}
pdev->vmirror = ptr[0] & 0x03;
}
@@ -1217,6 +1226,15 @@ static void pwc_cleanup(struct pwc_device *pdev)
{
pwc_remove_sysfs_files(pdev->vdev);
video_unregister_device(pdev->vdev);
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ if (pdev->button_dev) {
+ input_unregister_device(pdev->button_dev);
+ input_free_device(pdev->button_dev);
+ kfree(pdev->button_dev->phys);
+ pdev->button_dev = NULL;
+ }
+#endif
}
/* Note that all cleanup is done in the reverse order as in _open */
@@ -1484,6 +1502,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
int features = 0;
int video_nr = -1; /* default: use next available device */
char serial_number[30], *name;
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ char *phys = NULL;
+#endif
vendor_id = le16_to_cpu(udev->descriptor.idVendor);
product_id = le16_to_cpu(udev->descriptor.idProduct);
@@ -1808,6 +1829,35 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
pwc_set_leds(pdev, 0, 0);
pwc_camera_power(pdev, 0);
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ /* register webcam snapshot button input device */
+ pdev->button_dev = input_allocate_device();
+ if (!pdev->button_dev) {
+ PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
+ return -ENOMEM;
+ }
+
+ pdev->button_dev->name = "PWC snapshot button";
+ phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath);
+ if (!phys) {
+ input_free_device(pdev->button_dev);
+ return -ENOMEM;
+ }
+ pdev->button_dev->phys = phys;
+ usb_to_input_id(pdev->udev, &pdev->button_dev->id);
+ pdev->button_dev->dev.parent = &pdev->udev->dev;
+ pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
+ pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+
+ rc = input_register_device(pdev->button_dev);
+ if (rc) {
+ input_free_device(pdev->button_dev);
+ kfree(pdev->button_dev->phys);
+ pdev->button_dev = NULL;
+ return rc;
+ }
+#endif
+
return 0;
err_unreg:
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 01411fb2337a..0be6f814f539 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -37,6 +37,9 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/input.h>
+#endif
#include "pwc-uncompress.h"
#include <media/pwc-ioctl.h>
@@ -255,6 +258,9 @@ struct pwc_device
int pan_angle; /* in degrees * 100 */
int tilt_angle; /* absolute angle; 0,0 is home position */
int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ struct input_dev *button_dev; /* webcam snapshot button input */
+#endif
/*** Misc. data ***/
wait_queue_head_t frameq; /* When waiting for a frame to finish... */
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index a1d6008efcbb..e3e6b29ea6d2 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -35,7 +35,6 @@
#include <linux/videodev2.h>
#include <mach/dma.h>
-#include <mach/pxa-regs.h>
#include <mach/camera.h>
#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5)
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 13f85ad363cd..b5be633e3bb0 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -336,14 +336,19 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
u16 index, u16 value, void *buf,
s32 buf_len, int bOut);
+/* dev_err macro with driver name */
+#define S2255_DRIVER_NAME "s2255"
+#define s2255_dev_err(dev, fmt, arg...) \
+ dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
+
#define dprintk(level, fmt, arg...) \
do { \
if (*s2255_debug >= (level)) { \
- printk(KERN_DEBUG "s2255: " fmt, ##arg); \
+ printk(KERN_DEBUG S2255_DRIVER_NAME \
+ ": " fmt, ##arg); \
} \
} while (0)
-
static struct usb_driver s2255_driver;
@@ -528,14 +533,14 @@ static void s2255_fwchunk_complete(struct urb *urb)
int len;
dprintk(100, "udev %p urb %p", udev, urb);
if (urb->status) {
- dev_err(&udev->dev, "URB failed with status %d", urb->status);
+ dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
return;
}
if (data->fw_urb == NULL) {
- dev_err(&udev->dev, "s2255 disconnected\n");
+ s2255_dev_err(&udev->dev, "disconnected\n");
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
@@ -841,8 +846,7 @@ static int vidioc_querycap(struct file *file, void *priv,
struct s2255_dev *dev = fh->dev;
strlcpy(cap->driver, "s2255", sizeof(cap->driver));
strlcpy(cap->card, "s2255", sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev),
- sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = S2255_VERSION;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
return 0;
@@ -1278,7 +1282,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
}
if (!res_get(dev, fh)) {
- dev_err(&dev->udev->dev, "s2255: stream busy\n");
+ s2255_dev_err(&dev->udev->dev, "stream busy\n");
return -EBUSY;
}
@@ -1545,7 +1549,8 @@ static int s2255_open(struct file *file)
switch (atomic_read(&dev->fw_data->fw_state)) {
case S2255_FW_FAILED:
- err("2255 firmware load failed. retrying.\n");
+ s2255_dev_err(&dev->udev->dev,
+ "firmware load failed. retrying.\n");
s2255_fwload_start(dev, 1);
wait_event_timeout(dev->fw_data->wait_fw,
((atomic_read(&dev->fw_data->fw_state)
@@ -2173,7 +2178,8 @@ static int s2255_board_init(struct s2255_dev *dev)
printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
if (fw_ver < CUR_USB_FWVER)
- err("usb firmware not up to date %d\n", fw_ver);
+ dev_err(&dev->udev->dev,
+ "usb firmware not up to date %d\n", fw_ver);
for (j = 0; j < MAX_CHANNELS; j++) {
dev->b_acquire[j] = 0;
@@ -2228,13 +2234,13 @@ static void read_pipe_completion(struct urb *purb)
dprintk(100, "read pipe completion %p, status %d\n", purb,
purb->status);
if (pipe_info == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
dev = pipe_info->dev;
if (dev == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
status = purb->status;
@@ -2286,7 +2292,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pipe_info->stream_urb) {
dev_err(&dev->udev->dev,
- "ReadStream: Unable to alloc URB");
+ "ReadStream: Unable to alloc URB\n");
return -ENOMEM;
}
/* transfer buffer allocated in board_init */
@@ -2391,7 +2397,7 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
int j;
if (dev == NULL) {
- err("s2255: invalid device");
+ s2255_dev_err(&dev->udev->dev, "invalid device\n");
return;
}
dprintk(4, "stop read pipe\n");
@@ -2453,7 +2459,7 @@ static int s2255_probe(struct usb_interface *interface,
/* allocate memory for our device state and initialize it to zero */
dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
if (dev == NULL) {
- err("s2255: out of memory");
+ s2255_dev_err(&interface->dev, "out of memory\n");
goto error;
}
@@ -2487,7 +2493,7 @@ static int s2255_probe(struct usb_interface *interface,
}
if (!dev->read_endpoint) {
- dev_err(&interface->dev, "Could not find bulk-in endpoint");
+ dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
goto error;
}
@@ -2583,7 +2589,7 @@ static void s2255_disconnect(struct usb_interface *interface)
}
static struct usb_driver s2255_driver = {
- .name = "s2255",
+ .name = S2255_DRIVER_NAME,
.probe = s2255_probe,
.disconnect = s2255_disconnect,
.id_table = s2255_table,
@@ -2597,7 +2603,8 @@ static int __init usb_s2255_init(void)
result = usb_register(&s2255_driver);
if (result)
- err("usb_register failed. Error number %d", result);
+ pr_err(KBUILD_MODNAME
+ ": usb_register failed. Error number %d\n", result);
dprintk(2, "s2255_init: done\n");
return result;
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index e637e440b6d5..da47b2f05288 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -46,10 +46,11 @@
#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver");
@@ -388,13 +389,19 @@ MODULE_LICENSE("GPL");
struct saa5246a_device
{
+ struct v4l2_subdev sd;
+ struct video_device *vdev;
u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
int is_searching[NUM_DAUS];
- struct i2c_client *client;
unsigned long in_use;
struct mutex lock;
};
+static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa5246a_device, sd);
+}
+
static struct video_device saa_template; /* Declared near bottom */
/*
@@ -403,12 +410,13 @@ static struct video_device saa_template; /* Declared near bottom */
static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
char buf[64];
buf[0] = reg;
memcpy(buf+1, data, count);
- if(i2c_master_send(t->client, buf, count+1)==count+1)
+ if (i2c_master_send(client, buf, count + 1) == count + 1)
return 0;
return -1;
}
@@ -436,7 +444,9 @@ static int i2c_senddata(struct saa5246a_device *t, ...)
*/
static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
{
- if(i2c_master_recv(t->client, buf, count)!=count)
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+ if (i2c_master_recv(client, buf, count) != count)
return -1;
return 0;
}
@@ -961,9 +971,6 @@ static int saa5246a_open(struct file *file)
{
struct saa5246a_device *t = video_drvdata(file);
- if (t->client == NULL)
- return -ENODEV;
-
if (test_and_set_bit(0, &t->in_use))
return -EBUSY;
@@ -1033,18 +1040,29 @@ static struct video_device saa_template =
.minor = -1,
};
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5246A, 0);
+}
+
+static const struct v4l2_subdev_core_ops saa5246a_core_ops = {
+ .g_chip_ident = saa5246a_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5246a_ops = {
+ .core = &saa5246a_core_ops,
+};
-I2C_CLIENT_INSMOD;
static int saa5246a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int pgbuf;
int err;
- struct video_device *vd;
struct saa5246a_device *t;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -1053,40 +1071,43 @@ static int saa5246a_probe(struct i2c_client *client,
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL)
return -ENOMEM;
+ sd = &t->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa5246a_ops);
mutex_init(&t->lock);
/* Now create a video4linux device */
- vd = video_device_alloc();
- if (vd == NULL) {
+ t->vdev = video_device_alloc();
+ if (t->vdev == NULL) {
kfree(t);
return -ENOMEM;
}
- i2c_set_clientdata(client, vd);
- memcpy(vd, &saa_template, sizeof(*vd));
+ memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
t->is_searching[pgbuf] = false;
}
- video_set_drvdata(vd, t);
+ video_set_drvdata(t->vdev, t);
/* Register it */
- err = video_register_device(vd, VFL_TYPE_VTX, -1);
+ err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
if (err < 0) {
kfree(t);
- video_device_release(vd);
+ video_device_release(t->vdev);
+ t->vdev = NULL;
return err;
}
- t->client = client;
return 0;
}
static int saa5246a_remove(struct i2c_client *client)
{
- struct video_device *vd = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa5246a_device *t = to_dev(sd);
- video_unregister_device(vd);
- kfree(video_get_drvdata(vd));
+ video_unregister_device(t->vdev);
+ v4l2_device_unregister_subdev(sd);
+ kfree(t);
return 0;
}
@@ -1098,7 +1119,6 @@ MODULE_DEVICE_TABLE(i2c, saa5246a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa5246a",
- .driverid = I2C_DRIVERID_SAA5249,
.probe = saa5246a_probe,
.remove = saa5246a_remove,
.id_table = saa5246a_id,
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index e29765192469..48b27fe48087 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -50,15 +50,17 @@
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver");
MODULE_LICENSE("GPL");
+
#define VTX_VER_MAJ 1
#define VTX_VER_MIN 8
@@ -95,17 +97,23 @@ typedef struct {
struct saa5249_device
{
+ struct v4l2_subdev sd;
+ struct video_device *vdev;
vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */
/* real DAU, so we have to simulate some more) */
int vtx_use_count;
int is_searching[NUM_DAUS];
int disp_mode;
int virtual_mode;
- struct i2c_client *client;
unsigned long in_use;
struct mutex lock;
};
+static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa5249_device, sd);
+}
+
#define CCTWR 34 /* I²C write/read-address of vtx-chip */
#define CCTRD 35
@@ -147,12 +155,13 @@ static void jdelay(unsigned long delay)
static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
char buf[64];
buf[0] = reg;
memcpy(buf+1, data, count);
- if (i2c_master_send(t->client, buf, count + 1) == count + 1)
+ if (i2c_master_send(client, buf, count + 1) == count + 1)
return 0;
return -1;
}
@@ -180,7 +189,9 @@ static int i2c_senddata(struct saa5249_device *t, ...)
static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
{
- if(i2c_master_recv(t->client, buf, count)!=count)
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+ if (i2c_master_recv(client, buf, count) != count)
return -1;
return 0;
}
@@ -497,9 +508,6 @@ static int saa5249_open(struct file *file)
struct saa5249_device *t = video_drvdata(file);
int pgbuf;
- if (t->client == NULL)
- return -ENODEV;
-
if (test_and_set_bit(0, &t->in_use))
return -EBUSY;
@@ -553,18 +561,28 @@ static struct video_device saa_template =
.release = video_device_release,
};
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0);
+}
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_core_ops saa5249_core_ops = {
+ .g_chip_ident = saa5249_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5249_ops = {
+ .core = &saa5249_core_ops,
+};
static int saa5249_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int pgbuf;
int err;
- struct video_device *vd;
struct saa5249_device *t;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -573,16 +591,17 @@ static int saa5249_probe(struct i2c_client *client,
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL)
return -ENOMEM;
+ sd = &t->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa5249_ops);
mutex_init(&t->lock);
/* Now create a video4linux device */
- vd = kmalloc(sizeof(struct video_device), GFP_KERNEL);
- if (vd == NULL) {
+ t->vdev = video_device_alloc();
+ if (t->vdev == NULL) {
kfree(client);
return -ENOMEM;
}
- i2c_set_clientdata(client, vd);
- memcpy(vd, &saa_template, sizeof(*vd));
+ memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
@@ -593,26 +612,27 @@ static int saa5249_probe(struct i2c_client *client,
t->vdau[pgbuf].stopped = true;
t->is_searching[pgbuf] = false;
}
- video_set_drvdata(vd, t);
+ video_set_drvdata(t->vdev, t);
/* Register it */
- err = video_register_device(vd, VFL_TYPE_VTX, -1);
+ err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
if (err < 0) {
kfree(t);
- kfree(vd);
+ video_device_release(t->vdev);
+ t->vdev = NULL;
return err;
}
- t->client = client;
return 0;
}
static int saa5249_remove(struct i2c_client *client)
{
- struct video_device *vd = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa5249_device *t = to_dev(sd);
- video_unregister_device(vd);
- kfree(video_get_drvdata(vd));
- kfree(vd);
+ video_unregister_device(t->vdev);
+ v4l2_device_unregister_subdev(sd);
+ kfree(t);
return 0;
}
@@ -624,7 +644,6 @@ MODULE_DEVICE_TABLE(i2c, saa5249_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa5249",
- .driverid = I2C_DRIVERID_SAA5249,
.probe = saa5249_probe,
.remove = saa5249_remove,
.id_table = saa5249_id,
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index f05024259f01..258b7b2a1e99 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -32,6 +32,9 @@
#include <asm/uaccess.h>
#include <media/rds.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv-legacy.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = {
@@ -72,7 +75,7 @@ MODULE_LICENSE("GPL");
#define dprintk if (debug) printk
struct saa6588 {
- struct i2c_client client;
+ struct v4l2_subdev sd;
struct work_struct work;
struct timer_list timer;
spinlock_t lock;
@@ -86,8 +89,10 @@ struct saa6588 {
int data_available_for_read;
};
-static struct i2c_driver driver;
-static struct i2c_client client_template;
+static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa6588, sd);
+}
/* ---------------------------------------------------------------------- */
@@ -258,6 +263,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
static void saa6588_i2c_poll(struct saa6588 *s)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
unsigned long flags;
unsigned char tmpbuf[6];
unsigned char blocknum;
@@ -265,7 +271,7 @@ static void saa6588_i2c_poll(struct saa6588 *s)
/* Although we only need 3 bytes, we have to read at least 6.
SAA6588 returns garbage otherwise */
- if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) {
+ if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) {
if (debug > 1)
dprintk(PREFIX "read error!\n");
return;
@@ -333,6 +339,7 @@ static void saa6588_work(struct work_struct *work)
static int saa6588_configure(struct saa6588 *s)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
unsigned char buf[3];
int rc;
@@ -380,7 +387,8 @@ static int saa6588_configure(struct saa6588 *s)
dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n",
buf[0], buf[1], buf[2]);
- if (3 != (rc = i2c_master_send(&s->client, buf, 3)))
+ rc = i2c_master_send(client, buf, 3);
+ if (rc != 3)
printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
return 0;
@@ -388,33 +396,96 @@ static int saa6588_configure(struct saa6588 *s)
/* ---------------------------------------------------------------------- */
-static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
+static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+ struct saa6588 *s = to_saa6588(sd);
+ struct rds_command *a = arg;
+
+ switch (cmd) {
+ /* --- open() for /dev/radio --- */
+ case RDS_CMD_OPEN:
+ a->result = 0; /* return error if chip doesn't work ??? */
+ break;
+ /* --- close() for /dev/radio --- */
+ case RDS_CMD_CLOSE:
+ s->data_available_for_read = 1;
+ wake_up_interruptible(&s->read_queue);
+ a->result = 0;
+ break;
+ /* --- read() for /dev/radio --- */
+ case RDS_CMD_READ:
+ read_from_buf(s, a);
+ break;
+ /* --- poll() for /dev/radio --- */
+ case RDS_CMD_POLL:
+ a->result = 0;
+ if (s->data_available_for_read) {
+ a->result |= POLLIN | POLLRDNORM;
+ }
+ poll_wait(a->instance, &s->read_queue, a->event_list);
+ break;
+
+ default:
+ /* nothing */
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
+static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
+}
+
+static int saa6588_command(struct i2c_client *client, unsigned cmd, void *arg)
+{
+ return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops saa6588_core_ops = {
+ .g_chip_ident = saa6588_g_chip_ident,
+ .ioctl = saa6588_ioctl,
+};
+
+static const struct v4l2_subdev_ops saa6588_ops = {
+ .core = &saa6588_core_ops,
+};
+
+/* ---------------------------------------------------------------------- */
+
+static int saa6588_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct saa6588 *s;
- client_template.adapter = adap;
- client_template.addr = addr;
+ struct v4l2_subdev *sd;
- printk(PREFIX "chip found @ 0x%x\n", addr << 1);
+ v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
- if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL)))
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
+ if (s == NULL)
return -ENOMEM;
s->buf_size = bufblocks * 3;
- if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) {
+ s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
+ if (s->buffer == NULL) {
kfree(s);
return -ENOMEM;
}
+ sd = &s->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
spin_lock_init(&s->lock);
- s->client = client_template;
s->block_count = 0;
s->wr_index = 0;
s->rd_index = 0;
s->last_blocknum = 0xff;
init_waitqueue_head(&s->read_queue);
s->data_available_for_read = 0;
- i2c_set_clientdata(&s->client, s);
- i2c_attach_client(&s->client);
saa6588_configure(s);
@@ -427,97 +498,33 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
return 0;
}
-static int saa6588_probe(struct i2c_adapter *adap)
+static int saa6588_remove(struct i2c_client *client)
{
- if (adap->class & I2C_CLASS_TV_ANALOG)
- return i2c_probe(adap, &addr_data, saa6588_attach);
- return 0;
-}
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa6588 *s = to_saa6588(sd);
-static int saa6588_detach(struct i2c_client *client)
-{
- struct saa6588 *s = i2c_get_clientdata(client);
+ v4l2_device_unregister_subdev(sd);
del_timer_sync(&s->timer);
flush_scheduled_work();
- i2c_detach_client(client);
kfree(s->buffer);
kfree(s);
return 0;
}
-static int saa6588_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- struct saa6588 *s = i2c_get_clientdata(client);
- struct rds_command *a = (struct rds_command *)arg;
-
- switch (cmd) {
- /* --- open() for /dev/radio --- */
- case RDS_CMD_OPEN:
- a->result = 0; /* return error if chip doesn't work ??? */
- break;
- /* --- close() for /dev/radio --- */
- case RDS_CMD_CLOSE:
- s->data_available_for_read = 1;
- wake_up_interruptible(&s->read_queue);
- a->result = 0;
- break;
- /* --- read() for /dev/radio --- */
- case RDS_CMD_READ:
- read_from_buf(s, a);
- break;
- /* --- poll() for /dev/radio --- */
- case RDS_CMD_POLL:
- a->result = 0;
- if (s->data_available_for_read) {
- a->result |= POLLIN | POLLRDNORM;
- }
- poll_wait(a->instance, &s->read_queue, a->event_list);
- break;
-
- default:
- /* nothing */
- break;
- }
- return 0;
-}
-
/* ----------------------------------------------------------------------- */
-static struct i2c_driver driver = {
- .driver = {
- .name = "saa6588",
- },
- .id = -1, /* FIXME */
- .attach_adapter = saa6588_probe,
- .detach_client = saa6588_detach,
- .command = saa6588_command,
+static const struct i2c_device_id saa6588_id[] = {
+ { "saa6588", 0 },
+ { }
};
+MODULE_DEVICE_TABLE(i2c, saa6588_id);
-static struct i2c_client client_template = {
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa6588",
- .driver = &driver,
+ .command = saa6588_command,
+ .probe = saa6588_probe,
+ .remove = saa6588_remove,
+ .id_table = saa6588_id,
};
-
-static int __init saa6588_init_module(void)
-{
- return i2c_add_driver(&driver);
-}
-
-static void __exit saa6588_cleanup_module(void)
-{
- i2c_del_driver(&driver);
-}
-
-module_init(saa6588_init_module);
-module_exit(saa6588_cleanup_module);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 46c796c3fec8..dd1943987ce6 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -778,7 +778,7 @@ static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index d6848f7a503b..05221d47dd4c 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -149,7 +149,7 @@ static const struct i2c_reg_value saa7127_init_config_common[] = {
{ SAA7127_REG_COPYGEN_0, 0x77 },
{ SAA7127_REG_COPYGEN_1, 0x41 },
{ SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e },
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf },
{ SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
{ SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
{ SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
@@ -488,12 +488,18 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
break;
case SAA7127_OUTPUT_TYPE_COMPOSITE:
- state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
+ if (state->ident == V4L2_IDENT_SAA7129)
+ state->reg_2d = 0x20; /* CVBS only */
+ else
+ state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
case SAA7127_OUTPUT_TYPE_SVIDEO:
- state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */
+ if (state->ident == V4L2_IDENT_SAA7129)
+ state->reg_2d = 0x18; /* Y + C */
+ else
+ state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
@@ -508,7 +514,10 @@ static int saa7127_set_output_type(struct v4l2_subdev *sd, int output)
break;
case SAA7127_OUTPUT_TYPE_BOTH:
- state->reg_2d = 0xbf;
+ if (state->ident == V4L2_IDENT_SAA7129)
+ state->reg_2d = 0x38;
+ else
+ state->reg_2d = 0xbf;
state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
break;
@@ -731,24 +740,6 @@ static int saa7127_probe(struct i2c_client *client,
return -ENODEV;
}
- /* Configure Encoder */
-
- v4l2_dbg(1, debug, sd, "Configuring encoder\n");
- saa7127_write_inittab(sd, saa7127_init_config_common);
- saa7127_set_std(sd, V4L2_STD_NTSC);
- saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
- saa7127_set_vps(sd, &vbi);
- saa7127_set_wss(sd, &vbi);
- saa7127_set_cc(sd, &vbi);
- saa7127_set_xds(sd, &vbi);
- if (test_image == 1)
- /* The Encoder has an internal Colorbar generator */
- /* This can be used for debugging */
- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
- else
- saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
- saa7127_set_video_enable(sd, 1);
-
if (id->driver_data) { /* Chip type is already known */
state->ident = id->driver_data;
} else { /* Needs detection */
@@ -770,6 +761,23 @@ static int saa7127_probe(struct i2c_client *client,
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
client->addr << 1, client->adapter->name);
+
+ v4l2_dbg(1, debug, sd, "Configuring encoder\n");
+ saa7127_write_inittab(sd, saa7127_init_config_common);
+ saa7127_set_std(sd, V4L2_STD_NTSC);
+ saa7127_set_output_type(sd, SAA7127_OUTPUT_TYPE_BOTH);
+ saa7127_set_vps(sd, &vbi);
+ saa7127_set_wss(sd, &vbi);
+ saa7127_set_cc(sd, &vbi);
+ saa7127_set_xds(sd, &vbi);
+ if (test_image == 1)
+ /* The Encoder has an internal Colorbar generator */
+ /* This can be used for debugging */
+ saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_TEST_IMAGE);
+ else
+ saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
+ saa7127_set_video_enable(sd, 1);
+
if (state->ident == V4L2_IDENT_SAA7129)
saa7127_write_inittab(sd, saa7129_init_config_extra);
return 0;
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 1fee6e84a512..2d292ad776e9 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -33,9 +33,10 @@
#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <linux/init.h>
#include <linux/crc32.h>
@@ -44,10 +45,6 @@
#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
#define MPEG_PID_MAX ((1 << 14) - 1)
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
-
-I2C_CLIENT_INSMOD;
MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
MODULE_AUTHOR("Andrew de Quincey");
@@ -95,6 +92,7 @@ static const struct v4l2_format v4l2_format_table[] =
};
struct saa6752hs_state {
+ struct v4l2_subdev sd;
int chip;
u32 revision;
int has_ac3;
@@ -115,6 +113,11 @@ enum saa6752hs_command {
SAA6752HS_COMMAND_MAX
};
+static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa6752hs_state, sd);
+}
+
/* ---------------------------------------------------------------------- */
static u8 PAT[] = {
@@ -360,185 +363,191 @@ static int saa6752hs_set_bitrate(struct i2c_client *client,
return 0;
}
-static void saa6752hs_set_subsampling(struct i2c_client *client,
- struct v4l2_format *f)
-{
- struct saa6752hs_state *h = i2c_get_clientdata(client);
- int dist_352, dist_480, dist_720;
-
- /*
- FIXME: translate and round width/height into EMPRESS
- subsample type:
- type | PAL | NTSC
- ---------------------------
- SIF | 352x288 | 352x240
- 1/2 D1 | 352x576 | 352x480
- 2/3 D1 | 480x576 | 480x480
- D1 | 720x576 | 720x480
- */
-
- dist_352 = abs(f->fmt.pix.width - 352);
- dist_480 = abs(f->fmt.pix.width - 480);
- dist_720 = abs(f->fmt.pix.width - 720);
- if (dist_720 < dist_480) {
- f->fmt.pix.width = 720;
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_D1;
- }
- else if (dist_480 < dist_352) {
- f->fmt.pix.width = 480;
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_2_3_D1;
- }
- else {
- f->fmt.pix.width = 352;
- if (abs(f->fmt.pix.height - 576) <
- abs(f->fmt.pix.height - 288)) {
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_1_2_D1;
- }
- else {
- f->fmt.pix.height = 288;
- h->video_format = SAA6752HS_VF_SIF;
- }
+static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
+ struct v4l2_ext_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ ctrl->value = params->ts_pid_pmt;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ ctrl->value = params->ts_pid_audio;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ ctrl->value = params->ts_pid_video;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ ctrl->value = params->ts_pid_pcr;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ ctrl->value = params->au_encoding;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ ctrl->value = params->au_l2_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (!has_ac3)
+ return -EINVAL;
+ ctrl->value = params->au_ac3_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ ctrl->value = params->vi_aspect;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ ctrl->value = params->vi_bitrate * 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ ctrl->value = params->vi_bitrate_peak * 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ ctrl->value = params->vi_bitrate_mode;
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
}
-
static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
- struct v4l2_ext_control *ctrl, unsigned int cmd)
+ struct v4l2_ext_control *ctrl, int set)
{
int old = 0, new;
- int set = (cmd == VIDIOC_S_EXT_CTRLS);
new = ctrl->value;
switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- old = params->ts_pid_pmt;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pmt = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- old = params->ts_pid_audio;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_audio = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- old = params->ts_pid_video;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_video = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- old = params->ts_pid_pcr;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pcr = new;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- old = params->au_encoding;
- if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
- (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- old = params->au_l2_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
- params->au_l2_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!has_ac3)
- return -EINVAL;
- old = params->au_ac3_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
- params->au_ac3_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- old = params->vi_aspect;
- if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
- new != V4L2_MPEG_VIDEO_ASPECT_4x3)
- return -ERANGE;
- if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
- new = V4L2_MPEG_VIDEO_ASPECT_4x3;
- params->vi_aspect = new;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- old = params->vi_bitrate * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- old = params->vi_bitrate_peak * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate_peak = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- old = params->vi_bitrate_mode;
- params->vi_bitrate_mode = new;
- break;
- default:
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ old = params->ts_pid_pmt;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_pmt = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ old = params->ts_pid_audio;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_audio = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ old = params->ts_pid_video;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_video = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ old = params->ts_pid_pcr;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_pcr = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ old = params->au_encoding;
+ if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ old = params->au_l2_bitrate;
+ if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
+ new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
+ return -ERANGE;
+ if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
+ new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
+ else
+ new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
+ params->au_l2_bitrate = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (!has_ac3)
return -EINVAL;
+ old = params->au_ac3_bitrate;
+ if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
+ new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
+ return -ERANGE;
+ if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
+ new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
+ else
+ new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
+ params->au_ac3_bitrate = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ old = params->vi_aspect;
+ if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
+ new != V4L2_MPEG_VIDEO_ASPECT_4x3)
+ return -ERANGE;
+ if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
+ new = V4L2_MPEG_VIDEO_ASPECT_4x3;
+ params->vi_aspect = new;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ old = params->vi_bitrate * 1000;
+ new = 1000 * (new / 1000);
+ if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ return -ERANGE;
+ if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+ params->vi_bitrate = new / 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ old = params->vi_bitrate_peak * 1000;
+ new = 1000 * (new / 1000);
+ if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ return -ERANGE;
+ if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+ params->vi_bitrate_peak = new / 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ old = params->vi_bitrate_mode;
+ params->vi_bitrate_mode = new;
+ break;
+ default:
+ return -EINVAL;
}
- if (cmd == VIDIOC_G_EXT_CTRLS)
- ctrl->value = old;
- else
- ctrl->value = new;
+ ctrl->value = new;
return 0;
}
-static int saa6752hs_qctrl(struct saa6752hs_state *h,
- struct v4l2_queryctrl *qctrl)
+
+static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
{
+ struct saa6752hs_state *h = to_state(sd);
struct saa6752hs_mpeg_params *params = &h->params;
int err;
@@ -610,8 +619,7 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
return -EINVAL;
}
-static int saa6752hs_qmenu(struct saa6752hs_state *h,
- struct v4l2_querymenu *qmenu)
+static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
{
static const u32 mpeg_audio_encoding[] = {
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
@@ -632,11 +640,12 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
V4L2_CTRL_MENU_IDS_END
};
+ struct saa6752hs_state *h = to_state(sd);
struct v4l2_queryctrl qctrl;
int err;
qctrl.id = qmenu->id;
- err = saa6752hs_qctrl(h, &qctrl);
+ err = saa6752hs_queryctrl(sd, &qctrl);
if (err)
return err;
switch (qmenu->id) {
@@ -656,17 +665,16 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
}
-static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
+static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
{
unsigned char buf[9], buf2[4];
- struct saa6752hs_state *h;
+ struct saa6752hs_state *h = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
unsigned size;
u32 crc;
unsigned char localPAT[256];
unsigned char localPMT[256];
- h = i2c_get_clientdata(client);
-
/* Set video format - must be done first as it resets other settings */
set_reg8(client, 0x41, h->video_format);
@@ -762,7 +770,7 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
buf[3] = 0x82;
buf[4] = 0xB0;
buf[5] = buf2[0];
- switch(h->params.vi_aspect) {
+ switch (h->params.vi_aspect) {
case V4L2_MPEG_VIDEO_ASPECT_16x9:
buf[6] = buf2[1] | 0x40;
break;
@@ -770,7 +778,6 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
default:
buf[6] = buf2[1] & 0xBF;
break;
- break;
}
buf[7] = buf2[2];
buf[8] = buf2[3];
@@ -779,81 +786,162 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
return 0;
}
-static int
-saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
{
- struct saa6752hs_state *h = i2c_get_clientdata(client);
- struct v4l2_ext_controls *ctrls = arg;
+ struct saa6752hs_state *h = to_state(sd);
struct saa6752hs_mpeg_params params;
- int err = 0;
int i;
- switch (cmd) {
- case VIDIOC_INT_INIT:
- /* apply settings and start encoder */
- saa6752hs_init(client, *(u32 *)arg);
- break;
- case VIDIOC_S_EXT_CTRLS:
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- /* fall through */
- case VIDIOC_TRY_EXT_CTRLS:
- case VIDIOC_G_EXT_CTRLS:
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- params = h->params;
- for (i = 0; i < ctrls->count; i++) {
- err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, cmd);
- if (err) {
- ctrls->error_idx = i;
- return err;
- }
+ if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ params = h->params;
+ for (i = 0; i < ctrls->count; i++) {
+ int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
+
+ if (err) {
+ ctrls->error_idx = i;
+ return err;
}
- h->params = params;
- break;
- case VIDIOC_QUERYCTRL:
- return saa6752hs_qctrl(h, arg);
- case VIDIOC_QUERYMENU:
- return saa6752hs_qmenu(h, arg);
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
-
- if (h->video_format == SAA6752HS_VF_UNKNOWN)
- h->video_format = SAA6752HS_VF_D1;
- f->fmt.pix.width =
- v4l2_format_table[h->video_format].fmt.pix.width;
- f->fmt.pix.height =
- v4l2_format_table[h->video_format].fmt.pix.height;
- break ;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
+ if (set)
+ h->params = params;
+ return 0;
+}
- saa6752hs_set_subsampling(client, f);
- break;
+static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
+}
+
+static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
+}
+
+static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ struct saa6752hs_state *h = to_state(sd);
+ int i;
+
+ if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
+
+ if (err) {
+ ctrls->error_idx = i;
+ return err;
+ }
}
- case VIDIOC_S_STD:
- h->standard = *((v4l2_std_id *) arg);
- break;
+ return 0;
+}
- case VIDIOC_DBG_G_CHIP_IDENT:
- return v4l2_chip_ident_i2c_client(client,
- arg, h->chip, h->revision);
+static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+ struct saa6752hs_state *h = to_state(sd);
- default:
- /* nothing */
- break;
+ if (h->video_format == SAA6752HS_VF_UNKNOWN)
+ h->video_format = SAA6752HS_VF_D1;
+ f->fmt.pix.width =
+ v4l2_format_table[h->video_format].fmt.pix.width;
+ f->fmt.pix.height =
+ v4l2_format_table[h->video_format].fmt.pix.height;
+ return 0;
+}
+
+static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+ struct saa6752hs_state *h = to_state(sd);
+ int dist_352, dist_480, dist_720;
+
+ /*
+ FIXME: translate and round width/height into EMPRESS
+ subsample type:
+
+ type | PAL | NTSC
+ ---------------------------
+ SIF | 352x288 | 352x240
+ 1/2 D1 | 352x576 | 352x480
+ 2/3 D1 | 480x576 | 480x480
+ D1 | 720x576 | 720x480
+ */
+
+ dist_352 = abs(f->fmt.pix.width - 352);
+ dist_480 = abs(f->fmt.pix.width - 480);
+ dist_720 = abs(f->fmt.pix.width - 720);
+ if (dist_720 < dist_480) {
+ f->fmt.pix.width = 720;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_D1;
+ } else if (dist_480 < dist_352) {
+ f->fmt.pix.width = 480;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_2_3_D1;
+ } else {
+ f->fmt.pix.width = 352;
+ if (abs(f->fmt.pix.height - 576) <
+ abs(f->fmt.pix.height - 288)) {
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_1_2_D1;
+ } else {
+ f->fmt.pix.height = 288;
+ h->video_format = SAA6752HS_VF_SIF;
+ }
}
+ return 0;
+}
+
+static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct saa6752hs_state *h = to_state(sd);
+
+ h->standard = std;
+ return 0;
+}
- return err;
+static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa6752hs_state *h = to_state(sd);
+
+ return v4l2_chip_ident_i2c_client(client,
+ chip, h->chip, h->revision);
}
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
+ .g_chip_ident = saa6752hs_g_chip_ident,
+ .init = saa6752hs_init,
+ .queryctrl = saa6752hs_queryctrl,
+ .querymenu = saa6752hs_querymenu,
+ .g_ext_ctrls = saa6752hs_g_ext_ctrls,
+ .s_ext_ctrls = saa6752hs_s_ext_ctrls,
+ .try_ext_ctrls = saa6752hs_try_ext_ctrls,
+};
+
+static const struct v4l2_subdev_tuner_ops saa6752hs_tuner_ops = {
+ .s_std = saa6752hs_s_std,
+};
+
+static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
+ .s_fmt = saa6752hs_s_fmt,
+ .g_fmt = saa6752hs_g_fmt,
+};
+
+static const struct v4l2_subdev_ops saa6752hs_ops = {
+ .core = &saa6752hs_core_ops,
+ .tuner = &saa6752hs_tuner_ops,
+ .video = &saa6752hs_video_ops,
+};
+
static int saa6752hs_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
+ struct v4l2_subdev *sd;
u8 addr = 0x13;
u8 data[12];
@@ -861,6 +949,8 @@ static int saa6752hs_probe(struct i2c_client *client,
client->addr << 1, client->adapter->name);
if (h == NULL)
return -ENOMEM;
+ sd = &h->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops);
i2c_master_send(client, &addr, 1);
i2c_master_recv(client, data, sizeof(data));
@@ -874,14 +964,15 @@ static int saa6752hs_probe(struct i2c_client *client,
}
h->params = param_defaults;
h->standard = 0; /* Assume 625 input lines */
-
- i2c_set_clientdata(client, h);
return 0;
}
static int saa6752hs_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
return 0;
}
@@ -893,8 +984,6 @@ MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa6752hs",
- .driverid = I2C_DRIVERID_SAA6752HS,
- .command = saa6752hs_command,
.probe = saa6752hs_probe,
.remove = saa6752hs_remove,
.id_table = saa6752hs_id,
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 26194a0ce927..c750d3dd57d2 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -1089,7 +1089,11 @@ static int saa7134_alsa_init(void)
list_for_each(list,&saa7134_devlist) {
dev = list_entry(list, struct saa7134_dev, devlist);
- alsa_device_init(dev);
+ if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+ printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
+ dev->name, saa7134_boards[dev->board].name);
+ else
+ alsa_device_init(dev);
}
if (dev == NULL)
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index e2febcd6e529..67c223cc867f 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.tv = 1,
}, {
- .name = name_comp,
- .vmux = 0,
+ .name = name_comp1,
+ .vmux = 3,
.amux = LINE1,
}, {
.name = name_svideo,
.vmux = 8,
- .amux = LINE1,
+ .amux = LINE2,
} },
.radio = {
.name = name_radio,
@@ -4611,7 +4611,7 @@ struct saa7134_board saa7134_boards[] = {
.tuner_type = TUNER_YMEC_TVF_5533MF,
.radio_type = TUNER_TEA5767,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .radio_addr = 0x60,
.gpiomask = 0x80000700,
.inputs = { {
.name = name_tv,
@@ -6019,6 +6019,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
msleep(10);
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ saa7134_set_gpio(dev, 23, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 23, 1);
+ dev->has_remote = SAA7134_REMOTE_I2C;
+ break;
case SAA7134_BOARD_AVERMEDIA_M103:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
@@ -6109,7 +6114,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tun_setup.mode_mask = T_RADIO;
- saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ saa_call_all(dev, tuner, s_type_addr, &tun_setup);
mode_mask &= ~T_RADIO;
}
@@ -6121,7 +6126,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tun_setup.mode_mask = mode_mask;
- saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ saa_call_all(dev, tuner, s_type_addr, &tun_setup);
}
if (dev->tda9887_conf) {
@@ -6130,8 +6135,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &dev->tda9887_conf;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
}
if (dev->tuner_type == TUNER_XC2028) {
@@ -6158,7 +6162,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+ saa_call_all(dev, tuner, s_config, &xc2028_cfg);
}
}
@@ -6168,9 +6172,20 @@ int saa7134_board_init2(struct saa7134_dev *dev)
unsigned char buf;
int board;
+ /* Put here the code that enables the chips that are needed
+ for analog mode and doesn't depend on the tuner attachment.
+ It is also a good idea to get tuner type from eeprom, etc before
+ initializing tuner, since we can avoid loading tuner driver
+ on devices that has TUNER_ABSENT
+ */
switch (dev->board) {
case SAA7134_BOARD_BMK_MPEX_NOTUNER:
case SAA7134_BOARD_BMK_MPEX_TUNER:
+ /* Checks if the device has a tuner at 0x60 addr
+ If the device doesn't have a tuner, TUNER_ABSENT
+ will be used at tuner_type, avoiding loading tuner
+ without needing it
+ */
dev->i2c_client.addr = 0x60;
board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
? SAA7134_BOARD_BMK_MPEX_NOTUNER
@@ -6188,11 +6203,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
u8 subaddr;
u8 data[3];
int ret, tuner_t;
-
struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
+
subaddr= 0x14;
tuner_t = 0;
+
+ /* Retrieve device data from eeprom, checking for the
+ proper tuner_type.
+ */
ret = i2c_transfer(&dev->i2c_adap, msg, 2);
if (ret != 2) {
printk(KERN_ERR "EEPROM read failure\n");
@@ -6248,12 +6267,14 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name, saa7134_boards[dev->board].name);
break;
}
+ /* break intentionally omitted */
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
{
- /* The Philips EUROPA based hybrid boards have the tuner connected through
- * the channel decoder. We have to make it transparent to find it
+ /* The Philips EUROPA based hybrid boards have the tuner
+ connected through the channel decoder. We have to make it
+ transparent to find it
*/
u8 data[] = { 0x07, 0x02};
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
@@ -6274,21 +6295,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
dev->tuner_type = TUNER_PHILIPS_TDA8290;
- saa7134_tuner_setup(dev);
-
data[2] = 0x68;
i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- /* Tuner setup is handled before I2C transfer.
- Due to that, there's no need to do it later
- */
- return 0;
+ break;
}
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ASUSTeK_TVFM7135:
- /* The card below is detected as card=53, but is different */
+ case SAA7134_BOARD_ASUSTeK_TVFM7135:
+ /* The card below is detected as card=53, but is different */
if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
printk(KERN_INFO "%s: P7131 analog only, using "
@@ -6351,22 +6366,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
- case SAA7134_BOARD_KWORLD_ATSC110:
- {
- /* enable tuner */
- int i;
- static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16,
- 0x00, 0x14, 0x04, 0x17, 0x00 };
- dev->i2c_client.addr = 0x0a;
- for (i = 0; i < 5; i++)
- if (2 != i2c_master_send(&dev->i2c_client,
- &buffer[i*2], 2))
- printk(KERN_WARNING
- "%s: Unable to enable tuner(%i).\n",
- dev->name, i);
- break;
- }
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
/* The T200 and the T200A share the same pci id. Consequently,
@@ -6375,9 +6374,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
/* Don't do this if the board was specifically selected with an
* insmod option or if we have the default configuration T200*/
- if(!dev->autodetected || (dev->eedata[0x41] == 0xd0))
+ if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
break;
- if(dev->eedata[0x41] == 0x02) {
+ if (dev->eedata[0x41] == 0x02) {
/* Reconfigure board as T200A */
dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
@@ -6390,6 +6389,58 @@ int saa7134_board_init2(struct saa7134_dev *dev)
break;
}
break;
+ case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
+ case SAA7134_BOARD_KWORLD_ATSC110:
+ {
+ struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
+ int i;
+ static u8 buffer[][2] = {
+ { 0x10, 0x12 },
+ { 0x13, 0x04 },
+ { 0x16, 0x00 },
+ { 0x14, 0x04 },
+ { 0x17, 0x00 },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+ msg.buf = &buffer[i][0];
+ msg.len = ARRAY_SIZE(buffer[0]);
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ printk(KERN_WARNING
+ "%s: Unable to enable tuner(%i).\n",
+ dev->name, i);
+ }
+ break;
+ }
+ } /* switch() */
+
+ /* initialize tuner */
+ if (TUNER_ABSENT != dev->tuner_type) {
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+ /* Note: radio tuner address is always filled in,
+ so we do not need to probe for a radio tuner device. */
+ if (dev->radio_type != UNSET)
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->radio_addr);
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == ADDR_UNSET) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+ } else {
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ }
+ }
+
+ saa7134_tuner_setup(dev);
+
+ switch (dev->board) {
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
{
struct v4l2_priv_tun_config tea5767_cfg;
@@ -6401,12 +6452,10 @@ int saa7134_board_init2(struct saa7134_dev *dev)
ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
tea5767_cfg.tuner = TUNER_TEA5767;
tea5767_cfg.priv = &ctl;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg);
+ saa_call_all(dev, tuner, s_config, &tea5767_cfg);
break;
}
} /* switch() */
- saa7134_tuner_setup(dev);
-
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index dfbe08a9ad9b..ac574452d01e 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -54,13 +54,9 @@ static unsigned int gpio_tracking;
module_param(gpio_tracking, int, 0644);
MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
-static unsigned int alsa;
+static unsigned int alsa = 1;
module_param(alsa, int, 0644);
-MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
-
-static unsigned int oss;
-module_param(oss, int, 0644);
-MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
+MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]");
static unsigned int latency = UNSET;
module_param(latency, int, 0444);
@@ -90,8 +86,10 @@ MODULE_PARM_DESC(radio_nr, "radio device number");
MODULE_PARM_DESC(tuner, "tuner type");
MODULE_PARM_DESC(card, "card type");
-static DEFINE_MUTEX(devlist_lock);
+DEFINE_MUTEX(saa7134_devlist_lock);
+EXPORT_SYMBOL(saa7134_devlist_lock);
LIST_HEAD(saa7134_devlist);
+EXPORT_SYMBOL(saa7134_devlist);
static LIST_HEAD(mops_list);
static unsigned int saa7134_devcount;
@@ -156,10 +154,10 @@ static void request_module_async(struct work_struct *work){
request_module("saa7134-empress");
if (card_is_dvb(dev))
request_module("saa7134-dvb");
- if (alsa)
- request_module("saa7134-alsa");
- if (oss)
- request_module("saa7134-oss");
+ if (alsa) {
+ if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
+ request_module("saa7134-alsa");
+ }
}
static void request_submodules(struct saa7134_dev *dev)
@@ -660,6 +658,10 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, 0);
+
+ /* Clear any stale IRQ reports */
+ saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT));
+
mutex_init(&dev->lock);
spin_lock_init(&dev->slock);
@@ -847,6 +849,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
if (NULL == dev)
return -ENOMEM;
+ err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+ if (err)
+ goto fail0;
+
/* pci init */
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
@@ -923,6 +929,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->autodetected = card[dev->nr] != dev->board;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
+ dev->radio_type = saa7134_boards[dev->board].radio_type;
+ dev->radio_addr = saa7134_boards[dev->board].radio_addr;
dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
if (UNSET != tuner[dev->nr])
dev->tuner_type = tuner[dev->nr];
@@ -967,23 +975,36 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* wait a bit, register i2c bus */
msleep(100);
saa7134_i2c_register(dev);
-
- /* initialize hardware #2 */
- if (TUNER_ABSENT != dev->tuner_type)
- request_module("tuner");
saa7134_board_init2(dev);
saa7134_hwinit2(dev);
/* load i2c helpers */
if (card_is_empress(dev)) {
- request_module("saa6752hs");
+ struct v4l2_subdev *sd =
+ v4l2_i2c_new_subdev(&dev->i2c_adap, "saa6752hs",
+ "saa6752hs", 0x20);
+
+ if (sd)
+ sd->grp_id = GRP_EMPRESS;
}
request_submodules(dev);
v4l2_prio_init(&dev->prio);
+ mutex_lock(&saa7134_devlist_lock);
+ list_for_each_entry(mops, &mops_list, next)
+ mpeg_ops_attach(mops, dev);
+ list_add_tail(&dev->devlist, &saa7134_devlist);
+ mutex_unlock(&saa7134_devlist_lock);
+
+ /* check for signal */
+ saa7134_irq_video_signalchange(dev);
+
+ if (TUNER_ABSENT != dev->tuner_type)
+ saa_call_all(dev, core, s_standby, 0);
+
/* register v4l devices */
if (saa7134_no_overlay > 0)
printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
@@ -1019,24 +1040,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
}
/* everything worked */
- pci_set_drvdata(pci_dev,dev);
saa7134_devcount++;
- mutex_lock(&devlist_lock);
- list_for_each_entry(mops, &mops_list, next)
- mpeg_ops_attach(mops, dev);
- list_add_tail(&dev->devlist,&saa7134_devlist);
- mutex_unlock(&devlist_lock);
-
- /* check for signal */
- saa7134_irq_video_signalchange(dev);
-
- if (saa7134_dmasound_init && !dev->dmasound.priv_data) {
+ if (saa7134_dmasound_init && !dev->dmasound.priv_data)
saa7134_dmasound_init(dev);
- }
-
- if (TUNER_ABSENT != dev->tuner_type)
- saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
return 0;
@@ -1051,13 +1058,16 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
fail1:
+ v4l2_device_unregister(&dev->v4l2_dev);
+ fail0:
kfree(dev);
return err;
}
static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
{
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
struct saa7134_mpeg_ops *mops;
/* Release DMA sound modules if present */
@@ -1084,11 +1094,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
saa7134_hwfini(dev);
/* unregister */
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&dev->devlist);
list_for_each_entry(mops, &mops_list, next)
mpeg_ops_detach(mops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
saa7134_devcount--;
saa7134_i2c_unregister(dev);
@@ -1109,7 +1119,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
- pci_set_drvdata(pci_dev, NULL);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
/* free memory */
kfree(dev);
@@ -1144,8 +1155,8 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev,
static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
{
-
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
/* disable overlay - apps should enable it explicitly on resume*/
dev->ovenable = 0;
@@ -1181,7 +1192,8 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
static int saa7134_resume(struct pci_dev *pci_dev)
{
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
unsigned long flags;
pci_set_power_state(pci_dev, PCI_D0);
@@ -1243,11 +1255,11 @@ int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_attach(ops, dev);
list_add_tail(&ops->next,&mops_list);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
return 0;
}
@@ -1255,11 +1267,11 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&ops->next);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_detach(ops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
}
EXPORT_SYMBOL(saa7134_ts_register);
@@ -1303,8 +1315,6 @@ module_exit(saa7134_fini);
/* ----------------------------------------------------------- */
EXPORT_SYMBOL(saa7134_set_gpio);
-EXPORT_SYMBOL(saa7134_i2c_call_clients);
-EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards);
/* ----------------- for the DMA sound modules --------------- */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 0776ecf56d27..2276c928aaef 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -189,7 +189,7 @@ static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(&dev->i2c_adap, &msg, 1);
- saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+ saa_call_all(dev, tuner, s_frequency, &f);
msg.buf = on;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -1448,7 +1448,7 @@ static int dvb_fini(struct saa7134_dev *dev)
tda9887_cfg.priv = &on;
/* otherwise we don't detect the tuner on next insmod */
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
} else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) {
if ((dev->eedata[2] == 0x07) && use_frontend) {
/* turn off the 2nd lnb supply */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index c9d8beb87a60..2e15bb7c3f0a 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -76,7 +76,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
break;
}
ts_reset_encoder(dev);
- saa7134_i2c_call_clients(dev, VIDIOC_INT_INIT, &leading_null_bytes);
+ saa_call_all(dev, core, init, leading_null_bytes);
dev->empress_started = 1;
return 0;
}
@@ -234,7 +234,7 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,
{
struct saa7134_dev *dev = file->private_data;
- saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ saa_call_all(dev, video, g_fmt, f);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -247,7 +247,7 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
{
struct saa7134_dev *dev = file->private_data;
- saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f);
+ saa_call_all(dev, video, s_fmt, f);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -317,7 +317,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls);
+ err = saa_call_empress(dev, core, s_ext_ctrls, ctrls);
ts_init_encoder(dev);
return err;
@@ -330,7 +330,7 @@ static int empress_g_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+ return saa_call_empress(dev, core, g_ext_ctrls, ctrls);
}
static int empress_g_ctrl(struct file *file, void *priv,
@@ -352,6 +352,7 @@ static int empress_s_ctrl(struct file *file, void *priv,
static int empress_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *c)
{
+ /* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -364,6 +365,7 @@ static int empress_queryctrl(struct file *file, void *priv,
0
};
+ /* Must be sorted from low to high control ID! */
static const u32 mpeg_ctrls[] = {
V4L2_CID_MPEG_CLASS,
V4L2_CID_MPEG_STREAM_TYPE,
@@ -391,7 +393,7 @@ static int empress_queryctrl(struct file *file, void *priv,
return v4l2_ctrl_query_fill_std(c);
if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
return saa7134_queryctrl(file, priv, c);
- return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c);
+ return saa_call_empress(dev, core, queryctrl, c);
}
static int empress_querymenu(struct file *file, void *priv,
@@ -401,7 +403,7 @@ static int empress_querymenu(struct file *file, void *priv,
if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
+ return saa_call_empress(dev, core, querymenu, c);
}
static int empress_g_chip_ident(struct file *file, void *fh,
@@ -411,14 +413,12 @@ static int empress_g_chip_ident(struct file *file, void *fh,
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- if (dev->mpeg_i2c_client == NULL)
- return -EINVAL;
if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
!strcmp(chip->match.name, "saa6752hs"))
- return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+ return saa_call_empress(dev, core, g_chip_ident, chip);
if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR &&
- chip->match.addr == dev->mpeg_i2c_client->addr)
- return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+ chip->match.addr == 0x20)
+ return saa_call_empress(dev, core, g_chip_ident, chip);
return -EINVAL;
}
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 20c1b33caf7b..f3e285aa2fb4 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -255,7 +255,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
addr = msgs[i].addr << 1;
if (msgs[i].flags & I2C_M_RD)
addr |= 1;
- if (i > 0 && msgs[i].flags & I2C_M_RD) {
+ if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) {
/* workaround for a saa7134 i2c bug
* needed to talk to the mt352 demux
* thanks to pinnacle for the hint */
@@ -327,8 +327,6 @@ static int attach_inform(struct i2c_client *client)
d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
client->driver->driver.name, client->addr, client->name);
- if (client->addr == 0x20 && client->driver && client->driver->command)
- dev->mpeg_i2c_client = client;
/* Am I an i2c remote control? */
@@ -357,7 +355,6 @@ static struct i2c_algorithm saa7134_algo = {
static struct i2c_adapter saa7134_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
.name = "saa7134",
.id = I2C_HW_SAA7134,
.algo = &saa7134_algo,
@@ -421,29 +418,13 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
}
}
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
- unsigned int cmd, void *arg)
-{
- BUG_ON(NULL == dev->i2c_adap.algo_data);
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
- unsigned int cmd, void *arg)
-{
- if (dev->mpeg_i2c_client == NULL)
- return -EINVAL;
- return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client,
- cmd, arg);
-}
-EXPORT_SYMBOL_GPL(saa7134_i2c_call_saa6752);
-
int saa7134_i2c_register(struct saa7134_dev *dev)
{
dev->i2c_adap = saa7134_adap_template;
dev->i2c_adap.dev.parent = &dev->pci->dev;
strcpy(dev->i2c_adap.name,dev->name);
dev->i2c_adap.algo_data = dev;
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&dev->i2c_adap);
dev->i2c_client = saa7134_client_template;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index a1f7e351f572..aa7fa1f73a56 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -452,6 +452,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset odd field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -459,6 +460,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset even field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -627,10 +629,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
saa7134_set_decoder(dev);
if (card_in(dev, dev->ctl_input).tv)
- saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+ saa_call_all(dev, tuner, s_std, dev->tvnorm->id);
/* Set the correct norm for the saa6752hs. This function
does nothing if there is no saa6752hs. */
- saa7134_i2c_call_saa6752(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+ saa_call_empress(dev, tuner, s_std, dev->tvnorm->id);
}
static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -1266,8 +1268,7 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str
else
dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
}
break;
}
@@ -1334,7 +1335,7 @@ static int video_open(struct file *file)
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int radio = 0;
- lock_kernel();
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist) {
if (dev->video_dev && (dev->video_dev->minor == minor))
goto found;
@@ -1347,19 +1348,20 @@ static int video_open(struct file *file)
goto found;
}
}
- unlock_kernel();
+ mutex_unlock(&saa7134_devlist_lock);
return -ENODEV;
- found:
+
+found:
+ mutex_unlock(&saa7134_devlist_lock);
dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh) {
- unlock_kernel();
+ if (NULL == fh)
return -ENOMEM;
- }
+
file->private_data = fh;
fh->dev = dev;
fh->radio = radio;
@@ -1387,12 +1389,11 @@ static int video_open(struct file *file)
if (fh->radio) {
/* switch to radio mode */
saa7134_tvaudio_setinput(dev,&card(dev).radio);
- saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
+ saa_call_all(dev, tuner, s_radio);
} else {
/* switch to video/vbi mode */
video_mux(dev,dev->ctl_input);
}
- unlock_kernel();
return 0;
}
@@ -1498,7 +1499,7 @@ static int video_release(struct file *file)
saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
- saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ saa_call_all(dev, core, s_standby, 0);
/* free stuff */
videobuf_mmap_free(&fh->cap);
@@ -2041,7 +2042,7 @@ static int saa7134_s_frequency(struct file *file, void *priv,
mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
- saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+ saa_call_all(dev, tuner, s_frequency, f);
saa7134_tvaudio_do_scan(dev);
mutex_unlock(&dev->lock);
@@ -2299,7 +2300,7 @@ static int radio_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+ saa_call_all(dev, tuner, g_tuner, t);
if (dev->input->amux == TV) {
t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
t->rxsubchans = (saa_readb(0x529) & 0x08) ?
@@ -2316,7 +2317,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+ saa_call_all(dev, tuner, s_tuner, t);
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 14ee265f3374..4552a4d6f192 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -35,6 +35,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/ir-common.h>
#include <media/ir-kbd-i2c.h>
@@ -445,7 +446,6 @@ struct saa7134_dmasound {
unsigned int bufsize;
struct saa7134_pgtable pt;
struct videobuf_dmabuf dma;
- wait_queue_head_t wq;
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
@@ -482,6 +482,7 @@ struct saa7134_dev {
struct mutex lock;
spinlock_t slock;
struct v4l2_prio_state prio;
+ struct v4l2_device v4l2_dev;
/* workstruct for loading modules */
struct work_struct request_module_wk;
@@ -572,7 +573,6 @@ struct saa7134_dev {
enum saa7134_ts_status ts_state;
unsigned int buff_cnt;
struct saa7134_mpeg_ops *mops;
- struct i2c_client *mpeg_i2c_client;
/* SAA7134_MPEG_EMPRESS only */
struct video_device *empress_dev;
@@ -588,6 +588,7 @@ struct saa7134_dev {
int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
#endif
+ void (*gate_ctrl)(struct saa7134_dev *dev, int open);
};
/* ----------------------------------------------------------- */
@@ -616,10 +617,31 @@ struct saa7134_dev {
V4L2_STD_NTSC | V4L2_STD_PAL_M | \
V4L2_STD_PAL_60)
+#define GRP_EMPRESS (1)
+#define saa_call_all(dev, o, f, args...) do { \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+} while (0)
+
+#define saa_call_empress(dev, o, f, args...) ({ \
+ long _rc; \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ _rc = v4l2_device_call_until_err(&(dev)->v4l2_dev, \
+ GRP_EMPRESS, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+ _rc; \
+})
+
/* ----------------------------------------------------------- */
/* saa7134-core.c */
extern struct list_head saa7134_devlist;
+extern struct mutex saa7134_devlist_lock;
extern int saa7134_no_overlay;
void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
@@ -668,10 +690,6 @@ int saa7134_tuner_callback(void *priv, int component, int command, int arg);
int saa7134_i2c_register(struct saa7134_dev *dev);
int saa7134_i2c_unregister(struct saa7134_dev *dev);
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
- unsigned int cmd, void *arg);
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
- unsigned int cmd, void *arg);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 454ad1dd7507..5ad7a77699de 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -30,7 +30,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -932,7 +931,7 @@ static int saa717x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -1529,7 +1528,6 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa717x",
- .driverid = I2C_DRIVERID_SAA717X,
.command = saa717x_command,
.probe = saa717x_probe,
.remove = saa717x_remove,
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index 29991d1cf13e..b30c49248217 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -50,7 +50,7 @@ struct tcm825x_sensor {
};
/* list of image formats supported by TCM825X sensor */
-const static struct v4l2_fmtdesc tcm825x_formats[] = {
+static const struct v4l2_fmtdesc tcm825x_formats[] = {
{
.description = "YUYV (YUV 4:2:2), packed",
.pixelformat = V4L2_PIX_FMT_UYVY,
@@ -76,15 +76,15 @@ const static struct v4l2_fmtdesc tcm825x_formats[] = {
* TCM825X register configuration for all combinations of pixel format and
* image size
*/
-const static struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ };
-const static struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ };
-const static struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ };
-const static struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ };
-const static struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ };
-const static struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ };
+static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ };
+static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ };
+static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ };
+static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ };
+static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ };
+static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ };
-const static struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT };
-const static struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT };
+static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT };
+static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT };
/* Our own specific controls */
#define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE
@@ -248,10 +248,10 @@ static struct vcontrol {
};
-const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
+static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
{ &subqcif, &qqvga, &qcif, &qvga, &cif, &vga };
-const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
+static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
{ &yuv422, &rgb565 };
/*
diff --git a/drivers/media/video/tcm825x.h b/drivers/media/video/tcm825x.h
index 770ebacfa344..5b7e69682368 100644
--- a/drivers/media/video/tcm825x.h
+++ b/drivers/media/video/tcm825x.h
@@ -188,7 +188,7 @@ struct tcm825x_platform_data {
/* Array of image sizes supported by TCM825X. These must be ordered from
* smallest image size to largest.
*/
-const static struct capture_size tcm825x_sizes[] = {
+static const struct capture_size tcm825x_sizes[] = {
{ 128, 96 }, /* subQCIF */
{ 160, 120 }, /* QQVGA */
{ 176, 144 }, /* QCIF */
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 0c020585fffb..2090e170bd9c 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -498,7 +498,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda7432",
- .driverid = I2C_DRIVERID_TDA7432,
.command = tda7432_command,
.probe = tda7432_probe,
.remove = tda7432_remove,
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 6afb7059502d..fe1158094c24 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -30,8 +30,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-#include "tda9840.h"
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("tda9840 driver");
@@ -56,11 +56,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define TDA9840_SET_BOTH_R 0x16
#define TDA9840_SET_EXTERNAL 0x7a
-/* addresses to scan, found only at 0x42 (7-Bit) */
-static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
@@ -137,60 +132,17 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
return 0;
}
-static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- int byte;
-
- switch (cmd) {
- case TDA9840_LEVEL_ADJUST:
- byte = *(int *)arg;
- v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte);
-
- /* check for correct range */
- if (byte > 25 || byte < -20)
- return -EINVAL;
-
- /* calculate actual value to set, see specs, page 18 */
- byte /= 5;
- if (0 < byte)
- byte += 0x8;
- else
- byte = -byte;
- tda9840_write(sd, LEVEL_ADJUST, byte);
- break;
-
- case TDA9840_STEREO_ADJUST:
- byte = *(int *)arg;
- v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte);
-
- /* check for correct range */
- if (byte > 25 || byte < -24)
- return -EINVAL;
-
- /* calculate actual value to set */
- byte /= 5;
- if (0 < byte)
- byte += 0x20;
- else
- byte = -byte;
-
- tda9840_write(sd, STEREO_ADJUST, byte);
- break;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
-static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda9840_core_ops = {
- .ioctl = tda9840_ioctl,
+ .g_chip_ident = tda9840_g_chip_ident,
};
static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
@@ -209,8 +161,6 @@ static int tda9840_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct v4l2_subdev *sd;
- int result;
- int byte;
/* let's see whether this adapter can support what we need */
if (!i2c_check_functionality(client->adapter,
@@ -227,15 +177,9 @@ static int tda9840_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
/* set initial values for level & stereo - adjustment, mode */
- byte = 0;
- result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte);
- result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte);
+ tda9840_write(sd, LEVEL_ADJUST, 0);
+ tda9840_write(sd, STEREO_ADJUST, 0);
tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
- if (result) {
- v4l2_dbg(1, debug, sd, "could not initialize tda9840\n");
- kfree(sd);
- return -ENODEV;
- }
return 0;
}
@@ -248,12 +192,7 @@ static int tda9840_remove(struct i2c_client *client)
return 0;
}
-static int tda9840_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
+
static const struct i2c_device_id tda9840_id[] = {
{ "tda9840", 0 },
{ }
@@ -262,10 +201,7 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda9840",
- .driverid = I2C_DRIVERID_TDA9840,
- .command = tda9840_command,
.probe = tda9840_probe,
.remove = tda9840_remove,
- .legacy_probe = tda9840_legacy_probe,
.id_table = tda9840_id,
};
diff --git a/drivers/media/video/tda9840.h b/drivers/media/video/tda9840.h
deleted file mode 100644
index dc12ae7caf6f..000000000000
--- a/drivers/media/video/tda9840.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __INCLUDED_TDA9840__
-#define __INCLUDED_TDA9840__
-
-#define I2C_ADDR_TDA9840 0x42
-
-/* values may range between +2.5 and -2.0;
- the value has to be multiplied with 10 */
-#define TDA9840_LEVEL_ADJUST _IOW('v',3,int)
-
-/* values may range between +2.5 and -2.4;
- the value has to be multiplied with 10 */
-#define TDA9840_STEREO_ADJUST _IOW('v',4,int)
-
-#endif
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 56f0c0eb500f..19fbd18f4882 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -242,7 +242,7 @@ static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct tda9875 *t = to_state(sd);
- int chvol=0, volume, balance, left, right;
+ int chvol = 0, volume = 0, balance = 0, left, right;
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
@@ -401,7 +401,6 @@ MODULE_DEVICE_TABLE(i2c, tda9875_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda9875",
- .driverid = I2C_DRIVERID_TDA9875,
.command = tda9875_command,
.probe = tda9875_probe,
.remove = tda9875_remove,
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 7519fd1f57ef..d61c56f42bcd 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -32,7 +32,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "tea6415c.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,25 +45,22 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
-static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
-
-/* makes a connection between the input-pin 'i' and the output-pin 'o'
- for the tea6415c-client 'client' */
-static int switch_matrix(struct i2c_client *client, int i, int o)
+/* makes a connection between the input-pin 'i' and the output-pin 'o' */
+static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 byte = 0;
+ u32 i = route->input;
+ u32 o = route->output;
int ret;
- v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o);
+ v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);
/* check if the pins are valid */
if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i)
&& (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
- return -1;
+ return -EINVAL;
/* to understand this, have a look at the tea6415c-specs (p.5) */
switch (o) {
@@ -115,37 +113,33 @@ static int switch_matrix(struct i2c_client *client, int i, int o)
ret = i2c_smbus_write_byte(client, byte);
if (ret) {
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"i2c_smbus_write_byte() failed, ret:%d\n", ret);
return -EIO;
}
return ret;
}
-static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- if (cmd == TEA6415C_SWITCH) {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return switch_matrix(client, v->in, v->out);
- }
- return -ENOIOCTLCMD;
-}
-
-static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
- .ioctl = tea6415c_ioctl,
+ .g_chip_ident = tea6415c_g_chip_ident,
+};
+
+static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
+ .s_routing = tea6415c_s_routing,
};
static const struct v4l2_subdev_ops tea6415c_ops = {
.core = &tea6415c_core_ops,
+ .video = &tea6415c_video_ops,
};
/* this function is called by i2c_probe */
@@ -176,12 +170,6 @@ static int tea6415c_remove(struct i2c_client *client)
return 0;
}
-static int tea6415c_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
static const struct i2c_device_id tea6415c_id[] = {
{ "tea6415c", 0 },
@@ -191,10 +179,7 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tea6415c",
- .driverid = I2C_DRIVERID_TEA6415C,
- .command = tea6415c_command,
.probe = tea6415c_probe,
.remove = tea6415c_remove,
- .legacy_probe = tea6415c_legacy_probe,
.id_table = tea6415c_id,
};
diff --git a/drivers/media/video/tea6415c.h b/drivers/media/video/tea6415c.h
index f84ed80050b3..3a47d697536e 100644
--- a/drivers/media/video/tea6415c.h
+++ b/drivers/media/video/tea6415c.h
@@ -1,10 +1,6 @@
#ifndef __INCLUDED_TEA6415C__
#define __INCLUDED_TEA6415C__
-/* possible i2c-addresses */
-#define I2C_TEA6415C_1 0x03
-#define I2C_TEA6415C_2 0x43
-
/* the tea6415c's design is quite brain-dead. although there are
8 inputs and 6 outputs, these aren't enumerated in any way. because
I don't want to say "connect input pin 20 to output pin 17", I define
@@ -28,12 +24,4 @@
#define TEA6415C_INPUT7 1
#define TEA6415C_INPUT8 11
-struct tea6415c_multiplex
-{
- int in; /* input-pin */
- int out; /* output-pin */
-};
-
-#define TEA6415C_SWITCH _IOW('v',1,struct tea6415c_multiplex)
-
#endif
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 081e74fa3b2e..34922232402a 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -32,7 +32,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "tea6420.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,24 +45,23 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
-static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
/* make a connection between the input 'i' and the output 'o'
- with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */
-static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
+ with gain 'g' (note: i = 6 means 'mute') */
+static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int i = route->input;
+ int o = route->output & 0xf;
+ int g = (route->output >> 4) & 0xf;
u8 byte;
int ret;
- v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g);
+ v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
/* check if the parameters are valid */
if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
- return -1;
+ return -EINVAL;
byte = ((o - 1) << 5);
byte |= (i - 1);
@@ -83,37 +83,33 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
ret = i2c_smbus_write_byte(client, byte);
if (ret) {
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"i2c_smbus_write_byte() failed, ret:%d\n", ret);
return -EIO;
}
return 0;
}
-static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- if (cmd == TEA6420_SWITCH) {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return tea6420_switch(client, a->in, a->out, a->gain);
- }
- return -ENOIOCTLCMD;
-}
-
-static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tea6420_core_ops = {
- .ioctl = tea6420_ioctl,
+ .g_chip_ident = tea6420_g_chip_ident,
+};
+
+static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
+ .s_routing = tea6420_s_routing,
};
static const struct v4l2_subdev_ops tea6420_ops = {
.core = &tea6420_core_ops,
+ .audio = &tea6420_audio_ops,
};
/* this function is called by i2c_probe */
@@ -130,20 +126,24 @@ static int tea6420_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
+ sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ if (sd == NULL)
+ return -ENOMEM;
+ v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
+
/* set initial values: set "mute"-input to all outputs at gain 0 */
err = 0;
for (i = 1; i < 5; i++) {
- err += tea6420_switch(client, 6, i, 0);
+ struct v4l2_routing route;
+
+ route.input = 6;
+ route.output = i;
+ err += tea6420_s_routing(sd, &route);
}
if (err) {
v4l_dbg(1, debug, client, "could not initialize tea6420\n");
return -ENODEV;
}
-
- sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
- if (sd == NULL)
- return -ENOMEM;
- v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
return 0;
}
@@ -156,12 +156,6 @@ static int tea6420_remove(struct i2c_client *client)
return 0;
}
-static int tea6420_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
static const struct i2c_device_id tea6420_id[] = {
{ "tea6420", 0 },
@@ -171,10 +165,7 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tea6420",
- .driverid = I2C_DRIVERID_TEA6420,
- .command = tea6420_command,
.probe = tea6420_probe,
.remove = tea6420_remove,
- .legacy_probe = tea6420_legacy_probe,
.id_table = tea6420_id,
};
diff --git a/drivers/media/video/tea6420.h b/drivers/media/video/tea6420.h
index 5ef7c18e0c54..4aa3edb3e193 100644
--- a/drivers/media/video/tea6420.h
+++ b/drivers/media/video/tea6420.h
@@ -1,17 +1,24 @@
#ifndef __INCLUDED_TEA6420__
#define __INCLUDED_TEA6420__
-/* possible addresses */
-#define I2C_ADDR_TEA6420_1 0x4c
-#define I2C_ADDR_TEA6420_2 0x4d
+/* input pins */
+#define TEA6420_OUTPUT1 1
+#define TEA6420_OUTPUT2 2
+#define TEA6420_OUTPUT3 3
+#define TEA6420_OUTPUT4 4
-struct tea6420_multiplex
-{
- int in; /* input of audio switch */
- int out; /* output of audio switch */
- int gain; /* gain of connection */
-};
+/* output pins */
+#define TEA6420_INPUT1 1
+#define TEA6420_INPUT2 2
+#define TEA6420_INPUT3 3
+#define TEA6420_INPUT4 4
+#define TEA6420_INPUT5 5
+#define TEA6420_INPUT6 6
-#define TEA6420_SWITCH _IOW('v',1,struct tea6420_multiplex)
+/* gain on the output pins, ORed with the output pin */
+#define TEA6420_GAIN0 0x00
+#define TEA6420_GAIN2 0x20
+#define TEA6420_GAIN4 0x40
+#define TEA6420_GAIN6 0x60
#endif
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 5c95ecd09dc2..b6e838ada66d 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -208,7 +208,6 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tlv320aic23b",
- .driverid = I2C_DRIVERID_TLV320AIC23B,
.command = tlv320aic23b_command,
.probe = tlv320aic23b_probe,
.remove = tlv320aic23b_remove,
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3b0b84c2e451..63705b8cd1ed 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -262,6 +262,11 @@ hauppauge_tuner[] =
{ TUNER_PHILIPS_TDA8290, "Philips 18271_8295"},
/* 150-159 */
{ TUNER_ABSENT, "Xceive XC5000"},
+ { TUNER_ABSENT, "Xceive XC3028L"},
+ { TUNER_ABSENT, "NXP 18271C2_716x"},
+ { TUNER_ABSENT, "Xceive XC4000"},
+ { TUNER_ABSENT, "Dibcom 7070"},
+ { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
};
/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
@@ -427,6 +432,9 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
memset(tvee, 0, sizeof(*tvee));
+ tvee->tuner_type = TUNER_ABSENT;
+ tvee->tuner2_type = TUNER_ABSENT;
+
done = len = beenhere = 0;
/* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index ac9aa40d09f6..5f4cbc2b23c1 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -686,7 +686,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
break; /* Input detected */
}
- if ((current_std == STD_INVALID) || (try_count < 0))
+ if ((current_std == STD_INVALID) || (try_count <= 0))
return -EINVAL;
decoder->current_std = current_std;
@@ -1401,7 +1401,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
decoder->pdata = client->dev.platform_data;
if (!decoder->pdata) {
- v4l_err(client, "No platform data\n!!");
+ v4l_err(client, "No platform data!!\n");
return -ENODEV;
}
/*
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 2cd64ef27b95..6b600bed445f 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -1126,7 +1126,6 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tvp5150",
- .driverid = I2C_DRIVERID_TVP5150,
.command = tvp5150_command,
.probe = tvp5150_probe,
.remove = tvp5150_remove,
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 52c0357faa5d..8dc3ec79a06f 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -645,6 +645,19 @@ static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt,
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
int ret = -EINVAL;
u8 val;
+ int i;
+
+ /*
+ * check color format
+ */
+ for (i = 0 ; i < ARRAY_SIZE(tw9910_color_fmt) ; i++) {
+ if (pixfmt == tw9910_color_fmt[i].fourcc) {
+ ret = 0;
+ break;
+ }
+ }
+ if (ret < 0)
+ goto tw9910_set_fmt_error;
/*
* select suitable norm
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index 4f16effb530f..5b2c4399027c 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -21,7 +21,6 @@
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
@@ -268,7 +267,6 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64031a",
- .driverid = I2C_DRIVERID_UPD64031A,
.command = upd64031a_command,
.probe = upd64031a_probe,
.remove = upd64031a_remove,
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 4b712f69d1b7..acd66c172efe 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -21,7 +21,6 @@
* 02110-1301, USA.
*/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
@@ -240,7 +239,6 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64083",
- .driverid = I2C_DRIVERID_UPD64083,
.command = upd64083_command,
.probe = upd64083_probe,
.remove = upd64083_remove,
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 9e4f50639975..4444e7e3cdf8 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -381,8 +381,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
usbvision->scratch = vmalloc_32(scratch_buf_size);
scratch_reset(usbvision);
if(usbvision->scratch == NULL) {
- err("%s: unable to allocate %d bytes for scratch",
- __func__, scratch_buf_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d bytes for scratch\n",
+ __func__, scratch_buf_size);
return -ENOMEM;
}
return 0;
@@ -491,8 +492,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
if (usbvision->IntraFrameBuffer == NULL) {
- err("%s: unable to allocate %d for compr. frame buffer",
- __func__, IFB_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d for compr. frame buffer\n",
+ __func__, IFB_size);
return -ENOMEM;
}
return 0;
@@ -1514,8 +1516,9 @@ static void usbvision_isocIrq(struct urb *urb)
errCode = usb_submit_urb (urb, GFP_ATOMIC);
if(errCode) {
- err("%s: usb_submit_urb failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb failed: error %d\n",
+ __func__, errCode);
}
return;
@@ -1546,7 +1549,8 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
0, (__u16) reg, buffer, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
return errCode;
}
return buffer[0];
@@ -1574,7 +1578,8 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
}
return errCode;
}
@@ -1850,7 +1855,8 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
if (errCode < 0) {
- err("%s failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s failed: error %d\n", __func__, errCode);
return errCode;
}
usbvision->curwidth = usbvision->stretch_width * UsbWidth;
@@ -2236,7 +2242,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
(__u16) USBVISION_DRM_PRM1, value, 8, HZ);
if (rc < 0) {
- err("%sERROR=%d", __func__, rc);
+ dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
return rc;
}
@@ -2432,8 +2438,9 @@ int usbvision_set_alternate(struct usb_usbvision *dev)
PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
if (errCode < 0) {
- err ("cannot change alternate number to %d (error=%i)",
- dev->ifaceAlt, errCode);
+ dev_err(&dev->dev->dev,
+ "cannot change alternate number to %d (error=%i)\n",
+ dev->ifaceAlt, errCode);
return errCode;
}
}
@@ -2484,7 +2491,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
if (urb == NULL) {
- err("%s: usb_alloc_urb() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_alloc_urb() failed\n", __func__);
return -ENOMEM;
}
usbvision->sbuf[bufIdx].urb = urb;
@@ -2516,8 +2524,9 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
GFP_KERNEL);
if (errCode) {
- err("%s: usb_submit_urb(%d) failed: error %d",
- __func__, bufIdx, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb(%d) failed: error %d\n",
+ __func__, bufIdx, errCode);
}
}
@@ -2566,8 +2575,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->ifaceAlt);
if (errCode < 0) {
- err("%s: usb_set_interface() failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_set_interface() failed: error %d\n",
+ __func__, errCode);
usbvision->last_error = errCode;
}
regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 9907b9aff2b9..6057098282ca 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -119,7 +119,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
/* try extended address code... */
ret = try_write_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while writing");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while writing\n");
return -EREMOTEIO;
}
add[0] = addr;
@@ -128,7 +129,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
addr |= 0x01;
ret = try_read_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while reading");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while reading\n");
return -EREMOTEIO;
}
}
@@ -157,7 +159,7 @@ usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
struct i2c_msg *pmsg;
struct usb_usbvision *usbvision;
int i, ret;
- unsigned char addr;
+ unsigned char addr = 0;
usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 2622de003a45..334c77d9116f 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -329,7 +329,7 @@ static void usbvision_create_sysfs(struct video_device *vdev)
return;
} while (0);
- err("%s error: %d\n", __func__, res);
+ dev_err(&vdev->dev, "%s error: %d\n", __func__, res);
}
static void usbvision_remove_sysfs(struct video_device *vdev)
@@ -487,8 +487,9 @@ static int vidioc_g_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_G_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
reg->val = errCode;
@@ -507,8 +508,9 @@ static int vidioc_s_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_S_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
return 0;
@@ -524,8 +526,7 @@ static int vidioc_querycap (struct file *file, void *priv,
strlcpy(vc->card,
usbvision_device_data[usbvision->DevModel].ModelString,
sizeof(vc->card));
- strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev),
- sizeof(vc->bus_info));
+ usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
vc->version = USBVISION_DRIVER_VERSION;
vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_AUDIO |
@@ -1189,7 +1190,9 @@ static int usbvision_radio_open(struct file *file)
mutex_lock(&usbvision->lock);
if (usbvision->user) {
- err("%s: Someone tried to open an already opened USBVision Radio!", __func__);
+ dev_err(&usbvision->rdev->dev,
+ "%s: Someone tried to open an already opened USBVision Radio!\n",
+ __func__);
errCode = -EBUSY;
}
else {
@@ -1413,7 +1416,8 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
struct video_device *vdev;
if (usb_dev == NULL) {
- err("%s: usbvision->dev is not set", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usbvision->dev is not set\n", __func__);
return NULL;
}
@@ -1524,7 +1528,9 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
return 0;
err_exit:
- err("USBVision[%d]: video_register_device() failed", usbvision->nr);
+ dev_err(&usbvision->dev->dev,
+ "USBVision[%d]: video_register_device() failed\n",
+ usbvision->nr);
usbvision_unregister_video(usbvision);
return -1;
}
@@ -1675,20 +1681,20 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
}
endpoint = &interface->endpoint[1].desc;
if (!usb_endpoint_xfer_isoc(endpoint)) {
- err("%s: interface %d. has non-ISO endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
__func__, ifnum);
- err("%s: Endpoint attributes %d",
+ dev_err(&intf->dev, "%s: Endpoint attributes %d",
__func__, endpoint->bmAttributes);
return -ENODEV;
}
if (usb_endpoint_dir_out(endpoint)) {
- err("%s: interface %d. has ISO OUT endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
__func__, ifnum);
return -ENODEV;
}
if ((usbvision = usbvision_alloc(dev)) == NULL) {
- err("%s: couldn't allocate USBVision struct", __func__);
+ dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
return -ENOMEM;
}
@@ -1711,7 +1717,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
usbvision->alt_max_pkt_size = kmalloc(32*
usbvision->num_alt,GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
- err("usbvision: out of memory!\n");
+ dev_err(&intf->dev, "usbvision: out of memory!\n");
mutex_unlock(&usbvision->lock);
return -ENOMEM;
}
@@ -1772,7 +1778,8 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
PDEBUG(DBG_PROBE, "");
if (usbvision == NULL) {
- err("%s: usb_get_intfdata() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_get_intfdata() failed\n", __func__);
return;
}
usb_set_intfdata (intf, NULL);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 2208165aa6f0..0d7e38d6ff6a 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1,7 +1,7 @@
/*
* uvc_ctrl.c -- USB Video Class driver - Controls
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/uaccess.h>
@@ -29,7 +28,7 @@
#define UVC_CTRL_DATA_BACKUP 1
/* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Controls
*/
static struct uvc_control_info uvc_ctrls[] = {
@@ -635,7 +634,7 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping,
mask = (1 << bits) - 1;
}
- /* Sign-extend the value if needed */
+ /* Sign-extend the value if needed. */
if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)
value |= -(value & (1 << (mapping->size - 1)));
@@ -787,7 +786,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
v4l2_ctrl->id = mapping->id;
v4l2_ctrl->type = mapping->v4l2_type;
- strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
+ strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
v4l2_ctrl->flags = 0;
if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 89d8bd10a852..ebcd5bf0edb7 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1,7 +1,7 @@
/*
* uvc_driver.c -- USB Video Class driver
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -49,7 +48,7 @@ static unsigned int uvc_quirks_param;
unsigned int uvc_trace_param;
/* ------------------------------------------------------------------------
- * Control, formats, ...
+ * Video formats
*/
static struct uvc_format_desc uvc_fmts[] = {
@@ -315,7 +314,7 @@ static int uvc_parse_format(struct uvc_device *dev,
fmtdesc = uvc_format_by_guid(&buffer[5]);
if (fmtdesc != NULL) {
- strncpy(format->name, fmtdesc->name,
+ strlcpy(format->name, fmtdesc->name,
sizeof format->name);
format->fcc = fmtdesc->fcc;
} else {
@@ -346,7 +345,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncpy(format->name, "MJPEG", sizeof format->name);
+ strlcpy(format->name, "MJPEG", sizeof format->name);
format->fcc = V4L2_PIX_FMT_MJPEG;
format->flags = UVC_FMT_FLAG_COMPRESSED;
format->bpp = 0;
@@ -364,13 +363,13 @@ static int uvc_parse_format(struct uvc_device *dev,
switch (buffer[8] & 0x7f) {
case 0:
- strncpy(format->name, "SD-DV", sizeof format->name);
+ strlcpy(format->name, "SD-DV", sizeof format->name);
break;
case 1:
- strncpy(format->name, "SDL-DV", sizeof format->name);
+ strlcpy(format->name, "SDL-DV", sizeof format->name);
break;
case 2:
- strncpy(format->name, "HD-DV", sizeof format->name);
+ strlcpy(format->name, "HD-DV", sizeof format->name);
break;
default:
uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
@@ -380,7 +379,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
+ strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
sizeof format->name);
format->fcc = V4L2_PIX_FMT_DV;
@@ -474,7 +473,7 @@ static int uvc_parse_format(struct uvc_device *dev,
/* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
* completely. Observed behaviours range from setting the
- * value to 1.1x the actual frame size of hardwiring the
+ * value to 1.1x the actual frame size to hardwiring the
* 16 low bits to 0. This results in a higher than necessary
* memory usage as well as a wrong image size information. For
* uncompressed formats this can be fixed by computing the
@@ -487,7 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
/* Some bogus devices report dwMinFrameInterval equal to
* dwMaxFrameInterval and have dwFrameIntervalStep set to
* zero. Setting all null intervals to 1 fixes the problem and
- * some other divisions by zero which could happen.
+ * some other divisions by zero that could happen.
*/
for (i = 0; i < n; ++i) {
interval = get_unaligned_le32(&buffer[26+4*i]);
@@ -1200,13 +1199,13 @@ static void uvc_unregister_video(struct uvc_device *dev)
* Scan the UVC descriptors to locate a chain starting at an Output Terminal
* and containing the following units:
*
- * - a USB Streaming Output Terminal
+ * - one Output Terminal (USB Streaming or Display)
* - zero or one Processing Unit
* - zero, one or mode single-input Selector Units
* - zero or one multiple-input Selector Units, provided all inputs are
* connected to input terminals
* - zero, one or mode single-input Extension Units
- * - one Camera Input Terminal, or one or more External terminals.
+ * - one or more Input Terminals (Camera, External or USB Streaming)
*
* A side forward scan is made on each detected entity to check for additional
* extension units.
@@ -1527,14 +1526,10 @@ static int uvc_register_video(struct uvc_device *dev)
vdev->minor = -1;
vdev->fops = &uvc_fops;
vdev->release = video_device_release;
- strncpy(vdev->name, dev->name, sizeof vdev->name);
+ strlcpy(vdev->name, dev->name, sizeof vdev->name);
/* Set the driver data before calling video_register_device, otherwise
* uvc_v4l2_open might race us.
- *
- * FIXME: usb_set_intfdata hasn't been called so far. Is that a
- * problem ? Does any function which could be called here get
- * a pointer to the usb_interface ?
*/
dev->video.vdev = vdev;
video_set_drvdata(vdev, &dev->video);
@@ -1569,7 +1564,7 @@ void uvc_delete(struct kref *kref)
struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
struct list_head *p, *n;
- /* Unregister the video device */
+ /* Unregister the video device. */
uvc_unregister_video(dev);
usb_put_intf(dev->intf);
usb_put_dev(dev->udev);
@@ -1612,7 +1607,7 @@ static int uvc_probe(struct usb_interface *intf,
uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
udev->devpath);
- /* Allocate memory for the device and initialize it */
+ /* Allocate memory for the device and initialize it. */
if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
return -ENOMEM;
@@ -1626,21 +1621,21 @@ static int uvc_probe(struct usb_interface *intf,
dev->quirks = id->driver_info | uvc_quirks_param;
if (udev->product != NULL)
- strncpy(dev->name, udev->product, sizeof dev->name);
+ strlcpy(dev->name, udev->product, sizeof dev->name);
else
snprintf(dev->name, sizeof dev->name,
"UVC Camera (%04x:%04x)",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
- /* Parse the Video Class control descriptor */
+ /* Parse the Video Class control descriptor. */
if (uvc_parse_control(dev) < 0) {
uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
"descriptors.\n");
goto error;
}
- uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n",
+ uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
dev->uvc_version >> 8, dev->uvc_version & 0xff,
udev->product ? udev->product : "<unnamed>",
le16_to_cpu(udev->descriptor.idVendor),
@@ -1653,18 +1648,18 @@ static int uvc_probe(struct usb_interface *intf,
"linux-uvc-devel mailing list.\n");
}
- /* Initialize controls */
+ /* Initialize controls. */
if (uvc_ctrl_init_device(dev) < 0)
goto error;
- /* Register the video devices */
+ /* Register the video devices. */
if (uvc_register_video(dev) < 0)
goto error;
- /* Save our data pointer in the interface data */
+ /* Save our data pointer in the interface data. */
usb_set_intfdata(intf, dev);
- /* Initialize the interrupt URB */
+ /* Initialize the interrupt URB. */
if ((ret = uvc_status_init(dev)) < 0) {
uvc_printk(KERN_INFO, "Unable to initialize the status "
"endpoint (%d), status interrupt will not be "
@@ -1838,25 +1833,34 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0 },
+ /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x058f,
+ .idProduct = 0x3820,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* Apple Built-In iSight */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x05ac,
.idProduct = 0x8501,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_BUILTIN_ISIGHT },
/* Genesys Logic USB 2.0 PC Camera */
- { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x05e3,
- .idProduct = 0x0505,
- .bInterfaceClass = USB_CLASS_VIDEO,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .idVendor = 0x05e3,
+ .idProduct = 0x0505,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1884,7 +1888,7 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Asus F9SG */
+ /* Syntek (Asus F9SG) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x174f,
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
index 37bdefdbead5..436f462685a0 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -3,6 +3,8 @@
*
* Copyright (C) 2006-2007
* Ivan N. Zlatev <contact@i-nz.net>
+ * Copyright (C) 2008-2009
+ * Laurent Pinchart <laurent.pinchart@skynet.be>
*
* 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
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 42546342e97d..0155752e4a5a 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -1,7 +1,7 @@
/*
* uvc_queue.c -- USB Video Class driver - Buffers management
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/mm.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -37,22 +36,22 @@
* to user space will return -EBUSY.
*
* Video buffers are managed using two queues. However, unlike most USB video
- * drivers which use an in queue and an out queue, we use a main queue which
- * holds all queued buffers (both 'empty' and 'done' buffers), and an irq
- * queue which holds empty buffers. This design (copied from video-buf)
- * minimizes locking in interrupt, as only one queue is shared between
- * interrupt and user contexts.
+ * drivers that use an in queue and an out queue, we use a main queue to hold
+ * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to
+ * hold empty buffers. This design (copied from video-buf) minimizes locking
+ * in interrupt, as only one queue is shared between interrupt and user
+ * contexts.
*
* Use cases
* ---------
*
- * Unless stated otherwise, all operations which modify the irq buffers queue
+ * Unless stated otherwise, all operations that modify the irq buffers queue
* are protected by the irq spinlock.
*
* 1. The user queues the buffers, starts streaming and dequeues a buffer.
*
* The buffers are added to the main and irq queues. Both operations are
- * protected by the queue lock, and the latert is protected by the irq
+ * protected by the queue lock, and the later is protected by the irq
* spinlock as well.
*
* The completion handler fetches a buffer from the irq queue and fills it
@@ -60,7 +59,7 @@
* returns immediately.
*
* When the buffer is full, the completion handler removes it from the irq
- * queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue.
+ * queue, marks it as ready (UVC_BUF_STATE_DONE) and wakes its wait queue.
* At that point, any process waiting on the buffer will be woken up. If a
* process tries to dequeue a buffer after it has been marked ready, the
* dequeing will succeed immediately.
@@ -91,8 +90,8 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type)
/*
* Allocate the video buffers.
*
- * Pages are reserved to make sure they will not be swaped, as they will be
- * filled in URB completion handler.
+ * Pages are reserved to make sure they will not be swapped, as they will be
+ * filled in the URB completion handler.
*
* Buffers will be individually mapped, so they must all be page aligned.
*/
@@ -210,8 +209,8 @@ int uvc_query_buffer(struct uvc_video_queue *queue,
__uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
done:
- mutex_unlock(&queue->mutex);
- return ret;
+ mutex_unlock(&queue->mutex);
+ return ret;
}
/*
@@ -236,7 +235,7 @@ int uvc_queue_buffer(struct uvc_video_queue *queue,
}
mutex_lock(&queue->mutex);
- if (v4l2_buf->index >= queue->count) {
+ if (v4l2_buf->index >= queue->count) {
uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
ret = -EINVAL;
goto done;
@@ -429,7 +428,7 @@ done:
* Cancel the video buffers queue.
*
* Cancelling the queue marks all buffers on the irq queue as erroneous,
- * wakes them up and remove them from the queue.
+ * wakes them up and removes them from the queue.
*
* If the disconnect parameter is set, further calls to uvc_queue_buffer will
* fail with -ENODEV.
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index 5d60b264d59a..21d87124986b 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -1,7 +1,7 @@
/*
* uvc_status.c -- USB Video Class driver - Status endpoint
*
- * Copyright (C) 2007-2008
+ * Copyright (C) 2007-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
@@ -25,30 +24,23 @@
#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
static int uvc_input_init(struct uvc_device *dev)
{
- struct usb_device *udev = dev->udev;
struct input_dev *input;
- char *phys = NULL;
int ret;
input = input_allocate_device();
if (input == NULL)
return -ENOMEM;
- phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath),
- GFP_KERNEL);
- if (phys == NULL) {
- ret = -ENOMEM;
- goto error;
- }
- sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath);
+ usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
+ strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
input->name = dev->name;
- input->phys = phys;
- usb_to_input_id(udev, &input->id);
+ input->phys = dev->input_phys;
+ usb_to_input_id(dev->udev, &input->id);
input->dev.parent = &dev->intf->dev;
- set_bit(EV_KEY, input->evbit);
- set_bit(BTN_0, input->keybit);
+ __set_bit(EV_KEY, input->evbit);
+ __set_bit(KEY_CAMERA, input->keybit);
if ((ret = input_register_device(input)) < 0)
goto error;
@@ -58,7 +50,6 @@ static int uvc_input_init(struct uvc_device *dev)
error:
input_free_device(input);
- kfree(phys);
return ret;
}
@@ -71,8 +62,10 @@ static void uvc_input_cleanup(struct uvc_device *dev)
static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
int value)
{
- if (dev->input)
+ if (dev->input) {
input_report_key(dev->input, code, value);
+ input_sync(dev->input);
+ }
}
#else
@@ -97,7 +90,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
return;
uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
data[1], data[3] ? "pressed" : "released", len);
- uvc_input_report_key(dev, BTN_0, data[3]);
+ uvc_input_report_key(dev, KEY_CAMERA, data[3]);
} else {
uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
"len %d.\n", data[1], data[2], data[3], len);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index fa150fff2c10..30781b82b6b5 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -1,7 +1,7 @@
/*
* uvc_v4l2.c -- USB Video Class driver - V4L2 API
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
* must be grouped (for instance the Red Balance, Blue Balance and Do White
* Balance V4L2 controls use the White Balance Component UVC control) or
* otherwise translated. The approach we take here is to use a translation
- * table for the controls which can be mapped directly, and handle the others
+ * table for the controls that can be mapped directly, and handle the others
* manually.
*/
static int uvc_v4l2_query_menu(struct uvc_video_device *video,
@@ -55,7 +55,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
return -EINVAL;
menu_info = &mapping->menu_info[query_menu->index];
- strncpy(query_menu->name, menu_info->name, 32);
+ strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
return 0;
}
@@ -189,7 +189,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
probe->dwMaxVideoFrameSize =
video->streaming->ctrl.dwMaxVideoFrameSize;
- /* Probe the device */
+ /* Probe the device. */
if ((ret = uvc_probe_video(video, probe)) < 0)
goto done;
@@ -354,11 +354,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
*
* Each open instance of a UVC device can either be in a privileged or
* unprivileged state. Only a single instance can be in a privileged state at
- * a given time. Trying to perform an operation which requires privileges will
+ * a given time. Trying to perform an operation that requires privileges will
* automatically acquire the required privileges if possible, or return -EBUSY
* otherwise. Privileges are dismissed when closing the instance.
*
- * Operations which require privileges are:
+ * Operations that require privileges are:
*
* - VIDIOC_S_INPUT
* - VIDIOC_S_PARM
@@ -486,10 +486,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
struct v4l2_capability *cap = arg;
memset(cap, 0, sizeof *cap);
- strncpy(cap->driver, "uvcvideo", sizeof cap->driver);
- strncpy(cap->card, vdev->name, 32);
- strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
- sizeof cap->bus_info);
+ strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
+ strlcpy(cap->card, vdev->name, sizeof cap->card);
+ usb_make_path(video->dev->udev,
+ cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
@@ -620,7 +620,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
memset(input, 0, sizeof *input);
input->index = index;
- strncpy(input->name, iterm->name, sizeof input->name);
+ strlcpy(input->name, iterm->name, sizeof input->name);
if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA)
input->type = V4L2_INPUT_TYPE_CAMERA;
break;
@@ -682,7 +682,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
fmt->flags = 0;
if (format->flags & UVC_FMT_FLAG_COMPRESSED)
fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
- strncpy(fmt->description, format->name,
+ strlcpy(fmt->description, format->name,
sizeof fmt->description);
fmt->description[sizeof fmt->description - 1] = 0;
fmt->pixelformat = format->fcc;
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index e7c31995527f..7ebb89539c36 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1,7 +1,7 @@
/*
* uvc_video.c -- USB Video Class driver - Video handling
*
- * Copyright (C) 2005-2008
+ * Copyright (C) 2005-2009
* Laurent Pinchart (laurent.pinchart@skynet.be)
*
* This program is free software; you can redistribute it and/or modify
@@ -12,7 +12,6 @@
*/
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -115,7 +114,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
ret = 0;
goto out;
- } else if (query == GET_DEF && probe == 1) {
+ } else if (query == GET_DEF && probe == 1 && ret != size) {
/* Many cameras don't support the GET_DEF request on their
* video probe control. Warn once and return, the caller will
* fall back to GET_CUR.
@@ -160,7 +159,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
}
/* Some broken devices return a null or wrong dwMaxVideoFrameSize.
- * Try to get the value from the format and frame descriptor.
+ * Try to get the value from the format and frame descriptors.
*/
uvc_fixup_buffer_size(video, ctrl);
ret = 0;
@@ -191,9 +190,6 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
*(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality);
*(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize);
*(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay);
- /* Note: Some of the fields below are not required for IN devices (see
- * UVC spec, 4.3.1.1), but we still copy them in case support for OUT
- * devices is added in the future. */
put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
@@ -400,7 +396,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
*
* Empty buffers (bytesused == 0) don't trigger end of frame detection
* as it doesn't make sense to return an empty buffer. This also
- * avoids detecting and of frame conditions at FID toggling if the
+ * avoids detecting end of frame conditions at FID toggling if the
* previous payload had the EOF bit set.
*/
if (fid != video->last_fid && buf->buf.bytesused != 0) {
@@ -453,6 +449,17 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
}
}
+/* Video payload encoding is handled by uvc_video_encode_header() and
+ * uvc_video_encode_data(). Only bulk transfers are currently supported.
+ *
+ * uvc_video_encode_header is called at the start of a payload. It adds header
+ * data to the transfer buffer and returns the header size. As the only known
+ * UVC output device transfers a whole frame in a single payload, the EOF bit
+ * is always set in the header.
+ *
+ * uvc_video_encode_data is called for every URB and copies the data from the
+ * video buffer to the transfer buffer.
+ */
static int uvc_video_encode_header(struct uvc_video_device *video,
struct uvc_buffer *buf, __u8 *data, int len)
{
@@ -692,27 +699,47 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video)
* already allocated when resuming from suspend, in which case it will
* return without touching the buffers.
*
- * Return 0 on success or -ENOMEM when out of memory.
+ * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the
+ * system is too low on memory try successively smaller numbers of packets
+ * until allocation succeeds.
+ *
+ * Return the number of allocated packets on success or 0 when out of memory.
*/
static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
- unsigned int size)
+ unsigned int size, unsigned int psize, gfp_t gfp_flags)
{
+ unsigned int npackets;
unsigned int i;
/* Buffers are already allocated, bail out. */
if (video->urb_size)
return 0;
- for (i = 0; i < UVC_URBS; ++i) {
- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
- size, GFP_KERNEL, &video->urb_dma[i]);
- if (video->urb_buffer[i] == NULL) {
- uvc_free_urb_buffers(video);
- return -ENOMEM;
+ /* Compute the number of packets. Bulk endpoints might transfer UVC
+ * payloads accross multiple URBs.
+ */
+ npackets = DIV_ROUND_UP(size, psize);
+ if (npackets > UVC_MAX_PACKETS)
+ npackets = UVC_MAX_PACKETS;
+
+ /* Retry allocations until one succeed. */
+ for (; npackets > 1; npackets /= 2) {
+ for (i = 0; i < UVC_URBS; ++i) {
+ video->urb_buffer[i] = usb_buffer_alloc(
+ video->dev->udev, psize * npackets,
+ gfp_flags | __GFP_NOWARN, &video->urb_dma[i]);
+ if (!video->urb_buffer[i]) {
+ uvc_free_urb_buffers(video);
+ break;
+ }
+ }
+
+ if (i == UVC_URBS) {
+ video->urb_size = psize * npackets;
+ return npackets;
}
}
- video->urb_size = size;
return 0;
}
@@ -746,29 +773,19 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
{
struct urb *urb;
unsigned int npackets, i, j;
- __u16 psize;
- __u32 size;
+ u16 psize;
+ u32 size;
- /* Compute the number of isochronous packets to allocate by dividing
- * the maximum video frame size by the packet size. Limit the result
- * to UVC_MAX_ISO_PACKETS.
- */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-
size = video->streaming->ctrl.dwMaxVideoFrameSize;
- if (size > UVC_MAX_FRAME_SIZE)
- return -EINVAL;
- npackets = DIV_ROUND_UP(size, psize);
- if (npackets > UVC_MAX_ISO_PACKETS)
- npackets = UVC_MAX_ISO_PACKETS;
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
+ return -ENOMEM;
size = npackets * psize;
- if (uvc_alloc_urb_buffers(video, size) < 0)
- return -ENOMEM;
-
for (i = 0; i < UVC_URBS; ++i) {
urb = usb_alloc_urb(npackets, gfp_flags);
if (urb == NULL) {
@@ -807,25 +824,20 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
struct usb_host_endpoint *ep, gfp_t gfp_flags)
{
struct urb *urb;
- unsigned int pipe, i;
- __u16 psize;
- __u32 size;
-
- /* Compute the bulk URB size. Some devices set the maximum payload
- * size to a value too high for memory-constrained devices. We must
- * then transfer the payload accross multiple URBs. To be consistant
- * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk
- * URB.
- */
+ unsigned int npackets, pipe, i;
+ u16 psize;
+ u32 size;
+
psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
size = video->streaming->ctrl.dwMaxPayloadTransferSize;
video->bulk.max_payload_size = size;
- if (size > psize * UVC_MAX_ISO_PACKETS)
- size = psize * UVC_MAX_ISO_PACKETS;
- if (uvc_alloc_urb_buffers(video, size) < 0)
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
return -ENOMEM;
+ size = npackets * psize;
+
if (usb_endpoint_dir_in(&ep->desc))
pipe = usb_rcvbulkpipe(video->dev->udev,
ep->desc.bEndpointAddress);
@@ -953,7 +965,7 @@ int uvc_video_suspend(struct uvc_video_device *video)
}
/*
- * Reconfigure the video interface and restart streaming if it was enable
+ * Reconfigure the video interface and restart streaming if it was enabled
* before suspend.
*
* If an error occurs, disable the video queue. This will wake all pending
@@ -985,8 +997,8 @@ int uvc_video_resume(struct uvc_video_device *video)
*/
/*
- * Initialize the UVC video device by retrieving the default format and
- * committing it.
+ * Initialize the UVC video device by switching to alternate setting 0 and
+ * retrieve the default format.
*
* Some cameras (namely the Fuji Finepix) set the format and frame
* indexes to zero. The UVC standard doesn't clearly make this a spec
@@ -1014,7 +1026,7 @@ int uvc_video_init(struct uvc_video_device *video)
*/
usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
- /* Some webcams don't suport GET_DEF request on the probe control. We
+ /* Some webcams don't suport GET_DEF requests on the probe control. We
* fall back to GET_CUR if GET_DEF fails.
*/
if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index bcf4361dc1bc..6f55c4d49cf4 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -72,149 +72,149 @@ struct uvc_xu_control {
* UVC constants
*/
-#define SC_UNDEFINED 0x00
-#define SC_VIDEOCONTROL 0x01
-#define SC_VIDEOSTREAMING 0x02
-#define SC_VIDEO_INTERFACE_COLLECTION 0x03
+#define SC_UNDEFINED 0x00
+#define SC_VIDEOCONTROL 0x01
+#define SC_VIDEOSTREAMING 0x02
+#define SC_VIDEO_INTERFACE_COLLECTION 0x03
-#define PC_PROTOCOL_UNDEFINED 0x00
+#define PC_PROTOCOL_UNDEFINED 0x00
-#define CS_UNDEFINED 0x20
-#define CS_DEVICE 0x21
-#define CS_CONFIGURATION 0x22
-#define CS_STRING 0x23
-#define CS_INTERFACE 0x24
-#define CS_ENDPOINT 0x25
+#define CS_UNDEFINED 0x20
+#define CS_DEVICE 0x21
+#define CS_CONFIGURATION 0x22
+#define CS_STRING 0x23
+#define CS_INTERFACE 0x24
+#define CS_ENDPOINT 0x25
/* VideoControl class specific interface descriptor */
-#define VC_DESCRIPTOR_UNDEFINED 0x00
-#define VC_HEADER 0x01
-#define VC_INPUT_TERMINAL 0x02
-#define VC_OUTPUT_TERMINAL 0x03
-#define VC_SELECTOR_UNIT 0x04
-#define VC_PROCESSING_UNIT 0x05
-#define VC_EXTENSION_UNIT 0x06
+#define VC_DESCRIPTOR_UNDEFINED 0x00
+#define VC_HEADER 0x01
+#define VC_INPUT_TERMINAL 0x02
+#define VC_OUTPUT_TERMINAL 0x03
+#define VC_SELECTOR_UNIT 0x04
+#define VC_PROCESSING_UNIT 0x05
+#define VC_EXTENSION_UNIT 0x06
/* VideoStreaming class specific interface descriptor */
-#define VS_UNDEFINED 0x00
-#define VS_INPUT_HEADER 0x01
-#define VS_OUTPUT_HEADER 0x02
-#define VS_STILL_IMAGE_FRAME 0x03
-#define VS_FORMAT_UNCOMPRESSED 0x04
-#define VS_FRAME_UNCOMPRESSED 0x05
-#define VS_FORMAT_MJPEG 0x06
-#define VS_FRAME_MJPEG 0x07
-#define VS_FORMAT_MPEG2TS 0x0a
-#define VS_FORMAT_DV 0x0c
-#define VS_COLORFORMAT 0x0d
-#define VS_FORMAT_FRAME_BASED 0x10
-#define VS_FRAME_FRAME_BASED 0x11
-#define VS_FORMAT_STREAM_BASED 0x12
+#define VS_UNDEFINED 0x00
+#define VS_INPUT_HEADER 0x01
+#define VS_OUTPUT_HEADER 0x02
+#define VS_STILL_IMAGE_FRAME 0x03
+#define VS_FORMAT_UNCOMPRESSED 0x04
+#define VS_FRAME_UNCOMPRESSED 0x05
+#define VS_FORMAT_MJPEG 0x06
+#define VS_FRAME_MJPEG 0x07
+#define VS_FORMAT_MPEG2TS 0x0a
+#define VS_FORMAT_DV 0x0c
+#define VS_COLORFORMAT 0x0d
+#define VS_FORMAT_FRAME_BASED 0x10
+#define VS_FRAME_FRAME_BASED 0x11
+#define VS_FORMAT_STREAM_BASED 0x12
/* Endpoint type */
-#define EP_UNDEFINED 0x00
-#define EP_GENERAL 0x01
-#define EP_ENDPOINT 0x02
-#define EP_INTERRUPT 0x03
+#define EP_UNDEFINED 0x00
+#define EP_GENERAL 0x01
+#define EP_ENDPOINT 0x02
+#define EP_INTERRUPT 0x03
/* Request codes */
-#define RC_UNDEFINED 0x00
-#define SET_CUR 0x01
-#define GET_CUR 0x81
-#define GET_MIN 0x82
-#define GET_MAX 0x83
-#define GET_RES 0x84
-#define GET_LEN 0x85
-#define GET_INFO 0x86
-#define GET_DEF 0x87
+#define RC_UNDEFINED 0x00
+#define SET_CUR 0x01
+#define GET_CUR 0x81
+#define GET_MIN 0x82
+#define GET_MAX 0x83
+#define GET_RES 0x84
+#define GET_LEN 0x85
+#define GET_INFO 0x86
+#define GET_DEF 0x87
/* VideoControl interface controls */
-#define VC_CONTROL_UNDEFINED 0x00
-#define VC_VIDEO_POWER_MODE_CONTROL 0x01
-#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
+#define VC_CONTROL_UNDEFINED 0x00
+#define VC_VIDEO_POWER_MODE_CONTROL 0x01
+#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
/* Terminal controls */
-#define TE_CONTROL_UNDEFINED 0x00
+#define TE_CONTROL_UNDEFINED 0x00
/* Selector Unit controls */
-#define SU_CONTROL_UNDEFINED 0x00
-#define SU_INPUT_SELECT_CONTROL 0x01
+#define SU_CONTROL_UNDEFINED 0x00
+#define SU_INPUT_SELECT_CONTROL 0x01
/* Camera Terminal controls */
-#define CT_CONTROL_UNDEFINED 0x00
-#define CT_SCANNING_MODE_CONTROL 0x01
-#define CT_AE_MODE_CONTROL 0x02
-#define CT_AE_PRIORITY_CONTROL 0x03
-#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
-#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
-#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
-#define CT_FOCUS_RELATIVE_CONTROL 0x07
-#define CT_FOCUS_AUTO_CONTROL 0x08
-#define CT_IRIS_ABSOLUTE_CONTROL 0x09
-#define CT_IRIS_RELATIVE_CONTROL 0x0a
-#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
-#define CT_ZOOM_RELATIVE_CONTROL 0x0c
-#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
-#define CT_PANTILT_RELATIVE_CONTROL 0x0e
-#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
-#define CT_ROLL_RELATIVE_CONTROL 0x10
-#define CT_PRIVACY_CONTROL 0x11
+#define CT_CONTROL_UNDEFINED 0x00
+#define CT_SCANNING_MODE_CONTROL 0x01
+#define CT_AE_MODE_CONTROL 0x02
+#define CT_AE_PRIORITY_CONTROL 0x03
+#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
+#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
+#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
+#define CT_FOCUS_RELATIVE_CONTROL 0x07
+#define CT_FOCUS_AUTO_CONTROL 0x08
+#define CT_IRIS_ABSOLUTE_CONTROL 0x09
+#define CT_IRIS_RELATIVE_CONTROL 0x0a
+#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
+#define CT_ZOOM_RELATIVE_CONTROL 0x0c
+#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
+#define CT_PANTILT_RELATIVE_CONTROL 0x0e
+#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
+#define CT_ROLL_RELATIVE_CONTROL 0x10
+#define CT_PRIVACY_CONTROL 0x11
/* Processing Unit controls */
-#define PU_CONTROL_UNDEFINED 0x00
-#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
-#define PU_BRIGHTNESS_CONTROL 0x02
-#define PU_CONTRAST_CONTROL 0x03
-#define PU_GAIN_CONTROL 0x04
-#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
-#define PU_HUE_CONTROL 0x06
-#define PU_SATURATION_CONTROL 0x07
-#define PU_SHARPNESS_CONTROL 0x08
-#define PU_GAMMA_CONTROL 0x09
-#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
-#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
-#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
-#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
-#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
-#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
-#define PU_HUE_AUTO_CONTROL 0x10
-#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
-#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
+#define PU_CONTROL_UNDEFINED 0x00
+#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
+#define PU_BRIGHTNESS_CONTROL 0x02
+#define PU_CONTRAST_CONTROL 0x03
+#define PU_GAIN_CONTROL 0x04
+#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
+#define PU_HUE_CONTROL 0x06
+#define PU_SATURATION_CONTROL 0x07
+#define PU_SHARPNESS_CONTROL 0x08
+#define PU_GAMMA_CONTROL 0x09
+#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
+#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
+#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
+#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
+#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
+#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
+#define PU_HUE_AUTO_CONTROL 0x10
+#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
+#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01
#define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02
#define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03
/* VideoStreaming interface controls */
-#define VS_CONTROL_UNDEFINED 0x00
-#define VS_PROBE_CONTROL 0x01
-#define VS_COMMIT_CONTROL 0x02
-#define VS_STILL_PROBE_CONTROL 0x03
-#define VS_STILL_COMMIT_CONTROL 0x04
-#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
-#define VS_STREAM_ERROR_CODE_CONTROL 0x06
-#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
-#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
-#define VS_SYNC_DELAY_CONTROL 0x09
-
-#define TT_VENDOR_SPECIFIC 0x0100
-#define TT_STREAMING 0x0101
+#define VS_CONTROL_UNDEFINED 0x00
+#define VS_PROBE_CONTROL 0x01
+#define VS_COMMIT_CONTROL 0x02
+#define VS_STILL_PROBE_CONTROL 0x03
+#define VS_STILL_COMMIT_CONTROL 0x04
+#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
+#define VS_STREAM_ERROR_CODE_CONTROL 0x06
+#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
+#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
+#define VS_SYNC_DELAY_CONTROL 0x09
+
+#define TT_VENDOR_SPECIFIC 0x0100
+#define TT_STREAMING 0x0101
/* Input Terminal types */
-#define ITT_VENDOR_SPECIFIC 0x0200
-#define ITT_CAMERA 0x0201
-#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
+#define ITT_VENDOR_SPECIFIC 0x0200
+#define ITT_CAMERA 0x0201
+#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
/* Output Terminal types */
-#define OTT_VENDOR_SPECIFIC 0x0300
-#define OTT_DISPLAY 0x0301
-#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
+#define OTT_VENDOR_SPECIFIC 0x0300
+#define OTT_DISPLAY 0x0301
+#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
/* External Terminal types */
-#define EXTERNAL_VENDOR_SPECIFIC 0x0400
-#define COMPOSITE_CONNECTOR 0x0401
-#define SVIDEO_CONNECTOR 0x0402
-#define COMPONENT_CONNECTOR 0x0403
+#define EXTERNAL_VENDOR_SPECIFIC 0x0400
+#define COMPOSITE_CONNECTOR 0x0401
+#define SVIDEO_CONNECTOR 0x0402
+#define COMPONENT_CONNECTOR 0x0403
#define UVC_TERM_INPUT 0x0000
#define UVC_TERM_OUTPUT 0x8000
@@ -296,10 +296,8 @@ struct uvc_xu_control {
/* Number of isochronous URBs. */
#define UVC_URBS 5
-/* Maximum number of packets per isochronous URB. */
-#define UVC_MAX_ISO_PACKETS 40
-/* Maximum frame size in bytes, for sanity checking. */
-#define UVC_MAX_FRAME_SIZE (16*1024*1024)
+/* Maximum number of packets per URB. */
+#define UVC_MAX_PACKETS 32
/* Maximum number of video buffers. */
#define UVC_MAX_VIDEO_BUFFERS 32
/* Maximum status buffer size in bytes of interrupt URB. */
@@ -541,11 +539,11 @@ struct uvc_streaming {
};
enum uvc_buffer_state {
- UVC_BUF_STATE_IDLE = 0,
- UVC_BUF_STATE_QUEUED = 1,
- UVC_BUF_STATE_ACTIVE = 2,
- UVC_BUF_STATE_DONE = 3,
- UVC_BUF_STATE_ERROR = 4,
+ UVC_BUF_STATE_IDLE = 0,
+ UVC_BUF_STATE_QUEUED = 1,
+ UVC_BUF_STATE_ACTIVE = 2,
+ UVC_BUF_STATE_DONE = 3,
+ UVC_BUF_STATE_ERROR = 4,
};
struct uvc_buffer {
@@ -649,6 +647,7 @@ struct uvc_device {
struct urb *int_urb;
__u8 *status;
struct input_dev *input;
+ char input_phys[64];
/* Video Streaming interfaces */
struct list_head streaming;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index b8f2be8d5c0e..7086f9f3c785 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -555,7 +555,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
qctrl->step = step;
qctrl->default_value = def;
qctrl->reserved[0] = qctrl->reserved[1] = 0;
- snprintf(qctrl->name, sizeof(qctrl->name), name);
+ strlcpy(qctrl->name, name, sizeof(qctrl->name));
return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_query_fill);
@@ -720,7 +720,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
if (menu_items[i] == NULL || menu_items[i][0] == '\0')
return -EINVAL;
- snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
+ strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name));
return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_query_menu);
@@ -737,8 +737,8 @@ int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *id
return -EINVAL;
while (*ids != V4L2_CTRL_MENU_IDS_END) {
if (*ids++ == qmenu->index) {
- snprintf(qmenu->name, sizeof(qmenu->name),
- menu_items[qmenu->index]);
+ strlcpy(qmenu->name, menu_items[qmenu->index],
+ sizeof(qmenu->name));
return 0;
}
}
@@ -749,7 +749,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
/* ctrl_classes points to an array of u32 pointers, the last element is
a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
Each array must be sorted low to high and belong to the same control
- class. The array of u32 pointer must also be sorted, from low class IDs
+ class. The array of u32 pointers must also be sorted, from low class IDs
to high class IDs.
This function returns the first ID that follows after the given ID.
@@ -991,4 +991,40 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
+/* Return a list of I2C tuner addresses to probe. Use only if the tuner
+ addresses are unknown. */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
+{
+ static const unsigned short radio_addrs[] = {
+#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
+ 0x10,
+#endif
+ 0x60,
+ I2C_CLIENT_END
+ };
+ static const unsigned short demod_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b,
+ I2C_CLIENT_END
+ };
+ static const unsigned short tv_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ I2C_CLIENT_END
+ };
+
+ switch (type) {
+ case ADDRS_RADIO:
+ return radio_addrs;
+ case ADDRS_DEMOD:
+ return demod_addrs;
+ case ADDRS_TV:
+ return tv_addrs;
+ case ADDRS_TV_WITH_DEMOD:
+ return tv_addrs + 4;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
+
#endif
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index cf9d4c7f571a..8a4b74f3129f 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -34,7 +34,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
spin_lock_init(&v4l2_dev->lock);
v4l2_dev->dev = dev;
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
- dev->driver->name, dev->bus_id);
+ dev->driver->name, dev_name(dev));
dev_set_drvdata(dev, v4l2_dev);
return 0;
}
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 52d687b165e0..20a571f21577 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -24,6 +24,7 @@
#endif
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
#include <linux/video_decoder.h>
#define dbgarg(cmd, fmt, arg...) \
@@ -1745,6 +1746,8 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_chip_ident)
break;
+ p->ident = V4L2_IDENT_NONE;
+ p->revision = 0;
ret = ops->vidioc_g_chip_ident(file, fh, p);
if (!ret)
dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index fbe9cc0d433a..923ec8d01991 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -28,13 +28,19 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
{
switch (cmd) {
case VIDIOC_QUERYCTRL:
- return v4l2_subdev_call(sd, core, querymenu, arg);
+ return v4l2_subdev_call(sd, core, queryctrl, arg);
case VIDIOC_G_CTRL:
return v4l2_subdev_call(sd, core, g_ctrl, arg);
case VIDIOC_S_CTRL:
return v4l2_subdev_call(sd, core, s_ctrl, arg);
+ case VIDIOC_G_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, g_ext_ctrls, arg);
+ case VIDIOC_S_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, s_ext_ctrls, arg);
+ case VIDIOC_TRY_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, try_ext_ctrls, arg);
case VIDIOC_QUERYMENU:
- return v4l2_subdev_call(sd, core, queryctrl, arg);
+ return v4l2_subdev_call(sd, core, querymenu, arg);
case VIDIOC_LOG_STATUS:
return v4l2_subdev_call(sd, core, log_status);
case VIDIOC_DBG_G_CHIP_IDENT:
@@ -98,6 +104,10 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
return v4l2_subdev_call(sd, video, g_fmt, arg);
case VIDIOC_INT_S_STD_OUTPUT:
return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg);
+ case VIDIOC_QUERYSTD:
+ return v4l2_subdev_call(sd, video, querystd, arg);
+ case VIDIOC_INT_G_INPUT_STATUS:
+ return v4l2_subdev_call(sd, video, g_input_status, arg);
case VIDIOC_STREAMON:
return v4l2_subdev_call(sd, video, s_stream, 1);
case VIDIOC_STREAMOFF:
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 31944b11e6ea..6109fb5f34e2 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -400,7 +400,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr)
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index be65a2fb3976..30ae30f99ccc 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -425,7 +425,7 @@ void videobuf_vmalloc_free (struct videobuf_buffer *buf)
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0))
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 81d5aa5cf331..13e7bd06a80c 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -223,6 +223,9 @@ struct vivi_dev {
char timestr[13];
int mv_count; /* Controls bars movement */
+
+ /* Input Number */
+ int input;
};
struct vivi_fh {
@@ -235,6 +238,7 @@ struct vivi_fh {
enum v4l2_buf_type type;
unsigned char bars[8][3];
+ int input; /* Input Number on bars */
};
/* ------------------------------------------------------------------
@@ -254,18 +258,72 @@ enum colors {
BLACK,
};
-static u8 bars[8][3] = {
/* R G B */
- {204, 204, 204}, /* white */
- {208, 208, 0}, /* ambar */
- { 0, 206, 206}, /* cyan */
- { 0, 239, 0}, /* green */
- {239, 0, 239}, /* magenta */
- {205, 0, 0}, /* red */
- { 0, 0, 255}, /* blue */
- { 0, 0, 0}, /* black */
+#define COLOR_WHITE {204, 204, 204}
+#define COLOR_AMBAR {208, 208, 0}
+#define COLOR_CIAN { 0, 206, 206}
+#define COLOR_GREEN { 0, 239, 0}
+#define COLOR_MAGENTA {239, 0, 239}
+#define COLOR_RED {205, 0, 0}
+#define COLOR_BLUE { 0, 0, 255}
+#define COLOR_BLACK { 0, 0, 0}
+
+struct bar_std {
+ u8 bar[8][3];
+};
+
+/* Maximum number of bars are 10 - otherwise, the input print code
+ should be modified */
+static struct bar_std bars[] = {
+ { /* Standard ITU-R color bar sequence */
+ {
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_CIAN,
+ COLOR_GREEN,
+ COLOR_MAGENTA,
+ COLOR_RED,
+ COLOR_BLUE,
+ COLOR_BLACK,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_CIAN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_CIAN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_CIAN,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_GREEN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_GREEN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_GREEN,
+ }
+ },
};
+#define NUM_INPUTS ARRAY_SIZE(bars)
+
#define TO_Y(r, g, b) \
(((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
/* RGB to V(Cr) Color transform */
@@ -275,9 +333,10 @@ static u8 bars[8][3] = {
#define TO_U(r, g, b) \
(((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
-#define TSTAMP_MIN_Y 24
-#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
-#define TSTAMP_MIN_X 64
+#define TSTAMP_MIN_Y 24
+#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15)
+#define TSTAMP_INPUT_X 10
+#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
{
@@ -392,9 +451,29 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax,
pos += 4; /* only 16 bpp supported for now */
}
- /* Checks if it is possible to show timestamp */
+ /* Prints input entry number */
+
+ /* Checks if it is possible to input number */
if (TSTAMP_MAX_Y >= hmax)
goto end;
+
+ if (TSTAMP_INPUT_X + strlen(timestr) >= wmax)
+ goto end;
+
+ if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) {
+ chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y];
+ pos = TSTAMP_INPUT_X;
+ for (i = 0; i < 7; i++) {
+ /* Draw white font on black background */
+ if (chr & 1 << (7 - i))
+ gen_twopix(fh, basep + pos, WHITE);
+ else
+ gen_twopix(fh, basep + pos, BLACK);
+ pos += 2;
+ }
+ }
+
+ /* Checks if it is possible to show timestamp */
if (TSTAMP_MIN_X + strlen(timestr) >= wmax)
goto end;
@@ -807,38 +886,19 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-/*FIXME: This seems to be generic enough to be at videodev2 */
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+/* precalculate color bar values to speed up rendering */
+static void precalculate_bars(struct vivi_fh *fh)
{
- struct vivi_fh *fh = priv;
- struct videobuf_queue *q = &fh->vb_vidq;
+ struct vivi_dev *dev = fh->dev;
unsigned char r, g, b;
int k, is_yuv;
- int ret = vidioc_try_fmt_vid_cap(file, fh, f);
- if (ret < 0)
- return (ret);
-
- mutex_lock(&q->vb_lock);
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- dprintk(fh->dev, 1, "%s queue busy\n", __func__);
- ret = -EBUSY;
- goto out;
- }
+ fh->input = dev->input;
- fh->fmt = get_format(f);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vb_vidq.field = f->fmt.pix.field;
- fh->type = f->type;
-
- /* precalculate color bar values to speed up rendering */
for (k = 0; k < 8; k++) {
- r = bars[k][0];
- g = bars[k][1];
- b = bars[k][2];
+ r = bars[fh->input].bar[k][0];
+ g = bars[fh->input].bar[k][1];
+ b = bars[fh->input].bar[k][2];
is_yuv = 0;
switch (fh->fmt->fourcc) {
@@ -871,11 +931,40 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
}
}
+}
+
+/*FIXME: This seems to be generic enough to be at videodev2 */
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct vivi_fh *fh = priv;
+ struct videobuf_queue *q = &fh->vb_vidq;
+
+ int ret = vidioc_try_fmt_vid_cap(file, fh, f);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&q->vb_lock);
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ dprintk(fh->dev, 1, "%s queue busy\n", __func__);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ fh->fmt = get_format(f);
+ fh->width = f->fmt.pix.width;
+ fh->height = f->fmt.pix.height;
+ fh->vb_vidq.field = f->fmt.pix.field;
+ fh->type = f->type;
+
+ precalculate_bars(fh);
+
ret = 0;
out:
mutex_unlock(&q->vb_lock);
- return (ret);
+ return ret;
}
static int vidioc_reqbufs(struct file *file, void *priv,
@@ -950,27 +1039,36 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
{
- if (inp->index != 0)
+ if (inp->index >= NUM_INPUTS)
return -EINVAL;
inp->type = V4L2_INPUT_TYPE_CAMERA;
inp->std = V4L2_STD_525_60;
- strcpy(inp->name, "Camera");
+ sprintf(inp->name, "Camera %u", inp->index);
return (0);
}
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
- *i = 0;
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
+ *i = dev->input;
return (0);
}
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
- if (i > 0)
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
+ if (i >= NUM_INPUTS)
return -EINVAL;
+ dev->input = i;
+ precalculate_bars(fh);
+
return (0);
}
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 5d73f66d9f55..9a590a91d7de 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -206,7 +206,6 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "vp27smpx",
- .driverid = I2C_DRIVERID_VP27SMPX,
.command = vp27smpx_command,
.probe = vp27smpx_probe,
.remove = vp27smpx_remove,
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index f2864d5cd180..18535c4a0549 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -343,7 +343,6 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "wm8739",
- .driverid = I2C_DRIVERID_WM8739,
.command = wm8739_command,
.probe = wm8739_probe,
.remove = wm8739_remove,
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index b0cd49c438a3..3a408de91b9c 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -58,12 +58,20 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
.idProduct = (prod), \
.bInterfaceClass = (intclass)
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
#define ZC0301_ID_TABLE \
static const struct usb_device_id zc0301_id_table[] = { \
{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
{ ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \
{ } \
};
+#else
+#define ZC0301_ID_TABLE \
+static const struct usb_device_id zc0301_id_table[] = { \
+ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
+ { } \
+};
+#endif
/*****************************************************************************/
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index 46b7ad477ceb..e873a916250f 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -349,7 +349,6 @@ struct card_info {
u16 i2c_decoder, i2c_encoder; /* I2C types */
u16 video_vfe, video_codec; /* videocodec types */
u16 audio_chip; /* audio type */
- u16 vendor_id, device_id; /* subsystem vendor/device ID */
int inputs; /* number of video inputs */
struct input {
@@ -401,7 +400,6 @@ struct zoran {
char name[32]; /* name of this device */
struct pci_dev *pci_dev; /* PCI device */
unsigned char revision; /* revision of zr36057 */
- unsigned int zr36057_adr; /* bus address of IO mem returned by PCI BIOS */
unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */
spinlock_t spinlock; /* Spinlock */
@@ -490,16 +488,10 @@ struct zoran {
wait_queue_head_t test_q;
};
-/*The following should be done in more portable way. It depends on define
- of _ALPHA_BUZ in the Makefile.*/
-
-#ifdef _ALPHA_BUZ
-#define btwrite(dat,adr) writel((dat), zr->zr36057_adr+(adr))
-#define btread(adr) readl(zr->zr36057_adr+(adr))
-#else
+/* There was something called _ALPHA_BUZ that used the PCI address instead of
+ * the kernel iomapped address for btread/btwrite. */
#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
#define btread(adr) readl(zr->zr36057_mem+(adr))
-#endif
#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 05f39195372e..5d2f090aa0f8 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -61,17 +61,17 @@
extern const struct zoran_format zoran_formats[];
-static int card[BUZ_MAX] = { -1, -1, -1, -1 };
+static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card, "The type of card");
+MODULE_PARM_DESC(card, "Card type");
-static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(encoder, int, NULL, 0444);
-MODULE_PARM_DESC(encoder, "i2c TV encoder");
+MODULE_PARM_DESC(encoder, "Video encoder chip");
-static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
+static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(decoder, int, NULL, 0444);
-MODULE_PARM_DESC(decoder, "i2c TV decoder");
+MODULE_PARM_DESC(decoder, "Video decoder chip");
/*
The video mem address of the video card.
@@ -104,9 +104,9 @@ module_param(default_norm, int, 0444);
MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
/* /dev/videoN, -1 for autodetect */
-static int video_nr[BUZ_MAX] = {-1, -1, -1, -1};
+static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(video_nr, int, NULL, 0444);
-MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
+MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
/*
Number and size of grab buffers for Video 4 Linux
@@ -153,9 +153,21 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
MODULE_AUTHOR("Serguei Miridonov");
MODULE_LICENSE("GPL");
+#define ZR_DEVICE(subven, subdev, data) { \
+ .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
+ .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
+
+static struct pci_device_id zr36067_pci_tbl[] = {
+ ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus),
+ ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus),
+ ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
+ ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
+ ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
+ {0}
+};
+MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
-int zoran_num; /* number of Buzs in use */
-struct zoran *zoran[BUZ_MAX];
+static unsigned int zoran_num; /* number of cards found */
/* videocodec bus functions ZR36060 */
static u32
@@ -472,8 +484,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC10plus,
.name = "DC10plus",
- .vendor_id = PCI_VENDOR_ID_MIRO,
- .device_id = PCI_DEVICE_ID_MIRO_DC10PLUS,
.i2c_decoder = I2C_DRIVERID_SAA7110,
.i2c_encoder = I2C_DRIVERID_ADV7175,
.video_codec = CODEC_TYPE_ZR36060,
@@ -531,8 +541,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC30plus,
.name = "DC30plus",
- .vendor_id = PCI_VENDOR_ID_MIRO,
- .device_id = PCI_DEVICE_ID_MIRO_DC30PLUS,
.i2c_decoder = I2C_DRIVERID_VPX3220,
.i2c_encoder = I2C_DRIVERID_ADV7175,
.video_codec = CODEC_TYPE_ZR36050,
@@ -589,8 +597,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33R10,
.name = "LML33R10",
- .vendor_id = PCI_VENDOR_ID_ELECTRONICDESIGNGMBH,
- .device_id = PCI_DEVICE_ID_LML_33R10,
.i2c_decoder = I2C_DRIVERID_SAA7114,
.i2c_encoder = I2C_DRIVERID_ADV7170,
.video_codec = CODEC_TYPE_ZR36060,
@@ -618,8 +624,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = BUZ,
.name = "Buz",
- .vendor_id = PCI_VENDOR_ID_IOMEGA,
- .device_id = PCI_DEVICE_ID_IOMEGA_BUZ,
.i2c_decoder = I2C_DRIVERID_SAA7111A,
.i2c_encoder = I2C_DRIVERID_SAA7185B,
.video_codec = CODEC_TYPE_ZR36060,
@@ -649,8 +653,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
.name = "6-Eyes",
/* AverMedia chose not to brand the 6-Eyes. Thus it
can't be autodetected, and requires card=x. */
- .vendor_id = -1,
- .device_id = -1,
.i2c_decoder = I2C_DRIVERID_KS0127,
.i2c_encoder = I2C_DRIVERID_BT866,
.video_codec = CODEC_TYPE_ZR36060,
@@ -1138,7 +1140,8 @@ zr36057_init (struct zoran *zr)
strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0)
- goto exit_unregister;
+ goto exit_free;
+ video_set_drvdata(zr->video_dev, zr);
zoran_init_hardware(zr);
if (zr36067_debug > 2)
@@ -1153,19 +1156,19 @@ zr36057_init (struct zoran *zr)
zr->initialized = 1;
return 0;
-exit_unregister:
- zoran_unregister_i2c(zr);
exit_free:
kfree(zr->stat_com);
kfree(zr->video_dev);
return err;
}
-static void
-zoran_release (struct zoran *zr)
+static void __devexit zoran_remove(struct pci_dev *pdev)
{
+ struct zoran *zr = pci_get_drvdata(pdev);
+
if (!zr->initialized)
goto exit_free;
+
/* unregister videocodec bus */
if (zr->codec) {
struct videocodec_master *master = zr->codec->master_data;
@@ -1194,6 +1197,7 @@ zoran_release (struct zoran *zr)
pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev);
exit_free:
+ pci_set_drvdata(pdev, NULL);
kfree(zr);
}
@@ -1256,338 +1260,329 @@ zoran_setup_videocodec (struct zoran *zr,
* Scan for a Buz card (actually for the PCI controller ZR36057),
* request the irq and map the io memory
*/
-static int __devinit
-find_zr36057 (void)
+static int __devinit zoran_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
unsigned char latency, need_latency;
struct zoran *zr;
- struct pci_dev *dev = NULL;
int result;
struct videocodec_master *master_vfe = NULL;
struct videocodec_master *master_codec = NULL;
int card_num;
char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+ unsigned int nr;
- zoran_num = 0;
- while (zoran_num < BUZ_MAX &&
- (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
- card_num = card[zoran_num];
- zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
- if (!zr) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - kzalloc failed\n",
- ZORAN_NAME);
- continue;
- }
- zr->pci_dev = dev;
- //zr->zr36057_mem = NULL;
- zr->id = zoran_num;
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
- spin_lock_init(&zr->spinlock);
- mutex_init(&zr->resource_lock);
- if (pci_enable_device(dev))
- goto zr_free_mem;
- zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
- pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
- &zr->revision);
- if (zr->revision < 2) {
- dprintk(1,
- KERN_INFO
- "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
- ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
- zr->zr36057_adr);
- if (card_num == -1) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
- ZR_DEVNAME(zr));
- goto zr_free_mem;
- }
- } else {
- int i;
- unsigned short ss_vendor, ss_device;
+ nr = zoran_num++;
+ if (nr >= BUZ_MAX) {
+ dprintk(1,
+ KERN_ERR
+ "%s: driver limited to %d card(s) maximum\n",
+ ZORAN_NAME, BUZ_MAX);
+ return -ENOENT;
+ }
- ss_vendor = zr->pci_dev->subsystem_vendor;
- ss_device = zr->pci_dev->subsystem_device;
+ zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
+ if (!zr) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - kzalloc failed\n",
+ ZORAN_NAME);
+ return -ENOMEM;
+ }
+ zr->pci_dev = pdev;
+ zr->id = nr;
+ snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
+ spin_lock_init(&zr->spinlock);
+ mutex_init(&zr->resource_lock);
+ if (pci_enable_device(pdev))
+ goto zr_free_mem;
+ pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
+
+ dprintk(1,
+ KERN_INFO
+ "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n",
+ ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision,
+ zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0));
+ if (zr->revision >= 2) {
+ dprintk(1,
+ KERN_INFO
+ "%s: Subsystem vendor=0x%04x id=0x%04x\n",
+ ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor,
+ zr->pci_dev->subsystem_device);
+ }
+
+ /* Use auto-detected card type? */
+ if (card[nr] == -1) {
+ if (zr->revision < 2) {
dprintk(1,
- KERN_INFO
- "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
- ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
- zr->zr36057_adr);
+ KERN_ERR
+ "%s: No card type specified, please use the card=X module parameter\n",
+ ZR_DEVNAME(zr));
dprintk(1,
- KERN_INFO
- "%s: subsystem vendor=0x%04x id=0x%04x\n",
- ZR_DEVNAME(zr), ss_vendor, ss_device);
- if (card_num == -1) {
- dprintk(3,
- KERN_DEBUG
- "%s: find_zr36057() - trying to autodetect card type\n",
- ZR_DEVNAME(zr));
- for (i=0;i<NUM_CARDS;i++) {
- if (ss_vendor == zoran_cards[i].vendor_id &&
- ss_device == zoran_cards[i].device_id) {
- dprintk(3,
- KERN_DEBUG
- "%s: find_zr36057() - card %s detected\n",
- ZR_DEVNAME(zr),
- zoran_cards[i].name);
- card_num = i;
- break;
- }
- }
- if (i == NUM_CARDS) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - unknown card\n",
- ZR_DEVNAME(zr));
- goto zr_free_mem;
- }
- }
- }
-
- if (card_num < 0 || card_num >= NUM_CARDS) {
- dprintk(2,
KERN_ERR
- "%s: find_zr36057() - invalid cardnum %d\n",
- ZR_DEVNAME(zr), card_num);
+ "%s: It is not possible to auto-detect ZR36057 based cards\n",
+ ZR_DEVNAME(zr));
goto zr_free_mem;
}
- /* even though we make this a non pointer and thus
- * theoretically allow for making changes to this struct
- * on a per-individual card basis at runtime, this is
- * strongly discouraged. This structure is intended to
- * keep general card information, no settings or anything */
- zr->card = zoran_cards[card_num];
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
- "%s[%u]", zr->card.name, zr->id);
-
- zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
- if (!zr->zr36057_mem) {
+ card_num = ent->driver_data;
+ if (card_num >= NUM_CARDS) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - ioremap failed\n",
+ "%s: Unknown card, try specifying card=X module parameter\n",
ZR_DEVNAME(zr));
goto zr_free_mem;
}
-
- result = request_irq(zr->pci_dev->irq,
- zoran_irq,
- IRQF_SHARED | IRQF_DISABLED,
- ZR_DEVNAME(zr),
- (void *) zr);
- if (result < 0) {
- if (result == -EINVAL) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - bad irq number or handler\n",
- ZR_DEVNAME(zr));
- } else if (result == -EBUSY) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
- ZR_DEVNAME(zr), zr->pci_dev->irq);
- } else {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - can't assign irq, error code %d\n",
- ZR_DEVNAME(zr), result);
- }
- goto zr_unmap;
- }
-
- /* set PCI latency timer */
- pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
- &latency);
- need_latency = zr->revision > 1 ? 32 : 48;
- if (latency != need_latency) {
- dprintk(2,
- KERN_INFO
- "%s: Changing PCI latency from %d to %d.\n",
- ZR_DEVNAME(zr), latency, need_latency);
- pci_write_config_byte(zr->pci_dev,
- PCI_LATENCY_TIMER,
- need_latency);
+ dprintk(3,
+ KERN_DEBUG
+ "%s: %s() - card %s detected\n",
+ ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name);
+ } else {
+ card_num = card[nr];
+ if (card_num >= NUM_CARDS || card_num < 0) {
+ dprintk(1,
+ KERN_ERR
+ "%s: User specified card type %d out of range (0 .. %d)\n",
+ ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
+ goto zr_free_mem;
}
+ }
- zr36057_restart(zr);
- /* i2c */
- dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
- ZR_DEVNAME(zr));
+ /* even though we make this a non pointer and thus
+ * theoretically allow for making changes to this struct
+ * on a per-individual card basis at runtime, this is
+ * strongly discouraged. This structure is intended to
+ * keep general card information, no settings or anything */
+ zr->card = zoran_cards[card_num];
+ snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
+ "%s[%u]", zr->card.name, zr->id);
+
+ zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
+ if (!zr->zr36057_mem) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s() - ioremap failed\n",
+ ZR_DEVNAME(zr), __func__);
+ goto zr_free_mem;
+ }
- /* i2c decoder */
- if (decoder[zr->id] != -1) {
- i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
- zr->card.i2c_decoder = decoder[zr->id];
- } else if (zr->card.i2c_decoder != 0) {
- i2c_dec_name =
- i2cid_to_modulename(zr->card.i2c_decoder);
+ result = request_irq(zr->pci_dev->irq, zoran_irq,
+ IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
+ if (result < 0) {
+ if (result == -EINVAL) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - bad irq number or handler\n",
+ ZR_DEVNAME(zr));
+ } else if (result == -EBUSY) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
+ ZR_DEVNAME(zr), zr->pci_dev->irq);
} else {
- i2c_dec_name = NULL;
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - can't assign irq, error code %d\n",
+ ZR_DEVNAME(zr), result);
}
+ goto zr_unmap;
+ }
- if (i2c_dec_name) {
- if ((result = request_module(i2c_dec_name)) < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_dec_name, result);
- }
- }
+ /* set PCI latency timer */
+ pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+ &latency);
+ need_latency = zr->revision > 1 ? 32 : 48;
+ if (latency != need_latency) {
+ dprintk(2,
+ KERN_INFO
+ "%s: Changing PCI latency from %d to %d\n",
+ ZR_DEVNAME(zr), latency, need_latency);
+ pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
+ need_latency);
+ }
- /* i2c encoder */
- if (encoder[zr->id] != -1) {
- i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
- zr->card.i2c_encoder = encoder[zr->id];
- } else if (zr->card.i2c_encoder != 0) {
- i2c_enc_name =
- i2cid_to_modulename(zr->card.i2c_encoder);
- } else {
- i2c_enc_name = NULL;
- }
+ zr36057_restart(zr);
+ /* i2c */
+ dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
+ ZR_DEVNAME(zr));
+
+ /* i2c decoder */
+ if (decoder[zr->id] != -1) {
+ i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
+ zr->card.i2c_decoder = decoder[zr->id];
+ } else if (zr->card.i2c_decoder != 0) {
+ i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
+ } else {
+ i2c_dec_name = NULL;
+ }
- if (i2c_enc_name) {
- if ((result = request_module(i2c_enc_name)) < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_enc_name, result);
- }
+ if (i2c_dec_name) {
+ result = request_module(i2c_dec_name);
+ if (result < 0) {
+ dprintk(1,
+ KERN_ERR
+ "%s: failed to load module %s: %d\n",
+ ZR_DEVNAME(zr), i2c_dec_name, result);
}
+ }
+
+ /* i2c encoder */
+ if (encoder[zr->id] != -1) {
+ i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
+ zr->card.i2c_encoder = encoder[zr->id];
+ } else if (zr->card.i2c_encoder != 0) {
+ i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
+ } else {
+ i2c_enc_name = NULL;
+ }
- if (zoran_register_i2c(zr) < 0) {
+ if (i2c_enc_name) {
+ result = request_module(i2c_enc_name);
+ if (result < 0) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - can't initialize i2c bus\n",
- ZR_DEVNAME(zr));
- goto zr_free_irq;
+ "%s: failed to load module %s: %d\n",
+ ZR_DEVNAME(zr), i2c_enc_name, result);
}
+ }
- dprintk(2,
- KERN_INFO "%s: Initializing videocodec bus...\n",
+ if (zoran_register_i2c(zr) < 0) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - can't initialize i2c bus\n",
ZR_DEVNAME(zr));
+ goto zr_free_irq;
+ }
- if (zr->card.video_codec != 0 &&
- (codec_name =
- codecid_to_modulename(zr->card.video_codec)) != NULL) {
- if ((result = request_module(codec_name)) < 0) {
+ dprintk(2,
+ KERN_INFO "%s: Initializing videocodec bus...\n",
+ ZR_DEVNAME(zr));
+
+ if (zr->card.video_codec) {
+ codec_name = codecid_to_modulename(zr->card.video_codec);
+ if (codec_name) {
+ result = request_module(codec_name);
+ if (result) {
dprintk(1,
KERN_ERR
"%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), codec_name, result);
}
}
- if (zr->card.video_vfe != 0 &&
- (vfe_name =
- codecid_to_modulename(zr->card.video_vfe)) != NULL) {
- if ((result = request_module(vfe_name)) < 0) {
+ }
+ if (zr->card.video_vfe) {
+ vfe_name = codecid_to_modulename(zr->card.video_vfe);
+ if (vfe_name) {
+ result = request_module(vfe_name);
+ if (result < 0) {
dprintk(1,
KERN_ERR
"%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), vfe_name, result);
}
}
+ }
- /* reset JPEG codec */
- jpeg_codec_sleep(zr, 1);
- jpeg_codec_reset(zr);
- /* video bus enabled */
- /* display codec revision */
- if (zr->card.video_codec != 0) {
- master_codec = zoran_setup_videocodec(zr,
- zr->card.video_codec);
- if (!master_codec)
- goto zr_unreg_i2c;
- zr->codec = videocodec_attach(master_codec);
- if (!zr->codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no codec found\n",
- ZR_DEVNAME(zr));
- goto zr_free_codec;
- }
- if (zr->codec->type != zr->card.video_codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - wrong codec\n",
- ZR_DEVNAME(zr));
- goto zr_detach_codec;
- }
+ /* reset JPEG codec */
+ jpeg_codec_sleep(zr, 1);
+ jpeg_codec_reset(zr);
+ /* video bus enabled */
+ /* display codec revision */
+ if (zr->card.video_codec != 0) {
+ master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
+ if (!master_codec)
+ goto zr_unreg_i2c;
+ zr->codec = videocodec_attach(master_codec);
+ if (!zr->codec) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - no codec found\n",
+ ZR_DEVNAME(zr));
+ goto zr_free_codec;
}
- if (zr->card.video_vfe != 0) {
- master_vfe = zoran_setup_videocodec(zr,
- zr->card.video_vfe);
- if (!master_vfe)
- goto zr_detach_codec;
- zr->vfe = videocodec_attach(master_vfe);
- if (!zr->vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no VFE found\n",
- ZR_DEVNAME(zr));
- goto zr_free_vfe;
- }
- if (zr->vfe->type != zr->card.video_vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() = wrong VFE\n",
- ZR_DEVNAME(zr));
- goto zr_detach_vfe;
- }
+ if (zr->codec->type != zr->card.video_codec) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - wrong codec\n",
+ ZR_DEVNAME(zr));
+ goto zr_detach_codec;
+ }
+ }
+ if (zr->card.video_vfe != 0) {
+ master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
+ if (!master_vfe)
+ goto zr_detach_codec;
+ zr->vfe = videocodec_attach(master_vfe);
+ if (!zr->vfe) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() - no VFE found\n",
+ ZR_DEVNAME(zr));
+ goto zr_free_vfe;
+ }
+ if (zr->vfe->type != zr->card.video_vfe) {
+ dprintk(1,
+ KERN_ERR
+ "%s: find_zr36057() = wrong VFE\n",
+ ZR_DEVNAME(zr));
+ goto zr_detach_vfe;
}
- /* Success so keep the pci_dev referenced */
- pci_dev_get(zr->pci_dev);
- zoran[zoran_num++] = zr;
- continue;
-
- // Init errors
- zr_detach_vfe:
- videocodec_detach(zr->vfe);
- zr_free_vfe:
- kfree(master_vfe);
- zr_detach_codec:
- videocodec_detach(zr->codec);
- zr_free_codec:
- kfree(master_codec);
- zr_unreg_i2c:
- zoran_unregister_i2c(zr);
- zr_free_irq:
- btwrite(0, ZR36057_SPGPPCR);
- free_irq(zr->pci_dev->irq, zr);
- zr_unmap:
- iounmap(zr->zr36057_mem);
- zr_free_mem:
- kfree(zr);
- continue;
}
- if (dev) /* Clean up ref count on early exit */
- pci_dev_put(dev);
- if (zoran_num == 0) {
- dprintk(1, KERN_INFO "No known MJPEG cards found.\n");
+ /* take care of Natoma chipset and a revision 1 zr36057 */
+ if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
+ zr->jpg_buffers.need_contiguous = 1;
+ dprintk(1,
+ KERN_INFO
+ "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
+ ZR_DEVNAME(zr));
}
- return zoran_num;
+
+ if (zr36057_init(zr) < 0)
+ goto zr_detach_vfe;
+
+ zoran_proc_init(zr);
+
+ pci_set_drvdata(pdev, zr);
+
+ return 0;
+
+zr_detach_vfe:
+ videocodec_detach(zr->vfe);
+zr_free_vfe:
+ kfree(master_vfe);
+zr_detach_codec:
+ videocodec_detach(zr->codec);
+zr_free_codec:
+ kfree(master_codec);
+zr_unreg_i2c:
+ zoran_unregister_i2c(zr);
+zr_free_irq:
+ btwrite(0, ZR36057_SPGPPCR);
+ free_irq(zr->pci_dev->irq, zr);
+zr_unmap:
+ iounmap(zr->zr36057_mem);
+zr_free_mem:
+ kfree(zr);
+
+ return -ENODEV;
}
-static int __init
-init_dc10_cards (void)
+static struct pci_driver zoran_driver = {
+ .name = "zr36067",
+ .id_table = zr36067_pci_tbl,
+ .probe = zoran_probe,
+ .remove = zoran_remove,
+};
+
+static int __init zoran_init(void)
{
- int i;
+ int res;
- memset(zoran, 0, sizeof(zoran));
printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
- /* Look for cards */
- if (find_zr36057() < 0) {
- return -EIO;
- }
- if (zoran_num == 0)
- return -ENODEV;
- dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
- zoran_num);
/* check the parameters we have been given, adjust if necessary */
if (v4l_nbufs < 2)
v4l_nbufs = 2;
@@ -1629,37 +1624,22 @@ init_dc10_cards (void)
ZORAN_NAME);
}
- /* take care of Natoma chipset and a revision 1 zr36057 */
- for (i = 0; i < zoran_num; i++) {
- struct zoran *zr = zoran[i];
-
- if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
- zr->jpg_buffers.need_contiguous = 1;
- dprintk(1,
- KERN_INFO
- "%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
- ZR_DEVNAME(zr));
- }
-
- if (zr36057_init(zr) < 0) {
- for (i = 0; i < zoran_num; i++)
- zoran_release(zoran[i]);
- return -EIO;
- }
- zoran_proc_init(zr);
+ res = pci_register_driver(&zoran_driver);
+ if (res) {
+ dprintk(1,
+ KERN_ERR
+ "%s: Unable to register ZR36057 driver\n",
+ ZORAN_NAME);
+ return res;
}
return 0;
}
-static void __exit
-unload_dc10_cards (void)
+static void __exit zoran_exit(void)
{
- int i;
-
- for (i = 0; i < zoran_num; i++)
- zoran_release(zoran[i]);
+ pci_unregister_driver(&zoran_driver);
}
-module_init(init_dc10_cards);
-module_exit(unload_dc10_cards);
+module_init(zoran_init);
+module_exit(zoran_exit);
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h
index e4dc9d29b404..4507bdc5e338 100644
--- a/drivers/media/video/zoran/zoran_card.h
+++ b/drivers/media/video/zoran/zoran_card.h
@@ -40,8 +40,6 @@ extern int zr36067_debug;
/* Anybody who uses more than four? */
#define BUZ_MAX 4
-extern int zoran_num;
-extern struct zoran *zoran[BUZ_MAX];
extern struct video_device zoran_template;
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index b58b9dda715c..b81e20912fa7 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -344,9 +344,9 @@ v4l_fbuffer_alloc (struct file *file)
SetPageReserved(MAP_NR(mem + off));
dprintk(4,
KERN_INFO
- "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
+ "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\n",
ZR_DEVNAME(zr), i, (unsigned long) mem,
- virt_to_bus(mem));
+ (unsigned long long)virt_to_bus(mem));
} else {
/* Use high memory which has been left at boot time */
@@ -1196,83 +1196,54 @@ zoran_close_end_session (struct file *file)
* Open a zoran card. Right now the flags stuff is just playing
*/
-static int
-zoran_open(struct file *file)
+static int zoran_open(struct file *file)
{
- unsigned int minor = video_devdata(file)->minor;
- struct zoran *zr = NULL;
+ struct zoran *zr = video_drvdata(file);
struct zoran_fh *fh;
- int i, res, first_open = 0, have_module_locks = 0;
+ int res, first_open = 0;
- lock_kernel();
- /* find the device */
- for (i = 0; i < zoran_num; i++) {
- if (zoran[i]->video_dev->minor == minor) {
- zr = zoran[i];
- break;
- }
- }
+ dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
+ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
- if (!zr) {
- dprintk(1, KERN_ERR "%s: device not found!\n", ZORAN_NAME);
- res = -ENODEV;
- goto open_unlock_and_return;
- }
+ lock_kernel();
/* see fs/device.c - the kernel already locks during open(),
* so locking ourselves only causes deadlocks */
/*mutex_lock(&zr->resource_lock);*/
+ if (zr->user >= 2048) {
+ dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
+ ZR_DEVNAME(zr), zr->user);
+ res = -EBUSY;
+ goto fail_unlock;
+ }
+
if (!zr->decoder) {
dprintk(1,
KERN_ERR "%s: no TV decoder loaded for device!\n",
ZR_DEVNAME(zr));
res = -EIO;
- goto open_unlock_and_return;
+ goto fail_unlock;
}
- /* try to grab a module lock */
- if (!try_module_get(THIS_MODULE)) {
- dprintk(1,
- KERN_ERR
- "%s: failed to acquire my own lock! PANIC!\n",
- ZR_DEVNAME(zr));
- res = -ENODEV;
- goto open_unlock_and_return;
- }
if (!try_module_get(zr->decoder->driver->driver.owner)) {
dprintk(1,
KERN_ERR
- "%s: failed to grab ownership of i2c decoder\n",
+ "%s: failed to grab ownership of video decoder\n",
ZR_DEVNAME(zr));
res = -EIO;
- module_put(THIS_MODULE);
- goto open_unlock_and_return;
+ goto fail_unlock;
}
if (zr->encoder &&
!try_module_get(zr->encoder->driver->driver.owner)) {
dprintk(1,
KERN_ERR
- "%s: failed to grab ownership of i2c encoder\n",
+ "%s: failed to grab ownership of video encoder\n",
ZR_DEVNAME(zr));
res = -EIO;
- module_put(zr->decoder->driver->driver.owner);
- module_put(THIS_MODULE);
- goto open_unlock_and_return;
+ goto fail_decoder;
}
- have_module_locks = 1;
-
- if (zr->user >= 2048) {
- dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
- ZR_DEVNAME(zr), zr->user);
- res = -EBUSY;
- goto open_unlock_and_return;
- }
-
- dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
-
/* now, create the open()-specific file_ops struct */
fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
if (!fh) {
@@ -1281,7 +1252,7 @@ zoran_open(struct file *file)
"%s: zoran_open() - allocation of zoran_fh failed\n",
ZR_DEVNAME(zr));
res = -ENOMEM;
- goto open_unlock_and_return;
+ goto fail_encoder;
}
/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
* on norm-change! */
@@ -1292,9 +1263,8 @@ zoran_open(struct file *file)
KERN_ERR
"%s: zoran_open() - allocation of overlay_mask failed\n",
ZR_DEVNAME(zr));
- kfree(fh);
res = -ENOMEM;
- goto open_unlock_and_return;
+ goto fail_fh;
}
if (zr->user++ == 0)
@@ -1319,22 +1289,19 @@ zoran_open(struct file *file)
return 0;
-open_unlock_and_return:
- /* if we grabbed locks, release them accordingly */
- if (have_module_locks) {
- module_put(zr->decoder->driver->driver.owner);
- if (zr->encoder) {
- module_put(zr->encoder->driver->driver.owner);
- }
- module_put(THIS_MODULE);
- }
-
- /* if there's no device found, we didn't obtain the lock either */
- if (zr) {
- /*mutex_unlock(&zr->resource_lock);*/
- }
+fail_fh:
+ kfree(fh);
+fail_encoder:
+ if (zr->encoder)
+ module_put(zr->encoder->driver->driver.owner);
+fail_decoder:
+ module_put(zr->decoder->driver->driver.owner);
+fail_unlock:
unlock_kernel();
+ dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
+ ZR_DEVNAME(zr), res, zr->user);
+
return res;
}
@@ -1344,8 +1311,8 @@ zoran_close(struct file *file)
struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
- dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
+ dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
+ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
/* kernel locks (fs/device.c), so don't do that ourselves
* (prevents deadlocks) */
@@ -1391,10 +1358,8 @@ zoran_close(struct file *file)
/* release locks on the i2c modules */
module_put(zr->decoder->driver->driver.owner);
- if (zr->encoder) {
- module_put(zr->encoder->driver->driver.owner);
- }
- module_put(THIS_MODULE);
+ if (zr->encoder)
+ module_put(zr->encoder->driver->driver.owner);
/*mutex_unlock(&zr->resource_lock);*/
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 93023560f324..f2f8cdd71c46 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -96,6 +96,7 @@ static struct usb_device_id device_table[] = {
{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
+ {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
{} /* Terminating entry */
};
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 96ac88317b8e..ea3aafbbda44 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -91,9 +91,9 @@ MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
controllers (default=0)");
static int mpt_msi_enable_sas;
-module_param(mpt_msi_enable_sas, int, 1);
+module_param(mpt_msi_enable_sas, int, 0);
MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
- controllers (default=1)");
+ controllers (default=0)");
static int mpt_channel_mapping;
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c
index 1a4d04664d6d..aa266e1f69b2 100644
--- a/drivers/mfd/htc-egpio.c
+++ b/drivers/mfd/htc-egpio.c
@@ -286,7 +286,7 @@ static int __init egpio_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
goto fail;
- ei->base_addr = ioremap_nocache(res->start, res->end - res->start);
+ ei->base_addr = ioremap_nocache(res->start, resource_size(res));
if (!ei->base_addr)
goto fail;
pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr);
@@ -307,7 +307,7 @@ static int __init egpio_probe(struct platform_device *pdev)
ei->nchips = pdata->num_chips;
ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL);
- if (!ei) {
+ if (!ei->chip) {
ret = -ENOMEM;
goto fail;
}
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 6063dc2b52e8..57271cb3b316 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(mcp_host_alloc);
int mcp_host_register(struct mcp *mcp)
{
- strcpy(mcp->attached_device.bus_id, "mcp0");
+ dev_set_name(&mcp->attached_device, "mcp0");
return device_register(&mcp->attached_device);
}
EXPORT_SYMBOL(mcp_host_register);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 24508e28e3fb..2e36057659e1 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -626,7 +626,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
}
if (client->irq) {
- set_irq_handler(client->irq, handle_level_irq);
ret = request_irq(client->irq, pcf50633_irq,
IRQF_TRIGGER_LOW, "pcf50633", pcf);
@@ -679,6 +678,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
static struct i2c_device_id pcf50633_id_table[] = {
{"pcf50633", 0x73},
+ {/* end of list */}
};
static struct i2c_driver pcf50633_driver = {
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 0e5761f12634..4c7b7962f6b8 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1050,7 +1050,7 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm,
return gpiochip_add(gchip);
}
-static int sm501_register_gpio(struct sm501_devdata *sm)
+static int __devinit sm501_register_gpio(struct sm501_devdata *sm)
{
struct sm501_gpio *gpio = &sm->gpio;
resource_size_t iobase = sm->io_res->start + SM501_GPIO;
@@ -1321,7 +1321,7 @@ static unsigned int sm501_mem_local[] = {
* Common init code for an SM501
*/
-static int sm501_init_dev(struct sm501_devdata *sm)
+static int __devinit sm501_init_dev(struct sm501_devdata *sm)
{
struct sm501_initdata *idata;
struct sm501_platdata *pdata;
@@ -1397,7 +1397,7 @@ static int sm501_init_dev(struct sm501_devdata *sm)
return 0;
}
-static int sm501_plat_probe(struct platform_device *dev)
+static int __devinit sm501_plat_probe(struct platform_device *dev)
{
struct sm501_devdata *sm;
int ret;
@@ -1586,8 +1586,8 @@ static struct sm501_platdata sm501_pci_platdata = {
.gpio_base = -1,
};
-static int sm501_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int __devinit sm501_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
struct sm501_devdata *sm;
int err;
@@ -1693,7 +1693,7 @@ static void sm501_dev_remove(struct sm501_devdata *sm)
sm501_gpio_remove(sm);
}
-static void sm501_pci_remove(struct pci_dev *dev)
+static void __devexit sm501_pci_remove(struct pci_dev *dev)
{
struct sm501_devdata *sm = pci_get_drvdata(dev);
@@ -1727,16 +1727,16 @@ static struct pci_device_id sm501_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, sm501_pci_tbl);
-static struct pci_driver sm501_pci_drv = {
+static struct pci_driver sm501_pci_driver = {
.name = "sm501",
.id_table = sm501_pci_tbl,
.probe = sm501_pci_probe,
- .remove = sm501_pci_remove,
+ .remove = __devexit_p(sm501_pci_remove),
};
MODULE_ALIAS("platform:sm501");
-static struct platform_driver sm501_plat_drv = {
+static struct platform_driver sm501_plat_driver = {
.driver = {
.name = "sm501",
.owner = THIS_MODULE,
@@ -1749,14 +1749,14 @@ static struct platform_driver sm501_plat_drv = {
static int __init sm501_base_init(void)
{
- platform_driver_register(&sm501_plat_drv);
- return pci_register_driver(&sm501_pci_drv);
+ platform_driver_register(&sm501_plat_driver);
+ return pci_register_driver(&sm501_pci_driver);
}
static void __exit sm501_base_exit(void)
{
- platform_driver_unregister(&sm501_plat_drv);
- pci_unregister_driver(&sm501_pci_drv);
+ platform_driver_unregister(&sm501_plat_driver);
+ pci_unregister_driver(&sm501_pci_driver);
}
module_init(sm501_base_init);
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index e7ab0035d305..68826f1e36bc 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -38,7 +38,7 @@
#include <linux/i2c.h>
#include <linux/i2c/twl4030.h>
-#ifdef CONFIG_ARM
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
#include <mach/cpu.h>
#endif
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 6860c924f364..fea9085fe52c 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -492,7 +492,7 @@ static int ucb1x00_probe(struct mcp *mcp)
ucb->dev.class = &ucb1x00_class;
ucb->dev.parent = &mcp->attached_device;
- strlcpy(ucb->dev.bus_id, "ucb1x00", sizeof(ucb->dev.bus_id));
+ dev_set_name(&ucb->dev, "ucb1x00");
spin_lock_init(&ucb->lock);
spin_lock_init(&ucb->io_lock);
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index f92595c8f165..84d5ea1ec171 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
do {
schedule_timeout_interruptible(1);
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- } while (tries-- && (reg & WM8350_AUXADC_POLL));
+ } while (--tries && (reg & WM8350_AUXADC_POLL));
if (!tries)
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
@@ -1297,14 +1297,29 @@ static void wm8350_client_dev_register(struct wm8350 *wm8350,
int wm8350_device_init(struct wm8350 *wm8350, int irq,
struct wm8350_platform_data *pdata)
{
- int ret = -EINVAL;
+ int ret;
u16 id1, id2, mask_rev;
u16 cust_id, mode, chip_rev;
/* get WM8350 revision and config mode */
- wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1);
- wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2);
- wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), &mask_rev);
+ ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
+ goto err;
+ }
+
+ ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Failed to read ID: %d\n", ret);
+ goto err;
+ }
+
+ ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev),
+ &mask_rev);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Failed to read revision: %d\n", ret);
+ goto err;
+ }
id1 = be16_to_cpu(id1);
id2 = be16_to_cpu(id2);
@@ -1404,14 +1419,12 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
return ret;
}
- if (pdata && pdata->init) {
- ret = pdata->init(wm8350);
- if (ret != 0) {
- dev_err(wm8350->dev, "Platform init() failed: %d\n",
- ret);
- goto err;
- }
- }
+ wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
+ wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
mutex_init(&wm8350->auxadc_mutex);
mutex_init(&wm8350->irq_mutex);
@@ -1430,6 +1443,15 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
}
wm8350->chip_irq = irq;
+ if (pdata && pdata->init) {
+ ret = pdata->init(wm8350);
+ if (ret != 0) {
+ dev_err(wm8350->dev, "Platform init() failed: %d\n",
+ ret);
+ goto err;
+ }
+ }
+
wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0);
wm8350_client_dev_register(wm8350, "wm8350-codec",
diff --git a/drivers/mfd/wm8350-regmap.c b/drivers/mfd/wm8350-regmap.c
index 68887b817d17..9a4cc954cb7c 100644
--- a/drivers/mfd/wm8350-regmap.c
+++ b/drivers/mfd/wm8350-regmap.c
@@ -3188,7 +3188,7 @@ const struct wm8350_reg_access wm8350_reg_io_map[] = {
{ 0x7CFF, 0x0C00, 0x7FFF }, /* R1 - ID */
{ 0x0000, 0x0000, 0x0000 }, /* R2 */
{ 0xBE3B, 0xBE3B, 0x8000 }, /* R3 - System Control 1 */
- { 0xFCF7, 0xFCF7, 0xF800 }, /* R4 - System Control 2 */
+ { 0xFEF7, 0xFEF7, 0xF800 }, /* R4 - System Control 2 */
{ 0x80FF, 0x80FF, 0x8000 }, /* R5 - System Hibernate */
{ 0xFB0E, 0xFB0E, 0x0000 }, /* R6 - Interface Control */
{ 0x0000, 0x0000, 0x0000 }, /* R7 */
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 419c378bd24b..1c484084ed4f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -87,14 +87,6 @@ config PHANTOM
If you choose to build module, its name will be phantom. If unsure,
say N here.
-config EEPROM_93CX6
- tristate "EEPROM 93CX6 support"
- ---help---
- This is a driver for the EEPROM chipsets 93c46 and 93c66.
- The driver supports both read as well as write commands.
-
- If unsure, say N.
-
config SGI_IOC4
tristate "SGI IOC4 Base IO support"
depends on PCI
@@ -170,7 +162,7 @@ config ENCLOSURE_SERVICES
config SGI_XP
tristate "Support communication between SGI SSIs"
depends on NET
- depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_64) && SMP
+ depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP
@@ -197,7 +189,7 @@ config HP_ILO
config SGI_GRU
tristate "SGI GRU driver"
- depends on (X86_64 || IA64_SGI_UV || IA64_GENERIC) && SMP
+ depends on (X86_UV || IA64_SGI_UV || IA64_GENERIC) && SMP
default n
select MMU_NOTIFIER
---help---
@@ -225,11 +217,13 @@ config DELL_LAPTOP
depends on EXPERIMENTAL
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL
+ depends on POWER_SUPPLY
default n
---help---
This driver adds support for rfkill and backlight control to Dell
laptops.
source "drivers/misc/c2port/Kconfig"
+source "drivers/misc/eeprom/Kconfig"
endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d5749a7bc777..bc1199830554 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -13,10 +13,10 @@ obj-$(CONFIG_TIFM_CORE) += tifm_core.o
obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
obj-$(CONFIG_PHANTOM) += phantom.o
obj-$(CONFIG_SGI_IOC4) += ioc4.o
-obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
obj-$(CONFIG_SGI_XP) += sgi-xp/
obj-$(CONFIG_SGI_GRU) += sgi-gru/
obj-$(CONFIG_HP_ILO) += hpilo.o
obj-$(CONFIG_C2PORT) += c2port/
+obj-y += eeprom/
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index bf5e4d065436..558bf3f2c276 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -35,7 +35,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num)
if (!ssc_valid) {
spin_unlock(&user_lock);
- dev_dbg(&ssc->pdev->dev, "could not find requested device\n");
+ pr_err("ssc: ssc%d platform device is missing\n", ssc_num);
return ERR_PTR(-ENODEV);
}
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
new file mode 100644
index 000000000000..89fec052f3b4
--- /dev/null
+++ b/drivers/misc/eeprom/Kconfig
@@ -0,0 +1,59 @@
+menu "EEPROM support"
+
+config EEPROM_AT24
+ tristate "I2C EEPROMs from most vendors"
+ depends on I2C && SYSFS
+ help
+ Enable this driver to get read/write support to most I2C EEPROMs,
+ after you configure the driver to know about each EEPROM on
+ your target board. Use these generic chip names, instead of
+ vendor-specific ones like at24c64 or 24lc02:
+
+ 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
+ 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
+
+ Unless you like data loss puzzles, always be sure that any chip
+ you configure as a 24c32 (32 kbit) or larger is NOT really a
+ 24c16 (16 kbit) or smaller, and vice versa. Marking the chip
+ as read-only won't help recover from this. Also, if your chip
+ has any software write-protect mechanism you may want to review the
+ code to make sure this driver won't turn it on by accident.
+
+ If you use this with an SMBus adapter instead of an I2C adapter,
+ full functionality is not available. Only smaller devices are
+ supported (24c16 and below, max 4 kByte).
+
+ This driver can also be built as a module. If so, the module
+ will be called at24.
+
+config EEPROM_AT25
+ tristate "SPI EEPROMs from most vendors"
+ depends on SPI && SYSFS
+ help
+ Enable this driver to get read/write support to most SPI EEPROMs,
+ after you configure the board init code to know about each eeprom
+ on your target board.
+
+ This driver can also be built as a module. If so, the module
+ will be called at25.
+
+config EEPROM_LEGACY
+ tristate "Old I2C EEPROM reader"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get read-only access to the EEPROM data
+ available on modern memory DIMMs and Sony Vaio laptops via I2C. Such
+ EEPROMs could theoretically be available on other devices as well.
+
+ This driver can also be built as a module. If so, the module
+ will be called eeprom.
+
+config EEPROM_93CX6
+ tristate "EEPROM 93CX6 support"
+ help
+ This is a driver for the EEPROM chipsets 93c46 and 93c66.
+ The driver supports both read as well as write commands.
+
+ If unsure, say N.
+
+endmenu
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile
new file mode 100644
index 000000000000..539dd8f88128
--- /dev/null
+++ b/drivers/misc/eeprom/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_EEPROM_AT24) += at24.o
+obj-$(CONFIG_EEPROM_AT25) += at25.o
+obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
+obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
diff --git a/drivers/i2c/chips/at24.c b/drivers/misc/eeprom/at24.c
index d4775528abc6..d4775528abc6 100644
--- a/drivers/i2c/chips/at24.c
+++ b/drivers/misc/eeprom/at24.c
diff --git a/drivers/spi/at25.c b/drivers/misc/eeprom/at25.c
index 290dbe99647a..290dbe99647a 100644
--- a/drivers/spi/at25.c
+++ b/drivers/misc/eeprom/at25.c
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/misc/eeprom/eeprom.c
index 2c27193aeaa0..2c27193aeaa0 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/misc/eeprom/eeprom.c
diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom/eeprom_93cx6.c
index 15b1780025c8..15b1780025c8 100644
--- a/drivers/misc/eeprom_93cx6.c
+++ b/drivers/misc/eeprom/eeprom_93cx6.c
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 05e298289238..f26667a7abf7 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -207,7 +207,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
&device_ccb->recv_ctrl);
/* give iLO some time to process stop request */
- for (retries = 1000; retries > 0; retries--) {
+ for (retries = MAX_WAIT; retries > 0; retries--) {
doorbell_set(driver_ccb);
udelay(1);
if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
@@ -309,7 +309,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
doorbell_clr(driver_ccb);
/* make sure iLO is really handling requests */
- for (i = 1000; i > 0; i--) {
+ for (i = MAX_WAIT; i > 0; i--) {
if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
break;
udelay(1);
@@ -326,7 +326,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
return 0;
free:
- pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
+ ilo_ccb_close(pdev, data);
out:
return error;
}
@@ -758,7 +758,7 @@ static void __exit ilo_exit(void)
class_destroy(ilo_class);
}
-MODULE_VERSION("0.05");
+MODULE_VERSION("0.06");
MODULE_ALIAS(ILO_NAME);
MODULE_DESCRIPTION(ILO_NAME);
MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index a281207696c1..b64a20ef07e3 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -19,6 +19,8 @@
#define MAX_ILO_DEV 1
/* max number of files */
#define MAX_OPEN (MAX_CCB * MAX_ILO_DEV)
+/* spin counter for open/close delay */
+#define MAX_WAIT 10000
/*
* Per device, used to track global memory allocations.
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 650983806392..c67e4e8bd62c 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -36,23 +36,11 @@
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
+#include <asm/uv/uv.h>
#include "gru.h"
#include "grulib.h"
#include "grutables.h"
-#if defined CONFIG_X86_64
-#include <asm/genapic.h>
-#include <asm/irq.h>
-#define IS_UV() is_uv_system()
-#elif defined CONFIG_IA64
-#include <asm/system.h>
-#include <asm/sn/simulator.h>
-/* temp support for running on hardware simulator */
-#define IS_UV() IS_MEDUSA() || ia64_platform_is("uv")
-#else
-#define IS_UV() 0
-#endif
-
#include <asm/uv/uv_hub.h>
#include <asm/uv/uv_mmrs.h>
@@ -381,7 +369,7 @@ static int __init gru_init(void)
char id[10];
void *gru_start_vaddr;
- if (!IS_UV())
+ if (!is_uv_system())
return 0;
#if defined CONFIG_IA64
@@ -451,7 +439,7 @@ static void __exit gru_exit(void)
int order = get_order(sizeof(struct gru_state) *
GRU_CHIPLETS_PER_BLADE);
- if (!IS_UV())
+ if (!is_uv_system())
return;
for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h
index 7b4cbd5e03e9..2275126cb334 100644
--- a/drivers/misc/sgi-xp/xp.h
+++ b/drivers/misc/sgi-xp/xp.h
@@ -15,19 +15,19 @@
#include <linux/mutex.h>
-#ifdef CONFIG_IA64
+#if defined CONFIG_X86_UV || defined CONFIG_IA64_SGI_UV
+#include <asm/uv/uv.h>
+#define is_uv() is_uv_system()
+#endif
+
+#ifndef is_uv
+#define is_uv() 0
+#endif
+
+#if defined CONFIG_IA64
#include <asm/system.h>
#include <asm/sn/arch.h> /* defines is_shub1() and is_shub2() */
#define is_shub() ia64_platform_is("sn2")
-#ifdef CONFIG_IA64_SGI_UV
-#define is_uv() ia64_platform_is("uv")
-#else
-#define is_uv() 0
-#endif
-#endif
-#ifdef CONFIG_X86_64
-#include <asm/genapic.h>
-#define is_uv() is_uv_system()
#endif
#ifndef is_shub1
@@ -42,10 +42,6 @@
#define is_shub() 0
#endif
-#ifndef is_uv
-#define is_uv() 0
-#endif
-
#ifdef USE_DBUG_ON
#define DBUG_ON(condition) BUG_ON(condition)
#else
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index a5bd658c2e83..275b78896a73 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
@@ -514,7 +514,8 @@ struct xpc_channel_uv {
/* partition's notify mq */
struct xpc_send_msg_slot_uv *send_msg_slots;
- struct xpc_notify_mq_msg_uv *recv_msg_slots;
+ void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */
+ /* structure plus the user's payload */
struct xpc_fifo_head_uv msg_slot_free_list;
struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 9cd2ebe2a3b6..45fd653dbe31 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -49,9 +49,6 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING))
return;
-
- DBUG_ON(ch->local_msgqueue == NULL);
- DBUG_ON(ch->remote_msgqueue == NULL);
}
if (!(ch->flags & XPC_C_OPENREPLY)) {
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 89218f7cfaa7..6576170de962 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -318,7 +318,7 @@ xpc_hb_checker(void *ignore)
/* this thread was marked active by xpc_hb_init() */
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(XPC_HB_CHECK_CPU));
+ set_cpus_allowed_ptr(current, cpumask_of(XPC_HB_CHECK_CPU));
/* set our heartbeating to other partitions into motion */
xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 82fb9958f22f..2e975762c32b 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -1106,8 +1106,6 @@ xpc_process_activate_IRQ_rcvd_sn2(void)
int n_IRQs_expected;
int n_IRQs_detected;
- DBUG_ON(xpc_activate_IRQ_rcvd == 0);
-
spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
n_IRQs_expected = xpc_activate_IRQ_rcvd;
xpc_activate_IRQ_rcvd = 0;
@@ -1726,6 +1724,7 @@ xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch)
msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
(get % ch->local_nentries) *
ch->entry_size);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
msg->flags = 0;
} while (++get < ch_sn2->remote_GP.get);
}
@@ -1740,11 +1739,18 @@ xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
struct xpc_msg_sn2 *msg;
s64 put;
- put = ch_sn2->w_remote_GP.put;
+ /* flags are zeroed when the buffer is allocated */
+ if (ch_sn2->remote_GP.put < ch->remote_nentries)
+ return;
+
+ put = max(ch_sn2->w_remote_GP.put, ch->remote_nentries);
do {
msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
(put % ch->remote_nentries) *
ch->entry_size);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
+ DBUG_ON(!(msg->flags & XPC_M_SN2_DONE));
+ DBUG_ON(msg->number != put - ch->remote_nentries);
msg->flags = 0;
} while (++put < ch_sn2->remote_GP.put);
}
@@ -1836,6 +1842,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
*/
xpc_clear_remote_msgqueue_flags_sn2(ch);
+ smp_wmb(); /* ensure flags have been cleared before bte_copy */
ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put;
dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
@@ -1934,7 +1941,7 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
break;
get = ch_sn2->w_local_GP.get;
- rmb(); /* guarantee that .get loads before .put */
+ smp_rmb(); /* guarantee that .get loads before .put */
if (get == ch_sn2->w_remote_GP.put)
break;
@@ -1956,11 +1963,13 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
msg = xpc_pull_remote_msg_sn2(ch, get);
- DBUG_ON(msg != NULL && msg->number != get);
- DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE));
- DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY));
+ if (msg != NULL) {
+ DBUG_ON(msg->number != get);
+ DBUG_ON(msg->flags & XPC_M_SN2_DONE);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
- payload = &msg->payload;
+ payload = &msg->payload;
+ }
break;
}
@@ -2053,7 +2062,7 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
while (1) {
put = ch_sn2->w_local_GP.put;
- rmb(); /* guarantee that .put loads before .get */
+ smp_rmb(); /* guarantee that .put loads before .get */
if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) {
/* There are available message entries. We need to try
@@ -2186,7 +2195,7 @@ xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload,
* The preceding store of msg->flags must occur before the following
* load of local_GP->put.
*/
- mb();
+ smp_mb();
/* see if the message is next in line to be sent, if so send it */
@@ -2277,8 +2286,9 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n",
(void *)msg, msg_number, ch->partid, ch->number);
- DBUG_ON((((u64)msg - (u64)ch->remote_msgqueue) / ch->entry_size) !=
+ DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) !=
msg_number % ch->remote_nentries);
+ DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
DBUG_ON(msg->flags & XPC_M_SN2_DONE);
msg->flags |= XPC_M_SN2_DONE;
@@ -2287,7 +2297,7 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
* The preceding store of msg->flags must occur before the following
* load of local_GP->get.
*/
- mb();
+ smp_mb();
/*
* See if this message is next in line to be acknowledged as having
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 91a55b1b1037..29c0502a96b2 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
@@ -1010,8 +1010,8 @@ xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch)
continue;
for (entry = 0; entry < nentries; entry++) {
- msg_slot = ch_uv->recv_msg_slots + entry *
- ch->entry_size;
+ msg_slot = ch_uv->recv_msg_slots +
+ entry * ch->entry_size;
msg_slot->hdr.msg_slot_number = entry;
}
@@ -1308,9 +1308,8 @@ xpc_handle_notify_mq_msg_uv(struct xpc_partition *part,
/* we're dealing with a normal message sent via the notify_mq */
ch_uv = &ch->sn.uv;
- msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots +
- (msg->hdr.msg_slot_number % ch->remote_nentries) *
- ch->entry_size);
+ msg_slot = ch_uv->recv_msg_slots +
+ (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number);
BUG_ON(msg_slot->hdr.size != 0);
@@ -1423,7 +1422,7 @@ xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload,
atomic_inc(&ch->n_to_notify);
msg_slot->key = key;
- wmb(); /* a non-NULL func must hit memory after the key */
+ smp_wmb(); /* a non-NULL func must hit memory after the key */
msg_slot->func = func;
if (ch->flags & XPC_C_DISCONNECTING) {
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 7957f525b2f4..6faefcffcb53 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1999-2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999-2009 Silicon Graphics, Inc. All rights reserved.
*/
/*
@@ -551,6 +551,7 @@ xpnet_init(void)
netif_carrier_off(xpnet_device);
+ xpnet_device->netdev_ops = &xpnet_netdev_ops;
xpnet_device->mtu = XPNET_DEF_MTU;
/*
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 45b1f430685f..513eb09a638f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -584,7 +584,7 @@ static int mmc_blk_probe(struct mmc_card *card)
if (err)
goto out;
- string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2,
+ string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2,
cap_str, sizeof(cap_str));
printk(KERN_INFO "%s: %s %s %s %s\n",
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index b92b172074ee..b9f1e84897cc 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -494,7 +494,7 @@ static int mmc_test_basic_read(struct mmc_test_card *test)
sg_init_one(&sg, test->buffer, 512);
- ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
+ ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0);
if (ret)
return ret;
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index dfa585f7feaf..99d4b28d52ed 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -76,6 +76,16 @@ config MMC_OMAP
If unsure, say N.
+config MMC_OMAP_HS
+ tristate "TI OMAP High Speed Multimedia Card Interface support"
+ depends on ARCH_OMAP2430 || ARCH_OMAP3
+ help
+ This selects the TI OMAP High Speed Multimedia card Interface.
+ If you have an OMAP2430 or OMAP3 board with a Multimedia Card slot,
+ say Y or M here.
+
+ If unsure, say N.
+
config MMC_WBSD
tristate "Winbond W83L51xD SD/MMC Card Interface support"
depends on ISA_DMA_API
@@ -135,6 +145,16 @@ config MMC_IMX
If unsure, say N.
+config MMC_MXC
+ tristate "Freescale i.MX2/3 Multimedia Card Interface support"
+ depends on ARCH_MXC
+ help
+ This selects the Freescale i.MX2/3 Multimedia card Interface.
+ If you have a i.MX platform with a Multimedia Card slot,
+ say Y or M here.
+
+ If unsure, say N.
+
config MMC_TIFM_SD
tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)"
depends on EXPERIMENTAL && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index f4853288bbb1..dedec55861d9 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -9,12 +9,14 @@ endif
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
obj-$(CONFIG_MMC_PXA) += pxamci.o
obj-$(CONFIG_MMC_IMX) += imxmmc.o
+obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_OMAP) += omap.o
+obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_AT91) += at91_mci.o
obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 76bfe16c09b1..e94e92001e7c 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1548,9 +1548,10 @@ static bool filter(struct dma_chan *chan, void *slave)
{
struct dw_dma_slave *dws = slave;
- if (dws->dma_dev == chan->device->dev)
+ if (dws->dma_dev == chan->device->dev) {
+ chan->private = dws;
return true;
- else
+ } else
return false;
}
#endif
@@ -1602,7 +1603,7 @@ static int __init atmci_probe(struct platform_device *pdev)
tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host);
- ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, host);
+ ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host);
if (ret)
goto err_request_irq;
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 1bcbdd6763ac..2909bbc8ad00 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -430,6 +430,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
clk = 255;
host->cclk = host->mclk / (2 * (clk + 1));
}
+ if (host->hw_designer == 0x80)
+ clk |= MCI_FCEN; /* Bug fix in ST IP block */
clk |= MCI_CLK_ENABLE;
}
@@ -440,15 +442,27 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_OFF:
break;
case MMC_POWER_UP:
- pwr |= MCI_PWR_UP;
- break;
+ /* The ST version does not have this, fall through to POWER_ON */
+ if (host->hw_designer != 0x80) {
+ pwr |= MCI_PWR_UP;
+ break;
+ }
case MMC_POWER_ON:
pwr |= MCI_PWR_ON;
break;
}
- if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
- pwr |= MCI_ROD;
+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+ if (host->hw_designer != 0x80)
+ pwr |= MCI_ROD;
+ else {
+ /*
+ * The ST Micro variant use the ROD bit for something
+ * else and only has OD (Open Drain).
+ */
+ pwr |= MCI_OD;
+ }
+ }
writel(clk, host->base + MMCICLOCK);
@@ -500,6 +514,12 @@ static int mmci_probe(struct amba_device *dev, void *id)
}
host = mmc_priv(mmc);
+ /* Bits 12 thru 19 is the designer */
+ host->hw_designer = (dev->periphid >> 12) & 0xff;
+ /* Bits 20 thru 23 is the revison */
+ host->hw_revision = (dev->periphid >> 20) & 0xf;
+ DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
+ DBG(host, "revision = 0x%01x\n", host->hw_revision);
host->clk = clk_get(&dev->dev, NULL);
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
@@ -693,6 +713,15 @@ static struct amba_id mmci_ids[] = {
.id = 0x00041181,
.mask = 0x000fffff,
},
+ /* ST Micro variants */
+ {
+ .id = 0x00180180,
+ .mask = 0x00ffffff,
+ },
+ {
+ .id = 0x00280180,
+ .mask = 0x00ffffff,
+ },
{ 0, 0 },
};
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 0f39c490f022..0441bac1c0ec 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -11,13 +11,23 @@
#define MCI_PWR_OFF 0x00
#define MCI_PWR_UP 0x02
#define MCI_PWR_ON 0x03
+#define MCI_DATA2DIREN (1 << 2)
+#define MCI_CMDDIREN (1 << 3)
+#define MCI_DATA0DIREN (1 << 4)
+#define MCI_DATA31DIREN (1 << 5)
#define MCI_OD (1 << 6)
#define MCI_ROD (1 << 7)
+/* The ST Micro version does not have ROD */
+#define MCI_FBCLKEN (1 << 7)
+#define MCI_DATA74DIREN (1 << 8)
#define MMCICLOCK 0x004
#define MCI_CLK_ENABLE (1 << 8)
#define MCI_CLK_PWRSAVE (1 << 9)
#define MCI_CLK_BYPASS (1 << 10)
+#define MCI_WIDE_BUS (1 << 11)
+/* HW flow control on the ST Micro version */
+#define MCI_FCEN (1 << 13)
#define MMCIARGUMENT 0x008
#define MMCICOMMAND 0x00c
@@ -26,6 +36,10 @@
#define MCI_CPSM_INTERRUPT (1 << 8)
#define MCI_CPSM_PENDING (1 << 9)
#define MCI_CPSM_ENABLE (1 << 10)
+#define MCI_SDIO_SUSP (1 << 11)
+#define MCI_ENCMD_COMPL (1 << 12)
+#define MCI_NIEN (1 << 13)
+#define MCI_CE_ATACMD (1 << 14)
#define MMCIRESPCMD 0x010
#define MMCIRESPONSE0 0x014
@@ -39,6 +53,11 @@
#define MCI_DPSM_DIRECTION (1 << 1)
#define MCI_DPSM_MODE (1 << 2)
#define MCI_DPSM_DMAENABLE (1 << 3)
+#define MCI_DPSM_BLOCKSIZE (1 << 4)
+#define MCI_DPSM_RWSTART (1 << 8)
+#define MCI_DPSM_RWSTOP (1 << 9)
+#define MCI_DPSM_RWMOD (1 << 10)
+#define MCI_DPSM_SDIOEN (1 << 11)
#define MMCIDATACNT 0x030
#define MMCISTATUS 0x034
@@ -63,6 +82,8 @@
#define MCI_RXFIFOEMPTY (1 << 19)
#define MCI_TXDATAAVLBL (1 << 20)
#define MCI_RXDATAAVLBL (1 << 21)
+#define MCI_SDIOIT (1 << 22)
+#define MCI_CEATAEND (1 << 23)
#define MMCICLEAR 0x038
#define MCI_CMDCRCFAILCLR (1 << 0)
@@ -75,6 +96,8 @@
#define MCI_CMDSENTCLR (1 << 7)
#define MCI_DATAENDCLR (1 << 8)
#define MCI_DATABLOCKENDCLR (1 << 10)
+#define MCI_SDIOITC (1 << 22)
+#define MCI_CEATAENDC (1 << 23)
#define MMCIMASK0 0x03c
#define MCI_CMDCRCFAILMASK (1 << 0)
@@ -98,6 +121,8 @@
#define MCI_RXFIFOEMPTYMASK (1 << 19)
#define MCI_TXDATAAVLBLMASK (1 << 20)
#define MCI_RXDATAAVLBLMASK (1 << 21)
+#define MCI_SDIOITMASK (1 << 22)
+#define MCI_CEATAENDMASK (1 << 23)
#define MMCIMASK1 0x040
#define MMCIFIFOCNT 0x048
@@ -136,6 +161,9 @@ struct mmci_host {
u32 pwr;
struct mmc_platform_data *plat;
+ u8 hw_designer;
+ u8 hw_revision:4;
+
struct timer_list timer;
unsigned int oldstat;
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
new file mode 100644
index 000000000000..dda0be4e25dc
--- /dev/null
+++ b/drivers/mmc/host/mxcmmc.c
@@ -0,0 +1,880 @@
+/*
+ * linux/drivers/mmc/host/mxcmmc.c - Freescale i.MX MMCI driver
+ *
+ * This is a driver for the SDHC controller found in Freescale MX2/MX3
+ * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
+ * Unlike the hardware found on MX1, this hardware just works and does
+ * not need all the quirks found in imxmmc.c, hence the seperate driver.
+ *
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
+ *
+ * derived from pxamci.c by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/blkdev.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <mach/mmc.h>
+
+#ifdef CONFIG_ARCH_MX2
+#include <mach/dma-mx1-mx2.h>
+#define HAS_DMA
+#endif
+
+#define DRIVER_NAME "imx-mmc"
+
+#define MMC_REG_STR_STP_CLK 0x00
+#define MMC_REG_STATUS 0x04
+#define MMC_REG_CLK_RATE 0x08
+#define MMC_REG_CMD_DAT_CONT 0x0C
+#define MMC_REG_RES_TO 0x10
+#define MMC_REG_READ_TO 0x14
+#define MMC_REG_BLK_LEN 0x18
+#define MMC_REG_NOB 0x1C
+#define MMC_REG_REV_NO 0x20
+#define MMC_REG_INT_CNTR 0x24
+#define MMC_REG_CMD 0x28
+#define MMC_REG_ARG 0x2C
+#define MMC_REG_RES_FIFO 0x34
+#define MMC_REG_BUFFER_ACCESS 0x38
+
+#define STR_STP_CLK_RESET (1 << 3)
+#define STR_STP_CLK_START_CLK (1 << 1)
+#define STR_STP_CLK_STOP_CLK (1 << 0)
+
+#define STATUS_CARD_INSERTION (1 << 31)
+#define STATUS_CARD_REMOVAL (1 << 30)
+#define STATUS_YBUF_EMPTY (1 << 29)
+#define STATUS_XBUF_EMPTY (1 << 28)
+#define STATUS_YBUF_FULL (1 << 27)
+#define STATUS_XBUF_FULL (1 << 26)
+#define STATUS_BUF_UND_RUN (1 << 25)
+#define STATUS_BUF_OVFL (1 << 24)
+#define STATUS_SDIO_INT_ACTIVE (1 << 14)
+#define STATUS_END_CMD_RESP (1 << 13)
+#define STATUS_WRITE_OP_DONE (1 << 12)
+#define STATUS_DATA_TRANS_DONE (1 << 11)
+#define STATUS_READ_OP_DONE (1 << 11)
+#define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10)
+#define STATUS_CARD_BUS_CLK_RUN (1 << 8)
+#define STATUS_BUF_READ_RDY (1 << 7)
+#define STATUS_BUF_WRITE_RDY (1 << 6)
+#define STATUS_RESP_CRC_ERR (1 << 5)
+#define STATUS_CRC_READ_ERR (1 << 3)
+#define STATUS_CRC_WRITE_ERR (1 << 2)
+#define STATUS_TIME_OUT_RESP (1 << 1)
+#define STATUS_TIME_OUT_READ (1 << 0)
+#define STATUS_ERR_MASK 0x2f
+
+#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12)
+#define CMD_DAT_CONT_STOP_READWAIT (1 << 11)
+#define CMD_DAT_CONT_START_READWAIT (1 << 10)
+#define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8)
+#define CMD_DAT_CONT_INIT (1 << 7)
+#define CMD_DAT_CONT_WRITE (1 << 4)
+#define CMD_DAT_CONT_DATA_ENABLE (1 << 3)
+#define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0)
+#define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0)
+#define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0)
+
+#define INT_SDIO_INT_WKP_EN (1 << 18)
+#define INT_CARD_INSERTION_WKP_EN (1 << 17)
+#define INT_CARD_REMOVAL_WKP_EN (1 << 16)
+#define INT_CARD_INSERTION_EN (1 << 15)
+#define INT_CARD_REMOVAL_EN (1 << 14)
+#define INT_SDIO_IRQ_EN (1 << 13)
+#define INT_DAT0_EN (1 << 12)
+#define INT_BUF_READ_EN (1 << 4)
+#define INT_BUF_WRITE_EN (1 << 3)
+#define INT_END_CMD_RES_EN (1 << 2)
+#define INT_WRITE_OP_DONE_EN (1 << 1)
+#define INT_READ_OP_EN (1 << 0)
+
+struct mxcmci_host {
+ struct mmc_host *mmc;
+ struct resource *res;
+ void __iomem *base;
+ int irq;
+ int detect_irq;
+ int dma;
+ int do_dma;
+ unsigned int power_mode;
+ struct imxmmc_platform_data *pdata;
+
+ struct mmc_request *req;
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+
+ unsigned int dma_nents;
+ unsigned int datasize;
+ unsigned int dma_dir;
+
+ u16 rev_no;
+ unsigned int cmdat;
+
+ struct clk *clk;
+
+ int clock;
+
+ struct work_struct datawork;
+};
+
+static inline int mxcmci_use_dma(struct mxcmci_host *host)
+{
+ return host->do_dma;
+}
+
+static void mxcmci_softreset(struct mxcmci_host *host)
+{
+ int i;
+
+ /* reset sequence */
+ writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
+ writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
+ host->base + MMC_REG_STR_STP_CLK);
+
+ for (i = 0; i < 8; i++)
+ writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+
+ writew(0xff, host->base + MMC_REG_RES_TO);
+}
+
+static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
+{
+ unsigned int nob = data->blocks;
+ unsigned int blksz = data->blksz;
+ unsigned int datasize = nob * blksz;
+#ifdef HAS_DMA
+ struct scatterlist *sg;
+ int i;
+#endif
+ if (data->flags & MMC_DATA_STREAM)
+ nob = 0xffff;
+
+ host->data = data;
+ data->bytes_xfered = 0;
+
+ writew(nob, host->base + MMC_REG_NOB);
+ writew(blksz, host->base + MMC_REG_BLK_LEN);
+ host->datasize = datasize;
+
+#ifdef HAS_DMA
+ for_each_sg(data->sg, sg, data->sg_len, i) {
+ if (sg->offset & 3 || sg->length & 3) {
+ host->do_dma = 0;
+ return;
+ }
+ }
+
+ if (data->flags & MMC_DATA_READ) {
+ host->dma_dir = DMA_FROM_DEVICE;
+ host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma_dir);
+
+ imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
+ host->res->start + MMC_REG_BUFFER_ACCESS,
+ DMA_MODE_READ);
+ } else {
+ host->dma_dir = DMA_TO_DEVICE;
+ host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma_dir);
+
+ imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize,
+ host->res->start + MMC_REG_BUFFER_ACCESS,
+ DMA_MODE_WRITE);
+ }
+
+ wmb();
+
+ imx_dma_enable(host->dma);
+#endif /* HAS_DMA */
+}
+
+static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
+ unsigned int cmdat)
+{
+ WARN_ON(host->cmd != NULL);
+ host->cmd = cmd;
+
+ switch (mmc_resp_type(cmd)) {
+ case MMC_RSP_R1: /* short CRC, OPCODE */
+ case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
+ cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
+ break;
+ case MMC_RSP_R2: /* long 136 bit + CRC */
+ cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
+ break;
+ case MMC_RSP_R3: /* short */
+ cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
+ break;
+ case MMC_RSP_NONE:
+ break;
+ default:
+ dev_err(mmc_dev(host->mmc), "unhandled response type 0x%x\n",
+ mmc_resp_type(cmd));
+ cmd->error = -EINVAL;
+ return -EINVAL;
+ }
+
+ if (mxcmci_use_dma(host))
+ writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN |
+ INT_END_CMD_RES_EN,
+ host->base + MMC_REG_INT_CNTR);
+ else
+ writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR);
+
+ writew(cmd->opcode, host->base + MMC_REG_CMD);
+ writel(cmd->arg, host->base + MMC_REG_ARG);
+ writew(cmdat, host->base + MMC_REG_CMD_DAT_CONT);
+
+ return 0;
+}
+
+static void mxcmci_finish_request(struct mxcmci_host *host,
+ struct mmc_request *req)
+{
+ writel(0, host->base + MMC_REG_INT_CNTR);
+
+ host->req = NULL;
+ host->cmd = NULL;
+ host->data = NULL;
+
+ mmc_request_done(host->mmc, req);
+}
+
+static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
+{
+ struct mmc_data *data = host->data;
+ int data_error;
+
+#ifdef HAS_DMA
+ if (mxcmci_use_dma(host)) {
+ imx_dma_disable(host->dma);
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents,
+ host->dma_dir);
+ }
+#endif
+
+ if (stat & STATUS_ERR_MASK) {
+ dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
+ stat);
+ if (stat & STATUS_CRC_READ_ERR) {
+ data->error = -EILSEQ;
+ } else if (stat & STATUS_CRC_WRITE_ERR) {
+ u32 err_code = (stat >> 9) & 0x3;
+ if (err_code == 2) /* No CRC response */
+ data->error = -ETIMEDOUT;
+ else
+ data->error = -EILSEQ;
+ } else if (stat & STATUS_TIME_OUT_READ) {
+ data->error = -ETIMEDOUT;
+ } else {
+ data->error = -EIO;
+ }
+ } else {
+ data->bytes_xfered = host->datasize;
+ }
+
+ data_error = data->error;
+
+ host->data = NULL;
+
+ return data_error;
+}
+
+static void mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
+{
+ struct mmc_command *cmd = host->cmd;
+ int i;
+ u32 a, b, c;
+
+ if (!cmd)
+ return;
+
+ if (stat & STATUS_TIME_OUT_RESP) {
+ dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
+ cmd->error = -ETIMEDOUT;
+ } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
+ dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
+ cmd->error = -EILSEQ;
+ }
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ if (cmd->flags & MMC_RSP_136) {
+ for (i = 0; i < 4; i++) {
+ a = readw(host->base + MMC_REG_RES_FIFO);
+ b = readw(host->base + MMC_REG_RES_FIFO);
+ cmd->resp[i] = a << 16 | b;
+ }
+ } else {
+ a = readw(host->base + MMC_REG_RES_FIFO);
+ b = readw(host->base + MMC_REG_RES_FIFO);
+ c = readw(host->base + MMC_REG_RES_FIFO);
+ cmd->resp[0] = a << 24 | b << 8 | c >> 8;
+ }
+ }
+}
+
+static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
+{
+ u32 stat;
+ unsigned long timeout = jiffies + HZ;
+
+ do {
+ stat = readl(host->base + MMC_REG_STATUS);
+ if (stat & STATUS_ERR_MASK)
+ return stat;
+ if (time_after(jiffies, timeout))
+ return STATUS_TIME_OUT_READ;
+ if (stat & mask)
+ return 0;
+ cpu_relax();
+ } while (1);
+}
+
+static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
+{
+ unsigned int stat;
+ u32 *buf = _buf;
+
+ while (bytes > 3) {
+ stat = mxcmci_poll_status(host,
+ STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+ if (stat)
+ return stat;
+ *buf++ = readl(host->base + MMC_REG_BUFFER_ACCESS);
+ bytes -= 4;
+ }
+
+ if (bytes) {
+ u8 *b = (u8 *)buf;
+ u32 tmp;
+
+ stat = mxcmci_poll_status(host,
+ STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
+ if (stat)
+ return stat;
+ tmp = readl(host->base + MMC_REG_BUFFER_ACCESS);
+ memcpy(b, &tmp, bytes);
+ }
+
+ return 0;
+}
+
+static int mxcmci_push(struct mxcmci_host *host, void *_buf, int bytes)
+{
+ unsigned int stat;
+ u32 *buf = _buf;
+
+ while (bytes > 3) {
+ stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+ if (stat)
+ return stat;
+ writel(*buf++, host->base + MMC_REG_BUFFER_ACCESS);
+ bytes -= 4;
+ }
+
+ if (bytes) {
+ u8 *b = (u8 *)buf;
+ u32 tmp;
+
+ stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+ if (stat)
+ return stat;
+
+ memcpy(&tmp, b, bytes);
+ writel(tmp, host->base + MMC_REG_BUFFER_ACCESS);
+ }
+
+ stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
+ if (stat)
+ return stat;
+
+ return 0;
+}
+
+static int mxcmci_transfer_data(struct mxcmci_host *host)
+{
+ struct mmc_data *data = host->req->data;
+ struct scatterlist *sg;
+ int stat, i;
+
+ host->datasize = 0;
+
+ host->data = data;
+ host->datasize = 0;
+
+ if (data->flags & MMC_DATA_READ) {
+ for_each_sg(data->sg, sg, data->sg_len, i) {
+ stat = mxcmci_pull(host, sg_virt(sg), sg->length);
+ if (stat)
+ return stat;
+ host->datasize += sg->length;
+ }
+ } else {
+ for_each_sg(data->sg, sg, data->sg_len, i) {
+ stat = mxcmci_push(host, sg_virt(sg), sg->length);
+ if (stat)
+ return stat;
+ host->datasize += sg->length;
+ }
+ stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
+ if (stat)
+ return stat;
+ }
+ return 0;
+}
+
+static void mxcmci_datawork(struct work_struct *work)
+{
+ struct mxcmci_host *host = container_of(work, struct mxcmci_host,
+ datawork);
+ int datastat = mxcmci_transfer_data(host);
+ mxcmci_finish_data(host, datastat);
+
+ if (host->req->stop) {
+ if (mxcmci_start_cmd(host, host->req->stop, 0)) {
+ mxcmci_finish_request(host, host->req);
+ return;
+ }
+ } else {
+ mxcmci_finish_request(host, host->req);
+ }
+}
+
+#ifdef HAS_DMA
+static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
+{
+ struct mmc_data *data = host->data;
+ int data_error;
+
+ if (!data)
+ return;
+
+ data_error = mxcmci_finish_data(host, stat);
+
+ mxcmci_read_response(host, stat);
+ host->cmd = NULL;
+
+ if (host->req->stop) {
+ if (mxcmci_start_cmd(host, host->req->stop, 0)) {
+ mxcmci_finish_request(host, host->req);
+ return;
+ }
+ } else {
+ mxcmci_finish_request(host, host->req);
+ }
+}
+#endif /* HAS_DMA */
+
+static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
+{
+ mxcmci_read_response(host, stat);
+ host->cmd = NULL;
+
+ if (!host->data && host->req) {
+ mxcmci_finish_request(host, host->req);
+ return;
+ }
+
+ /* For the DMA case the DMA engine handles the data transfer
+ * automatically. For non DMA we have to to it ourselves.
+ * Don't do it in interrupt context though.
+ */
+ if (!mxcmci_use_dma(host) && host->data)
+ schedule_work(&host->datawork);
+
+}
+
+static irqreturn_t mxcmci_irq(int irq, void *devid)
+{
+ struct mxcmci_host *host = devid;
+ u32 stat;
+
+ stat = readl(host->base + MMC_REG_STATUS);
+ writel(stat, host->base + MMC_REG_STATUS);
+
+ dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
+
+ if (stat & STATUS_END_CMD_RESP)
+ mxcmci_cmd_done(host, stat);
+#ifdef HAS_DMA
+ if (mxcmci_use_dma(host) &&
+ (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
+ mxcmci_data_done(host, stat);
+#endif
+ return IRQ_HANDLED;
+}
+
+static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+ struct mxcmci_host *host = mmc_priv(mmc);
+ unsigned int cmdat = host->cmdat;
+
+ WARN_ON(host->req != NULL);
+
+ host->req = req;
+ host->cmdat &= ~CMD_DAT_CONT_INIT;
+#ifdef HAS_DMA
+ host->do_dma = 1;
+#endif
+ if (req->data) {
+ mxcmci_setup_data(host, req->data);
+
+ cmdat |= CMD_DAT_CONT_DATA_ENABLE;
+
+ if (req->data->flags & MMC_DATA_WRITE)
+ cmdat |= CMD_DAT_CONT_WRITE;
+ }
+
+ if (mxcmci_start_cmd(host, req->cmd, cmdat))
+ mxcmci_finish_request(host, req);
+}
+
+static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
+{
+ unsigned int divider;
+ int prescaler = 0;
+ unsigned int clk_in = clk_get_rate(host->clk);
+
+ while (prescaler <= 0x800) {
+ for (divider = 1; divider <= 0xF; divider++) {
+ int x;
+
+ x = (clk_in / (divider + 1));
+
+ if (prescaler)
+ x /= (prescaler * 2);
+
+ if (x <= clk_ios)
+ break;
+ }
+ if (divider < 0x10)
+ break;
+
+ if (prescaler == 0)
+ prescaler = 1;
+ else
+ prescaler <<= 1;
+ }
+
+ writew((prescaler << 4) | divider, host->base + MMC_REG_CLK_RATE);
+
+ dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n",
+ prescaler, divider, clk_in, clk_ios);
+}
+
+static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct mxcmci_host *host = mmc_priv(mmc);
+#ifdef HAS_DMA
+ unsigned int blen;
+ /*
+ * use burstlen of 64 in 4 bit mode (--> reg value 0)
+ * use burstlen of 16 in 1 bit mode (--> reg value 16)
+ */
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ blen = 0;
+ else
+ blen = 16;
+
+ imx_dma_config_burstlen(host->dma, blen);
+#endif
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
+ else
+ host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
+
+ if (host->power_mode != ios->power_mode) {
+ if (host->pdata && host->pdata->setpower)
+ host->pdata->setpower(mmc_dev(mmc), ios->vdd);
+ host->power_mode = ios->power_mode;
+ if (ios->power_mode == MMC_POWER_ON)
+ host->cmdat |= CMD_DAT_CONT_INIT;
+ }
+
+ if (ios->clock) {
+ mxcmci_set_clk_rate(host, ios->clock);
+ writew(STR_STP_CLK_START_CLK, host->base + MMC_REG_STR_STP_CLK);
+ } else {
+ writew(STR_STP_CLK_STOP_CLK, host->base + MMC_REG_STR_STP_CLK);
+ }
+
+ host->clock = ios->clock;
+}
+
+static irqreturn_t mxcmci_detect_irq(int irq, void *data)
+{
+ struct mmc_host *mmc = data;
+
+ dev_dbg(mmc_dev(mmc), "%s\n", __func__);
+
+ mmc_detect_change(mmc, msecs_to_jiffies(250));
+ return IRQ_HANDLED;
+}
+
+static int mxcmci_get_ro(struct mmc_host *mmc)
+{
+ struct mxcmci_host *host = mmc_priv(mmc);
+
+ if (host->pdata && host->pdata->get_ro)
+ return !!host->pdata->get_ro(mmc_dev(mmc));
+ /*
+ * Board doesn't support read only detection; let the mmc core
+ * decide what to do.
+ */
+ return -ENOSYS;
+}
+
+
+static const struct mmc_host_ops mxcmci_ops = {
+ .request = mxcmci_request,
+ .set_ios = mxcmci_set_ios,
+ .get_ro = mxcmci_get_ro,
+};
+
+static int mxcmci_probe(struct platform_device *pdev)
+{
+ struct mmc_host *mmc;
+ struct mxcmci_host *host = NULL;
+ struct resource *r;
+ int ret = 0, irq;
+
+ printk(KERN_INFO "i.MX SDHC driver\n");
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!r || irq < 0)
+ return -EINVAL;
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (!r)
+ return -EBUSY;
+
+ mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto out_release_mem;
+ }
+
+ mmc->ops = &mxcmci_ops;
+ mmc->caps = MMC_CAP_4_BIT_DATA;
+
+ /* MMC core transfer sizes tunable parameters */
+ mmc->max_hw_segs = 64;
+ mmc->max_phys_segs = 64;
+ mmc->max_blk_size = 2048;
+ mmc->max_blk_count = 65535;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_seg_size;
+
+ host = mmc_priv(mmc);
+ host->base = ioremap(r->start, resource_size(r));
+ if (!host->base) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
+ host->mmc = mmc;
+ host->pdata = pdev->dev.platform_data;
+
+ if (host->pdata && host->pdata->ocr_avail)
+ mmc->ocr_avail = host->pdata->ocr_avail;
+ else
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ host->res = r;
+ host->irq = irq;
+
+ host->clk = clk_get(&pdev->dev, "sdhc_clk");
+ if (IS_ERR(host->clk)) {
+ ret = PTR_ERR(host->clk);
+ goto out_iounmap;
+ }
+ clk_enable(host->clk);
+
+ mxcmci_softreset(host);
+
+ host->rev_no = readw(host->base + MMC_REG_REV_NO);
+ if (host->rev_no != 0x400) {
+ ret = -ENODEV;
+ dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
+ host->rev_no);
+ goto out_clk_put;
+ }
+
+ mmc->f_min = clk_get_rate(host->clk) >> 7;
+ mmc->f_max = clk_get_rate(host->clk) >> 1;
+
+ /* recommended in data sheet */
+ writew(0x2db4, host->base + MMC_REG_READ_TO);
+
+ writel(0, host->base + MMC_REG_INT_CNTR);
+
+#ifdef HAS_DMA
+ host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
+ if (host->dma < 0) {
+ dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n");
+ ret = -EBUSY;
+ goto out_clk_put;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (!r) {
+ ret = -EINVAL;
+ goto out_free_dma;
+ }
+
+ ret = imx_dma_config_channel(host->dma,
+ IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO,
+ IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
+ r->start, 0);
+ if (ret) {
+ dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n");
+ goto out_free_dma;
+ }
+#endif
+ INIT_WORK(&host->datawork, mxcmci_datawork);
+
+ ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host);
+ if (ret)
+ goto out_free_dma;
+
+ platform_set_drvdata(pdev, mmc);
+
+ if (host->pdata && host->pdata->init) {
+ ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,
+ host->mmc);
+ if (ret)
+ goto out_free_irq;
+ }
+
+ mmc_add_host(mmc);
+
+ return 0;
+
+out_free_irq:
+ free_irq(host->irq, host);
+out_free_dma:
+#ifdef HAS_DMA
+ imx_dma_free(host->dma);
+#endif
+out_clk_put:
+ clk_disable(host->clk);
+ clk_put(host->clk);
+out_iounmap:
+ iounmap(host->base);
+out_free:
+ mmc_free_host(mmc);
+out_release_mem:
+ release_mem_region(host->res->start, resource_size(host->res));
+ return ret;
+}
+
+static int mxcmci_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct mxcmci_host *host = mmc_priv(mmc);
+
+ platform_set_drvdata(pdev, NULL);
+
+ mmc_remove_host(mmc);
+
+ if (host->pdata && host->pdata->exit)
+ host->pdata->exit(&pdev->dev, mmc);
+
+ free_irq(host->irq, host);
+ iounmap(host->base);
+#ifdef HAS_DMA
+ imx_dma_free(host->dma);
+#endif
+ clk_disable(host->clk);
+ clk_put(host->clk);
+
+ release_mem_region(host->res->start, resource_size(host->res));
+ release_resource(host->res);
+
+ mmc_free_host(mmc);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxcmci_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc)
+ ret = mmc_suspend_host(mmc, state);
+
+ return ret;
+}
+
+static int mxcmci_resume(struct platform_device *dev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct mxcmci_host *host;
+ int ret = 0;
+
+ if (mmc) {
+ host = mmc_priv(mmc);
+ ret = mmc_resume_host(mmc);
+ }
+
+ return ret;
+}
+#else
+#define mxcmci_suspend NULL
+#define mxcmci_resume NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver mxcmci_driver = {
+ .probe = mxcmci_probe,
+ .remove = mxcmci_remove,
+ .suspend = mxcmci_suspend,
+ .resume = mxcmci_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ }
+};
+
+static int __init mxcmci_init(void)
+{
+ return platform_driver_register(&mxcmci_driver);
+}
+
+static void __exit mxcmci_exit(void)
+{
+ platform_driver_unregister(&mxcmci_driver);
+}
+
+module_init(mxcmci_init);
+module_exit(mxcmci_exit);
+
+MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-mmc");
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index fb2921f8099d..0c44d560bf1a 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -103,7 +103,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
if (!gpio_is_valid(oms->gpios[i]))
continue;
- ret = gpio_request(oms->gpios[i], dev->bus_id);
+ ret = gpio_request(oms->gpios[i], dev_name(dev));
if (ret < 0) {
oms->gpios[i] = -EINVAL;
continue;
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
new file mode 100644
index 000000000000..a631c81dce12
--- /dev/null
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -0,0 +1,1280 @@
+/*
+ * drivers/mmc/host/omap_hsmmc.c
+ *
+ * Driver for OMAP2430/3430 MMC controller.
+ *
+ * Copyright (C) 2007 Texas Instruments.
+ *
+ * Authors:
+ * Syed Mohammed Khasim <x0khasim@ti.com>
+ * Madhusudhan <madhu.cr@ti.com>
+ * Mohit Jalori <mjalori@ti.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include <linux/semaphore.h>
+#include <mach/dma.h>
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/mmc.h>
+#include <mach/cpu.h>
+
+/* OMAP HSMMC Host Controller Registers */
+#define OMAP_HSMMC_SYSCONFIG 0x0010
+#define OMAP_HSMMC_CON 0x002C
+#define OMAP_HSMMC_BLK 0x0104
+#define OMAP_HSMMC_ARG 0x0108
+#define OMAP_HSMMC_CMD 0x010C
+#define OMAP_HSMMC_RSP10 0x0110
+#define OMAP_HSMMC_RSP32 0x0114
+#define OMAP_HSMMC_RSP54 0x0118
+#define OMAP_HSMMC_RSP76 0x011C
+#define OMAP_HSMMC_DATA 0x0120
+#define OMAP_HSMMC_HCTL 0x0128
+#define OMAP_HSMMC_SYSCTL 0x012C
+#define OMAP_HSMMC_STAT 0x0130
+#define OMAP_HSMMC_IE 0x0134
+#define OMAP_HSMMC_ISE 0x0138
+#define OMAP_HSMMC_CAPA 0x0140
+
+#define VS18 (1 << 26)
+#define VS30 (1 << 25)
+#define SDVS18 (0x5 << 9)
+#define SDVS30 (0x6 << 9)
+#define SDVS33 (0x7 << 9)
+#define SDVSCLR 0xFFFFF1FF
+#define SDVSDET 0x00000400
+#define AUTOIDLE 0x1
+#define SDBP (1 << 8)
+#define DTO 0xe
+#define ICE 0x1
+#define ICS 0x2
+#define CEN (1 << 2)
+#define CLKD_MASK 0x0000FFC0
+#define CLKD_SHIFT 6
+#define DTO_MASK 0x000F0000
+#define DTO_SHIFT 16
+#define INT_EN_MASK 0x307F0033
+#define INIT_STREAM (1 << 1)
+#define DP_SELECT (1 << 21)
+#define DDIR (1 << 4)
+#define DMA_EN 0x1
+#define MSBS (1 << 5)
+#define BCE (1 << 1)
+#define FOUR_BIT (1 << 1)
+#define CC 0x1
+#define TC 0x02
+#define OD 0x1
+#define ERR (1 << 15)
+#define CMD_TIMEOUT (1 << 16)
+#define DATA_TIMEOUT (1 << 20)
+#define CMD_CRC (1 << 17)
+#define DATA_CRC (1 << 21)
+#define CARD_ERR (1 << 28)
+#define STAT_CLEAR 0xFFFFFFFF
+#define INIT_STREAM_CMD 0x00000000
+#define DUAL_VOLT_OCR_BIT 7
+#define SRC (1 << 25)
+#define SRD (1 << 26)
+
+/*
+ * FIXME: Most likely all the data using these _DEVID defines should come
+ * from the platform_data, or implemented in controller and slot specific
+ * functions.
+ */
+#define OMAP_MMC1_DEVID 0
+#define OMAP_MMC2_DEVID 1
+
+#define OMAP_MMC_DATADIR_NONE 0
+#define OMAP_MMC_DATADIR_READ 1
+#define OMAP_MMC_DATADIR_WRITE 2
+#define MMC_TIMEOUT_MS 20
+#define OMAP_MMC_MASTER_CLOCK 96000000
+#define DRIVER_NAME "mmci-omap-hs"
+
+/*
+ * One controller can have multiple slots, like on some omap boards using
+ * omap.c controller driver. Luckily this is not currently done on any known
+ * omap_hsmmc.c device.
+ */
+#define mmc_slot(host) (host->pdata->slots[host->slot_id])
+
+/*
+ * MMC Host controller read/write API's
+ */
+#define OMAP_HSMMC_READ(base, reg) \
+ __raw_readl((base) + OMAP_HSMMC_##reg)
+
+#define OMAP_HSMMC_WRITE(base, reg, val) \
+ __raw_writel((val), (base) + OMAP_HSMMC_##reg)
+
+struct mmc_omap_host {
+ struct device *dev;
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+ struct clk *fclk;
+ struct clk *iclk;
+ struct clk *dbclk;
+ struct semaphore sem;
+ struct work_struct mmc_carddetect_work;
+ void __iomem *base;
+ resource_size_t mapbase;
+ unsigned int id;
+ unsigned int dma_len;
+ unsigned int dma_dir;
+ unsigned char bus_mode;
+ unsigned char datadir;
+ u32 *buffer;
+ u32 bytesleft;
+ int suspended;
+ int irq;
+ int carddetect;
+ int use_dma, dma_ch;
+ int initstr;
+ int slot_id;
+ int dbclk_enabled;
+ struct omap_mmc_platform_data *pdata;
+};
+
+/*
+ * Stop clock to the card
+ */
+static void omap_mmc_stop_clock(struct mmc_omap_host *host)
+{
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) & ~CEN);
+ if ((OMAP_HSMMC_READ(host->base, SYSCTL) & CEN) != 0x0)
+ dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n");
+}
+
+/*
+ * Send init stream sequence to card
+ * before sending IDLE command
+ */
+static void send_init_stream(struct mmc_omap_host *host)
+{
+ int reg = 0;
+ unsigned long timeout;
+
+ disable_irq(host->irq);
+ OMAP_HSMMC_WRITE(host->base, CON,
+ OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM);
+ OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD);
+
+ timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+ while ((reg != CC) && time_before(jiffies, timeout))
+ reg = OMAP_HSMMC_READ(host->base, STAT) & CC;
+
+ OMAP_HSMMC_WRITE(host->base, CON,
+ OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM);
+ enable_irq(host->irq);
+}
+
+static inline
+int mmc_omap_cover_is_closed(struct mmc_omap_host *host)
+{
+ int r = 1;
+
+ if (host->pdata->slots[host->slot_id].get_cover_state)
+ r = host->pdata->slots[host->slot_id].get_cover_state(host->dev,
+ host->slot_id);
+ return r;
+}
+
+static ssize_t
+mmc_omap_show_cover_switch(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
+ struct mmc_omap_host *host = mmc_priv(mmc);
+
+ return sprintf(buf, "%s\n", mmc_omap_cover_is_closed(host) ? "closed" :
+ "open");
+}
+
+static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);
+
+static ssize_t
+mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id];
+
+ return sprintf(buf, "slot:%s\n", slot.name);
+}
+
+static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
+
+/*
+ * Configure the response type and send the cmd.
+ */
+static void
+mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
+ struct mmc_data *data)
+{
+ int cmdreg = 0, resptype = 0, cmdtype = 0;
+
+ dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
+ mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
+ host->cmd = cmd;
+
+ /*
+ * Clear status bits and enable interrupts
+ */
+ OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ if (cmd->flags & MMC_RSP_136)
+ resptype = 1;
+ else
+ resptype = 2;
+ }
+
+ /*
+ * Unlike OMAP1 controller, the cmdtype does not seem to be based on
+ * ac, bc, adtc, bcr. Only commands ending an open ended transfer need
+ * a val of 0x3, rest 0x0.
+ */
+ if (cmd == host->mrq->stop)
+ cmdtype = 0x3;
+
+ cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22);
+
+ if (data) {
+ cmdreg |= DP_SELECT | MSBS | BCE;
+ if (data->flags & MMC_DATA_READ)
+ cmdreg |= DDIR;
+ else
+ cmdreg &= ~(DDIR);
+ }
+
+ if (host->use_dma)
+ cmdreg |= DMA_EN;
+
+ OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg);
+ OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
+}
+
+/*
+ * Notify the transfer complete to MMC core
+ */
+static void
+mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
+{
+ host->data = NULL;
+
+ if (host->use_dma && host->dma_ch != -1)
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
+ host->dma_dir);
+
+ host->datadir = OMAP_MMC_DATADIR_NONE;
+
+ if (!data->error)
+ data->bytes_xfered += data->blocks * (data->blksz);
+ else
+ data->bytes_xfered = 0;
+
+ if (!data->stop) {
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, data->mrq);
+ return;
+ }
+ mmc_omap_start_command(host, data->stop, NULL);
+}
+
+/*
+ * Notify the core about command completion
+ */
+static void
+mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
+{
+ host->cmd = NULL;
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ if (cmd->flags & MMC_RSP_136) {
+ /* response type 2 */
+ cmd->resp[3] = OMAP_HSMMC_READ(host->base, RSP10);
+ cmd->resp[2] = OMAP_HSMMC_READ(host->base, RSP32);
+ cmd->resp[1] = OMAP_HSMMC_READ(host->base, RSP54);
+ cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP76);
+ } else {
+ /* response types 1, 1b, 3, 4, 5, 6 */
+ cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
+ }
+ }
+ if (host->data == NULL || cmd->error) {
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, cmd->mrq);
+ }
+}
+
+/*
+ * DMA clean up for command errors
+ */
+static void mmc_dma_cleanup(struct mmc_omap_host *host)
+{
+ host->data->error = -ETIMEDOUT;
+
+ if (host->use_dma && host->dma_ch != -1) {
+ dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
+ host->dma_dir);
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ up(&host->sem);
+ }
+ host->data = NULL;
+ host->datadir = OMAP_MMC_DATADIR_NONE;
+}
+
+/*
+ * Readable error output
+ */
+#ifdef CONFIG_MMC_DEBUG
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u32 status)
+{
+ /* --- means reserved bit without definition at documentation */
+ static const char *mmc_omap_status_bits[] = {
+ "CC", "TC", "BGE", "---", "BWR", "BRR", "---", "---", "CIRQ",
+ "OBI", "---", "---", "---", "---", "---", "ERRI", "CTO", "CCRC",
+ "CEB", "CIE", "DTO", "DCRC", "DEB", "---", "ACE", "---",
+ "---", "---", "---", "CERR", "CERR", "BADA", "---", "---", "---"
+ };
+ char res[256];
+ char *buf = res;
+ int len, i;
+
+ len = sprintf(buf, "MMC IRQ 0x%x :", status);
+ buf += len;
+
+ for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++)
+ if (status & (1 << i)) {
+ len = sprintf(buf, " %s", mmc_omap_status_bits[i]);
+ buf += len;
+ }
+
+ dev_dbg(mmc_dev(host->mmc), "%s\n", res);
+}
+#endif /* CONFIG_MMC_DEBUG */
+
+/*
+ * MMC controller internal state machines reset
+ *
+ * Used to reset command or data internal state machines, using respectively
+ * SRC or SRD bit of SYSCTL register
+ * Can be called from interrupt context
+ */
+static inline void mmc_omap_reset_controller_fsm(struct mmc_omap_host *host,
+ unsigned long bit)
+{
+ unsigned long i = 0;
+ unsigned long limit = (loops_per_jiffy *
+ msecs_to_jiffies(MMC_TIMEOUT_MS));
+
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
+
+ while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
+ (i++ < limit))
+ cpu_relax();
+
+ if (OMAP_HSMMC_READ(host->base, SYSCTL) & bit)
+ dev_err(mmc_dev(host->mmc),
+ "Timeout waiting on controller reset in %s\n",
+ __func__);
+}
+
+/*
+ * MMC controller IRQ handler
+ */
+static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
+{
+ struct mmc_omap_host *host = dev_id;
+ struct mmc_data *data;
+ int end_cmd = 0, end_trans = 0, status;
+
+ if (host->cmd == NULL && host->data == NULL) {
+ OMAP_HSMMC_WRITE(host->base, STAT,
+ OMAP_HSMMC_READ(host->base, STAT));
+ return IRQ_HANDLED;
+ }
+
+ data = host->data;
+ status = OMAP_HSMMC_READ(host->base, STAT);
+ dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
+
+ if (status & ERR) {
+#ifdef CONFIG_MMC_DEBUG
+ mmc_omap_report_irq(host, status);
+#endif
+ if ((status & CMD_TIMEOUT) ||
+ (status & CMD_CRC)) {
+ if (host->cmd) {
+ if (status & CMD_TIMEOUT) {
+ mmc_omap_reset_controller_fsm(host, SRC);
+ host->cmd->error = -ETIMEDOUT;
+ } else {
+ host->cmd->error = -EILSEQ;
+ }
+ end_cmd = 1;
+ }
+ if (host->data) {
+ mmc_dma_cleanup(host);
+ mmc_omap_reset_controller_fsm(host, SRD);
+ }
+ }
+ if ((status & DATA_TIMEOUT) ||
+ (status & DATA_CRC)) {
+ if (host->data) {
+ if (status & DATA_TIMEOUT)
+ mmc_dma_cleanup(host);
+ else
+ host->data->error = -EILSEQ;
+ mmc_omap_reset_controller_fsm(host, SRD);
+ end_trans = 1;
+ }
+ }
+ if (status & CARD_ERR) {
+ dev_dbg(mmc_dev(host->mmc),
+ "Ignoring card err CMD%d\n", host->cmd->opcode);
+ if (host->cmd)
+ end_cmd = 1;
+ if (host->data)
+ end_trans = 1;
+ }
+ }
+
+ OMAP_HSMMC_WRITE(host->base, STAT, status);
+
+ if (end_cmd || (status & CC))
+ mmc_omap_cmd_done(host, host->cmd);
+ if (end_trans || (status & TC))
+ mmc_omap_xfer_done(host, data);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Switch MMC interface voltage ... only relevant for MMC1.
+ *
+ * MMC2 and MMC3 use fixed 1.8V levels, and maybe a transceiver.
+ * The MMC2 transceiver controls are used instead of DAT4..DAT7.
+ * Some chips, like eMMC ones, use internal transceivers.
+ */
+static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
+{
+ u32 reg_val = 0;
+ int ret;
+
+ if (host->id != OMAP_MMC1_DEVID)
+ return 0;
+
+ /* Disable the clocks */
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_disable(host->dbclk);
+
+ /* Turn the power off */
+ ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
+ if (ret != 0)
+ goto err;
+
+ /* Turn the power ON with given VDD 1.8 or 3.0v */
+ ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd);
+ if (ret != 0)
+ goto err;
+
+ clk_enable(host->fclk);
+ clk_enable(host->iclk);
+ clk_enable(host->dbclk);
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR);
+ reg_val = OMAP_HSMMC_READ(host->base, HCTL);
+
+ /*
+ * If a MMC dual voltage card is detected, the set_ios fn calls
+ * this fn with VDD bit set for 1.8V. Upon card removal from the
+ * slot, omap_mmc_set_ios sets the VDD back to 3V on MMC_POWER_OFF.
+ *
+ * Cope with a bit of slop in the range ... per data sheets:
+ * - "1.8V" for vdds_mmc1/vdds_mmc1a can be up to 2.45V max,
+ * but recommended values are 1.71V to 1.89V
+ * - "3.0V" for vdds_mmc1/vdds_mmc1a can be up to 3.5V max,
+ * but recommended values are 2.7V to 3.3V
+ *
+ * Board setup code shouldn't permit anything very out-of-range.
+ * TWL4030-family VMMC1 and VSIM regulators are fine (avoiding the
+ * middle range) but VSIM can't power DAT4..DAT7 at more than 3V.
+ */
+ if ((1 << vdd) <= MMC_VDD_23_24)
+ reg_val |= SDVS18;
+ else
+ reg_val |= SDVS30;
+
+ OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+
+ return 0;
+err:
+ dev_dbg(mmc_dev(host->mmc), "Unable to switch operating voltage\n");
+ return ret;
+}
+
+/*
+ * Work Item to notify the core about card insertion/removal
+ */
+static void mmc_omap_detect(struct work_struct *work)
+{
+ struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
+ mmc_carddetect_work);
+ struct omap_mmc_slot_data *slot = &mmc_slot(host);
+
+ host->carddetect = slot->card_detect(slot->card_detect_irq);
+
+ sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
+ if (host->carddetect) {
+ mmc_detect_change(host->mmc, (HZ * 200) / 1000);
+ } else {
+ mmc_omap_reset_controller_fsm(host, SRD);
+ mmc_detect_change(host->mmc, (HZ * 50) / 1000);
+ }
+}
+
+/*
+ * ISR for handling card insertion and removal
+ */
+static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id)
+{
+ struct mmc_omap_host *host = (struct mmc_omap_host *)dev_id;
+
+ schedule_work(&host->mmc_carddetect_work);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * DMA call back function
+ */
+static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
+{
+ struct mmc_omap_host *host = data;
+
+ if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ)
+ dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n");
+
+ if (host->dma_ch < 0)
+ return;
+
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ /*
+ * DMA Callback: run in interrupt context.
+ * mutex_unlock will through a kernel warning if used.
+ */
+ up(&host->sem);
+}
+
+/*
+ * Configure dma src and destination parameters
+ */
+static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
+ struct mmc_data *data)
+{
+ if (sync_dir == 0) {
+ omap_set_dma_dest_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_src_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(&data->sg[0]), 0, 0);
+ } else {
+ omap_set_dma_src_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_dest_params(host->dma_ch, 0,
+ OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(&data->sg[0]), 0, 0);
+ }
+ return 0;
+}
+/*
+ * Routine to configure and start DMA for the MMC card
+ */
+static int
+mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
+{
+ int sync_dev, sync_dir = 0;
+ int dma_ch = 0, ret = 0, err = 1;
+ struct mmc_data *data = req->data;
+
+ /*
+ * If for some reason the DMA transfer is still active,
+ * we wait for timeout period and free the dma
+ */
+ if (host->dma_ch != -1) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(100);
+ if (down_trylock(&host->sem)) {
+ omap_free_dma(host->dma_ch);
+ host->dma_ch = -1;
+ up(&host->sem);
+ return err;
+ }
+ } else {
+ if (down_trylock(&host->sem))
+ return err;
+ }
+
+ if (!(data->flags & MMC_DATA_WRITE)) {
+ host->dma_dir = DMA_FROM_DEVICE;
+ if (host->id == OMAP_MMC1_DEVID)
+ sync_dev = OMAP24XX_DMA_MMC1_RX;
+ else
+ sync_dev = OMAP24XX_DMA_MMC2_RX;
+ } else {
+ host->dma_dir = DMA_TO_DEVICE;
+ if (host->id == OMAP_MMC1_DEVID)
+ sync_dev = OMAP24XX_DMA_MMC1_TX;
+ else
+ sync_dev = OMAP24XX_DMA_MMC2_TX;
+ }
+
+ ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb,
+ host, &dma_ch);
+ if (ret != 0) {
+ dev_dbg(mmc_dev(host->mmc),
+ "%s: omap_request_dma() failed with %d\n",
+ mmc_hostname(host->mmc), ret);
+ return ret;
+ }
+
+ host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma_dir);
+ host->dma_ch = dma_ch;
+
+ if (!(data->flags & MMC_DATA_WRITE))
+ mmc_omap_config_dma_param(1, host, data);
+ else
+ mmc_omap_config_dma_param(0, host, data);
+
+ if ((data->blksz % 4) == 0)
+ omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
+ (data->blksz / 4), data->blocks, OMAP_DMA_SYNC_FRAME,
+ sync_dev, sync_dir);
+ else
+ /* REVISIT: The MMC buffer increments only when MSB is written.
+ * Return error for blksz which is non multiple of four.
+ */
+ return -EINVAL;
+
+ omap_start_dma(dma_ch);
+ return 0;
+}
+
+static void set_data_timeout(struct mmc_omap_host *host,
+ struct mmc_request *req)
+{
+ unsigned int timeout, cycle_ns;
+ uint32_t reg, clkd, dto = 0;
+
+ reg = OMAP_HSMMC_READ(host->base, SYSCTL);
+ clkd = (reg & CLKD_MASK) >> CLKD_SHIFT;
+ if (clkd == 0)
+ clkd = 1;
+
+ cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd);
+ timeout = req->data->timeout_ns / cycle_ns;
+ timeout += req->data->timeout_clks;
+ if (timeout) {
+ while ((timeout & 0x80000000) == 0) {
+ dto += 1;
+ timeout <<= 1;
+ }
+ dto = 31 - dto;
+ timeout <<= 1;
+ if (timeout && dto)
+ dto += 1;
+ if (dto >= 13)
+ dto -= 13;
+ else
+ dto = 0;
+ if (dto > 14)
+ dto = 14;
+ }
+
+ reg &= ~DTO_MASK;
+ reg |= dto << DTO_SHIFT;
+ OMAP_HSMMC_WRITE(host->base, SYSCTL, reg);
+}
+
+/*
+ * Configure block length for MMC/SD cards and initiate the transfer.
+ */
+static int
+mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
+{
+ int ret;
+ host->data = req->data;
+
+ if (req->data == NULL) {
+ host->datadir = OMAP_MMC_DATADIR_NONE;
+ OMAP_HSMMC_WRITE(host->base, BLK, 0);
+ return 0;
+ }
+
+ OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz)
+ | (req->data->blocks << 16));
+ set_data_timeout(host, req);
+
+ host->datadir = (req->data->flags & MMC_DATA_WRITE) ?
+ OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;
+
+ if (host->use_dma) {
+ ret = mmc_omap_start_dma_transfer(host, req);
+ if (ret != 0) {
+ dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Request function. for read/write operation
+ */
+static void omap_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+
+ WARN_ON(host->mrq != NULL);
+ host->mrq = req;
+ mmc_omap_prepare_data(host, req);
+ mmc_omap_start_command(host, req->cmd, req->data);
+}
+
+
+/* Routine to configure clock values. Exposed API to core */
+static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ u16 dsor = 0;
+ unsigned long regval;
+ unsigned long timeout;
+
+ switch (ios->power_mode) {
+ case MMC_POWER_OFF:
+ mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
+ /*
+ * Reset interface voltage to 3V if it's 1.8V now;
+ * only relevant on MMC-1, the others always use 1.8V.
+ *
+ * REVISIT: If we are able to detect cards after unplugging
+ * a 1.8V card, this code should not be needed.
+ */
+ if (host->id != OMAP_MMC1_DEVID)
+ break;
+ if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
+ int vdd = fls(host->mmc->ocr_avail) - 1;
+ if (omap_mmc_switch_opcond(host, vdd) != 0)
+ host->mmc->ios.vdd = vdd;
+ }
+ break;
+ case MMC_POWER_UP:
+ mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
+ break;
+ }
+
+ switch (mmc->ios.bus_width) {
+ case MMC_BUS_WIDTH_4:
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
+ break;
+ case MMC_BUS_WIDTH_1:
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
+ break;
+ }
+
+ if (host->id == OMAP_MMC1_DEVID) {
+ /* Only MMC1 can interface at 3V without some flavor
+ * of external transceiver; but they all handle 1.8V.
+ */
+ if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) &&
+ (ios->vdd == DUAL_VOLT_OCR_BIT)) {
+ /*
+ * The mmc_select_voltage fn of the core does
+ * not seem to set the power_mode to
+ * MMC_POWER_UP upon recalculating the voltage.
+ * vdd 1.8v.
+ */
+ if (omap_mmc_switch_opcond(host, ios->vdd) != 0)
+ dev_dbg(mmc_dev(host->mmc),
+ "Switch operation failed\n");
+ }
+ }
+
+ if (ios->clock) {
+ dsor = OMAP_MMC_MASTER_CLOCK / ios->clock;
+ if (dsor < 1)
+ dsor = 1;
+
+ if (OMAP_MMC_MASTER_CLOCK / dsor > ios->clock)
+ dsor++;
+
+ if (dsor > 250)
+ dsor = 250;
+ }
+ omap_mmc_stop_clock(host);
+ regval = OMAP_HSMMC_READ(host->base, SYSCTL);
+ regval = regval & ~(CLKD_MASK);
+ regval = regval | (dsor << 6) | (DTO << 16);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
+
+ /* Wait till the ICS bit is set */
+ timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
+ while ((OMAP_HSMMC_READ(host->base, SYSCTL) & ICS) != 0x2
+ && time_before(jiffies, timeout))
+ msleep(1);
+
+ OMAP_HSMMC_WRITE(host->base, SYSCTL,
+ OMAP_HSMMC_READ(host->base, SYSCTL) | CEN);
+
+ if (ios->power_mode == MMC_POWER_ON)
+ send_init_stream(host);
+
+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+ OMAP_HSMMC_WRITE(host->base, CON,
+ OMAP_HSMMC_READ(host->base, CON) | OD);
+}
+
+static int omap_hsmmc_get_cd(struct mmc_host *mmc)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ struct omap_mmc_platform_data *pdata = host->pdata;
+
+ if (!pdata->slots[0].card_detect)
+ return -ENOSYS;
+ return pdata->slots[0].card_detect(pdata->slots[0].card_detect_irq);
+}
+
+static int omap_hsmmc_get_ro(struct mmc_host *mmc)
+{
+ struct mmc_omap_host *host = mmc_priv(mmc);
+ struct omap_mmc_platform_data *pdata = host->pdata;
+
+ if (!pdata->slots[0].get_ro)
+ return -ENOSYS;
+ return pdata->slots[0].get_ro(host->dev, 0);
+}
+
+static struct mmc_host_ops mmc_omap_ops = {
+ .request = omap_mmc_request,
+ .set_ios = omap_mmc_set_ios,
+ .get_cd = omap_hsmmc_get_cd,
+ .get_ro = omap_hsmmc_get_ro,
+ /* NYET -- enable_sdio_irq */
+};
+
+static int __init omap_mmc_probe(struct platform_device *pdev)
+{
+ struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
+ struct mmc_host *mmc;
+ struct mmc_omap_host *host = NULL;
+ struct resource *res;
+ int ret = 0, irq;
+ u32 hctl, capa;
+
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "Platform Data is missing\n");
+ return -ENXIO;
+ }
+
+ if (pdata->nr_slots == 0) {
+ dev_err(&pdev->dev, "No Slots\n");
+ return -ENXIO;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (res == NULL || irq < 0)
+ return -ENXIO;
+
+ 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) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ host->pdata = pdata;
+ host->dev = &pdev->dev;
+ host->use_dma = 1;
+ host->dev->dma_mask = &pdata->dma_mask;
+ host->dma_ch = -1;
+ host->irq = irq;
+ host->id = pdev->id;
+ host->slot_id = 0;
+ host->mapbase = res->start;
+ host->base = ioremap(host->mapbase, SZ_4K);
+
+ platform_set_drvdata(pdev, host);
+ INIT_WORK(&host->mmc_carddetect_work, mmc_omap_detect);
+
+ mmc->ops = &mmc_omap_ops;
+ mmc->f_min = 400000;
+ mmc->f_max = 52000000;
+
+ sema_init(&host->sem, 1);
+
+ host->iclk = clk_get(&pdev->dev, "mmchs_ick");
+ if (IS_ERR(host->iclk)) {
+ ret = PTR_ERR(host->iclk);
+ host->iclk = NULL;
+ goto err1;
+ }
+ host->fclk = clk_get(&pdev->dev, "mmchs_fck");
+ if (IS_ERR(host->fclk)) {
+ ret = PTR_ERR(host->fclk);
+ host->fclk = NULL;
+ clk_put(host->iclk);
+ goto err1;
+ }
+
+ if (clk_enable(host->fclk) != 0) {
+ clk_put(host->iclk);
+ clk_put(host->fclk);
+ goto err1;
+ }
+
+ if (clk_enable(host->iclk) != 0) {
+ clk_disable(host->fclk);
+ clk_put(host->iclk);
+ clk_put(host->fclk);
+ goto err1;
+ }
+
+ host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck");
+ /*
+ * MMC can still work without debounce clock.
+ */
+ if (IS_ERR(host->dbclk))
+ dev_warn(mmc_dev(host->mmc), "Failed to get debounce clock\n");
+ else
+ if (clk_enable(host->dbclk) != 0)
+ dev_dbg(mmc_dev(host->mmc), "Enabling debounce"
+ " clk failed\n");
+ else
+ host->dbclk_enabled = 1;
+
+#ifdef CONFIG_MMC_BLOCK_BOUNCE
+ mmc->max_phys_segs = 1;
+ mmc->max_hw_segs = 1;
+#endif
+ mmc->max_blk_size = 512; /* Block Length at max can be 1024 */
+ mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_req_size;
+
+ mmc->ocr_avail = mmc_slot(host).ocr_mask;
+ mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
+
+ if (pdata->slots[host->slot_id].wires >= 4)
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
+
+ /* Only MMC1 supports 3.0V */
+ if (host->id == OMAP_MMC1_DEVID) {
+ hctl = SDVS30;
+ capa = VS30 | VS18;
+ } else {
+ hctl = SDVS18;
+ capa = VS18;
+ }
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | hctl);
+
+ OMAP_HSMMC_WRITE(host->base, CAPA,
+ OMAP_HSMMC_READ(host->base, CAPA) | capa);
+
+ /* Set the controller to AUTO IDLE mode */
+ OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
+ OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+
+ /* Set SD bus power bit */
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+
+ /* Request IRQ for MMC operations */
+ ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
+ mmc_hostname(mmc), host);
+ if (ret) {
+ dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
+ goto err_irq;
+ }
+
+ if (pdata->init != NULL) {
+ if (pdata->init(&pdev->dev) != 0) {
+ dev_dbg(mmc_dev(host->mmc),
+ "Unable to configure MMC IRQs\n");
+ goto err_irq_cd_init;
+ }
+ }
+
+ /* Request IRQ for card detect */
+ if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+ ret = request_irq(mmc_slot(host).card_detect_irq,
+ omap_mmc_cd_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
+ | IRQF_DISABLED,
+ mmc_hostname(mmc), host);
+ if (ret) {
+ dev_dbg(mmc_dev(host->mmc),
+ "Unable to grab MMC CD IRQ\n");
+ goto err_irq_cd;
+ }
+ }
+
+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+
+ mmc_add_host(mmc);
+
+ if (host->pdata->slots[host->slot_id].name != NULL) {
+ ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name);
+ if (ret < 0)
+ goto err_slot_name;
+ }
+ if (mmc_slot(host).card_detect_irq && mmc_slot(host).card_detect &&
+ host->pdata->slots[host->slot_id].get_cover_state) {
+ ret = device_create_file(&mmc->class_dev,
+ &dev_attr_cover_switch);
+ if (ret < 0)
+ goto err_cover_switch;
+ }
+
+ return 0;
+
+err_cover_switch:
+ device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);
+err_slot_name:
+ mmc_remove_host(mmc);
+err_irq_cd:
+ free_irq(mmc_slot(host).card_detect_irq, host);
+err_irq_cd_init:
+ free_irq(host->irq, host);
+err_irq:
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_put(host->fclk);
+ clk_put(host->iclk);
+ if (host->dbclk_enabled) {
+ clk_disable(host->dbclk);
+ clk_put(host->dbclk);
+ }
+
+err1:
+ iounmap(host->base);
+err:
+ dev_dbg(mmc_dev(host->mmc), "Probe Failed\n");
+ release_mem_region(res->start, res->end - res->start + 1);
+ if (host)
+ mmc_free_host(mmc);
+ return ret;
+}
+
+static int omap_mmc_remove(struct platform_device *pdev)
+{
+ struct mmc_omap_host *host = platform_get_drvdata(pdev);
+ struct resource *res;
+
+ if (host) {
+ mmc_remove_host(host->mmc);
+ if (host->pdata->cleanup)
+ host->pdata->cleanup(&pdev->dev);
+ free_irq(host->irq, host);
+ if (mmc_slot(host).card_detect_irq)
+ free_irq(mmc_slot(host).card_detect_irq, host);
+ flush_scheduled_work();
+
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_put(host->fclk);
+ clk_put(host->iclk);
+ if (host->dbclk_enabled) {
+ clk_disable(host->dbclk);
+ clk_put(host->dbclk);
+ }
+
+ mmc_free_host(host->mmc);
+ iounmap(host->base);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ release_mem_region(res->start, res->end - res->start + 1);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ int ret = 0;
+ struct mmc_omap_host *host = platform_get_drvdata(pdev);
+
+ if (host && host->suspended)
+ return 0;
+
+ if (host) {
+ ret = mmc_suspend_host(host->mmc, state);
+ if (ret == 0) {
+ host->suspended = 1;
+
+ OMAP_HSMMC_WRITE(host->base, ISE, 0);
+ OMAP_HSMMC_WRITE(host->base, IE, 0);
+
+ if (host->pdata->suspend) {
+ ret = host->pdata->suspend(&pdev->dev,
+ host->slot_id);
+ if (ret)
+ dev_dbg(mmc_dev(host->mmc),
+ "Unable to handle MMC board"
+ " level suspend\n");
+ }
+
+ if (host->id == OMAP_MMC1_DEVID
+ && !(OMAP_HSMMC_READ(host->base, HCTL)
+ & SDVSDET)) {
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL)
+ & SDVSCLR);
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL)
+ | SDVS30);
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL)
+ | SDBP);
+ }
+
+ clk_disable(host->fclk);
+ clk_disable(host->iclk);
+ clk_disable(host->dbclk);
+ }
+
+ }
+ return ret;
+}
+
+/* Routine to resume the MMC device */
+static int omap_mmc_resume(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct mmc_omap_host *host = platform_get_drvdata(pdev);
+
+ if (host && !host->suspended)
+ return 0;
+
+ if (host) {
+
+ ret = clk_enable(host->fclk);
+ if (ret)
+ goto clk_en_err;
+
+ ret = clk_enable(host->iclk);
+ if (ret) {
+ clk_disable(host->fclk);
+ clk_put(host->fclk);
+ goto clk_en_err;
+ }
+
+ if (clk_enable(host->dbclk) != 0)
+ dev_dbg(mmc_dev(host->mmc),
+ "Enabling debounce clk failed\n");
+
+ if (host->pdata->resume) {
+ ret = host->pdata->resume(&pdev->dev, host->slot_id);
+ if (ret)
+ dev_dbg(mmc_dev(host->mmc),
+ "Unmask interrupt failed\n");
+ }
+
+ /* Notify the core to resume the host */
+ ret = mmc_resume_host(host->mmc);
+ if (ret == 0)
+ host->suspended = 0;
+ }
+
+ return ret;
+
+clk_en_err:
+ dev_dbg(mmc_dev(host->mmc),
+ "Failed to enable MMC clocks during resume\n");
+ return ret;
+}
+
+#else
+#define omap_mmc_suspend NULL
+#define omap_mmc_resume NULL
+#endif
+
+static struct platform_driver omap_mmc_driver = {
+ .probe = omap_mmc_probe,
+ .remove = omap_mmc_remove,
+ .suspend = omap_mmc_suspend,
+ .resume = omap_mmc_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init omap_mmc_init(void)
+{
+ /* Register the MMC driver */
+ return platform_driver_register(&omap_mmc_driver);
+}
+
+static void __exit omap_mmc_cleanup(void)
+{
+ /* Unregister MMC driver */
+ platform_driver_unregister(&omap_mmc_driver);
+}
+
+module_init(omap_mmc_init);
+module_exit(omap_mmc_cleanup);
+
+MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 3c5483b75da4..430095725f9f 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -30,9 +30,8 @@
#include <asm/sizes.h>
-#include <mach/dma.h>
#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/dma.h>
#include <mach/mmc.h>
#include "pxamci.h"
@@ -180,7 +179,15 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
else
DALGN &= ~(1 << host->dma);
DDADR(host->dma) = host->sg_dma;
- DCSR(host->dma) = DCSR_RUN;
+
+ /*
+ * workaround for erratum #91:
+ * only start DMA now if we are doing a read,
+ * otherwise we wait until CMD/RESP has finished
+ * before starting DMA.
+ */
+ if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ)
+ DCSR(host->dma) = DCSR_RUN;
}
static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat)
@@ -251,23 +258,28 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
if (stat & STAT_TIME_OUT_RESPONSE) {
cmd->error = -ETIMEDOUT;
} else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
-#ifdef CONFIG_PXA27x
/*
* workaround for erratum #42:
* Intel PXA27x Family Processor Specification Update Rev 001
* A bogus CRC error can appear if the msb of a 136 bit
* response is a one.
*/
- if (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000) {
+ if (cpu_is_pxa27x() &&
+ (cmd->flags & MMC_RSP_136 && cmd->resp[0] & 0x80000000))
pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode);
- } else
-#endif
- cmd->error = -EILSEQ;
+ else
+ cmd->error = -EILSEQ;
}
pxamci_disable_irq(host, END_CMD_RES);
if (host->data && !cmd->error) {
pxamci_enable_irq(host, DATA_TRAN_DONE);
+ /*
+ * workaround for erratum #91, if doing write
+ * enable DMA late
+ */
+ if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE)
+ DCSR(host->dma) = DCSR_RUN;
} else {
pxamci_finish_request(host, host->mrq);
}
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
index be9e7b32b34e..f62790513322 100644
--- a/drivers/mmc/host/ricoh_mmc.c
+++ b/drivers/mmc/host/ricoh_mmc.c
@@ -196,7 +196,7 @@ static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
+static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state)
{
struct pci_dev *fw_dev = NULL;
@@ -210,7 +210,7 @@ static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
-static int ricoh_mmc_resume(struct pci_dev *pdev)
+static int ricoh_mmc_resume_early(struct pci_dev *pdev)
{
struct pci_dev *fw_dev = NULL;
@@ -229,8 +229,8 @@ static struct pci_driver ricoh_mmc_driver = {
.id_table = pci_ids,
.probe = ricoh_mmc_probe,
.remove = __devexit_p(ricoh_mmc_remove),
- .suspend = ricoh_mmc_suspend,
- .resume = ricoh_mmc_resume,
+ .suspend_late = ricoh_mmc_suspend_late,
+ .resume_early = ricoh_mmc_resume_early,
};
/*****************************************************************************\
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index fcc98a4cce3c..f4a67c65d301 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -20,7 +20,7 @@
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/dma.h>
+#include <mach/dma.h>
#include <mach/regs-sdi.h>
#include <mach/regs-gpio.h>
@@ -329,7 +329,7 @@ static void do_pio_write(struct s3cmci_host *host)
to_ptr = host->base + host->sdidata;
- while ((fifo = fifo_free(host))) {
+ while ((fifo = fifo_free(host)) > 3) {
if (!host->pio_bytes) {
res = get_data_buffer(host, &host->pio_bytes,
&host->pio_ptr);
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index f07255cb17ee..8cff5f5e7f86 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -144,8 +144,7 @@ static int jmicron_probe(struct sdhci_pci_chip *chip)
SDHCI_QUIRK_32BIT_DMA_SIZE |
SDHCI_QUIRK_32BIT_ADMA_SIZE |
SDHCI_QUIRK_RESET_AFTER_REQUEST |
- SDHCI_QUIRK_BROKEN_SMALL_PIO |
- SDHCI_QUIRK_FORCE_HIGHSPEED;
+ SDHCI_QUIRK_BROKEN_SMALL_PIO;
}
/*
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6b2d1f99af67..f52f3053ed92 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1636,8 +1636,7 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->f_max = host->max_clk;
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
- if ((caps & SDHCI_CAN_DO_HISPD) ||
- (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED))
+ if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED;
mmc->ocr_avail = 0;
@@ -1723,7 +1722,9 @@ int sdhci_add_host(struct sdhci_host *host)
#endif
#ifdef SDHCI_USE_LEDS_CLASS
- host->led.name = mmc_hostname(mmc);
+ snprintf(host->led_name, sizeof(host->led_name),
+ "%s::", mmc_hostname(mmc));
+ host->led.name = host->led_name;
host->led.brightness = LED_OFF;
host->led.default_trigger = mmc_hostname(mmc);
host->led.brightness_set = sdhci_led_control;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 3efba2363941..ebb83657e27a 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -208,8 +208,6 @@ struct sdhci_host {
#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12)
/* Controller has an issue with buffer bits for small transfers */
#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)
-/* Controller supports high speed but doesn't have the caps bit set */
-#define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14)
int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */
@@ -222,6 +220,7 @@ struct sdhci_host {
#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
struct led_classdev led; /* LED control */
+ char led_name[32];
#endif
spinlock_t lock; /* Mutex */
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 771139c5bf87..e9026cb1c5b2 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-static int __init pxa2xx_flash_probe(struct device *dev)
+static int __init pxa2xx_flash_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *flash = pdev->dev.platform_data;
struct pxa2xx_flash_info *info;
struct mtd_partition *parts;
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev)
add_mtd_device(info->mtd);
}
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
}
-static int __exit pxa2xx_flash_remove(struct device *dev)
+static int __exit pxa2xx_flash_remove(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
#ifdef CONFIG_MTD_PARTITIONS
if (info->nr_parts)
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
int ret = 0;
if (info->mtd && info->mtd->suspend)
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
return ret;
}
-static int pxa2xx_flash_resume(struct device *dev)
+static int pxa2xx_flash_resume(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
if (info->mtd && info->mtd->resume)
info->mtd->resume(info->mtd);
return 0;
}
-static void pxa2xx_flash_shutdown(struct device *dev)
+static void pxa2xx_flash_shutdown(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
if (info && info->mtd->suspend(info->mtd) == 0)
info->mtd->resume(info->mtd);
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev)
#define pxa2xx_flash_shutdown NULL
#endif
-static struct device_driver pxa2xx_flash_driver = {
- .name = "pxa2xx-flash",
- .bus = &platform_bus_type,
+static struct platform_driver pxa2xx_flash_driver = {
+ .driver = {
+ .name = "pxa2xx-flash",
+ .owner = THIS_MODULE,
+ },
.probe = pxa2xx_flash_probe,
- .remove = __exit_p(pxa2xx_flash_remove),
+ .remove = __devexit_p(pxa2xx_flash_remove),
.suspend = pxa2xx_flash_suspend,
.resume = pxa2xx_flash_resume,
.shutdown = pxa2xx_flash_shutdown,
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash_driver = {
static int __init init_pxa2xx_flash(void)
{
- return driver_register(&pxa2xx_flash_driver);
+ return platform_driver_register(&pxa2xx_flash_driver);
}
static void __exit cleanup_pxa2xx_flash(void)
{
- driver_unregister(&pxa2xx_flash_driver);
+ platform_driver_unregister(&pxa2xx_flash_driver);
}
module_init(init_pxa2xx_flash);
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 7df6bbf0e4d9..6f6a0f6dafd6 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -453,7 +453,7 @@ static struct platform_driver sa1100_mtd_driver = {
.resume = sa1100_mtd_resume,
.shutdown = sa1100_mtd_shutdown,
.driver = {
- .name = "flash",
+ .name = "sa1100-mtd",
.owner = THIS_MODULE,
},
};
@@ -474,4 +474,4 @@ module_exit(sa1100_mtd_exit);
MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("SA1100 CFI map driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:flash");
+MODULE_ALIAS("platform:sa1100-mtd");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8b12e6e109d3..2ff88791cebc 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -273,7 +273,7 @@ config MTD_NAND_CAFE
config MTD_NAND_CS553X
tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
- depends on X86_32 && (X86_PC || X86_GENERICARCH)
+ depends on X86_32
help
The CS553x companion chips for the AMD Geode processor
include NAND flash controllers with built-in hardware ECC
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index c98c1570a40b..47a33cec3793 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -139,7 +139,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd)
struct nand_chip *nand_chip = mtd->priv;
struct atmel_nand_host *host = nand_chip->priv;
- return gpio_get_value(host->board->rdy_pin);
+ return gpio_get_value(host->board->rdy_pin) ^
+ !!host->board->rdy_pin_active_low;
}
/*
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index fa129c09bca8..10081e656a6f 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -26,8 +26,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
#define GPIO_NAND_CS (11)
#define GPIO_NAND_RB (89)
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
index ced14b5294d5..72446fb48d4b 100644
--- a/drivers/mtd/nand/excite_nandflash.c
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct mtd_info *mtd)
* The binding to the mtd and all allocated
* resources are released.
*/
-static int __exit excite_nand_remove(struct device *dev)
+static int __exit excite_nand_remove(struct platform_device *dev)
{
- struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
+ struct excite_nand_drvdata * const this = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (unlikely(!this)) {
printk(KERN_ERR "%s: called %s without private data!!",
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(struct device *dev)
* it can allocate all necessary resources then calls the
* nand layer to look for devices.
*/
-static int __init excite_nand_probe(struct device *dev)
+static int __init excite_nand_probe(struct platform_device *pdev)
{
- struct platform_device * const pdev = to_platform_device(dev);
struct excite_nand_drvdata *drvdata; /* private driver data */
struct nand_chip *board_chip; /* private flash chip data */
struct mtd_info *board_mtd; /* mtd info for this board */
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(struct device *dev)
}
/* bind private data into driver */
- dev_set_drvdata(dev, drvdata);
+ platform_set_drvdata(pdev, drvdata);
/* allocate and map the resource */
drvdata->regs =
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(struct device *dev)
return 0;
}
-static struct device_driver excite_nand_driver = {
- .name = "excite_nand",
- .bus = &platform_bus_type,
+static struct platform_driver excite_nand_driver = {
+ .driver = {
+ .name = "excite_nand",
+ .owner = THIS_MODULE,
+ },
.probe = excite_nand_probe,
- .remove = __exit_p(excite_nand_remove)
+ .remove = __devexit_p(excite_nand_remove)
};
static int __init excite_nand_init(void)
{
pr_info("Basler eXcite nand flash driver Version "
EXCITE_NANDFLASH_VERSION "\n");
- return driver_register(&excite_nand_driver);
+ return platform_driver_register(&excite_nand_driver);
}
static void __exit excite_nand_exit(void)
{
- driver_unregister(&excite_nand_driver);
+ platform_driver_unregister(&excite_nand_driver);
}
module_init(excite_nand_init);
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 65929db29446..1f6eb2578717 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -676,7 +676,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
dev_dbg(ctrl->dev, "fsl_elbc_init: nand->numchips = %d\n",
chip->numchips);
- dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %ld\n",
+ dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
chip->chipsize);
dev_dbg(ctrl->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
chip->pagemask);
@@ -703,7 +703,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd)
dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.layout = %p\n",
chip->ecc.layout);
dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags);
- dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %d\n", mtd->size);
+ dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size);
dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->erasesize = %d\n",
mtd->erasesize);
dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->writesize = %d\n",
@@ -932,8 +932,8 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
#endif
add_mtd_device(&priv->mtd);
- printk(KERN_INFO "eLBC NAND device at 0x%zx, bank %d\n",
- res.start, priv->bank);
+ printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
+ (unsigned long long)res.start, priv->bank);
return 0;
err:
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 582cf80f555a..89bf85af642c 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -187,7 +187,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
return -ENODEV;
ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
- ndfc->ofdev->dev.bus_id, flash_np->name);
+ dev_name(&ndfc->ofdev->dev), flash_np->name);
if (!ndfc->mtd.name) {
ret = -ENOMEM;
goto err;
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c
index 9bd6c9ac8443..a8b9376cf324 100644
--- a/drivers/mtd/nand/pasemi_nand.c
+++ b/drivers/mtd/nand/pasemi_nand.c
@@ -107,7 +107,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev,
if (pasemi_nand_mtd)
return -ENODEV;
- pr_debug("pasemi_nand at %lx-%lx\n", res.start, res.end);
+ pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end);
/* Allocate memory for MTD device structure and private data */
pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) +
@@ -170,7 +170,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev,
goto out_lpc;
}
- printk(KERN_INFO "PA Semi NAND flash at %08lx, control at I/O %x\n",
+ printk(KERN_INFO "PA Semi NAND flash at %08llx, control at I/O %x\n",
res.start, lpcctl);
return 0;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index cc55cbc2b308..61b69cc40009 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -22,7 +22,6 @@
#include <linux/irq.h>
#include <mach/dma.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa3xx_nand.h>
#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 5b69e7773c6c..3a496c33fb52 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -36,10 +36,9 @@ struct onenand_info {
struct onenand_chip onenand;
};
-static int __devinit generic_onenand_probe(struct device *dev)
+static int __devinit generic_onenand_probe(struct platform_device *pdev)
{
struct onenand_info *info;
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *pdata = pdev->dev.platform_data;
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
if (!info)
return -ENOMEM;
- if (!request_mem_region(res->start, size, dev->driver->name)) {
+ if (!request_mem_region(res->start, size, pdev->dev.driver->name)) {
err = -EBUSY;
goto out_free_info;
}
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
#endif
err = add_mtd_device(&info->mtd);
- dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
@@ -96,14 +95,13 @@ out_free_info:
return err;
}
-static int __devexit generic_onenand_remove(struct device *dev)
+static int __devexit generic_onenand_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct onenand_info *info = dev_get_drvdata(&pdev->dev);
+ struct onenand_info *info = platform_get_drvdata(pdev);
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (info) {
if (info->parts)
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_remove(struct device *dev)
return 0;
}
-static struct device_driver generic_onenand_driver = {
- .name = DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver generic_onenand_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
.probe = generic_onenand_probe,
.remove = __devexit_p(generic_onenand_remove),
};
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME);
static int __init generic_onenand_init(void)
{
- return driver_register(&generic_onenand_driver);
+ return platform_driver_register(&generic_onenand_driver);
}
static void __exit generic_onenand_exit(void)
{
- driver_unregister(&generic_onenand_driver);
+ platform_driver_unregister(&generic_onenand_driver);
}
module_init(generic_onenand_init);
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 96ecc1766fa8..77a4f1446156 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -629,7 +629,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
}
if (c->gpio_irq) {
- if ((r = omap_request_gpio(c->gpio_irq)) < 0) {
+ if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
dev_err(&pdev->dev, "Failed to request GPIO%d for "
"OneNAND\n", c->gpio_irq);
goto err_iounmap;
@@ -726,7 +726,7 @@ err_release_dma:
free_irq(gpio_to_irq(c->gpio_irq), c);
err_release_gpio:
if (c->gpio_irq)
- omap_free_gpio(c->gpio_irq);
+ gpio_free(c->gpio_irq);
err_iounmap:
iounmap(c->onenand.base);
err_release_mem_region:
@@ -761,7 +761,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
if (c->gpio_irq) {
free_irq(gpio_to_irq(c->gpio_irq), c);
- omap_free_gpio(c->gpio_irq);
+ gpio_free(c->gpio_irq);
}
iounmap(c->onenand.base);
release_mem_region(c->phys_base, ONENAND_IO_SIZE);
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug
index 1e2ee22edeff..2246f154e2f7 100644
--- a/drivers/mtd/ubi/Kconfig.debug
+++ b/drivers/mtd/ubi/Kconfig.debug
@@ -33,16 +33,6 @@ config MTD_UBI_DEBUG_DISABLE_BGT
This option switches the background thread off by default. The thread
may be also be enabled/disabled via UBI sysfs.
-config MTD_UBI_DEBUG_USERSPACE_IO
- bool "Direct user-space write/erase support"
- default n
- depends on MTD_UBI_DEBUG
- help
- By default, users cannot directly write and erase individual
- eraseblocks of dynamic volumes, and have to use update operation
- instead. This option enables this capability - it is very useful for
- debugging and testing.
-
config MTD_UBI_DEBUG_EMULATE_BITFLIPS
bool "Emulate flash bit-flips"
depends on MTD_UBI_DEBUG
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 9082768cc6c3..4048db83aef6 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -263,8 +263,12 @@ static ssize_t dev_attribute_show(struct device *dev,
return ret;
}
-/* Fake "release" method for UBI devices */
-static void dev_release(struct device *dev) { }
+static void dev_release(struct device *dev)
+{
+ struct ubi_device *ubi = container_of(dev, struct ubi_device, dev);
+
+ kfree(ubi);
+}
/**
* ubi_sysfs_init - initialize sysfs for an UBI device.
@@ -380,7 +384,7 @@ static void free_user_volumes(struct ubi_device *ubi)
*/
static int uif_init(struct ubi_device *ubi)
{
- int i, err, do_free = 0;
+ int i, err;
dev_t dev;
sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
@@ -427,13 +431,10 @@ static int uif_init(struct ubi_device *ubi)
out_volumes:
kill_volumes(ubi);
- do_free = 0;
out_sysfs:
ubi_sysfs_close(ubi);
cdev_del(&ubi->cdev);
out_unreg:
- if (do_free)
- free_user_volumes(ubi);
unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err);
return err;
@@ -947,6 +948,12 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
if (ubi->bgt_thread)
kthread_stop(ubi->bgt_thread);
+ /*
+ * Get a reference to the device in order to prevent 'dev_release()'
+ * from freeing @ubi object.
+ */
+ get_device(&ubi->dev);
+
uif_close(ubi);
ubi_wl_close(ubi);
free_internal_volumes(ubi);
@@ -958,7 +965,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
vfree(ubi->dbg_peb_buf);
#endif
ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
- kfree(ubi);
+ put_device(&ubi->dev);
return 0;
}
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 98cf31ed0814..e63c8fc3df3a 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -40,9 +40,9 @@
#include <linux/ioctl.h>
#include <linux/capability.h>
#include <linux/uaccess.h>
-#include <linux/smp_lock.h>
+#include <linux/compat.h>
+#include <linux/math64.h>
#include <mtd/ubi-user.h>
-#include <asm/div64.h>
#include "ubi.h"
/**
@@ -195,7 +195,6 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
int err, lnum, off, len, tbuf_size;
size_t count_save = count;
void *tbuf;
- uint64_t tmp;
dbg_gen("read %zd bytes from offset %lld of volume %d",
count, *offp, vol->vol_id);
@@ -225,10 +224,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
return -ENOMEM;
len = count > tbuf_size ? tbuf_size : count;
-
- tmp = *offp;
- off = do_div(tmp, vol->usable_leb_size);
- lnum = tmp;
+ lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
do {
cond_resched();
@@ -263,12 +259,9 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
return err ? err : count_save - count;
}
-#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO
-
/*
* This function allows to directly write to dynamic UBI volumes, without
- * issuing the volume update operation. Available only as a debugging feature.
- * Very useful for testing UBI.
+ * issuing the volume update operation.
*/
static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
size_t count, loff_t *offp)
@@ -279,7 +272,9 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
int lnum, off, len, tbuf_size, err = 0;
size_t count_save = count;
char *tbuf;
- uint64_t tmp;
+
+ if (!vol->direct_writes)
+ return -EPERM;
dbg_gen("requested: write %zd bytes to offset %lld of volume %u",
count, *offp, vol->vol_id);
@@ -287,10 +282,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
if (vol->vol_type == UBI_STATIC_VOLUME)
return -EROFS;
- tmp = *offp;
- off = do_div(tmp, vol->usable_leb_size);
- lnum = tmp;
-
+ lnum = div_u64_rem(*offp, vol->usable_leb_size, &off);
if (off & (ubi->min_io_size - 1)) {
dbg_err("unaligned position");
return -EINVAL;
@@ -347,10 +339,6 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
return err ? err : count_save - count;
}
-#else
-#define vol_cdev_direct_write(file, buf, count, offp) (-EPERM)
-#endif /* CONFIG_MTD_UBI_DEBUG_USERSPACE_IO */
-
static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
size_t count, loff_t *offp)
{
@@ -402,8 +390,8 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
return count;
}
-static int vol_cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
int err = 0;
struct ubi_volume_desc *desc = file->private_data;
@@ -487,7 +475,6 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file,
break;
}
-#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO
/* Logical eraseblock erasure command */
case UBI_IOCEBER:
{
@@ -518,13 +505,77 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file,
err = ubi_wl_flush(ubi);
break;
}
-#endif
+
+ /* Logical eraseblock map command */
+ case UBI_IOCEBMAP:
+ {
+ struct ubi_map_req req;
+
+ err = copy_from_user(&req, argp, sizeof(struct ubi_map_req));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ err = ubi_leb_map(desc, req.lnum, req.dtype);
+ break;
+ }
+
+ /* Logical eraseblock un-map command */
+ case UBI_IOCEBUNMAP:
+ {
+ int32_t lnum;
+
+ err = get_user(lnum, (__user int32_t *)argp);
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ err = ubi_leb_unmap(desc, lnum);
+ break;
+ }
+
+ /* Check if logical eraseblock is mapped command */
+ case UBI_IOCEBISMAP:
+ {
+ int32_t lnum;
+
+ err = get_user(lnum, (__user int32_t *)argp);
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ err = ubi_is_mapped(desc, lnum);
+ break;
+ }
+
+ /* Set volume property command*/
+ case UBI_IOCSETPROP:
+ {
+ struct ubi_set_prop_req req;
+
+ err = copy_from_user(&req, argp,
+ sizeof(struct ubi_set_prop_req));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+ switch (req.property) {
+ case UBI_PROP_DIRECT_WRITE:
+ mutex_lock(&ubi->volumes_mutex);
+ desc->vol->direct_writes = !!req.value;
+ mutex_unlock(&ubi->volumes_mutex);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ break;
+ }
default:
err = -ENOTTY;
break;
}
-
return err;
}
@@ -762,8 +813,8 @@ out_free:
return err;
}
-static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
int err = 0;
struct ubi_device *ubi;
@@ -773,7 +824,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
if (!capable(CAP_SYS_RESOURCE))
return -EPERM;
- ubi = ubi_get_by_major(imajor(inode));
+ ubi = ubi_get_by_major(imajor(file->f_mapping->host));
if (!ubi)
return -ENODEV;
@@ -843,7 +894,6 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
case UBI_IOCRSVOL:
{
int pebs;
- uint64_t tmp;
struct ubi_rsvol_req req;
dbg_gen("re-size volume");
@@ -863,9 +913,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
break;
}
- tmp = req.bytes;
- pebs = !!do_div(tmp, desc->vol->usable_leb_size);
- pebs += tmp;
+ pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1,
+ desc->vol->usable_leb_size);
mutex_lock(&ubi->volumes_mutex);
err = ubi_resize_volume(desc, pebs);
@@ -909,8 +958,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
return err;
}
-static int ctrl_cdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
int err = 0;
void __user *argp = (void __user *)arg;
@@ -986,26 +1035,59 @@ static int ctrl_cdev_ioctl(struct inode *inode, struct file *file,
return err;
}
-/* UBI control character device operations */
-struct file_operations ubi_ctrl_cdev_operations = {
- .ioctl = ctrl_cdev_ioctl,
- .owner = THIS_MODULE,
+#ifdef CONFIG_COMPAT
+static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned long translated_arg = (unsigned long)compat_ptr(arg);
+
+ return vol_cdev_ioctl(file, cmd, translated_arg);
+}
+
+static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned long translated_arg = (unsigned long)compat_ptr(arg);
+
+ return ubi_cdev_ioctl(file, cmd, translated_arg);
+}
+
+static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned long translated_arg = (unsigned long)compat_ptr(arg);
+
+ return ctrl_cdev_ioctl(file, cmd, translated_arg);
+}
+#else
+#define vol_cdev_compat_ioctl NULL
+#define ubi_cdev_compat_ioctl NULL
+#define ctrl_cdev_compat_ioctl NULL
+#endif
+
+/* UBI volume character device operations */
+const struct file_operations ubi_vol_cdev_operations = {
+ .owner = THIS_MODULE,
+ .open = vol_cdev_open,
+ .release = vol_cdev_release,
+ .llseek = vol_cdev_llseek,
+ .read = vol_cdev_read,
+ .write = vol_cdev_write,
+ .unlocked_ioctl = vol_cdev_ioctl,
+ .compat_ioctl = vol_cdev_compat_ioctl,
};
/* UBI character device operations */
-struct file_operations ubi_cdev_operations = {
- .owner = THIS_MODULE,
- .ioctl = ubi_cdev_ioctl,
- .llseek = no_llseek,
+const struct file_operations ubi_cdev_operations = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .unlocked_ioctl = ubi_cdev_ioctl,
+ .compat_ioctl = ubi_cdev_compat_ioctl,
};
-/* UBI volume character device operations */
-struct file_operations ubi_vol_cdev_operations = {
- .owner = THIS_MODULE,
- .open = vol_cdev_open,
- .release = vol_cdev_release,
- .llseek = vol_cdev_llseek,
- .read = vol_cdev_read,
- .write = vol_cdev_write,
- .ioctl = vol_cdev_ioctl,
+/* UBI control character device operations */
+const struct file_operations ubi_ctrl_cdev_operations = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = ctrl_cdev_ioctl,
+ .compat_ioctl = ctrl_cdev_compat_ioctl,
};
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index 6dd4f5e77f82..49cd55ade9c8 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -28,7 +28,7 @@
* eraseblock size is equivalent to the logical eraseblock size of the volume.
*/
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
/**
@@ -109,7 +109,6 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
int err = 0, lnum, offs, total_read;
struct ubi_volume *vol;
struct ubi_device *ubi;
- uint64_t tmp = from;
dbg_gen("read %zd bytes from offset %lld", len, from);
@@ -119,9 +118,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
vol = container_of(mtd, struct ubi_volume, gluebi_mtd);
ubi = vol->ubi;
- offs = do_div(tmp, mtd->erasesize);
- lnum = tmp;
-
+ lnum = div_u64_rem(from, mtd->erasesize, &offs);
total_read = len;
while (total_read) {
size_t to_read = mtd->erasesize - offs;
@@ -160,7 +157,6 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
int err = 0, lnum, offs, total_written;
struct ubi_volume *vol;
struct ubi_device *ubi;
- uint64_t tmp = to;
dbg_gen("write %zd bytes to offset %lld", len, to);
@@ -173,8 +169,7 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
if (ubi->ro_mode)
return -EROFS;
- offs = do_div(tmp, mtd->erasesize);
- lnum = tmp;
+ lnum = div_u64_rem(to, mtd->erasesize, &offs);
if (len % mtd->writesize || offs % mtd->writesize)
return -EINVAL;
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index ecde202a5a12..c3d653ba5ca0 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -42,7 +42,7 @@
#include <linux/err.h>
#include <linux/crc32.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
@@ -904,10 +904,8 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
dbg_msg("scanning is finished");
/* Calculate mean erase counter */
- if (si->ec_count) {
- do_div(si->ec_sum, si->ec_count);
- si->mean_ec = si->ec_sum;
- }
+ if (si->ec_count)
+ si->mean_ec = div_u64(si->ec_sum, si->ec_count);
if (si->is_empty)
ubi_msg("empty MTD device detected");
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 4a8ec485c91d..c055511bb1b2 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -206,6 +206,7 @@ struct ubi_volume_desc;
* @upd_marker: %1 if the update marker is set for this volume
* @updating: %1 if the volume is being updated
* @changing_leb: %1 if the atomic LEB change ioctl command is in progress
+ * @direct_writes: %1 if direct writes are enabled for this volume
*
* @gluebi_desc: gluebi UBI volume descriptor
* @gluebi_refcount: reference count of the gluebi MTD device
@@ -253,6 +254,7 @@ struct ubi_volume {
unsigned int upd_marker:1;
unsigned int updating:1;
unsigned int changing_leb:1;
+ unsigned int direct_writes:1;
#ifdef CONFIG_MTD_UBI_GLUEBI
/*
@@ -304,7 +306,8 @@ struct ubi_wl_entry;
* @vtbl_size: size of the volume table in bytes
* @vtbl: in-RAM volume table copy
* @volumes_mutex: protects on-flash volume table and serializes volume
- * changes, like creation, deletion, update, re-size and re-name
+ * changes, like creation, deletion, update, re-size,
+ * re-name and set property
*
* @max_ec: current highest erase counter value
* @mean_ec: current mean erase counter value
@@ -449,9 +452,9 @@ struct ubi_device {
};
extern struct kmem_cache *ubi_wl_entry_slab;
-extern struct file_operations ubi_ctrl_cdev_operations;
-extern struct file_operations ubi_cdev_operations;
-extern struct file_operations ubi_vol_cdev_operations;
+extern const struct file_operations ubi_ctrl_cdev_operations;
+extern const struct file_operations ubi_cdev_operations;
+extern const struct file_operations ubi_vol_cdev_operations;
extern struct class *ubi_class;
extern struct mutex ubi_devices_mutex;
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index 8b89cc18ff0b..6b4d1ae891ae 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -40,7 +40,7 @@
#include <linux/err.h>
#include <linux/uaccess.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
/**
@@ -89,7 +89,6 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol,
long long bytes)
{
int err;
- uint64_t tmp;
struct ubi_vtbl_record vtbl_rec;
dbg_gen("clear update marker for volume %d", vol->vol_id);
@@ -101,9 +100,9 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol,
if (vol->vol_type == UBI_STATIC_VOLUME) {
vol->corrupted = 0;
- vol->used_bytes = tmp = bytes;
- vol->last_eb_bytes = do_div(tmp, vol->usable_leb_size);
- vol->used_ebs = tmp;
+ vol->used_bytes = bytes;
+ vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size,
+ &vol->last_eb_bytes);
if (vol->last_eb_bytes)
vol->used_ebs += 1;
else
@@ -131,7 +130,6 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
long long bytes)
{
int i, err;
- uint64_t tmp;
dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes);
ubi_assert(!vol->updating && !vol->changing_leb);
@@ -161,9 +159,8 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
if (!vol->upd_buf)
return -ENOMEM;
- tmp = bytes;
- vol->upd_ebs = !!do_div(tmp, vol->usable_leb_size);
- vol->upd_ebs += tmp;
+ vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1,
+ vol->usable_leb_size);
vol->upd_bytes = bytes;
vol->upd_received = 0;
return 0;
@@ -282,7 +279,6 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
const void __user *buf, int count)
{
- uint64_t tmp;
int lnum, offs, err = 0, len, to_write = count;
dbg_gen("write %d of %lld bytes, %lld already passed",
@@ -291,10 +287,7 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
if (ubi->ro_mode)
return -EROFS;
- tmp = vol->upd_received;
- offs = do_div(tmp, vol->usable_leb_size);
- lnum = tmp;
-
+ lnum = div_u64_rem(vol->upd_received, vol->usable_leb_size, &offs);
if (vol->upd_received + count > vol->upd_bytes)
to_write = count = vol->upd_bytes - vol->upd_received;
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 22e1d7398fce..df5483562b7a 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -24,7 +24,7 @@
*/
#include <linux/err.h>
-#include <asm/div64.h>
+#include <linux/math64.h>
#include "ubi.h"
#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
@@ -205,7 +205,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
int i, err, vol_id = req->vol_id, do_free = 1;
struct ubi_volume *vol;
struct ubi_vtbl_record vtbl_rec;
- uint64_t bytes;
dev_t dev;
if (ubi->ro_mode)
@@ -255,10 +254,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
/* Calculate how many eraseblocks are requested */
vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment;
- bytes = req->bytes;
- if (do_div(bytes, vol->usable_leb_size))
- vol->reserved_pebs = 1;
- vol->reserved_pebs += bytes;
+ vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1,
+ vol->usable_leb_size);
/* Reserve physical eraseblocks */
if (vol->reserved_pebs > ubi->avail_pebs) {
@@ -301,10 +298,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vol->used_bytes =
(long long)vol->used_ebs * vol->usable_leb_size;
} else {
- bytes = vol->used_bytes;
- vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size);
- vol->used_ebs = bytes;
- if (vol->last_eb_bytes)
+ vol->used_ebs = div_u64_rem(vol->used_bytes,
+ vol->usable_leb_size,
+ &vol->last_eb_bytes);
+ if (vol->last_eb_bytes != 0)
vol->used_ebs += 1;
else
vol->last_eb_bytes = vol->usable_leb_size;
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index 6124605bef05..a8107f992fb4 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -493,21 +493,27 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
}
/* read the data */
spin_lock_irqsave(&adapter->lock, flags);
- i = 0;
- do {
- j = 0;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000);
- pcb->data.raw[i++] = inb_command(dev->base_addr);
- if (i > MAX_PCB_DATA)
- INVALID_PCB_MSG(i);
- } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000);
+ for (i = 0; i < MAX_PCB_DATA; i++) {
+ for (j = 0; j < 20000; j++) {
+ stat = get_status(dev->base_addr);
+ if (stat & ACRF)
+ break;
+ }
+ pcb->data.raw[i] = inb_command(dev->base_addr);
+ if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000)
+ break;
+ }
spin_unlock_irqrestore(&adapter->lock, flags);
+ if (i >= MAX_PCB_DATA) {
+ INVALID_PCB_MSG(i);
+ return false;
+ }
if (j >= 20000) {
TIMEOUT_MSG(__LINE__);
return false;
}
- /* woops, the last "data" byte was really the length! */
- total_length = pcb->data.raw[--i];
+ /* the last "data" byte was really the length! */
+ total_length = pcb->data.raw[i];
/* safety check total length vs data length */
if (total_length != (pcb->length + 2)) {
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 535c234286ea..8c694213035b 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -1475,6 +1475,7 @@ el3_resume(struct device *pdev)
spin_lock_irqsave(&lp->lock, flags);
outw(PowerUp, ioaddr + EL3_CMD);
+ EL3WINDOW(0);
el3_up(dev);
if (netif_running(dev))
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9fe8cb7d43ac..a2f185fd7072 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1829,7 +1829,7 @@ config 68360_ENET
config FEC
bool "FEC ethernet controller (of ColdFire CPUs)"
- depends on M523x || M527x || M5272 || M528x || M520x
+ depends on M523x || M527x || M5272 || M528x || M520x || M532x
help
Say Y here if you want to use the built-in 10/100 Fast ethernet
controller on some Motorola ColdFire processors.
@@ -2342,6 +2342,17 @@ config ATL1E
To compile this driver as a module, choose M here. The module
will be called atl1e.
+config ATL1C
+ tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
+ depends on PCI && EXPERIMENTAL
+ select CRC32
+ select MII
+ help
+ This driver supports the Atheros L1C gigabit ethernet adapter.
+
+ To compile this driver as a module, choose M here. The module
+ will be called atl1c.
+
config JME
tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
depends on PCI
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index a3c5c002f224..aca8492db654 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_ATL2) += atlx/
obj-$(CONFIG_ATL1E) += atl1e/
+obj-$(CONFIG_ATL1C) += atl1c/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
obj-$(CONFIG_TEHUTI) += tehuti.o
obj-$(CONFIG_ENIC) += enic/
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile
index c69c0cdba4a2..811a3ccd14c1 100644
--- a/drivers/net/arm/Makefile
+++ b/drivers/net/arm/Makefile
@@ -4,7 +4,7 @@
#
obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
-obj-$(CONFIG_ARM_ETHERH) += etherh.o ../8390.o
+obj-$(CONFIG_ARM_ETHERH) += etherh.o
obj-$(CONFIG_ARM_ETHER3) += ether3.o
obj-$(CONFIG_ARM_ETHER1) += ether1.o
obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 0c628a9e5339..c2d012fcc29b 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -208,9 +208,9 @@ am79c961_init_for_open(struct net_device *dev)
/*
* Stop the chip.
*/
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */
write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */
@@ -332,10 +332,10 @@ am79c961_close(struct net_device *dev)
netif_stop_queue(dev);
netif_carrier_off(dev);
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_STOP);
write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
free_irq (dev->irq, dev);
@@ -391,7 +391,7 @@ static void am79c961_setmulticastlist (struct net_device *dev)
am79c961_mc_hash(dmi, multi_hash);
}
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
@@ -405,9 +405,9 @@ static void am79c961_setmulticastlist (struct net_device *dev)
* Spin waiting for chip to report suspend mode
*/
while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
nop();
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
}
}
@@ -429,7 +429,7 @@ static void am79c961_setmulticastlist (struct net_device *dev)
write_rreg(dev->base_addr, CTRL1, 0);
}
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
}
static void am79c961_timeout(struct net_device *dev)
@@ -467,10 +467,10 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
priv->txhead = head;
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
dev->trans_start = jiffies;
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
/*
* If the next packet is owned by the ethernet device,
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index d15d8b79d8e5..f52f668c49bf 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -641,15 +641,15 @@ static const struct net_device_ops etherh_netdev_ops = {
.ndo_open = etherh_open,
.ndo_stop = etherh_close,
.ndo_set_config = etherh_set_config,
- .ndo_start_xmit = ei_start_xmit,
- .ndo_tx_timeout = ei_tx_timeout,
- .ndo_get_stats = ei_get_stats,
- .ndo_set_multicast_list = ei_set_multicast_list,
+ .ndo_start_xmit = __ei_start_xmit,
+ .ndo_tx_timeout = __ei_tx_timeout,
+ .ndo_get_stats = __ei_get_stats,
+ .ndo_set_multicast_list = __ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_set_mac_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ei_poll,
+ .ndo_poll_controller = __ei_poll,
#endif
};
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 1cf2f949c0b4..b39210cf4fb3 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -1059,7 +1059,7 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
{
strlcpy(info->driver, MODULENAME, sizeof(info->driver));
strlcpy(info->version, MODULEVERSION, sizeof(info->version));
- strlcpy(info->bus_info, ndev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(ndev->dev.parent),
sizeof(info->bus_info));
}
diff --git a/drivers/net/atl1c/Makefile b/drivers/net/atl1c/Makefile
new file mode 100644
index 000000000000..c37d966952ee
--- /dev/null
+++ b/drivers/net/atl1c/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ATL1C) += atl1c.o
+atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
new file mode 100644
index 000000000000..ac11b84b8377
--- /dev/null
+++ b/drivers/net/atl1c/atl1c.h
@@ -0,0 +1,606 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. 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.
+ */
+
+#ifndef _ATL1C_H_
+#define _ATL1C_H_
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/mii.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/tcp.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/workqueue.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include "atl1c_hw.h"
+
+/* Wake Up Filter Control */
+#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
+#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
+#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
+#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
+
+#define AT_VLAN_TO_TAG(_vlan, _tag) \
+ _tag = ((((_vlan) >> 8) & 0xFF) |\
+ (((_vlan) & 0xFF) << 8))
+
+#define AT_TAG_TO_VLAN(_tag, _vlan) \
+ _vlan = ((((_tag) >> 8) & 0xFF) |\
+ (((_tag) & 0xFF) << 8))
+
+#define SPEED_0 0xffff
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+#define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)
+#define MAX_JUMBO_FRAME_SIZE (9*1024)
+#define MAX_TX_OFFLOAD_THRESH (9*1024)
+
+#define AT_MAX_RECEIVE_QUEUE 4
+#define AT_DEF_RECEIVE_QUEUE 1
+#define AT_MAX_TRANSMIT_QUEUE 2
+
+#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL
+#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL
+
+#define AT_TX_WATCHDOG (5 * HZ)
+#define AT_MAX_INT_WORK 5
+#define AT_TWSI_EEPROM_TIMEOUT 100
+#define AT_HW_MAX_IDLE_DELAY 10
+#define AT_SUSPEND_LINK_TIMEOUT 28
+
+#define AT_ASPM_L0S_TIMER 6
+#define AT_ASPM_L1_TIMER 12
+
+#define ATL1C_PCIE_L0S_L1_DISABLE 0x01
+#define ATL1C_PCIE_PHY_RESET 0x02
+
+#define ATL1C_ASPM_L0s_ENABLE 0x0001
+#define ATL1C_ASPM_L1_ENABLE 0x0002
+
+#define AT_REGS_LEN (75 * sizeof(u32))
+#define AT_EEPROM_LEN 512
+
+#define ATL1C_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
+#define ATL1C_RFD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc)
+#define ATL1C_TPD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc)
+#define ATL1C_RRD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status)
+
+/* tpd word 1 bit 0:7 General Checksum task offload */
+#define TPD_L4HDR_OFFSET_MASK 0x00FF
+#define TPD_L4HDR_OFFSET_SHIFT 0
+
+/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */
+#define TPD_TCPHDR_OFFSET_MASK 0x00FF
+#define TPD_TCPHDR_OFFSET_SHIFT 0
+
+/* tpd word 1 bit 0:7 Custom Checksum task offload */
+#define TPD_PLOADOFFSET_MASK 0x00FF
+#define TPD_PLOADOFFSET_SHIFT 0
+
+/* tpd word 1 bit 8:17 */
+#define TPD_CCSUM_EN_MASK 0x0001
+#define TPD_CCSUM_EN_SHIFT 8
+#define TPD_IP_CSUM_MASK 0x0001
+#define TPD_IP_CSUM_SHIFT 9
+#define TPD_TCP_CSUM_MASK 0x0001
+#define TPD_TCP_CSUM_SHIFT 10
+#define TPD_UDP_CSUM_MASK 0x0001
+#define TPD_UDP_CSUM_SHIFT 11
+#define TPD_LSO_EN_MASK 0x0001 /* TCP Large Send Offload */
+#define TPD_LSO_EN_SHIFT 12
+#define TPD_LSO_VER_MASK 0x0001
+#define TPD_LSO_VER_SHIFT 13 /* 0 : ipv4; 1 : ipv4/ipv6 */
+#define TPD_CON_VTAG_MASK 0x0001
+#define TPD_CON_VTAG_SHIFT 14
+#define TPD_INS_VTAG_MASK 0x0001
+#define TPD_INS_VTAG_SHIFT 15
+#define TPD_IPV4_PACKET_MASK 0x0001 /* valid when LSO VER is 1 */
+#define TPD_IPV4_PACKET_SHIFT 16
+#define TPD_ETH_TYPE_MASK 0x0001
+#define TPD_ETH_TYPE_SHIFT 17 /* 0 : 802.3 frame; 1 : Ethernet */
+
+/* tpd word 18:25 Custom Checksum task offload */
+#define TPD_CCSUM_OFFSET_MASK 0x00FF
+#define TPD_CCSUM_OFFSET_SHIFT 18
+#define TPD_CCSUM_EPAD_MASK 0x0001
+#define TPD_CCSUM_EPAD_SHIFT 30
+
+/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */
+#define TPD_MSS_MASK 0x1FFF
+#define TPD_MSS_SHIFT 18
+
+#define TPD_EOP_MASK 0x0001
+#define TPD_EOP_SHIFT 31
+
+struct atl1c_tpd_desc {
+ __le16 buffer_len; /* include 4-byte CRC */
+ __le16 vlan_tag;
+ __le32 word1;
+ __le64 buffer_addr;
+};
+
+struct atl1c_tpd_ext_desc {
+ u32 reservd_0;
+ __le32 word1;
+ __le32 pkt_len;
+ u32 reservd_1;
+};
+/* rrs word 0 bit 0:31 */
+#define RRS_RX_CSUM_MASK 0xFFFF
+#define RRS_RX_CSUM_SHIFT 0
+#define RRS_RX_RFD_CNT_MASK 0x000F
+#define RRS_RX_RFD_CNT_SHIFT 16
+#define RRS_RX_RFD_INDEX_MASK 0x0FFF
+#define RRS_RX_RFD_INDEX_SHIFT 20
+
+/* rrs flag bit 0:16 */
+#define RRS_HEAD_LEN_MASK 0x00FF
+#define RRS_HEAD_LEN_SHIFT 0
+#define RRS_HDS_TYPE_MASK 0x0003
+#define RRS_HDS_TYPE_SHIFT 8
+#define RRS_CPU_NUM_MASK 0x0003
+#define RRS_CPU_NUM_SHIFT 10
+#define RRS_HASH_FLG_MASK 0x000F
+#define RRS_HASH_FLG_SHIFT 12
+
+#define RRS_HDS_TYPE_HEAD 1
+#define RRS_HDS_TYPE_DATA 2
+
+#define RRS_IS_NO_HDS_TYPE(flag) \
+ (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0)
+
+#define RRS_IS_HDS_HEAD(flag) \
+ (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+ RRS_HDS_TYPE_HEAD)
+
+#define RRS_IS_HDS_DATA(flag) \
+ (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+ RRS_HDS_TYPE_DATA)
+
+/* rrs word 3 bit 0:31 */
+#define RRS_PKT_SIZE_MASK 0x3FFF
+#define RRS_PKT_SIZE_SHIFT 0
+#define RRS_ERR_L4_CSUM_MASK 0x0001
+#define RRS_ERR_L4_CSUM_SHIFT 14
+#define RRS_ERR_IP_CSUM_MASK 0x0001
+#define RRS_ERR_IP_CSUM_SHIFT 15
+#define RRS_VLAN_INS_MASK 0x0001
+#define RRS_VLAN_INS_SHIFT 16
+#define RRS_PROT_ID_MASK 0x0007
+#define RRS_PROT_ID_SHIFT 17
+#define RRS_RX_ERR_SUM_MASK 0x0001
+#define RRS_RX_ERR_SUM_SHIFT 20
+#define RRS_RX_ERR_CRC_MASK 0x0001
+#define RRS_RX_ERR_CRC_SHIFT 21
+#define RRS_RX_ERR_FAE_MASK 0x0001
+#define RRS_RX_ERR_FAE_SHIFT 22
+#define RRS_RX_ERR_TRUNC_MASK 0x0001
+#define RRS_RX_ERR_TRUNC_SHIFT 23
+#define RRS_RX_ERR_RUNC_MASK 0x0001
+#define RRS_RX_ERR_RUNC_SHIFT 24
+#define RRS_RX_ERR_ICMP_MASK 0x0001
+#define RRS_RX_ERR_ICMP_SHIFT 25
+#define RRS_PACKET_BCAST_MASK 0x0001
+#define RRS_PACKET_BCAST_SHIFT 26
+#define RRS_PACKET_MCAST_MASK 0x0001
+#define RRS_PACKET_MCAST_SHIFT 27
+#define RRS_PACKET_TYPE_MASK 0x0001
+#define RRS_PACKET_TYPE_SHIFT 28
+#define RRS_FIFO_FULL_MASK 0x0001
+#define RRS_FIFO_FULL_SHIFT 29
+#define RRS_802_3_LEN_ERR_MASK 0x0001
+#define RRS_802_3_LEN_ERR_SHIFT 30
+#define RRS_RXD_UPDATED_MASK 0x0001
+#define RRS_RXD_UPDATED_SHIFT 31
+
+#define RRS_ERR_L4_CSUM 0x00004000
+#define RRS_ERR_IP_CSUM 0x00008000
+#define RRS_VLAN_INS 0x00010000
+#define RRS_RX_ERR_SUM 0x00100000
+#define RRS_RX_ERR_CRC 0x00200000
+#define RRS_802_3_LEN_ERR 0x40000000
+#define RRS_RXD_UPDATED 0x80000000
+
+#define RRS_PACKET_TYPE_802_3 1
+#define RRS_PACKET_TYPE_ETH 0
+#define RRS_PACKET_IS_ETH(word) \
+ (((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \
+ RRS_PACKET_TYPE_ETH)
+#define RRS_RXD_IS_VALID(word) \
+ ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
+
+#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \
+ ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1)
+#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \
+ ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6)
+
+struct atl1c_recv_ret_status {
+ __le32 word0;
+ __le32 rss_hash;
+ __le16 vlan_tag;
+ __le16 flag;
+ __le32 word3;
+};
+
+/* RFD desciptor */
+struct atl1c_rx_free_desc {
+ __le64 buffer_addr;
+};
+
+/* DMA Order Settings */
+enum atl1c_dma_order {
+ atl1c_dma_ord_in = 1,
+ atl1c_dma_ord_enh = 2,
+ atl1c_dma_ord_out = 4
+};
+
+enum atl1c_dma_rcb {
+ atl1c_rcb_64 = 0,
+ atl1c_rcb_128 = 1
+};
+
+enum atl1c_mac_speed {
+ atl1c_mac_speed_0 = 0,
+ atl1c_mac_speed_10_100 = 1,
+ atl1c_mac_speed_1000 = 2
+};
+
+enum atl1c_dma_req_block {
+ atl1c_dma_req_128 = 0,
+ atl1c_dma_req_256 = 1,
+ atl1c_dma_req_512 = 2,
+ atl1c_dma_req_1024 = 3,
+ atl1c_dma_req_2048 = 4,
+ atl1c_dma_req_4096 = 5
+};
+
+enum atl1c_rss_mode {
+ atl1c_rss_mode_disable = 0,
+ atl1c_rss_sig_que = 1,
+ atl1c_rss_mul_que_sig_int = 2,
+ atl1c_rss_mul_que_mul_int = 4,
+};
+
+enum atl1c_rss_type {
+ atl1c_rss_disable = 0,
+ atl1c_rss_ipv4 = 1,
+ atl1c_rss_ipv4_tcp = 2,
+ atl1c_rss_ipv6 = 4,
+ atl1c_rss_ipv6_tcp = 8
+};
+
+enum atl1c_nic_type {
+ athr_l1c = 0,
+ athr_l2c = 1,
+};
+
+enum atl1c_trans_queue {
+ atl1c_trans_normal = 0,
+ atl1c_trans_high = 1
+};
+
+struct atl1c_hw_stats {
+ /* rx */
+ unsigned long rx_ok; /* The number of good packet received. */
+ unsigned long rx_bcast; /* The number of good broadcast packet received. */
+ unsigned long rx_mcast; /* The number of good multicast packet received. */
+ unsigned long rx_pause; /* The number of Pause packet received. */
+ unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */
+ unsigned long rx_fcs_err; /* The number of packets with bad FCS. */
+ unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */
+ unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */
+ unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */
+ unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */
+ unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */
+ unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */
+ unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */
+ unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */
+ unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
+ unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
+ unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
+ unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
+ unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */
+ unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */
+ unsigned long rx_align_err; /* Alignment Error */
+ unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
+ unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
+ unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */
+
+ /* tx */
+ unsigned long tx_ok; /* The number of good packet transmitted. */
+ unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */
+ unsigned long tx_mcast; /* The number of good multicast packet transmitted. */
+ unsigned long tx_pause; /* The number of Pause packet transmitted. */
+ unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */
+ unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */
+ unsigned long tx_defer; /* The number of packets transmitted that is deferred. */
+ unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */
+ unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */
+ unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
+ unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
+ unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
+ unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
+ unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
+ unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
+ unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */
+ unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
+ unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */
+ unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */
+ unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
+ unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
+ unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */
+ unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */
+ unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */
+ unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */
+};
+
+struct atl1c_hw {
+ u8 __iomem *hw_addr; /* inner register address */
+ struct atl1c_adapter *adapter;
+ enum atl1c_nic_type nic_type;
+ enum atl1c_dma_order dma_order;
+ enum atl1c_dma_rcb rcb_value;
+ enum atl1c_dma_req_block dmar_block;
+ enum atl1c_dma_req_block dmaw_block;
+
+ u16 device_id;
+ u16 vendor_id;
+ u16 subsystem_id;
+ u16 subsystem_vendor_id;
+ u8 revision_id;
+
+ u32 intr_mask;
+ u8 dmaw_dly_cnt;
+ u8 dmar_dly_cnt;
+
+ u8 preamble_len;
+ u16 max_frame_size;
+ u16 min_frame_size;
+
+ enum atl1c_mac_speed mac_speed;
+ bool mac_duplex;
+ bool hibernate;
+ u16 media_type;
+#define MEDIA_TYPE_AUTO_SENSOR 0
+#define MEDIA_TYPE_100M_FULL 1
+#define MEDIA_TYPE_100M_HALF 2
+#define MEDIA_TYPE_10M_FULL 3
+#define MEDIA_TYPE_10M_HALF 4
+
+ u16 autoneg_advertised;
+ u16 mii_autoneg_adv_reg;
+ u16 mii_1000t_ctrl_reg;
+
+ u16 tx_imt; /* TX Interrupt Moderator timer ( 2us resolution) */
+ u16 rx_imt; /* RX Interrupt Moderator timer ( 2us resolution) */
+ u16 ict; /* Interrupt Clear timer (2us resolution) */
+ u16 ctrl_flags;
+#define ATL1C_INTR_CLEAR_ON_READ 0x0001
+#define ATL1C_INTR_MODRT_ENABLE 0x0002
+#define ATL1C_CMB_ENABLE 0x0004
+#define ATL1C_SMB_ENABLE 0x0010
+#define ATL1C_TXQ_MODE_ENHANCE 0x0020
+#define ATL1C_RX_IPV6_CHKSUM 0x0040
+#define ATL1C_ASPM_L0S_SUPPORT 0x0080
+#define ATL1C_ASPM_L1_SUPPORT 0x0100
+#define ATL1C_ASPM_CTRL_MON 0x0200
+#define ATL1C_HIB_DISABLE 0x0400
+#define ATL1C_LINK_CAP_1000M 0x0800
+#define ATL1C_FPGA_VERSION 0x8000
+ u16 cmb_tpd;
+ u16 cmb_rrd;
+ u16 cmb_rx_timer; /* 2us resolution */
+ u16 cmb_tx_timer;
+ u32 smb_timer;
+
+ u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
+ interrupt request */
+ u16 tpd_thresh;
+ u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */
+ u8 rfd_burst;
+ enum atl1c_rss_type rss_type;
+ enum atl1c_rss_mode rss_mode;
+ u8 rss_hash_bits;
+ u32 base_cpu;
+ u32 indirect_tab;
+ u8 mac_addr[ETH_ALEN];
+ u8 perm_mac_addr[ETH_ALEN];
+
+ bool phy_configured;
+ bool re_autoneg;
+ bool emi_ca;
+};
+
+/*
+ * atl1c_ring_header represents a single, contiguous block of DMA space
+ * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
+ * message blocks (cmb, smb) described below
+ */
+struct atl1c_ring_header {
+ void *desc; /* virtual address */
+ dma_addr_t dma; /* physical address*/
+ unsigned int size; /* length in bytes */
+};
+
+/*
+ * atl1c_buffer is wrapper around a pointer to a socket buffer
+ * so a DMA handle can be stored along with the skb
+ */
+struct atl1c_buffer {
+ struct sk_buff *skb; /* socket buffer */
+ u16 length; /* rx buffer length */
+ u16 state; /* state of buffer */
+#define ATL1_BUFFER_FREE 0
+#define ATL1_BUFFER_BUSY 1
+ dma_addr_t dma;
+};
+
+/* transimit packet descriptor (tpd) ring */
+struct atl1c_tpd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use; /* this is protectd by adapter->tx_lock */
+ atomic_t next_to_clean;
+ struct atl1c_buffer *buffer_info;
+};
+
+/* receive free descriptor (rfd) ring */
+struct atl1c_rfd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use;
+ u16 next_to_clean;
+ struct atl1c_buffer *buffer_info;
+};
+
+/* receive return desciptor (rrd) ring */
+struct atl1c_rrd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use;
+ u16 next_to_clean;
+};
+
+struct atl1c_cmb {
+ void *cmb;
+ dma_addr_t dma;
+};
+
+struct atl1c_smb {
+ void *smb;
+ dma_addr_t dma;
+};
+
+/* board specific private data structure */
+struct atl1c_adapter {
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+ struct vlan_group *vlgrp;
+ struct napi_struct napi;
+ struct atl1c_hw hw;
+ struct atl1c_hw_stats hw_stats;
+ struct net_device_stats net_stats;
+ struct mii_if_info mii; /* MII interface info */
+ u16 rx_buffer_len;
+
+ unsigned long flags;
+#define __AT_TESTING 0x0001
+#define __AT_RESETTING 0x0002
+#define __AT_DOWN 0x0003
+ u32 msg_enable;
+
+ bool have_msi;
+ u32 wol;
+ u16 link_speed;
+ u16 link_duplex;
+
+ spinlock_t mdio_lock;
+ spinlock_t tx_lock;
+ atomic_t irq_sem;
+
+ struct work_struct reset_task;
+ struct work_struct link_chg_task;
+ struct timer_list watchdog_timer;
+ struct timer_list phy_config_timer;
+
+ /* All Descriptor memory */
+ struct atl1c_ring_header ring_header;
+ struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE];
+ struct atl1c_rfd_ring rfd_ring[AT_MAX_RECEIVE_QUEUE];
+ struct atl1c_rrd_ring rrd_ring[AT_MAX_RECEIVE_QUEUE];
+ struct atl1c_cmb cmb;
+ struct atl1c_smb smb;
+ int num_rx_queues;
+ u32 bd_number; /* board number;*/
+};
+
+#define AT_WRITE_REG(a, reg, value) ( \
+ writel((value), ((a)->hw_addr + reg)))
+
+#define AT_WRITE_FLUSH(a) (\
+ readl((a)->hw_addr))
+
+#define AT_READ_REG(a, reg, pdata) do { \
+ if (unlikely((a)->hibernate)) { \
+ readl((a)->hw_addr + reg); \
+ *(u32 *)pdata = readl((a)->hw_addr + reg); \
+ } else { \
+ *(u32 *)pdata = readl((a)->hw_addr + reg); \
+ } \
+ } while (0)
+
+#define AT_WRITE_REGB(a, reg, value) (\
+ writeb((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGB(a, reg) (\
+ readb((a)->hw_addr + reg))
+
+#define AT_WRITE_REGW(a, reg, value) (\
+ writew((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGW(a, reg) (\
+ readw((a)->hw_addr + reg))
+
+#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+ writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
+
+#define AT_READ_REG_ARRAY(a, reg, offset) ( \
+ readl(((a)->hw_addr + reg) + ((offset) << 2)))
+
+extern char atl1c_driver_name[];
+extern char atl1c_driver_version[];
+
+extern int atl1c_up(struct atl1c_adapter *adapter);
+extern void atl1c_down(struct atl1c_adapter *adapter);
+extern void atl1c_reinit_locked(struct atl1c_adapter *adapter);
+extern s32 atl1c_reset_hw(struct atl1c_hw *hw);
+extern void atl1c_set_ethtool_ops(struct net_device *netdev);
+#endif /* _ATL1C_H_ */
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
new file mode 100644
index 000000000000..45c5b7332cd3
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. 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.
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+
+#include "atl1c.h"
+
+static int atl1c_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+
+ ecmd->supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_TP);
+ if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M)
+ ecmd->supported |= SUPPORTED_1000baseT_Full;
+
+ ecmd->advertising = ADVERTISED_TP;
+
+ ecmd->advertising |= hw->autoneg_advertised;
+
+ ecmd->port = PORT_TP;
+ ecmd->phy_address = 0;
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (adapter->link_speed != SPEED_0) {
+ ecmd->speed = adapter->link_speed;
+ if (adapter->link_duplex == FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+ } else {
+ ecmd->speed = -1;
+ ecmd->duplex = -1;
+ }
+
+ ecmd->autoneg = AUTONEG_ENABLE;
+ return 0;
+}
+
+static int atl1c_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u16 autoneg_advertised;
+
+ while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+ msleep(1);
+
+ if (ecmd->autoneg == AUTONEG_ENABLE) {
+ autoneg_advertised = ADVERTISED_Autoneg;
+ } else {
+ if (ecmd->speed == SPEED_1000) {
+ if (ecmd->duplex != DUPLEX_FULL) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev,
+ "1000M half is invalid\n");
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+ autoneg_advertised = ADVERTISED_1000baseT_Full;
+ } else if (ecmd->speed == SPEED_100) {
+ if (ecmd->duplex == DUPLEX_FULL)
+ autoneg_advertised = ADVERTISED_100baseT_Full;
+ else
+ autoneg_advertised = ADVERTISED_100baseT_Half;
+ } else {
+ if (ecmd->duplex == DUPLEX_FULL)
+ autoneg_advertised = ADVERTISED_10baseT_Full;
+ else
+ autoneg_advertised = ADVERTISED_10baseT_Half;
+ }
+ }
+
+ if (hw->autoneg_advertised != autoneg_advertised) {
+ hw->autoneg_advertised = autoneg_advertised;
+ if (atl1c_restart_autoneg(hw) != 0) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev,
+ "ethtool speed/duplex setting failed\n");
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+ }
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return 0;
+}
+
+static u32 atl1c_get_tx_csum(struct net_device *netdev)
+{
+ return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static u32 atl1c_get_msglevel(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ return adapter->msg_enable;
+}
+
+static void atl1c_set_msglevel(struct net_device *netdev, u32 data)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ adapter->msg_enable = data;
+}
+
+static int atl1c_get_regs_len(struct net_device *netdev)
+{
+ return AT_REGS_LEN;
+}
+
+static void atl1c_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 *regs_buff = p;
+ u16 phy_data;
+
+ memset(p, 0, AT_REGS_LEN);
+
+ regs->version = 0;
+ AT_READ_REG(hw, REG_VPD_CAP, p++);
+ AT_READ_REG(hw, REG_PM_CTRL, p++);
+ AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++);
+ AT_READ_REG(hw, REG_TWSI_CTRL, p++);
+ AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++);
+ AT_READ_REG(hw, REG_MASTER_CTRL, p++);
+ AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++);
+ AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++);
+ AT_READ_REG(hw, REG_GPHY_CTRL, p++);
+ AT_READ_REG(hw, REG_LINK_CTRL, p++);
+ AT_READ_REG(hw, REG_IDLE_STATUS, p++);
+ AT_READ_REG(hw, REG_MDIO_CTRL, p++);
+ AT_READ_REG(hw, REG_SERDES_LOCK, p++);
+ AT_READ_REG(hw, REG_MAC_CTRL, p++);
+ AT_READ_REG(hw, REG_MAC_IPG_IFG, p++);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR, p++);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++);
+ AT_READ_REG(hw, REG_RX_HASH_TABLE, p++);
+ AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++);
+ AT_READ_REG(hw, REG_RXQ_CTRL, p++);
+ AT_READ_REG(hw, REG_TXQ_CTRL, p++);
+ AT_READ_REG(hw, REG_MTU, p++);
+ AT_READ_REG(hw, REG_WOL_CTRL, p++);
+
+ atl1c_read_phy_reg(hw, MII_BMCR, &phy_data);
+ regs_buff[73] = (u32) phy_data;
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ regs_buff[74] = (u32) phy_data;
+}
+
+static int atl1c_get_eeprom_len(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (atl1c_check_eeprom_exist(&adapter->hw))
+ return AT_EEPROM_LEN;
+ else
+ return 0;
+}
+
+static int atl1c_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 *eeprom_buff;
+ int first_dword, last_dword;
+ int ret_val = 0;
+ int i;
+
+ if (eeprom->len == 0)
+ return -EINVAL;
+
+ if (!atl1c_check_eeprom_exist(hw)) /* not exist */
+ return -EINVAL;
+
+ eeprom->magic = adapter->pdev->vendor |
+ (adapter->pdev->device << 16);
+
+ first_dword = eeprom->offset >> 2;
+ last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+ eeprom_buff = kmalloc(sizeof(u32) *
+ (last_dword - first_dword + 1), GFP_KERNEL);
+ if (eeprom_buff == NULL)
+ return -ENOMEM;
+
+ for (i = first_dword; i < last_dword; i++) {
+ if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
+ kfree(eeprom_buff);
+ return -EIO;
+ }
+ }
+
+ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+ eeprom->len);
+ kfree(eeprom_buff);
+
+ return ret_val;
+ return 0;
+}
+
+static void atl1c_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ strncpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver));
+ strncpy(drvinfo->version, atl1c_driver_version,
+ sizeof(drvinfo->version));
+ strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+ strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
+ drvinfo->n_stats = 0;
+ drvinfo->testinfo_len = 0;
+ drvinfo->regdump_len = atl1c_get_regs_len(netdev);
+ drvinfo->eedump_len = atl1c_get_eeprom_len(netdev);
+}
+
+static void atl1c_get_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_MAGIC | WAKE_PHY;
+ wol->wolopts = 0;
+
+ if (adapter->wol & AT_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if (adapter->wol & AT_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if (adapter->wol & AT_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if (adapter->wol & AT_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+ if (adapter->wol & AT_WUFC_LNKC)
+ wol->wolopts |= WAKE_PHY;
+
+ return;
+}
+
+static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
+ WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+ return -EOPNOTSUPP;
+ /* these settings will always override what we currently have */
+ adapter->wol = 0;
+
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= AT_WUFC_MAG;
+ if (wol->wolopts & WAKE_PHY)
+ adapter->wol |= AT_WUFC_LNKC;
+
+ return 0;
+}
+
+static int atl1c_nway_reset(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ if (netif_running(netdev))
+ atl1c_reinit_locked(adapter);
+ return 0;
+}
+
+static struct ethtool_ops atl1c_ethtool_ops = {
+ .get_settings = atl1c_get_settings,
+ .set_settings = atl1c_set_settings,
+ .get_drvinfo = atl1c_get_drvinfo,
+ .get_regs_len = atl1c_get_regs_len,
+ .get_regs = atl1c_get_regs,
+ .get_wol = atl1c_get_wol,
+ .set_wol = atl1c_set_wol,
+ .get_msglevel = atl1c_get_msglevel,
+ .set_msglevel = atl1c_set_msglevel,
+ .nway_reset = atl1c_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = atl1c_get_eeprom_len,
+ .get_eeprom = atl1c_get_eeprom,
+ .get_tx_csum = atl1c_get_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+};
+
+void atl1c_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops);
+}
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c
new file mode 100644
index 000000000000..3e69b940b8f7
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_hw.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. 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.
+ */
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+
+#include "atl1c.h"
+
+/*
+ * check_eeprom_exist
+ * return 1 if eeprom exist
+ */
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
+ if (data & TWSI_DEBUG_DEV_EXIST)
+ return 1;
+
+ return 0;
+}
+
+void atl1c_hw_set_mac_addr(struct atl1c_hw *hw)
+{
+ u32 value;
+ /*
+ * 00-0B-6A-F6-00-DC
+ * 0: 6AF600DC 1: 000B
+ * low dword
+ */
+ value = (((u32)hw->mac_addr[2]) << 24) |
+ (((u32)hw->mac_addr[3]) << 16) |
+ (((u32)hw->mac_addr[4]) << 8) |
+ (((u32)hw->mac_addr[5])) ;
+ AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+ /* hight dword */
+ value = (((u32)hw->mac_addr[0]) << 8) |
+ (((u32)hw->mac_addr[1])) ;
+ AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/*
+ * atl1c_get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int atl1c_get_permanent_address(struct atl1c_hw *hw)
+{
+ u32 addr[2];
+ u32 i;
+ u32 otp_ctrl_data;
+ u32 twsi_ctrl_data;
+ u8 eth_addr[ETH_ALEN];
+
+ /* init */
+ addr[0] = addr[1] = 0;
+ AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+ if (atl1c_check_eeprom_exist(hw)) {
+ /* Enable OTP CLK */
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
+ otp_ctrl_data |= OTP_CTRL_CLK_EN;
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(1);
+ }
+
+ AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+ twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
+ AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
+ for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
+ msleep(10);
+ AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+ if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
+ break;
+ }
+ if (i >= AT_TWSI_EEPROM_TIMEOUT)
+ return -1;
+ }
+ /* Disable OTP_CLK */
+ if (otp_ctrl_data & OTP_CTRL_CLK_EN) {
+ otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(1);
+ }
+
+ /* maybe MAC-address is from BIOS */
+ AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
+ *(u32 *) &eth_addr[2] = swab32(addr[0]);
+ *(u16 *) &eth_addr[0] = swab16(*(u16 *)&addr[1]);
+
+ if (is_valid_ether_addr(eth_addr)) {
+ memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+ return 0;
+ }
+
+ return -1;
+}
+
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
+{
+ int i;
+ int ret = false;
+ u32 otp_ctrl_data;
+ u32 control;
+ u32 data;
+
+ if (offset & 3)
+ return ret; /* address do not align */
+
+ AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+ AT_WRITE_REG(hw, REG_OTP_CTRL,
+ (otp_ctrl_data | OTP_CTRL_CLK_EN));
+
+ AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
+ control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
+ AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
+
+ for (i = 0; i < 10; i++) {
+ udelay(100);
+ AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
+ if (control & EEPROM_CTRL_RW)
+ break;
+ }
+ if (control & EEPROM_CTRL_RW) {
+ AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
+ AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
+ data = data & 0xFFFF;
+ *p_value = swab32((data << 16) | (*p_value >> 16));
+ ret = true;
+ }
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+
+ return ret;
+}
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+int atl1c_read_mac_addr(struct atl1c_hw *hw)
+{
+ int err = 0;
+
+ err = atl1c_get_permanent_address(hw);
+ if (err)
+ random_ether_addr(hw->perm_mac_addr);
+
+ memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
+ return 0;
+}
+
+/*
+ * atl1c_hash_mc_addr
+ * purpose
+ * set hash value for a multicast address
+ * hash calcu processing :
+ * 1. calcu 32bit CRC for multicast address
+ * 2. reverse crc with MSB to LSB
+ */
+u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
+{
+ u32 crc32;
+ u32 value = 0;
+ int i;
+
+ crc32 = ether_crc_le(6, mc_addr);
+ for (i = 0; i < 32; i++)
+ value |= (((crc32 >> i) & 1) << (31 - i));
+
+ return value;
+}
+
+/*
+ * Sets the bit in the multicast table corresponding to the hash value.
+ * hw - Struct containing variables accessed by shared code
+ * hash_value - Multicast address hash value
+ */
+void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
+{
+ u32 hash_bit, hash_reg;
+ u32 mta;
+
+ /*
+ * The HASH Table is a register array of 2 32-bit registers.
+ * It is treated like an array of 64 bits. We want to set
+ * bit BitArray[hash_value]. So we figure out what register
+ * the bit is in, read it, OR in the new bit, then write
+ * back the new value. The register is determined by the
+ * upper bit of the hash value and the bit within that
+ * register are determined by the lower 5 bits of the value.
+ */
+ hash_reg = (hash_value >> 31) & 0x1;
+ hash_bit = (hash_value >> 26) & 0x1F;
+
+ mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+ mta |= (1 << hash_bit);
+
+ AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+ u32 val;
+ int i;
+
+ val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
+ MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW |
+ MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+ udelay(2);
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ break;
+ }
+ if (!(val & (MDIO_START | MDIO_BUSY))) {
+ *phy_data = (u16)val;
+ return 0;
+ }
+
+ return -1;
+}
+
+/*
+ * Writes a value to a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to write
+ * data - data to write to the PHY
+ */
+int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
+{
+ int i;
+ u32 val;
+
+ val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
+ (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
+ MDIO_SUP_PREAMBLE | MDIO_START |
+ MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+ udelay(2);
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ break;
+ }
+
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ return 0;
+
+ return -1;
+}
+
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
+{
+ u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_SPEED_MASK;
+ u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
+ ~GIGA_CR_1000T_SPEED_MASK;
+
+ if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
+ mii_adv_data |= ADVERTISE_10HALF;
+ if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
+ mii_adv_data |= ADVERTISE_10FULL;
+ if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
+ mii_adv_data |= ADVERTISE_100HALF;
+ if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
+ mii_adv_data |= ADVERTISE_100FULL;
+
+ if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+ mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL;
+
+ if (hw->ctrl_flags & ATL1C_LINK_CAP_1000M) {
+ if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
+ mii_giga_ctrl_data |= ADVERTISE_1000HALF;
+ if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
+ mii_giga_ctrl_data |= ADVERTISE_1000FULL;
+ if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+ mii_giga_ctrl_data |= ADVERTISE_1000HALF |
+ ADVERTISE_1000FULL;
+ }
+
+ if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
+ atl1c_write_phy_reg(hw, MII_GIGA_CR, mii_giga_ctrl_data) != 0)
+ return -1;
+ return 0;
+}
+
+void atl1c_phy_disable(struct atl1c_hw *hw)
+{
+ AT_WRITE_REGW(hw, REG_GPHY_CTRL,
+ GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
+}
+
+static void atl1c_phy_magic_data(struct atl1c_hw *hw)
+{
+ u16 data;
+
+ data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
+ ((1 & ANA_INTERVAL_SEL_TIMER_MASK) <<
+ ANA_INTERVAL_SEL_TIMER_SHIFT);
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_18);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = (2 & ANA_SERDES_CDR_BW_MASK) | ANA_MS_PAD_DBG |
+ ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | ANA_SERDES_EN_PLL |
+ ANA_SERDES_EN_LCKDT;
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_5);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = (44 & ANA_LONG_CABLE_TH_100_MASK) |
+ ((33 & ANA_SHORT_CABLE_TH_100_MASK) <<
+ ANA_SHORT_CABLE_TH_100_SHIFT) | ANA_BP_BAD_LINK_ACCUM |
+ ANA_BP_SMALL_BW;
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_54);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = (11 & ANA_IECHO_ADJ_MASK) | ((11 & ANA_IECHO_ADJ_MASK) <<
+ ANA_IECHO_ADJ_2_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
+ ANA_IECHO_ADJ_1_SHIFT) | ((8 & ANA_IECHO_ADJ_MASK) <<
+ ANA_IECHO_ADJ_0_SHIFT);
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_4);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ data = ANA_RESTART_CAL | ((7 & ANA_MANUL_SWICH_ON_MASK) <<
+ ANA_MANUL_SWICH_ON_SHIFT) | ANA_MAN_ENABLE |
+ ANA_SEL_HSP | ANA_EN_HB | ANA_OEN_125M;
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_0);
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ if (hw->ctrl_flags & ATL1C_HIB_DISABLE) {
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_41);
+ if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
+ return;
+ data &= ~ANA_TOP_PS_EN;
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+
+ atl1c_write_phy_reg(hw, MII_DBG_ADDR, MII_ANA_CTRL_11);
+ if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &data) != 0)
+ return;
+ data &= ~ANA_PS_HIB_EN;
+ atl1c_write_phy_reg(hw, MII_DBG_DATA, data);
+ }
+}
+
+int atl1c_phy_reset(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 phy_ctrl_data = GPHY_CTRL_DEFAULT;
+ u32 mii_ier_data = IER_LINK_UP | IER_LINK_DOWN;
+ int err;
+
+ if (hw->ctrl_flags & ATL1C_HIB_DISABLE)
+ phy_ctrl_data &= ~GPHY_CTRL_HIB_EN;
+
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(40);
+ phy_ctrl_data |= GPHY_CTRL_EXT_RESET;
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(10);
+
+ /*Enable PHY LinkChange Interrupt */
+ err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data);
+ if (err) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Error enable PHY linkChange Interrupt\n");
+ return err;
+ }
+ if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+ atl1c_phy_magic_data(hw);
+ return 0;
+}
+
+int atl1c_phy_init(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ int ret_val;
+ u16 mii_bmcr_data = BMCR_RESET;
+ u16 phy_id1, phy_id2;
+
+ if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &phy_id1) != 0) ||
+ (atl1c_read_phy_reg(hw, MII_PHYSID2, &phy_id2) != 0)) {
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev, "Error get phy ID\n");
+ return -1;
+ }
+ switch (hw->media_type) {
+ case MEDIA_TYPE_AUTO_SENSOR:
+ ret_val = atl1c_phy_setup_adv(hw);
+ if (ret_val) {
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev,
+ "Error Setting up Auto-Negotiation\n");
+ return ret_val;
+ }
+ mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG;
+ break;
+ case MEDIA_TYPE_100M_FULL:
+ mii_bmcr_data |= BMCR_SPEED_100 | BMCR_FULL_DUPLEX;
+ break;
+ case MEDIA_TYPE_100M_HALF:
+ mii_bmcr_data |= BMCR_SPEED_100;
+ break;
+ case MEDIA_TYPE_10M_FULL:
+ mii_bmcr_data |= BMCR_SPEED_10 | BMCR_FULL_DUPLEX;
+ break;
+ case MEDIA_TYPE_10M_HALF:
+ mii_bmcr_data |= BMCR_SPEED_10;
+ break;
+ default:
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev, "Wrong Media type %d\n",
+ hw->media_type);
+ return -1;
+ break;
+ }
+
+ ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+ if (ret_val)
+ return ret_val;
+ hw->phy_configured = true;
+
+ return 0;
+}
+
+/*
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ */
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
+{
+ int err;
+ u16 phy_data;
+
+ /* Read PHY Specific Status Register (17) */
+ err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
+ if (err)
+ return err;
+
+ if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
+ return -1;
+
+ switch (phy_data & GIGA_PSSR_SPEED) {
+ case GIGA_PSSR_1000MBS:
+ *speed = SPEED_1000;
+ break;
+ case GIGA_PSSR_100MBS:
+ *speed = SPEED_100;
+ break;
+ case GIGA_PSSR_10MBS:
+ *speed = SPEED_10;
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ if (phy_data & GIGA_PSSR_DPLX)
+ *duplex = FULL_DUPLEX;
+ else
+ *duplex = HALF_DUPLEX;
+
+ return 0;
+}
+
+int atl1c_restart_autoneg(struct atl1c_hw *hw)
+{
+ int err = 0;
+ u16 mii_bmcr_data = BMCR_RESET;
+
+ err = atl1c_phy_setup_adv(hw);
+ if (err)
+ return err;
+ mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG;
+
+ return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+}
diff --git a/drivers/net/atl1c/atl1c_hw.h b/drivers/net/atl1c/atl1c_hw.h
new file mode 100644
index 000000000000..c2c738df5c63
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_hw.h
@@ -0,0 +1,859 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. 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.
+ */
+
+#ifndef _ATL1C_HW_H_
+#define _ATL1C_HW_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+
+struct atl1c_adapter;
+struct atl1c_hw;
+
+/* function prototype */
+void atl1c_phy_disable(struct atl1c_hw *hw);
+void atl1c_hw_set_mac_addr(struct atl1c_hw *hw);
+int atl1c_phy_reset(struct atl1c_hw *hw);
+int atl1c_read_mac_addr(struct atl1c_hw *hw);
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex);
+u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr);
+void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value);
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data);
+int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data);
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value);
+int atl1c_phy_init(struct atl1c_hw *hw);
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw);
+int atl1c_restart_autoneg(struct atl1c_hw *hw);
+
+/* register definition */
+#define REG_DEVICE_CAP 0x5C
+#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7
+#define DEVICE_CAP_MAX_PAYLOAD_SHIFT 0
+
+#define REG_DEVICE_CTRL 0x60
+#define DEVICE_CTRL_MAX_PAYLOAD_MASK 0x7
+#define DEVICE_CTRL_MAX_PAYLOAD_SHIFT 5
+#define DEVICE_CTRL_MAX_RREQ_SZ_MASK 0x7
+#define DEVICE_CTRL_MAX_RREQ_SZ_SHIFT 12
+
+#define REG_LINK_CTRL 0x68
+#define LINK_CTRL_L0S_EN 0x01
+#define LINK_CTRL_L1_EN 0x02
+
+#define REG_VPD_CAP 0x6C
+#define VPD_CAP_ID_MASK 0xff
+#define VPD_CAP_ID_SHIFT 0
+#define VPD_CAP_NEXT_PTR_MASK 0xFF
+#define VPD_CAP_NEXT_PTR_SHIFT 8
+#define VPD_CAP_VPD_ADDR_MASK 0x7FFF
+#define VPD_CAP_VPD_ADDR_SHIFT 16
+#define VPD_CAP_VPD_FLAG 0x80000000
+
+#define REG_VPD_DATA 0x70
+
+#define REG_PCIE_UC_SEVERITY 0x10C
+#define PCIE_UC_SERVRITY_TRN 0x00000001
+#define PCIE_UC_SERVRITY_DLP 0x00000010
+#define PCIE_UC_SERVRITY_PSN_TLP 0x00001000
+#define PCIE_UC_SERVRITY_FCP 0x00002000
+#define PCIE_UC_SERVRITY_CPL_TO 0x00004000
+#define PCIE_UC_SERVRITY_CA 0x00008000
+#define PCIE_UC_SERVRITY_UC 0x00010000
+#define PCIE_UC_SERVRITY_ROV 0x00020000
+#define PCIE_UC_SERVRITY_MLFP 0x00040000
+#define PCIE_UC_SERVRITY_ECRC 0x00080000
+#define PCIE_UC_SERVRITY_UR 0x00100000
+
+#define REG_DEV_SERIALNUM_CTRL 0x200
+#define REG_DEV_MAC_SEL_MASK 0x0 /* 0:EUI; 1:MAC */
+#define REG_DEV_MAC_SEL_SHIFT 0
+#define REG_DEV_SERIAL_NUM_EN_MASK 0x1
+#define REG_DEV_SERIAL_NUM_EN_SHIFT 1
+
+#define REG_TWSI_CTRL 0x218
+#define TWSI_CTRL_LD_OFFSET_MASK 0xFF
+#define TWSI_CTRL_LD_OFFSET_SHIFT 0
+#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7
+#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8
+#define TWSI_CTRL_SW_LDSTART 0x800
+#define TWSI_CTRL_HW_LDSTART 0x1000
+#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x7F
+#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15
+#define TWSI_CTRL_LD_EXIST 0x400000
+#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3
+#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23
+#define TWSI_CTRL_FREQ_SEL_100K 0
+#define TWSI_CTRL_FREQ_SEL_200K 1
+#define TWSI_CTRL_FREQ_SEL_300K 2
+#define TWSI_CTRL_FREQ_SEL_400K 3
+#define TWSI_CTRL_SMB_SLV_ADDR
+#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3
+#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24
+
+
+#define REG_PCIE_DEV_MISC_CTRL 0x21C
+#define PCIE_DEV_MISC_EXT_PIPE 0x2
+#define PCIE_DEV_MISC_RETRY_BUFDIS 0x1
+#define PCIE_DEV_MISC_SPIROM_EXIST 0x4
+#define PCIE_DEV_MISC_SERDES_ENDIAN 0x8
+#define PCIE_DEV_MISC_SERDES_SEL_DIN 0x10
+
+#define REG_PCIE_PHYMISC 0x1000
+#define PCIE_PHYMISC_FORCE_RCV_DET 0x4
+
+#define REG_TWSI_DEBUG 0x1108
+#define TWSI_DEBUG_DEV_EXIST 0x20000000
+
+#define REG_EEPROM_CTRL 0x12C0
+#define EEPROM_CTRL_DATA_HI_MASK 0xFFFF
+#define EEPROM_CTRL_DATA_HI_SHIFT 0
+#define EEPROM_CTRL_ADDR_MASK 0x3FF
+#define EEPROM_CTRL_ADDR_SHIFT 16
+#define EEPROM_CTRL_ACK 0x40000000
+#define EEPROM_CTRL_RW 0x80000000
+
+#define REG_EEPROM_DATA_LO 0x12C4
+
+#define REG_OTP_CTRL 0x12F0
+#define OTP_CTRL_CLK_EN 0x0002
+
+#define REG_PM_CTRL 0x12F8
+#define PM_CTRL_SDES_EN 0x00000001
+#define PM_CTRL_RBER_EN 0x00000002
+#define PM_CTRL_CLK_REQ_EN 0x00000004
+#define PM_CTRL_ASPM_L1_EN 0x00000008
+#define PM_CTRL_SERDES_L1_EN 0x00000010
+#define PM_CTRL_SERDES_PLL_L1_EN 0x00000020
+#define PM_CTRL_SERDES_PD_EX_L1 0x00000040
+#define PM_CTRL_SERDES_BUDS_RX_L1_EN 0x00000080
+#define PM_CTRL_L0S_ENTRY_TIMER_MASK 0xF
+#define PM_CTRL_L0S_ENTRY_TIMER_SHIFT 8
+#define PM_CTRL_ASPM_L0S_EN 0x00001000
+#define PM_CTRL_CLK_SWH_L1 0x00002000
+#define PM_CTRL_CLK_PWM_VER1_1 0x00004000
+#define PM_CTRL_PCIE_RECV 0x00008000
+#define PM_CTRL_L1_ENTRY_TIMER_MASK 0xF
+#define PM_CTRL_L1_ENTRY_TIMER_SHIFT 16
+#define PM_CTRL_PM_REQ_TIMER_MASK 0xF
+#define PM_CTRL_PM_REQ_TIMER_SHIFT 20
+#define PM_CTRL_LCKDET_TIMER_MASK 0x3F
+#define PM_CTRL_LCKDET_TIMER_SHIFT 24
+#define PM_CTRL_MAC_ASPM_CHK 0x40000000
+#define PM_CTRL_HOTRST 0x80000000
+
+/* Selene Master Control Register */
+#define REG_MASTER_CTRL 0x1400
+#define MASTER_CTRL_SOFT_RST 0x1
+#define MASTER_CTRL_TEST_MODE_MASK 0x3
+#define MASTER_CTRL_TEST_MODE_SHIFT 2
+#define MASTER_CTRL_BERT_START 0x10
+#define MASTER_CTRL_MTIMER_EN 0x100
+#define MASTER_CTRL_MANUAL_INT 0x200
+#define MASTER_CTRL_TX_ITIMER_EN 0x400
+#define MASTER_CTRL_RX_ITIMER_EN 0x800
+#define MASTER_CTRL_CLK_SEL_DIS 0x1000
+#define MASTER_CTRL_CLK_SWH_MODE 0x2000
+#define MASTER_CTRL_INT_RDCLR 0x4000
+#define MASTER_CTRL_REV_NUM_SHIFT 16
+#define MASTER_CTRL_REV_NUM_MASK 0xff
+#define MASTER_CTRL_DEV_ID_SHIFT 24
+#define MASTER_CTRL_DEV_ID_MASK 0x7f
+#define MASTER_CTRL_OTP_SEL 0x80000000
+
+/* Timer Initial Value Register */
+#define REG_MANUAL_TIMER_INIT 0x1404
+
+/* IRQ ModeratorTimer Initial Value Register */
+#define REG_IRQ_MODRT_TIMER_INIT 0x1408
+#define IRQ_MODRT_TIMER_MASK 0xffff
+#define IRQ_MODRT_TX_TIMER_SHIFT 0
+#define IRQ_MODRT_RX_TIMER_SHIFT 16
+
+#define REG_GPHY_CTRL 0x140C
+#define GPHY_CTRL_EXT_RESET 0x1
+#define GPHY_CTRL_RTL_MODE 0x2
+#define GPHY_CTRL_LED_MODE 0x4
+#define GPHY_CTRL_ANEG_NOW 0x8
+#define GPHY_CTRL_REV_ANEG 0x10
+#define GPHY_CTRL_GATE_25M_EN 0x20
+#define GPHY_CTRL_LPW_EXIT 0x40
+#define GPHY_CTRL_PHY_IDDQ 0x80
+#define GPHY_CTRL_PHY_IDDQ_DIS 0x100
+#define GPHY_CTRL_GIGA_DIS 0x200
+#define GPHY_CTRL_HIB_EN 0x400
+#define GPHY_CTRL_HIB_PULSE 0x800
+#define GPHY_CTRL_SEL_ANA_RST 0x1000
+#define GPHY_CTRL_PHY_PLL_ON 0x2000
+#define GPHY_CTRL_PWDOWN_HW 0x4000
+#define GPHY_CTRL_PHY_PLL_BYPASS 0x8000
+
+#define GPHY_CTRL_DEFAULT ( \
+ GPHY_CTRL_SEL_ANA_RST |\
+ GPHY_CTRL_HIB_PULSE |\
+ GPHY_CTRL_HIB_EN)
+
+#define GPHY_CTRL_PW_WOL_DIS ( \
+ GPHY_CTRL_SEL_ANA_RST |\
+ GPHY_CTRL_HIB_PULSE |\
+ GPHY_CTRL_HIB_EN |\
+ GPHY_CTRL_PWDOWN_HW |\
+ GPHY_CTRL_PHY_IDDQ)
+
+/* Block IDLE Status Register */
+#define REG_IDLE_STATUS 0x1410
+#define IDLE_STATUS_MASK 0x00FF
+#define IDLE_STATUS_RXMAC_NO_IDLE 0x1
+#define IDLE_STATUS_TXMAC_NO_IDLE 0x2
+#define IDLE_STATUS_RXQ_NO_IDLE 0x4
+#define IDLE_STATUS_TXQ_NO_IDLE 0x8
+#define IDLE_STATUS_DMAR_NO_IDLE 0x10
+#define IDLE_STATUS_DMAW_NO_IDLE 0x20
+#define IDLE_STATUS_SMB_NO_IDLE 0x40
+#define IDLE_STATUS_CMB_NO_IDLE 0x80
+
+/* MDIO Control Register */
+#define REG_MDIO_CTRL 0x1414
+#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit
+ * control data to write to PHY
+ * MII management register */
+#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit
+ * status data that was read
+ * from the PHY MII management register */
+#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */
+#define MDIO_REG_ADDR_SHIFT 16
+#define MDIO_RW 0x200000 /* 1: read, 0: write */
+#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */
+#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO
+ * master. And this bit is self
+ * cleared after one cycle */
+#define MDIO_CLK_SEL_SHIFT 24
+#define MDIO_CLK_25_4 0
+#define MDIO_CLK_25_6 2
+#define MDIO_CLK_25_8 3
+#define MDIO_CLK_25_10 4
+#define MDIO_CLK_25_14 5
+#define MDIO_CLK_25_20 6
+#define MDIO_CLK_25_28 7
+#define MDIO_BUSY 0x8000000
+#define MDIO_AP_EN 0x10000000
+#define MDIO_WAIT_TIMES 10
+
+/* MII PHY Status Register */
+#define REG_PHY_STATUS 0x1418
+#define PHY_GENERAL_STATUS_MASK 0xFFFF
+#define PHY_STATUS_RECV_ENABLE 0x0001
+#define PHY_OE_PWSP_STATUS_MASK 0x07FF
+#define PHY_OE_PWSP_STATUS_SHIFT 16
+#define PHY_STATUS_LPW_STATE 0x80000000
+/* BIST Control and Status Register0 (for the Packet Memory) */
+#define REG_BIST0_CTRL 0x141c
+#define BIST0_NOW 0x1
+#define BIST0_SRAM_FAIL 0x2 /* 1: The SRAM failure is
+ * un-repairable because
+ * it has address decoder
+ * failure or more than 1 cell
+ * stuck-to-x failure */
+#define BIST0_FUSE_FLAG 0x4
+
+/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
+#define REG_BIST1_CTRL 0x1420
+#define BIST1_NOW 0x1
+#define BIST1_SRAM_FAIL 0x2
+#define BIST1_FUSE_FLAG 0x4
+
+/* SerDes Lock Detect Control and Status Register */
+#define REG_SERDES_LOCK 0x1424
+#define SERDES_LOCK_DETECT 0x1 /* SerDes lock detected. This signal
+ * comes from Analog SerDes */
+#define SERDES_LOCK_DETECT_EN 0x2 /* 1: Enable SerDes Lock detect function */
+
+/* MAC Control Register */
+#define REG_MAC_CTRL 0x1480
+#define MAC_CTRL_TX_EN 0x1
+#define MAC_CTRL_RX_EN 0x2
+#define MAC_CTRL_TX_FLOW 0x4
+#define MAC_CTRL_RX_FLOW 0x8
+#define MAC_CTRL_LOOPBACK 0x10
+#define MAC_CTRL_DUPLX 0x20
+#define MAC_CTRL_ADD_CRC 0x40
+#define MAC_CTRL_PAD 0x80
+#define MAC_CTRL_LENCHK 0x100
+#define MAC_CTRL_HUGE_EN 0x200
+#define MAC_CTRL_PRMLEN_SHIFT 10
+#define MAC_CTRL_PRMLEN_MASK 0xf
+#define MAC_CTRL_RMV_VLAN 0x4000
+#define MAC_CTRL_PROMIS_EN 0x8000
+#define MAC_CTRL_TX_PAUSE 0x10000
+#define MAC_CTRL_SCNT 0x20000
+#define MAC_CTRL_SRST_TX 0x40000
+#define MAC_CTRL_TX_SIMURST 0x80000
+#define MAC_CTRL_SPEED_SHIFT 20
+#define MAC_CTRL_SPEED_MASK 0x3
+#define MAC_CTRL_DBG_TX_BKPRESURE 0x400000
+#define MAC_CTRL_TX_HUGE 0x800000
+#define MAC_CTRL_RX_CHKSUM_EN 0x1000000
+#define MAC_CTRL_MC_ALL_EN 0x2000000
+#define MAC_CTRL_BC_EN 0x4000000
+#define MAC_CTRL_DBG 0x8000000
+#define MAC_CTRL_SINGLE_PAUSE_EN 0x10000000
+
+/* MAC IPG/IFG Control Register */
+#define REG_MAC_IPG_IFG 0x1484
+#define MAC_IPG_IFG_IPGT_SHIFT 0 /* Desired back to back
+ * inter-packet gap. The
+ * default is 96-bit time */
+#define MAC_IPG_IFG_IPGT_MASK 0x7f
+#define MAC_IPG_IFG_MIFG_SHIFT 8 /* Minimum number of IFG to
+ * enforce in between RX frames */
+#define MAC_IPG_IFG_MIFG_MASK 0xff /* Frame gap below such IFP is dropped */
+#define MAC_IPG_IFG_IPGR1_SHIFT 16 /* 64bit Carrier-Sense window */
+#define MAC_IPG_IFG_IPGR1_MASK 0x7f
+#define MAC_IPG_IFG_IPGR2_SHIFT 24 /* 96-bit IPG window */
+#define MAC_IPG_IFG_IPGR2_MASK 0x7f
+
+/* MAC STATION ADDRESS */
+#define REG_MAC_STA_ADDR 0x1488
+
+/* Hash table for multicast address */
+#define REG_RX_HASH_TABLE 0x1490
+
+/* MAC Half-Duplex Control Register */
+#define REG_MAC_HALF_DUPLX_CTRL 0x1498
+#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 /* Collision Window */
+#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff
+#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
+#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf
+#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 /* No back-off on backpressure,
+ * immediately start the
+ * transmission after back pressure */
+#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 /* Maximum binary exponential number */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 /* IPG to start JAM for collision based flow control in half-duplex */
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf /* mode. In unit of 8-bit time */
+
+/* Maximum Frame Length Control Register */
+#define REG_MTU 0x149c
+
+/* Wake-On-Lan control register */
+#define REG_WOL_CTRL 0x14a0
+#define WOL_PATTERN_EN 0x00000001
+#define WOL_PATTERN_PME_EN 0x00000002
+#define WOL_MAGIC_EN 0x00000004
+#define WOL_MAGIC_PME_EN 0x00000008
+#define WOL_LINK_CHG_EN 0x00000010
+#define WOL_LINK_CHG_PME_EN 0x00000020
+#define WOL_PATTERN_ST 0x00000100
+#define WOL_MAGIC_ST 0x00000200
+#define WOL_LINKCHG_ST 0x00000400
+#define WOL_CLK_SWITCH_EN 0x00008000
+#define WOL_PT0_EN 0x00010000
+#define WOL_PT1_EN 0x00020000
+#define WOL_PT2_EN 0x00040000
+#define WOL_PT3_EN 0x00080000
+#define WOL_PT4_EN 0x00100000
+#define WOL_PT5_EN 0x00200000
+#define WOL_PT6_EN 0x00400000
+
+/* WOL Length ( 2 DWORD ) */
+#define REG_WOL_PATTERN_LEN 0x14a4
+#define WOL_PT_LEN_MASK 0x7f
+#define WOL_PT0_LEN_SHIFT 0
+#define WOL_PT1_LEN_SHIFT 8
+#define WOL_PT2_LEN_SHIFT 16
+#define WOL_PT3_LEN_SHIFT 24
+#define WOL_PT4_LEN_SHIFT 0
+#define WOL_PT5_LEN_SHIFT 8
+#define WOL_PT6_LEN_SHIFT 16
+
+/* Internal SRAM Partition Register */
+#define RFDX_HEAD_ADDR_MASK 0x03FF
+#define RFDX_HARD_ADDR_SHIFT 0
+#define RFDX_TAIL_ADDR_MASK 0x03FF
+#define RFDX_TAIL_ADDR_SHIFT 16
+
+#define REG_SRAM_RFD0_INFO 0x1500
+#define REG_SRAM_RFD1_INFO 0x1504
+#define REG_SRAM_RFD2_INFO 0x1508
+#define REG_SRAM_RFD3_INFO 0x150C
+
+#define REG_RFD_NIC_LEN 0x1510 /* In 8-bytes */
+#define RFD_NIC_LEN_MASK 0x03FF
+
+#define REG_SRAM_TRD_ADDR 0x1518
+#define TPD_HEAD_ADDR_MASK 0x03FF
+#define TPD_HEAD_ADDR_SHIFT 0
+#define TPD_TAIL_ADDR_MASK 0x03FF
+#define TPD_TAIL_ADDR_SHIFT 16
+
+#define REG_SRAM_TRD_LEN 0x151C /* In 8-bytes */
+#define TPD_NIC_LEN_MASK 0x03FF
+
+#define REG_SRAM_RXF_ADDR 0x1520
+#define REG_SRAM_RXF_LEN 0x1524
+#define REG_SRAM_TXF_ADDR 0x1528
+#define REG_SRAM_TXF_LEN 0x152C
+#define REG_SRAM_TCPH_ADDR 0x1530
+#define REG_SRAM_PKTH_ADDR 0x1532
+
+/*
+ * Load Ptr Register
+ * Software sets this bit after the initialization of the head and tail */
+#define REG_LOAD_PTR 0x1534
+
+/*
+ * addresses of all descriptors, as well as the following descriptor
+ * control register, which triggers each function block to load the head
+ * pointer to prepare for the operation. This bit is then self-cleared
+ * after one cycle.
+ */
+#define REG_RX_BASE_ADDR_HI 0x1540
+#define REG_TX_BASE_ADDR_HI 0x1544
+#define REG_SMB_BASE_ADDR_HI 0x1548
+#define REG_SMB_BASE_ADDR_LO 0x154C
+#define REG_RFD0_HEAD_ADDR_LO 0x1550
+#define REG_RFD1_HEAD_ADDR_LO 0x1554
+#define REG_RFD2_HEAD_ADDR_LO 0x1558
+#define REG_RFD3_HEAD_ADDR_LO 0x155C
+#define REG_RFD_RING_SIZE 0x1560
+#define RFD_RING_SIZE_MASK 0x0FFF
+#define REG_RX_BUF_SIZE 0x1564
+#define RX_BUF_SIZE_MASK 0xFFFF
+#define REG_RRD0_HEAD_ADDR_LO 0x1568
+#define REG_RRD1_HEAD_ADDR_LO 0x156C
+#define REG_RRD2_HEAD_ADDR_LO 0x1570
+#define REG_RRD3_HEAD_ADDR_LO 0x1574
+#define REG_RRD_RING_SIZE 0x1578
+#define RRD_RING_SIZE_MASK 0x0FFF
+#define REG_HTPD_HEAD_ADDR_LO 0x157C
+#define REG_NTPD_HEAD_ADDR_LO 0x1580
+#define REG_TPD_RING_SIZE 0x1584
+#define TPD_RING_SIZE_MASK 0xFFFF
+#define REG_CMB_BASE_ADDR_LO 0x1588
+
+/* RSS about */
+#define REG_RSS_KEY0 0x14B0
+#define REG_RSS_KEY1 0x14B4
+#define REG_RSS_KEY2 0x14B8
+#define REG_RSS_KEY3 0x14BC
+#define REG_RSS_KEY4 0x14C0
+#define REG_RSS_KEY5 0x14C4
+#define REG_RSS_KEY6 0x14C8
+#define REG_RSS_KEY7 0x14CC
+#define REG_RSS_KEY8 0x14D0
+#define REG_RSS_KEY9 0x14D4
+#define REG_IDT_TABLE0 0x14E0
+#define REG_IDT_TABLE1 0x14E4
+#define REG_IDT_TABLE2 0x14E8
+#define REG_IDT_TABLE3 0x14EC
+#define REG_IDT_TABLE4 0x14F0
+#define REG_IDT_TABLE5 0x14F4
+#define REG_IDT_TABLE6 0x14F8
+#define REG_IDT_TABLE7 0x14FC
+#define REG_IDT_TABLE REG_IDT_TABLE0
+#define REG_RSS_HASH_VALUE 0x15B0
+#define REG_RSS_HASH_FLAG 0x15B4
+#define REG_BASE_CPU_NUMBER 0x15B8
+
+/* TXQ Control Register */
+#define REG_TXQ_CTRL 0x1590
+#define TXQ_NUM_TPD_BURST_MASK 0xF
+#define TXQ_NUM_TPD_BURST_SHIFT 0
+#define TXQ_CTRL_IP_OPTION_EN 0x10
+#define TXQ_CTRL_EN 0x20
+#define TXQ_CTRL_ENH_MODE 0x40
+#define TXQ_CTRL_LS_8023_EN 0x80
+#define TXQ_TXF_BURST_NUM_SHIFT 16
+#define TXQ_TXF_BURST_NUM_MASK 0xFFFF
+
+/* Jumbo packet Threshold for task offload */
+#define REG_TX_TSO_OFFLOAD_THRESH 0x1594 /* In 8-bytes */
+#define TX_TSO_OFFLOAD_THRESH_MASK 0x07FF
+
+#define REG_TXF_WATER_MARK 0x1598 /* In 8-bytes */
+#define TXF_WATER_MARK_MASK 0x0FFF
+#define TXF_LOW_WATER_MARK_SHIFT 0
+#define TXF_HIGH_WATER_MARK_SHIFT 16
+#define TXQ_CTRL_BURST_MODE_EN 0x80000000
+
+#define REG_THRUPUT_MON_CTRL 0x159C
+#define THRUPUT_MON_RATE_MASK 0x3
+#define THRUPUT_MON_RATE_SHIFT 0
+#define THRUPUT_MON_EN 0x80
+
+/* RXQ Control Register */
+#define REG_RXQ_CTRL 0x15A0
+#define ASPM_THRUPUT_LIMIT_MASK 0x3
+#define ASPM_THRUPUT_LIMIT_SHIFT 0
+#define ASPM_THRUPUT_LIMIT_NO 0x00
+#define ASPM_THRUPUT_LIMIT_1M 0x01
+#define ASPM_THRUPUT_LIMIT_10M 0x02
+#define ASPM_THRUPUT_LIMIT_100M 0x04
+#define RXQ1_CTRL_EN 0x10
+#define RXQ2_CTRL_EN 0x20
+#define RXQ3_CTRL_EN 0x40
+#define IPV6_CHKSUM_CTRL_EN 0x80
+#define RSS_HASH_BITS_MASK 0x00FF
+#define RSS_HASH_BITS_SHIFT 8
+#define RSS_HASH_IPV4 0x10000
+#define RSS_HASH_IPV4_TCP 0x20000
+#define RSS_HASH_IPV6 0x40000
+#define RSS_HASH_IPV6_TCP 0x80000
+#define RXQ_RFD_BURST_NUM_MASK 0x003F
+#define RXQ_RFD_BURST_NUM_SHIFT 20
+#define RSS_MODE_MASK 0x0003
+#define RSS_MODE_SHIFT 26
+#define RSS_NIP_QUEUE_SEL_MASK 0x1
+#define RSS_NIP_QUEUE_SEL_SHIFT 28
+#define RRS_HASH_CTRL_EN 0x20000000
+#define RX_CUT_THRU_EN 0x40000000
+#define RXQ_CTRL_EN 0x80000000
+
+#define REG_RFD_FREE_THRESH 0x15A4
+#define RFD_FREE_THRESH_MASK 0x003F
+#define RFD_FREE_HI_THRESH_SHIFT 0
+#define RFD_FREE_LO_THRESH_SHIFT 6
+
+/* RXF flow control register */
+#define REG_RXQ_RXF_PAUSE_THRESH 0x15A8
+#define RXQ_RXF_PAUSE_TH_HI_SHIFT 0
+#define RXQ_RXF_PAUSE_TH_HI_MASK 0x0FFF
+#define RXQ_RXF_PAUSE_TH_LO_SHIFT 16
+#define RXQ_RXF_PAUSE_TH_LO_MASK 0x0FFF
+
+#define REG_RXD_DMA_CTRL 0x15AC
+#define RXD_DMA_THRESH_MASK 0x0FFF /* In 8-bytes */
+#define RXD_DMA_THRESH_SHIFT 0
+#define RXD_DMA_DOWN_TIMER_MASK 0xFFFF
+#define RXD_DMA_DOWN_TIMER_SHIFT 16
+
+/* DMA Engine Control Register */
+#define REG_DMA_CTRL 0x15C0
+#define DMA_CTRL_DMAR_IN_ORDER 0x1
+#define DMA_CTRL_DMAR_ENH_ORDER 0x2
+#define DMA_CTRL_DMAR_OUT_ORDER 0x4
+#define DMA_CTRL_RCB_VALUE 0x8
+#define DMA_CTRL_DMAR_BURST_LEN_MASK 0x0007
+#define DMA_CTRL_DMAR_BURST_LEN_SHIFT 4
+#define DMA_CTRL_DMAW_BURST_LEN_MASK 0x0007
+#define DMA_CTRL_DMAW_BURST_LEN_SHIFT 7
+#define DMA_CTRL_DMAR_REQ_PRI 0x400
+#define DMA_CTRL_DMAR_DLY_CNT_MASK 0x001F
+#define DMA_CTRL_DMAR_DLY_CNT_SHIFT 11
+#define DMA_CTRL_DMAW_DLY_CNT_MASK 0x000F
+#define DMA_CTRL_DMAW_DLY_CNT_SHIFT 16
+#define DMA_CTRL_CMB_EN 0x100000
+#define DMA_CTRL_SMB_EN 0x200000
+#define DMA_CTRL_CMB_NOW 0x400000
+#define MAC_CTRL_SMB_DIS 0x1000000
+#define DMA_CTRL_SMB_NOW 0x80000000
+
+/* CMB/SMB Control Register */
+#define REG_SMB_STAT_TIMER 0x15C4 /* 2us resolution */
+#define SMB_STAT_TIMER_MASK 0xFFFFFF
+#define REG_CMB_TPD_THRESH 0x15C8
+#define CMB_TPD_THRESH_MASK 0xFFFF
+#define REG_CMB_TX_TIMER 0x15CC /* 2us resolution */
+#define CMB_TX_TIMER_MASK 0xFFFF
+
+/* Mail box */
+#define MB_RFDX_PROD_IDX_MASK 0xFFFF
+#define REG_MB_RFD0_PROD_IDX 0x15E0
+#define REG_MB_RFD1_PROD_IDX 0x15E4
+#define REG_MB_RFD2_PROD_IDX 0x15E8
+#define REG_MB_RFD3_PROD_IDX 0x15EC
+
+#define MB_PRIO_PROD_IDX_MASK 0xFFFF
+#define REG_MB_PRIO_PROD_IDX 0x15F0
+#define MB_HTPD_PROD_IDX_SHIFT 0
+#define MB_NTPD_PROD_IDX_SHIFT 16
+
+#define MB_PRIO_CONS_IDX_MASK 0xFFFF
+#define REG_MB_PRIO_CONS_IDX 0x15F4
+#define MB_HTPD_CONS_IDX_SHIFT 0
+#define MB_NTPD_CONS_IDX_SHIFT 16
+
+#define REG_MB_RFD01_CONS_IDX 0x15F8
+#define MB_RFD0_CONS_IDX_MASK 0x0000FFFF
+#define MB_RFD1_CONS_IDX_MASK 0xFFFF0000
+#define REG_MB_RFD23_CONS_IDX 0x15FC
+#define MB_RFD2_CONS_IDX_MASK 0x0000FFFF
+#define MB_RFD3_CONS_IDX_MASK 0xFFFF0000
+
+/* Interrupt Status Register */
+#define REG_ISR 0x1600
+#define ISR_SMB 0x00000001
+#define ISR_TIMER 0x00000002
+/*
+ * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
+ * in Table 51 Selene Master Control Register (Offset 0x1400).
+ */
+#define ISR_MANUAL 0x00000004
+#define ISR_HW_RXF_OV 0x00000008 /* RXF overflow interrupt */
+#define ISR_RFD0_UR 0x00000010 /* RFD0 under run */
+#define ISR_RFD1_UR 0x00000020
+#define ISR_RFD2_UR 0x00000040
+#define ISR_RFD3_UR 0x00000080
+#define ISR_TXF_UR 0x00000100
+#define ISR_DMAR_TO_RST 0x00000200
+#define ISR_DMAW_TO_RST 0x00000400
+#define ISR_TX_CREDIT 0x00000800
+#define ISR_GPHY 0x00001000
+/* GPHY low power state interrupt */
+#define ISR_GPHY_LPW 0x00002000
+#define ISR_TXQ_TO_RST 0x00004000
+#define ISR_TX_PKT 0x00008000
+#define ISR_RX_PKT_0 0x00010000
+#define ISR_RX_PKT_1 0x00020000
+#define ISR_RX_PKT_2 0x00040000
+#define ISR_RX_PKT_3 0x00080000
+#define ISR_MAC_RX 0x00100000
+#define ISR_MAC_TX 0x00200000
+#define ISR_UR_DETECTED 0x00400000
+#define ISR_FERR_DETECTED 0x00800000
+#define ISR_NFERR_DETECTED 0x01000000
+#define ISR_CERR_DETECTED 0x02000000
+#define ISR_PHY_LINKDOWN 0x04000000
+#define ISR_DIS_INT 0x80000000
+
+/* Interrupt Mask Register */
+#define REG_IMR 0x1604
+
+#define IMR_NORMAL_MASK (\
+ ISR_MANUAL |\
+ ISR_HW_RXF_OV |\
+ ISR_RFD0_UR |\
+ ISR_TXF_UR |\
+ ISR_DMAR_TO_RST |\
+ ISR_TXQ_TO_RST |\
+ ISR_DMAW_TO_RST |\
+ ISR_GPHY |\
+ ISR_TX_PKT |\
+ ISR_RX_PKT_0 |\
+ ISR_GPHY_LPW |\
+ ISR_PHY_LINKDOWN)
+
+#define ISR_RX_PKT (\
+ ISR_RX_PKT_0 |\
+ ISR_RX_PKT_1 |\
+ ISR_RX_PKT_2 |\
+ ISR_RX_PKT_3)
+
+#define ISR_OVER (\
+ ISR_RFD0_UR |\
+ ISR_RFD1_UR |\
+ ISR_RFD2_UR |\
+ ISR_RFD3_UR |\
+ ISR_HW_RXF_OV |\
+ ISR_TXF_UR)
+
+#define ISR_ERROR (\
+ ISR_DMAR_TO_RST |\
+ ISR_TXQ_TO_RST |\
+ ISR_DMAW_TO_RST |\
+ ISR_PHY_LINKDOWN)
+
+#define REG_INT_RETRIG_TIMER 0x1608
+#define INT_RETRIG_TIMER_MASK 0xFFFF
+
+#define REG_HDS_CTRL 0x160C
+#define HDS_CTRL_EN 0x0001
+#define HDS_CTRL_BACKFILLSIZE_SHIFT 8
+#define HDS_CTRL_BACKFILLSIZE_MASK 0x0FFF
+#define HDS_CTRL_MAX_HDRSIZE_SHIFT 20
+#define HDS_CTRL_MAC_HDRSIZE_MASK 0x0FFF
+
+#define REG_MAC_RX_STATUS_BIN 0x1700
+#define REG_MAC_RX_STATUS_END 0x175c
+#define REG_MAC_TX_STATUS_BIN 0x1760
+#define REG_MAC_TX_STATUS_END 0x17c0
+
+/* DEBUG ADDR */
+#define REG_DEBUG_DATA0 0x1900
+#define REG_DEBUG_DATA1 0x1904
+
+/* PHY Control Register */
+#define MII_BMCR 0x00
+#define BMCR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define BMCR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
+#define BMCR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
+#define BMCR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
+#define BMCR_ISOLATE 0x0400 /* Isolate PHY from MII */
+#define BMCR_POWER_DOWN 0x0800 /* Power down */
+#define BMCR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
+#define BMCR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define BMCR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
+#define BMCR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
+#define BMCR_SPEED_MASK 0x2040
+#define BMCR_SPEED_1000 0x0040
+#define BMCR_SPEED_100 0x2000
+#define BMCR_SPEED_10 0x0000
+
+/* PHY Status Register */
+#define MII_BMSR 0x01
+#define BMMSR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
+#define BMSR_JABBER_DETECT 0x0002 /* Jabber Detected */
+#define BMSR_LINK_STATUS 0x0004 /* Link Status 1 = link */
+#define BMSR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
+#define BMSR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
+#define BMSR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
+#define BMSR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
+#define BMSR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
+#define BMSR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
+#define BMSR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
+#define BMSR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
+#define BMSR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
+#define BMSR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
+#define BMMII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
+#define BMMII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
+
+#define MII_PHYSID1 0x02
+#define MII_PHYSID2 0x03
+
+/* Autoneg Advertisement Register */
+#define MII_ADVERTISE 0x04
+#define ADVERTISE_SPEED_MASK 0x01E0
+#define ADVERTISE_DEFAULT_CAP 0x0DE0
+
+/* 1000BASE-T Control Register */
+#define MII_GIGA_CR 0x09
+#define GIGA_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port 0=DTE device */
+
+#define GIGA_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master 0=Configure PHY as Slave */
+#define GIGA_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
+#define GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
+#define GIGA_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
+#define GIGA_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
+#define GIGA_CR_1000T_SPEED_MASK 0x0300
+#define GIGA_CR_1000T_DEFAULT_CAP 0x0300
+
+/* PHY Specific Status Register */
+#define MII_GIGA_PSSR 0x11
+#define GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
+#define GIGA_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
+#define GIGA_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
+#define GIGA_PSSR_10MBS 0x0000 /* 00=10Mbs */
+#define GIGA_PSSR_100MBS 0x4000 /* 01=100Mbs */
+#define GIGA_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
+
+/* PHY Interrupt Enable Register */
+#define MII_IER 0x12
+#define IER_LINK_UP 0x0400
+#define IER_LINK_DOWN 0x0800
+
+/* PHY Interrupt Status Register */
+#define MII_ISR 0x13
+#define ISR_LINK_UP 0x0400
+#define ISR_LINK_DOWN 0x0800
+
+/* Cable-Detect-Test Control Register */
+#define MII_CDTC 0x16
+#define CDTC_EN_OFF 0 /* sc */
+#define CDTC_EN_BITS 1
+#define CDTC_PAIR_OFF 8
+#define CDTC_PAIR_BIT 2
+
+/* Cable-Detect-Test Status Register */
+#define MII_CDTS 0x1C
+#define CDTS_STATUS_OFF 8
+#define CDTS_STATUS_BITS 2
+#define CDTS_STATUS_NORMAL 0
+#define CDTS_STATUS_SHORT 1
+#define CDTS_STATUS_OPEN 2
+#define CDTS_STATUS_INVALID 3
+
+#define MII_DBG_ADDR 0x1D
+#define MII_DBG_DATA 0x1E
+
+#define MII_ANA_CTRL_0 0x0
+#define ANA_RESTART_CAL 0x0001
+#define ANA_MANUL_SWICH_ON_SHIFT 0x1
+#define ANA_MANUL_SWICH_ON_MASK 0xF
+#define ANA_MAN_ENABLE 0x0020
+#define ANA_SEL_HSP 0x0040
+#define ANA_EN_HB 0x0080
+#define ANA_EN_HBIAS 0x0100
+#define ANA_OEN_125M 0x0200
+#define ANA_EN_LCKDT 0x0400
+#define ANA_LCKDT_PHY 0x0800
+#define ANA_AFE_MODE 0x1000
+#define ANA_VCO_SLOW 0x2000
+#define ANA_VCO_FAST 0x4000
+#define ANA_SEL_CLK125M_DSP 0x8000
+
+#define MII_ANA_CTRL_4 0x4
+#define ANA_IECHO_ADJ_MASK 0xF
+#define ANA_IECHO_ADJ_3_SHIFT 0
+#define ANA_IECHO_ADJ_2_SHIFT 4
+#define ANA_IECHO_ADJ_1_SHIFT 8
+#define ANA_IECHO_ADJ_0_SHIFT 12
+
+#define MII_ANA_CTRL_5 0x5
+#define ANA_SERDES_CDR_BW_SHIFT 0
+#define ANA_SERDES_CDR_BW_MASK 0x3
+#define ANA_MS_PAD_DBG 0x0004
+#define ANA_SPEEDUP_DBG 0x0008
+#define ANA_SERDES_TH_LOS_SHIFT 4
+#define ANA_SERDES_TH_LOS_MASK 0x3
+#define ANA_SERDES_EN_DEEM 0x0040
+#define ANA_SERDES_TXELECIDLE 0x0080
+#define ANA_SERDES_BEACON 0x0100
+#define ANA_SERDES_HALFTXDR 0x0200
+#define ANA_SERDES_SEL_HSP 0x0400
+#define ANA_SERDES_EN_PLL 0x0800
+#define ANA_SERDES_EN 0x1000
+#define ANA_SERDES_EN_LCKDT 0x2000
+
+#define MII_ANA_CTRL_11 0xB
+#define ANA_PS_HIB_EN 0x8000
+
+#define MII_ANA_CTRL_18 0x12
+#define ANA_TEST_MODE_10BT_01SHIFT 0
+#define ANA_TEST_MODE_10BT_01MASK 0x3
+#define ANA_LOOP_SEL_10BT 0x0004
+#define ANA_RGMII_MODE_SW 0x0008
+#define ANA_EN_LONGECABLE 0x0010
+#define ANA_TEST_MODE_10BT_2 0x0020
+#define ANA_EN_10BT_IDLE 0x0400
+#define ANA_EN_MASK_TB 0x0800
+#define ANA_TRIGGER_SEL_TIMER_SHIFT 12
+#define ANA_TRIGGER_SEL_TIMER_MASK 0x3
+#define ANA_INTERVAL_SEL_TIMER_SHIFT 14
+#define ANA_INTERVAL_SEL_TIMER_MASK 0x3
+
+#define MII_ANA_CTRL_41 0x29
+#define ANA_TOP_PS_EN 0x8000
+
+#define MII_ANA_CTRL_54 0x36
+#define ANA_LONG_CABLE_TH_100_SHIFT 0
+#define ANA_LONG_CABLE_TH_100_MASK 0x3F
+#define ANA_DESERVED 0x0040
+#define ANA_EN_LIT_CH 0x0080
+#define ANA_SHORT_CABLE_TH_100_SHIFT 8
+#define ANA_SHORT_CABLE_TH_100_MASK 0x3F
+#define ANA_BP_BAD_LINK_ACCUM 0x4000
+#define ANA_BP_SMALL_BW 0x8000
+
+#endif /*_ATL1C_HW_H_*/
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
new file mode 100644
index 000000000000..deb7b53167ee
--- /dev/null
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -0,0 +1,2797 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. 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.
+ */
+
+#include "atl1c.h"
+
+#define ATL1C_DRV_VERSION "1.0.0.1-NAPI"
+char atl1c_driver_name[] = "atl1c";
+char atl1c_driver_version[] = ATL1C_DRV_VERSION;
+#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062
+#define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063
+/*
+ * atl1c_pci_tbl - PCI Device ID Table
+ *
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ * Class, Class Mask, private data (not used) }
+ */
+static struct pci_device_id atl1c_pci_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)},
+ /* required last entry */
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl);
+
+MODULE_AUTHOR("Jie Yang <jie.yang@atheros.com>");
+MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATL1C_DRV_VERSION);
+
+static int atl1c_stop_mac(struct atl1c_hw *hw);
+static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw);
+static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw);
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw);
+static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup);
+static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter);
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
+ int *work_done, int work_to_do);
+
+static const u16 atl1c_pay_load_size[] = {
+ 128, 256, 512, 1024, 2048, 4096,
+};
+
+static const u16 atl1c_rfd_prod_idx_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+ REG_MB_RFD0_PROD_IDX,
+ REG_MB_RFD1_PROD_IDX,
+ REG_MB_RFD2_PROD_IDX,
+ REG_MB_RFD3_PROD_IDX
+};
+
+static const u16 atl1c_rfd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+ REG_RFD0_HEAD_ADDR_LO,
+ REG_RFD1_HEAD_ADDR_LO,
+ REG_RFD2_HEAD_ADDR_LO,
+ REG_RFD3_HEAD_ADDR_LO
+};
+
+static const u16 atl1c_rrd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+ REG_RRD0_HEAD_ADDR_LO,
+ REG_RRD1_HEAD_ADDR_LO,
+ REG_RRD2_HEAD_ADDR_LO,
+ REG_RRD3_HEAD_ADDR_LO
+};
+
+static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
+ NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
+
+/*
+ * atl1c_init_pcie - init PCIE module
+ */
+static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
+{
+ u32 data;
+ u32 pci_cmd;
+ struct pci_dev *pdev = hw->adapter->pdev;
+
+ AT_READ_REG(hw, PCI_COMMAND, &pci_cmd);
+ pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ pci_cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_IO);
+ AT_WRITE_REG(hw, PCI_COMMAND, pci_cmd);
+
+ /*
+ * Clear any PowerSaveing Settings
+ */
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ /*
+ * Mask some pcie error bits
+ */
+ AT_READ_REG(hw, REG_PCIE_UC_SEVERITY, &data);
+ data &= ~PCIE_UC_SERVRITY_DLP;
+ data &= ~PCIE_UC_SERVRITY_FCP;
+ AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data);
+
+ if (flag & ATL1C_PCIE_L0S_L1_DISABLE)
+ atl1c_disable_l0s_l1(hw);
+ if (flag & ATL1C_PCIE_PHY_RESET)
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
+ else
+ AT_WRITE_REG(hw, REG_GPHY_CTRL,
+ GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET);
+
+ msleep(1);
+}
+
+/*
+ * atl1c_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_enable(struct atl1c_adapter *adapter)
+{
+ if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
+ AT_WRITE_REG(&adapter->hw, REG_ISR, 0x7FFFFFFF);
+ AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+ AT_WRITE_FLUSH(&adapter->hw);
+ }
+}
+
+/*
+ * atl1c_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_disable(struct atl1c_adapter *adapter)
+{
+ atomic_inc(&adapter->irq_sem);
+ AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+ AT_WRITE_FLUSH(&adapter->hw);
+ synchronize_irq(adapter->pdev->irq);
+}
+
+/*
+ * atl1c_irq_reset - reset interrupt confiure on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
+{
+ atomic_set(&adapter->irq_sem, 1);
+ atl1c_irq_enable(adapter);
+}
+
+/*
+ * atl1c_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1c_phy_config(unsigned long data)
+{
+ struct atl1c_adapter *adapter = (struct atl1c_adapter *) data;
+ struct atl1c_hw *hw = &adapter->hw;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ atl1c_restart_autoneg(hw);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+void atl1c_reinit_locked(struct atl1c_adapter *adapter)
+{
+
+ WARN_ON(in_interrupt());
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ clear_bit(__AT_RESETTING, &adapter->flags);
+}
+
+static void atl1c_reset_task(struct work_struct *work)
+{
+ struct atl1c_adapter *adapter;
+ struct net_device *netdev;
+
+ adapter = container_of(work, struct atl1c_adapter, reset_task);
+ netdev = adapter->netdev;
+
+ netif_device_detach(netdev);
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ netif_device_attach(netdev);
+}
+
+static void atl1c_check_link_status(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ int err;
+ unsigned long flags;
+ u16 speed, duplex, phy_data;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ /* MII_BMSR must read twise */
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+
+ if ((phy_data & BMSR_LSTATUS) == 0) {
+ /* link down */
+ if (netif_carrier_ok(netdev)) {
+ hw->hibernate = true;
+ atl1c_set_aspm(hw, false);
+ if (atl1c_stop_mac(hw) != 0)
+ if (netif_msg_hw(adapter))
+ dev_warn(&pdev->dev,
+ "stop mac failed\n");
+ }
+ netif_carrier_off(netdev);
+ } else {
+ /* Link Up */
+ hw->hibernate = false;
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ err = atl1c_get_speed_and_duplex(hw, &speed, &duplex);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+ if (unlikely(err))
+ return;
+ /* link result is our setting */
+ if (adapter->link_speed != speed ||
+ adapter->link_duplex != duplex) {
+ adapter->link_speed = speed;
+ adapter->link_duplex = duplex;
+ atl1c_enable_tx_ctrl(hw);
+ atl1c_enable_rx_ctrl(hw);
+ atl1c_setup_mac_ctrl(adapter);
+ atl1c_set_aspm(hw, true);
+ if (netif_msg_link(adapter))
+ dev_info(&pdev->dev,
+ "%s: %s NIC Link is Up<%d Mbps %s>\n",
+ atl1c_driver_name, netdev->name,
+ adapter->link_speed,
+ adapter->link_duplex == FULL_DUPLEX ?
+ "Full Duplex" : "Half Duplex");
+ }
+ if (!netif_carrier_ok(netdev))
+ netif_carrier_on(netdev);
+ }
+}
+
+/*
+ * atl1c_link_chg_task - deal with link change event Out of interrupt context
+ * @netdev: network interface device structure
+ */
+static void atl1c_link_chg_task(struct work_struct *work)
+{
+ struct atl1c_adapter *adapter;
+
+ adapter = container_of(work, struct atl1c_adapter, link_chg_task);
+ atl1c_check_link_status(adapter);
+}
+
+static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 phy_data;
+ u16 link_up;
+
+ spin_lock(&adapter->mdio_lock);
+ atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ spin_unlock(&adapter->mdio_lock);
+ link_up = phy_data & BMSR_LSTATUS;
+ /* notify upper layer link down ASAP */
+ if (!link_up) {
+ if (netif_carrier_ok(netdev)) {
+ /* old link state: Up */
+ netif_carrier_off(netdev);
+ if (netif_msg_link(adapter))
+ dev_info(&pdev->dev,
+ "%s: %s NIC Link is Down\n",
+ atl1c_driver_name, netdev->name);
+ adapter->link_speed = SPEED_0;
+ }
+ }
+ schedule_work(&adapter->link_chg_task);
+}
+
+static void atl1c_del_timer(struct atl1c_adapter *adapter)
+{
+ del_timer_sync(&adapter->phy_config_timer);
+}
+
+static void atl1c_cancel_work(struct atl1c_adapter *adapter)
+{
+ cancel_work_sync(&adapter->reset_task);
+ cancel_work_sync(&adapter->link_chg_task);
+}
+
+/*
+ * atl1c_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl1c_tx_timeout(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ /* Do the reset outside of interrupt context */
+ schedule_work(&adapter->reset_task);
+}
+
+/*
+ * atl1c_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ */
+static void atl1c_set_multi(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ struct dev_mc_list *mc_ptr;
+ u32 mac_ctrl_data;
+ u32 hash_value;
+
+ /* Check for Promiscuous and All Multicast modes */
+ AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
+
+ if (netdev->flags & IFF_PROMISC) {
+ mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+ } else if (netdev->flags & IFF_ALLMULTI) {
+ mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+ mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
+ } else {
+ mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+ }
+
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+ /* clear the old settings from the multicast hash table */
+ AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+ AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+ /* comoute mc addresses' hash value ,and put it into hash table */
+ for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+ hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr);
+ atl1c_hash_set(hw, hash_value);
+ }
+}
+
+static void atl1c_vlan_rx_register(struct net_device *netdev,
+ struct vlan_group *grp)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ u32 mac_ctrl_data = 0;
+
+ if (netif_msg_pktdata(adapter))
+ dev_dbg(&pdev->dev, "atl1c_vlan_rx_register\n");
+
+ atl1c_irq_disable(adapter);
+
+ adapter->vlgrp = grp;
+ AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data);
+
+ if (grp) {
+ /* enable VLAN tag insert/strip */
+ mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+ } else {
+ /* disable VLAN tag insert/strip */
+ mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
+ }
+
+ AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
+ atl1c_irq_enable(adapter);
+}
+
+static void atl1c_restore_vlan(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ if (netif_msg_pktdata(adapter))
+ dev_dbg(&pdev->dev, "atl1c_restore_vlan !");
+ atl1c_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+}
+/*
+ * atl1c_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1c_set_mac_addr(struct net_device *netdev, void *p)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (netif_running(netdev))
+ return -EBUSY;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+ atl1c_hw_set_mac_addr(&adapter->hw);
+
+ return 0;
+}
+
+static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
+ struct net_device *dev)
+{
+ int mtu = dev->mtu;
+
+ adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
+ roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
+}
+/*
+ * atl1c_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ int old_mtu = netdev->mtu;
+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+ if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+ (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+ return -EINVAL;
+ }
+ /* set MTU */
+ if (old_mtu != new_mtu && netif_running(netdev)) {
+ while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+ msleep(1);
+ netdev->mtu = new_mtu;
+ adapter->hw.max_frame_size = new_mtu;
+ atl1c_set_rxbufsize(adapter, netdev);
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
+ u32 phy_data;
+
+ AT_READ_REG(&adapter->hw, 0x1414, &phy_data);
+ phy_data |= 0x10000000;
+ AT_WRITE_REG(&adapter->hw, 0x1414, phy_data);
+ }
+
+ }
+ return 0;
+}
+
+/*
+ * caller should hold mdio_lock
+ */
+static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ u16 result;
+
+ atl1c_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
+ return result;
+}
+
+static void atl1c_mdio_write(struct net_device *netdev, int phy_id,
+ int reg_num, int val)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ atl1c_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
+}
+
+/*
+ * atl1c_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1c_mii_ioctl(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ struct mii_ioctl_data *data = if_mii(ifr);
+ unsigned long flags;
+ int retval = 0;
+
+ if (!netif_running(netdev))
+ return -EINVAL;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ data->phy_id = 0;
+ break;
+
+ case SIOCGMIIREG:
+ if (!capable(CAP_NET_ADMIN)) {
+ retval = -EPERM;
+ goto out;
+ }
+ if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+ &data->val_out)) {
+ retval = -EIO;
+ goto out;
+ }
+ break;
+
+ case SIOCSMIIREG:
+ if (!capable(CAP_NET_ADMIN)) {
+ retval = -EPERM;
+ goto out;
+ }
+ if (data->reg_num & ~(0x1F)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ dev_dbg(&pdev->dev, "<atl1c_mii_ioctl> write %x %x",
+ data->reg_num, data->val_in);
+ if (atl1c_write_phy_reg(&adapter->hw,
+ data->reg_num, data->val_in)) {
+ retval = -EIO;
+ goto out;
+ }
+ break;
+
+ default:
+ retval = -EOPNOTSUPP;
+ break;
+ }
+out:
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+ return retval;
+}
+
+/*
+ * atl1c_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1c_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ return atl1c_mii_ioctl(netdev, ifr, cmd);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+/*
+ * atl1c_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ */
+static int __devinit atl1c_alloc_queues(struct atl1c_adapter *adapter)
+{
+ return 0;
+}
+
+static void atl1c_set_mac_type(struct atl1c_hw *hw)
+{
+ switch (hw->device_id) {
+ case PCI_DEVICE_ID_ATTANSIC_L2C:
+ hw->nic_type = athr_l2c;
+ break;
+
+ case PCI_DEVICE_ID_ATTANSIC_L1C:
+ hw->nic_type = athr_l1c;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
+{
+ u32 phy_status_data;
+ u32 link_ctrl_data;
+
+ atl1c_set_mac_type(hw);
+ AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data);
+ AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
+
+ hw->ctrl_flags = ATL1C_INTR_CLEAR_ON_READ |
+ ATL1C_INTR_MODRT_ENABLE |
+ ATL1C_RX_IPV6_CHKSUM |
+ ATL1C_TXQ_MODE_ENHANCE;
+ if (link_ctrl_data & LINK_CTRL_L0S_EN)
+ hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT;
+ if (link_ctrl_data & LINK_CTRL_L1_EN)
+ hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT;
+
+ if (hw->nic_type == athr_l1c) {
+ hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON;
+ hw->ctrl_flags |= ATL1C_LINK_CAP_1000M;
+ }
+ return 0;
+}
+/*
+ * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl1c_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ */
+static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+
+ adapter->wol = 0;
+ adapter->link_speed = SPEED_0;
+ adapter->link_duplex = FULL_DUPLEX;
+ adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE;
+ adapter->tpd_ring[0].count = 1024;
+ adapter->rfd_ring[0].count = 512;
+
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_id = pdev->subsystem_device;
+
+ /* before link up, we assume hibernate is true */
+ hw->hibernate = true;
+ hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
+ if (atl1c_setup_mac_funcs(hw) != 0) {
+ dev_err(&pdev->dev, "set mac function pointers failed\n");
+ return -1;
+ }
+ hw->intr_mask = IMR_NORMAL_MASK;
+ hw->phy_configured = false;
+ hw->preamble_len = 7;
+ hw->max_frame_size = adapter->netdev->mtu;
+ if (adapter->num_rx_queues < 2) {
+ hw->rss_type = atl1c_rss_disable;
+ hw->rss_mode = atl1c_rss_mode_disable;
+ } else {
+ hw->rss_type = atl1c_rss_ipv4;
+ hw->rss_mode = atl1c_rss_mul_que_mul_int;
+ hw->rss_hash_bits = 16;
+ }
+ hw->autoneg_advertised = ADVERTISED_Autoneg;
+ hw->indirect_tab = 0xE4E4E4E4;
+ hw->base_cpu = 0;
+
+ hw->ict = 50000; /* 100ms */
+ hw->smb_timer = 200000; /* 400ms */
+ hw->cmb_tpd = 4;
+ hw->cmb_tx_timer = 1; /* 2 us */
+ hw->rx_imt = 200;
+ hw->tx_imt = 1000;
+
+ hw->tpd_burst = 5;
+ hw->rfd_burst = 8;
+ hw->dma_order = atl1c_dma_ord_out;
+ hw->dmar_block = atl1c_dma_req_1024;
+ hw->dmaw_block = atl1c_dma_req_1024;
+ hw->dmar_dly_cnt = 15;
+ hw->dmaw_dly_cnt = 4;
+
+ if (atl1c_alloc_queues(adapter)) {
+ dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
+ }
+ /* TODO */
+ atl1c_set_rxbufsize(adapter, adapter->netdev);
+ atomic_set(&adapter->irq_sem, 1);
+ spin_lock_init(&adapter->mdio_lock);
+ spin_lock_init(&adapter->tx_lock);
+ set_bit(__AT_DOWN, &adapter->flags);
+
+ return 0;
+}
+
+/*
+ * atl1c_clean_tx_ring - Free Tx-skb
+ * @adapter: board private structure
+ */
+static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 index, ring_count;
+
+ ring_count = tpd_ring->count;
+ for (index = 0; index < ring_count; index++) {
+ buffer_info = &tpd_ring->buffer_info[index];
+ if (buffer_info->state == ATL1_BUFFER_FREE)
+ continue;
+ if (buffer_info->dma)
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length,
+ PCI_DMA_TODEVICE);
+ if (buffer_info->skb)
+ dev_kfree_skb(buffer_info->skb);
+ buffer_info->dma = 0;
+ buffer_info->skb = NULL;
+ buffer_info->state = ATL1_BUFFER_FREE;
+ }
+
+ /* Zero out Tx-buffers */
+ memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
+ ring_count);
+ atomic_set(&tpd_ring->next_to_clean, 0);
+ tpd_ring->next_to_use = 0;
+}
+
+/*
+ * atl1c_clean_rx_ring - Free rx-reservation skbs
+ * @adapter: board private structure
+ */
+static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
+{
+ struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+ struct atl1c_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ int i, j;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ for (j = 0; j < rfd_ring[i].count; j++) {
+ buffer_info = &rfd_ring[i].buffer_info[j];
+ if (buffer_info->state == ATL1_BUFFER_FREE)
+ continue;
+ if (buffer_info->dma)
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length,
+ PCI_DMA_FROMDEVICE);
+ if (buffer_info->skb)
+ dev_kfree_skb(buffer_info->skb);
+ buffer_info->state = ATL1_BUFFER_FREE;
+ buffer_info->skb = NULL;
+ }
+ /* zero out the descriptor ring */
+ memset(rfd_ring[i].desc, 0, rfd_ring[i].size);
+ rfd_ring[i].next_to_clean = 0;
+ rfd_ring[i].next_to_use = 0;
+ rrd_ring[i].next_to_use = 0;
+ rrd_ring[i].next_to_clean = 0;
+ }
+}
+
+/*
+ * Read / Write Ptr Initialize:
+ */
+static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
+{
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+ struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+ struct atl1c_buffer *buffer_info;
+ int i, j;
+
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].next_to_use = 0;
+ atomic_set(&tpd_ring[i].next_to_clean, 0);
+ buffer_info = tpd_ring[i].buffer_info;
+ for (j = 0; j < tpd_ring->count; j++)
+ buffer_info[i].state = ATL1_BUFFER_FREE;
+ }
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ rfd_ring[i].next_to_use = 0;
+ rfd_ring[i].next_to_clean = 0;
+ rrd_ring[i].next_to_use = 0;
+ rrd_ring[i].next_to_clean = 0;
+ for (j = 0; j < rfd_ring[i].count; j++) {
+ buffer_info = &rfd_ring[i].buffer_info[j];
+ buffer_info->state = ATL1_BUFFER_FREE;
+ }
+ }
+}
+
+/*
+ * atl1c_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl1c_free_ring_resources(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ pci_free_consistent(pdev, adapter->ring_header.size,
+ adapter->ring_header.desc,
+ adapter->ring_header.dma);
+ adapter->ring_header.desc = NULL;
+
+ /* Note: just free tdp_ring.buffer_info,
+ * it contain rfd_ring.buffer_info, do not double free */
+ if (adapter->tpd_ring[0].buffer_info) {
+ kfree(adapter->tpd_ring[0].buffer_info);
+ adapter->tpd_ring[0].buffer_info = NULL;
+ }
+}
+
+/*
+ * atl1c_setup_mem_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+ struct atl1c_rfd_ring *rfd_ring = adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = adapter->rrd_ring;
+ struct atl1c_ring_header *ring_header = &adapter->ring_header;
+ int num_rx_queues = adapter->num_rx_queues;
+ int size;
+ int i;
+ int count = 0;
+ int rx_desc_count = 0;
+ u32 offset = 0;
+
+ rrd_ring[0].count = rfd_ring[0].count;
+ for (i = 1; i < AT_MAX_TRANSMIT_QUEUE; i++)
+ tpd_ring[i].count = tpd_ring[0].count;
+
+ for (i = 1; i < adapter->num_rx_queues; i++)
+ rfd_ring[i].count = rrd_ring[i].count = rfd_ring[0].count;
+
+ /* 2 tpd queue, one high priority queue,
+ * another normal priority queue */
+ size = sizeof(struct atl1c_buffer) * (tpd_ring->count * 2 +
+ rfd_ring->count * num_rx_queues);
+ tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
+ if (unlikely(!tpd_ring->buffer_info)) {
+ dev_err(&pdev->dev, "kzalloc failed, size = %d\n",
+ size);
+ goto err_nomem;
+ }
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].buffer_info =
+ (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
+ count += tpd_ring[i].count;
+ }
+
+ for (i = 0; i < num_rx_queues; i++) {
+ rfd_ring[i].buffer_info =
+ (struct atl1c_buffer *) (tpd_ring->buffer_info + count);
+ count += rfd_ring[i].count;
+ rx_desc_count += rfd_ring[i].count;
+ }
+ /*
+ * real ring DMA buffer
+ * each ring/block may need up to 8 bytes for alignment, hence the
+ * additional bytes tacked onto the end.
+ */
+ ring_header->size = size =
+ sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 +
+ sizeof(struct atl1c_rx_free_desc) * rx_desc_count +
+ sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
+ sizeof(struct atl1c_hw_stats) +
+ 8 * 4 + 8 * 2 * num_rx_queues;
+
+ ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
+ &ring_header->dma);
+ if (unlikely(!ring_header->desc)) {
+ dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+ goto err_nomem;
+ }
+ memset(ring_header->desc, 0, ring_header->size);
+ /* init TPD ring */
+
+ tpd_ring[0].dma = roundup(ring_header->dma, 8);
+ offset = tpd_ring[0].dma - ring_header->dma;
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].dma = ring_header->dma + offset;
+ tpd_ring[i].desc = (u8 *) ring_header->desc + offset;
+ tpd_ring[i].size =
+ sizeof(struct atl1c_tpd_desc) * tpd_ring[i].count;
+ offset += roundup(tpd_ring[i].size, 8);
+ }
+ /* init RFD ring */
+ for (i = 0; i < num_rx_queues; i++) {
+ rfd_ring[i].dma = ring_header->dma + offset;
+ rfd_ring[i].desc = (u8 *) ring_header->desc + offset;
+ rfd_ring[i].size = sizeof(struct atl1c_rx_free_desc) *
+ rfd_ring[i].count;
+ offset += roundup(rfd_ring[i].size, 8);
+ }
+
+ /* init RRD ring */
+ for (i = 0; i < num_rx_queues; i++) {
+ rrd_ring[i].dma = ring_header->dma + offset;
+ rrd_ring[i].desc = (u8 *) ring_header->desc + offset;
+ rrd_ring[i].size = sizeof(struct atl1c_recv_ret_status) *
+ rrd_ring[i].count;
+ offset += roundup(rrd_ring[i].size, 8);
+ }
+
+ adapter->smb.dma = ring_header->dma + offset;
+ adapter->smb.smb = (u8 *)ring_header->desc + offset;
+ return 0;
+
+err_nomem:
+ kfree(tpd_ring->buffer_info);
+ return -ENOMEM;
+}
+
+static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct atl1c_rfd_ring *rfd_ring = (struct atl1c_rfd_ring *)
+ adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = (struct atl1c_rrd_ring *)
+ adapter->rrd_ring;
+ struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
+ adapter->tpd_ring;
+ struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb;
+ struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb;
+ int i;
+
+ /* TPD */
+ AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI,
+ (u32)((tpd_ring[atl1c_trans_normal].dma &
+ AT_DMA_HI_ADDR_MASK) >> 32));
+ /* just enable normal priority TX queue */
+ AT_WRITE_REG(hw, REG_NTPD_HEAD_ADDR_LO,
+ (u32)(tpd_ring[atl1c_trans_normal].dma &
+ AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_HTPD_HEAD_ADDR_LO,
+ (u32)(tpd_ring[atl1c_trans_high].dma &
+ AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_TPD_RING_SIZE,
+ (u32)(tpd_ring[0].count & TPD_RING_SIZE_MASK));
+
+
+ /* RFD */
+ AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI,
+ (u32)((rfd_ring[0].dma & AT_DMA_HI_ADDR_MASK) >> 32));
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ AT_WRITE_REG(hw, atl1c_rfd_addr_lo_regs[i],
+ (u32)(rfd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
+
+ AT_WRITE_REG(hw, REG_RFD_RING_SIZE,
+ rfd_ring[0].count & RFD_RING_SIZE_MASK);
+ AT_WRITE_REG(hw, REG_RX_BUF_SIZE,
+ adapter->rx_buffer_len & RX_BUF_SIZE_MASK);
+
+ /* RRD */
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ AT_WRITE_REG(hw, atl1c_rrd_addr_lo_regs[i],
+ (u32)(rrd_ring[i].dma & AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_RRD_RING_SIZE,
+ (rrd_ring[0].count & RRD_RING_SIZE_MASK));
+
+ /* CMB */
+ AT_WRITE_REG(hw, REG_CMB_BASE_ADDR_LO, cmb->dma & AT_DMA_LO_ADDR_MASK);
+
+ /* SMB */
+ AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_HI,
+ (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32));
+ AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO,
+ (u32)(smb->dma & AT_DMA_LO_ADDR_MASK));
+ /* Load all of base address above */
+ AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
+}
+
+static void atl1c_configure_tx(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 dev_ctrl_data;
+ u32 max_pay_load;
+ u16 tx_offload_thresh;
+ u32 txq_ctrl_data;
+ u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */
+
+ extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
+ tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
+ AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
+ (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
+ AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data);
+ max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) &
+ DEVICE_CTRL_MAX_PAYLOAD_MASK;
+ hw->dmaw_block = min(max_pay_load, hw->dmaw_block);
+ max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) &
+ DEVICE_CTRL_MAX_RREQ_SZ_MASK;
+ hw->dmar_block = min(max_pay_load, hw->dmar_block);
+
+ txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) <<
+ TXQ_NUM_TPD_BURST_SHIFT;
+ if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE)
+ txq_ctrl_data |= TXQ_CTRL_ENH_MODE;
+ txq_ctrl_data |= (atl1c_pay_load_size[hw->dmar_block] &
+ TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT;
+
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data);
+}
+
+static void atl1c_configure_rx(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 rxq_ctrl_data;
+
+ rxq_ctrl_data = (hw->rfd_burst & RXQ_RFD_BURST_NUM_MASK) <<
+ RXQ_RFD_BURST_NUM_SHIFT;
+
+ if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM)
+ rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN;
+ if (hw->rss_type == atl1c_rss_ipv4)
+ rxq_ctrl_data |= RSS_HASH_IPV4;
+ if (hw->rss_type == atl1c_rss_ipv4_tcp)
+ rxq_ctrl_data |= RSS_HASH_IPV4_TCP;
+ if (hw->rss_type == atl1c_rss_ipv6)
+ rxq_ctrl_data |= RSS_HASH_IPV6;
+ if (hw->rss_type == atl1c_rss_ipv6_tcp)
+ rxq_ctrl_data |= RSS_HASH_IPV6_TCP;
+ if (hw->rss_type != atl1c_rss_disable)
+ rxq_ctrl_data |= RRS_HASH_CTRL_EN;
+
+ rxq_ctrl_data |= (hw->rss_mode & RSS_MODE_MASK) <<
+ RSS_MODE_SHIFT;
+ rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) <<
+ RSS_HASH_BITS_SHIFT;
+ if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON)
+ rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_100M &
+ ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT;
+
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
+}
+
+static void atl1c_configure_rss(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+
+ AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
+ AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
+}
+
+static void atl1c_configure_dma(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 dma_ctrl_data;
+
+ dma_ctrl_data = DMA_CTRL_DMAR_REQ_PRI;
+ if (hw->ctrl_flags & ATL1C_CMB_ENABLE)
+ dma_ctrl_data |= DMA_CTRL_CMB_EN;
+ if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
+ dma_ctrl_data |= DMA_CTRL_SMB_EN;
+ else
+ dma_ctrl_data |= MAC_CTRL_SMB_DIS;
+
+ switch (hw->dma_order) {
+ case atl1c_dma_ord_in:
+ dma_ctrl_data |= DMA_CTRL_DMAR_IN_ORDER;
+ break;
+ case atl1c_dma_ord_enh:
+ dma_ctrl_data |= DMA_CTRL_DMAR_ENH_ORDER;
+ break;
+ case atl1c_dma_ord_out:
+ dma_ctrl_data |= DMA_CTRL_DMAR_OUT_ORDER;
+ break;
+ default:
+ break;
+ }
+
+ dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
+ << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
+ dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+ << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
+ dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
+ << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
+ dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
+ << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
+
+ AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
+}
+
+/*
+ * Stop the mac, transmit and receive units
+ * hw - Struct containing variables accessed by shared code
+ * return : 0 or idle status (if error)
+ */
+static int atl1c_stop_mac(struct atl1c_hw *hw)
+{
+ u32 data;
+ int timeout;
+
+ AT_READ_REG(hw, REG_RXQ_CTRL, &data);
+ data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN |
+ RXQ3_CTRL_EN | RXQ_CTRL_EN);
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
+
+ AT_READ_REG(hw, REG_TXQ_CTRL, &data);
+ data &= ~TXQ_CTRL_EN;
+ AT_WRITE_REG(hw, REG_TWSI_CTRL, data);
+
+ for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+ AT_READ_REG(hw, REG_IDLE_STATUS, &data);
+ if ((data & (IDLE_STATUS_RXQ_NO_IDLE |
+ IDLE_STATUS_TXQ_NO_IDLE)) == 0)
+ break;
+ msleep(1);
+ }
+
+ AT_READ_REG(hw, REG_MAC_CTRL, &data);
+ data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, data);
+
+ for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+ AT_READ_REG(hw, REG_IDLE_STATUS, &data);
+ if ((data & IDLE_STATUS_MASK) == 0)
+ return 0;
+ msleep(1);
+ }
+ return data;
+}
+
+static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_RXQ_CTRL, &data);
+ switch (hw->adapter->num_rx_queues) {
+ case 4:
+ data |= (RXQ3_CTRL_EN | RXQ2_CTRL_EN | RXQ1_CTRL_EN);
+ break;
+ case 3:
+ data |= (RXQ2_CTRL_EN | RXQ1_CTRL_EN);
+ break;
+ case 2:
+ data |= RXQ1_CTRL_EN;
+ break;
+ default:
+ break;
+ }
+ data |= RXQ_CTRL_EN;
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
+}
+
+static void atl1c_enable_tx_ctrl(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_TXQ_CTRL, &data);
+ data |= TXQ_CTRL_EN;
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, data);
+}
+
+/*
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ * hw - Struct containing variables accessed by shared code
+ * return : 0 or idle status (if error)
+ */
+static int atl1c_reset_mac(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 idle_status_data = 0;
+ int timeout = 0;
+ int ret;
+
+ AT_WRITE_REG(hw, REG_IMR, 0);
+ AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT);
+
+ ret = atl1c_stop_mac(hw);
+ if (ret)
+ return ret;
+ /*
+ * Issue Soft Reset to the MAC. This will reset the chip's
+ * transmit, receive, DMA. It will not effect
+ * the current PCI configuration. The global reset bit is self-
+ * clearing, and should clear within a microsecond.
+ */
+ AT_WRITE_REGW(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST);
+ AT_WRITE_FLUSH(hw);
+ msleep(10);
+ /* Wait at least 10ms for All module to be Idle */
+ for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+ AT_READ_REG(hw, REG_IDLE_STATUS, &idle_status_data);
+ if ((idle_status_data & IDLE_STATUS_MASK) == 0)
+ break;
+ msleep(1);
+ }
+ if (timeout >= AT_HW_MAX_IDLE_DELAY) {
+ dev_err(&pdev->dev,
+ "MAC state machine cann't be idle since"
+ " disabled for 10ms second\n");
+ return -1;
+ }
+ return 0;
+}
+
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw)
+{
+ u32 pm_ctrl_data;
+
+ AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
+ pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
+ PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+ pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+ pm_ctrl_data &= ~PM_CTRL_MAC_ASPM_CHK;
+ pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
+
+ pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
+ pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
+ pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
+ AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
+}
+
+/*
+ * Set ASPM state.
+ * Enable/disable L0s/L1 depend on link state.
+ */
+static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
+{
+ u32 pm_ctrl_data;
+
+ AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
+
+ pm_ctrl_data &= PM_CTRL_SERDES_PD_EX_L1;
+ pm_ctrl_data |= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
+ pm_ctrl_data |= ~PM_CTRL_SERDES_L1_EN;
+ pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
+ PM_CTRL_L1_ENTRY_TIMER_SHIFT);
+
+ pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK;
+
+ if (linkup) {
+ pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
+ pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
+
+ if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) {
+ pm_ctrl_data |= AT_ASPM_L1_TIMER <<
+ PM_CTRL_L1_ENTRY_TIMER_SHIFT;
+ pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
+ } else
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+
+ if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
+ pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
+ else
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+
+ } else {
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+ pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
+
+ pm_ctrl_data |= PM_CTRL_CLK_SWH_L1;
+
+ if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT)
+ pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
+ else
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
+ }
+
+ AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
+}
+
+static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ u32 mac_ctrl_data;
+
+ mac_ctrl_data = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN;
+ mac_ctrl_data |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+
+ if (adapter->link_duplex == FULL_DUPLEX) {
+ hw->mac_duplex = true;
+ mac_ctrl_data |= MAC_CTRL_DUPLX;
+ }
+
+ if (adapter->link_speed == SPEED_1000)
+ hw->mac_speed = atl1c_mac_speed_1000;
+ else
+ hw->mac_speed = atl1c_mac_speed_10_100;
+
+ mac_ctrl_data |= (hw->mac_speed & MAC_CTRL_SPEED_MASK) <<
+ MAC_CTRL_SPEED_SHIFT;
+
+ mac_ctrl_data |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+ mac_ctrl_data |= ((hw->preamble_len & MAC_CTRL_PRMLEN_MASK) <<
+ MAC_CTRL_PRMLEN_SHIFT);
+
+ if (adapter->vlgrp)
+ mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+
+ mac_ctrl_data |= MAC_CTRL_BC_EN;
+ if (netdev->flags & IFF_PROMISC)
+ mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+ if (netdev->flags & IFF_ALLMULTI)
+ mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+
+ mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN;
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+}
+
+/*
+ * atl1c_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl1c_configure(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 master_ctrl_data = 0;
+ u32 intr_modrt_data;
+
+ /* clear interrupt status */
+ AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF);
+ /* Clear any WOL status */
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+ /* set Interrupt Clear Timer
+ * HW will enable self to assert interrupt event to system after
+ * waiting x-time for software to notify it accept interrupt.
+ */
+ AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER,
+ hw->ict & INT_RETRIG_TIMER_MASK);
+
+ atl1c_configure_des_ring(adapter);
+
+ if (hw->ctrl_flags & ATL1C_INTR_MODRT_ENABLE) {
+ intr_modrt_data = (hw->tx_imt & IRQ_MODRT_TIMER_MASK) <<
+ IRQ_MODRT_TX_TIMER_SHIFT;
+ intr_modrt_data |= (hw->rx_imt & IRQ_MODRT_TIMER_MASK) <<
+ IRQ_MODRT_RX_TIMER_SHIFT;
+ AT_WRITE_REG(hw, REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data);
+ master_ctrl_data |=
+ MASTER_CTRL_TX_ITIMER_EN | MASTER_CTRL_RX_ITIMER_EN;
+ }
+
+ if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ)
+ master_ctrl_data |= MASTER_CTRL_INT_RDCLR;
+
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+
+ if (hw->ctrl_flags & ATL1C_CMB_ENABLE) {
+ AT_WRITE_REG(hw, REG_CMB_TPD_THRESH,
+ hw->cmb_tpd & CMB_TPD_THRESH_MASK);
+ AT_WRITE_REG(hw, REG_CMB_TX_TIMER,
+ hw->cmb_tx_timer & CMB_TX_TIMER_MASK);
+ }
+
+ if (hw->ctrl_flags & ATL1C_SMB_ENABLE)
+ AT_WRITE_REG(hw, REG_SMB_STAT_TIMER,
+ hw->smb_timer & SMB_STAT_TIMER_MASK);
+ /* set MTU */
+ AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
+ VLAN_HLEN + ETH_FCS_LEN);
+ /* HDS, disable */
+ AT_WRITE_REG(hw, REG_HDS_CTRL, 0);
+
+ atl1c_configure_tx(adapter);
+ atl1c_configure_rx(adapter);
+ atl1c_configure_rss(adapter);
+ atl1c_configure_dma(adapter);
+
+ return 0;
+}
+
+static void atl1c_update_hw_stats(struct atl1c_adapter *adapter)
+{
+ u16 hw_reg_addr = 0;
+ unsigned long *stats_item = NULL;
+ u32 data;
+
+ /* update rx status */
+ hw_reg_addr = REG_MAC_RX_STATUS_BIN;
+ stats_item = &adapter->hw_stats.rx_ok;
+ while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
+ AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+ *stats_item += data;
+ stats_item++;
+ hw_reg_addr += 4;
+ }
+/* update tx status */
+ hw_reg_addr = REG_MAC_TX_STATUS_BIN;
+ stats_item = &adapter->hw_stats.tx_ok;
+ while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
+ AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+ *stats_item += data;
+ stats_item++;
+ hw_reg_addr += 4;
+ }
+}
+
+/*
+ * atl1c_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ */
+static struct net_device_stats *atl1c_get_stats(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw_stats *hw_stats = &adapter->hw_stats;
+ struct net_device_stats *net_stats = &adapter->net_stats;
+
+ atl1c_update_hw_stats(adapter);
+ net_stats->rx_packets = hw_stats->rx_ok;
+ net_stats->tx_packets = hw_stats->tx_ok;
+ net_stats->rx_bytes = hw_stats->rx_byte_cnt;
+ net_stats->tx_bytes = hw_stats->tx_byte_cnt;
+ net_stats->multicast = hw_stats->rx_mcast;
+ net_stats->collisions = hw_stats->tx_1_col +
+ hw_stats->tx_2_col * 2 +
+ hw_stats->tx_late_col + hw_stats->tx_abort_col;
+ net_stats->rx_errors = hw_stats->rx_frag + hw_stats->rx_fcs_err +
+ hw_stats->rx_len_err + hw_stats->rx_sz_ov +
+ hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
+ net_stats->rx_fifo_errors = hw_stats->rx_rxf_ov;
+ net_stats->rx_length_errors = hw_stats->rx_len_err;
+ net_stats->rx_crc_errors = hw_stats->rx_fcs_err;
+ net_stats->rx_frame_errors = hw_stats->rx_align_err;
+ net_stats->rx_over_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+ net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+ net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
+ hw_stats->tx_underrun + hw_stats->tx_trunc;
+ net_stats->tx_fifo_errors = hw_stats->tx_underrun;
+ net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+ net_stats->tx_window_errors = hw_stats->tx_late_col;
+
+ return &adapter->net_stats;
+}
+
+static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter)
+{
+ u16 phy_data;
+
+ spin_lock(&adapter->mdio_lock);
+ atl1c_read_phy_reg(&adapter->hw, MII_ISR, &phy_data);
+ spin_unlock(&adapter->mdio_lock);
+}
+
+static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
+ &adapter->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+ u16 hw_next_to_clean;
+ u16 shift;
+ u32 data;
+
+ if (type == atl1c_trans_high)
+ shift = MB_HTPD_CONS_IDX_SHIFT;
+ else
+ shift = MB_NTPD_CONS_IDX_SHIFT;
+
+ AT_READ_REG(&adapter->hw, REG_MB_PRIO_CONS_IDX, &data);
+ hw_next_to_clean = (data >> shift) & MB_PRIO_PROD_IDX_MASK;
+
+ while (next_to_clean != hw_next_to_clean) {
+ buffer_info = &tpd_ring->buffer_info[next_to_clean];
+ if (buffer_info->state == ATL1_BUFFER_BUSY) {
+ pci_unmap_page(adapter->pdev, buffer_info->dma,
+ buffer_info->length, PCI_DMA_TODEVICE);
+ buffer_info->dma = 0;
+ if (buffer_info->skb) {
+ dev_kfree_skb_irq(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
+ buffer_info->state = ATL1_BUFFER_FREE;
+ }
+ if (++next_to_clean == tpd_ring->count)
+ next_to_clean = 0;
+ atomic_set(&tpd_ring->next_to_clean, next_to_clean);
+ }
+
+ if (netif_queue_stopped(adapter->netdev) &&
+ netif_carrier_ok(adapter->netdev)) {
+ netif_wake_queue(adapter->netdev);
+ }
+
+ return true;
+}
+
+/*
+ * atl1c_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ */
+static irqreturn_t atl1c_intr(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_hw *hw = &adapter->hw;
+ int max_ints = AT_MAX_INT_WORK;
+ int handled = IRQ_NONE;
+ u32 status;
+ u32 reg_data;
+
+ do {
+ AT_READ_REG(hw, REG_ISR, &reg_data);
+ status = reg_data & hw->intr_mask;
+
+ if (status == 0 || (status & ISR_DIS_INT) != 0) {
+ if (max_ints != AT_MAX_INT_WORK)
+ handled = IRQ_HANDLED;
+ break;
+ }
+ /* link event */
+ if (status & ISR_GPHY)
+ atl1c_clear_phy_int(adapter);
+ /* Ack ISR */
+ AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+ if (status & ISR_RX_PKT) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
+ hw->intr_mask &= ~ISR_RX_PKT;
+ AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
+ __napi_schedule(&adapter->napi);
+ }
+ }
+ if (status & ISR_TX_PKT)
+ atl1c_clean_tx_irq(adapter, atl1c_trans_normal);
+
+ handled = IRQ_HANDLED;
+ /* check if PCIE PHY Link down */
+ if (status & ISR_ERROR) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "atl1c hardware error (status = 0x%x)\n",
+ status & ISR_ERROR);
+ /* reset MAC */
+ hw->intr_mask &= ~ISR_ERROR;
+ AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
+ schedule_work(&adapter->reset_task);
+ break;
+ }
+
+ if (status & ISR_OVER)
+ if (netif_msg_intr(adapter))
+ dev_warn(&pdev->dev,
+ "TX/RX over flow (status = 0x%x)\n",
+ status & ISR_OVER);
+
+ /* link event */
+ if (status & (ISR_GPHY | ISR_MANUAL)) {
+ adapter->net_stats.tx_carrier_errors++;
+ atl1c_link_chg_event(adapter);
+ break;
+ }
+
+ } while (--max_ints > 0);
+ /* re-enable Interrupt*/
+ AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+ return handled;
+}
+
+static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
+ struct sk_buff *skb, struct atl1c_recv_ret_status *prrs)
+{
+ /*
+ * The pid field in RRS in not correct sometimes, so we
+ * cannot figure out if the packet is fragmented or not,
+ * so we tell the KERNEL CHECKSUM_NONE
+ */
+ skb->ip_summed = CHECKSUM_NONE;
+}
+
+static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid)
+{
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[ringid];
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_buffer *buffer_info, *next_info;
+ struct sk_buff *skb;
+ void *vir_addr = NULL;
+ u16 num_alloc = 0;
+ u16 rfd_next_to_use, next_next;
+ struct atl1c_rx_free_desc *rfd_desc;
+
+ next_next = rfd_next_to_use = rfd_ring->next_to_use;
+ if (++next_next == rfd_ring->count)
+ next_next = 0;
+ buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+ next_info = &rfd_ring->buffer_info[next_next];
+
+ while (next_info->state == ATL1_BUFFER_FREE) {
+ rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
+
+ skb = dev_alloc_skb(adapter->rx_buffer_len);
+ if (unlikely(!skb)) {
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev, "alloc rx buffer failed\n");
+ break;
+ }
+
+ /*
+ * Make buffer alignment 2 beyond a 16 byte boundary
+ * this will result in a 16 byte aligned IP header after
+ * the 14 byte MAC header is removed
+ */
+ vir_addr = skb->data;
+ buffer_info->state = ATL1_BUFFER_BUSY;
+ buffer_info->skb = skb;
+ buffer_info->length = adapter->rx_buffer_len;
+ buffer_info->dma = pci_map_single(pdev, vir_addr,
+ buffer_info->length,
+ PCI_DMA_FROMDEVICE);
+ rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+ rfd_next_to_use = next_next;
+ if (++next_next == rfd_ring->count)
+ next_next = 0;
+ buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+ next_info = &rfd_ring->buffer_info[next_next];
+ num_alloc++;
+ }
+
+ if (num_alloc) {
+ /* TODO: update mailbox here */
+ wmb();
+ rfd_ring->next_to_use = rfd_next_to_use;
+ AT_WRITE_REG(&adapter->hw, atl1c_rfd_prod_idx_regs[ringid],
+ rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK);
+ }
+
+ return num_alloc;
+}
+
+static void atl1c_clean_rrd(struct atl1c_rrd_ring *rrd_ring,
+ struct atl1c_recv_ret_status *rrs, u16 num)
+{
+ u16 i;
+ /* the relationship between rrd and rfd is one map one */
+ for (i = 0; i < num; i++, rrs = ATL1C_RRD_DESC(rrd_ring,
+ rrd_ring->next_to_clean)) {
+ rrs->word3 &= ~RRS_RXD_UPDATED;
+ if (++rrd_ring->next_to_clean == rrd_ring->count)
+ rrd_ring->next_to_clean = 0;
+ }
+}
+
+static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
+ struct atl1c_recv_ret_status *rrs, u16 num)
+{
+ u16 i;
+ u16 rfd_index;
+ struct atl1c_buffer *buffer_info = rfd_ring->buffer_info;
+
+ rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+ RRS_RX_RFD_INDEX_MASK;
+ for (i = 0; i < num; i++) {
+ buffer_info[rfd_index].skb = NULL;
+ buffer_info[rfd_index].state = ATL1_BUFFER_FREE;
+ if (++rfd_index == rfd_ring->count)
+ rfd_index = 0;
+ }
+ rfd_ring->next_to_clean = rfd_index;
+}
+
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que,
+ int *work_done, int work_to_do)
+{
+ u16 rfd_num, rfd_index;
+ u16 count = 0;
+ u16 length;
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring[que];
+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring[que];
+ struct sk_buff *skb;
+ struct atl1c_recv_ret_status *rrs;
+ struct atl1c_buffer *buffer_info;
+
+ while (1) {
+ if (*work_done >= work_to_do)
+ break;
+ rrs = ATL1C_RRD_DESC(rrd_ring, rrd_ring->next_to_clean);
+ if (likely(RRS_RXD_IS_VALID(rrs->word3))) {
+ rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) &
+ RRS_RX_RFD_CNT_MASK;
+ if (unlikely(rfd_num) != 1)
+ /* TODO support mul rfd*/
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "Multi rfd not support yet!\n");
+ goto rrs_checked;
+ } else {
+ break;
+ }
+rrs_checked:
+ atl1c_clean_rrd(rrd_ring, rrs, rfd_num);
+ if (rrs->word3 & (RRS_RX_ERR_SUM | RRS_802_3_LEN_ERR)) {
+ atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "wrong packet! rrs word3 is %x\n",
+ rrs->word3);
+ continue;
+ }
+
+ length = le16_to_cpu((rrs->word3 >> RRS_PKT_SIZE_SHIFT) &
+ RRS_PKT_SIZE_MASK);
+ /* Good Receive */
+ if (likely(rfd_num == 1)) {
+ rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+ RRS_RX_RFD_INDEX_MASK;
+ buffer_info = &rfd_ring->buffer_info[rfd_index];
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length, PCI_DMA_FROMDEVICE);
+ skb = buffer_info->skb;
+ } else {
+ /* TODO */
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "Multi rfd not support yet!\n");
+ break;
+ }
+ atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+ skb_put(skb, length - ETH_FCS_LEN);
+ skb->protocol = eth_type_trans(skb, netdev);
+ skb->dev = netdev;
+ atl1c_rx_checksum(adapter, skb, rrs);
+ if (unlikely(adapter->vlgrp) && rrs->word3 & RRS_VLAN_INS) {
+ u16 vlan;
+
+ AT_TAG_TO_VLAN(rrs->vlan_tag, vlan);
+ vlan = le16_to_cpu(vlan);
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vlan);
+ } else
+ netif_receive_skb(skb);
+
+ netdev->last_rx = jiffies;
+ (*work_done)++;
+ count++;
+ }
+ if (count)
+ atl1c_alloc_rx_buffer(adapter, que);
+}
+
+/*
+ * atl1c_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ */
+static int atl1c_clean(struct napi_struct *napi, int budget)
+{
+ struct atl1c_adapter *adapter =
+ container_of(napi, struct atl1c_adapter, napi);
+ int work_done = 0;
+
+ /* Keep link state information with original netdev */
+ if (!netif_carrier_ok(adapter->netdev))
+ goto quit_polling;
+ /* just enable one RXQ */
+ atl1c_clean_rx_irq(adapter, 0, &work_done, budget);
+
+ if (work_done < budget) {
+quit_polling:
+ napi_complete(napi);
+ adapter->hw.intr_mask |= ISR_RX_PKT;
+ AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+ }
+ return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void atl1c_netpoll(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ disable_irq(adapter->pdev->irq);
+ atl1c_intr(adapter->pdev->irq, netdev);
+ enable_irq(adapter->pdev->irq);
+}
+#endif
+
+static inline u16 atl1c_tpd_avail(struct atl1c_adapter *adapter, enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ u16 next_to_use = 0;
+ u16 next_to_clean = 0;
+
+ next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+ next_to_use = tpd_ring->next_to_use;
+
+ return (u16)(next_to_clean > next_to_use) ?
+ (next_to_clean - next_to_use - 1) :
+ (tpd_ring->count + next_to_clean - next_to_use - 1);
+}
+
+/*
+ * get next usable tpd
+ * Note: should call atl1c_tdp_avail to make sure
+ * there is enough tpd to use
+ */
+static struct atl1c_tpd_desc *atl1c_get_tpd(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ struct atl1c_tpd_desc *tpd_desc;
+ u16 next_to_use = 0;
+
+ next_to_use = tpd_ring->next_to_use;
+ if (++tpd_ring->next_to_use == tpd_ring->count)
+ tpd_ring->next_to_use = 0;
+ tpd_desc = ATL1C_TPD_DESC(tpd_ring, next_to_use);
+ memset(tpd_desc, 0, sizeof(struct atl1c_tpd_desc));
+ return tpd_desc;
+}
+
+static struct atl1c_buffer *
+atl1c_get_tx_buffer(struct atl1c_adapter *adapter, struct atl1c_tpd_desc *tpd)
+{
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+
+ return &tpd_ring->buffer_info[tpd -
+ (struct atl1c_tpd_desc *)tpd_ring->desc];
+}
+
+/* Calculate the transmit packet descript needed*/
+static u16 atl1c_cal_tpd_req(const struct sk_buff *skb)
+{
+ u16 tpd_req;
+ u16 proto_hdr_len = 0;
+
+ tpd_req = skb_shinfo(skb)->nr_frags + 1;
+
+ if (skb_is_gso(skb)) {
+ proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ if (proto_hdr_len < skb_headlen(skb))
+ tpd_req++;
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+ tpd_req++;
+ }
+ return tpd_req;
+}
+
+static int atl1c_tso_csum(struct atl1c_adapter *adapter,
+ struct sk_buff *skb,
+ struct atl1c_tpd_desc **tpd,
+ enum atl1c_trans_queue type)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ u8 hdr_len;
+ u32 real_len;
+ unsigned short offload_type;
+ int err;
+
+ if (skb_is_gso(skb)) {
+ if (skb_header_cloned(skb)) {
+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+ if (unlikely(err))
+ return -1;
+ }
+ offload_type = skb_shinfo(skb)->gso_type;
+
+ if (offload_type & SKB_GSO_TCPV4) {
+ real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
+ + ntohs(ip_hdr(skb)->tot_len));
+
+ if (real_len < skb->len)
+ pskb_trim(skb, real_len);
+
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (unlikely(skb->len == hdr_len)) {
+ /* only xsum need */
+ if (netif_msg_tx_queued(adapter))
+ dev_warn(&pdev->dev,
+ "IPV4 tso with zero data??\n");
+ goto check_sum;
+ } else {
+ ip_hdr(skb)->check = 0;
+ tcp_hdr(skb)->check = ~csum_tcpudp_magic(
+ ip_hdr(skb)->saddr,
+ ip_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ (*tpd)->word1 |= 1 << TPD_IPV4_PACKET_SHIFT;
+ }
+ }
+
+ if (offload_type & SKB_GSO_TCPV6) {
+ struct atl1c_tpd_ext_desc *etpd =
+ *(struct atl1c_tpd_ext_desc **)(tpd);
+
+ memset(etpd, 0, sizeof(struct atl1c_tpd_ext_desc));
+ *tpd = atl1c_get_tpd(adapter, type);
+ ipv6_hdr(skb)->payload_len = 0;
+ /* check payload == 0 byte ? */
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (unlikely(skb->len == hdr_len)) {
+ /* only xsum need */
+ if (netif_msg_tx_queued(adapter))
+ dev_warn(&pdev->dev,
+ "IPV6 tso with zero data??\n");
+ goto check_sum;
+ } else
+ tcp_hdr(skb)->check = ~csum_ipv6_magic(
+ &ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ etpd->word1 |= 1 << TPD_LSO_EN_SHIFT;
+ etpd->word1 |= 1 << TPD_LSO_VER_SHIFT;
+ etpd->pkt_len = cpu_to_le32(skb->len);
+ (*tpd)->word1 |= 1 << TPD_LSO_VER_SHIFT;
+ }
+
+ (*tpd)->word1 |= 1 << TPD_LSO_EN_SHIFT;
+ (*tpd)->word1 |= (skb_transport_offset(skb) & TPD_TCPHDR_OFFSET_MASK) <<
+ TPD_TCPHDR_OFFSET_SHIFT;
+ (*tpd)->word1 |= (skb_shinfo(skb)->gso_size & TPD_MSS_MASK) <<
+ TPD_MSS_SHIFT;
+ return 0;
+ }
+
+check_sum:
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+ u8 css, cso;
+ cso = skb_transport_offset(skb);
+
+ if (unlikely(cso & 0x1)) {
+ if (netif_msg_tx_err(adapter))
+ dev_err(&adapter->pdev->dev,
+ "payload offset should not an event number\n");
+ return -1;
+ } else {
+ css = cso + skb->csum_offset;
+
+ (*tpd)->word1 |= ((cso >> 1) & TPD_PLOADOFFSET_MASK) <<
+ TPD_PLOADOFFSET_SHIFT;
+ (*tpd)->word1 |= ((css >> 1) & TPD_CCSUM_OFFSET_MASK) <<
+ TPD_CCSUM_OFFSET_SHIFT;
+ (*tpd)->word1 |= 1 << TPD_CCSUM_EN_SHIFT;
+ }
+ }
+ return 0;
+}
+
+static void atl1c_tx_map(struct atl1c_adapter *adapter,
+ struct sk_buff *skb, struct atl1c_tpd_desc *tpd,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_desc *use_tpd = NULL;
+ struct atl1c_buffer *buffer_info = NULL;
+ u16 buf_len = skb_headlen(skb);
+ u16 map_len = 0;
+ u16 mapped_len = 0;
+ u16 hdr_len = 0;
+ u16 nr_frags;
+ u16 f;
+ int tso;
+
+ nr_frags = skb_shinfo(skb)->nr_frags;
+ tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK;
+ if (tso) {
+ /* TSO */
+ map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ use_tpd = tpd;
+
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = map_len;
+ buffer_info->dma = pci_map_single(adapter->pdev,
+ skb->data, hdr_len, PCI_DMA_TODEVICE);
+ buffer_info->state = ATL1_BUFFER_BUSY;
+ mapped_len += map_len;
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ if (mapped_len < buf_len) {
+ /* mapped_len == 0, means we should use the first tpd,
+ which is given by caller */
+ if (mapped_len == 0)
+ use_tpd = tpd;
+ else {
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+ }
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = buf_len - mapped_len;
+ buffer_info->dma =
+ pci_map_single(adapter->pdev, skb->data + mapped_len,
+ buffer_info->length, PCI_DMA_TODEVICE);
+ buffer_info->state = ATL1_BUFFER_BUSY;
+
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ for (f = 0; f < nr_frags; f++) {
+ struct skb_frag_struct *frag;
+
+ frag = &skb_shinfo(skb)->frags[f];
+
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = frag->size;
+ buffer_info->dma =
+ pci_map_page(adapter->pdev, frag->page,
+ frag->page_offset,
+ buffer_info->length,
+ PCI_DMA_TODEVICE);
+ buffer_info->state = ATL1_BUFFER_BUSY;
+
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ /* The last tpd */
+ use_tpd->word1 |= 1 << TPD_EOP_SHIFT;
+ /* The last buffer info contain the skb address,
+ so it will be free after unmap */
+ buffer_info->skb = skb;
+}
+
+static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
+ struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ u32 prod_data;
+
+ AT_READ_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, &prod_data);
+ switch (type) {
+ case atl1c_trans_high:
+ prod_data &= 0xFFFF0000;
+ prod_data |= tpd_ring->next_to_use & 0xFFFF;
+ break;
+ case atl1c_trans_normal:
+ prod_data &= 0x0000FFFF;
+ prod_data |= (tpd_ring->next_to_use & 0xFFFF) << 16;
+ break;
+ default:
+ break;
+ }
+ wmb();
+ AT_WRITE_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, prod_data);
+}
+
+static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ unsigned long flags;
+ u16 tpd_req = 1;
+ struct atl1c_tpd_desc *tpd;
+ enum atl1c_trans_queue type = atl1c_trans_normal;
+
+ if (test_bit(__AT_DOWN, &adapter->flags)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ tpd_req = atl1c_cal_tpd_req(skb);
+ if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
+ if (netif_msg_pktdata(adapter))
+ dev_info(&adapter->pdev->dev, "tx locked\n");
+ return NETDEV_TX_LOCKED;
+ }
+ if (skb->mark == 0x01)
+ type = atl1c_trans_high;
+ else
+ type = atl1c_trans_normal;
+
+ if (atl1c_tpd_avail(adapter, type) < tpd_req) {
+ /* no enough descriptor, just stop queue */
+ netif_stop_queue(netdev);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+ tpd = atl1c_get_tpd(adapter, type);
+
+ /* do TSO and check sum */
+ if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) {
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+ u16 vlan = vlan_tx_tag_get(skb);
+ __le16 tag;
+
+ vlan = cpu_to_le16(vlan);
+ AT_VLAN_TO_TAG(vlan, tag);
+ tpd->word1 |= 1 << TPD_INS_VTAG_SHIFT;
+ tpd->vlan_tag = tag;
+ }
+
+ if (skb_network_offset(skb) != ETH_HLEN)
+ tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */
+
+ atl1c_tx_map(adapter, skb, tpd, type);
+ atl1c_tx_queue(adapter, skb, tpd, type);
+
+ netdev->trans_start = jiffies;
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ return NETDEV_TX_OK;
+}
+
+static void atl1c_free_irq(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ free_irq(adapter->pdev->irq, netdev);
+
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
+}
+
+static int atl1c_request_irq(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ int flags = 0;
+ int err = 0;
+
+ adapter->have_msi = true;
+ err = pci_enable_msi(adapter->pdev);
+ if (err) {
+ if (netif_msg_ifup(adapter))
+ dev_err(&pdev->dev,
+ "Unable to allocate MSI interrupt Error: %d\n",
+ err);
+ adapter->have_msi = false;
+ } else
+ netdev->irq = pdev->irq;
+
+ if (!adapter->have_msi)
+ flags |= IRQF_SHARED;
+ err = request_irq(adapter->pdev->irq, &atl1c_intr, flags,
+ netdev->name, netdev);
+ if (err) {
+ if (netif_msg_ifup(adapter))
+ dev_err(&pdev->dev,
+ "Unable to allocate interrupt Error: %d\n",
+ err);
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
+ return err;
+ }
+ if (netif_msg_ifup(adapter))
+ dev_dbg(&pdev->dev, "atl1c_request_irq OK\n");
+ return err;
+}
+
+int atl1c_up(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int num;
+ int err;
+ int i;
+
+ netif_carrier_off(netdev);
+ atl1c_init_ring_ptrs(adapter);
+ atl1c_set_multi(netdev);
+ atl1c_restore_vlan(adapter);
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ num = atl1c_alloc_rx_buffer(adapter, i);
+ if (unlikely(num == 0)) {
+ err = -ENOMEM;
+ goto err_alloc_rx;
+ }
+ }
+
+ if (atl1c_configure(adapter)) {
+ err = -EIO;
+ goto err_up;
+ }
+
+ err = atl1c_request_irq(adapter);
+ if (unlikely(err))
+ goto err_up;
+
+ clear_bit(__AT_DOWN, &adapter->flags);
+ napi_enable(&adapter->napi);
+ atl1c_irq_enable(adapter);
+ atl1c_check_link_status(adapter);
+ netif_start_queue(netdev);
+ return err;
+
+err_up:
+err_alloc_rx:
+ atl1c_clean_rx_ring(adapter);
+ return err;
+}
+
+void atl1c_down(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ atl1c_del_timer(adapter);
+ atl1c_cancel_work(adapter);
+
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ set_bit(__AT_DOWN, &adapter->flags);
+ netif_carrier_off(netdev);
+ napi_disable(&adapter->napi);
+ atl1c_irq_disable(adapter);
+ atl1c_free_irq(adapter);
+ AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT);
+ /* reset MAC to disable all RX/TX */
+ atl1c_reset_mac(&adapter->hw);
+ msleep(1);
+
+ adapter->link_speed = SPEED_0;
+ adapter->link_duplex = -1;
+ atl1c_clean_tx_ring(adapter, atl1c_trans_normal);
+ atl1c_clean_tx_ring(adapter, atl1c_trans_high);
+ atl1c_clean_rx_ring(adapter);
+}
+
+/*
+ * atl1c_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP). At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ */
+static int atl1c_open(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ int err;
+
+ /* disallow open during test */
+ if (test_bit(__AT_TESTING, &adapter->flags))
+ return -EBUSY;
+
+ /* allocate rx/tx dma buffer & descriptors */
+ err = atl1c_setup_ring_resources(adapter);
+ if (unlikely(err))
+ return err;
+
+ err = atl1c_up(adapter);
+ if (unlikely(err))
+ goto err_up;
+
+ if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
+ u32 phy_data;
+
+ AT_READ_REG(&adapter->hw, REG_MDIO_CTRL, &phy_data);
+ phy_data |= MDIO_AP_EN;
+ AT_WRITE_REG(&adapter->hw, REG_MDIO_CTRL, phy_data);
+ }
+ return 0;
+
+err_up:
+ atl1c_free_irq(adapter);
+ atl1c_free_ring_resources(adapter);
+ atl1c_reset_mac(&adapter->hw);
+ return err;
+}
+
+/*
+ * atl1c_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS. The hardware is still under the drivers control, but
+ * needs to be disabled. A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ */
+static int atl1c_close(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+ atl1c_down(adapter);
+ atl1c_free_ring_resources(adapter);
+ return 0;
+}
+
+static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 ctrl;
+ u32 mac_ctrl_data;
+ u32 master_ctrl_data;
+ u32 wol_ctrl_data;
+ u16 mii_bmsr_data;
+ u16 save_autoneg_advertised;
+ u16 mii_intr_status_data;
+ u32 wufc = adapter->wol;
+ u32 i;
+ int retval = 0;
+
+ if (netif_running(netdev)) {
+ WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+ atl1c_down(adapter);
+ }
+ netif_device_detach(netdev);
+ atl1c_disable_l0s_l1(hw);
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+ if (wufc) {
+ AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
+ master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS;
+
+ /* get link status */
+ atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+ atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+ save_autoneg_advertised = hw->autoneg_advertised;
+ hw->autoneg_advertised = ADVERTISED_10baseT_Half;
+ if (atl1c_restart_autoneg(hw) != 0)
+ if (netif_msg_link(adapter))
+ dev_warn(&pdev->dev, "phy autoneg failed\n");
+ hw->phy_configured = false; /* re-init PHY when resume */
+ hw->autoneg_advertised = save_autoneg_advertised;
+ /* turn on magic packet wol */
+ if (wufc & AT_WUFC_MAG)
+ wol_ctrl_data = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+
+ if (wufc & AT_WUFC_LNKC) {
+ for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
+ msleep(100);
+ atl1c_read_phy_reg(hw, MII_BMSR,
+ (u16 *)&mii_bmsr_data);
+ if (mii_bmsr_data & BMSR_LSTATUS)
+ break;
+ }
+ if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
+ if (netif_msg_link(adapter))
+ dev_warn(&pdev->dev,
+ "%s: Link may change"
+ "when suspend\n",
+ atl1c_driver_name);
+ wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
+ /* only link up can wake up */
+ if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev,
+ "%s: read write phy "
+ "register failed.\n",
+ atl1c_driver_name);
+ goto wol_dis;
+ }
+ }
+ /* clear phy interrupt */
+ atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data);
+ /* Config MAC Ctrl register */
+ mac_ctrl_data = MAC_CTRL_RX_EN;
+ /* set to 10/100M halt duplex */
+ mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT;
+ mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
+ MAC_CTRL_PRMLEN_MASK) <<
+ MAC_CTRL_PRMLEN_SHIFT);
+
+ if (adapter->vlgrp)
+ mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+
+ /* magic packet maybe Broadcast&multicast&Unicast frame */
+ if (wufc & AT_WUFC_MAG)
+ mac_ctrl_data |= MAC_CTRL_BC_EN;
+
+ if (netif_msg_hw(adapter))
+ dev_dbg(&pdev->dev,
+ "%s: suspend MAC=0x%x\n",
+ atl1c_driver_name, mac_ctrl_data);
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+ AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+ /* pcie patch */
+ AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl);
+ ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+ AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+ goto suspend_exit;
+ }
+wol_dis:
+
+ /* WOL disabled */
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+ /* pcie patch */
+ AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl);
+ ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+ AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+
+ atl1c_phy_disable(hw);
+ hw->phy_configured = false; /* re-init PHY when resume */
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+suspend_exit:
+
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int atl1c_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+
+ atl1c_phy_reset(&adapter->hw);
+ atl1c_reset_mac(&adapter->hw);
+ netif_device_attach(netdev);
+ if (netif_running(netdev))
+ atl1c_up(adapter);
+
+ return 0;
+}
+
+static void atl1c_shutdown(struct pci_dev *pdev)
+{
+ atl1c_suspend(pdev, PMSG_SUSPEND);
+}
+
+static const struct net_device_ops atl1c_netdev_ops = {
+ .ndo_open = atl1c_open,
+ .ndo_stop = atl1c_close,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_start_xmit = atl1c_xmit_frame,
+ .ndo_set_mac_address = atl1c_set_mac_addr,
+ .ndo_set_multicast_list = atl1c_set_multi,
+ .ndo_change_mtu = atl1c_change_mtu,
+ .ndo_do_ioctl = atl1c_ioctl,
+ .ndo_tx_timeout = atl1c_tx_timeout,
+ .ndo_get_stats = atl1c_get_stats,
+ .ndo_vlan_rx_register = atl1c_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl1c_netpoll,
+#endif
+};
+
+static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
+{
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ pci_set_drvdata(pdev, netdev);
+
+ netdev->irq = pdev->irq;
+ netdev->netdev_ops = &atl1c_netdev_ops;
+ netdev->watchdog_timeo = AT_TX_WATCHDOG;
+ atl1c_set_ethtool_ops(netdev);
+
+ /* TODO: add when ready */
+ netdev->features = NETIF_F_SG |
+ NETIF_F_HW_CSUM |
+ NETIF_F_HW_VLAN_TX |
+ NETIF_F_HW_VLAN_RX |
+ NETIF_F_TSO |
+ NETIF_F_TSO6;
+ return 0;
+}
+
+/*
+ * atl1c_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl1c_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl1c_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ */
+static int __devinit atl1c_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct net_device *netdev;
+ struct atl1c_adapter *adapter;
+ static int cards_found;
+
+ int err = 0;
+
+ /* enable device (incl. PCI PM wakeup and hotplug setup) */
+ err = pci_enable_device_mem(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ return err;
+ }
+
+ /*
+ * The atl1c chip can DMA to 64-bit addresses, but it uses a single
+ * shared register for the high 32 bits, so only a single, aligned,
+ * 4 GB physical address range can be used at a time.
+ *
+ * Supporting 64-bit DMA on this hardware is more trouble than it's
+ * worth. It is far easier to limit to 32-bit DMA than update
+ * various kernel subsystems to support the mechanics required by a
+ * fixed-high-32-bit system.
+ */
+ if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
+ (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+ dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
+ goto err_dma;
+ }
+
+ err = pci_request_regions(pdev, atl1c_driver_name);
+ if (err) {
+ dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+ goto err_pci_reg;
+ }
+
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev(sizeof(struct atl1c_adapter));
+ if (netdev == NULL) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "etherdev alloc failed\n");
+ goto err_alloc_etherdev;
+ }
+
+ err = atl1c_init_netdev(netdev, pdev);
+ if (err) {
+ dev_err(&pdev->dev, "init netdevice failed\n");
+ goto err_init_netdev;
+ }
+ adapter = netdev_priv(netdev);
+ adapter->bd_number = cards_found;
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->hw.adapter = adapter;
+ adapter->msg_enable = netif_msg_init(-1, atl1c_default_msg);
+ adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+ if (!adapter->hw.hw_addr) {
+ err = -EIO;
+ dev_err(&pdev->dev, "cannot map device registers\n");
+ goto err_ioremap;
+ }
+ netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
+
+ /* init mii data */
+ adapter->mii.dev = netdev;
+ adapter->mii.mdio_read = atl1c_mdio_read;
+ adapter->mii.mdio_write = atl1c_mdio_write;
+ adapter->mii.phy_id_mask = 0x1f;
+ adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
+ netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
+ setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
+ (unsigned long)adapter);
+ /* setup the private structure */
+ err = atl1c_sw_init(adapter);
+ if (err) {
+ dev_err(&pdev->dev, "net device private data init failed\n");
+ goto err_sw_init;
+ }
+ atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE |
+ ATL1C_PCIE_PHY_RESET);
+
+ /* Init GPHY as early as possible due to power saving issue */
+ atl1c_phy_reset(&adapter->hw);
+
+ err = atl1c_reset_mac(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ goto err_reset;
+ }
+
+ device_init_wakeup(&pdev->dev, 1);
+ /* reset the controller to
+ * put the device in a known good starting state */
+ err = atl1c_phy_init(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ goto err_reset;
+ }
+ if (atl1c_read_mac_addr(&adapter->hw) != 0) {
+ err = -EIO;
+ dev_err(&pdev->dev, "get mac address failed\n");
+ goto err_eeprom;
+ }
+ memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+ memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+ if (netif_msg_probe(adapter))
+ dev_dbg(&pdev->dev,
+ "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n",
+ adapter->hw.mac_addr[0], adapter->hw.mac_addr[1],
+ adapter->hw.mac_addr[2], adapter->hw.mac_addr[3],
+ adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
+
+ atl1c_hw_set_mac_addr(&adapter->hw);
+ INIT_WORK(&adapter->reset_task, atl1c_reset_task);
+ INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task);
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&pdev->dev, "register netdevice failed\n");
+ goto err_register;
+ }
+
+ if (netif_msg_probe(adapter))
+ dev_info(&pdev->dev, "version %s\n", ATL1C_DRV_VERSION);
+ cards_found++;
+ return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+err_eeprom:
+ iounmap(adapter->hw.hw_addr);
+err_init_netdev:
+err_ioremap:
+ free_netdev(netdev);
+err_alloc_etherdev:
+ pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+ pci_disable_device(pdev);
+ return err;
+}
+
+/*
+ * atl1c_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl1c_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device. The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ */
+static void __devexit atl1c_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ unregister_netdev(netdev);
+ atl1c_phy_disable(&adapter->hw);
+
+ iounmap(adapter->hw.hw_addr);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ free_netdev(netdev);
+}
+
+/*
+ * atl1c_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ atl1c_down(adapter);
+
+ pci_disable_device(pdev);
+
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/*
+ * atl1c_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t atl1c_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (pci_enable_device(pdev)) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Cannot re-enable PCI device after reset\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ atl1c_reset_mac(&adapter->hw);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/*
+ * atl1c_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the atl1c_resume routine.
+ */
+static void atl1c_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (netif_running(netdev)) {
+ if (atl1c_up(adapter)) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Cannot bring device back up after reset\n");
+ return;
+ }
+ }
+
+ netif_device_attach(netdev);
+}
+
+static struct pci_error_handlers atl1c_err_handler = {
+ .error_detected = atl1c_io_error_detected,
+ .slot_reset = atl1c_io_slot_reset,
+ .resume = atl1c_io_resume,
+};
+
+static struct pci_driver atl1c_driver = {
+ .name = atl1c_driver_name,
+ .id_table = atl1c_pci_tbl,
+ .probe = atl1c_probe,
+ .remove = __devexit_p(atl1c_remove),
+ /* Power Managment Hooks */
+ .suspend = atl1c_suspend,
+ .resume = atl1c_resume,
+ .shutdown = atl1c_shutdown,
+ .err_handler = &atl1c_err_handler
+};
+
+/*
+ * atl1c_init_module - Driver Registration Routine
+ *
+ * atl1c_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl1c_init_module(void)
+{
+ return pci_register_driver(&atl1c_driver);
+}
+
+/*
+ * atl1c_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl1c_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl1c_exit_module(void)
+{
+ pci_unregister_driver(&atl1c_driver);
+}
+
+module_init(atl1c_init_module);
+module_exit(atl1c_exit_module);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 9c875bb3f76c..79aec32c6add 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -355,8 +355,8 @@ static int mii_probe (struct net_device *dev)
/* now we are supposed to have a proper phydev, to attach to... */
BUG_ON(phydev->attached_dev);
- phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &au1000_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
@@ -381,8 +381,8 @@ static int mii_probe (struct net_device *dev)
aup->phy_dev = phydev;
printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
return 0;
}
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 78e31aa861e0..9afe8092dfc4 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -415,11 +415,11 @@ static int mii_probe(struct net_device *dev)
}
#if defined(CONFIG_BFIN_MAC_RMII)
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_RMII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_RMII);
#else
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
#endif
if (IS_ERR(phydev)) {
@@ -447,7 +447,7 @@ static int mii_probe(struct net_device *dev)
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)"
"@sclk=%dMHz)\n",
- DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq,
+ DRV_NAME, phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
MDC_CLK, mdc_div, sclk/1000000);
return 0;
@@ -488,7 +488,7 @@ static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->fw_version, "N/A");
- strcpy(info->bus_info, dev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&dev->dev));
}
static struct ethtool_ops bfin_mac_ethtool_ops = {
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 8a546a33d581..1ab58375d061 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1240,7 +1240,7 @@ static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *inf
{
struct bmac_data *bp = netdev_priv(dev);
strcpy(info->driver, "bmac");
- strcpy(info->bus_info, bp->mdev->ofdev.dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev));
}
static const struct ethtool_ops bmac_ethtool_ops = {
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d4a3dac21dcf..6500b7c4739f 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1,6 +1,6 @@
/* bnx2.c: Broadcom NX2 network driver.
*
- * Copyright (c) 2004-2008 Broadcom Corporation
+ * Copyright (c) 2004-2009 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
@@ -57,8 +57,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.9.0"
-#define DRV_MODULE_RELDATE "Dec 16, 2008"
+#define DRV_MODULE_VERSION "1.9.2"
+#define DRV_MODULE_RELDATE "Feb 11, 2009"
#define RUN_AT(x) (jiffies + (x))
@@ -2910,18 +2910,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
rx_hdr = (struct l2_fhdr *) skb->data;
len = rx_hdr->l2_fhdr_pkt_len;
+ status = rx_hdr->l2_fhdr_status;
- if ((status = rx_hdr->l2_fhdr_status) &
- (L2_FHDR_ERRORS_BAD_CRC |
- L2_FHDR_ERRORS_PHY_DECODE |
- L2_FHDR_ERRORS_ALIGNMENT |
- L2_FHDR_ERRORS_TOO_SHORT |
- L2_FHDR_ERRORS_GIANT_FRAME)) {
-
- bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
- sw_ring_prod);
- goto next_rx;
- }
hdr_len = 0;
if (status & L2_FHDR_STATUS_SPLIT) {
hdr_len = rx_hdr->l2_fhdr_ip_xsum;
@@ -2931,6 +2921,24 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
pg_ring_used = 1;
}
+ if (unlikely(status & (L2_FHDR_ERRORS_BAD_CRC |
+ L2_FHDR_ERRORS_PHY_DECODE |
+ L2_FHDR_ERRORS_ALIGNMENT |
+ L2_FHDR_ERRORS_TOO_SHORT |
+ L2_FHDR_ERRORS_GIANT_FRAME))) {
+
+ bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
+ sw_ring_prod);
+ if (pg_ring_used) {
+ int pages;
+
+ pages = PAGE_ALIGN(len - hdr_len) >> PAGE_SHIFT;
+
+ bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages);
+ }
+ goto next_rx;
+ }
+
len -= 4;
if (len <= bp->rx_copy_thresh) {
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 900641ac63e0..704cbbcbf97a 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1,6 +1,6 @@
/* bnx2.h: Broadcom NX2 network driver.
*
- * Copyright (c) 2004-2007 Broadcom Corporation
+ * Copyright (c) 2004-2009 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
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 24c3cc40c23d..6a4f1d695de7 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -15,854 +15,849 @@
*/
static u8 bnx2_COM_b06FwText[] = {
- 0xcd, 0x7c, 0x0d, 0x70, 0x5b, 0xd7, 0x95, 0xde, 0xc1, 0x03, 0x40, 0x82,
- 0x10, 0x45, 0x3d, 0x52, 0x30, 0x0d, 0x3b, 0x4c, 0x82, 0x47, 0x3c, 0x92,
- 0xb0, 0xc9, 0x64, 0x9f, 0x64, 0x46, 0x66, 0x12, 0xac, 0x05, 0x03, 0xa4,
- 0x4c, 0x27, 0xea, 0x92, 0xb6, 0x19, 0x47, 0x6d, 0x35, 0x09, 0x17, 0x92,
- 0x12, 0xdb, 0x4d, 0xa7, 0x9a, 0xc6, 0xe9, 0x2a, 0x1b, 0xc7, 0x82, 0x41,
- 0xca, 0x51, 0x52, 0x8a, 0x60, 0x24, 0x4a, 0xf2, 0x74, 0xb3, 0xbb, 0x0c,
- 0x48, 0x4a, 0x8e, 0x03, 0x09, 0x96, 0xec, 0x75, 0xdc, 0xad, 0xb3, 0x62,
- 0x68, 0xad, 0xec, 0x4d, 0xb3, 0xad, 0x9d, 0x49, 0x3a, 0x9a, 0xa9, 0xb7,
- 0x55, 0x95, 0xa4, 0xf9, 0x99, 0xfe, 0xb8, 0x49, 0xa6, 0x75, 0xbb, 0xf1,
- 0xbe, 0x7e, 0xdf, 0x7d, 0xf7, 0x11, 0x20, 0xc5, 0x28, 0xde, 0xec, 0x64,
- 0x66, 0x39, 0x83, 0xb9, 0xef, 0xde, 0x77, 0x7f, 0xce, 0x3d, 0xf7, 0xfc,
- 0x7c, 0xe7, 0xde, 0xfb, 0x78, 0x87, 0x48, 0x54, 0xf4, 0xdf, 0x46, 0xfc,
- 0xfa, 0xff, 0xe9, 0x3f, 0xdb, 0xb3, 0xf5, 0xdd, 0xfd, 0xef, 0x66, 0xde,
- 0x30, 0x42, 0x21, 0xa6, 0x41, 0xfc, 0x62, 0xf8, 0x6d, 0xd5, 0xcf, 0xeb,
- 0xfd, 0x99, 0xf8, 0x6d, 0x0b, 0x88, 0x8c, 0xff, 0x44, 0x24, 0xb0, 0xe6,
- 0x5d, 0x64, 0x9d, 0xfa, 0xae, 0xfb, 0x4b, 0x3a, 0xd2, 0x7f, 0x06, 0x7e,
- 0x89, 0xeb, 0x57, 0x59, 0x19, 0xf7, 0xd7, 0xfd, 0x0b, 0xea, 0xe6, 0x1b,
- 0xf5, 0x4f, 0x22, 0x46, 0x5a, 0x46, 0xb2, 0xb6, 0x44, 0x82, 0xe9, 0x9f,
- 0x8f, 0xec, 0xb1, 0x45, 0x32, 0x95, 0xde, 0x44, 0x4e, 0xde, 0x74, 0x0b,
- 0xb1, 0x90, 0xb0, 0xfc, 0xed, 0xe9, 0x5f, 0x1c, 0xfc, 0xfa, 0xed, 0xd6,
- 0xeb, 0x73, 0x41, 0x89, 0x98, 0xe9, 0x37, 0xc4, 0xec, 0x96, 0x48, 0x07,
- 0xda, 0x7c, 0xa9, 0xe7, 0x49, 0x43, 0x5a, 0xfc, 0xbe, 0xcc, 0xf1, 0x60,
- 0x5a, 0x46, 0xf7, 0x4e, 0x1d, 0x74, 0x0d, 0x5b, 0x0a, 0x37, 0xa7, 0xed,
- 0x44, 0x51, 0x9a, 0x07, 0x26, 0xfb, 0x6f, 0x17, 0xe4, 0x47, 0xf7, 0x56,
- 0x22, 0x92, 0xad, 0x16, 0x9a, 0x0d, 0xdb, 0x46, 0x1a, 0x29, 0xbc, 0x2d,
- 0x2d, 0x91, 0x86, 0xf4, 0x6c, 0xe3, 0x25, 0x9b, 0xe3, 0x0f, 0x60, 0xfc,
- 0xb7, 0x49, 0xc8, 0x76, 0xdd, 0x49, 0x8c, 0xbf, 0xa3, 0xf2, 0xa6, 0xfb,
- 0x58, 0xc8, 0x1b, 0xdb, 0x48, 0x1f, 0x08, 0x32, 0x0d, 0xa4, 0x33, 0x23,
- 0x9d, 0x15, 0x95, 0x6f, 0xf0, 0xf2, 0x83, 0x3a, 0x1f, 0x89, 0x7a, 0xb4,
- 0x4b, 0x13, 0x68, 0x8f, 0x84, 0xd2, 0xe9, 0x26, 0xf4, 0x11, 0x09, 0xa7,
- 0x97, 0x7e, 0x7b, 0x51, 0xd5, 0x3b, 0xac, 0xeb, 0x3d, 0x10, 0xf6, 0xda,
- 0x4d, 0x8e, 0x74, 0x57, 0x98, 0xce, 0x8e, 0x74, 0xa9, 0xf4, 0x4b, 0x23,
- 0x49, 0x95, 0xce, 0xa9, 0x7a, 0x81, 0xf4, 0xc2, 0x88, 0xad, 0xd2, 0xb4,
- 0x2e, 0x1f, 0x1e, 0x49, 0xa8, 0x74, 0xa7, 0x4e, 0x47, 0x75, 0x3a, 0xa6,
- 0xd3, 0x5d, 0x3a, 0xdd, 0xad, 0xd3, 0x71, 0x9d, 0xee, 0xd5, 0xfd, 0x3c,
- 0xa0, 0xf3, 0x9f, 0xd0, 0xe9, 0x7e, 0x9d, 0x3e, 0xac, 0xd3, 0x03, 0x3a,
- 0x7d, 0x44, 0xd3, 0x55, 0xd0, 0xe9, 0x94, 0x2e, 0x9f, 0xd1, 0x74, 0x3e,
- 0x01, 0x7a, 0xfe, 0x71, 0xa3, 0x96, 0x5b, 0xcc, 0x37, 0x21, 0x7b, 0xa6,
- 0x22, 0x52, 0x2c, 0x05, 0x25, 0xa7, 0xd6, 0xf3, 0xe3, 0x61, 0x89, 0x46,
- 0x64, 0xa2, 0x1a, 0x91, 0x2b, 0x4a, 0x5c, 0x7f, 0xe4, 0x7e, 0xbd, 0xc7,
- 0x94, 0xa7, 0xab, 0x31, 0xb9, 0x50, 0x95, 0xc0, 0x68, 0x4f, 0x93, 0x18,
- 0x47, 0x6f, 0x96, 0x8c, 0x19, 0x90, 0xa0, 0xe2, 0x6b, 0x42, 0xb2, 0x53,
- 0xed, 0xc8, 0x5b, 0x71, 0x91, 0xc5, 0xb0, 0xb7, 0x8e, 0x11, 0x09, 0x9e,
- 0xe0, 0xba, 0x3c, 0x37, 0x72, 0x69, 0x36, 0x2e, 0xa1, 0xe9, 0x04, 0xfa,
- 0x6f, 0x96, 0xf0, 0x09, 0xe9, 0x08, 0x4a, 0x57, 0xfc, 0x63, 0xa8, 0x31,
- 0x58, 0x09, 0xc9, 0x50, 0x25, 0x80, 0xb5, 0x8a, 0x40, 0x4e, 0x9a, 0xf1,
- 0x33, 0xf1, 0x8b, 0xe1, 0x17, 0xc7, 0xef, 0xaf, 0xd0, 0x4f, 0x87, 0xe4,
- 0x2a, 0xec, 0x13, 0xe3, 0x96, 0x30, 0x7e, 0xc9, 0x32, 0xc7, 0x85, 0x34,
- 0xc5, 0xe5, 0xeb, 0x3d, 0x1e, 0x4d, 0x17, 0xaa, 0x91, 0x40, 0xf6, 0xa4,
- 0xec, 0xcf, 0x39, 0x92, 0x30, 0xec, 0xa8, 0xe4, 0xcd, 0x40, 0x62, 0x6f,
- 0xaa, 0x4d, 0x0a, 0x63, 0x78, 0x57, 0x92, 0x8c, 0x81, 0xbe, 0xf3, 0xa6,
- 0x8c, 0x7b, 0xef, 0x58, 0xf6, 0x7f, 0xa1, 0xaf, 0x96, 0x49, 0xc1, 0xbd,
- 0x50, 0xfa, 0xd7, 0x78, 0x66, 0x5f, 0x2f, 0x86, 0x3c, 0x9a, 0xdf, 0x40,
- 0x9e, 0xe5, 0xee, 0x26, 0x2f, 0xcf, 0x67, 0xd6, 0xf5, 0xc7, 0xf4, 0xe7,
- 0xca, 0xb1, 0x7b, 0x30, 0x5f, 0x8e, 0xbf, 0x32, 0x5f, 0xd0, 0xd1, 0x1c,
- 0xc8, 0x9d, 0x4c, 0xc8, 0xa1, 0xd2, 0x1d, 0x92, 0x75, 0x5c, 0x77, 0x8f,
- 0x23, 0x31, 0x43, 0xba, 0xcc, 0x1c, 0xde, 0x96, 0x2b, 0x12, 0xc8, 0x96,
- 0x7c, 0x7e, 0xb0, 0xdf, 0x10, 0xca, 0xda, 0x51, 0xbf, 0x25, 0x30, 0x78,
- 0x12, 0xb4, 0xa7, 0xc9, 0x17, 0xc8, 0xac, 0xd3, 0x15, 0xdf, 0x8b, 0xf1,
- 0xe6, 0x2b, 0x5d, 0xce, 0xb2, 0x98, 0xe8, 0xb3, 0x0d, 0x75, 0xc8, 0x23,
- 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x33, 0xda, 0xc6, 0xf0, 0x8e, 0x34, 0xb9,
- 0x6e, 0xd6, 0x31, 0x99, 0x97, 0x39, 0xf0, 0x6d, 0x8e, 0x7c, 0x8b, 0x76,
- 0xc8, 0xa9, 0x0a, 0xc7, 0x58, 0x8f, 0xee, 0x5b, 0xff, 0x9e, 0xd1, 0x1d,
- 0x47, 0xff, 0x31, 0xa4, 0x1b, 0x02, 0xd9, 0x63, 0x2e, 0xc6, 0x8f, 0xe3,
- 0x79, 0xbd, 0x39, 0x5c, 0xd1, 0x32, 0x18, 0x07, 0xed, 0x31, 0x39, 0xa7,
- 0xe4, 0x70, 0x83, 0x04, 0x21, 0x87, 0x5c, 0xe3, 0xd6, 0x13, 0xef, 0x91,
- 0x7c, 0xcc, 0x4a, 0xd0, 0x76, 0x76, 0x6e, 0x6d, 0xc2, 0x1c, 0xb5, 0x15,
- 0x9c, 0x8e, 0x41, 0x0e, 0x97, 0x5b, 0x0d, 0x94, 0x18, 0x62, 0x99, 0xff,
- 0x48, 0x0a, 0x92, 0x5b, 0xf8, 0xbd, 0x80, 0x44, 0x0d, 0xd4, 0xbb, 0x25,
- 0xe0, 0xf1, 0x80, 0xfc, 0xc9, 0x80, 0x3f, 0x01, 0xd1, 0xf6, 0x41, 0x3a,
- 0x2b, 0x7c, 0xdf, 0x9b, 0x30, 0xd4, 0xbb, 0x41, 0xbc, 0x0b, 0x49, 0x72,
- 0xab, 0xff, 0x7e, 0x10, 0xef, 0x6f, 0x96, 0x71, 0x13, 0xb4, 0x94, 0x9e,
- 0x37, 0xb2, 0xa0, 0xf1, 0xce, 0x90, 0x9a, 0x2b, 0xea, 0x8e, 0xd7, 0xf5,
- 0x33, 0x8e, 0x7a, 0xff, 0x0a, 0x63, 0x81, 0xde, 0x52, 0x02, 0xb4, 0xb4,
- 0x83, 0x16, 0xd2, 0x58, 0x30, 0xb2, 0xd5, 0x10, 0xf2, 0x93, 0x46, 0xee,
- 0xf4, 0x61, 0x3c, 0x8b, 0x69, 0xa4, 0x9f, 0x67, 0x8a, 0xf6, 0xbb, 0xeb,
- 0xda, 0xef, 0x46, 0x7b, 0x8e, 0xc1, 0xf6, 0x9e, 0xfc, 0x17, 0x94, 0x2c,
- 0x26, 0xae, 0xc3, 0x8f, 0xe0, 0xaf, 0xc1, 0x8f, 0x7f, 0xa3, 0xf9, 0xf1,
- 0xd7, 0xf2, 0x9b, 0xe7, 0xc7, 0x7f, 0xfa, 0x0d, 0xf1, 0x43, 0x24, 0x7f,
- 0x8c, 0xcf, 0x21, 0x29, 0x28, 0xbb, 0x45, 0xbd, 0xa5, 0xbc, 0xd3, 0x66,
- 0x91, 0x4f, 0x94, 0x63, 0xe8, 0x40, 0x35, 0x84, 0xf4, 0x49, 0xa4, 0x1b,
- 0x02, 0xa3, 0xc7, 0xae, 0x62, 0xfd, 0x5d, 0x31, 0xb7, 0xfa, 0x7e, 0xa3,
- 0x10, 0x37, 0xa5, 0x43, 0xcc, 0x77, 0xc3, 0x69, 0xb7, 0x5b, 0x66, 0x5e,
- 0x7e, 0x80, 0xf7, 0x6f, 0x06, 0x7c, 0xff, 0x9e, 0x9d, 0x6a, 0x7a, 0x23,
- 0xa3, 0x9e, 0xc2, 0xe4, 0x67, 0xc6, 0x48, 0x87, 0x02, 0xb9, 0x52, 0x62,
- 0xdc, 0x48, 0xc7, 0x60, 0xa7, 0x98, 0x1f, 0x08, 0x78, 0x34, 0xf7, 0xa3,
- 0xae, 0x6f, 0xb3, 0x7c, 0xda, 0xfb, 0x41, 0xfb, 0x5a, 0xdb, 0x95, 0x01,
- 0x2d, 0xa4, 0x81, 0x74, 0x15, 0x82, 0x9a, 0xf7, 0xe8, 0xe7, 0x80, 0xea,
- 0x27, 0x98, 0x1e, 0x10, 0xfa, 0xd0, 0xfc, 0x14, 0xf5, 0x80, 0xed, 0xd8,
- 0x97, 0x67, 0x93, 0xf3, 0x15, 0xbf, 0x8f, 0x42, 0x7d, 0x1f, 0xa0, 0x47,
- 0x36, 0x19, 0x76, 0x18, 0x6b, 0xcf, 0xae, 0x0e, 0xe3, 0xdd, 0x97, 0x24,
- 0x7b, 0xfa, 0x76, 0x03, 0x73, 0x40, 0xbf, 0xe4, 0xd1, 0x28, 0x6c, 0x36,
- 0xf5, 0x2c, 0x22, 0xb9, 0x18, 0xcb, 0x3e, 0xa2, 0xc7, 0x0d, 0x49, 0x46,
- 0xe5, 0xbf, 0xd2, 0x52, 0xa3, 0xe3, 0x79, 0x3d, 0x9f, 0x34, 0xe6, 0x43,
- 0x1a, 0xfc, 0xb9, 0xa4, 0xeb, 0xe6, 0xe2, 0xf3, 0x9a, 0xbc, 0x30, 0x61,
- 0xe3, 0x23, 0xda, 0x87, 0xb0, 0xdd, 0x64, 0xdd, 0xda, 0x4d, 0xa2, 0x0d,
- 0x79, 0x8f, 0x3a, 0x6b, 0xfc, 0x0a, 0x7d, 0xca, 0x20, 0xfa, 0x29, 0xce,
- 0x1a, 0x92, 0x73, 0xe0, 0xab, 0x9d, 0xb7, 0x69, 0x79, 0xad, 0xc9, 0x52,
- 0x78, 0x5d, 0x59, 0x3a, 0x68, 0x78, 0xf6, 0x1a, 0xbe, 0x05, 0xfe, 0x67,
- 0x62, 0xd6, 0x4a, 0xf9, 0xb2, 0x54, 0x9c, 0x7a, 0x2b, 0xb2, 0xe4, 0xb7,
- 0x8f, 0x40, 0x76, 0xfd, 0x31, 0xd6, 0xd2, 0xec, 0xd7, 0x01, 0x8d, 0xa5,
- 0xac, 0xc6, 0x28, 0x1c, 0xc7, 0xf3, 0x0d, 0x73, 0xab, 0x7c, 0xc3, 0x61,
- 0xb4, 0x95, 0x40, 0xae, 0xa7, 0x59, 0xf6, 0xcd, 0xfa, 0x7d, 0x1c, 0x56,
- 0x32, 0xbb, 0x77, 0xca, 0x32, 0x87, 0x82, 0x92, 0x19, 0x9a, 0x19, 0x90,
- 0xc1, 0x6a, 0x07, 0xd6, 0xf4, 0x0d, 0x17, 0xbe, 0xf3, 0xdd, 0x61, 0xb1,
- 0x61, 0x17, 0x31, 0xe7, 0x7e, 0xf0, 0xb8, 0x1a, 0x16, 0x23, 0xed, 0x20,
- 0xad, 0xc7, 0x58, 0xa1, 0xd0, 0xd0, 0xaa, 0x7c, 0x03, 0xea, 0xa0, 0xef,
- 0xfe, 0xb5, 0xf5, 0x20, 0x9f, 0xe0, 0x6d, 0xd6, 0x79, 0xd3, 0x85, 0x1f,
- 0xd6, 0x3e, 0x8b, 0xa5, 0xb4, 0x13, 0xbe, 0x8d, 0xf8, 0x10, 0xf4, 0x5b,
- 0xe9, 0x42, 0xc1, 0x48, 0xef, 0x47, 0x1f, 0xa2, 0xe4, 0xb4, 0x58, 0x7d,
- 0xda, 0xd7, 0x7b, 0x55, 0xbe, 0xa3, 0x9f, 0xb2, 0x37, 0x07, 0x4c, 0xc0,
- 0x39, 0x2d, 0x28, 0x5d, 0xcf, 0x99, 0x31, 0x99, 0x2c, 0x29, 0x4c, 0x23,
- 0xc9, 0xca, 0x1f, 0x49, 0xee, 0xb4, 0xc8, 0x37, 0xa7, 0x58, 0xef, 0x05,
- 0x5d, 0xef, 0x79, 0xd4, 0x4b, 0x26, 0x06, 0x03, 0x16, 0xfc, 0x80, 0x05,
- 0x35, 0xe9, 0x4d, 0x20, 0x35, 0x87, 0xf1, 0x1b, 0xa4, 0x93, 0x41, 0x3d,
- 0x0f, 0x03, 0x3d, 0x0f, 0x7e, 0x88, 0xdc, 0x53, 0x6a, 0x84, 0x3d, 0xf9,
- 0x2f, 0xa0, 0x35, 0x26, 0x5f, 0xc0, 0x3c, 0x2e, 0x4d, 0x11, 0x67, 0xbd,
- 0x20, 0x8b, 0x53, 0xc4, 0x5d, 0xcf, 0xcb, 0xe4, 0x54, 0xd2, 0xf9, 0x26,
- 0xf8, 0x7c, 0x4a, 0x38, 0x97, 0x5e, 0x07, 0x29, 0x30, 0xa0, 0x95, 0x78,
- 0x1c, 0xf6, 0xac, 0x67, 0xab, 0xd7, 0x5f, 0x97, 0xee, 0xcf, 0xae, 0x58,
- 0x72, 0xc5, 0xa4, 0x7d, 0xba, 0x56, 0xc7, 0xb3, 0x5a, 0xc7, 0x47, 0x9d,
- 0x0e, 0x31, 0xa0, 0xd7, 0x99, 0xb1, 0x02, 0xbc, 0x1f, 0xf5, 0xfa, 0x7f,
- 0x1b, 0x35, 0xfc, 0x33, 0x00, 0xac, 0x6a, 0x29, 0x7f, 0xf7, 0xb7, 0xd3,
- 0xf1, 0x7a, 0xdd, 0xe6, 0xf8, 0x2d, 0x68, 0x13, 0x42, 0x7a, 0x7d, 0xbd,
- 0x46, 0x1f, 0x75, 0x6d, 0x07, 0xa8, 0x17, 0x68, 0xf3, 0x07, 0xe0, 0x05,
- 0xf9, 0xff, 0x56, 0xf4, 0xb9, 0x37, 0xf8, 0x96, 0xf4, 0x79, 0xec, 0x7a,
- 0xfa, 0x5c, 0xaf, 0xcb, 0x67, 0xc9, 0x0b, 0x8c, 0x2d, 0x33, 0x9e, 0x6c,
- 0x75, 0x81, 0xd7, 0x09, 0xc8, 0x29, 0x68, 0x28, 0xfd, 0x8d, 0x9b, 0x09,
- 0x79, 0x78, 0xce, 0x93, 0x27, 0xd6, 0xf3, 0xeb, 0x78, 0xb6, 0x77, 0xb0,
- 0x7a, 0x45, 0xd9, 0xd9, 0x73, 0xca, 0xce, 0x5a, 0x87, 0x0b, 0x42, 0x79,
- 0xbb, 0x2d, 0x48, 0xbe, 0x3f, 0xed, 0x7c, 0x16, 0x34, 0x5a, 0x89, 0x84,
- 0xd1, 0x55, 0x30, 0x8c, 0xcf, 0xca, 0xfe, 0xf9, 0x87, 0x65, 0x7f, 0x89,
- 0x7d, 0xa4, 0xf1, 0xde, 0x46, 0x59, 0x13, 0x6c, 0x2d, 0x6d, 0xfa, 0x1b,
- 0x01, 0x6f, 0x2c, 0x03, 0xfe, 0x6b, 0x29, 0x70, 0x4f, 0xf5, 0x62, 0x20,
- 0x3b, 0x4f, 0xdd, 0x45, 0x79, 0xb5, 0xde, 0xe6, 0xfb, 0xf6, 0xbe, 0x66,
- 0xff, 0x06, 0x4b, 0x93, 0xc4, 0x80, 0x46, 0xd6, 0xe1, 0x9a, 0x51, 0x37,
- 0x2f, 0x98, 0xde, 0x9c, 0x3f, 0x09, 0x3e, 0x51, 0xaf, 0xc9, 0x37, 0xf8,
- 0xc0, 0x10, 0x75, 0x96, 0xcf, 0xe2, 0x06, 0xd3, 0xd4, 0x3b, 0x09, 0x05,
- 0x41, 0x46, 0x2e, 0xc6, 0x3a, 0x77, 0x80, 0xce, 0xb5, 0x3a, 0xcd, 0x75,
- 0x14, 0x6d, 0x43, 0x58, 0x36, 0x80, 0xe7, 0x4e, 0x19, 0x9f, 0xcf, 0x60,
- 0xcc, 0x3b, 0x75, 0xdf, 0xab, 0x7c, 0x0c, 0xfa, 0x48, 0xe8, 0xf5, 0xd8,
- 0xe0, 0xdb, 0x41, 0x94, 0x39, 0xba, 0xac, 0xa1, 0xae, 0xcc, 0x5f, 0xb7,
- 0x8f, 0x62, 0x7c, 0xfa, 0x8a, 0x61, 0x8d, 0x7f, 0x5c, 0x37, 0xc7, 0xf5,
- 0xee, 0xfb, 0x87, 0x42, 0xdd, 0xb8, 0x50, 0x2a, 0x98, 0x41, 0x25, 0xa3,
- 0x2f, 0xfc, 0x4e, 0x4d, 0x46, 0x81, 0x97, 0x55, 0x2f, 0xe4, 0x31, 0x69,
- 0x69, 0x06, 0x4f, 0x07, 0x41, 0x2b, 0x78, 0xd7, 0x1e, 0x00, 0xff, 0x9a,
- 0x25, 0x5f, 0x4d, 0xeb, 0x77, 0x2c, 0x0f, 0xc9, 0x68, 0xcc, 0xf7, 0x47,
- 0xb7, 0x99, 0x1e, 0xe6, 0x45, 0x9d, 0xd2, 0x8f, 0x83, 0x9e, 0x0e, 0x98,
- 0x92, 0x3f, 0x39, 0x08, 0x59, 0x23, 0x26, 0x6b, 0x80, 0xac, 0xc5, 0x94,
- 0xad, 0x37, 0x6c, 0xd6, 0xc7, 0xbb, 0xd3, 0xbf, 0x17, 0xf4, 0xda, 0xb0,
- 0x9e, 0xdf, 0xc6, 0x1f, 0xbb, 0x6d, 0xa5, 0xed, 0xa8, 0x63, 0x48, 0x50,
- 0x8d, 0x8f, 0xb2, 0xd3, 0xab, 0xc7, 0x37, 0xda, 0xfd, 0xf1, 0x1f, 0xd1,
- 0x7d, 0xb5, 0xd5, 0xf5, 0x15, 0xbb, 0xce, 0xf8, 0x78, 0x77, 0xfa, 0xa3,
- 0x9b, 0xbd, 0x36, 0xb1, 0xba, 0x36, 0xed, 0x6b, 0xda, 0xb0, 0xbe, 0x3f,
- 0x06, 0xde, 0x9d, 0xbe, 0xab, 0xd9, 0x6b, 0xc3, 0x7a, 0x0d, 0xf0, 0x6d,
- 0x7c, 0x47, 0xd9, 0xdf, 0x5f, 0x27, 0xfb, 0xfb, 0x21, 0xfb, 0xbe, 0x4c,
- 0xad, 0xc5, 0xc9, 0x7e, 0xbc, 0xc3, 0x38, 0x87, 0xd8, 0xaa, 0x16, 0xd7,
- 0x84, 0x4e, 0x34, 0x03, 0xb7, 0xb4, 0x30, 0x96, 0xd1, 0xb8, 0x98, 0xb1,
- 0x0d, 0x71, 0xb0, 0xd8, 0x21, 0xe9, 0x82, 0x8d, 0xea, 0x8a, 0xef, 0xa3,
- 0xc2, 0x55, 0x62, 0x0a, 0x2f, 0x67, 0xf4, 0x18, 0x8c, 0x6b, 0xc8, 0x77,
- 0xe6, 0x73, 0x2b, 0x71, 0x4e, 0x07, 0xe2, 0x20, 0xe2, 0x5d, 0xe2, 0x25,
- 0x9f, 0x7e, 0x9f, 0x9e, 0x03, 0x46, 0x4d, 0x27, 0x32, 0xc6, 0x60, 0x75,
- 0xd0, 0xf0, 0x74, 0x82, 0xef, 0x0f, 0x68, 0x9f, 0xb6, 0x96, 0xde, 0xb7,
- 0xaf, 0xa1, 0x97, 0xb8, 0x2a, 0x21, 0x13, 0x90, 0x91, 0xd0, 0x09, 0xda,
- 0xd8, 0xe7, 0x46, 0x16, 0x67, 0x89, 0x1f, 0xfa, 0xc0, 0x17, 0xd2, 0x4b,
- 0xfe, 0x51, 0x97, 0x5b, 0x60, 0x1f, 0xba, 0x52, 0x65, 0xd4, 0x67, 0x7c,
- 0x3d, 0xae, 0xe2, 0xb2, 0x66, 0xa4, 0x08, 0x9e, 0x40, 0xeb, 0x38, 0x68,
- 0x1d, 0xd7, 0x31, 0xd9, 0x3e, 0xd8, 0xef, 0xd0, 0xb4, 0x4f, 0xeb, 0x8d,
- 0x21, 0x7f, 0x6d, 0x56, 0xd3, 0x5e, 0xef, 0x77, 0x3c, 0xfc, 0x75, 0x4f,
- 0x0f, 0x65, 0xc6, 0x2a, 0x10, 0xb3, 0x8d, 0x2b, 0xf9, 0x00, 0xf6, 0x33,
- 0xc4, 0xd3, 0xa5, 0x16, 0xdf, 0xff, 0x72, 0x3e, 0xf4, 0xff, 0xd4, 0x79,
- 0x7f, 0x0e, 0xcd, 0xd2, 0x79, 0x82, 0x73, 0x58, 0xa1, 0x3f, 0xc6, 0xdd,
- 0x8d, 0xfd, 0xb0, 0x9b, 0x79, 0x45, 0xeb, 0x4e, 0xd9, 0x5b, 0x7a, 0xa7,
- 0xa6, 0xbf, 0x19, 0xf4, 0x8f, 0x42, 0xb6, 0x6b, 0x36, 0x23, 0x5f, 0x19,
- 0x43, 0xde, 0xc3, 0x62, 0xe4, 0x71, 0xbe, 0x42, 0xfb, 0xa1, 0xe7, 0x13,
- 0xe5, 0x7c, 0xd6, 0xda, 0x96, 0xf5, 0xf8, 0xfa, 0x8e, 0x35, 0x7c, 0x15,
- 0xcd, 0xd7, 0x88, 0x34, 0x9c, 0x50, 0x71, 0x2d, 0xfa, 0x25, 0xaf, 0xe9,
- 0xbf, 0x9e, 0x1b, 0x99, 0x9c, 0x95, 0xbe, 0xb0, 0x90, 0xbe, 0x38, 0xcb,
- 0xfa, 0x1b, 0xa4, 0xcb, 0xb9, 0x88, 0x79, 0xe7, 0xb1, 0xde, 0xc6, 0xb4,
- 0x27, 0xdf, 0xe4, 0x6f, 0xbe, 0x12, 0x45, 0x2c, 0xcd, 0xb1, 0xc9, 0x33,
- 0xd2, 0x6f, 0x2a, 0x7a, 0x56, 0xf8, 0x0d, 0xfa, 0x3e, 0x56, 0x59, 0xcb,
- 0xdb, 0x7a, 0x3b, 0xe3, 0xc7, 0xec, 0xdf, 0x35, 0x3d, 0xbd, 0x58, 0x2f,
- 0x66, 0x6f, 0x86, 0x7d, 0x0c, 0xd1, 0x36, 0x82, 0xf7, 0xdc, 0x5f, 0x59,
- 0x0a, 0x11, 0x83, 0x5f, 0x28, 0x85, 0x95, 0xcd, 0xcb, 0x3a, 0x2d, 0x5a,
- 0x3f, 0x6e, 0xd3, 0xbe, 0x23, 0xac, 0x6c, 0xb6, 0x18, 0x26, 0x71, 0x09,
- 0xca, 0x90, 0x9f, 0x67, 0xde, 0xa7, 0xe3, 0xde, 0x5d, 0x61, 0xfb, 0x0f,
- 0x43, 0xbe, 0x4d, 0xa8, 0xd1, 0x55, 0x1f, 0x93, 0xbb, 0xc0, 0x72, 0xef,
- 0x84, 0xdc, 0xde, 0x89, 0xb8, 0x3b, 0x21, 0xf9, 0x14, 0xf5, 0x68, 0x40,
- 0xc5, 0x26, 0x86, 0xbd, 0x0f, 0x65, 0x4d, 0x28, 0x83, 0x13, 0x33, 0x31,
- 0x7f, 0xfb, 0x77, 0x65, 0x1c, 0x32, 0x9e, 0x4f, 0xf5, 0x82, 0x0e, 0xda,
- 0x60, 0x60, 0x1c, 0x3b, 0xc5, 0xb8, 0x1d, 0x7f, 0xfd, 0x61, 0x6f, 0x5e,
- 0xbb, 0x90, 0x47, 0x0c, 0x9f, 0xea, 0xd4, 0x75, 0x36, 0x08, 0xf7, 0x7f,
- 0xf2, 0x66, 0x0b, 0xd2, 0xee, 0x35, 0x75, 0xdf, 0x8f, 0xfc, 0x7b, 0x75,
- 0xff, 0x05, 0xbc, 0xdf, 0x86, 0xdf, 0x20, 0xca, 0x6e, 0x47, 0x99, 0x83,
- 0xb2, 0xf7, 0x20, 0xff, 0x7e, 0xbd, 0x1f, 0xe0, 0xb7, 0x69, 0x41, 0xfe,
- 0x31, 0xbc, 0x87, 0xad, 0x30, 0x5f, 0xc6, 0xfb, 0xf7, 0xe2, 0xf7, 0xee,
- 0x35, 0x75, 0xda, 0xd6, 0xe4, 0x3f, 0xb5, 0xc2, 0x83, 0x0b, 0xa5, 0x9f,
- 0x69, 0xbb, 0x46, 0x79, 0x66, 0xfe, 0x94, 0x7e, 0xf7, 0xce, 0xd0, 0xea,
- 0xf2, 0x1d, 0x7e, 0xbe, 0x6e, 0x0d, 0x3b, 0xb1, 0x86, 0x3e, 0xc6, 0x7c,
- 0xbb, 0xf6, 0x5d, 0x6f, 0xf7, 0xe2, 0xf4, 0x92, 0xdf, 0x8e, 0x7e, 0xed,
- 0xce, 0x35, 0x63, 0x3c, 0xdf, 0x50, 0xcb, 0x37, 0x07, 0x86, 0x4e, 0xb2,
- 0xec, 0x72, 0xc3, 0xea, 0x3a, 0x6f, 0xd6, 0xe5, 0x37, 0x06, 0x86, 0x94,
- 0x8f, 0xbb, 0xab, 0x71, 0x75, 0x9d, 0x64, 0x63, 0x6d, 0x1e, 0x35, 0x5b,
- 0x18, 0x4a, 0x2f, 0x53, 0x8e, 0xa1, 0x0b, 0xdf, 0x1a, 0xc9, 0x4e, 0xb9,
- 0xee, 0x84, 0xb3, 0x14, 0x0f, 0x0a, 0x7d, 0x10, 0xb1, 0x2a, 0xcb, 0x5f,
- 0x46, 0x39, 0xb0, 0x4c, 0x75, 0x54, 0x68, 0x93, 0xd6, 0xc7, 0xa4, 0x09,
- 0x8d, 0x49, 0x55, 0x36, 0x94, 0x55, 0x18, 0xf2, 0xf9, 0x11, 0x60, 0x1e,
- 0xfd, 0xfc, 0x02, 0x9e, 0x13, 0xf5, 0xb8, 0x17, 0xfd, 0x2e, 0x8d, 0x64,
- 0x67, 0xe9, 0xf3, 0x2e, 0x8e, 0xec, 0x99, 0xa5, 0xce, 0x5f, 0x82, 0xce,
- 0x07, 0x64, 0x52, 0xf9, 0x3f, 0xd2, 0xc1, 0x76, 0x4b, 0x23, 0x9d, 0x0b,
- 0x4c, 0x97, 0x47, 0xec, 0x85, 0xa0, 0xec, 0x8b, 0x79, 0x6d, 0x99, 0x4f,
- 0x2c, 0xf8, 0x3a, 0x10, 0x95, 0x70, 0x9a, 0x32, 0x69, 0xa5, 0x80, 0xbd,
- 0x31, 0x9f, 0x27, 0x47, 0x26, 0x6d, 0xca, 0xe7, 0x87, 0x1a, 0xa4, 0x25,
- 0x2a, 0x0d, 0xca, 0xde, 0x3c, 0xa5, 0xc7, 0xba, 0x84, 0xb1, 0x36, 0x29,
- 0x7d, 0xca, 0xda, 0xa1, 0x38, 0xc6, 0x39, 0x68, 0xd8, 0xbd, 0x18, 0x8f,
- 0x91, 0x72, 0x87, 0x4c, 0x54, 0xa9, 0x37, 0xdb, 0xc2, 0xb5, 0xf8, 0xf8,
- 0x3c, 0xda, 0xf9, 0x71, 0x19, 0xc7, 0x2b, 0x03, 0x97, 0x41, 0x96, 0xd3,
- 0x96, 0x99, 0x0d, 0xc2, 0xcf, 0xcf, 0xfa, 0x75, 0x48, 0xd3, 0xd9, 0x91,
- 0xe4, 0x42, 0x12, 0x7d, 0x75, 0xd0, 0x86, 0xc1, 0x76, 0x05, 0xf1, 0x63,
- 0xdf, 0x6c, 0x07, 0x5f, 0x34, 0x40, 0x3f, 0x72, 0x1e, 0x7e, 0xa4, 0x43,
- 0x0e, 0x95, 0x54, 0x1f, 0x09, 0xf6, 0x51, 0xd4, 0x6d, 0x3b, 0x17, 0x1a,
- 0x10, 0xdb, 0x24, 0xcd, 0x17, 0xa5, 0xd6, 0x76, 0x48, 0xbc, 0x76, 0x5e,
- 0xdf, 0x3f, 0x77, 0x33, 0xb1, 0x7a, 0xdd, 0x8f, 0x4a, 0x10, 0x74, 0xe4,
- 0xd0, 0x07, 0xc7, 0xaf, 0xf5, 0xed, 0xf7, 0x97, 0x34, 0x97, 0xaf, 0xe9,
- 0x6b, 0x93, 0x8e, 0xb9, 0xac, 0x44, 0xee, 0xd7, 0x1a, 0x5b, 0xc5, 0x00,
- 0x90, 0x07, 0x09, 0xe5, 0x7a, 0x60, 0x17, 0xab, 0x03, 0x5a, 0x46, 0x5e,
- 0x40, 0x59, 0x7d, 0x6c, 0xe3, 0xc9, 0x57, 0x01, 0x98, 0xae, 0x08, 0x3d,
- 0x0f, 0xa6, 0x33, 0xad, 0xde, 0x5e, 0xd3, 0xf5, 0xe2, 0x19, 0xc8, 0x0d,
- 0xfa, 0x2c, 0xae, 0xb4, 0xe5, 0x9c, 0x5e, 0x18, 0xb9, 0x34, 0x15, 0xc7,
- 0x9c, 0x3c, 0xbf, 0xe0, 0xf1, 0x9a, 0x3e, 0x27, 0x20, 0x8b, 0x76, 0x02,
- 0x71, 0x33, 0x7d, 0x7c, 0x42, 0x5e, 0xb2, 0x7d, 0xff, 0x43, 0x5f, 0x84,
- 0xfa, 0x55, 0xd2, 0x46, 0xda, 0xcf, 0x63, 0x6e, 0xae, 0xcc, 0x38, 0x9e,
- 0x0c, 0xf6, 0xc0, 0x8f, 0x7c, 0x23, 0x64, 0x1d, 0x66, 0x7c, 0x75, 0x25,
- 0x54, 0x3f, 0x1f, 0x1f, 0x2b, 0x3c, 0xaf, 0xf7, 0x7e, 0xcf, 0x6b, 0x79,
- 0x59, 0x82, 0xbc, 0xf4, 0x26, 0x4c, 0xe9, 0x06, 0xed, 0xa8, 0xd3, 0xd7,
- 0x85, 0x38, 0x87, 0x31, 0x74, 0x1c, 0xf4, 0x98, 0xb0, 0x1d, 0x9b, 0x34,
- 0x66, 0xff, 0x77, 0x61, 0xfa, 0xb6, 0x56, 0xb5, 0xaf, 0x7c, 0x5e, 0xc9,
- 0xb3, 0x27, 0xdf, 0x41, 0xfd, 0xde, 0x97, 0xa9, 0x20, 0x21, 0x8d, 0xd4,
- 0xf6, 0x4f, 0x59, 0xff, 0x39, 0x5d, 0xff, 0x59, 0xd4, 0x0f, 0x60, 0x4e,
- 0xae, 0xbb, 0x57, 0xd1, 0xfb, 0x1c, 0xf8, 0x1e, 0x94, 0xe2, 0x8a, 0xcc,
- 0x3f, 0x07, 0x99, 0xa7, 0x7c, 0x9f, 0x87, 0xbe, 0x82, 0xf8, 0x7b, 0x29,
- 0xf7, 0x65, 0x19, 0x3c, 0x9d, 0x6b, 0xe0, 0x5e, 0x67, 0xc2, 0x60, 0xec,
- 0x49, 0x99, 0xec, 0x90, 0xc7, 0x4b, 0x49, 0x73, 0xa2, 0x6e, 0x2d, 0x77,
- 0xac, 0x5a, 0x4b, 0xca, 0x80, 0xaa, 0x9f, 0x62, 0xfd, 0x72, 0x9d, 0x0c,
- 0xcc, 0xcf, 0x5e, 0xaf, 0x1d, 0x65, 0x80, 0xed, 0xd6, 0xc3, 0xe9, 0xdc,
- 0x1b, 0x74, 0xdd, 0x45, 0x87, 0xfb, 0xb8, 0x8d, 0x52, 0x50, 0x32, 0x16,
- 0x90, 0xa2, 0x43, 0xbd, 0xca, 0x26, 0x42, 0x62, 0x01, 0x2b, 0x7d, 0x10,
- 0x74, 0x66, 0x52, 0x61, 0xf1, 0xf6, 0x12, 0xc6, 0xb1, 0x06, 0x4b, 0xa6,
- 0xeb, 0x5e, 0xb2, 0x45, 0xca, 0x88, 0x3d, 0x17, 0x91, 0x16, 0x2b, 0xd0,
- 0xd9, 0x68, 0x08, 0x36, 0xc0, 0x97, 0xf1, 0x88, 0xcc, 0xa1, 0xce, 0x3c,
- 0xde, 0x3d, 0x5e, 0xf1, 0x25, 0xc6, 0x75, 0x0d, 0xf0, 0x68, 0x8f, 0xfd,
- 0xff, 0xdc, 0x7c, 0xac, 0xbe, 0xae, 0x8f, 0x89, 0x89, 0x65, 0x89, 0x4d,
- 0x89, 0x29, 0xf9, 0x8e, 0x38, 0xf1, 0x20, 0x68, 0xa1, 0xce, 0xb6, 0x48,
- 0x24, 0x6d, 0xc5, 0x87, 0xc5, 0xf7, 0xfd, 0x97, 0x21, 0x4b, 0x05, 0xb7,
- 0xd1, 0xee, 0x90, 0x67, 0x20, 0x37, 0xe7, 0x57, 0x70, 0x4c, 0x02, 0x72,
- 0x44, 0x3f, 0xea, 0xca, 0x39, 0xc7, 0x4e, 0x7c, 0x0e, 0xe9, 0xb7, 0x9d,
- 0xdf, 0x22, 0xdf, 0x9e, 0x10, 0xe9, 0x43, 0x2c, 0x04, 0xbb, 0x3e, 0xe3,
- 0x63, 0xfb, 0x16, 0xc6, 0x64, 0x5a, 0x96, 0xae, 0xa0, 0x4f, 0xcb, 0x34,
- 0x00, 0x6a, 0xef, 0x42, 0x3d, 0x4f, 0x37, 0xfc, 0xb2, 0x83, 0xa8, 0x4b,
- 0x1a, 0x18, 0x2f, 0x7f, 0x07, 0x3a, 0xeb, 0xba, 0xf7, 0x39, 0x8b, 0x75,
- 0xb6, 0xe6, 0x39, 0xac, 0xbf, 0x92, 0xf3, 0xfe, 0x56, 0xe1, 0xfe, 0xaa,
- 0xf4, 0xb5, 0xa9, 0x78, 0x8e, 0xcf, 0x90, 0xf7, 0x7e, 0x62, 0xa1, 0x84,
- 0xc2, 0x9a, 0xc4, 0x0d, 0xe7, 0xc1, 0xfb, 0x4f, 0x2a, 0x4c, 0x43, 0xfc,
- 0x06, 0xfa, 0x4b, 0xc4, 0x14, 0x1e, 0x96, 0xf6, 0x70, 0x1d, 0xb1, 0x45,
- 0x0a, 0x6b, 0xe3, 0xe3, 0x0b, 0xb6, 0x65, 0x3d, 0xb6, 0xad, 0x5f, 0x3f,
- 0xd6, 0xd9, 0x14, 0xc8, 0x1d, 0xa3, 0x3c, 0xd3, 0x3f, 0xb6, 0xca, 0xbe,
- 0x54, 0x23, 0xf8, 0xde, 0xa6, 0xfd, 0xf8, 0xfb, 0x80, 0xd9, 0x80, 0xbd,
- 0x4d, 0xcb, 0xa9, 0xd9, 0x9e, 0xf7, 0xa0, 0xec, 0x17, 0xe0, 0x3f, 0xcb,
- 0xf6, 0x37, 0x78, 0x7e, 0xf2, 0x61, 0xe8, 0xf2, 0xdc, 0x26, 0x6f, 0xef,
- 0x8a, 0xeb, 0xe0, 0xe3, 0x04, 0x1f, 0xf7, 0x99, 0x1a, 0xef, 0x73, 0x6d,
- 0xbc, 0x7d, 0x2e, 0x43, 0xd5, 0x65, 0xac, 0x55, 0x1f, 0x5b, 0x52, 0x87,
- 0x5d, 0xf7, 0x9c, 0xe3, 0xe3, 0xc8, 0xed, 0xf0, 0xa1, 0x21, 0xcd, 0xeb,
- 0x66, 0xf0, 0x9a, 0x18, 0x25, 0x22, 0x89, 0x36, 0x62, 0x8a, 0x07, 0x1b,
- 0x6a, 0x58, 0xe6, 0x6f, 0xdc, 0xa0, 0xcd, 0x78, 0x8f, 0x38, 0x86, 0xb4,
- 0x6f, 0xd7, 0x78, 0x86, 0xd8, 0xe6, 0x31, 0x8c, 0x11, 0x94, 0x44, 0x3b,
- 0xf3, 0x7f, 0xa9, 0xdb, 0xf0, 0xd9, 0x95, 0xee, 0xad, 0xf5, 0xf2, 0x3c,
- 0x00, 0x3a, 0x39, 0x1f, 0x7f, 0xef, 0xb5, 0x43, 0xd9, 0x93, 0x9a, 0x5c,
- 0xf8, 0x34, 0xf9, 0xe3, 0x92, 0xb6, 0xb8, 0xb4, 0x81, 0xb6, 0x7b, 0xe0,
- 0x53, 0xb6, 0xb6, 0xb1, 0x4f, 0x7f, 0xec, 0x7a, 0x9a, 0xea, 0xf1, 0x55,
- 0x02, 0x63, 0x34, 0xca, 0xd6, 0x76, 0xf2, 0xae, 0x43, 0xf9, 0x96, 0xda,
- 0x7a, 0xd0, 0xf7, 0x73, 0xec, 0xb5, 0xe5, 0xef, 0xad, 0xa3, 0x6b, 0x2d,
- 0xe6, 0xdb, 0x86, 0x77, 0xa4, 0xc9, 0x84, 0x5d, 0x72, 0x65, 0x87, 0xe3,
- 0xe3, 0xbb, 0x7a, 0x3a, 0x88, 0xf1, 0x48, 0x33, 0x69, 0xf0, 0x31, 0x39,
- 0x7f, 0x5c, 0x1b, 0xd2, 0x93, 0xd6, 0xe7, 0x44, 0xfb, 0xf5, 0xbc, 0x6e,
- 0xd3, 0x75, 0x92, 0x68, 0xfb, 0xc7, 0x98, 0x03, 0x9f, 0x39, 0x0f, 0x1f,
- 0x1b, 0x26, 0xbd, 0x7e, 0xa2, 0xeb, 0xc5, 0x00, 0xd4, 0x19, 0x9f, 0x4f,
- 0x6d, 0x7a, 0x8d, 0xb6, 0xaf, 0x19, 0xd7, 0x72, 0x56, 0xdb, 0x91, 0xf7,
- 0xd4, 0xcd, 0xaf, 0x4f, 0x0a, 0xf3, 0x94, 0x8b, 0x77, 0x21, 0xf5, 0x63,
- 0xa3, 0x7e, 0xf8, 0x91, 0x0c, 0x62, 0x21, 0xc6, 0x48, 0xd7, 0xc4, 0x47,
- 0x3c, 0x47, 0x1c, 0xcb, 0x23, 0x5e, 0x56, 0x7e, 0xc4, 0xf3, 0x91, 0xc8,
- 0xc3, 0x9e, 0x54, 0xef, 0xa5, 0x8c, 0x8d, 0x8d, 0x57, 0x9c, 0xb1, 0xbd,
- 0x95, 0xfe, 0x31, 0xc6, 0x11, 0x9e, 0xcc, 0xa1, 0x7e, 0x45, 0xc6, 0x0d,
- 0xb4, 0xcb, 0xaa, 0x76, 0x6a, 0x1f, 0x68, 0x9d, 0x7e, 0x84, 0xfa, 0x38,
- 0xee, 0x8d, 0x15, 0x19, 0xcb, 0xc1, 0x06, 0xcd, 0xcf, 0xc0, 0xc7, 0xd9,
- 0x56, 0x86, 0x72, 0xb9, 0xc7, 0xb1, 0x86, 0x95, 0xec, 0xc5, 0xac, 0x51,
- 0xae, 0x65, 0x79, 0xe6, 0x1d, 0xb0, 0xa1, 0xae, 0xdc, 0x0d, 0x5b, 0xf8,
- 0x10, 0x64, 0x55, 0xce, 0xc0, 0x10, 0x9e, 0x81, 0xf1, 0x3a, 0x13, 0x13,
- 0xe3, 0x78, 0x87, 0x84, 0x8f, 0xc4, 0x25, 0x74, 0x84, 0xb1, 0x58, 0xd2,
- 0xbc, 0x5b, 0x04, 0x3e, 0xf1, 0xc5, 0xdb, 0x0d, 0xb1, 0x06, 0x32, 0x92,
- 0x44, 0x3c, 0xd9, 0x6b, 0x96, 0x91, 0x16, 0x25, 0x99, 0x3a, 0x8d, 0xbe,
- 0xc2, 0x67, 0x50, 0x17, 0xed, 0x9a, 0x16, 0x13, 0xf8, 0xb5, 0x4b, 0x74,
- 0xd1, 0xd3, 0x95, 0xe8, 0xe2, 0xea, 0x3d, 0x94, 0xc1, 0x95, 0x3d, 0x14,
- 0xbe, 0x7f, 0x43, 0xef, 0xfd, 0x3c, 0xab, 0xe3, 0x1a, 0xca, 0x08, 0x7d,
- 0x9b, 0x8a, 0xcd, 0x60, 0xc7, 0x9f, 0x45, 0x2c, 0x6c, 0x4b, 0xae, 0x04,
- 0xcc, 0x9e, 0x76, 0xe5, 0x29, 0xa7, 0xe0, 0x66, 0xfb, 0x5d, 0xb9, 0xec,
- 0xd8, 0x85, 0xbc, 0x58, 0x6f, 0xd0, 0xde, 0xfd, 0x4f, 0xe7, 0xfd, 0xb2,
- 0xab, 0xd5, 0xda, 0x95, 0x09, 0x14, 0xdc, 0x66, 0x3b, 0x2a, 0x37, 0xa5,
- 0x0f, 0xca, 0x9e, 0x2d, 0x4b, 0x66, 0x50, 0x32, 0x37, 0x01, 0x17, 0xc6,
- 0xf3, 0xca, 0x56, 0xbd, 0xa6, 0xe2, 0xeb, 0x07, 0xba, 0x0e, 0xca, 0xc6,
- 0x2d, 0x96, 0x79, 0x35, 0x48, 0xcc, 0x76, 0x10, 0xb1, 0x80, 0x15, 0xcf,
- 0x05, 0x6d, 0x73, 0xa7, 0x58, 0xc3, 0x9f, 0x16, 0x9e, 0xdb, 0xda, 0xd2,
- 0x79, 0xc4, 0x8e, 0x7f, 0x22, 0xd0, 0xbd, 0xff, 0x13, 0x8c, 0xef, 0xce,
- 0x30, 0xef, 0x4a, 0x64, 0x8b, 0x89, 0xe7, 0x98, 0x74, 0x1e, 0x4f, 0x48,
- 0x12, 0x7c, 0xe9, 0x51, 0x3c, 0xe1, 0xf9, 0x51, 0x5c, 0xba, 0x8f, 0x10,
- 0x43, 0x29, 0xde, 0xf4, 0x80, 0x37, 0x29, 0xf0, 0x06, 0x31, 0x55, 0xaf,
- 0x79, 0x15, 0xe9, 0xb2, 0x24, 0x07, 0x7e, 0x00, 0xde, 0xf4, 0x80, 0x37,
- 0xdd, 0x67, 0x12, 0x68, 0x8f, 0x3e, 0x16, 0x3b, 0x91, 0x46, 0xe5, 0x83,
- 0x37, 0xb4, 0xe3, 0xd9, 0x96, 0xe4, 0x91, 0x08, 0xc6, 0x08, 0xc8, 0x8e,
- 0xae, 0x82, 0x0c, 0x6d, 0x41, 0x6c, 0x16, 0x3b, 0x28, 0x17, 0xe1, 0x87,
- 0x4a, 0x88, 0x11, 0x9e, 0x1a, 0xb0, 0x46, 0x97, 0x60, 0x4b, 0xab, 0xf7,
- 0xb8, 0xf2, 0xf2, 0x96, 0xbf, 0x70, 0xe3, 0x37, 0x58, 0xbb, 0x24, 0xd0,
- 0x2f, 0x93, 0x25, 0xe5, 0x1f, 0xe2, 0xd9, 0xa0, 0xc2, 0x65, 0x98, 0x63,
- 0x01, 0x3e, 0x86, 0xe7, 0xd1, 0x36, 0x6c, 0xfd, 0xa7, 0xe5, 0xa1, 0xb9,
- 0x09, 0xfc, 0x10, 0x6f, 0x4e, 0xb1, 0xee, 0x7e, 0xc4, 0x73, 0x0f, 0xcb,
- 0xbe, 0x29, 0x60, 0xc7, 0x34, 0xe8, 0xee, 0xb7, 0x11, 0xcf, 0xcd, 0x37,
- 0x4a, 0x0b, 0xca, 0xc0, 0xdb, 0xd1, 0xea, 0xda, 0x38, 0x6e, 0x09, 0xeb,
- 0x30, 0x20, 0x7f, 0x56, 0xed, 0x97, 0xaf, 0x55, 0xfb, 0xe4, 0x4f, 0xe0,
- 0x5b, 0xce, 0x57, 0x3b, 0xa0, 0x2b, 0x71, 0xac, 0x49, 0x1a, 0xeb, 0xe3,
- 0xc8, 0x73, 0xd5, 0x94, 0x3c, 0x0b, 0x5e, 0x3d, 0x83, 0xdf, 0x50, 0x29,
- 0x25, 0x3b, 0x4a, 0x7d, 0x7a, 0x8d, 0xb8, 0x3e, 0x36, 0xe8, 0xb1, 0x31,
- 0x77, 0xeb, 0xc9, 0x02, 0xf4, 0x6f, 0xbe, 0x6a, 0xbf, 0x5e, 0x96, 0x8f,
- 0x37, 0x72, 0x8f, 0xf7, 0xd4, 0x8a, 0x7f, 0x29, 0xb8, 0xa6, 0x6d, 0x1d,
- 0x1e, 0xc7, 0x3a, 0x94, 0xa1, 0xa7, 0xa3, 0x8a, 0xf7, 0x35, 0xdf, 0x53,
- 0xf6, 0x7c, 0x8f, 0x3f, 0xbf, 0x99, 0xbc, 0x7c, 0x5b, 0xb2, 0x47, 0x27,
- 0x65, 0xcf, 0x31, 0x57, 0x3e, 0xec, 0xb8, 0x90, 0x63, 0xda, 0xe2, 0x7e,
- 0xda, 0xf8, 0xc4, 0x78, 0xd0, 0x50, 0xb1, 0x94, 0x87, 0x5b, 0x7a, 0x37,
- 0x43, 0x67, 0x53, 0x19, 0x63, 0x42, 0x92, 0x47, 0x27, 0xa4, 0xf3, 0x28,
- 0x64, 0xc1, 0x61, 0x5f, 0x4b, 0xa6, 0x71, 0x8d, 0x3c, 0x70, 0x1c, 0x6b,
- 0x20, 0x27, 0xb6, 0xf9, 0xba, 0xa4, 0x30, 0xfe, 0x01, 0xe9, 0x42, 0x1b,
- 0x1b, 0x6d, 0xae, 0xaa, 0xb1, 0x9b, 0x31, 0x76, 0xa3, 0x1c, 0x8a, 0x59,
- 0x90, 0x35, 0xfa, 0xf0, 0xff, 0x25, 0xd9, 0x32, 0xd3, 0x9f, 0x4a, 0xf6,
- 0xd4, 0x47, 0x23, 0x12, 0xe5, 0x33, 0x4c, 0xc3, 0x09, 0x96, 0x77, 0x22,
- 0x65, 0xb9, 0x8d, 0x38, 0xfa, 0xe7, 0x92, 0x3d, 0xcb, 0xb1, 0x5f, 0x47,
- 0xf9, 0xcb, 0x92, 0x9d, 0xfe, 0x05, 0xf2, 0x17, 0x91, 0xbe, 0x81, 0x74,
- 0x54, 0x3a, 0xa7, 0x25, 0x90, 0x3d, 0xfb, 0x2d, 0xe4, 0x43, 0x48, 0x0f,
- 0xa1, 0xde, 0x76, 0xd0, 0xf7, 0xa7, 0xe8, 0x2f, 0x03, 0x9b, 0xf7, 0x3b,
- 0x9a, 0x7e, 0x96, 0xb3, 0x8c, 0xef, 0x0e, 0xc1, 0xa6, 0xfd, 0x67, 0xd8,
- 0x34, 0xfd, 0x3c, 0xcf, 0x3c, 0x6d, 0x1b, 0x9f, 0x27, 0xc0, 0x93, 0x03,
- 0xc8, 0xbb, 0xf2, 0xb0, 0x43, 0x7f, 0xb3, 0x4d, 0xc6, 0xcc, 0x82, 0x1b,
- 0x05, 0xae, 0x68, 0x86, 0x1e, 0x4c, 0x6c, 0x5d, 0x5f, 0x0f, 0x0e, 0x77,
- 0x1f, 0x94, 0xa6, 0x2d, 0xfe, 0xfc, 0xfd, 0xf9, 0xda, 0xe6, 0x4f, 0x14,
- 0x1f, 0xac, 0xc2, 0x27, 0x84, 0xf3, 0xb0, 0xe3, 0x5f, 0x30, 0xba, 0x77,
- 0x3d, 0x04, 0x3d, 0x30, 0xce, 0x32, 0xef, 0xe9, 0x81, 0x71, 0x16, 0xb6,
- 0xe1, 0x04, 0x62, 0xc4, 0x13, 0x1d, 0xd2, 0x38, 0x5d, 0xd3, 0x83, 0x86,
- 0xe9, 0x5f, 0xad, 0x07, 0x8d, 0x67, 0x51, 0xef, 0x2c, 0x79, 0x86, 0x3e,
- 0x4e, 0x91, 0x67, 0xed, 0x48, 0x3f, 0x8d, 0xb9, 0x92, 0xf6, 0x46, 0xd0,
- 0xee, 0xe1, 0xa2, 0xdb, 0x21, 0xef, 0x0f, 0x6c, 0x39, 0xa0, 0xcb, 0xff,
- 0xd2, 0x1d, 0x8e, 0x59, 0x73, 0x12, 0x20, 0x4f, 0x51, 0xb7, 0x4c, 0x1e,
- 0xde, 0xdc, 0x24, 0xd1, 0xfd, 0xd2, 0x49, 0xfe, 0x95, 0x77, 0x22, 0x5f,
- 0x70, 0xc3, 0x76, 0xb3, 0xe6, 0x27, 0x70, 0x52, 0x3f, 0xcb, 0x5f, 0x85,
- 0xcc, 0x10, 0xaf, 0xbe, 0x26, 0x7b, 0xa6, 0x5c, 0x19, 0x73, 0x38, 0xff,
- 0xef, 0x63, 0xfe, 0x99, 0x2d, 0x31, 0x59, 0x4a, 0xc4, 0xc0, 0x93, 0x79,
- 0xd8, 0xf6, 0x8b, 0xe2, 0xf1, 0x81, 0xe7, 0x02, 0x3b, 0xc4, 0x8e, 0x0f,
- 0x89, 0x9d, 0xfa, 0x01, 0xf8, 0x30, 0x04, 0xd9, 0xcf, 0x55, 0x29, 0x3b,
- 0xaf, 0xc8, 0x20, 0x64, 0xe2, 0x7b, 0x8e, 0x95, 0x02, 0x16, 0x82, 0xbd,
- 0xa0, 0x5c, 0x50, 0x26, 0x5a, 0x94, 0x4d, 0x3a, 0xe1, 0x58, 0x4f, 0x94,
- 0xe5, 0x56, 0x39, 0xd1, 0x46, 0xda, 0xf1, 0x6e, 0x5a, 0xf9, 0x8b, 0xd4,
- 0xb8, 0xd1, 0x05, 0x1b, 0x9d, 0x12, 0xb3, 0xbb, 0xd8, 0xe8, 0xdf, 0x21,
- 0xc9, 0x1f, 0x0d, 0xc8, 0x44, 0x37, 0xd7, 0x8a, 0xfd, 0x22, 0x5f, 0x2e,
- 0xb8, 0x21, 0xfb, 0x75, 0xf7, 0x64, 0x7b, 0x42, 0x3e, 0xd9, 0xbd, 0x22,
- 0x97, 0x73, 0x22, 0x9e, 0x5e, 0x0c, 0xaa, 0xf5, 0xf0, 0xe9, 0xf6, 0xe7,
- 0xe2, 0xbf, 0xeb, 0xab, 0x7b, 0xc7, 0xb9, 0x50, 0xd6, 0x57, 0x74, 0x27,
- 0x71, 0x2d, 0xad, 0xaf, 0x41, 0x9e, 0xac, 0x27, 0x8a, 0x72, 0x19, 0xb2,
- 0x07, 0x1e, 0x9e, 0x65, 0x4a, 0x1e, 0x4e, 0x40, 0xee, 0x5f, 0x95, 0x1d,
- 0x47, 0xa9, 0x33, 0xaf, 0x62, 0xae, 0xca, 0x96, 0xc0, 0x46, 0xb0, 0x3f,
- 0x57, 0x26, 0x9d, 0xae, 0xd4, 0x29, 0xb9, 0x35, 0xbe, 0x17, 0x31, 0xe7,
- 0xb8, 0xe9, 0xca, 0xa2, 0x53, 0x90, 0xc5, 0x01, 0xb4, 0x29, 0x7f, 0x1a,
- 0xbf, 0x4f, 0xe9, 0xb9, 0x3d, 0x0a, 0xbe, 0x5b, 0x89, 0x39, 0xe3, 0xf7,
- 0xc1, 0xf7, 0x87, 0x25, 0x39, 0xbd, 0x62, 0x6b, 0x20, 0x77, 0x9e, 0xad,
- 0x49, 0x9e, 0x35, 0xa5, 0x5c, 0xb2, 0xe5, 0x23, 0xb4, 0x21, 0x25, 0xce,
- 0x0b, 0x36, 0x86, 0x67, 0xec, 0x25, 0xd8, 0x99, 0x12, 0x6c, 0x0a, 0x6c,
- 0xc8, 0x9f, 0xa0, 0xfc, 0x59, 0xd4, 0x79, 0x06, 0xf1, 0xd3, 0x79, 0x60,
- 0xbf, 0x73, 0xc0, 0x14, 0x4f, 0x97, 0x32, 0x3a, 0x96, 0x55, 0xf3, 0x85,
- 0xcf, 0x52, 0xb1, 0x8f, 0x94, 0xe7, 0xd4, 0x7d, 0x1e, 0xb5, 0xb6, 0x59,
- 0x67, 0x13, 0x71, 0x16, 0x28, 0x13, 0x99, 0x9b, 0xf3, 0x79, 0x42, 0xdb,
- 0xc7, 0xf3, 0x19, 0xdf, 0x56, 0x36, 0xaf, 0xb1, 0x95, 0x22, 0x2f, 0x56,
- 0x3c, 0x3c, 0x49, 0x7c, 0x5c, 0x9c, 0x4a, 0xac, 0x9c, 0x63, 0x16, 0xe1,
- 0x37, 0x97, 0x11, 0x67, 0x44, 0xd2, 0xdf, 0x94, 0xc8, 0x71, 0xd7, 0xfd,
- 0x21, 0xfc, 0x66, 0x01, 0x6b, 0x62, 0x04, 0x50, 0xbe, 0xc0, 0x77, 0x94,
- 0x7b, 0xca, 0x76, 0x80, 0xe7, 0x19, 0xf2, 0x12, 0xca, 0xca, 0x2a, 0xfe,
- 0xfa, 0x16, 0xe8, 0xd1, 0xf4, 0xa9, 0x32, 0xd6, 0x6b, 0x94, 0xdc, 0x58,
- 0x0a, 0x31, 0x4e, 0xaf, 0xd9, 0x88, 0xf6, 0x73, 0x0b, 0x6c, 0x63, 0x0d,
- 0xf0, 0x3a, 0xd5, 0x4b, 0x0b, 0x2c, 0xef, 0x90, 0x8b, 0x88, 0x45, 0x49,
- 0x43, 0x79, 0x36, 0x2d, 0xde, 0xde, 0x31, 0xed, 0x15, 0x69, 0x45, 0x1e,
- 0xfc, 0xca, 0x96, 0xe8, 0x67, 0x43, 0x52, 0x88, 0x93, 0xd7, 0x71, 0x59,
- 0x9e, 0xfa, 0x4c, 0x13, 0xf7, 0x66, 0xb3, 0x36, 0x9f, 0xfd, 0xbd, 0x0e,
- 0xf3, 0x2d, 0xec, 0x75, 0x70, 0x7f, 0x23, 0x04, 0x5f, 0xa6, 0xf6, 0x3c,
- 0x90, 0x26, 0xea, 0xe2, 0x5f, 0xbe, 0xf7, 0xb0, 0x51, 0x0d, 0x3f, 0x12,
- 0x4f, 0x72, 0xbe, 0x56, 0x61, 0x09, 0xf6, 0xa3, 0x2d, 0x7d, 0x49, 0xee,
- 0x3d, 0xe1, 0xcd, 0xcf, 0x38, 0x25, 0xbc, 0x4b, 0x23, 0x57, 0x67, 0x2d,
- 0xe7, 0x0a, 0x30, 0x45, 0x2e, 0xe6, 0x60, 0xbd, 0x46, 0x9b, 0x60, 0xbf,
- 0x06, 0x32, 0xc6, 0x99, 0x26, 0x0f, 0x9f, 0x85, 0x64, 0x62, 0x8a, 0xe7,
- 0x9e, 0xb0, 0x6d, 0xc0, 0x90, 0xbf, 0x1b, 0xc2, 0x73, 0x85, 0x79, 0xc4,
- 0xa4, 0x5e, 0x3c, 0x8b, 0x67, 0xaf, 0x3f, 0xf2, 0xdc, 0x38, 0xc1, 0xb9,
- 0x07, 0xe4, 0x5e, 0xa0, 0x13, 0x41, 0xff, 0x9d, 0x7a, 0xac, 0xce, 0x53,
- 0x29, 0xee, 0x65, 0x4b, 0x12, 0xf6, 0x22, 0x8b, 0x58, 0x32, 0x17, 0xeb,
- 0xd0, 0xd8, 0x9c, 0xef, 0xd6, 0x62, 0x4f, 0x3f, 0xc6, 0x4b, 0xc9, 0xe7,
- 0x4b, 0x3e, 0xd6, 0x4b, 0xc1, 0xc7, 0x4a, 0x68, 0xb8, 0xc7, 0x95, 0x1f,
- 0x3a, 0xe4, 0x57, 0x1f, 0xf2, 0x8e, 0x1c, 0xae, 0xfe, 0xb2, 0xf3, 0xcd,
- 0xfa, 0xbf, 0x66, 0xd0, 0xc8, 0x1f, 0xe8, 0x03, 0x3e, 0x22, 0xed, 0x06,
- 0xfc, 0x79, 0x11, 0xb8, 0xcb, 0x38, 0xd3, 0xa1, 0xde, 0x19, 0xc0, 0x06,
- 0xe5, 0x29, 0xd8, 0xc6, 0x33, 0x3c, 0xf3, 0x85, 0x6d, 0x3b, 0x13, 0x96,
- 0xe2, 0x0c, 0xe5, 0x52, 0xda, 0x0c, 0xac, 0x17, 0xeb, 0x97, 0xa7, 0x3a,
- 0x90, 0x36, 0x23, 0x4d, 0xa8, 0x7e, 0xca, 0x53, 0xb6, 0x6a, 0x5f, 0x9e,
- 0x4a, 0xa9, 0x76, 0xe5, 0xa9, 0x3e, 0xa4, 0x8e, 0x34, 0x9c, 0x41, 0xe0,
- 0x74, 0xa6, 0x5b, 0x26, 0x4e, 0xc2, 0xbf, 0xf4, 0x1b, 0xea, 0xbe, 0xc4,
- 0x38, 0xfc, 0x4f, 0x08, 0x51, 0xd6, 0x15, 0x73, 0x00, 0x18, 0x6b, 0x1b,
- 0x30, 0xc8, 0x36, 0xb1, 0x8f, 0x73, 0xfe, 0xb4, 0xbd, 0xcb, 0xdc, 0xff,
- 0x8a, 0x3f, 0x28, 0x19, 0xd9, 0x37, 0xd3, 0x08, 0x7d, 0x0d, 0x99, 0x45,
- 0xe9, 0x32, 0x87, 0x90, 0xcf, 0xcf, 0x91, 0x6f, 0xf7, 0xab, 0xd8, 0x2d,
- 0xeb, 0xc4, 0xa2, 0x12, 0x4d, 0x63, 0x8c, 0xb7, 0xd2, 0xbe, 0x07, 0xf2,
- 0x67, 0xeb, 0x3e, 0xd2, 0xa0, 0xa7, 0x9e, 0x1f, 0x3c, 0xeb, 0xcd, 0xfc,
- 0x8a, 0xb3, 0x5e, 0xca, 0x35, 0xf9, 0x7b, 0xbf, 0x2c, 0xdb, 0x69, 0x79,
- 0xc9, 0x4e, 0xc9, 0x45, 0x7b, 0xab, 0xfc, 0x39, 0xfc, 0xf4, 0x25, 0x7b,
- 0xba, 0x89, 0x58, 0xa0, 0xac, 0xce, 0xcf, 0xfc, 0xb5, 0xb2, 0xf5, 0x3e,
- 0xfa, 0x8f, 0x64, 0x71, 0x8a, 0xd8, 0xd9, 0xdd, 0xbe, 0xc7, 0x29, 0xd0,
- 0x6f, 0x81, 0x06, 0x62, 0xb5, 0x02, 0xfc, 0xdf, 0x41, 0x19, 0x72, 0xe8,
- 0xf7, 0x94, 0x8f, 0x8a, 0x0f, 0x79, 0xfa, 0xec, 0xe4, 0x61, 0x57, 0x97,
- 0x67, 0xa0, 0x4f, 0x42, 0xf9, 0xc7, 0xf3, 0x1c, 0xd7, 0xdd, 0x96, 0x2f,
- 0x94, 0x38, 0xcf, 0xe2, 0xe6, 0xa8, 0x04, 0x65, 0x58, 0xe1, 0x85, 0x16,
- 0x79, 0x71, 0x61, 0x83, 0x18, 0xf0, 0x50, 0xc6, 0x2d, 0x61, 0x75, 0xd3,
- 0x84, 0xf1, 0xb7, 0xb4, 0xf2, 0xbe, 0xd8, 0x87, 0xc1, 0x1b, 0xee, 0x05,
- 0x60, 0x6e, 0xad, 0x9c, 0x89, 0x9f, 0xef, 0x83, 0x7e, 0xf1, 0x39, 0x20,
- 0x39, 0x3b, 0x86, 0x67, 0xa6, 0xd4, 0x39, 0xee, 0x93, 0x05, 0xc5, 0xc3,
- 0xdc, 0xe3, 0xea, 0x7d, 0xa3, 0x7d, 0x07, 0x70, 0x1d, 0xe5, 0x15, 0xe9,
- 0xa2, 0x37, 0x6e, 0x0e, 0x38, 0x2e, 0xdf, 0xd7, 0xa4, 0xce, 0xff, 0x0a,
- 0xd0, 0x85, 0x71, 0x55, 0xbf, 0x5f, 0x2e, 0x4d, 0xed, 0x8f, 0x7a, 0xfa,
- 0x31, 0xa0, 0x9f, 0xf9, 0x9e, 0xf1, 0x15, 0xf7, 0x4b, 0x5e, 0x19, 0x99,
- 0xb4, 0xbf, 0xa1, 0xf5, 0x47, 0x02, 0x77, 0xf7, 0x00, 0x87, 0x1e, 0x69,
- 0xc0, 0x5c, 0xac, 0x44, 0x22, 0x60, 0xb4, 0x1b, 0xc0, 0xf1, 0x43, 0xca,
- 0xe7, 0xf6, 0xa8, 0xfd, 0xe8, 0x53, 0xa9, 0x16, 0x29, 0x9b, 0xb6, 0xba,
- 0x17, 0xb7, 0x64, 0x6e, 0x21, 0xd6, 0xc7, 0xaf, 0x09, 0x65, 0x5d, 0x48,
- 0x1b, 0x91, 0xbe, 0x4b, 0x8a, 0xc7, 0xa6, 0xf5, 0x78, 0xe1, 0x35, 0xf9,
- 0x3e, 0x9d, 0x7e, 0x44, 0xc7, 0x53, 0x1c, 0x27, 0x2c, 0xf6, 0x17, 0x9b,
- 0xa5, 0xeb, 0x88, 0x09, 0x6c, 0x1b, 0x07, 0xd6, 0xed, 0x90, 0xd4, 0x91,
- 0x84, 0xdc, 0x72, 0xc4, 0xdf, 0x73, 0xfa, 0x0f, 0x23, 0x49, 0xb5, 0xc7,
- 0xf9, 0xdd, 0x11, 0x7b, 0x8e, 0xe9, 0x6b, 0xfa, 0xfe, 0xde, 0x15, 0x7d,
- 0xaf, 0xef, 0x47, 0x23, 0x3d, 0x2a, 0xfd, 0x6f, 0x23, 0x29, 0x95, 0xbe,
- 0x3e, 0x72, 0x4b, 0xc5, 0x8b, 0x8f, 0x8a, 0xf3, 0x29, 0xf9, 0x5c, 0x89,
- 0xf8, 0xb2, 0x1f, 0xd8, 0xd1, 0x81, 0x9d, 0xe9, 0x83, 0x9d, 0x49, 0xc1,
- 0xce, 0x0c, 0xd0, 0xce, 0xc0, 0x6e, 0xbf, 0x02, 0xbb, 0xed, 0xc8, 0xf7,
- 0x20, 0xaf, 0x4f, 0x3b, 0x8d, 0xc0, 0x85, 0xae, 0xeb, 0xcd, 0xd5, 0x7a,
- 0x62, 0x09, 0xeb, 0x5b, 0x3e, 0x2d, 0x91, 0x56, 0xd8, 0xa0, 0x2d, 0x27,
- 0x1a, 0x64, 0x3e, 0xe6, 0xba, 0x47, 0x1d, 0x5b, 0xae, 0xa2, 0x7e, 0xd6,
- 0xa6, 0x1e, 0xbf, 0x14, 0x65, 0x3c, 0x76, 0x75, 0x6a, 0x2b, 0x6c, 0x12,
- 0xe5, 0x3d, 0x22, 0xe5, 0xb1, 0xb8, 0x2c, 0x20, 0x3e, 0xab, 0xd5, 0x49,
- 0xe1, 0x99, 0xfa, 0xff, 0x5d, 0xd4, 0x4d, 0xc1, 0x3f, 0x98, 0xb2, 0xd8,
- 0x93, 0x90, 0x53, 0x3d, 0xd6, 0x40, 0xc2, 0xa0, 0xed, 0x4a, 0xc8, 0x1c,
- 0x62, 0xfd, 0x72, 0x89, 0xf5, 0x59, 0x0f, 0xfa, 0x59, 0xf2, 0xda, 0x4d,
- 0x96, 0x7c, 0x3b, 0xd1, 0xcf, 0x7d, 0xc8, 0x50, 0xae, 0xc7, 0xf3, 0x01,
- 0x86, 0xd1, 0x08, 0x39, 0x70, 0xc0, 0xff, 0x31, 0x94, 0xf7, 0xf3, 0xbe,
- 0x07, 0xca, 0x88, 0x85, 0x7e, 0x1c, 0x25, 0x46, 0xcc, 0x39, 0x63, 0x28,
- 0x63, 0x1b, 0x2b, 0x9e, 0x44, 0xf9, 0xa8, 0x24, 0xe3, 0x79, 0x75, 0xf7,
- 0xac, 0x1d, 0x65, 0xec, 0x23, 0xa8, 0xf7, 0x63, 0xfe, 0x8f, 0x92, 0xa3,
- 0xa0, 0xed, 0x97, 0xf7, 0xaa, 0xbd, 0x81, 0x8c, 0xe9, 0x40, 0x1f, 0x58,
- 0x96, 0x34, 0xd9, 0x2e, 0xe7, 0x38, 0xca, 0x16, 0xde, 0x57, 0xe1, 0x19,
- 0x5e, 0x44, 0xee, 0xad, 0x34, 0x4b, 0xae, 0xd2, 0x70, 0x1d, 0xfb, 0xef,
- 0xeb, 0xe4, 0x72, 0xdc, 0x14, 0xde, 0x83, 0xf0, 0xf4, 0x3c, 0xb4, 0x95,
- 0x3a, 0x31, 0xc0, 0x73, 0x03, 0xf8, 0x5b, 0xac, 0x05, 0xfc, 0xef, 0x39,
- 0xf8, 0xdf, 0xa7, 0x4b, 0x35, 0xfb, 0xe1, 0xf9, 0x5d, 0xda, 0x80, 0x27,
- 0xb1, 0x66, 0xa3, 0xc0, 0xfd, 0x3b, 0x11, 0x0f, 0x0c, 0x03, 0xfb, 0x0f,
- 0x62, 0xfd, 0xd2, 0x58, 0xbb, 0x31, 0xde, 0x17, 0xc2, 0x3a, 0x0e, 0xa8,
- 0x73, 0xe6, 0x19, 0x75, 0xe7, 0xe2, 0x47, 0xca, 0xf7, 0x3e, 0x5e, 0x32,
- 0xe0, 0x1f, 0x0a, 0xee, 0x66, 0xdb, 0x02, 0xfe, 0x5b, 0xd1, 0xe7, 0x81,
- 0x17, 0x61, 0x57, 0x7e, 0x06, 0xba, 0xce, 0xcf, 0xd0, 0x9f, 0xa3, 0x8e,
- 0x87, 0xb7, 0x1d, 0xee, 0x75, 0x41, 0x9f, 0x0f, 0x2f, 0xcb, 0x12, 0x70,
- 0x47, 0x86, 0x72, 0x8c, 0xf8, 0xc1, 0x7a, 0x7a, 0x4e, 0xba, 0x69, 0x03,
- 0xe7, 0xa8, 0x2b, 0xfd, 0xd3, 0x71, 0x60, 0x3d, 0x20, 0x79, 0x75, 0xae,
- 0x8a, 0xe7, 0xb3, 0x1b, 0xc5, 0x20, 0xde, 0x73, 0x6e, 0x40, 0x19, 0xed,
- 0x86, 0x8f, 0x91, 0x96, 0x06, 0xda, 0x24, 0xb3, 0xa5, 0x4d, 0xd9, 0x0e,
- 0xcb, 0x79, 0x09, 0xe3, 0xee, 0x90, 0x46, 0x60, 0xb8, 0x02, 0xc6, 0x38,
- 0x20, 0xff, 0xd5, 0xe1, 0x1e, 0x95, 0x17, 0xfb, 0x81, 0x96, 0x08, 0x78,
- 0xd6, 0xb4, 0xc7, 0x36, 0x23, 0x3b, 0xaa, 0xec, 0x3f, 0xa2, 0x30, 0x56,
- 0x4e, 0xd8, 0x3f, 0xfc, 0x04, 0xc6, 0x4c, 0x4e, 0x53, 0xf6, 0x7b, 0xb1,
- 0x6e, 0xbf, 0x0d, 0x0c, 0x44, 0xae, 0x7e, 0x75, 0x83, 0xa7, 0x2f, 0xa4,
- 0x7f, 0x89, 0x78, 0x82, 0x67, 0x00, 0x5e, 0x5c, 0xbe, 0x42, 0x5b, 0x3f,
- 0xe8, 0x9d, 0xdd, 0xe0, 0x9f, 0x25, 0x77, 0x4e, 0x7b, 0xfe, 0xba, 0xf3,
- 0x2c, 0x5a, 0x1d, 0x95, 0x76, 0x9e, 0x4a, 0x1b, 0x72, 0x8b, 0xdc, 0x19,
- 0xf2, 0xfa, 0x31, 0x4e, 0x98, 0x90, 0x55, 0xda, 0x81, 0x76, 0xc8, 0x39,
- 0xf3, 0xb4, 0x29, 0xb4, 0x09, 0x94, 0x05, 0x5b, 0x8a, 0x55, 0xd8, 0x84,
- 0x96, 0x0e, 0x99, 0x23, 0xcf, 0x4e, 0xd0, 0x4e, 0xfc, 0x48, 0x26, 0xd7,
- 0xd8, 0xca, 0x41, 0xf1, 0xe3, 0xda, 0x66, 0x09, 0xa7, 0x6d, 0xf3, 0x3e,
- 0x35, 0x47, 0xcf, 0x5e, 0xee, 0x23, 0xfe, 0x9c, 0xc9, 0x58, 0x6d, 0xa2,
- 0xb1, 0xa7, 0xc2, 0x4f, 0xdf, 0xc7, 0x5c, 0xd9, 0x87, 0xe2, 0xd3, 0xc0,
- 0xa0, 0x17, 0x0b, 0xa8, 0x3d, 0x3f, 0xe0, 0xe0, 0xf8, 0xcf, 0x60, 0x6b,
- 0x73, 0xc4, 0x25, 0xe0, 0x73, 0xe7, 0x51, 0xca, 0xd1, 0x66, 0xda, 0x32,
- 0xe0, 0xbc, 0x14, 0xed, 0xb5, 0x2c, 0x4c, 0x03, 0x73, 0x19, 0x77, 0x48,
- 0x9e, 0xf2, 0xca, 0xbb, 0x0a, 0x0b, 0x86, 0x4c, 0xce, 0xb6, 0x48, 0xd7,
- 0x09, 0xee, 0xaf, 0x9e, 0x8a, 0x4a, 0x0b, 0xf7, 0x58, 0xe9, 0x83, 0xfa,
- 0x25, 0x87, 0xf2, 0xce, 0x13, 0x41, 0xb5, 0x1f, 0x36, 0x67, 0x90, 0x47,
- 0x7d, 0xb0, 0x07, 0x56, 0x6a, 0xc9, 0xd8, 0xd6, 0xe4, 0x61, 0x48, 0xc8,
- 0x52, 0x09, 0x32, 0x56, 0x82, 0x8c, 0x95, 0x20, 0x63, 0x25, 0xc8, 0x18,
- 0xb0, 0xdf, 0x79, 0xe8, 0xdf, 0xb9, 0xd2, 0x80, 0xf6, 0xeb, 0xbb, 0x94,
- 0x5f, 0x3f, 0x54, 0x7a, 0xc5, 0x65, 0xfa, 0xac, 0x8a, 0x4d, 0xfb, 0x20,
- 0x83, 0x8c, 0x45, 0xfd, 0x18, 0xf5, 0x15, 0x79, 0x72, 0xe6, 0x55, 0x39,
- 0x35, 0x53, 0xc3, 0x81, 0x13, 0x25, 0x57, 0x5e, 0x72, 0x10, 0x7f, 0xce,
- 0x13, 0x53, 0x65, 0x5a, 0x1b, 0x15, 0xb6, 0x3a, 0x28, 0x79, 0x85, 0x93,
- 0x95, 0x1f, 0x01, 0xbe, 0x52, 0xb8, 0x90, 0xba, 0x29, 0x6d, 0x5b, 0x2e,
- 0xcb, 0x39, 0xf8, 0xf1, 0x85, 0xea, 0x6b, 0xf2, 0x8c, 0xc2, 0xe3, 0xe4,
- 0xc3, 0x3b, 0xe5, 0xa7, 0xa6, 0x77, 0x9e, 0x7f, 0x0a, 0x58, 0x63, 0xa1,
- 0x87, 0xb6, 0x23, 0x04, 0x5f, 0x60, 0x15, 0x3a, 0xa1, 0xd7, 0xfb, 0x8d,
- 0x1b, 0x81, 0x69, 0xf8, 0x7e, 0xa3, 0xbc, 0x38, 0x53, 0xa8, 0x93, 0x09,
- 0xda, 0x07, 0xeb, 0xb0, 0x18, 0xf4, 0x53, 0xf4, 0x9b, 0x9c, 0x2f, 0xfd,
- 0xd4, 0x4f, 0x37, 0xf0, 0x0e, 0x57, 0xf9, 0x58, 0x6c, 0x03, 0xf7, 0x1b,
- 0x63, 0x36, 0x79, 0x7a, 0x59, 0xf6, 0x57, 0x58, 0xf6, 0x2a, 0xd6, 0x87,
- 0xe9, 0x0f, 0xdc, 0x7b, 0x63, 0x1c, 0x8f, 0xfd, 0x02, 0x37, 0xb5, 0x63,
- 0xae, 0xa5, 0x8f, 0x68, 0xcc, 0xdd, 0xa7, 0x70, 0xf4, 0xb5, 0x78, 0x99,
- 0x7c, 0x72, 0xc0, 0xa7, 0xcb, 0x6a, 0x3f, 0x70, 0x9d, 0x7d, 0xe2, 0x27,
- 0xa0, 0x57, 0x85, 0x2b, 0xc2, 0x3d, 0x4b, 0xee, 0xe7, 0x72, 0xaf, 0xb8,
- 0xde, 0x62, 0xa8, 0x7b, 0x03, 0x72, 0x0f, 0xec, 0xcb, 0xbd, 0xb0, 0x2f,
- 0xf7, 0x5d, 0x73, 0x07, 0xda, 0x3f, 0x03, 0xe8, 0x2a, 0x04, 0x8d, 0x0e,
- 0x19, 0xad, 0xd4, 0xb7, 0xe5, 0x3e, 0xee, 0x7a, 0xfb, 0xb6, 0xdc, 0xd3,
- 0x4d, 0xad, 0xd9, 0x0b, 0xa4, 0x6c, 0xb8, 0x72, 0xc9, 0xe1, 0xbe, 0x9b,
- 0x7f, 0x6f, 0x7e, 0x3d, 0xfc, 0x15, 0x68, 0xf6, 0xf7, 0x9c, 0x43, 0xe9,
- 0x2b, 0xc2, 0xfb, 0xf3, 0xc5, 0x29, 0xe2, 0x81, 0x98, 0xba, 0x17, 0x63,
- 0xa8, 0x7d, 0x3e, 0xaf, 0x6d, 0x71, 0x4a, 0x9d, 0x31, 0x15, 0xb8, 0x77,
- 0x6d, 0x6e, 0xb5, 0xcc, 0xd1, 0xa0, 0x77, 0x1f, 0x93, 0xba, 0xec, 0xd9,
- 0x32, 0xc8, 0x62, 0xb5, 0x76, 0xcf, 0x71, 0x50, 0xd9, 0x8b, 0x2b, 0xd0,
- 0x01, 0xae, 0x17, 0xe2, 0x05, 0xe8, 0xc9, 0x04, 0xec, 0x53, 0x5e, 0xf5,
- 0x17, 0xa1, 0x5c, 0x64, 0xb2, 0x41, 0x43, 0xc2, 0xc7, 0x19, 0x0b, 0x79,
- 0x7b, 0x2d, 0xb9, 0xa0, 0xa5, 0xec, 0x37, 0x68, 0x07, 0x3e, 0xa3, 0x7e,
- 0x26, 0xc6, 0x1b, 0xd3, 0x0d, 0xf0, 0xab, 0x58, 0xbf, 0x2a, 0xf7, 0x04,
- 0xa0, 0xbb, 0x8b, 0xdf, 0x91, 0x7d, 0xb3, 0xdd, 0xcd, 0x9e, 0xfc, 0x73,
- 0x1f, 0x99, 0xf3, 0xf3, 0x69, 0x58, 0xdd, 0xb7, 0x71, 0x5c, 0x22, 0x51,
- 0xf8, 0xb4, 0x0f, 0x20, 0xce, 0xd8, 0x01, 0x59, 0x59, 0x8a, 0xb1, 0x5f,
- 0x4f, 0x67, 0x26, 0x4b, 0xec, 0xfb, 0x3b, 0x32, 0x34, 0x5b, 0x6a, 0xa6,
- 0x2f, 0x59, 0x84, 0x1d, 0x58, 0x36, 0xe9, 0x43, 0xc7, 0xe0, 0xe3, 0xda,
- 0xe5, 0xfb, 0xb3, 0xf4, 0x8f, 0x49, 0xf3, 0x94, 0xf4, 0xc6, 0x4f, 0x81,
- 0xa6, 0xcf, 0x3b, 0x21, 0xc6, 0x68, 0xee, 0x20, 0xca, 0xfe, 0x5c, 0x92,
- 0x66, 0x67, 0x80, 0xcf, 0xbd, 0xe6, 0x17, 0x80, 0x61, 0x33, 0x66, 0xd2,
- 0xbc, 0x35, 0x40, 0x39, 0x42, 0xcc, 0xbd, 0x58, 0xa3, 0xf3, 0x07, 0xb3,
- 0x2a, 0x4e, 0x52, 0x76, 0x66, 0xd1, 0xe1, 0x78, 0xa0, 0x5b, 0xd9, 0xac,
- 0x5b, 0x61, 0x4f, 0x22, 0xfa, 0xfc, 0x0d, 0x6d, 0x88, 0x6d, 0x9c, 0x90,
- 0xce, 0x3f, 0x2a, 0xd9, 0x93, 0x31, 0xd8, 0x33, 0xf6, 0xe5, 0xc7, 0x0e,
- 0xf4, 0x91, 0x3e, 0xde, 0xa6, 0xbf, 0xbb, 0x03, 0x7e, 0xef, 0x66, 0x45,
- 0xcf, 0xb0, 0xd3, 0x27, 0x13, 0xc7, 0x38, 0x76, 0x0f, 0x6c, 0x79, 0x5c,
- 0xc9, 0x6d, 0xb1, 0xb4, 0x1c, 0x8f, 0xc0, 0x26, 0x47, 0xb6, 0x90, 0x9f,
- 0xef, 0x93, 0xbb, 0xec, 0x31, 0xb9, 0x1b, 0xb2, 0x33, 0x68, 0x3b, 0x32,
- 0x84, 0xb5, 0xd8, 0x61, 0xc3, 0xef, 0x28, 0x0c, 0xdd, 0x88, 0xb8, 0x8b,
- 0x63, 0xb7, 0xeb, 0xfb, 0x17, 0x1e, 0x7e, 0xfc, 0x4a, 0xd5, 0xe3, 0x51,
- 0x76, 0xf6, 0x49, 0xc5, 0x9b, 0x61, 0x67, 0x9b, 0xf6, 0xb3, 0x2d, 0x92,
- 0x53, 0xf5, 0xb6, 0x29, 0x7f, 0x5c, 0x5c, 0xb8, 0x1f, 0x29, 0x7c, 0xf3,
- 0x02, 0xec, 0x0d, 0x30, 0x77, 0xb1, 0xb2, 0x15, 0x79, 0xf8, 0xd0, 0x85,
- 0x34, 0xd2, 0xf7, 0x21, 0x65, 0xdd, 0x07, 0x9a, 0xbd, 0xbd, 0xdc, 0xb5,
- 0xf7, 0xb8, 0x24, 0xf0, 0x01, 0x85, 0x4b, 0xaf, 0xa8, 0x3b, 0x80, 0x88,
- 0xa1, 0x47, 0xb2, 0xb0, 0x2b, 0xcd, 0xc0, 0x40, 0x53, 0xc7, 0xad, 0xd4,
- 0x50, 0x60, 0xbb, 0x7c, 0x10, 0xb1, 0x7c, 0xd9, 0xe1, 0x5a, 0x6e, 0x95,
- 0x07, 0xdf, 0x4b, 0x19, 0xd9, 0x2e, 0x7b, 0xde, 0x1b, 0x90, 0x3d, 0x7d,
- 0x56, 0x86, 0x74, 0xdf, 0xf2, 0x2e, 0x3f, 0x9e, 0xee, 0x1a, 0x4e, 0x06,
- 0xfa, 0xe5, 0x0b, 0x90, 0xb1, 0x02, 0xe4, 0x6b, 0xa8, 0x4a, 0x9e, 0xd3,
- 0xde, 0xd3, 0xce, 0xa7, 0x80, 0x95, 0x7d, 0xec, 0x67, 0xcb, 0x54, 0xb5,
- 0x41, 0x12, 0x37, 0x70, 0x3f, 0x39, 0xe1, 0x9d, 0x71, 0xdc, 0x40, 0x99,
- 0x40, 0x0c, 0x72, 0x83, 0xa7, 0x9f, 0xea, 0xee, 0xdd, 0x0d, 0x9e, 0x5f,
- 0x41, 0xfc, 0xeb, 0x12, 0xe7, 0x79, 0x77, 0x0d, 0xbe, 0xa1, 0x6d, 0x69,
- 0x68, 0xe3, 0x0a, 0xbe, 0x6b, 0x61, 0xfc, 0xf0, 0x87, 0xcd, 0xb5, 0x6f,
- 0x07, 0xd6, 0xca, 0xa2, 0xbf, 0xef, 0x36, 0x87, 0x39, 0xd3, 0xa7, 0x5b,
- 0x26, 0x6d, 0x61, 0xab, 0xbd, 0x4b, 0xfe, 0x0c, 0xfe, 0xfd, 0x6b, 0x2b,
- 0xfe, 0x7d, 0x37, 0xf8, 0xb1, 0x16, 0x03, 0xd8, 0xe6, 0x3d, 0x98, 0xcb,
- 0x30, 0xd6, 0xf3, 0x6e, 0xfc, 0xee, 0x2a, 0xad, 0xda, 0xc7, 0x9b, 0x29,
- 0x00, 0x4f, 0x36, 0xd8, 0xec, 0x6f, 0xd5, 0x7e, 0x5e, 0x21, 0x2f, 0x2b,
- 0x7b, 0x85, 0x03, 0x57, 0x85, 0x7e, 0xef, 0x75, 0x09, 0x77, 0xdb, 0xaf,
- 0x77, 0x06, 0xec, 0xe7, 0x8d, 0x00, 0xcf, 0xc1, 0x1d, 0x39, 0x5d, 0x25,
- 0x0e, 0xbb, 0x28, 0xc6, 0x59, 0x62, 0xb0, 0x97, 0xd5, 0x1e, 0x54, 0xb9,
- 0xf4, 0x2d, 0xa4, 0xa8, 0x0f, 0xfb, 0x18, 0xf4, 0xf6, 0x29, 0x14, 0x56,
- 0xa1, 0x9d, 0xbd, 0x1b, 0xeb, 0x30, 0x81, 0x5f, 0xe7, 0x96, 0x5b, 0xa1,
- 0xbf, 0x94, 0x53, 0xee, 0x7d, 0x75, 0x9b, 0x5b, 0x02, 0x7c, 0xb7, 0xde,
- 0x3e, 0xd8, 0xb7, 0x25, 0x74, 0x14, 0xbe, 0xce, 0xa0, 0x7d, 0xe0, 0x3c,
- 0xe8, 0x27, 0x4d, 0x99, 0x3f, 0x46, 0x5d, 0x5f, 0xaf, 0xbe, 0x5f, 0xd7,
- 0x9f, 0x8b, 0xf2, 0x1b, 0x99, 0x3c, 0xf7, 0x38, 0x4b, 0x5c, 0x03, 0x07,
- 0x6b, 0xe0, 0xca, 0x71, 0xa7, 0x95, 0x36, 0x5d, 0x82, 0xc7, 0x5d, 0x19,
- 0x54, 0xd8, 0xb5, 0x17, 0x98, 0x6b, 0xa3, 0xc6, 0x0d, 0x31, 0x09, 0x1d,
- 0xef, 0x90, 0x46, 0xe0, 0xea, 0x86, 0x23, 0xf4, 0x91, 0xc9, 0xc4, 0x20,
- 0x84, 0x20, 0xa4, 0xee, 0x93, 0x5a, 0x03, 0xdf, 0x97, 0xde, 0xc4, 0xf7,
- 0x85, 0x78, 0xe9, 0x51, 0xac, 0x9f, 0xe5, 0x5c, 0x5c, 0xa7, 0x7e, 0xb1,
- 0x56, 0x1f, 0x72, 0xc4, 0xbd, 0x35, 0xb6, 0xe1, 0x5e, 0x5b, 0x72, 0xe0,
- 0x7b, 0xdc, 0x63, 0x43, 0xac, 0xd9, 0x70, 0xc6, 0xa3, 0xc1, 0x58, 0x6c,
- 0x93, 0xf2, 0x49, 0xea, 0x28, 0xf7, 0x59, 0x4c, 0x2f, 0x4e, 0x2d, 0x31,
- 0x5e, 0xe5, 0xfb, 0x84, 0x7e, 0xdf, 0xa9, 0xdf, 0x33, 0x1e, 0x2d, 0xb8,
- 0x0d, 0xe0, 0xe9, 0x0e, 0xd8, 0xcf, 0xfb, 0xb7, 0xda, 0x0a, 0x37, 0xdc,
- 0xbf, 0xb2, 0x66, 0x3b, 0xd5, 0xdd, 0xa2, 0x72, 0xe9, 0xa0, 0xd8, 0x5b,
- 0x96, 0x52, 0x21, 0x19, 0xc5, 0x5a, 0x30, 0x9f, 0x21, 0x3d, 0xa9, 0x43,
- 0xb2, 0x5f, 0xad, 0x4d, 0xf9, 0x98, 0x75, 0x38, 0x11, 0x98, 0x10, 0xa3,
- 0xcc, 0xe7, 0x4f, 0x23, 0x3d, 0x04, 0xbc, 0xe3, 0xed, 0x5d, 0x1a, 0xe5,
- 0xd5, 0xbc, 0x04, 0xc6, 0x30, 0x77, 0xac, 0xda, 0xc7, 0xaa, 0xed, 0x71,
- 0xf1, 0xfd, 0xa0, 0x7a, 0x9f, 0x5a, 0xb5, 0xcf, 0x95, 0x33, 0x88, 0x65,
- 0xfc, 0xf7, 0x5c, 0x0b, 0xae, 0x17, 0x7c, 0xf1, 0x31, 0x7f, 0xcf, 0xab,
- 0x45, 0xaf, 0x0b, 0xd7, 0x67, 0x4a, 0xce, 0x99, 0xd6, 0x30, 0xe5, 0xef,
- 0xb6, 0xad, 0x37, 0xc9, 0x78, 0x3b, 0xf7, 0xdb, 0xea, 0x69, 0x58, 0xbb,
- 0x8f, 0x56, 0x3f, 0xfe, 0xda, 0xfd, 0x37, 0x8e, 0xed, 0xed, 0xb1, 0x65,
- 0x57, 0xed, 0xb1, 0xd5, 0x8f, 0xc7, 0xb1, 0x36, 0x22, 0x7e, 0x2a, 0xb8,
- 0x31, 0x9b, 0x6b, 0xd4, 0x95, 0x98, 0x65, 0xfe, 0xcb, 0x06, 0xd6, 0x31,
- 0x06, 0x3f, 0xc2, 0xb5, 0xf4, 0xcf, 0x9e, 0xb9, 0xa6, 0xc9, 0xc4, 0x21,
- 0x6f, 0x3d, 0x07, 0xbc, 0x75, 0xf7, 0xd6, 0xff, 0xe2, 0xca, 0x3a, 0xd2,
- 0x3f, 0x70, 0x1d, 0xdb, 0x45, 0x60, 0x67, 0x8d, 0x23, 0x5c, 0x43, 0xa6,
- 0x5c, 0x43, 0xbe, 0xe3, 0x1a, 0x76, 0xea, 0x77, 0x5c, 0x3f, 0xe0, 0xb4,
- 0x2f, 0x02, 0x63, 0x38, 0x59, 0xf5, 0x1d, 0x54, 0x67, 0xb7, 0xaf, 0x8b,
- 0x29, 0x79, 0x66, 0x3e, 0x2a, 0x66, 0xda, 0x9b, 0xd7, 0xd8, 0xaa, 0xfd,
- 0x76, 0x9e, 0x5f, 0xf5, 0x11, 0x7b, 0xfa, 0xf3, 0x8a, 0x73, 0x5e, 0xfb,
- 0xe5, 0xb2, 0xe4, 0xa7, 0x42, 0x88, 0x01, 0x53, 0xc0, 0x39, 0x7d, 0xb0,
- 0xb7, 0xdc, 0x1f, 0x45, 0x59, 0x85, 0x78, 0x85, 0xbe, 0x2e, 0x05, 0x5d,
- 0xa1, 0x0d, 0x26, 0x1e, 0x79, 0x55, 0x72, 0x73, 0xbe, 0x8d, 0x41, 0xff,
- 0x86, 0xdf, 0x3f, 0xf9, 0x9c, 0xb9, 0x65, 0xb3, 0x2c, 0x25, 0x36, 0x8b,
- 0x95, 0x58, 0x90, 0xda, 0xba, 0x8e, 0xad, 0xcf, 0x77, 0xe7, 0xfe, 0x60,
- 0x4d, 0x36, 0xc6, 0xd6, 0x59, 0xfb, 0xbd, 0xe2, 0xbf, 0xf7, 0xd7, 0x7e,
- 0xdd, 0x75, 0x28, 0xbc, 0x22, 0x5c, 0x0b, 0xf2, 0x80, 0x78, 0x38, 0x2c,
- 0x9f, 0x8a, 0x51, 0x1f, 0x0b, 0xea, 0x7c, 0x33, 0x69, 0x74, 0x2b, 0x9b,
- 0x31, 0xe8, 0x78, 0xf2, 0x5a, 0xc0, 0x38, 0x91, 0xae, 0x7f, 0xe1, 0x0e,
- 0xc6, 0x10, 0xe7, 0x76, 0xd1, 0xbe, 0xf8, 0x3a, 0x1d, 0x55, 0x3a, 0xfd,
- 0x79, 0x27, 0x20, 0x45, 0x3b, 0x20, 0x13, 0xf6, 0x41, 0x85, 0xf1, 0x3f,
- 0x84, 0xbe, 0x1e, 0xd4, 0x7d, 0x4d, 0x48, 0xb7, 0xb6, 0x3f, 0x07, 0x20,
- 0xe7, 0xae, 0xdc, 0xe7, 0x6c, 0x95, 0xdb, 0x5a, 0xa9, 0x03, 0xfe, 0xfc,
- 0x0f, 0x4a, 0xd7, 0xd6, 0xa5, 0x04, 0x22, 0x83, 0x5b, 0xc2, 0x2b, 0x3c,
- 0xa0, 0x9e, 0xf9, 0xf2, 0xed, 0xf1, 0xc1, 0x9b, 0xff, 0xaa, 0xb9, 0xea,
- 0x79, 0x72, 0xce, 0xac, 0xc7, 0xb9, 0x7a, 0x58, 0xbe, 0x36, 0x57, 0xbf,
- 0x7e, 0x33, 0x64, 0xc9, 0x4a, 0x48, 0xa0, 0x9e, 0x37, 0x2b, 0x36, 0x6a,
- 0x98, 0x7b, 0x24, 0x4b, 0xa6, 0x95, 0x4a, 0x04, 0xfc, 0xbd, 0x68, 0x0f,
- 0xeb, 0x76, 0x02, 0x87, 0xdb, 0xdd, 0xdd, 0xa9, 0xbc, 0xda, 0x23, 0x35,
- 0xd4, 0xbc, 0x26, 0x80, 0xc9, 0xe6, 0x9d, 0x57, 0xdc, 0x4f, 0x02, 0xb3,
- 0x8e, 0xcb, 0xc3, 0x12, 0x5c, 0xb5, 0x97, 0x8b, 0xfc, 0x59, 0xee, 0xe7,
- 0x5a, 0x89, 0x0c, 0xd6, 0xf8, 0xc3, 0x88, 0xe1, 0xcb, 0xb0, 0xfb, 0x1f,
- 0xa1, 0x6f, 0x28, 0xc1, 0x5f, 0x00, 0x97, 0x7c, 0xed, 0xba, 0x18, 0x7e,
- 0xbc, 0x6e, 0x2f, 0xd7, 0xc3, 0xa7, 0xe7, 0x14, 0x26, 0x25, 0x6e, 0x3f,
- 0x1c, 0xb8, 0xa7, 0x27, 0x88, 0x38, 0xa3, 0xe0, 0x46, 0x6c, 0xe2, 0xb8,
- 0x83, 0x72, 0x17, 0xd6, 0xe7, 0xf4, 0x7c, 0x21, 0xb0, 0xa3, 0xe4, 0xcb,
- 0x2a, 0xe2, 0xca, 0xaa, 0x95, 0x5a, 0x06, 0x3f, 0x9e, 0xd4, 0x98, 0x8f,
- 0xe7, 0x35, 0x65, 0x1d, 0xb3, 0x70, 0x6f, 0xa8, 0x58, 0x3d, 0x28, 0x93,
- 0x0e, 0xf7, 0x76, 0xba, 0xa4, 0x18, 0xcb, 0xdc, 0xd4, 0xb8, 0xc2, 0x23,
- 0xcb, 0x44, 0xcc, 0x97, 0xa2, 0xfd, 0x2e, 0xeb, 0xf3, 0x8e, 0x27, 0x95,
- 0x7c, 0xf9, 0xfb, 0xc2, 0x8c, 0x8f, 0x78, 0x5e, 0xd5, 0x65, 0x0e, 0xf3,
- 0x79, 0x8e, 0x32, 0xa0, 0x62, 0x26, 0xf0, 0xf2, 0x21, 0xc9, 0x8c, 0x26,
- 0x14, 0x6e, 0x79, 0xbc, 0x44, 0x7d, 0x21, 0xfe, 0xbf, 0x0c, 0xec, 0x1f,
- 0xc2, 0x9a, 0x31, 0x0e, 0xe0, 0xd8, 0xd4, 0x0b, 0x94, 0x55, 0xcc, 0x5f,
- 0xa2, 0x17, 0xdb, 0x37, 0x11, 0x63, 0x5c, 0x28, 0x7d, 0x5c, 0xf1, 0x6f,
- 0x49, 0xfc, 0xbd, 0x73, 0x85, 0x05, 0x0b, 0xd9, 0x60, 0x40, 0x92, 0x47,
- 0x3f, 0x03, 0x19, 0x1a, 0x41, 0x8c, 0xc4, 0x7a, 0xa2, 0xce, 0xaf, 0x06,
- 0x81, 0xb9, 0x0c, 0xfb, 0x46, 0x29, 0x9a, 0x61, 0x29, 0xaa, 0x7b, 0x80,
- 0x3c, 0xcf, 0x0d, 0xaa, 0xbd, 0x9d, 0xa2, 0x49, 0xcc, 0x9f, 0xd9, 0xe4,
- 0xdf, 0x03, 0x2c, 0x9a, 0x6c, 0xc7, 0x3c, 0xcb, 0x27, 0x24, 0x7c, 0xf4,
- 0x80, 0x34, 0x1c, 0x7d, 0x58, 0x1a, 0xa7, 0x89, 0xf1, 0xb8, 0x77, 0x6f,
- 0xdc, 0xd1, 0x28, 0xc4, 0xdc, 0x5f, 0xc5, 0xd8, 0x07, 0xe5, 0x87, 0x8e,
- 0x4f, 0xd3, 0x86, 0x8d, 0xd2, 0xc2, 0x3a, 0x7e, 0xde, 0xc7, 0xe3, 0x77,
- 0x80, 0x1e, 0xce, 0x3f, 0xa1, 0x71, 0xdf, 0x1d, 0x75, 0xb1, 0x6b, 0x83,
- 0x8e, 0x5d, 0xd9, 0xee, 0x32, 0x7c, 0xf6, 0x31, 0x09, 0xdb, 0x7e, 0xfb,
- 0xed, 0xa8, 0x17, 0xaf, 0xbb, 0x03, 0xc1, 0x3a, 0xfa, 0x4e, 0x40, 0x0b,
- 0x71, 0x0f, 0xcf, 0xdb, 0x59, 0xe6, 0x9d, 0xf9, 0x1b, 0xe5, 0x74, 0x70,
- 0xf5, 0xf8, 0xdb, 0xea, 0xea, 0xfa, 0x65, 0x7e, 0x9b, 0xb0, 0x17, 0xf3,
- 0xf7, 0x87, 0xeb, 0xda, 0x7d, 0xd7, 0xf4, 0x52, 0x2f, 0xf6, 0xf0, 0xe2,
- 0x20, 0xce, 0x21, 0x55, 0x87, 0x73, 0x56, 0x7f, 0x2f, 0x9a, 0x43, 0x79,
- 0x7e, 0xd6, 0xbf, 0x3b, 0x64, 0x60, 0x2e, 0x56, 0x81, 0xf1, 0x8b, 0xc9,
- 0x6f, 0x33, 0x67, 0x0b, 0xa0, 0xfb, 0x66, 0x75, 0xef, 0x88, 0x77, 0x37,
- 0x50, 0x2f, 0xe1, 0xe1, 0x4f, 0xe6, 0xe3, 0x58, 0xf3, 0x77, 0x75, 0x18,
- 0xe9, 0xff, 0x7e, 0x53, 0xb6, 0x9f, 0xf8, 0x66, 0x13, 0xcf, 0x21, 0x81,
- 0x9b, 0x29, 0x67, 0xdf, 0x81, 0x9c, 0x35, 0xaa, 0x73, 0x9f, 0x62, 0x89,
- 0xf1, 0x5c, 0x1e, 0xf2, 0xc3, 0xfb, 0x7b, 0x8c, 0xfb, 0xf2, 0x7a, 0x3f,
- 0x96, 0x74, 0x12, 0xd3, 0xfb, 0xf1, 0x01, 0xfb, 0x5c, 0xef, 0x9e, 0xb2,
- 0x1f, 0xb3, 0x51, 0xde, 0xe2, 0x8a, 0xe6, 0xa1, 0x35, 0xf1, 0xca, 0x21,
- 0xd8, 0x82, 0x79, 0xc8, 0xf3, 0x5e, 0xd8, 0xc0, 0xc1, 0x20, 0xf5, 0x33,
- 0xaa, 0x63, 0x59, 0x9b, 0x71, 0x7b, 0x60, 0x14, 0x7d, 0x18, 0xd3, 0xaf,
- 0xc9, 0x04, 0xec, 0xff, 0x64, 0x35, 0xa9, 0xbe, 0xe9, 0xc9, 0xc4, 0x79,
- 0x9f, 0x8c, 0xe5, 0x5f, 0x83, 0xbc, 0xbe, 0x06, 0x3c, 0xbc, 0x01, 0xfc,
- 0x34, 0xf4, 0x5a, 0xfd, 0x96, 0xde, 0x8b, 0x8a, 0x70, 0x2f, 0x1e, 0x76,
- 0xb3, 0xe8, 0x61, 0xcd, 0xd8, 0x24, 0xd2, 0x7f, 0x1e, 0xf5, 0xe4, 0xf5,
- 0xdf, 0x6a, 0x79, 0x6b, 0x42, 0xf9, 0x63, 0x6a, 0x0f, 0xd2, 0x9b, 0x93,
- 0xa5, 0x63, 0x95, 0x30, 0x64, 0x8e, 0xf3, 0xfa, 0x53, 0xd4, 0xa3, 0xac,
- 0xf5, 0xe8, 0xb3, 0xd9, 0xa8, 0xb2, 0x8f, 0x39, 0xc8, 0x52, 0x5e, 0xc5,
- 0x11, 0xc0, 0xf7, 0x0e, 0xdb, 0x3d, 0xb7, 0x89, 0x67, 0x9f, 0x0d, 0xb6,
- 0x8a, 0x2d, 0xda, 0x83, 0xe2, 0x97, 0xdd, 0x89, 0x32, 0xca, 0xd9, 0x8d,
- 0x58, 0x1b, 0x96, 0x65, 0x91, 0xe7, 0x58, 0x37, 0xe9, 0x71, 0x38, 0x46,
- 0x77, 0xf3, 0x6a, 0x9a, 0x38, 0x97, 0xf6, 0x35, 0xdf, 0x35, 0xb0, 0xec,
- 0x46, 0x5d, 0x16, 0xd2, 0xf3, 0x1b, 0xd2, 0xdf, 0xd2, 0x5a, 0x87, 0x33,
- 0x2b, 0xd8, 0x98, 0xf4, 0x45, 0x54, 0xbb, 0x8c, 0xe9, 0xc9, 0xce, 0x21,
- 0xac, 0x47, 0x28, 0x1d, 0xe4, 0x99, 0x2c, 0xf8, 0xeb, 0xeb, 0x44, 0x5c,
- 0xc5, 0x9d, 0x09, 0xc3, 0xbb, 0xbb, 0x74, 0xee, 0x9a, 0xfb, 0xd9, 0xde,
- 0x5d, 0xf7, 0xa1, 0x9e, 0x26, 0x99, 0x9f, 0x89, 0xe8, 0x7b, 0x93, 0x71,
- 0xa5, 0xb3, 0xf9, 0x31, 0xe6, 0xff, 0xc7, 0x26, 0x7e, 0xc7, 0x6c, 0xd8,
- 0x2c, 0x6f, 0xd7, 0xfc, 0xbd, 0x51, 0xdd, 0x33, 0xa2, 0x2e, 0x14, 0xe7,
- 0xde, 0x50, 0xef, 0x4f, 0xcf, 0x36, 0xa8, 0xfa, 0xa7, 0x67, 0xd7, 0xde,
- 0x15, 0x62, 0xd9, 0xdb, 0xb8, 0xbf, 0x21, 0x0b, 0x53, 0x0d, 0xb2, 0x38,
- 0x1b, 0x60, 0xbc, 0x96, 0x6e, 0xac, 0x7d, 0x0b, 0xa3, 0xbf, 0x5b, 0x73,
- 0x65, 0x08, 0xeb, 0x37, 0x3f, 0x30, 0x29, 0xe5, 0x01, 0xc6, 0x23, 0xea,
- 0x3e, 0x20, 0x64, 0xa4, 0x01, 0x58, 0xb4, 0xe0, 0x96, 0x6d, 0xee, 0x03,
- 0xb7, 0x68, 0xbd, 0x7e, 0x45, 0xc7, 0x7c, 0xe4, 0x91, 0x21, 0xb9, 0xbe,
- 0x09, 0x45, 0x57, 0x59, 0xf1, 0xca, 0xff, 0xd6, 0x88, 0xfd, 0xf3, 0x7b,
- 0xa3, 0xa0, 0xc6, 0xb2, 0xfb, 0x35, 0xcf, 0xff, 0x4a, 0xa7, 0x8f, 0xca,
- 0x9e, 0x63, 0xbf, 0x0f, 0x5a, 0x9b, 0xbc, 0x3b, 0x4f, 0x52, 0xff, 0x3d,
- 0x49, 0x48, 0x7d, 0xcf, 0x12, 0xb2, 0x1f, 0x45, 0x19, 0xf7, 0xc1, 0x1e,
- 0x55, 0xf3, 0xe0, 0xbd, 0xba, 0x82, 0xfc, 0xaa, 0xfb, 0x21, 0x7e, 0x2c,
- 0xc6, 0xbb, 0x4b, 0x51, 0xdd, 0xdf, 0x0e, 0xbd, 0x8e, 0x63, 0xb2, 0x07,
- 0xbe, 0x26, 0x0f, 0x4c, 0xca, 0xfb, 0x5e, 0xe3, 0xc1, 0xfa, 0x31, 0x7d,
- 0x59, 0xf6, 0xe2, 0x7c, 0xff, 0xde, 0x41, 0x50, 0xc5, 0x23, 0x2b, 0x7b,
- 0x06, 0xba, 0x7c, 0x4c, 0xf6, 0x95, 0xd4, 0xde, 0x81, 0x3a, 0x2f, 0x9c,
- 0x84, 0x4e, 0x0e, 0x2a, 0x7f, 0x12, 0x09, 0x0c, 0x55, 0xd2, 0x92, 0x3f,
- 0xb9, 0x13, 0xe3, 0x70, 0x1f, 0x2e, 0xa3, 0xcf, 0xe5, 0x76, 0xcb, 0x9e,
- 0xaa, 0x37, 0xf6, 0xde, 0x12, 0xdf, 0x27, 0xe1, 0xa3, 0xf9, 0x3e, 0x17,
- 0x0f, 0xaa, 0x93, 0x85, 0x5b, 0xd1, 0xb6, 0x41, 0xf3, 0x96, 0xf7, 0xfc,
- 0xd9, 0x9e, 0xfa, 0xf7, 0x4f, 0x4c, 0x89, 0xe6, 0xf0, 0x9e, 0x6d, 0xfc,
- 0xfe, 0xf6, 0xc2, 0x67, 0x30, 0x36, 0x7e, 0x44, 0x96, 0xe6, 0x26, 0x65,
- 0x79, 0xce, 0x97, 0x33, 0xde, 0xb9, 0x26, 0xed, 0x77, 0xeb, 0x3b, 0xd7,
- 0x19, 0xac, 0xc3, 0x6a, 0x5e, 0xe5, 0x56, 0x7d, 0x8f, 0xf4, 0x75, 0xd3,
- 0xfb, 0x26, 0x70, 0xbb, 0xba, 0x3f, 0xb5, 0x5a, 0xde, 0xd9, 0xcf, 0x57,
- 0x4c, 0x9e, 0x33, 0x78, 0x77, 0xc0, 0xda, 0xeb, 0xde, 0xc7, 0xf4, 0xbd,
- 0xab, 0xaf, 0xe9, 0xbb, 0xfa, 0xe4, 0xe7, 0xa8, 0xa6, 0xf7, 0x56, 0xe8,
- 0x1e, 0xfb, 0x7c, 0x4c, 0xaf, 0x1b, 0xd2, 0x79, 0x3e, 0xab, 0xbb, 0xa6,
- 0xfa, 0xec, 0xd5, 0xd4, 0x63, 0xd4, 0xdf, 0x7b, 0x6b, 0xa8, 0x1b, 0x97,
- 0xed, 0xe9, 0x1b, 0xfc, 0x3b, 0xe0, 0x2c, 0x3b, 0xa6, 0xef, 0xd7, 0xf9,
- 0x77, 0xbe, 0x59, 0xe6, 0xdf, 0x03, 0x23, 0xbf, 0xb8, 0x9f, 0x88, 0xb4,
- 0x3a, 0xaa, 0x9f, 0x47, 0xeb, 0xbe, 0x1d, 0xf2, 0xfb, 0x0c, 0xa1, 0x8f,
- 0x3b, 0x83, 0xd7, 0xde, 0x11, 0xe7, 0xb7, 0x54, 0x94, 0x45, 0x83, 0xdf,
- 0x78, 0x33, 0x06, 0x03, 0x6e, 0xda, 0x28, 0x7b, 0x15, 0x3d, 0x05, 0x75,
- 0x57, 0x22, 0xeb, 0x34, 0xc9, 0xa0, 0xe9, 0xe5, 0xf7, 0xce, 0xaf, 0x95,
- 0x53, 0x96, 0x6f, 0x8a, 0x48, 0x94, 0xdf, 0x70, 0xf1, 0xfd, 0x7a, 0xdf,
- 0x2e, 0x84, 0xf5, 0xf7, 0x53, 0x0e, 0xda, 0x7c, 0x9e, 0xf2, 0x5e, 0x28,
- 0xac, 0xdc, 0xd1, 0x2c, 0xa8, 0x3d, 0x52, 0x00, 0x73, 0x7d, 0x57, 0x92,
- 0xdf, 0xb0, 0x8b, 0x3c, 0x5d, 0xe1, 0xb7, 0x5c, 0xdb, 0xd5, 0x1d, 0x16,
- 0xef, 0x5c, 0x90, 0x74, 0x75, 0x29, 0x9b, 0x5c, 0xae, 0x14, 0xc9, 0x53,
- 0xed, 0x57, 0xc3, 0xda, 0xaf, 0x92, 0xc7, 0xc3, 0xe0, 0xf1, 0x5f, 0xeb,
- 0x75, 0x61, 0xfb, 0x8c, 0xba, 0x0b, 0x9e, 0x89, 0xf1, 0x6c, 0xea, 0x31,
- 0x35, 0x17, 0xda, 0x68, 0xb4, 0x7d, 0x47, 0x50, 0xe9, 0xae, 0xfa, 0x46,
- 0x1e, 0xf2, 0xc9, 0x6f, 0xde, 0x61, 0x5f, 0x4b, 0xfc, 0xb6, 0x7d, 0x58,
- 0x7d, 0x67, 0x52, 0xae, 0x70, 0x5d, 0xf9, 0x4d, 0xfb, 0x68, 0x9d, 0x3c,
- 0x06, 0xf5, 0x58, 0x9b, 0x5a, 0x25, 0xea, 0xad, 0x3b, 0xbf, 0x51, 0x29,
- 0x57, 0xfc, 0xfb, 0x9d, 0x1b, 0x96, 0xa8, 0x13, 0xa2, 0x62, 0x6c, 0xef,
- 0x3b, 0x9b, 0xb2, 0xfa, 0x6e, 0x25, 0xc1, 0xef, 0x2e, 0xe1, 0x3b, 0x76,
- 0xe1, 0x99, 0x67, 0xba, 0xbb, 0x91, 0xc2, 0xe6, 0x54, 0xc6, 0x91, 0x3e,
- 0x2c, 0x39, 0xb5, 0xe7, 0xd6, 0x8c, 0xfc, 0x5e, 0x35, 0x76, 0xb1, 0xf2,
- 0x80, 0xec, 0x39, 0xf9, 0x10, 0xbf, 0xed, 0x51, 0xdf, 0xe5, 0x67, 0x1d,
- 0xd2, 0x18, 0x93, 0x09, 0x35, 0xef, 0x42, 0xed, 0x9b, 0x11, 0xc5, 0xfb,
- 0x5c, 0x2b, 0xd7, 0xb4, 0x50, 0x69, 0x06, 0x8d, 0x01, 0x7d, 0xc7, 0x93,
- 0x58, 0xdc, 0x9f, 0x7f, 0x94, 0xf7, 0x06, 0x5d, 0x9e, 0xdd, 0xed, 0x29,
- 0xf1, 0x0e, 0x67, 0x52, 0xc7, 0xe8, 0xdc, 0xb7, 0xe3, 0xd9, 0x00, 0x65,
- 0xdc, 0x4a, 0x8d, 0xc3, 0xfa, 0x87, 0x25, 0xce, 0x73, 0x65, 0x3d, 0x97,
- 0xe6, 0xba, 0xb9, 0xf0, 0xde, 0xaa, 0x37, 0x1f, 0x7e, 0x0b, 0x93, 0x2f,
- 0xd5, 0x7f, 0xc7, 0xa3, 0xbe, 0x11, 0x57, 0xdf, 0xcd, 0x8c, 0x57, 0x3e,
- 0x21, 0x1f, 0x2b, 0x6d, 0xd4, 0xdf, 0xf0, 0x44, 0xe4, 0x63, 0x95, 0xd7,
- 0x14, 0x4f, 0xf3, 0xea, 0xfb, 0xa3, 0xb0, 0x5e, 0xb3, 0x98, 0xea, 0xa3,
- 0xf6, 0x1d, 0x92, 0x55, 0xf7, 0x4d, 0x4a, 0x58, 0xc6, 0xe7, 0x7f, 0xd9,
- 0xb7, 0x48, 0x8f, 0x08, 0xbf, 0x47, 0xb9, 0xe4, 0x4c, 0xca, 0xe3, 0x73,
- 0xae, 0x7b, 0x97, 0x43, 0x5c, 0xb7, 0x41, 0x96, 0x63, 0xa3, 0x3b, 0xbe,
- 0x67, 0xb7, 0x05, 0xca, 0x33, 0x8d, 0xb0, 0xd7, 0xc4, 0x12, 0x12, 0x65,
- 0x7e, 0x7e, 0x86, 0x7a, 0x1a, 0xc2, 0x1c, 0x2d, 0xf3, 0xaa, 0x7c, 0xa6,
- 0x95, 0x7b, 0x5e, 0x77, 0x21, 0x8e, 0xfc, 0xb8, 0xe3, 0xd9, 0xe5, 0xcf,
- 0x2d, 0xec, 0x94, 0xcf, 0x55, 0x22, 0x81, 0xf2, 0x14, 0xef, 0xfa, 0x59,
- 0xc3, 0x73, 0x92, 0x44, 0x3d, 0xf6, 0x0f, 0x79, 0x89, 0x6f, 0x96, 0xa7,
- 0x8e, 0xfd, 0xc2, 0xbd, 0x6a, 0xe3, 0x3d, 0x6c, 0xcd, 0xb2, 0xe3, 0xef,
- 0xeb, 0x21, 0x86, 0x3f, 0xc2, 0x7a, 0x9b, 0x21, 0x07, 0xf0, 0xdb, 0xd0,
- 0x39, 0xc6, 0x98, 0x57, 0xb5, 0xdd, 0x32, 0x8e, 0xdc, 0x2c, 0x57, 0x57,
- 0xee, 0x0a, 0x5f, 0x86, 0x6c, 0x27, 0x3c, 0xfe, 0xab, 0x7d, 0xf0, 0x03,
- 0x12, 0xfc, 0x22, 0xfc, 0xc4, 0x17, 0x1b, 0x94, 0x6d, 0xa7, 0x3f, 0x43,
- 0xfc, 0x81, 0x18, 0x23, 0x84, 0x7e, 0x1e, 0x6c, 0xf5, 0x64, 0x76, 0x52,
- 0xe4, 0xcb, 0x4d, 0x92, 0x69, 0x65, 0x0c, 0x2b, 0xbf, 0xc2, 0x7e, 0xd5,
- 0xeb, 0x59, 0x4a, 0xbe, 0x42, 0x1d, 0xaf, 0x72, 0x2e, 0xc9, 0xf8, 0x8f,
- 0xe5, 0x93, 0x32, 0x1e, 0xe7, 0x5c, 0x1e, 0x91, 0xc2, 0xdc, 0x63, 0xf8,
- 0x71, 0x9e, 0xa4, 0xfb, 0x1f, 0xe8, 0x7b, 0x04, 0xa3, 0x52, 0x9c, 0x4a,
- 0xcb, 0xc4, 0xec, 0x5e, 0x7e, 0xa3, 0x3b, 0x7c, 0x97, 0x3a, 0x5f, 0xb3,
- 0xe2, 0xc9, 0x40, 0x6f, 0x62, 0x82, 0xf7, 0x26, 0xd4, 0x7c, 0xf6, 0x62,
- 0x3e, 0xdf, 0x6a, 0xe5, 0xdd, 0xf3, 0xab, 0xb0, 0xbf, 0xc6, 0x71, 0xca,
- 0xa1, 0x65, 0x76, 0x06, 0x98, 0xdf, 0x8d, 0xd8, 0x99, 0x65, 0xbb, 0x25,
- 0x78, 0x64, 0xc5, 0xce, 0xa3, 0x5c, 0x9f, 0xf3, 0xaa, 0xf6, 0xff, 0x11,
- 0x6d, 0x51, 0xef, 0x88, 0xdf, 0xd6, 0xaf, 0xc3, 0xb6, 0x9c, 0xe7, 0x4e,
- 0xc4, 0xec, 0x3e, 0x5d, 0x90, 0xc3, 0x78, 0x3d, 0xbf, 0xa3, 0x6b, 0xf8,
- 0x1d, 0x22, 0xde, 0x04, 0xbf, 0xc8, 0xe3, 0xa0, 0xe6, 0xf1, 0x9b, 0xe8,
- 0xdf, 0x5f, 0x83, 0xbb, 0x50, 0x66, 0xea, 0x6f, 0x03, 0xdf, 0x0a, 0xdf,
- 0xc9, 0x73, 0xd6, 0x7f, 0xb0, 0xd5, 0x93, 0x35, 0xd2, 0xb3, 0x1e, 0xcf,
- 0x3b, 0xdb, 0xbc, 0x75, 0xd9, 0x0d, 0x7e, 0xf1, 0x4e, 0x67, 0xaf, 0xfa,
- 0x4e, 0x20, 0x33, 0xb6, 0x1b, 0xb2, 0xe3, 0xcf, 0xab, 0x17, 0x32, 0xc6,
- 0x33, 0x0b, 0xd6, 0xaf, 0xe7, 0x89, 0xe7, 0xf7, 0x82, 0xdc, 0x77, 0xb0,
- 0x39, 0x57, 0x60, 0xc2, 0x2f, 0xab, 0xef, 0x82, 0x60, 0x27, 0xdf, 0xb6,
- 0xf2, 0x5d, 0xd0, 0xf5, 0xd7, 0x78, 0xa0, 0xcd, 0xf3, 0x51, 0x26, 0x78,
- 0xd2, 0xa2, 0xdb, 0xec, 0x06, 0x3e, 0xe5, 0x5e, 0x6c, 0x32, 0xfe, 0xa0,
- 0xf8, 0xe3, 0xb8, 0xdb, 0x19, 0x73, 0x0e, 0xf6, 0xf7, 0x22, 0xbe, 0x56,
- 0xf7, 0x65, 0xe2, 0xbc, 0x7f, 0x93, 0x0c, 0xec, 0x56, 0x77, 0x27, 0x2e,
- 0xac, 0xfa, 0xb6, 0x2b, 0x25, 0x4f, 0xd5, 0x64, 0x65, 0xf8, 0x27, 0x62,
- 0x49, 0xe2, 0x26, 0xca, 0x0a, 0xfb, 0xdd, 0xcb, 0x79, 0xc6, 0x1f, 0x52,
- 0xf3, 0x34, 0x11, 0xc3, 0xf1, 0x9e, 0x83, 0x19, 0x28, 0xcf, 0x72, 0xdd,
- 0x91, 0x2e, 0xf0, 0xd9, 0x3f, 0x6b, 0x55, 0x76, 0x05, 0xe3, 0xb2, 0x8c,
- 0xb6, 0x91, 0xef, 0xd3, 0xfa, 0x2c, 0xf6, 0xc3, 0x6d, 0xbc, 0x0f, 0x90,
- 0x47, 0xd9, 0xdc, 0xc2, 0xfa, 0xb4, 0x7d, 0x5c, 0xc9, 0xc1, 0x23, 0xe0,
- 0xfb, 0x1f, 0xa3, 0xee, 0x63, 0x48, 0x39, 0xc7, 0xf4, 0xca, 0xba, 0x93,
- 0xdf, 0x1f, 0x90, 0x01, 0xc8, 0x05, 0xf3, 0x8f, 0x48, 0x51, 0xdd, 0x63,
- 0x42, 0x3a, 0xc7, 0x67, 0xda, 0x7a, 0x5b, 0xfb, 0x53, 0xd2, 0xb2, 0x5b,
- 0x7f, 0x4f, 0xe6, 0xcb, 0xd3, 0x2e, 0xdd, 0x6e, 0x6c, 0x85, 0x57, 0x0f,
- 0x5d, 0x83, 0x37, 0xc2, 0x2b, 0x78, 0xc3, 0x1b, 0xeb, 0xf1, 0x36, 0x1f,
- 0x6b, 0x78, 0x73, 0xf0, 0xb0, 0x86, 0x27, 0xe7, 0x7b, 0x25, 0x04, 0x39,
- 0x0e, 0xd6, 0xe4, 0x18, 0xb8, 0xc7, 0xd3, 0x99, 0x09, 0x9e, 0x21, 0x2a,
- 0x3e, 0x53, 0x0e, 0x29, 0xbf, 0x5c, 0xc7, 0xfa, 0xb5, 0x7e, 0xcf, 0x2f,
- 0x59, 0xeb, 0x97, 0xdb, 0x7c, 0xfc, 0xf0, 0x77, 0xd3, 0x83, 0x0b, 0x6d,
- 0x35, 0x3d, 0xb8, 0xf9, 0x37, 0xa4, 0x07, 0x6b, 0xe5, 0xb2, 0x5e, 0xa6,
- 0x4c, 0xc8, 0x13, 0xd7, 0x8b, 0xf2, 0x44, 0x39, 0x22, 0x2f, 0x69, 0x4f,
- 0x1b, 0x19, 0x3b, 0xc5, 0xaf, 0xa8, 0xef, 0x36, 0x26, 0x61, 0x83, 0xda,
- 0x02, 0x73, 0x73, 0x31, 0x29, 0x2e, 0xbc, 0x4f, 0xc9, 0xf4, 0x53, 0x55,
- 0xda, 0xa5, 0xeb, 0xcd, 0x7d, 0xb5, 0xcd, 0xcd, 0xaf, 0xb1, 0xb9, 0xf9,
- 0x15, 0x9b, 0xdb, 0xaa, 0xe3, 0xa5, 0xbf, 0x8b, 0xcd, 0x8d, 0xd5, 0x9d,
- 0xcb, 0xf8, 0x67, 0x32, 0x12, 0xc8, 0xf6, 0x44, 0x65, 0x07, 0xfc, 0xc8,
- 0xf0, 0xd4, 0x4e, 0xf9, 0x97, 0x53, 0x93, 0xea, 0x8e, 0xd2, 0x5f, 0x38,
- 0xc9, 0xf8, 0x03, 0x01, 0x57, 0x3e, 0x80, 0x78, 0x77, 0xbc, 0xa3, 0x41,
- 0x76, 0xbc, 0x4b, 0x9d, 0x35, 0x9a, 0xd9, 0x40, 0xbb, 0x70, 0x17, 0x3c,
- 0xe7, 0x58, 0x4e, 0x22, 0xc0, 0xfb, 0x6a, 0x8d, 0x32, 0x1e, 0x6b, 0x96,
- 0x9d, 0xc0, 0x4e, 0x85, 0x1b, 0x1c, 0xf5, 0x2d, 0x79, 0x46, 0x9d, 0xe5,
- 0xdc, 0xb2, 0xd9, 0x1b, 0x17, 0x7c, 0x68, 0x31, 0xe5, 0xab, 0xd5, 0x5b,
- 0xd4, 0x77, 0xd1, 0x17, 0x4a, 0xd5, 0xd6, 0xd5, 0x79, 0x3e, 0xff, 0x7b,
- 0xd4, 0x89, 0x81, 0x57, 0xf5, 0x77, 0x7f, 0x82, 0x8a, 0x9f, 0xc5, 0xb9,
- 0x31, 0x75, 0xa7, 0xea, 0x4a, 0x90, 0xfc, 0x52, 0x71, 0x53, 0x3c, 0x1b,
- 0x04, 0xc6, 0x99, 0x01, 0x92, 0xb6, 0x19, 0xf3, 0x69, 0xfc, 0x09, 0xfb,
- 0xbf, 0x47, 0x9d, 0xed, 0x2e, 0x81, 0x37, 0xae, 0xda, 0xfb, 0xcd, 0xc7,
- 0x88, 0xeb, 0x6b, 0xf7, 0x87, 0xaf, 0xc5, 0xf7, 0xde, 0xb7, 0x67, 0xfa,
- 0x1c, 0x42, 0xef, 0x15, 0xe9, 0x18, 0x5c, 0x9d, 0xab, 0xad, 0xf7, 0x7f,
- 0x29, 0x88, 0xf5, 0xf8, 0x7f, 0x0f, 0x88, 0xed, 0xac, 0xc3, 0x73, 0xe2,
- 0xa8, 0x38, 0x30, 0x43, 0xfe, 0x96, 0xb1, 0x4e, 0xd3, 0x71, 0xdf, 0x9f,
- 0x07, 0x3a, 0xcf, 0xd6, 0xc7, 0x81, 0xec, 0x23, 0xa2, 0xee, 0x63, 0xd4,
- 0xfe, 0x0f, 0x0e, 0xf7, 0x77, 0x32, 0x81, 0x7b, 0x4a, 0x93, 0x12, 0x3c,
- 0x3a, 0x2a, 0xa1, 0x69, 0xee, 0xa5, 0x67, 0xa4, 0x18, 0x73, 0xe5, 0x63,
- 0xce, 0xea, 0xd8, 0xa4, 0xd3, 0x58, 0x4b, 0xfb, 0x23, 0x32, 0x78, 0xf2,
- 0x31, 0x09, 0x1f, 0xe5, 0xbb, 0x55, 0xe7, 0x28, 0xb0, 0x47, 0x1b, 0x64,
- 0x2e, 0xc6, 0xfd, 0xe4, 0xb0, 0x3a, 0x97, 0x5e, 0x1e, 0x7b, 0x2d, 0x5c,
- 0x04, 0x56, 0xc8, 0x2b, 0xdb, 0x82, 0x74, 0x25, 0x96, 0x38, 0xbc, 0x99,
- 0x3a, 0x85, 0x18, 0x33, 0x30, 0x3e, 0x17, 0x56, 0xf7, 0x83, 0x96, 0x63,
- 0xac, 0x8b, 0xf8, 0xfd, 0x28, 0x71, 0x06, 0x6c, 0xc7, 0xa8, 0x44, 0x99,
- 0x0f, 0x1e, 0xad, 0xe1, 0x0c, 0xda, 0x84, 0x41, 0x27, 0x26, 0xa1, 0x53,
- 0xde, 0xdc, 0xf9, 0x8f, 0x95, 0x8c, 0x13, 0x3b, 0x25, 0x38, 0xcd, 0xe7,
- 0xfa, 0x78, 0x88, 0xd8, 0x1d, 0xbe, 0xe1, 0xec, 0x67, 0xd1, 0x1f, 0xdf,
- 0x65, 0xf4, 0x37, 0xba, 0xc8, 0x97, 0xff, 0xb6, 0xff, 0x43, 0x81, 0xb2,
- 0xff, 0xff, 0x01, 0xe6, 0x8e, 0x9a, 0x21, 0xc0, 0x4e, 0x00, 0x00, 0x00 };
+ 0xcd, 0x7c, 0x0d, 0x70, 0x5c, 0xd7, 0x75, 0xde, 0xd9, 0xb7, 0xbb, 0xc0,
+ 0x12, 0x04, 0xc1, 0x07, 0x68, 0x05, 0xad, 0x24, 0x24, 0xde, 0x87, 0x7d,
+ 0x00, 0x56, 0x22, 0xe4, 0x3c, 0x32, 0x10, 0x0d, 0xb9, 0x5b, 0x72, 0xbd,
+ 0x0b, 0x50, 0x90, 0x43, 0x23, 0x90, 0x84, 0x28, 0x6a, 0x86, 0xe3, 0x41,
+ 0x97, 0xa0, 0x62, 0x69, 0xdc, 0x86, 0x1e, 0x2b, 0x29, 0xe5, 0x2a, 0xe6,
+ 0x6a, 0x01, 0xca, 0x94, 0x02, 0x72, 0x61, 0x12, 0x04, 0xd5, 0x54, 0x6d,
+ 0xd7, 0x0b, 0x80, 0x54, 0xd4, 0x25, 0x97, 0x94, 0xfc, 0xa3, 0x99, 0xd8,
+ 0x21, 0x4a, 0xd1, 0x92, 0xed, 0x71, 0xa7, 0x92, 0xc7, 0x9d, 0xaa, 0x33,
+ 0x9a, 0x94, 0xa5, 0xe4, 0xda, 0xf1, 0x34, 0x8d, 0x6a, 0x7b, 0x1a, 0x25,
+ 0xb1, 0xf3, 0xfa, 0x7d, 0xf7, 0xdd, 0x0b, 0x2c, 0x20, 0x48, 0x56, 0x92,
+ 0xf1, 0x4c, 0x30, 0xb3, 0xbc, 0xef, 0xde, 0x77, 0x7f, 0xcf, 0x39, 0xf7,
+ 0x9c, 0xef, 0x9c, 0x7b, 0x1f, 0x77, 0x89, 0xb4, 0x88, 0xfe, 0xdb, 0x82,
+ 0xdf, 0xc0, 0xbf, 0xf8, 0x9d, 0xfd, 0xdb, 0x3f, 0xb8, 0xf3, 0x83, 0x78,
+ 0xdc, 0x69, 0xd9, 0x4d, 0x11, 0x96, 0x87, 0xf1, 0x8b, 0xe3, 0xb7, 0x43,
+ 0x3f, 0x6f, 0xf4, 0x67, 0xb3, 0x41, 0x48, 0x64, 0xe2, 0x87, 0x22, 0xa1,
+ 0x75, 0xef, 0x62, 0xef, 0xd2, 0xe6, 0xbd, 0xfe, 0xac, 0xf7, 0x59, 0xcf,
+ 0xfe, 0x7b, 0xf4, 0x6d, 0xfe, 0xc2, 0xba, 0xf9, 0x16, 0xfd, 0x93, 0x98,
+ 0x95, 0xb9, 0xfa, 0xb1, 0x9c, 0x2b, 0xb1, 0x70, 0xe6, 0xbb, 0xa3, 0xfb,
+ 0x5d, 0x91, 0x6c, 0x6d, 0x5b, 0x32, 0x2f, 0x3f, 0xf3, 0x8b, 0xf1, 0x88,
+ 0xb0, 0xfc, 0x97, 0x32, 0x3f, 0x3d, 0xfc, 0xb5, 0x0f, 0x39, 0x6f, 0x55,
+ 0xc2, 0x12, 0xb3, 0x33, 0x6f, 0x8b, 0xdd, 0x2b, 0xb1, 0x2e, 0xb4, 0x79,
+ 0xba, 0xef, 0x59, 0x4b, 0xda, 0x4c, 0x5f, 0xf6, 0x44, 0x38, 0x23, 0x63,
+ 0x93, 0x33, 0x87, 0x7d, 0xcb, 0x95, 0xe2, 0x4d, 0x19, 0x37, 0x59, 0x92,
+ 0xd6, 0xc1, 0xe9, 0x81, 0x0f, 0x09, 0xf2, 0x63, 0x93, 0xb5, 0x98, 0xe4,
+ 0xea, 0xc5, 0x56, 0xcb, 0x75, 0x91, 0xc6, 0x8a, 0x37, 0x67, 0x24, 0xd6,
+ 0x94, 0x79, 0xba, 0xf9, 0x25, 0x97, 0xe3, 0x27, 0x46, 0x73, 0xee, 0xcd,
+ 0x12, 0x71, 0x7d, 0x7f, 0x1a, 0xe3, 0xef, 0xa9, 0xfd, 0xcc, 0x7f, 0x2c,
+ 0x12, 0x8c, 0x6d, 0x65, 0x8a, 0x61, 0xa6, 0xa1, 0x4c, 0x72, 0xb4, 0xbb,
+ 0xa6, 0xf2, 0x4d, 0x41, 0xde, 0x35, 0xf9, 0x2d, 0x41, 0x7e, 0x42, 0xe7,
+ 0xed, 0x96, 0x60, 0x2d, 0xb1, 0x4d, 0x58, 0x4b, 0x2c, 0x92, 0x19, 0xda,
+ 0x84, 0x3e, 0x63, 0xd1, 0x8c, 0x9b, 0x59, 0x52, 0xf5, 0x3e, 0xa1, 0xeb,
+ 0x1d, 0x8c, 0x06, 0xed, 0x26, 0x47, 0x7b, 0x6b, 0x4c, 0x1f, 0x1e, 0xed,
+ 0x51, 0xe9, 0xa3, 0xa3, 0x29, 0x95, 0x16, 0x55, 0xbd, 0x50, 0x66, 0x7a,
+ 0xd4, 0x55, 0x69, 0x97, 0x2e, 0x4f, 0x8f, 0x26, 0x55, 0xda, 0xaf, 0x53,
+ 0x4f, 0xa7, 0x03, 0x3a, 0x1d, 0xd4, 0x69, 0x46, 0xa7, 0x59, 0x9d, 0x0e,
+ 0xe9, 0x7e, 0x46, 0x74, 0x7e, 0xaf, 0x4e, 0xc7, 0x74, 0x3a, 0xae, 0xd3,
+ 0xfb, 0x75, 0xba, 0x4f, 0xcf, 0xeb, 0x93, 0x3a, 0x7f, 0x50, 0xcf, 0xef,
+ 0x10, 0xe6, 0xf1, 0x93, 0x26, 0x2d, 0xbf, 0x58, 0x67, 0x52, 0xf6, 0xcf,
+ 0xc4, 0xa4, 0x54, 0x0e, 0x4b, 0x5e, 0xf1, 0xb5, 0x3f, 0x2a, 0x2d, 0x31,
+ 0x99, 0xaa, 0xc7, 0xe4, 0xaa, 0x12, 0xdb, 0x1f, 0xf8, 0x5f, 0xeb, 0xb3,
+ 0xe5, 0x42, 0x3d, 0x2e, 0x97, 0xea, 0x12, 0x1a, 0xeb, 0xdb, 0x24, 0xd6,
+ 0x89, 0x9b, 0x24, 0x6b, 0x87, 0x24, 0xac, 0xe8, 0x9b, 0x94, 0xdc, 0x4c,
+ 0x27, 0xf2, 0x4e, 0x42, 0x64, 0x32, 0x1a, 0xf0, 0x33, 0x26, 0xe1, 0x79,
+ 0xf2, 0x67, 0x7e, 0xf4, 0xa5, 0xb9, 0x84, 0x44, 0x8e, 0x27, 0xd1, 0x7f,
+ 0xab, 0x44, 0xe7, 0xa5, 0x2b, 0x2c, 0x3d, 0x89, 0x07, 0x50, 0x63, 0xa8,
+ 0x16, 0x91, 0xe1, 0x5a, 0x08, 0x3c, 0x8b, 0x41, 0x5e, 0x5a, 0xf1, 0xb3,
+ 0xf1, 0x8b, 0xe3, 0x97, 0xc0, 0xef, 0x09, 0xf4, 0xd3, 0x25, 0xf9, 0x1a,
+ 0xfb, 0xc4, 0xb8, 0x65, 0x8c, 0x5f, 0x76, 0xec, 0x09, 0xe1, 0x9c, 0x12,
+ 0xf2, 0xb5, 0xbe, 0x60, 0x4e, 0x97, 0xea, 0xb1, 0x50, 0xee, 0xb4, 0x1c,
+ 0xcc, 0x7b, 0x92, 0xb4, 0xdc, 0x16, 0x29, 0xd8, 0xa1, 0xe4, 0x64, 0xba,
+ 0x43, 0x8a, 0xe3, 0x78, 0x57, 0x96, 0xac, 0x85, 0xbe, 0x0b, 0xb6, 0x4c,
+ 0x04, 0xef, 0x58, 0xf6, 0x37, 0xd8, 0xb7, 0x8e, 0x4d, 0x01, 0xbe, 0x54,
+ 0xfe, 0x63, 0x3c, 0xb3, 0xaf, 0xff, 0x17, 0x0e, 0xe6, 0xfc, 0xd7, 0xc8,
+ 0xb3, 0xfc, 0xcb, 0x5b, 0x83, 0x3c, 0x9f, 0x59, 0xd7, 0x8c, 0x69, 0xd6,
+ 0xca, 0xb1, 0xfb, 0xb0, 0x5e, 0x8e, 0xbf, 0xb2, 0x5e, 0xcc, 0xa3, 0x35,
+ 0x94, 0x3f, 0x9d, 0x94, 0x23, 0xe5, 0x5d, 0x92, 0xf3, 0x7c, 0x7f, 0xbf,
+ 0x27, 0x71, 0x4b, 0x7a, 0xec, 0x3c, 0xde, 0x56, 0x6b, 0x12, 0xca, 0x95,
+ 0x0d, 0x3d, 0xd8, 0x6f, 0x04, 0x65, 0x9d, 0xa8, 0xdf, 0x16, 0x1a, 0x3a,
+ 0x8d, 0xb9, 0x67, 0x48, 0x17, 0xc8, 0xae, 0xd7, 0x93, 0x98, 0xc4, 0x78,
+ 0x0b, 0xb5, 0x1e, 0xef, 0xb2, 0xd8, 0xe8, 0xb3, 0x03, 0x75, 0x48, 0x23,
+ 0xf6, 0xc5, 0x3e, 0xd9, 0x5f, 0x2b, 0xda, 0xc6, 0xf1, 0x8e, 0x73, 0xf2,
+ 0xfd, 0x9c, 0x67, 0x33, 0x2f, 0x15, 0xd0, 0xad, 0x42, 0xba, 0xb5, 0x74,
+ 0xc9, 0x99, 0x1a, 0xc7, 0xd8, 0x68, 0xde, 0xb7, 0xfe, 0x23, 0x9b, 0x77,
+ 0x02, 0xfd, 0xc7, 0x91, 0x6e, 0x0e, 0xe5, 0x4e, 0xfa, 0x18, 0x3f, 0x81,
+ 0xe7, 0x8d, 0xd6, 0x70, 0x55, 0xcb, 0x60, 0x02, 0x73, 0x8f, 0xcb, 0x45,
+ 0x25, 0x87, 0x9b, 0x25, 0x0c, 0x39, 0x24, 0x8f, 0xdb, 0xe7, 0x6f, 0x97,
+ 0x42, 0xdc, 0x49, 0x52, 0x87, 0x76, 0xef, 0xd8, 0x84, 0x35, 0x6a, 0x6d,
+ 0x78, 0x3c, 0x0e, 0x39, 0xbc, 0xdc, 0x6e, 0xa1, 0xc4, 0x12, 0xc7, 0xfe,
+ 0x2d, 0x29, 0x4a, 0x7e, 0xf1, 0x91, 0x90, 0xb4, 0x58, 0xa8, 0xb7, 0x2d,
+ 0x14, 0xd0, 0x80, 0xf4, 0xc9, 0x82, 0x3e, 0x21, 0x09, 0xf6, 0x73, 0x56,
+ 0xba, 0x6b, 0xea, 0x7d, 0xd2, 0x52, 0xef, 0x86, 0xf0, 0x2e, 0x22, 0xa9,
+ 0x1d, 0xe6, 0xfd, 0x10, 0xde, 0xdf, 0x24, 0x13, 0x36, 0xe6, 0x52, 0x7e,
+ 0xc1, 0xca, 0x61, 0x8e, 0x1f, 0x89, 0xa8, 0xb5, 0xa2, 0xee, 0x44, 0x43,
+ 0x3f, 0x13, 0xa8, 0xf7, 0x34, 0xc6, 0xc2, 0x7c, 0xcb, 0x49, 0xcc, 0xa5,
+ 0x13, 0x73, 0xe1, 0x1c, 0x8b, 0x56, 0xae, 0x1e, 0x41, 0x7e, 0xda, 0xca,
+ 0x9f, 0x3d, 0x8a, 0x67, 0xb1, 0xad, 0xcc, 0x0b, 0x4c, 0xd1, 0x7e, 0x5f,
+ 0x43, 0xfb, 0x7d, 0x68, 0xcf, 0x31, 0xd8, 0x3e, 0x90, 0xff, 0xa2, 0x92,
+ 0xc5, 0xe4, 0x7b, 0xd0, 0x23, 0xfc, 0xf7, 0xa0, 0xc7, 0xd7, 0x34, 0x3d,
+ 0x7e, 0x26, 0xbf, 0x78, 0x7a, 0x5c, 0xfd, 0x05, 0xd1, 0x43, 0xa4, 0x70,
+ 0x92, 0xcf, 0x11, 0x29, 0x2a, 0xbd, 0xc5, 0x7d, 0x4b, 0x79, 0xa7, 0xce,
+ 0x22, 0x9d, 0x28, 0xc7, 0xd8, 0x03, 0xf5, 0x08, 0xd2, 0x67, 0x90, 0x6e,
+ 0x0e, 0x8d, 0x9d, 0x7c, 0x13, 0xfc, 0xf7, 0xc5, 0xde, 0x61, 0xec, 0x47,
+ 0x31, 0x61, 0x4b, 0x97, 0xd8, 0x1f, 0x84, 0xf1, 0xee, 0x74, 0xec, 0x82,
+ 0x7c, 0x9f, 0xef, 0x43, 0xc6, 0xce, 0xe7, 0x66, 0x36, 0xbd, 0x9d, 0x55,
+ 0x4f, 0x51, 0xd2, 0x33, 0x6b, 0x65, 0x22, 0xa1, 0x7c, 0x39, 0x39, 0x61,
+ 0x65, 0xe2, 0xd0, 0x53, 0xcc, 0x0f, 0x86, 0x82, 0x39, 0x0f, 0xa0, 0xae,
+ 0xd1, 0x59, 0x66, 0xee, 0x03, 0x98, 0xfb, 0x7a, 0xdd, 0x95, 0xc5, 0x5c,
+ 0x38, 0x07, 0xce, 0xab, 0xa8, 0x75, 0x10, 0xfb, 0x39, 0xa4, 0xfa, 0x09,
+ 0x67, 0x06, 0x85, 0xb6, 0xb4, 0x30, 0xc3, 0x7d, 0xc0, 0x76, 0xec, 0x2b,
+ 0xd0, 0xc9, 0x85, 0x9a, 0xe9, 0xa3, 0xd8, 0xd8, 0x07, 0xe6, 0x23, 0x5b,
+ 0x2d, 0x37, 0x0a, 0xde, 0xb3, 0xab, 0xa3, 0x78, 0xf7, 0xb4, 0xe4, 0xce,
+ 0xde, 0x61, 0x61, 0x0d, 0xe8, 0x97, 0x34, 0x1a, 0x83, 0xce, 0xe6, 0x3e,
+ 0x8b, 0x49, 0x3e, 0xce, 0xb2, 0x49, 0x3d, 0x6e, 0x44, 0xb2, 0x2a, 0x9f,
+ 0x6b, 0x5b, 0x9d, 0xc7, 0x0b, 0x7a, 0x3d, 0x19, 0xac, 0x87, 0x73, 0x30,
+ 0x6b, 0xc9, 0x34, 0xac, 0xc5, 0xd0, 0x9a, 0xb4, 0xb0, 0xa1, 0xe3, 0x63,
+ 0xda, 0x86, 0xb0, 0xdd, 0x74, 0x03, 0xef, 0xa6, 0xd1, 0x86, 0xb4, 0x47,
+ 0x9d, 0x75, 0x76, 0x85, 0x36, 0x65, 0x08, 0xfd, 0x94, 0xe6, 0x2c, 0xc9,
+ 0x7b, 0xb0, 0xd9, 0xde, 0xcd, 0x5a, 0x5e, 0x57, 0x65, 0x29, 0xba, 0xa1,
+ 0x2c, 0x3d, 0x66, 0x05, 0xfa, 0x1a, 0xb6, 0x05, 0xf6, 0x67, 0x6a, 0xce,
+ 0x49, 0x1b, 0x59, 0x2a, 0xcd, 0xbc, 0x1f, 0x59, 0x32, 0xed, 0x63, 0x90,
+ 0x5d, 0x33, 0xc6, 0xfa, 0x39, 0x9b, 0x3a, 0x98, 0x63, 0x79, 0x48, 0x63,
+ 0x15, 0x8e, 0x13, 0xd8, 0x86, 0xca, 0x1a, 0xdb, 0x70, 0x14, 0x6d, 0x25,
+ 0x94, 0xef, 0x6b, 0x95, 0x03, 0x73, 0xa6, 0x8f, 0xa3, 0x4a, 0x66, 0x27,
+ 0x67, 0x1c, 0x7b, 0x38, 0x2c, 0xd9, 0xe1, 0xd9, 0x41, 0x19, 0xaa, 0x77,
+ 0x81, 0xa7, 0x6f, 0xfb, 0xb0, 0x9d, 0x1f, 0x8c, 0x8a, 0x0b, 0xbd, 0x88,
+ 0x35, 0x0f, 0x80, 0xc6, 0xf5, 0xa8, 0x58, 0x19, 0x0f, 0x69, 0x23, 0xd6,
+ 0x8a, 0x44, 0x86, 0xd7, 0xe4, 0x9b, 0x50, 0x07, 0x7d, 0x0f, 0xac, 0xaf,
+ 0x07, 0xf9, 0x04, 0x6d, 0x73, 0xde, 0xcf, 0x7c, 0xd8, 0x61, 0x6d, 0xb3,
+ 0x58, 0x4a, 0x3d, 0x61, 0x74, 0xc4, 0x6f, 0x60, 0x7f, 0xab, 0xbd, 0x50,
+ 0x04, 0x76, 0x41, 0x1f, 0xa2, 0xe4, 0xb4, 0x54, 0x7f, 0xce, 0xec, 0x7b,
+ 0x55, 0xbe, 0x67, 0x80, 0xb2, 0x57, 0x01, 0x26, 0xe0, 0x9a, 0x16, 0xd5,
+ 0x5e, 0xcf, 0xdb, 0x71, 0x99, 0x2e, 0x73, 0x3d, 0x8b, 0x92, 0xaa, 0xfd,
+ 0x7b, 0xc9, 0x9f, 0x15, 0xf9, 0xd6, 0x0c, 0xeb, 0x7d, 0x55, 0xd7, 0x7b,
+ 0x01, 0xf5, 0x52, 0xc9, 0xa1, 0x90, 0x03, 0x3b, 0xe0, 0x60, 0x9b, 0x6c,
+ 0x4b, 0x22, 0xb5, 0x47, 0xf0, 0x1b, 0xa2, 0x91, 0x41, 0xbd, 0x00, 0xfb,
+ 0xbc, 0x00, 0x7a, 0x88, 0xdc, 0x5d, 0x6e, 0x86, 0x3e, 0xf9, 0x9f, 0x98,
+ 0x6b, 0x5c, 0x9e, 0xc4, 0x3a, 0x5e, 0x9a, 0x21, 0xbe, 0xfa, 0xaa, 0x2c,
+ 0xcd, 0x10, 0x6f, 0xbd, 0x20, 0xd3, 0x33, 0x29, 0xef, 0x5b, 0xa0, 0xf3,
+ 0x19, 0xe1, 0x5a, 0xb6, 0x79, 0x48, 0x81, 0x05, 0x9d, 0xe4, 0xe3, 0xd0,
+ 0x67, 0x7d, 0x3b, 0x82, 0xfe, 0x7a, 0x74, 0x7f, 0x6e, 0xcd, 0x91, 0xab,
+ 0x36, 0xf5, 0xd3, 0x3b, 0xf7, 0x78, 0x4e, 0xef, 0xf1, 0x31, 0xaf, 0x4b,
+ 0x2c, 0xec, 0xeb, 0xec, 0x78, 0x11, 0xd6, 0x8f, 0xfb, 0xfa, 0x6d, 0x6b,
+ 0x15, 0xff, 0x24, 0x80, 0x59, 0x1d, 0x65, 0xef, 0xfe, 0x6e, 0x7b, 0xbc,
+ 0x71, 0x6f, 0x73, 0xfc, 0x36, 0xb4, 0x89, 0x20, 0x7d, 0xef, 0x7d, 0x8d,
+ 0x3e, 0x1a, 0xda, 0x0e, 0x72, 0x5f, 0xa0, 0xcd, 0xbf, 0x05, 0x2d, 0x48,
+ 0xff, 0xf7, 0xb3, 0x9f, 0x6f, 0x0b, 0xbf, 0xaf, 0xfd, 0x3c, 0xfe, 0x5e,
+ 0xfb, 0xb9, 0x71, 0x2f, 0x5f, 0x20, 0x2d, 0x30, 0xb6, 0xcc, 0x06, 0xb2,
+ 0xd5, 0x03, 0x5a, 0x27, 0x21, 0xa7, 0x98, 0x43, 0xf9, 0x6f, 0xfd, 0x6c,
+ 0x24, 0xc0, 0x73, 0x81, 0x3c, 0xb1, 0x9e, 0xa9, 0x13, 0xe8, 0xde, 0xa1,
+ 0xfa, 0x55, 0xa5, 0x67, 0x2f, 0x2a, 0x3d, 0xeb, 0x1c, 0x2d, 0x0a, 0xe5,
+ 0xed, 0xf6, 0x30, 0xe9, 0x7e, 0xc1, 0xfb, 0x7d, 0xcc, 0xd1, 0x49, 0x26,
+ 0xad, 0x9e, 0xa2, 0x65, 0xfd, 0xbe, 0x1c, 0x5c, 0x78, 0x58, 0x0e, 0x96,
+ 0xd9, 0xc7, 0x2e, 0xbc, 0x77, 0x51, 0xb6, 0x09, 0xba, 0x96, 0x3a, 0xfd,
+ 0xed, 0x50, 0x30, 0x96, 0x05, 0xfb, 0xb5, 0x1c, 0xba, 0xbb, 0x7e, 0x25,
+ 0x94, 0x5b, 0xe0, 0xde, 0x45, 0x79, 0xbd, 0x51, 0xe7, 0x1b, 0x7d, 0xff,
+ 0x0a, 0xc6, 0x34, 0x72, 0xee, 0x35, 0xe8, 0xd4, 0x69, 0xe2, 0x41, 0x2b,
+ 0xe7, 0x91, 0x7f, 0xb4, 0x2d, 0x8f, 0xd8, 0xc1, 0xfa, 0x0f, 0x81, 0x66,
+ 0xb4, 0x49, 0xa4, 0x21, 0xec, 0x61, 0x84, 0xfb, 0x97, 0xcf, 0xe2, 0x87,
+ 0x33, 0xdc, 0x83, 0x12, 0x09, 0x67, 0x80, 0x7f, 0xe3, 0xac, 0xb3, 0x0b,
+ 0x73, 0x0e, 0xf6, 0x77, 0x71, 0x65, 0x7f, 0x77, 0xcb, 0xc4, 0x42, 0x16,
+ 0x3a, 0x20, 0xaf, 0xfa, 0x89, 0xba, 0x6b, 0x6c, 0x0b, 0xea, 0x27, 0x35,
+ 0x1f, 0x36, 0x1b, 0xfd, 0x87, 0x32, 0x4f, 0x97, 0x35, 0x35, 0x94, 0x19,
+ 0x7e, 0x15, 0x30, 0x16, 0x6d, 0xc4, 0x88, 0xc6, 0x3d, 0xbe, 0x9f, 0x27,
+ 0x9f, 0xfb, 0xf7, 0x09, 0xf7, 0xc4, 0xa5, 0x72, 0xd1, 0x0e, 0x2b, 0xd9,
+ 0x5c, 0xfc, 0xd8, 0xaa, 0x6c, 0x02, 0x27, 0xab, 0x5e, 0x48, 0x5b, 0xce,
+ 0xa5, 0x15, 0xb4, 0x1c, 0xc2, 0x1a, 0x40, 0xb3, 0xce, 0x10, 0xe8, 0xd6,
+ 0x2a, 0x85, 0xfa, 0x2e, 0xfd, 0x8e, 0xe5, 0x11, 0x19, 0x8b, 0x1b, 0x3b,
+ 0xf4, 0xe7, 0x5b, 0x03, 0xac, 0x8b, 0x3a, 0xe5, 0xff, 0x1d, 0x0e, 0x64,
+ 0xdf, 0x96, 0xc2, 0xe9, 0x21, 0xc8, 0x18, 0xb1, 0xd8, 0x26, 0x2d, 0x63,
+ 0xec, 0x07, 0xe5, 0x67, 0x29, 0xc3, 0xa2, 0xf5, 0xe7, 0x20, 0xd2, 0x1f,
+ 0x87, 0x69, 0xb7, 0xd9, 0x57, 0xe1, 0xb4, 0x69, 0x6f, 0xe6, 0xd1, 0xb1,
+ 0xd2, 0xcf, 0x98, 0x67, 0x49, 0x58, 0xcd, 0x05, 0x65, 0x67, 0xd7, 0xce,
+ 0xc5, 0xea, 0x34, 0x73, 0x79, 0x34, 0x1c, 0xcc, 0xa5, 0xa3, 0xa1, 0xaf,
+ 0x78, 0xc3, 0x5c, 0x9a, 0x30, 0x97, 0xb8, 0xb2, 0x37, 0x9c, 0xcb, 0x05,
+ 0xf0, 0xbe, 0x70, 0xf6, 0xc6, 0xeb, 0x82, 0x36, 0xf1, 0x86, 0x36, 0x9d,
+ 0xeb, 0xda, 0xb0, 0xbe, 0x19, 0x03, 0xef, 0xce, 0x5e, 0xdd, 0x1c, 0xb4,
+ 0x61, 0xbd, 0x26, 0xd8, 0x37, 0xbe, 0x53, 0x7e, 0x5b, 0x83, 0xfc, 0x1f,
+ 0x84, 0xfc, 0x1b, 0xb9, 0x32, 0xb6, 0xd9, 0xf0, 0x75, 0x53, 0x28, 0x7f,
+ 0xf2, 0x03, 0xf4, 0x3d, 0x43, 0x63, 0xe5, 0x25, 0xf8, 0x0f, 0x49, 0x29,
+ 0xa4, 0xe1, 0x9b, 0xd8, 0x83, 0xa2, 0xfc, 0x89, 0x34, 0x7c, 0x16, 0x7b,
+ 0xb3, 0xc2, 0x5b, 0x85, 0x74, 0xbf, 0xb6, 0x59, 0xdf, 0x97, 0x09, 0xc8,
+ 0x70, 0x21, 0x9d, 0xc6, 0x78, 0xd0, 0xd5, 0x6e, 0x2f, 0xda, 0x71, 0xdc,
+ 0xb7, 0x22, 0xb4, 0x23, 0x17, 0xca, 0x1f, 0x47, 0x7e, 0x33, 0xde, 0xff,
+ 0xa9, 0x9e, 0x4f, 0x1b, 0xea, 0x7c, 0x5a, 0xf9, 0x26, 0x17, 0x54, 0x1d,
+ 0xf6, 0x71, 0x19, 0xf9, 0x3b, 0x50, 0x07, 0x9b, 0x1c, 0x12, 0x68, 0xb9,
+ 0x3b, 0xf1, 0xfb, 0x36, 0xca, 0x3e, 0x84, 0xb2, 0x2f, 0xa3, 0xec, 0x76,
+ 0xe4, 0x5f, 0x5c, 0xd7, 0xef, 0x36, 0xe4, 0x1f, 0xc3, 0x7b, 0xac, 0xd3,
+ 0xfe, 0x06, 0xde, 0xdf, 0x81, 0xdf, 0x97, 0xd7, 0xd5, 0xf9, 0x37, 0xeb,
+ 0xf2, 0xc6, 0x2f, 0xf8, 0x63, 0x2d, 0x73, 0xc6, 0x27, 0x08, 0xf4, 0xe8,
+ 0x54, 0xb9, 0x35, 0x34, 0x7c, 0x3a, 0x16, 0xda, 0x73, 0x9a, 0x78, 0x23,
+ 0xa2, 0xfc, 0x80, 0x08, 0xfc, 0x80, 0xe9, 0x39, 0x3a, 0x88, 0x11, 0x94,
+ 0x11, 0xbb, 0xcb, 0x40, 0x93, 0xf4, 0x78, 0x57, 0xb0, 0x4f, 0x0a, 0xb5,
+ 0x2e, 0xe4, 0xb9, 0x7f, 0x20, 0x63, 0xb5, 0x16, 0xc8, 0x75, 0x4f, 0xba,
+ 0x0a, 0x19, 0x3b, 0x00, 0xdf, 0x64, 0x02, 0x36, 0x70, 0xa2, 0xd6, 0x25,
+ 0x0f, 0xd4, 0xae, 0x44, 0x02, 0x39, 0x32, 0x63, 0x3f, 0xbd, 0x6e, 0xec,
+ 0x18, 0xfd, 0x0a, 0xc8, 0xfd, 0xfc, 0xe8, 0xfe, 0x39, 0x8e, 0x6f, 0x75,
+ 0x47, 0xa4, 0x0d, 0x73, 0xa0, 0xff, 0x28, 0xbd, 0x11, 0xe9, 0x49, 0x4e,
+ 0x29, 0x07, 0xb5, 0x28, 0xe1, 0x4c, 0x0f, 0xec, 0x83, 0xca, 0xc3, 0x5f,
+ 0x84, 0xbe, 0xab, 0xad, 0xfa, 0x91, 0xc3, 0x2b, 0x7e, 0x64, 0x17, 0xfc,
+ 0xcc, 0x17, 0x23, 0xc1, 0xde, 0x6f, 0x85, 0x6e, 0xb8, 0x9e, 0x38, 0x47,
+ 0xe9, 0x77, 0xee, 0xf1, 0x9c, 0xd7, 0xae, 0xf3, 0x94, 0x65, 0xe8, 0x0b,
+ 0x2b, 0xaa, 0xf4, 0x95, 0x58, 0x78, 0x37, 0x40, 0xf9, 0x45, 0x7e, 0xa1,
+ 0x71, 0x7f, 0xff, 0x0e, 0xf6, 0x32, 0xdf, 0x1b, 0x39, 0xc3, 0x3f, 0x4a,
+ 0xc6, 0x18, 0xbf, 0xf8, 0x8b, 0x75, 0x6b, 0x3b, 0xb0, 0x6e, 0x6d, 0x91,
+ 0x15, 0xba, 0x72, 0x8d, 0x51, 0xac, 0x71, 0x69, 0x8e, 0xb4, 0xed, 0x87,
+ 0x7c, 0x8a, 0x1b, 0x11, 0xca, 0x31, 0xf5, 0x6a, 0x1b, 0x74, 0x35, 0x69,
+ 0x17, 0x11, 0xc6, 0x3c, 0x26, 0xb0, 0xa6, 0x09, 0xac, 0x69, 0xa2, 0x81,
+ 0x8e, 0x07, 0x56, 0xd6, 0x64, 0xe6, 0x8d, 0x7a, 0x6a, 0xbf, 0xf1, 0x99,
+ 0x3f, 0xe8, 0xa9, 0x36, 0x83, 0x69, 0x38, 0x97, 0xdc, 0xba, 0xb9, 0x90,
+ 0x16, 0x9c, 0xcb, 0xca, 0x3c, 0xe2, 0x8c, 0x1c, 0x1d, 0xac, 0x91, 0xaf,
+ 0x1c, 0x73, 0xaf, 0x4c, 0x96, 0x3f, 0xa0, 0xe7, 0xd1, 0x8a, 0x79, 0x8c,
+ 0x41, 0x6f, 0x70, 0x3c, 0xec, 0xff, 0xda, 0x38, 0x9e, 0xe3, 0xe4, 0xbf,
+ 0x9e, 0x8b, 0xa1, 0x05, 0xfd, 0xb6, 0x84, 0xc6, 0xe2, 0x86, 0x5e, 0xae,
+ 0xc2, 0x0e, 0x97, 0xca, 0xff, 0x6d, 0x6b, 0x30, 0xb7, 0xa4, 0x9e, 0x47,
+ 0x40, 0x63, 0x60, 0x78, 0x60, 0xa9, 0xbc, 0xd6, 0x07, 0x8d, 0x74, 0xbd,
+ 0xbb, 0x49, 0xeb, 0x2b, 0xc8, 0x40, 0x63, 0xf9, 0xa7, 0x9a, 0x56, 0xeb,
+ 0x32, 0x3f, 0xaf, 0xf3, 0x5b, 0x42, 0xc3, 0x27, 0x4d, 0xd9, 0xd5, 0xa6,
+ 0x77, 0xf6, 0xf7, 0xd5, 0x26, 0xa3, 0x3f, 0x2e, 0x95, 0x1b, 0xf7, 0xfb,
+ 0x21, 0x2b, 0xb0, 0x3b, 0x45, 0x29, 0x0d, 0x64, 0xa1, 0xe7, 0x68, 0x7f,
+ 0x86, 0xac, 0xc0, 0xf6, 0xb0, 0xce, 0x21, 0x85, 0x1d, 0x23, 0x99, 0x2a,
+ 0xe5, 0x1e, 0xb4, 0xac, 0x8d, 0xe6, 0x66, 0x7c, 0x7f, 0xca, 0x5b, 0x4e,
+ 0x84, 0x85, 0x7a, 0x99, 0xb8, 0x8d, 0xe5, 0xcf, 0xa0, 0x1c, 0x76, 0xbd,
+ 0x3e, 0x26, 0x6c, 0xb7, 0x31, 0x3e, 0x4b, 0x6a, 0x7c, 0x16, 0x00, 0xbb,
+ 0x9c, 0xc2, 0x53, 0x4f, 0x8d, 0xc2, 0xfe, 0xeb, 0xe7, 0xa7, 0xf1, 0x9c,
+ 0x6c, 0xc4, 0x80, 0xe8, 0xb7, 0x32, 0x9a, 0x9b, 0x53, 0x76, 0x00, 0xfb,
+ 0x81, 0xbc, 0x3a, 0x03, 0x5e, 0x85, 0x64, 0x5a, 0xd9, 0x04, 0xce, 0x83,
+ 0xed, 0x2a, 0xa3, 0xdd, 0x8b, 0x4c, 0xab, 0xa3, 0xee, 0x62, 0x58, 0x0e,
+ 0xc4, 0x83, 0xb6, 0xcc, 0x27, 0x17, 0x8d, 0xdd, 0x6e, 0x91, 0x68, 0x86,
+ 0xba, 0xcd, 0x49, 0x03, 0x87, 0x62, 0x3d, 0x47, 0x47, 0xa7, 0x5d, 0xda,
+ 0xcb, 0xff, 0x03, 0x79, 0x68, 0x91, 0x26, 0x25, 0x27, 0x4f, 0xea, 0xb1,
+ 0xce, 0x60, 0xac, 0xad, 0x98, 0x6b, 0x18, 0x3a, 0x32, 0x92, 0xc0, 0x38,
+ 0x87, 0x2d, 0x77, 0x1b, 0xc6, 0xa3, 0xd7, 0xd8, 0x25, 0x53, 0x75, 0xca,
+ 0xfa, 0xdf, 0x44, 0x56, 0x7d, 0xc5, 0x13, 0x68, 0x67, 0x7c, 0x14, 0x8e,
+ 0x57, 0x05, 0x46, 0x69, 0xc1, 0x3a, 0x1c, 0x3b, 0x17, 0x86, 0xed, 0x9b,
+ 0x33, 0x75, 0x38, 0xa7, 0xe3, 0xa3, 0xa9, 0xc5, 0x14, 0xfa, 0xea, 0xa2,
+ 0xec, 0x41, 0xe6, 0xc2, 0xf8, 0xb1, 0x6f, 0xb6, 0x83, 0x4e, 0x1e, 0x34,
+ 0x76, 0x7c, 0xb5, 0xbd, 0x69, 0xd7, 0xbd, 0x38, 0xa2, 0x65, 0xf7, 0xaf,
+ 0xfc, 0xec, 0x38, 0xdf, 0x37, 0xc6, 0x07, 0x4c, 0x3b, 0x53, 0x27, 0xac,
+ 0xf5, 0xf1, 0x7d, 0xd1, 0xd5, 0x79, 0x3e, 0x35, 0x1a, 0xf8, 0x31, 0x12,
+ 0xc9, 0xf7, 0x0d, 0x6a, 0xbe, 0x3d, 0x8d, 0x32, 0xb6, 0xc7, 0x5e, 0xa8,
+ 0x37, 0x62, 0xf0, 0xa0, 0xdf, 0x22, 0xb0, 0x47, 0xa9, 0xdc, 0x04, 0x5d,
+ 0x93, 0x6d, 0x0f, 0x62, 0x22, 0xef, 0x85, 0xbb, 0xc1, 0x53, 0xf4, 0x53,
+ 0x5a, 0x69, 0xab, 0xe2, 0x93, 0xa3, 0x2f, 0xa1, 0xff, 0x23, 0xe5, 0x60,
+ 0xaf, 0x05, 0x74, 0x20, 0x5e, 0x0a, 0xc9, 0x92, 0x9b, 0x84, 0x7f, 0x47,
+ 0x3b, 0x94, 0x94, 0x97, 0x5d, 0x83, 0x9f, 0x88, 0x9d, 0x50, 0xbf, 0xce,
+ 0xf9, 0x70, 0xdd, 0x27, 0xb0, 0x6e, 0x5f, 0x66, 0xbd, 0x40, 0x3e, 0xfa,
+ 0xb0, 0x37, 0xff, 0x53, 0xc4, 0x39, 0x4a, 0x3f, 0xe0, 0x6a, 0xa4, 0x71,
+ 0x5d, 0xc6, 0x9e, 0x3d, 0xa5, 0x63, 0x93, 0x27, 0x34, 0x2f, 0x2b, 0xe0,
+ 0xe5, 0xb6, 0xa4, 0x2d, 0xbd, 0x98, 0x3b, 0xea, 0xf4, 0xf7, 0x00, 0x8f,
+ 0xd3, 0xd7, 0x4b, 0x60, 0x3e, 0x36, 0x64, 0x7d, 0xab, 0xb6, 0xfb, 0x9f,
+ 0x89, 0x52, 0x5f, 0xb4, 0xab, 0xb8, 0xe7, 0x09, 0x25, 0x6b, 0x81, 0xec,
+ 0x85, 0xf5, 0x7b, 0xc3, 0xef, 0x30, 0xcd, 0xae, 0xac, 0xc6, 0xf9, 0x8c,
+ 0xae, 0x66, 0xfd, 0x39, 0xd4, 0x0f, 0x61, 0x4d, 0xbe, 0x3f, 0xa9, 0xe6,
+ 0x3b, 0x0f, 0x5e, 0x87, 0xa5, 0xb4, 0x22, 0x8f, 0xf3, 0x90, 0xc7, 0x26,
+ 0x91, 0x8e, 0x46, 0xb9, 0xa1, 0xac, 0xbc, 0x1e, 0x65, 0x4c, 0x2e, 0x69,
+ 0x19, 0xde, 0x45, 0x88, 0xdd, 0x90, 0x37, 0xbc, 0xe3, 0xf3, 0x46, 0x18,
+ 0x90, 0x71, 0x27, 0xdf, 0x5f, 0xf2, 0x18, 0x23, 0x6c, 0x96, 0xa2, 0x1d,
+ 0xe0, 0x97, 0x92, 0x47, 0x39, 0xcd, 0x25, 0x23, 0xe2, 0x24, 0x0e, 0xc8,
+ 0x9b, 0xe8, 0x3b, 0x9b, 0x8e, 0x4a, 0xe0, 0xa7, 0x4e, 0x80, 0x6e, 0xcb,
+ 0xb6, 0xef, 0xbf, 0x04, 0xbf, 0xba, 0x0a, 0xbf, 0x66, 0x09, 0x69, 0xa9,
+ 0x86, 0x3d, 0xd0, 0x12, 0xc1, 0x9e, 0x32, 0x7b, 0x25, 0x26, 0x15, 0xd4,
+ 0x59, 0xc0, 0xbb, 0xc7, 0x6b, 0x86, 0xcb, 0xbe, 0x6f, 0x61, 0x5d, 0xfb,
+ 0xdd, 0xbf, 0xf6, 0x0b, 0xf1, 0xc6, 0xba, 0x06, 0x77, 0x11, 0x33, 0x11,
+ 0xf3, 0x10, 0xab, 0xf0, 0x1d, 0xf1, 0xc7, 0x61, 0xcc, 0x85, 0x32, 0xdc,
+ 0x26, 0xb1, 0x8c, 0x93, 0x18, 0x11, 0xa3, 0x8b, 0x5f, 0x03, 0xff, 0x8b,
+ 0x7e, 0xb3, 0xdb, 0x25, 0xcf, 0x83, 0xd7, 0xcf, 0xd5, 0x0d, 0xef, 0x93,
+ 0xe0, 0xbd, 0x53, 0x2c, 0x8a, 0x2f, 0x17, 0x3d, 0x37, 0xf9, 0x39, 0xa4,
+ 0xdf, 0xf1, 0x7e, 0x85, 0xb4, 0x78, 0x0a, 0x26, 0x0f, 0x38, 0x1b, 0x7a,
+ 0x75, 0xd6, 0xe0, 0xc7, 0x36, 0xe2, 0x7d, 0x4d, 0xc7, 0xab, 0xe8, 0xd3,
+ 0xb1, 0x2d, 0x80, 0xa5, 0x3b, 0x51, 0x2f, 0x90, 0x6b, 0x53, 0x76, 0x18,
+ 0x75, 0x39, 0x07, 0xfa, 0x62, 0xdf, 0xc5, 0x5e, 0xf2, 0xfd, 0x7b, 0xbd,
+ 0xc9, 0x86, 0x3d, 0x31, 0x0f, 0x1e, 0x28, 0xd9, 0x1c, 0x68, 0x17, 0xc6,
+ 0xee, 0xa4, 0xbf, 0x43, 0xf9, 0x0a, 0x7c, 0x86, 0x8c, 0x0e, 0xd0, 0x26,
+ 0x24, 0x55, 0xdc, 0x8f, 0xb6, 0xe7, 0x39, 0xd0, 0xfe, 0xd3, 0x35, 0xf2,
+ 0xa1, 0x55, 0xe9, 0xfe, 0xe7, 0xcb, 0xb4, 0xef, 0x01, 0x46, 0x9b, 0x50,
+ 0xb1, 0x5c, 0xda, 0x84, 0x34, 0x78, 0x13, 0xc4, 0xf0, 0x1e, 0x50, 0x6d,
+ 0x59, 0x8f, 0x6d, 0x1b, 0xf9, 0xc7, 0x3a, 0x5b, 0x81, 0xaf, 0x28, 0x83,
+ 0x6d, 0xc0, 0x25, 0xed, 0x72, 0x20, 0xdd, 0x0c, 0xba, 0x77, 0x28, 0x3c,
+ 0x65, 0xb9, 0x1f, 0x86, 0xed, 0x02, 0xa6, 0xb3, 0x1d, 0x6f, 0xd5, 0xf7,
+ 0xb8, 0x1d, 0x65, 0x3f, 0x05, 0xfd, 0x59, 0xb6, 0x49, 0xc7, 0xaf, 0x1f,
+ 0xc6, 0xfe, 0xab, 0x6c, 0x0d, 0xe2, 0x22, 0xe4, 0x83, 0xd1, 0x03, 0xc6,
+ 0xfe, 0xd9, 0x1a, 0x47, 0x92, 0x37, 0x41, 0x0c, 0xc5, 0x52, 0x75, 0x89,
+ 0xe7, 0x1b, 0xfd, 0x16, 0xee, 0x3b, 0xdf, 0xbf, 0xe8, 0x29, 0x7b, 0x0a,
+ 0x1e, 0xec, 0x86, 0x0d, 0x8b, 0x68, 0x5a, 0xb7, 0x82, 0xd6, 0x81, 0x8d,
+ 0x4d, 0x76, 0x40, 0xef, 0xb8, 0x56, 0x53, 0x40, 0x3f, 0x62, 0x85, 0xbf,
+ 0x85, 0x1f, 0x4f, 0xff, 0x81, 0x38, 0x81, 0x73, 0x47, 0xbb, 0x05, 0xd6,
+ 0xa5, 0x2d, 0x7e, 0x0c, 0x63, 0x84, 0x25, 0xd9, 0xc9, 0xfc, 0x03, 0xba,
+ 0x0d, 0x9f, 0x7d, 0xe9, 0xdd, 0xd1, 0x28, 0xcf, 0x83, 0x98, 0x27, 0xd7,
+ 0x63, 0xe2, 0x7a, 0x5d, 0x4a, 0x07, 0xac, 0xca, 0x85, 0x99, 0x93, 0x19,
+ 0x97, 0x73, 0x4b, 0x48, 0x07, 0xe6, 0x76, 0x37, 0x74, 0xf4, 0x8e, 0x0e,
+ 0xf6, 0x69, 0xc6, 0x6e, 0x9c, 0x93, 0xc1, 0x2f, 0x81, 0xdd, 0x8d, 0xba,
+ 0xcd, 0xb2, 0xa3, 0x93, 0xb4, 0xeb, 0x52, 0xba, 0x7a, 0x95, 0x1f, 0xb4,
+ 0xbf, 0x1c, 0x7b, 0x7d, 0xf9, 0x1d, 0x0d, 0xf3, 0x6a, 0x3c, 0x03, 0x20,
+ 0x76, 0xd8, 0x89, 0x77, 0x9c, 0x13, 0x9c, 0xe4, 0xb8, 0x2f, 0x7b, 0x14,
+ 0xdd, 0x38, 0xb7, 0xc6, 0x79, 0x10, 0x43, 0x71, 0xce, 0x9c, 0xc3, 0x7a,
+ 0x6c, 0xc2, 0xf9, 0xfc, 0x57, 0xcd, 0xc3, 0x4d, 0x7a, 0x5d, 0x06, 0xcb,
+ 0xa4, 0xd0, 0xf6, 0x3f, 0x60, 0x0d, 0x7c, 0xe6, 0x3a, 0x8c, 0xcd, 0x4e,
+ 0x05, 0xfd, 0xb4, 0x98, 0x78, 0xb0, 0x89, 0x6b, 0x70, 0x5e, 0xdc, 0x33,
+ 0x86, 0x4e, 0x1d, 0x9a, 0x47, 0xbb, 0xd7, 0x8d, 0xeb, 0x78, 0x6b, 0xf5,
+ 0xc8, 0xed, 0x0d, 0xeb, 0xeb, 0x97, 0xe2, 0x02, 0xe5, 0xe2, 0x36, 0xa4,
+ 0x06, 0x13, 0x0c, 0x40, 0xf7, 0xbf, 0x2b, 0x26, 0xe0, 0x59, 0xd5, 0x78,
+ 0x01, 0x3e, 0x99, 0xd2, 0xfd, 0x6a, 0x2f, 0xc6, 0x90, 0x87, 0x3e, 0xa9,
+ 0xdf, 0x43, 0x19, 0x1b, 0x9f, 0xa8, 0x79, 0xe3, 0x93, 0xb5, 0x81, 0x71,
+ 0xe2, 0xa9, 0x40, 0xe6, 0x50, 0xbf, 0x26, 0x13, 0xf0, 0xb3, 0xc7, 0x73,
+ 0xaa, 0x9d, 0x8a, 0x31, 0x6c, 0xd0, 0x8f, 0x70, 0x3f, 0x4e, 0x04, 0x63,
+ 0xc5, 0xc6, 0xf3, 0xd0, 0x41, 0x0b, 0xb3, 0xb0, 0x4b, 0xae, 0x93, 0xa5,
+ 0x5c, 0xee, 0xf7, 0x9c, 0x11, 0x25, 0x7b, 0x71, 0x67, 0x8c, 0xbc, 0xac,
+ 0xce, 0xfe, 0xb2, 0x2c, 0xcc, 0xf9, 0x72, 0x17, 0x74, 0xe1, 0x43, 0x90,
+ 0x55, 0x39, 0x07, 0x45, 0x78, 0x0e, 0xca, 0xeb, 0x5c, 0x5c, 0xac, 0x53,
+ 0x5d, 0x12, 0x3d, 0x96, 0x90, 0xc8, 0x31, 0x62, 0xcb, 0x94, 0x7d, 0x97,
+ 0x08, 0xec, 0xd8, 0x8b, 0x1f, 0xb2, 0xc4, 0x19, 0xcc, 0x4a, 0x2a, 0xf9,
+ 0x38, 0x6c, 0x6f, 0x15, 0x69, 0x49, 0x52, 0xe9, 0xb3, 0xe8, 0x2b, 0x7a,
+ 0x0e, 0x75, 0xd1, 0x6e, 0xd3, 0x52, 0x12, 0xbf, 0x4e, 0x69, 0x59, 0x0a,
+ 0xf6, 0x4a, 0xcb, 0xd2, 0x5a, 0xff, 0x7c, 0x68, 0xc5, 0x3f, 0xe7, 0xfb,
+ 0xb7, 0x75, 0x5c, 0xe1, 0x8b, 0xfa, 0x8c, 0x81, 0x32, 0x42, 0x7b, 0xa4,
+ 0x7c, 0x63, 0xe8, 0xfd, 0x2f, 0xc2, 0xc7, 0x02, 0x0e, 0x2c, 0xc3, 0x97,
+ 0xca, 0xf8, 0xf2, 0xac, 0x57, 0xf4, 0x73, 0x03, 0xbe, 0xbc, 0xe6, 0xb9,
+ 0xc5, 0x82, 0x38, 0x6f, 0x53, 0xdf, 0xfd, 0x85, 0xf7, 0x4f, 0xe4, 0xfe,
+ 0x76, 0xe7, 0xfe, 0x6c, 0xa8, 0xe8, 0xb7, 0xc2, 0xb7, 0xba, 0x31, 0x73,
+ 0x58, 0xf6, 0x6f, 0x5f, 0x86, 0x0f, 0x9c, 0xbd, 0x11, 0x38, 0x2b, 0x51,
+ 0x50, 0xba, 0xea, 0x75, 0xe5, 0xb7, 0x7d, 0xa2, 0xe7, 0xb0, 0x6c, 0xd9,
+ 0xee, 0xd8, 0xd7, 0xc2, 0xc4, 0x40, 0x87, 0x25, 0x0f, 0xfd, 0x9f, 0x0f,
+ 0xbb, 0xf6, 0x5e, 0x71, 0x46, 0x1e, 0x11, 0x9e, 0x0d, 0xba, 0xd2, 0x7d,
+ 0xcc, 0x4d, 0x7c, 0x32, 0xd4, 0x7b, 0xf0, 0x93, 0xc0, 0xae, 0xdd, 0xe7,
+ 0x98, 0xf7, 0x25, 0xb6, 0xdd, 0xc6, 0x73, 0x5c, 0xba, 0x4f, 0x25, 0x25,
+ 0x05, 0xba, 0xf4, 0x29, 0x9a, 0xf0, 0x6c, 0x22, 0x21, 0xbd, 0xc7, 0x88,
+ 0x49, 0x14, 0x6d, 0xfa, 0x40, 0x9b, 0x34, 0x68, 0x03, 0x9f, 0x66, 0x9b,
+ 0x7d, 0x0d, 0xe9, 0x65, 0x49, 0x0d, 0x7e, 0x0f, 0xb4, 0xe9, 0x03, 0x6d,
+ 0x7a, 0xcf, 0x25, 0xd1, 0x1e, 0x7d, 0x2c, 0x75, 0x23, 0x6d, 0x91, 0x5f,
+ 0xbb, 0xbe, 0x13, 0xcf, 0xae, 0xa4, 0x8e, 0xc5, 0x30, 0x46, 0x48, 0xf6,
+ 0xf4, 0x14, 0x65, 0x78, 0x3b, 0x30, 0x74, 0xfc, 0xb0, 0x5c, 0x81, 0x1d,
+ 0x2a, 0xc3, 0x7f, 0x7b, 0x76, 0xd0, 0x19, 0x5b, 0x86, 0x2e, 0xad, 0xdf,
+ 0xed, 0xcb, 0x37, 0xb6, 0x7f, 0xd3, 0x4f, 0x5c, 0xef, 0xdc, 0x2f, 0xa1,
+ 0x01, 0x99, 0x2e, 0x2b, 0xfb, 0x90, 0xc8, 0x85, 0x15, 0xd6, 0xc1, 0x1a,
+ 0x8b, 0xb0, 0x31, 0x3c, 0xf3, 0x74, 0xa1, 0xeb, 0x1f, 0x91, 0x87, 0x2a,
+ 0x53, 0xf8, 0x01, 0x77, 0xcf, 0xb0, 0xee, 0x41, 0xe0, 0xed, 0x87, 0xe5,
+ 0xc0, 0x0c, 0xb0, 0x58, 0x06, 0xf3, 0x1e, 0x70, 0x81, 0xcb, 0x33, 0xcd,
+ 0xd2, 0x86, 0x32, 0xd0, 0x76, 0xac, 0xbe, 0x1e, 0xd7, 0x2e, 0x83, 0x0f,
+ 0x83, 0xf2, 0x27, 0xf5, 0x01, 0xf9, 0x4a, 0xbd, 0x5f, 0xbe, 0x04, 0xdb,
+ 0xf2, 0x5c, 0xbd, 0x0b, 0x7b, 0x25, 0x01, 0x9e, 0x64, 0xc0, 0x1f, 0x4f,
+ 0xbe, 0x5c, 0x4f, 0xcb, 0x17, 0x41, 0xab, 0xe7, 0xf1, 0x1b, 0x2e, 0xa7,
+ 0x65, 0x4f, 0xb9, 0x5f, 0xf3, 0x88, 0xfc, 0x71, 0x31, 0x1f, 0x17, 0x6b,
+ 0x77, 0x9e, 0x29, 0x62, 0xff, 0x2d, 0xd4, 0xdd, 0xb7, 0xaa, 0x34, 0xb2,
+ 0x6d, 0xb6, 0x9c, 0x59, 0xb1, 0x2f, 0x45, 0xdf, 0x76, 0x9d, 0xa3, 0x13,
+ 0xe0, 0x43, 0x15, 0xfb, 0x74, 0x4c, 0xd1, 0x7e, 0xd5, 0xf6, 0x54, 0x03,
+ 0xdb, 0x63, 0xd6, 0x37, 0x5b, 0x90, 0xef, 0x48, 0xee, 0xc4, 0xb4, 0xec,
+ 0x3f, 0xe9, 0xcb, 0x6f, 0x7a, 0x3e, 0xe4, 0x98, 0xba, 0x78, 0x80, 0x3a,
+ 0x3e, 0x39, 0x11, 0xb6, 0x94, 0x9f, 0x1b, 0x60, 0x8d, 0xef, 0x75, 0x60,
+ 0xcf, 0xa6, 0xb3, 0xd6, 0x94, 0xa4, 0x4e, 0x4c, 0x49, 0xf7, 0x09, 0xc8,
+ 0x82, 0xc7, 0xbe, 0x96, 0x6d, 0xeb, 0x1d, 0xf2, 0xc0, 0x71, 0x9c, 0xc1,
+ 0xbc, 0xb8, 0xf6, 0x5b, 0x92, 0xc6, 0xf8, 0x87, 0xa4, 0x07, 0x6d, 0x5c,
+ 0xb4, 0xb9, 0xa6, 0xc6, 0x6e, 0xc5, 0xd8, 0xcd, 0x72, 0x24, 0xee, 0x40,
+ 0xd6, 0x68, 0xc3, 0xff, 0xaf, 0xe4, 0xaa, 0x4c, 0x7f, 0x24, 0xb9, 0x33,
+ 0x6f, 0x37, 0x4b, 0x0b, 0x9f, 0xa1, 0x1a, 0xe6, 0x59, 0xde, 0x8d, 0x94,
+ 0xe5, 0xae, 0x58, 0xc7, 0x7f, 0x22, 0xb9, 0xf3, 0x1c, 0xfb, 0x2d, 0x94,
+ 0x7f, 0x43, 0x72, 0xc7, 0x7f, 0x8a, 0xfc, 0x15, 0xa4, 0x6f, 0x23, 0x1d,
+ 0x93, 0xee, 0xe3, 0xf0, 0x91, 0xcf, 0x7f, 0x1b, 0x79, 0xf8, 0x74, 0xe7,
+ 0x8f, 0xa0, 0xde, 0x6e, 0xcc, 0xef, 0xde, 0x18, 0xb0, 0x06, 0x74, 0x5e,
+ 0xec, 0xba, 0x60, 0xfe, 0x2c, 0x67, 0x19, 0xdf, 0x1d, 0x81, 0x4e, 0xfb,
+ 0x1f, 0xd0, 0x69, 0xfa, 0x79, 0x81, 0x79, 0xea, 0x36, 0x3e, 0x4f, 0x81,
+ 0x26, 0x87, 0x90, 0xf7, 0xe5, 0x61, 0x8f, 0xf6, 0x66, 0xa7, 0x8c, 0xdb,
+ 0x45, 0xbf, 0x05, 0xb8, 0xa2, 0x15, 0xfb, 0x60, 0x6a, 0xc7, 0xc6, 0xfb,
+ 0xe0, 0x68, 0xef, 0x61, 0xd9, 0xb4, 0xdd, 0xac, 0xdf, 0xac, 0xd7, 0xb5,
+ 0x7f, 0xa8, 0xe8, 0xe0, 0x14, 0x3f, 0x29, 0x5c, 0x87, 0x9b, 0x78, 0xd2,
+ 0xea, 0xbd, 0xff, 0x21, 0xec, 0x03, 0xeb, 0x3c, 0xf3, 0xc1, 0x3e, 0xb0,
+ 0xce, 0x43, 0x37, 0xcc, 0xc3, 0x47, 0x9b, 0xef, 0x92, 0xe6, 0xe3, 0xab,
+ 0xfb, 0xa0, 0xe9, 0xf8, 0xcf, 0xdf, 0x07, 0xcd, 0xe7, 0x51, 0xef, 0x3c,
+ 0x69, 0x86, 0x3e, 0xce, 0x90, 0x66, 0x9d, 0x48, 0x1f, 0xc1, 0x5a, 0x39,
+ 0xf7, 0x66, 0xcc, 0x3d, 0xc0, 0x45, 0x1f, 0x82, 0xbc, 0x7f, 0x62, 0xfb,
+ 0x21, 0x5d, 0xfe, 0x9f, 0xfd, 0x91, 0xb8, 0x53, 0x91, 0x10, 0x69, 0x8a,
+ 0xba, 0x55, 0xd2, 0xf0, 0x79, 0xd0, 0xe6, 0xa0, 0x74, 0x93, 0x7e, 0xd5,
+ 0xbd, 0xc8, 0x17, 0xfd, 0x28, 0x7d, 0x74, 0x45, 0x4f, 0xe0, 0xa4, 0x01,
+ 0x96, 0xbf, 0x0a, 0x99, 0x21, 0xc6, 0x7c, 0x5d, 0xf6, 0xcf, 0xf8, 0x32,
+ 0xee, 0x71, 0xfd, 0x6f, 0x62, 0xfd, 0xd9, 0xed, 0x71, 0x59, 0x4e, 0xc6,
+ 0x41, 0x93, 0x05, 0xe8, 0xf6, 0x2b, 0x12, 0xd0, 0x81, 0x31, 0xe7, 0x3d,
+ 0xe2, 0x26, 0x86, 0xc5, 0x4d, 0x7f, 0x0f, 0x74, 0x18, 0x86, 0xec, 0xe7,
+ 0xeb, 0x94, 0x9d, 0x57, 0x64, 0x08, 0x32, 0xf1, 0x86, 0xe7, 0xa4, 0x81,
+ 0x85, 0xa0, 0x2f, 0x28, 0x17, 0x94, 0x89, 0x36, 0xa5, 0x93, 0xe6, 0x3d,
+ 0xe7, 0xa9, 0xaa, 0xdc, 0x2a, 0xf3, 0x0a, 0x9b, 0xe2, 0xdd, 0x71, 0x65,
+ 0x2f, 0xd2, 0x13, 0x56, 0x0f, 0x74, 0x74, 0x5a, 0xec, 0xde, 0x9b, 0x9b,
+ 0xcd, 0x3d, 0x85, 0xc2, 0x89, 0x90, 0x4c, 0xf5, 0x92, 0x57, 0xec, 0x17,
+ 0xf9, 0x6a, 0xd1, 0x8f, 0xb8, 0x6f, 0xf9, 0xa7, 0x3b, 0x93, 0xf2, 0xe9,
+ 0xde, 0x15, 0xb9, 0xac, 0x88, 0x04, 0xfb, 0x62, 0x48, 0xf1, 0xc3, 0xcc,
+ 0xdb, 0xac, 0xc5, 0xbc, 0xeb, 0x6f, 0x78, 0xc7, 0xb5, 0x50, 0xd6, 0x57,
+ 0xf6, 0x4e, 0xf2, 0x9d, 0x73, 0xfd, 0x5d, 0xd0, 0xcc, 0x79, 0xaa, 0x24,
+ 0xaf, 0x41, 0xf6, 0x40, 0xc3, 0xf3, 0x4c, 0x49, 0xc3, 0x29, 0xc8, 0xfd,
+ 0xab, 0xb2, 0xe7, 0x04, 0xf7, 0xcc, 0xab, 0x58, 0xab, 0xd2, 0x25, 0xd0,
+ 0x11, 0xec, 0xcf, 0x97, 0x69, 0x8f, 0xb1, 0x92, 0x5b, 0x13, 0x93, 0xf0,
+ 0xe1, 0x26, 0x6c, 0x5f, 0x96, 0xbc, 0xa2, 0x2c, 0x0d, 0xa2, 0x4d, 0xf5,
+ 0x11, 0xfc, 0xda, 0xf4, 0xda, 0x3e, 0x0b, 0xba, 0x3b, 0xc9, 0x8a, 0xf5,
+ 0x19, 0xd0, 0xfd, 0x61, 0x49, 0x1d, 0x5f, 0xd1, 0x35, 0x90, 0xbb, 0x40,
+ 0xd7, 0xa4, 0xce, 0xdb, 0x52, 0x2d, 0xbb, 0xf2, 0x71, 0xea, 0x90, 0x32,
+ 0xd7, 0x05, 0x1d, 0xc3, 0xf3, 0xdb, 0x32, 0xf4, 0x4c, 0x19, 0x3a, 0x05,
+ 0x3a, 0xe4, 0x4b, 0x28, 0xff, 0x22, 0xea, 0x3c, 0x0f, 0x9f, 0xe7, 0x39,
+ 0x60, 0xbf, 0x8b, 0xc0, 0x14, 0x17, 0xca, 0x59, 0xed, 0x1b, 0xaa, 0xf5,
+ 0xc2, 0x66, 0x29, 0x7f, 0x45, 0xaa, 0x15, 0xd2, 0xe3, 0x27, 0x8a, 0xb7,
+ 0x39, 0x6f, 0x2b, 0x71, 0x16, 0x66, 0x26, 0x52, 0xa9, 0x18, 0x9a, 0x50,
+ 0xf7, 0x31, 0xf6, 0x6f, 0x74, 0x65, 0xeb, 0x3a, 0x5d, 0x29, 0xf2, 0x62,
+ 0x2d, 0xc0, 0x93, 0xc4, 0xc7, 0xa5, 0x99, 0xe4, 0xca, 0x19, 0x59, 0x09,
+ 0x76, 0xf3, 0x32, 0xfc, 0x92, 0x58, 0xe6, 0x5b, 0x12, 0x3b, 0xe5, 0xfb,
+ 0xdf, 0x87, 0xdd, 0x2c, 0x82, 0x27, 0x56, 0x08, 0xe5, 0x8b, 0x7c, 0x47,
+ 0xb9, 0xa7, 0x6c, 0x87, 0x18, 0x2b, 0x97, 0x97, 0x51, 0x56, 0x55, 0x3e,
+ 0xd3, 0xb7, 0x31, 0x1f, 0x3d, 0x3f, 0x55, 0xc6, 0x7a, 0xcd, 0x92, 0x1f,
+ 0x4f, 0xcb, 0xe3, 0xe5, 0x6d, 0x76, 0x33, 0xda, 0x57, 0x16, 0xd9, 0xc6,
+ 0x19, 0xe4, 0x95, 0x9d, 0x97, 0x17, 0x59, 0xde, 0x25, 0x57, 0x66, 0x32,
+ 0x6a, 0x0e, 0xd5, 0xb9, 0x8c, 0x04, 0x31, 0x49, 0xea, 0x2b, 0xce, 0x15,
+ 0x79, 0xfa, 0x96, 0x65, 0xda, 0xd9, 0x88, 0x14, 0x13, 0xa4, 0x75, 0x42,
+ 0x2e, 0xcf, 0xc4, 0x37, 0x31, 0x86, 0x93, 0x73, 0xf9, 0x6c, 0x62, 0x07,
+ 0xf6, 0xfb, 0x88, 0x1d, 0x30, 0x5e, 0x10, 0x81, 0x2d, 0x53, 0x31, 0x04,
+ 0xa4, 0xc9, 0x06, 0x9f, 0x95, 0xef, 0x03, 0x6c, 0xb4, 0x8a, 0x1f, 0x89,
+ 0x27, 0xb9, 0x5e, 0xa7, 0xb8, 0x0c, 0xfd, 0xd1, 0x91, 0x79, 0x49, 0xee,
+ 0x99, 0x0f, 0xd6, 0x67, 0x9d, 0x11, 0xde, 0xd3, 0x90, 0x6b, 0x73, 0x8e,
+ 0x77, 0x15, 0x98, 0x22, 0x1f, 0xf7, 0xc0, 0xaf, 0x3f, 0x8b, 0x41, 0x7f,
+ 0x0d, 0x66, 0xad, 0x3d, 0x9b, 0x02, 0x7c, 0x16, 0x91, 0xa9, 0x19, 0x9e,
+ 0xa9, 0x41, 0xb7, 0x01, 0x43, 0xfe, 0xf3, 0x08, 0x9e, 0x6b, 0xcc, 0xc3,
+ 0x4f, 0x0b, 0x7c, 0x50, 0x3c, 0x07, 0xfd, 0x91, 0xe6, 0xd6, 0x3c, 0xd7,
+ 0x1e, 0x92, 0x7b, 0x80, 0x4e, 0x04, 0xfd, 0x77, 0xeb, 0xb1, 0xba, 0xcf,
+ 0xa4, 0x19, 0xc3, 0x93, 0x14, 0xf4, 0x45, 0x6e, 0x2e, 0x82, 0xb1, 0xba,
+ 0x34, 0x36, 0xe7, 0xbb, 0xf5, 0xd8, 0xd3, 0xf8, 0x78, 0x69, 0x79, 0xa2,
+ 0x6c, 0xb0, 0x5e, 0x1a, 0x36, 0x56, 0x22, 0x23, 0x7d, 0xbe, 0x7c, 0xdf,
+ 0x23, 0xbd, 0xfa, 0x91, 0xf7, 0xe4, 0x68, 0xfd, 0xdd, 0xce, 0xce, 0x1a,
+ 0xff, 0x5a, 0x31, 0x47, 0xfe, 0x30, 0x3f, 0xe0, 0x23, 0xce, 0xdd, 0x82,
+ 0x3d, 0x2f, 0x01, 0x77, 0x59, 0xe7, 0xba, 0xd4, 0x3b, 0x0b, 0xd8, 0xa0,
+ 0x3a, 0x03, 0xdd, 0x78, 0x8e, 0xe7, 0x89, 0xd0, 0x6d, 0xe7, 0xa2, 0x52,
+ 0x9a, 0xa5, 0x5c, 0x4a, 0x87, 0x05, 0x7e, 0xb1, 0x7e, 0x75, 0xa6, 0x0b,
+ 0x69, 0x2b, 0xd2, 0xa4, 0xea, 0xa7, 0x3a, 0xe3, 0xaa, 0xf6, 0xd5, 0x99,
+ 0xb4, 0x6a, 0x57, 0x9d, 0xe9, 0x47, 0xea, 0x49, 0xd3, 0x39, 0x38, 0x4e,
+ 0xe7, 0x7a, 0x65, 0xea, 0x34, 0xec, 0xcb, 0x80, 0xa5, 0xce, 0xe2, 0x27,
+ 0x60, 0x7f, 0x22, 0xf0, 0xb2, 0xae, 0xda, 0x83, 0xc0, 0x58, 0x3b, 0x81,
+ 0x41, 0x76, 0x8a, 0x7b, 0x8a, 0xeb, 0xa7, 0xee, 0xbd, 0xcc, 0x78, 0x52,
+ 0xe2, 0x41, 0xc9, 0xca, 0x81, 0xd9, 0x66, 0xec, 0xd7, 0x88, 0x5d, 0x92,
+ 0x1e, 0x7b, 0x18, 0xf9, 0x42, 0x85, 0x74, 0xbb, 0x4f, 0xf9, 0x6e, 0x39,
+ 0xef, 0x1c, 0x78, 0x92, 0xc1, 0x18, 0xef, 0xa7, 0x7d, 0x1f, 0xe4, 0xcf,
+ 0xd5, 0x7d, 0x64, 0x30, 0x9f, 0x46, 0x7a, 0xf0, 0x1c, 0x31, 0xfb, 0x73,
+ 0xce, 0x11, 0x29, 0xd7, 0xa4, 0xef, 0x7d, 0x72, 0xd9, 0xcd, 0xc8, 0xcb,
+ 0x6e, 0x5a, 0xae, 0xb8, 0x3b, 0xe4, 0xeb, 0xb0, 0xd3, 0x2f, 0xb9, 0x7d,
+ 0x9b, 0x88, 0x05, 0xaa, 0xea, 0x6c, 0xc6, 0xf0, 0xca, 0xd5, 0xf1, 0xc4,
+ 0x1f, 0xc8, 0xd2, 0x0c, 0xb1, 0xb3, 0xbf, 0x7b, 0xbf, 0x57, 0xa4, 0xdd,
+ 0xc2, 0x1c, 0x88, 0xd5, 0x8a, 0xb0, 0x7f, 0x87, 0x65, 0xd8, 0xa3, 0xdd,
+ 0x53, 0x36, 0x2a, 0x31, 0x1c, 0xec, 0x67, 0xaf, 0x00, 0xbd, 0x7a, 0x79,
+ 0x16, 0xfb, 0x49, 0x28, 0xff, 0x78, 0xae, 0x90, 0xef, 0xae, 0x3c, 0x59,
+ 0xe6, 0x3a, 0x4b, 0xd7, 0xb5, 0x48, 0x58, 0x46, 0x14, 0x5e, 0x68, 0x93,
+ 0x17, 0x17, 0x37, 0x8b, 0x05, 0x0b, 0x65, 0xdd, 0x12, 0x55, 0xb7, 0x18,
+ 0xe8, 0x7f, 0x4b, 0x3b, 0xef, 0x22, 0xbd, 0x05, 0xda, 0x30, 0x16, 0x80,
+ 0xb5, 0xb5, 0x73, 0x25, 0x26, 0xdf, 0x8f, 0xfd, 0xf5, 0x96, 0xda, 0x6b,
+ 0x79, 0x37, 0x8e, 0x67, 0xa6, 0xdc, 0x73, 0x8c, 0x3b, 0x85, 0x75, 0xfc,
+ 0xf7, 0xaf, 0xd4, 0xfb, 0x66, 0x77, 0x17, 0x70, 0x1d, 0xe5, 0x15, 0xe9,
+ 0x52, 0x30, 0x6e, 0x1e, 0x38, 0xae, 0xd0, 0xcf, 0x3b, 0x14, 0x4e, 0xba,
+ 0x88, 0xbd, 0x30, 0xa1, 0xea, 0xef, 0xc4, 0x7e, 0xda, 0xd4, 0x42, 0xfc,
+ 0xb0, 0x07, 0xb2, 0xf8, 0xd2, 0x0c, 0x9f, 0xf9, 0x9e, 0xfe, 0x15, 0xe3,
+ 0x6b, 0x17, 0x46, 0xa7, 0xdd, 0xdf, 0xd2, 0xfb, 0x47, 0x42, 0x77, 0xf5,
+ 0x01, 0x87, 0x1e, 0x6b, 0xc2, 0x5a, 0x9c, 0x64, 0x32, 0x64, 0x75, 0x5a,
+ 0xc0, 0xf1, 0xc3, 0xca, 0xe6, 0xf6, 0x61, 0xfe, 0x69, 0x39, 0x93, 0x6e,
+ 0x93, 0xaa, 0xed, 0xaa, 0x3b, 0x57, 0xcb, 0xf6, 0x76, 0x62, 0x7d, 0xfc,
+ 0x36, 0xa1, 0xac, 0x07, 0x69, 0x33, 0xd2, 0xdb, 0xa4, 0x74, 0xb2, 0xaf,
+ 0x25, 0xe8, 0x2f, 0xba, 0x2e, 0xff, 0x75, 0x3d, 0xce, 0x5f, 0x6a, 0x7f,
+ 0x8a, 0xe3, 0x44, 0xc5, 0xfd, 0x7c, 0xab, 0xf4, 0x1c, 0xb3, 0x81, 0x6d,
+ 0x13, 0xc0, 0xba, 0x5d, 0x92, 0x3e, 0x96, 0x94, 0x5b, 0x8e, 0x99, 0x38,
+ 0xd1, 0x97, 0x47, 0x53, 0x2a, 0x66, 0xf8, 0xa5, 0x51, 0xb7, 0xa2, 0xce,
+ 0x53, 0xf5, 0xdd, 0xb0, 0x65, 0x7d, 0x67, 0xec, 0x1b, 0xa3, 0x7d, 0x2a,
+ 0xfd, 0xf6, 0x68, 0x5a, 0xa5, 0xaf, 0x8c, 0xde, 0x52, 0x0b, 0xfc, 0xa3,
+ 0xd2, 0x42, 0x5a, 0x3e, 0x57, 0x26, 0xbe, 0x1c, 0x00, 0x76, 0xf4, 0xa0,
+ 0x67, 0xfa, 0xa1, 0x67, 0xd2, 0xd0, 0x33, 0x83, 0xd4, 0x33, 0xd0, 0xdb,
+ 0xaf, 0x40, 0x6f, 0x7b, 0xf2, 0x06, 0xe4, 0xf5, 0x82, 0xd7, 0x0c, 0x5c,
+ 0xe8, 0xfb, 0xc1, 0x5a, 0x9d, 0xa7, 0x96, 0xc1, 0xdf, 0xea, 0x59, 0x89,
+ 0xb5, 0x43, 0x07, 0x6d, 0x9f, 0x6f, 0x92, 0x85, 0xb8, 0xef, 0x9f, 0xf0,
+ 0x5c, 0xb9, 0x86, 0xfa, 0x39, 0x97, 0xfb, 0x78, 0xa2, 0x85, 0xfe, 0xd8,
+ 0xb5, 0x99, 0x1d, 0xd0, 0x49, 0x94, 0xf7, 0x98, 0x54, 0xc7, 0x13, 0xb2,
+ 0x08, 0xff, 0x6c, 0xb5, 0x4e, 0x1a, 0xcf, 0xdc, 0xff, 0xff, 0x12, 0x75,
+ 0xd3, 0xb0, 0x0f, 0xb6, 0x2c, 0xf5, 0x25, 0xe5, 0x4c, 0x9f, 0x33, 0x98,
+ 0xb4, 0xa8, 0xbb, 0x92, 0x52, 0x81, 0xaf, 0x5f, 0x2d, 0xb3, 0x3e, 0xeb,
+ 0x61, 0x7f, 0x96, 0x83, 0x76, 0xd3, 0x65, 0xa3, 0x27, 0x20, 0x9f, 0x73,
+ 0x8c, 0x03, 0x06, 0x36, 0xc0, 0xb2, 0x9a, 0x21, 0x07, 0x1e, 0xe8, 0x3f,
+ 0x8e, 0xf2, 0x01, 0xde, 0x25, 0x40, 0x19, 0xb1, 0x50, 0x49, 0xf1, 0x38,
+ 0xef, 0x8d, 0xa3, 0x8c, 0x6d, 0x9c, 0x44, 0x0a, 0xe5, 0x63, 0x92, 0x4a,
+ 0x14, 0xd4, 0xbd, 0xa6, 0x4e, 0x94, 0xb1, 0x8f, 0xb0, 0x8e, 0xc7, 0xcc,
+ 0xb6, 0x50, 0x8e, 0xc2, 0xae, 0x29, 0xdf, 0xa6, 0x62, 0x03, 0x59, 0xdb,
+ 0xc3, 0x7e, 0x60, 0x59, 0xca, 0x66, 0xbb, 0xbc, 0xe7, 0x29, 0x5d, 0x78,
+ 0xaf, 0x3e, 0xb7, 0xb8, 0xa7, 0xd6, 0x2a, 0xf9, 0x5a, 0xd3, 0x7b, 0xe8,
+ 0x7f, 0xb3, 0x27, 0x2f, 0x27, 0x6c, 0xe1, 0x19, 0x7b, 0xb0, 0xcf, 0x23,
+ 0x3b, 0xb8, 0x27, 0x40, 0x77, 0xd8, 0xdf, 0xe7, 0xb1, 0xde, 0xe7, 0x60,
+ 0x7f, 0x2f, 0xc2, 0xfe, 0x5e, 0x28, 0xaf, 0xea, 0x8f, 0xc0, 0xee, 0x52,
+ 0x07, 0x3c, 0x03, 0x9e, 0x8d, 0x01, 0xf7, 0xef, 0x85, 0x3f, 0x30, 0x02,
+ 0xec, 0x3f, 0x04, 0xfe, 0x65, 0xc0, 0xbb, 0x71, 0xde, 0x45, 0x01, 0x1f,
+ 0x07, 0xd5, 0x59, 0xe6, 0xac, 0x3a, 0xcf, 0xff, 0x81, 0xb2, 0xbd, 0x8f,
+ 0x97, 0x2d, 0xd8, 0x87, 0xa2, 0x7f, 0x9d, 0xeb, 0x00, 0xff, 0xad, 0xec,
+ 0xe7, 0xc1, 0x17, 0xa1, 0x57, 0x7e, 0x8c, 0x79, 0x3d, 0x37, 0x4b, 0x7b,
+ 0x8e, 0x3a, 0x01, 0xde, 0xf6, 0x18, 0xeb, 0xc2, 0x7e, 0x3e, 0x7a, 0x59,
+ 0x96, 0x81, 0x3b, 0xb2, 0x94, 0x63, 0xf8, 0x0f, 0xce, 0x85, 0x8a, 0xf4,
+ 0x52, 0x07, 0x02, 0x13, 0x0d, 0xca, 0xc0, 0xf1, 0x04, 0xb0, 0x1e, 0x90,
+ 0xbc, 0x3a, 0xaf, 0xc3, 0xf3, 0xf9, 0x2d, 0x62, 0x11, 0xef, 0x79, 0x3c,
+ 0x9b, 0xa1, 0xde, 0x30, 0x18, 0x69, 0x79, 0xb0, 0x43, 0xb2, 0xdb, 0x3b,
+ 0x94, 0xee, 0x70, 0xbc, 0x97, 0x31, 0xee, 0x1e, 0xb8, 0x20, 0x6f, 0x00,
+ 0x21, 0x58, 0x99, 0x43, 0xf2, 0xbf, 0x3c, 0xc6, 0xa8, 0x02, 0xdf, 0x0f,
+ 0x73, 0x89, 0x81, 0x66, 0x9b, 0xf6, 0xbb, 0x76, 0x6c, 0x4f, 0x9d, 0xfd,
+ 0xc7, 0x14, 0xc6, 0xca, 0x0b, 0xfb, 0x87, 0x9d, 0xc0, 0x98, 0xa9, 0xe3,
+ 0x94, 0xfd, 0x6d, 0xe0, 0xdb, 0x3f, 0x05, 0x06, 0x22, 0x55, 0x87, 0x36,
+ 0x07, 0xfb, 0x85, 0xf3, 0x5f, 0x26, 0x9e, 0x60, 0x4c, 0x3d, 0xf0, 0xcb,
+ 0x57, 0xe6, 0xb6, 0x13, 0xf6, 0xeb, 0xb6, 0xcd, 0x94, 0x81, 0x71, 0x0f,
+ 0x7e, 0xdf, 0xf1, 0xc0, 0x5e, 0x77, 0x9f, 0x47, 0xab, 0x13, 0xd2, 0xc9,
+ 0xd3, 0x4e, 0x4b, 0x6e, 0x91, 0x8f, 0x44, 0x82, 0x7e, 0xac, 0x79, 0x1b,
+ 0xb2, 0x4a, 0x3d, 0xd0, 0x09, 0x39, 0x67, 0x9e, 0x3a, 0x85, 0x3a, 0x81,
+ 0xb2, 0xe0, 0x4a, 0xa9, 0x0e, 0x9d, 0xd0, 0xd6, 0x25, 0x15, 0xd2, 0x6c,
+ 0x9e, 0x7a, 0xe2, 0x07, 0x32, 0xbd, 0x4e, 0x57, 0x0e, 0x89, 0xf1, 0x6b,
+ 0x5b, 0x25, 0x9a, 0x71, 0xed, 0x7b, 0xd5, 0x1a, 0x03, 0x7d, 0x79, 0x80,
+ 0xf8, 0x73, 0x36, 0xeb, 0x74, 0x88, 0xc6, 0x9e, 0x0a, 0x3f, 0xbd, 0x89,
+ 0xb5, 0xb2, 0x0f, 0x45, 0xa7, 0xc1, 0xa1, 0xc0, 0x17, 0x50, 0x31, 0x3f,
+ 0xe0, 0xe0, 0xc4, 0x8f, 0xa1, 0x6b, 0xf3, 0xc4, 0x25, 0xa0, 0x73, 0xf7,
+ 0x09, 0xca, 0xd1, 0x75, 0xea, 0x6c, 0xbc, 0x62, 0xa5, 0xa9, 0xaf, 0x65,
+ 0xf1, 0x38, 0x30, 0x97, 0xb5, 0x4b, 0x0a, 0x94, 0x57, 0x9e, 0x7d, 0x2f,
+ 0x5a, 0x32, 0x3d, 0xd7, 0x26, 0x3d, 0xf3, 0x8c, 0xaf, 0xee, 0x6e, 0x91,
+ 0x36, 0xc6, 0x58, 0x69, 0x83, 0x06, 0x24, 0x8f, 0xf2, 0xee, 0xf9, 0xb0,
+ 0x8a, 0x87, 0x55, 0x2c, 0xd2, 0xa8, 0x1f, 0xfa, 0xc0, 0x49, 0x2f, 0x5b,
+ 0xff, 0x25, 0x16, 0x60, 0x48, 0xc8, 0x52, 0x19, 0x32, 0x56, 0x86, 0x8c,
+ 0x95, 0x21, 0x63, 0x65, 0xc8, 0x18, 0xb0, 0xdf, 0x73, 0xd8, 0x7f, 0x17,
+ 0xcb, 0x83, 0xda, 0xae, 0xdf, 0xaf, 0xec, 0xfa, 0x91, 0x32, 0xcf, 0xf0,
+ 0xe9, 0x83, 0x26, 0x95, 0x0e, 0xb9, 0xa4, 0x7c, 0x51, 0xe3, 0xa3, 0xbe,
+ 0x22, 0xcf, 0xcc, 0xbe, 0x2a, 0x67, 0x66, 0x57, 0x71, 0xe0, 0x54, 0xd9,
+ 0x97, 0x97, 0x3d, 0xf8, 0x9f, 0x0b, 0xc4, 0x54, 0xd9, 0xf6, 0x66, 0x85,
+ 0xad, 0x0e, 0x4b, 0x41, 0xe1, 0x64, 0x65, 0x47, 0x80, 0xaf, 0x14, 0x2e,
+ 0xe4, 0xde, 0x94, 0x8e, 0xed, 0xaf, 0xc9, 0x45, 0xd8, 0xf1, 0xc5, 0xfa,
+ 0xeb, 0xf2, 0xbc, 0xc2, 0xe3, 0xa4, 0xc3, 0x07, 0xe4, 0x47, 0x76, 0x70,
+ 0x4e, 0x7c, 0x06, 0x58, 0x63, 0xb1, 0x8f, 0xba, 0x23, 0x02, 0x5b, 0xe0,
+ 0x14, 0xbb, 0xb1, 0xaf, 0x0f, 0x5a, 0x37, 0x00, 0xd3, 0xf0, 0xfd, 0x16,
+ 0x79, 0x71, 0xb6, 0xd8, 0x20, 0x13, 0xd4, 0x0f, 0xce, 0x51, 0xb1, 0x68,
+ 0xa7, 0x68, 0x37, 0xb9, 0x5e, 0xda, 0xa9, 0x3f, 0xd8, 0xcc, 0xb3, 0xd4,
+ 0xea, 0xc9, 0x73, 0x2d, 0x8c, 0x37, 0xc6, 0x5d, 0xd2, 0xf4, 0x35, 0x39,
+ 0x58, 0x63, 0xd9, 0xab, 0xe0, 0x0f, 0xd3, 0xef, 0xf9, 0xf7, 0xc4, 0x39,
+ 0x1e, 0xfb, 0x05, 0x6e, 0xea, 0xc4, 0x5a, 0xcb, 0x7f, 0xa9, 0x63, 0x5e,
+ 0xfd, 0x0a, 0x47, 0xbf, 0x13, 0x2f, 0x9b, 0x7b, 0x0d, 0xaf, 0xa9, 0x78,
+ 0xe0, 0x06, 0x71, 0xe2, 0xa7, 0xb0, 0xaf, 0x8a, 0x57, 0x85, 0x31, 0x4b,
+ 0xc6, 0x73, 0x19, 0x2b, 0x6e, 0xd4, 0x18, 0xea, 0xbc, 0x54, 0xee, 0x86,
+ 0x7e, 0xb9, 0x07, 0xfa, 0xe5, 0xde, 0x77, 0xdc, 0xaf, 0x35, 0x71, 0xfb,
+ 0x9e, 0x62, 0xd8, 0xea, 0x92, 0xb1, 0x5a, 0x63, 0x5b, 0xc6, 0x71, 0x37,
+ 0x8a, 0xdb, 0x32, 0xa6, 0x9b, 0x5e, 0x17, 0x0b, 0xa4, 0x6c, 0xf8, 0xf2,
+ 0x92, 0xc7, 0xb8, 0x9b, 0xb9, 0x9b, 0xbd, 0x11, 0xfe, 0xfa, 0xc3, 0xcd,
+ 0x26, 0xe6, 0x1c, 0xc9, 0x5c, 0x15, 0xde, 0xd1, 0x2e, 0xcd, 0x10, 0x0f,
+ 0xa8, 0xb3, 0x40, 0x15, 0xbb, 0xce, 0x07, 0xf1, 0x03, 0x94, 0xc3, 0xea,
+ 0xc2, 0xdf, 0x61, 0xec, 0xda, 0xde, 0xe1, 0xd8, 0x63, 0xe1, 0xe0, 0xae,
+ 0x1f, 0xf7, 0x72, 0xa0, 0xcb, 0x20, 0x8b, 0xf5, 0xd5, 0x3b, 0x74, 0x43,
+ 0x4a, 0x5f, 0x5c, 0xc5, 0x1e, 0x20, 0xbf, 0xe0, 0x2f, 0x60, 0x9f, 0x4c,
+ 0x41, 0x3f, 0x15, 0x54, 0x7f, 0x31, 0xca, 0x45, 0x36, 0x17, 0xb6, 0x24,
+ 0x7a, 0x8a, 0xbe, 0x50, 0x10, 0x6b, 0xc9, 0x87, 0x1d, 0xa5, 0xbf, 0x31,
+ 0x77, 0xe0, 0x33, 0xee, 0xcf, 0xe4, 0x44, 0x73, 0xa6, 0x09, 0x76, 0x15,
+ 0xfc, 0xab, 0x33, 0x26, 0x80, 0xbd, 0xbb, 0xf4, 0x5d, 0x39, 0x30, 0x77,
+ 0x69, 0x73, 0x20, 0xff, 0x8c, 0x23, 0x73, 0x7d, 0x66, 0x0e, 0x6b, 0xfb,
+ 0xb6, 0x4e, 0x49, 0xac, 0x05, 0x36, 0xed, 0xa3, 0xa7, 0x88, 0x07, 0x9a,
+ 0x65, 0x39, 0xce, 0x7e, 0x83, 0x3d, 0x33, 0x5d, 0x66, 0xdf, 0xdf, 0x95,
+ 0xe1, 0xb9, 0x74, 0x2b, 0xf5, 0xc8, 0x12, 0xf4, 0xc0, 0x65, 0x9b, 0x36,
+ 0x74, 0x1c, 0x36, 0xae, 0x53, 0xde, 0x9c, 0xa3, 0x7d, 0x4c, 0xd9, 0x67,
+ 0x64, 0x5b, 0xe2, 0x0c, 0xe6, 0xf4, 0x84, 0x17, 0xa1, 0x8f, 0xe6, 0x0f,
+ 0xa1, 0xec, 0xeb, 0x92, 0xb2, 0xbb, 0x43, 0x7c, 0xde, 0x66, 0x3f, 0x29,
+ 0xbc, 0x6f, 0x90, 0xb2, 0x6f, 0x0d, 0x51, 0x8e, 0xe0, 0x73, 0x2f, 0xad,
+ 0xce, 0xf3, 0x7b, 0x73, 0xca, 0x4f, 0x52, 0x7a, 0x66, 0xc9, 0xe3, 0x78,
+ 0x97, 0xb4, 0x6e, 0xbb, 0x15, 0xfa, 0x24, 0xa6, 0xcf, 0xc2, 0xd0, 0x86,
+ 0xd8, 0xc6, 0x8b, 0xe8, 0xfc, 0x67, 0x25, 0x77, 0x3a, 0x0e, 0x7d, 0xc6,
+ 0xbe, 0x8c, 0xef, 0x40, 0x1b, 0x69, 0xf0, 0x36, 0xed, 0xdd, 0x2e, 0xd8,
+ 0xbd, 0x9b, 0xd4, 0x7c, 0x46, 0xbc, 0x7e, 0x99, 0x3a, 0xc9, 0xb1, 0xfb,
+ 0xa0, 0xcb, 0x13, 0x4a, 0x6e, 0x4b, 0xe5, 0xcb, 0x89, 0x18, 0x74, 0x72,
+ 0x6c, 0x3b, 0xe9, 0xf9, 0x61, 0xb9, 0xd3, 0x1d, 0x97, 0xbb, 0x20, 0x3b,
+ 0x43, 0xae, 0x27, 0xc3, 0xe0, 0xc5, 0x1e, 0x17, 0x76, 0x47, 0x61, 0xe8,
+ 0x66, 0xf8, 0x5d, 0x1c, 0x9b, 0xf7, 0xc4, 0xd9, 0x36, 0xc0, 0x8f, 0x7f,
+ 0x54, 0x0f, 0x68, 0x94, 0x9b, 0xfb, 0x88, 0xa2, 0xcd, 0x88, 0xb7, 0x53,
+ 0xdb, 0xd9, 0x36, 0xc9, 0xab, 0x7a, 0x3b, 0x95, 0x3d, 0x2e, 0x2d, 0xde,
+ 0x87, 0x14, 0xb6, 0x79, 0x11, 0xfa, 0x06, 0x98, 0xbb, 0x54, 0xdb, 0x81,
+ 0x3c, 0x6c, 0xe8, 0x62, 0x06, 0xe9, 0x87, 0x91, 0xb2, 0x6e, 0xa8, 0x35,
+ 0x88, 0xe5, 0x1a, 0x3c, 0xba, 0x7a, 0xbf, 0xf0, 0xa3, 0x0a, 0x97, 0x5e,
+ 0x55, 0xf7, 0xcb, 0x2c, 0x60, 0x9d, 0x1c, 0xf4, 0x4a, 0x2b, 0x30, 0xd0,
+ 0xcc, 0x29, 0x27, 0x3d, 0x1c, 0xda, 0x2d, 0xbf, 0x06, 0x5f, 0xbe, 0xea,
+ 0x91, 0x97, 0x3b, 0xe4, 0xc1, 0x3b, 0x28, 0x23, 0xbb, 0x65, 0xff, 0x1d,
+ 0x21, 0xd9, 0xdf, 0xef, 0x64, 0x39, 0xef, 0x5b, 0x6e, 0x33, 0xfe, 0x74,
+ 0xcf, 0x48, 0x2a, 0x34, 0x20, 0x4f, 0x42, 0xc6, 0x8a, 0x90, 0xaf, 0xe1,
+ 0x3a, 0x69, 0x4e, 0x7d, 0x4f, 0x3d, 0x9f, 0x06, 0x56, 0x36, 0xd8, 0xcf,
+ 0x95, 0x99, 0x7a, 0x93, 0x24, 0xaf, 0x67, 0x3c, 0x39, 0x19, 0x9c, 0x71,
+ 0x5c, 0x4f, 0x99, 0x80, 0x0f, 0x72, 0x7d, 0xb0, 0x3f, 0xd5, 0xbd, 0x2e,
+ 0xf5, 0x1c, 0xa7, 0xff, 0xeb, 0x13, 0xe7, 0x15, 0x14, 0x5f, 0x68, 0x23,
+ 0x98, 0xfe, 0xbb, 0xd6, 0x15, 0x7c, 0xd7, 0x46, 0xff, 0x61, 0x67, 0xeb,
+ 0xea, 0xbd, 0xf4, 0xf5, 0xb2, 0x68, 0xe2, 0x6e, 0x15, 0xac, 0x99, 0x36,
+ 0xdd, 0xb1, 0xa9, 0x0b, 0xdb, 0xdd, 0xfb, 0xe5, 0x4f, 0x60, 0xdf, 0xbf,
+ 0xb2, 0x62, 0xdf, 0xf7, 0x81, 0x1e, 0xeb, 0x31, 0x80, 0x6b, 0xdf, 0x8d,
+ 0xb5, 0x8c, 0x80, 0x9f, 0x77, 0xe1, 0x77, 0x67, 0x79, 0x4d, 0x1c, 0x6f,
+ 0xb6, 0x08, 0x3c, 0xd9, 0xe4, 0xb2, 0xbf, 0x35, 0xf1, 0xbc, 0x62, 0x41,
+ 0x56, 0x62, 0x85, 0x83, 0xd7, 0x84, 0x76, 0xef, 0x2d, 0x89, 0xf6, 0xba,
+ 0x6f, 0x75, 0x87, 0xdc, 0x17, 0xac, 0x10, 0xcf, 0x95, 0x3d, 0x39, 0x5b,
+ 0x27, 0x0e, 0xbb, 0x22, 0xd6, 0x79, 0x62, 0xb0, 0x6f, 0xa8, 0x18, 0x54,
+ 0xb5, 0xfc, 0x6d, 0xa4, 0xa8, 0x0f, 0xfd, 0x18, 0x0e, 0xe2, 0x14, 0x0a,
+ 0xab, 0x50, 0xcf, 0xde, 0x05, 0x3e, 0x4c, 0xe1, 0xd7, 0xbd, 0xfd, 0x56,
+ 0xec, 0x5f, 0xca, 0x29, 0x63, 0x5f, 0xbd, 0xf6, 0xf6, 0x10, 0xdf, 0x6d,
+ 0x14, 0x07, 0xfb, 0x8e, 0x44, 0x4e, 0xc0, 0xd6, 0x59, 0xd4, 0x0f, 0x5c,
+ 0x07, 0xed, 0xa4, 0x2d, 0x0b, 0x27, 0xb9, 0xd7, 0x37, 0xaa, 0x6f, 0xea,
+ 0x9a, 0xb5, 0x28, 0xbb, 0x91, 0x2d, 0x30, 0xc6, 0x59, 0x26, 0x0f, 0x3c,
+ 0xf0, 0xc0, 0x97, 0x53, 0x5e, 0x3b, 0xf4, 0x76, 0x5c, 0xc2, 0xa7, 0x7c,
+ 0x19, 0x52, 0xd8, 0x75, 0x1b, 0x30, 0xd7, 0x16, 0x8d, 0x1b, 0xe2, 0x12,
+ 0x39, 0xd5, 0x25, 0xcd, 0xc0, 0xd5, 0x4d, 0xc7, 0x68, 0x23, 0x53, 0xc9,
+ 0x21, 0x08, 0x41, 0x44, 0xdd, 0x55, 0x74, 0x06, 0xdf, 0x94, 0x6d, 0xc9,
+ 0x37, 0x85, 0x78, 0xe9, 0x86, 0x2d, 0xf0, 0x09, 0xbc, 0x2b, 0x1b, 0xd4,
+ 0x2f, 0xad, 0xd6, 0x87, 0x1c, 0x31, 0xb6, 0xc6, 0x36, 0x8c, 0xb5, 0xa5,
+ 0x06, 0xdf, 0x60, 0x8c, 0x0d, 0xbe, 0x66, 0xd3, 0xb9, 0x60, 0x0e, 0xd6,
+ 0x52, 0x87, 0x54, 0x4f, 0x73, 0x8f, 0x32, 0xce, 0x62, 0x07, 0x7e, 0x6a,
+ 0x99, 0xfe, 0x2a, 0xdf, 0x27, 0xf5, 0xfb, 0x6e, 0xfd, 0x9e, 0xfe, 0x68,
+ 0xd1, 0x6f, 0x02, 0x4d, 0xf7, 0x40, 0x7f, 0xde, 0xb7, 0xc3, 0x55, 0xb8,
+ 0xe1, 0xbe, 0x15, 0x9e, 0xed, 0x15, 0xeb, 0x38, 0xfc, 0xd4, 0xf2, 0x61,
+ 0x71, 0xb7, 0x2f, 0xa7, 0x23, 0x32, 0x06, 0x5e, 0x30, 0x9f, 0xe5, 0x7c,
+ 0xd2, 0x47, 0xe4, 0xa0, 0xe2, 0x4d, 0xf5, 0xa4, 0x73, 0x34, 0x19, 0x9a,
+ 0x12, 0xab, 0xca, 0xe7, 0x47, 0x90, 0x1e, 0x01, 0xde, 0x09, 0x62, 0x97,
+ 0x56, 0x75, 0x2d, 0x2d, 0x81, 0x31, 0xec, 0x3d, 0x6b, 0xe2, 0x58, 0xab,
+ 0x31, 0x2e, 0xbe, 0x1f, 0x52, 0xef, 0xd3, 0x6b, 0xe2, 0x5c, 0x79, 0x8b,
+ 0x58, 0xc6, 0xbc, 0x27, 0x2f, 0xc8, 0x2f, 0xd8, 0xe2, 0x93, 0x26, 0xe6,
+ 0xd5, 0xa6, 0xf9, 0x42, 0xfe, 0xcc, 0xc8, 0x45, 0xdb, 0x19, 0xa1, 0xfc,
+ 0xfd, 0xea, 0x8e, 0x1b, 0x65, 0xa2, 0x93, 0xf1, 0xb6, 0xc6, 0x39, 0xac,
+ 0x8f, 0xa3, 0x35, 0x8e, 0xbf, 0x3e, 0xfe, 0xc6, 0xb1, 0x83, 0x18, 0x5b,
+ 0x6e, 0x4d, 0x8c, 0xad, 0x71, 0x3c, 0x8e, 0xb5, 0x05, 0xfe, 0x53, 0xd1,
+ 0x8f, 0xbb, 0xe4, 0x51, 0x4f, 0x72, 0x8e, 0xf9, 0x2f, 0x58, 0xe0, 0x63,
+ 0x1c, 0x76, 0x84, 0xbc, 0x34, 0x67, 0xcf, 0xe4, 0x69, 0x2a, 0x79, 0x24,
+ 0xe0, 0xe7, 0x60, 0xc0, 0xf7, 0x80, 0xff, 0x57, 0x56, 0xf8, 0x48, 0xfb,
+ 0x40, 0x3e, 0x76, 0x8a, 0x40, 0xcf, 0x5a, 0xc7, 0xc8, 0x43, 0xa6, 0xe4,
+ 0x21, 0xdf, 0x91, 0x87, 0xdd, 0xfa, 0x1d, 0xf9, 0x07, 0x9c, 0xf6, 0x79,
+ 0x60, 0x0c, 0x2f, 0xa7, 0xbe, 0xb1, 0xe9, 0xee, 0x35, 0x7b, 0x31, 0x2d,
+ 0xcf, 0x2f, 0xb4, 0x88, 0x9d, 0x09, 0xd6, 0x35, 0xbe, 0x26, 0xde, 0xce,
+ 0xf3, 0xab, 0x7e, 0x62, 0x4f, 0xb3, 0xae, 0x04, 0xd7, 0x75, 0x50, 0x5e,
+ 0x93, 0xc2, 0x4c, 0x04, 0x3e, 0x60, 0x1a, 0x38, 0xa7, 0x1f, 0xfa, 0x96,
+ 0xf1, 0x51, 0x94, 0xd5, 0x88, 0x57, 0x68, 0xeb, 0xd2, 0xd8, 0x2b, 0xd4,
+ 0xc1, 0xc4, 0x23, 0xaf, 0x4a, 0xbe, 0x62, 0x74, 0x0c, 0xfa, 0xb7, 0x4c,
+ 0xff, 0xa4, 0x73, 0xf6, 0x96, 0xeb, 0x64, 0x39, 0x79, 0x9d, 0x38, 0xc9,
+ 0x45, 0x59, 0xe5, 0xeb, 0xf8, 0xc6, 0x74, 0xf7, 0xee, 0x0b, 0xaf, 0xca,
+ 0xc6, 0xf8, 0x06, 0xbc, 0x9f, 0x14, 0xf3, 0xde, 0xf0, 0x7e, 0x43, 0x3e,
+ 0x14, 0x5f, 0x11, 0xf2, 0x82, 0x34, 0x20, 0x1e, 0x8e, 0xca, 0xef, 0xc6,
+ 0xb9, 0x1f, 0x8b, 0xea, 0x7c, 0x33, 0x65, 0xf5, 0x2a, 0x9d, 0x31, 0xe4,
+ 0x05, 0xf2, 0x5a, 0xc4, 0x38, 0xb1, 0x9e, 0xdf, 0xf3, 0x87, 0xe2, 0xf0,
+ 0x73, 0x7b, 0xa8, 0x5f, 0xcc, 0x9e, 0x6e, 0x51, 0x7b, 0xfa, 0x09, 0x2f,
+ 0x24, 0x25, 0x37, 0x24, 0x53, 0xee, 0x61, 0x85, 0xf1, 0x7f, 0x03, 0x7d,
+ 0x3d, 0xa8, 0xfb, 0x9a, 0x92, 0x5e, 0xad, 0x7f, 0x0e, 0x41, 0xce, 0x7d,
+ 0xb9, 0xd7, 0xdb, 0x21, 0xbf, 0xda, 0xce, 0x3d, 0x60, 0xd6, 0x7f, 0x58,
+ 0x7a, 0x76, 0x2c, 0x27, 0xe1, 0x19, 0xdc, 0x12, 0x5d, 0xa1, 0x01, 0xf7,
+ 0x99, 0x91, 0xef, 0x80, 0x0e, 0xc1, 0xfa, 0xd7, 0xac, 0x55, 0xaf, 0x93,
+ 0x6b, 0x66, 0x3d, 0xae, 0x35, 0xc0, 0xf2, 0xab, 0x6b, 0x35, 0xf5, 0x5b,
+ 0x21, 0x4b, 0x4e, 0x52, 0x42, 0x8d, 0xb4, 0x59, 0xd1, 0x51, 0x23, 0x8c,
+ 0x91, 0x2c, 0xdb, 0x4e, 0x3a, 0x19, 0x32, 0xb1, 0xe8, 0x00, 0xeb, 0x76,
+ 0x03, 0x87, 0xbb, 0xbd, 0xbd, 0xe9, 0x82, 0x8a, 0x91, 0x5a, 0x6a, 0x5d,
+ 0x53, 0xc0, 0x64, 0x0b, 0xde, 0x2b, 0xfe, 0xa7, 0x81, 0x59, 0x27, 0xe4,
+ 0x61, 0x09, 0xaf, 0x89, 0xe5, 0x22, 0x7f, 0x9e, 0xf1, 0x5c, 0x27, 0x99,
+ 0x05, 0x8f, 0x7f, 0x13, 0x3e, 0x7c, 0x15, 0x7a, 0xff, 0xe3, 0xb4, 0x0d,
+ 0x65, 0xd8, 0x0b, 0xe0, 0x92, 0xaf, 0xbc, 0x27, 0x86, 0x9f, 0x68, 0x88,
+ 0xe5, 0x06, 0xf8, 0xf4, 0xa2, 0xc2, 0xa4, 0xc4, 0xed, 0x47, 0x43, 0x77,
+ 0xf7, 0x85, 0xe1, 0x67, 0x14, 0xfd, 0x98, 0x4b, 0x1c, 0x77, 0x58, 0xee,
+ 0x04, 0x7f, 0xce, 0x2e, 0x14, 0x43, 0x7b, 0xca, 0x46, 0x56, 0xe1, 0x57,
+ 0xd6, 0x9d, 0xf4, 0x65, 0xd0, 0xe3, 0x19, 0x8d, 0xf9, 0x78, 0x5e, 0x53,
+ 0xd5, 0x3e, 0x0b, 0x63, 0x43, 0xa5, 0xfa, 0x61, 0x99, 0xf6, 0x18, 0xdb,
+ 0xe9, 0x91, 0x52, 0x3c, 0x7b, 0x63, 0xf3, 0x0a, 0x8d, 0x1c, 0x1b, 0x3e,
+ 0x5f, 0x9a, 0xfa, 0xbb, 0xaa, 0xcf, 0x3b, 0x9e, 0x51, 0xf2, 0x65, 0xe2,
+ 0xc2, 0xf4, 0x8f, 0x78, 0x5e, 0xd5, 0x63, 0x8f, 0xf0, 0xb9, 0x42, 0x19,
+ 0x50, 0x3e, 0x13, 0x68, 0xf9, 0x90, 0x64, 0xc7, 0x92, 0x0a, 0xb7, 0x3c,
+ 0x5e, 0xe6, 0x7e, 0x21, 0xfe, 0x7f, 0x0d, 0xd8, 0x3f, 0x02, 0x9e, 0xd1,
+ 0x0f, 0xe0, 0xd8, 0xdc, 0x17, 0x28, 0xab, 0xd9, 0xef, 0xb2, 0x2f, 0x5e,
+ 0x6b, 0x23, 0xc6, 0xb8, 0x54, 0x16, 0x45, 0xbf, 0x65, 0x31, 0xb1, 0x73,
+ 0x85, 0x05, 0x8b, 0xb9, 0x70, 0x48, 0x52, 0x27, 0xfe, 0x35, 0x64, 0xe8,
+ 0xd7, 0xe1, 0x23, 0xa9, 0x7a, 0xea, 0xfc, 0x6a, 0x08, 0x98, 0xcb, 0x72,
+ 0x6f, 0x90, 0x92, 0x1d, 0x95, 0x92, 0xba, 0xa3, 0xc9, 0xf3, 0xdc, 0xb0,
+ 0x8a, 0xed, 0x94, 0x6c, 0x62, 0xfe, 0xff, 0xde, 0x16, 0xd8, 0xfa, 0x0e,
+ 0xe4, 0xd9, 0x8e, 0x79, 0x96, 0x4f, 0x49, 0xf4, 0xc4, 0x21, 0x69, 0x3a,
+ 0xf1, 0xb0, 0x34, 0x1f, 0x27, 0xc6, 0x63, 0xec, 0xde, 0xda, 0xd5, 0x2c,
+ 0xc4, 0xdc, 0x43, 0x18, 0xfb, 0xb0, 0x7c, 0xdf, 0x33, 0x73, 0x5a, 0xc4,
+ 0x1c, 0x59, 0xc7, 0xe4, 0x0d, 0x1e, 0xdf, 0x85, 0xf9, 0x70, 0xfd, 0x49,
+ 0x8d, 0xfb, 0x76, 0x35, 0xf8, 0xae, 0x4d, 0xda, 0x77, 0x65, 0xbb, 0x4f,
+ 0x61, 0xad, 0x27, 0x25, 0xea, 0x9a, 0xf6, 0xbb, 0x51, 0x2f, 0xd1, 0x70,
+ 0x07, 0x82, 0x75, 0xf4, 0x9d, 0x80, 0x36, 0xe2, 0x1e, 0x9e, 0xb7, 0xb3,
+ 0x2c, 0x38, 0xf3, 0xb7, 0xaa, 0xbb, 0xc2, 0x6b, 0xc7, 0xdf, 0xd9, 0x50,
+ 0xd7, 0x94, 0x99, 0x36, 0xd1, 0xc0, 0xe7, 0x1f, 0x88, 0x36, 0xb4, 0x83,
+ 0x71, 0x53, 0x69, 0xe0, 0x7b, 0x04, 0x7e, 0x10, 0xd7, 0x90, 0x6e, 0xc0,
+ 0x39, 0x6b, 0xbf, 0x45, 0xcc, 0xa3, 0xbc, 0x30, 0x67, 0xee, 0x91, 0x59,
+ 0x58, 0x8b, 0x53, 0xa4, 0xff, 0x62, 0xf3, 0x4e, 0xee, 0x5c, 0x11, 0xf3,
+ 0xbe, 0x49, 0xdd, 0x25, 0xe2, 0xdd, 0x0d, 0xd4, 0x4b, 0x06, 0xf8, 0x93,
+ 0xf9, 0x04, 0x78, 0x7e, 0x5b, 0x97, 0x95, 0xf9, 0xf3, 0x1b, 0x73, 0x03,
+ 0xc4, 0x37, 0x5b, 0x79, 0x0e, 0x09, 0xdc, 0x4c, 0x39, 0xfb, 0x2e, 0xe4,
+ 0xac, 0x59, 0x9d, 0xfb, 0x94, 0xca, 0xf4, 0xe7, 0x0a, 0x90, 0x1f, 0xde,
+ 0x87, 0xa3, 0xdf, 0x57, 0xd0, 0xf1, 0x58, 0xce, 0x93, 0x98, 0xde, 0xf8,
+ 0x07, 0xec, 0x73, 0xfd, 0x19, 0x6c, 0xe3, 0xfd, 0x12, 0xca, 0x5b, 0x42,
+ 0xcd, 0x79, 0x78, 0x9d, 0xbf, 0x72, 0x04, 0xba, 0x60, 0x01, 0xf2, 0x3c,
+ 0x09, 0x1d, 0x38, 0x14, 0xe6, 0xfe, 0x6c, 0xd1, 0xbe, 0xac, 0x4b, 0xbf,
+ 0x3d, 0x34, 0x86, 0x3e, 0xac, 0xe3, 0xaf, 0xcb, 0x14, 0xf4, 0xff, 0x74,
+ 0x3d, 0xa5, 0xbe, 0x17, 0xc9, 0x26, 0x78, 0x07, 0x8c, 0xe5, 0x63, 0x18,
+ 0xff, 0x75, 0xe0, 0xe1, 0xcd, 0xa0, 0xa7, 0xa5, 0x79, 0xf5, 0x2b, 0x3a,
+ 0x16, 0x15, 0x63, 0x2c, 0x1e, 0x7a, 0xb3, 0x14, 0x60, 0xcd, 0xf8, 0x34,
+ 0xd2, 0xcd, 0x2d, 0x81, 0xbc, 0x4e, 0x6e, 0xd5, 0x77, 0x2f, 0x50, 0xfe,
+ 0x98, 0x8a, 0x41, 0x06, 0x6b, 0x72, 0xb4, 0xaf, 0x12, 0x85, 0xcc, 0x71,
+ 0x5d, 0xf7, 0xa2, 0x1e, 0x65, 0xad, 0x4f, 0x9f, 0xcd, 0xb6, 0x28, 0xfd,
+ 0x98, 0x87, 0x2c, 0x15, 0x94, 0x1f, 0x01, 0x7c, 0xef, 0xb1, 0xdd, 0xaf,
+ 0x6f, 0xe5, 0xd9, 0x67, 0x93, 0xab, 0x7c, 0x8b, 0xce, 0xb0, 0x98, 0xb2,
+ 0x8f, 0xa0, 0x8c, 0x72, 0x76, 0x03, 0x78, 0xc3, 0xb2, 0x1c, 0xf2, 0x1c,
+ 0xeb, 0x46, 0x3d, 0x0e, 0xc7, 0xb8, 0xb4, 0x79, 0xed, 0x9c, 0xb8, 0x96,
+ 0xce, 0x75, 0x77, 0xe7, 0x59, 0x76, 0x83, 0x2e, 0x8b, 0xe8, 0xf5, 0xfd,
+ 0xa9, 0xfe, 0xb6, 0xc1, 0x39, 0x9a, 0x5d, 0xc1, 0xc6, 0x9c, 0x5f, 0x4c,
+ 0xb5, 0xcb, 0xda, 0x81, 0xec, 0x1c, 0x01, 0x3f, 0x22, 0x99, 0xaf, 0xf1,
+ 0x4c, 0x19, 0xf4, 0x35, 0x7b, 0x22, 0xa1, 0xfc, 0xce, 0xa4, 0x15, 0xdc,
+ 0x5d, 0xba, 0x58, 0x6e, 0xf4, 0x19, 0xcc, 0xfd, 0x6f, 0x57, 0xc6, 0x56,
+ 0x78, 0x45, 0xbe, 0x91, 0x5f, 0xef, 0xc6, 0x2b, 0xf2, 0x91, 0xfc, 0x2a,
+ 0x48, 0x69, 0x96, 0x7c, 0xa2, 0xbc, 0x8c, 0x29, 0x79, 0x29, 0x55, 0x0c,
+ 0x4e, 0xa6, 0x2e, 0xe1, 0x37, 0x0f, 0x1b, 0x9d, 0xd7, 0x9b, 0xbb, 0x61,
+ 0xbf, 0x44, 0xfa, 0x85, 0x86, 0xe1, 0x1e, 0x2d, 0xcc, 0x2a, 0x9d, 0x02,
+ 0xbb, 0x98, 0x50, 0xba, 0xa2, 0x30, 0xce, 0xfc, 0xd2, 0x56, 0x7e, 0x9b,
+ 0x8b, 0x79, 0xa0, 0xbc, 0x53, 0xf3, 0xf5, 0x06, 0x75, 0xbf, 0x89, 0x7b,
+ 0xb0, 0x54, 0xa9, 0xab, 0xf7, 0x67, 0xe7, 0x9a, 0x54, 0xfd, 0xb3, 0x73,
+ 0xeb, 0xef, 0x28, 0xb1, 0xec, 0x66, 0xc6, 0x55, 0x64, 0x71, 0xa6, 0x49,
+ 0x96, 0xe6, 0xfe, 0x90, 0x7e, 0x22, 0x8c, 0xc1, 0xca, 0xf7, 0x1d, 0xfa,
+ 0x5b, 0x2c, 0x5f, 0x86, 0x21, 0x37, 0x0b, 0x83, 0xd3, 0x52, 0x1d, 0xa4,
+ 0x1f, 0xa4, 0xee, 0x0e, 0x62, 0xbd, 0x4d, 0xc0, 0xc0, 0xc0, 0x85, 0x2e,
+ 0xe3, 0xcf, 0x5b, 0xb4, 0x3e, 0x79, 0xb0, 0x75, 0x25, 0x2e, 0x1d, 0x2f,
+ 0xfa, 0x55, 0xd7, 0x7c, 0x33, 0xc3, 0x3e, 0xf9, 0xdd, 0x0c, 0x79, 0x66,
+ 0xa1, 0x3d, 0xef, 0x64, 0x76, 0x33, 0xae, 0xad, 0xf9, 0x1c, 0x46, 0x7d,
+ 0xa6, 0xbf, 0xa7, 0xf3, 0x73, 0x3a, 0xfd, 0xac, 0xec, 0x3f, 0xf9, 0x19,
+ 0xcc, 0x7b, 0x53, 0x70, 0xef, 0x4a, 0x1a, 0xbf, 0x9b, 0x88, 0xe8, 0x6f,
+ 0x34, 0x3e, 0x8b, 0x32, 0xc6, 0xe2, 0x3e, 0xab, 0xd6, 0xc4, 0xbb, 0x7d,
+ 0x45, 0xf9, 0x79, 0x77, 0x54, 0x8c, 0x3f, 0xc8, 0xfb, 0x53, 0x2d, 0xba,
+ 0xbf, 0x3d, 0x5a, 0x96, 0xc6, 0x65, 0x3f, 0xec, 0x5d, 0x01, 0xb8, 0x98,
+ 0x77, 0xce, 0x26, 0xc2, 0x8d, 0x63, 0x9a, 0xfd, 0x14, 0xc4, 0x1a, 0xcc,
+ 0xdd, 0x87, 0xb0, 0xf2, 0x89, 0x56, 0xe2, 0x16, 0xba, 0x7c, 0x5c, 0x0e,
+ 0x94, 0x55, 0xfc, 0x42, 0x9d, 0x59, 0x4e, 0x43, 0x2f, 0x0c, 0x29, 0x9b,
+ 0x16, 0x0b, 0x0d, 0xd7, 0x32, 0x52, 0x38, 0xbd, 0x17, 0xe3, 0x30, 0x16,
+ 0x98, 0xd5, 0x67, 0x83, 0xfb, 0x64, 0x7f, 0x3d, 0x18, 0x7b, 0xb2, 0xcc,
+ 0xf7, 0x29, 0xe0, 0x04, 0xbe, 0xcf, 0x27, 0xc2, 0xea, 0x74, 0xe3, 0x56,
+ 0xb4, 0x6d, 0xd2, 0x74, 0xe6, 0xbd, 0x6b, 0xb6, 0xa7, 0x0e, 0x00, 0xc0,
+ 0x69, 0xc9, 0xe3, 0x3d, 0xdb, 0x98, 0xfe, 0x26, 0x61, 0xb7, 0xe8, 0x9f,
+ 0x3f, 0x2a, 0xcb, 0x95, 0x69, 0xb9, 0x5c, 0x31, 0xb2, 0xce, 0xbb, 0xd7,
+ 0x9c, 0xfb, 0x5d, 0xc1, 0xb7, 0xbf, 0xe5, 0x2c, 0xf8, 0xb3, 0x96, 0x56,
+ 0xf9, 0x35, 0xdf, 0xdb, 0xfc, 0x2b, 0x3b, 0xf8, 0xe6, 0x6d, 0xb7, 0xba,
+ 0xc3, 0xb5, 0x76, 0xcf, 0xb1, 0x9f, 0xfd, 0x36, 0xcf, 0x3a, 0x82, 0x7b,
+ 0x68, 0x9d, 0x0d, 0xef, 0xe3, 0xfa, 0xee, 0xd7, 0xa7, 0xec, 0x80, 0x8f,
+ 0xa4, 0xe7, 0x98, 0x9e, 0xef, 0xad, 0xd8, 0xff, 0xec, 0xf3, 0x31, 0xcd,
+ 0x37, 0xa4, 0x0b, 0x7c, 0xe6, 0xfe, 0x5a, 0xd6, 0xe7, 0xbf, 0xb6, 0x1e,
+ 0xa3, 0xf1, 0xee, 0x5d, 0x53, 0xc3, 0xb8, 0x6c, 0x4f, 0xfb, 0x64, 0xee,
+ 0x80, 0xb3, 0xec, 0xa4, 0xbe, 0xe3, 0x77, 0xb5, 0xa1, 0xcc, 0xdc, 0x45,
+ 0x23, 0xbd, 0x18, 0xd3, 0x44, 0x5a, 0x1f, 0xd3, 0xcf, 0x63, 0x0d, 0xdf,
+ 0xc8, 0x98, 0x3e, 0x23, 0xe8, 0xc3, 0xdc, 0x41, 0x6f, 0xbc, 0x53, 0xcc,
+ 0xef, 0x83, 0x28, 0x8b, 0x16, 0xbf, 0x61, 0xa6, 0x1f, 0x08, 0xec, 0xb6,
+ 0x45, 0x26, 0xd5, 0x7c, 0x8a, 0xea, 0xbe, 0x06, 0xbf, 0x9b, 0x19, 0xb2,
+ 0x83, 0xfc, 0xe4, 0xc2, 0x7a, 0x39, 0x65, 0xf9, 0x33, 0xcd, 0xd2, 0x52,
+ 0xc4, 0x38, 0x7c, 0xbf, 0xd1, 0xf7, 0xf4, 0x51, 0xfd, 0x9d, 0x90, 0x87,
+ 0x36, 0x4f, 0x50, 0xde, 0x8b, 0xc5, 0x95, 0x7b, 0xa2, 0xc5, 0xe0, 0x1b,
+ 0x26, 0xcb, 0xdc, 0xd7, 0xe4, 0x37, 0xda, 0x22, 0x17, 0x6a, 0xfc, 0x3e,
+ 0x69, 0xb7, 0xba, 0x47, 0x13, 0x9c, 0x4d, 0x72, 0x5e, 0x3d, 0xca, 0x2e,
+ 0x54, 0x6b, 0x25, 0xd2, 0x54, 0xdb, 0xf6, 0xa8, 0xb6, 0xed, 0xa4, 0xf1,
+ 0x08, 0x68, 0xfc, 0x25, 0xcd, 0x17, 0xb6, 0xcf, 0xaa, 0xfb, 0xdd, 0xd9,
+ 0x38, 0xcf, 0xc7, 0x1e, 0x53, 0x6b, 0xa1, 0x9d, 0x40, 0xdb, 0x5f, 0x0e,
+ 0xab, 0x78, 0xa7, 0xfa, 0x06, 0x1c, 0xf2, 0xc9, 0x6f, 0xba, 0xa1, 0xe3,
+ 0xcb, 0xfc, 0x76, 0x7b, 0x04, 0x29, 0xbf, 0xd9, 0xde, 0xab, 0xee, 0xff,
+ 0x57, 0xd5, 0x37, 0x01, 0x46, 0x1e, 0xc3, 0x7a, 0xac, 0x6f, 0x62, 0x8c,
+ 0x80, 0xef, 0x85, 0x32, 0xbf, 0xe5, 0x36, 0x77, 0x4c, 0x37, 0x2f, 0x73,
+ 0x4f, 0x88, 0xf2, 0xf3, 0x83, 0x6f, 0xfb, 0xab, 0xea, 0x3b, 0x82, 0x24,
+ 0xbf, 0x2b, 0x84, 0xfd, 0xba, 0x1f, 0xcf, 0x3c, 0x57, 0xde, 0x87, 0x14,
+ 0xfa, 0xa7, 0x36, 0x81, 0xf4, 0x61, 0xc9, 0xab, 0xb8, 0x5f, 0x2b, 0xf2,
+ 0x93, 0x6a, 0xec, 0x52, 0xed, 0x13, 0xb2, 0xff, 0xf4, 0x43, 0xfc, 0x5e,
+ 0x42, 0x7d, 0x77, 0x9e, 0xf3, 0x38, 0xc7, 0xb8, 0x4c, 0xa9, 0x75, 0x17,
+ 0x35, 0xed, 0xcd, 0x59, 0xcc, 0xcf, 0xd4, 0xb7, 0x19, 0xc5, 0x5a, 0x2b,
+ 0xe6, 0x18, 0xd2, 0xf7, 0x4c, 0xe9, 0x0f, 0x98, 0xf5, 0xb7, 0xf0, 0xee,
+ 0xa2, 0xcf, 0xf3, 0xc3, 0xfd, 0x65, 0xde, 0x23, 0x4d, 0xe9, 0x38, 0x01,
+ 0x63, 0x87, 0x3c, 0x9f, 0xa0, 0x8c, 0x3b, 0xe9, 0x09, 0x58, 0xa0, 0xa8,
+ 0x24, 0x78, 0xb6, 0xad, 0xd7, 0xd2, 0xda, 0xb0, 0x16, 0xde, 0x9d, 0x0d,
+ 0xd6, 0xc3, 0xef, 0x21, 0x0a, 0xe5, 0xc6, 0x6f, 0x2a, 0xd4, 0x37, 0xd0,
+ 0xfc, 0x76, 0x46, 0x26, 0x6a, 0x9f, 0x94, 0x07, 0xca, 0x5b, 0xf4, 0xf7,
+ 0x14, 0x31, 0x79, 0xa0, 0xf6, 0xba, 0xa2, 0x69, 0x41, 0x7d, 0xd7, 0x11,
+ 0xd5, 0x3c, 0x33, 0xdf, 0x54, 0x04, 0xfd, 0x1d, 0xa8, 0x39, 0x0d, 0xdf,
+ 0x2f, 0x44, 0x65, 0x62, 0xe1, 0x47, 0x91, 0x8d, 0xbf, 0x61, 0x78, 0x54,
+ 0x72, 0xa7, 0x69, 0xa3, 0xa7, 0xe5, 0xf1, 0x8a, 0xef, 0xdf, 0xe9, 0x11,
+ 0x5b, 0x6e, 0x96, 0xcb, 0xf1, 0xb1, 0x3d, 0x6f, 0xb8, 0x1d, 0xa1, 0xea,
+ 0x6c, 0x33, 0x74, 0x2f, 0xf1, 0x8c, 0xb4, 0x30, 0xbf, 0x30, 0xcb, 0x7d,
+ 0x1a, 0xc1, 0x1a, 0x1d, 0xfb, 0x9a, 0xdc, 0xde, 0xce, 0xb8, 0xdb, 0x9d,
+ 0xf0, 0x65, 0x7f, 0xdb, 0x0b, 0xf4, 0xf5, 0xe7, 0x16, 0xf7, 0xca, 0xe7,
+ 0x6a, 0xb1, 0x50, 0x75, 0x86, 0xf7, 0x0d, 0x9d, 0x91, 0x8a, 0xa4, 0x50,
+ 0x8f, 0xfd, 0x43, 0x5e, 0x12, 0xd7, 0xc9, 0xb3, 0x27, 0x7f, 0xea, 0x5f,
+ 0x73, 0xf1, 0x1e, 0xba, 0xe6, 0xb2, 0x67, 0x62, 0x8b, 0x63, 0xf0, 0x5d,
+ 0x59, 0xef, 0x3a, 0xc8, 0x01, 0xb0, 0x03, 0xf6, 0x1c, 0xfd, 0xdc, 0x6b,
+ 0x5a, 0x6f, 0x59, 0xc7, 0x6e, 0x92, 0x6b, 0x2b, 0xf7, 0x95, 0x5f, 0x83,
+ 0x6c, 0x27, 0x03, 0xfa, 0xab, 0x58, 0xfc, 0x21, 0x09, 0x7f, 0x1e, 0x36,
+ 0xe5, 0xf3, 0x4d, 0x4a, 0xb7, 0xd3, 0xb6, 0xc1, 0x07, 0x82, 0x9f, 0x13,
+ 0x41, 0x3f, 0xa9, 0xf6, 0x40, 0x66, 0xa7, 0x45, 0xbe, 0xb0, 0x49, 0xb2,
+ 0xed, 0xf4, 0xa3, 0xe5, 0xe7, 0xe8, 0xaf, 0xc6, 0x7d, 0x96, 0x96, 0x3f,
+ 0xe2, 0x1e, 0xaf, 0x73, 0x2d, 0xa9, 0xc4, 0x9f, 0xc9, 0xa7, 0x65, 0x22,
+ 0xc1, 0xb5, 0x3c, 0x2a, 0xc5, 0xca, 0x63, 0xf8, 0x71, 0x9d, 0x9c, 0xf7,
+ 0xc7, 0xf4, 0x5d, 0x86, 0x31, 0x29, 0xcd, 0x64, 0x64, 0x6a, 0x6e, 0x92,
+ 0xdf, 0xa0, 0x8e, 0xdc, 0xa9, 0xce, 0xf8, 0x9c, 0x44, 0x2a, 0xb4, 0x2d,
+ 0x39, 0xc5, 0xbb, 0x1b, 0x6a, 0x3d, 0x93, 0x58, 0xcf, 0xe3, 0xed, 0xbc,
+ 0xb3, 0x7e, 0x0d, 0xfa, 0xd7, 0x3a, 0x45, 0x39, 0x74, 0xec, 0xee, 0x10,
+ 0xf3, 0xfb, 0xe0, 0xbf, 0xb3, 0x6c, 0x9f, 0x84, 0x8f, 0xad, 0xe8, 0x79,
+ 0x94, 0xeb, 0xb3, 0x66, 0xd5, 0xfe, 0x14, 0xda, 0xa2, 0xde, 0x31, 0xd3,
+ 0xd6, 0xd4, 0x61, 0x5b, 0xae, 0x73, 0xaf, 0x34, 0x9f, 0x33, 0xf3, 0x82,
+ 0x1c, 0x26, 0x1a, 0xe9, 0xdd, 0xb2, 0x8e, 0xde, 0x11, 0x62, 0x5e, 0xd0,
+ 0x8b, 0x34, 0x0e, 0x6b, 0x1a, 0x7f, 0x05, 0xfd, 0x1b, 0x1e, 0xdc, 0x89,
+ 0x32, 0x5b, 0x7f, 0x93, 0xf4, 0x7e, 0xe8, 0x4e, 0x9a, 0xb3, 0x3e, 0xe9,
+ 0x4e, 0xd9, 0xe2, 0x7c, 0x36, 0xa2, 0xf9, 0xeb, 0x9a, 0x2f, 0xfb, 0x40,
+ 0x2f, 0xde, 0x2b, 0xdd, 0xa6, 0xbe, 0x2f, 0xc8, 0x8e, 0xef, 0x83, 0xec,
+ 0x98, 0x75, 0x6d, 0x83, 0x8c, 0xf1, 0xdc, 0x84, 0xf5, 0x1b, 0x69, 0x12,
+ 0xd8, 0xbd, 0x30, 0x63, 0x1f, 0x2e, 0xd7, 0x0a, 0x5c, 0xfa, 0x05, 0xda,
+ 0x28, 0x7e, 0x63, 0x7d, 0xb3, 0xb6, 0x51, 0x3f, 0x8f, 0xc7, 0x3f, 0x6a,
+ 0x0f, 0x6c, 0x94, 0x0d, 0x9a, 0xb4, 0xe9, 0x36, 0xfb, 0x80, 0x91, 0x19,
+ 0x0f, 0x4e, 0x25, 0x1e, 0x14, 0x33, 0x8e, 0xbf, 0x9b, 0x7e, 0xef, 0xd0,
+ 0xc0, 0x36, 0xa0, 0x16, 0x75, 0x67, 0x27, 0xc1, 0x3b, 0x40, 0xa9, 0xd0,
+ 0x3e, 0x75, 0x7f, 0x63, 0xed, 0xf7, 0x23, 0x69, 0x79, 0x76, 0x55, 0x56,
+ 0x46, 0x7e, 0x28, 0x8e, 0x24, 0x6f, 0xa4, 0xac, 0xb0, 0xdf, 0x49, 0xae,
+ 0x33, 0xf1, 0x90, 0x5a, 0xa7, 0x0d, 0x3f, 0x92, 0x77, 0x2d, 0xec, 0x50,
+ 0x75, 0x8e, 0x7c, 0x47, 0xba, 0xc8, 0x67, 0x73, 0xde, 0xab, 0xf4, 0x0a,
+ 0xc6, 0x65, 0x19, 0x75, 0x23, 0xdf, 0x67, 0xf4, 0x79, 0x70, 0x7b, 0x07,
+ 0xef, 0x24, 0x14, 0x50, 0x56, 0x59, 0xdc, 0x78, 0x6e, 0xbf, 0xad, 0xe4,
+ 0xe0, 0x51, 0xd0, 0xfd, 0x9f, 0xa1, 0xee, 0x63, 0x48, 0xb9, 0xc6, 0xcc,
+ 0x0a, 0xdf, 0x49, 0xef, 0x8f, 0xca, 0x20, 0xe4, 0x82, 0xf9, 0x47, 0x81,
+ 0x37, 0x69, 0x4f, 0x91, 0x56, 0xf8, 0x4c, 0x5d, 0xef, 0x6a, 0x7b, 0xca,
+ 0xb9, 0xec, 0xc3, 0x5c, 0xd4, 0x3a, 0xb5, 0x3c, 0xdd, 0xaf, 0xdb, 0x8d,
+ 0xaf, 0xd0, 0xea, 0xa1, 0x77, 0xe0, 0x8d, 0xe8, 0x0a, 0xde, 0x08, 0xc6,
+ 0xca, 0x76, 0x18, 0xac, 0x11, 0xac, 0x21, 0xc0, 0x1a, 0x81, 0x9c, 0x4f,
+ 0x4a, 0x04, 0x72, 0x1c, 0x5e, 0x95, 0x63, 0xe0, 0x9e, 0x60, 0xcf, 0x4c,
+ 0xf1, 0x1c, 0x53, 0xd1, 0x99, 0x72, 0x48, 0xf9, 0x25, 0x1f, 0x1b, 0x79,
+ 0x7d, 0xfb, 0xbb, 0xf0, 0xba, 0xd4, 0x61, 0xf0, 0xc3, 0x3f, 0x6c, 0x1f,
+ 0x3c, 0xd2, 0xb1, 0xba, 0x0f, 0x6e, 0xfa, 0x05, 0xed, 0x83, 0xf5, 0x72,
+ 0xd9, 0x28, 0x53, 0x36, 0xe4, 0x89, 0xfc, 0xa2, 0x3c, 0x51, 0x8e, 0x48,
+ 0x4b, 0xea, 0xd3, 0x66, 0xfa, 0x6f, 0x89, 0xab, 0xea, 0xdb, 0x91, 0x69,
+ 0xe8, 0xa0, 0x8e, 0x50, 0xa5, 0x12, 0x97, 0xd2, 0xe2, 0x4f, 0x94, 0x4c,
+ 0x3f, 0x5b, 0xa7, 0x5e, 0x7a, 0xaf, 0xb5, 0xaf, 0xd5, 0xb9, 0x85, 0x75,
+ 0x3a, 0xb7, 0xb0, 0xa2, 0x73, 0xdb, 0xb5, 0xcf, 0xf6, 0x0f, 0xd1, 0xb9,
+ 0xf1, 0x86, 0xb3, 0x21, 0x73, 0x2e, 0x24, 0xa1, 0x5c, 0x5f, 0x8b, 0xec,
+ 0x81, 0x1d, 0x19, 0x99, 0xd9, 0x2b, 0x7f, 0x30, 0x33, 0xad, 0xee, 0x49,
+ 0x7d, 0xd3, 0x4b, 0x25, 0x3e, 0x11, 0xf2, 0xe5, 0xa3, 0xf0, 0xb9, 0x27,
+ 0xba, 0x9a, 0x64, 0xcf, 0x6d, 0xea, 0xbc, 0xd3, 0xce, 0x85, 0x3a, 0x85,
+ 0x91, 0xf8, 0xbc, 0xe7, 0x78, 0xc9, 0x10, 0xef, 0xcc, 0x35, 0xcb, 0x44,
+ 0xbc, 0x55, 0xf6, 0x02, 0x3b, 0x15, 0xaf, 0xf7, 0xd4, 0x37, 0xd3, 0x59,
+ 0x75, 0x9e, 0xf4, 0x86, 0xe6, 0x3b, 0xe8, 0xd0, 0x66, 0xcb, 0x7f, 0xac,
+ 0x33, 0xcf, 0xf2, 0x07, 0xd7, 0xe5, 0xf9, 0xfc, 0x04, 0xfc, 0xb9, 0x38,
+ 0x68, 0xd5, 0x78, 0xff, 0x28, 0xac, 0xe8, 0x59, 0xaa, 0x8c, 0xab, 0x7b,
+ 0x5d, 0x57, 0xc3, 0xa4, 0x97, 0xf2, 0xa1, 0x12, 0xb9, 0x30, 0x30, 0xce,
+ 0x2c, 0x90, 0xb4, 0x4b, 0xbf, 0x53, 0xe3, 0x4f, 0xe8, 0xff, 0xfd, 0xea,
+ 0x7c, 0x79, 0x19, 0xb4, 0xf1, 0x55, 0xfc, 0xb9, 0x10, 0x27, 0xae, 0x5f,
+ 0xbd, 0xc3, 0xfc, 0x4e, 0x7c, 0xaf, 0xb0, 0xbd, 0x39, 0x0b, 0xd1, 0xf1,
+ 0x2a, 0x1d, 0x07, 0x50, 0x67, 0x7b, 0x1b, 0xfd, 0xbf, 0x0b, 0xc4, 0x7a,
+ 0xfc, 0xae, 0x9f, 0xd8, 0xce, 0x39, 0x5a, 0x91, 0x1f, 0x2a, 0x5f, 0x34,
+ 0x4b, 0xfa, 0x56, 0xc1, 0xa7, 0xe3, 0x09, 0x63, 0xcf, 0x43, 0xdd, 0xe7,
+ 0x1b, 0x7d, 0x51, 0xf6, 0x11, 0x53, 0x77, 0x42, 0x56, 0xff, 0x9f, 0x17,
+ 0xc6, 0x98, 0xb2, 0xa1, 0xbb, 0xcb, 0xd3, 0x12, 0x3e, 0x31, 0x26, 0x91,
+ 0xe3, 0x8c, 0xe7, 0x67, 0xa5, 0x14, 0xf7, 0xe5, 0x01, 0x6f, 0xad, 0x6f,
+ 0xd2, 0x6d, 0xad, 0x9f, 0xfb, 0xa3, 0x32, 0x74, 0xfa, 0x31, 0x89, 0x9e,
+ 0xe0, 0xbb, 0x35, 0x67, 0x39, 0xd0, 0x47, 0x9b, 0xa5, 0x12, 0x67, 0x4c,
+ 0x3b, 0xaa, 0xce, 0xc6, 0x2f, 0x8f, 0xbf, 0x1e, 0x2d, 0x01, 0x2b, 0x14,
+ 0x94, 0x6e, 0x41, 0xba, 0xe2, 0x4b, 0xe4, 0xae, 0xe3, 0x9e, 0x82, 0xbf,
+ 0x19, 0x9a, 0xa8, 0x44, 0xd5, 0x1d, 0xa5, 0xcb, 0x71, 0xd6, 0x7d, 0x0c,
+ 0x7e, 0x37, 0x71, 0x06, 0x74, 0xc7, 0x98, 0xb4, 0x30, 0x1f, 0x3e, 0xb1,
+ 0x8a, 0x33, 0xa8, 0x13, 0x86, 0xbc, 0xb8, 0x44, 0xce, 0x04, 0x6b, 0xe7,
+ 0x7f, 0x1c, 0x64, 0xcd, 0xef, 0x95, 0xf0, 0x71, 0x3e, 0x37, 0xfa, 0x43,
+ 0xc4, 0xee, 0xb0, 0x0d, 0xe7, 0x7f, 0x1f, 0xfd, 0xf1, 0x5d, 0x56, 0x7f,
+ 0x87, 0x8b, 0x7c, 0xf5, 0xef, 0xfa, 0x7f, 0x04, 0x50, 0xf6, 0xff, 0x3f,
+ 0xc3, 0x8e, 0xbb, 0xb0, 0xa8, 0x4d, 0x00, 0x00, 0x00 };
static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = {
- 0x08000e7c, 0x08000ec4, 0x08000ef8, 0x08000f44, 0x08000f78, 0x00000000
+ 0x08000e7c, 0x08000ec4, 0x08000f04, 0x08000f50, 0x08000f84, 0x00000000
};
static struct fw_info bnx2_com_fw_06 = {
- /* Firmware version: 4.4.2 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x2,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x080000f8,
.text_addr = 0x08000000,
- .text_len = 0x4ebc,
+ .text_len = 0x4da4,
.text_index = 0x0,
.gz_text = bnx2_COM_b06FwText,
.gz_text_len = sizeof(bnx2_COM_b06FwText),
@@ -872,15 +867,15 @@ static struct fw_info bnx2_com_fw_06 = {
.data_index = 0x0,
.data = bnx2_COM_b06FwData,
- .sbss_addr = 0x08004f00,
+ .sbss_addr = 0x08004de0,
.sbss_len = 0x38,
.sbss_index = 0x0,
- .bss_addr = 0x08004f38,
+ .bss_addr = 0x08004e18,
.bss_len = 0xbc,
.bss_index = 0x0,
- .rodata_addr = 0x08004ebc,
+ .rodata_addr = 0x08004da4,
.rodata_len = 0x14,
.rodata_index = 0x0,
.rodata = bnx2_COM_b06FwRodata,
@@ -903,1232 +898,1219 @@ static const struct cpu_reg cpu_reg_com = {
};
static u8 bnx2_CP_b06FwText[] = {
- 0x9d, 0xbc, 0x0d, 0x78, 0x1b, 0xe5, 0x95, 0x36, 0x7c, 0xcf, 0x48, 0xb2,
- 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x9c, 0x28, 0x6c, 0x9a, 0x68, 0xf0, 0x28,
- 0x51, 0xb0, 0x69, 0x47, 0x89, 0x03, 0x82, 0x55, 0x89, 0xea, 0x98, 0xc4,
- 0x81, 0x50, 0x9c, 0x12, 0x5a, 0xb3, 0x4b, 0x5b, 0xe1, 0xfc, 0x60, 0x42,
- 0xa0, 0xa1, 0xb0, 0xef, 0x9a, 0xef, 0x65, 0x5f, 0xab, 0xb6, 0x93, 0x38,
- 0x89, 0x2c, 0x39, 0x8e, 0x21, 0x61, 0xbf, 0x5e, 0x8b, 0x89, 0x9d, 0x38,
- 0x80, 0x6c, 0x85, 0x36, 0xdd, 0x0d, 0x7d, 0xd3, 0x8d, 0x36, 0x09, 0x60,
- 0xfe, 0xda, 0x40, 0xbb, 0x2c, 0xed, 0xcb, 0x07, 0xde, 0x14, 0x42, 0xd8,
- 0xb6, 0x40, 0xb7, 0x3f, 0x1b, 0x5a, 0xca, 0xbc, 0xf7, 0x19, 0x49, 0x89,
- 0x13, 0x28, 0xed, 0x7e, 0xbe, 0xae, 0xb9, 0xac, 0x99, 0x79, 0x7e, 0xce,
- 0x73, 0x9e, 0x73, 0xee, 0x73, 0x9f, 0x67, 0x9e, 0x19, 0x3f, 0x50, 0x8a,
- 0xfc, 0x5f, 0x39, 0x8f, 0x4f, 0x37, 0x6c, 0x5c, 0xbd, 0x60, 0xc1, 0xa7,
- 0x1b, 0xe4, 0xdc, 0x39, 0xdd, 0xe9, 0xc4, 0x9f, 0xf9, 0xe7, 0xff, 0x73,
- 0x0b, 0x7e, 0xcc, 0x9f, 0x03, 0xd0, 0x0a, 0xfd, 0xcb, 0x01, 0xb7, 0x1a,
- 0x71, 0xde, 0xdc, 0x68, 0xc0, 0xed, 0x88, 0x4c, 0xb4, 0xad, 0x36, 0x80,
- 0x68, 0xba, 0xce, 0xbf, 0x04, 0x7f, 0xb0, 0xe2, 0x5e, 0x27, 0xe4, 0xfa,
- 0xa7, 0x22, 0x1f, 0x74, 0x7e, 0xef, 0x72, 0xfd, 0xbd, 0x21, 0x07, 0xdc,
- 0x5a, 0x24, 0x0e, 0x6d, 0x2e, 0xdc, 0xb3, 0x58, 0xe7, 0x9b, 0xf3, 0xbe,
- 0xa9, 0xa0, 0xa2, 0xd0, 0xd6, 0x69, 0xeb, 0x7b, 0xf3, 0x7c, 0xb1, 0x92,
- 0x88, 0x86, 0x23, 0x19, 0xb4, 0xd4, 0xf7, 0x75, 0x5a, 0xe5, 0x46, 0x08,
- 0x6e, 0xc3, 0x68, 0xed, 0x53, 0x3c, 0xe1, 0xf5, 0x8b, 0xe0, 0x29, 0x36,
- 0x10, 0xbf, 0x28, 0x82, 0x96, 0x4b, 0xc6, 0x4a, 0xe3, 0xce, 0x88, 0x1b,
- 0xcd, 0x19, 0x77, 0xfc, 0x2f, 0x22, 0x06, 0x96, 0x65, 0x66, 0x95, 0xa2,
- 0xc2, 0x8d, 0x9e, 0xcc, 0xeb, 0x25, 0xb9, 0xf6, 0xea, 0xf3, 0xff, 0x83,
- 0xd3, 0x72, 0xff, 0xa7, 0xc7, 0x9c, 0x11, 0x60, 0x53, 0xc2, 0xb2, 0x8a,
- 0x22, 0x37, 0xdc, 0xa0, 0x46, 0x0c, 0xdf, 0x3e, 0x2c, 0x46, 0x9b, 0x86,
- 0xfb, 0x36, 0x37, 0xfc, 0xa7, 0x72, 0x74, 0x90, 0x0d, 0x8f, 0x3a, 0x10,
- 0xd5, 0x8e, 0xf3, 0xff, 0xec, 0xd9, 0xad, 0x61, 0x03, 0xbb, 0x47, 0xcf,
- 0xf0, 0xba, 0xd3, 0xbe, 0xd6, 0xbd, 0x6b, 0xf6, 0xec, 0x9b, 0xc2, 0xc7,
- 0xf1, 0xe0, 0xa8, 0xfc, 0xbe, 0x15, 0x9d, 0xf5, 0x0a, 0x26, 0x6f, 0x58,
- 0x07, 0x87, 0x61, 0xa0, 0x67, 0x97, 0xe2, 0xec, 0xaa, 0x57, 0x11, 0xf5,
- 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20, 0x56, 0x1c, 0x09, 0x3b, 0xdf,
- 0x4e, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1, 0xd0, 0x0c, 0x38, 0xaa, 0x2c,
- 0xeb, 0x09, 0xd3, 0x03, 0xff, 0x97, 0x9e, 0x42, 0x7c, 0xb8, 0x05, 0xaa,
- 0xf1, 0x14, 0xba, 0x86, 0x9f, 0xc2, 0x43, 0x3b, 0x4b, 0x31, 0x39, 0x8d,
- 0xe3, 0x4d, 0xf9, 0xf0, 0xbd, 0x79, 0xd2, 0xb7, 0xc8, 0x51, 0xcf, 0xc3,
- 0x8d, 0x49, 0xc7, 0x6b, 0xfc, 0x2f, 0x65, 0xce, 0x58, 0x93, 0x33, 0xce,
- 0x95, 0xd9, 0xc4, 0x32, 0x3d, 0x17, 0x94, 0x89, 0x0f, 0x47, 0xf0, 0x5c,
- 0x42, 0xc1, 0xfa, 0x50, 0x05, 0xa2, 0x55, 0x32, 0x5e, 0xcb, 0x1a, 0x35,
- 0x4f, 0x59, 0x93, 0x9a, 0xf4, 0x35, 0x81, 0xe7, 0x79, 0x6f, 0x73, 0xe8,
- 0x0d, 0x2b, 0xeb, 0x95, 0xf6, 0xbe, 0x4e, 0x1b, 0x5a, 0xc9, 0xeb, 0x4e,
- 0xa4, 0x12, 0x88, 0x55, 0x44, 0x6e, 0xe4, 0xb9, 0x6e, 0xbe, 0xa3, 0xb8,
- 0xdd, 0xef, 0x26, 0xdc, 0x5f, 0x2a, 0x37, 0xd4, 0x7b, 0x2a, 0xe1, 0xc4,
- 0x0b, 0x94, 0xf9, 0x90, 0xb9, 0x0e, 0x2e, 0xe3, 0x6e, 0xb1, 0x39, 0x8e,
- 0xeb, 0x47, 0x16, 0x66, 0x14, 0xea, 0x4b, 0xbb, 0x6e, 0x6c, 0x4e, 0x59,
- 0xd6, 0x56, 0x33, 0x7a, 0x45, 0x09, 0x0d, 0xe2, 0x58, 0xa2, 0x05, 0xee,
- 0x48, 0xc0, 0x7f, 0x1a, 0x61, 0x2c, 0xc9, 0x78, 0xf1, 0x64, 0x02, 0xce,
- 0xc6, 0x79, 0x5e, 0x74, 0x65, 0x22, 0xb8, 0x3a, 0x63, 0xa2, 0x29, 0xf3,
- 0xa7, 0x2d, 0xeb, 0xda, 0x94, 0x9f, 0x63, 0xf8, 0x83, 0x95, 0x1b, 0x83,
- 0x8c, 0x2f, 0xf7, 0xbf, 0x27, 0x75, 0x11, 0xb6, 0x71, 0x8e, 0xb6, 0x70,
- 0xfe, 0x96, 0x87, 0xb2, 0xd1, 0x12, 0xe8, 0xe6, 0x69, 0x44, 0xb0, 0x34,
- 0x63, 0x70, 0x4e, 0x23, 0x58, 0x92, 0xaa, 0xd5, 0x86, 0x31, 0x1f, 0x51,
- 0x5f, 0xce, 0xb6, 0xb7, 0x73, 0xbc, 0x6d, 0x81, 0x16, 0x94, 0xd3, 0x46,
- 0xd2, 0x8b, 0xc2, 0x68, 0x64, 0xff, 0x2b, 0xfe, 0x8c, 0xfe, 0xaf, 0x67,
- 0xff, 0xef, 0xb0, 0xff, 0xac, 0xdd, 0x3f, 0x9c, 0xd7, 0xf0, 0xdc, 0x4d,
- 0x7b, 0xdc, 0x96, 0x76, 0x3a, 0x97, 0xa7, 0xbc, 0xd8, 0x9a, 0x36, 0x69,
- 0x73, 0x72, 0xcb, 0x87, 0xcd, 0x83, 0xb3, 0xb0, 0x65, 0x50, 0xf7, 0x3d,
- 0xcd, 0xdf, 0xdd, 0x23, 0x17, 0x61, 0xd3, 0xa0, 0x82, 0x3d, 0xc6, 0x45,
- 0xe8, 0xe2, 0xef, 0xdd, 0x83, 0xb3, 0xf1, 0xe0, 0xa0, 0x03, 0xe1, 0x69,
- 0xe7, 0x8f, 0x63, 0xd2, 0x71, 0x11, 0xe2, 0x23, 0x7e, 0x74, 0x25, 0x9e,
- 0xb7, 0x75, 0x58, 0x1e, 0xf9, 0x5e, 0xc1, 0x9f, 0xe9, 0x3b, 0x7e, 0xac,
- 0x4e, 0x68, 0xe8, 0x4a, 0x89, 0x1f, 0xb8, 0x69, 0x9b, 0xe2, 0x07, 0xbf,
- 0x06, 0x2a, 0x34, 0x74, 0x67, 0x0a, 0xf7, 0x15, 0x38, 0x39, 0x6f, 0x6b,
- 0x34, 0x37, 0xb6, 0xa6, 0xc4, 0x26, 0xa4, 0x4d, 0xb1, 0x0b, 0xf9, 0x5d,
- 0x4d, 0xbb, 0x2b, 0x85, 0x7f, 0x6f, 0x29, 0x82, 0xf7, 0x6b, 0x78, 0xb3,
- 0x41, 0xae, 0xd3, 0xde, 0x43, 0x52, 0xa6, 0x1f, 0xfb, 0xd2, 0xe2, 0xa7,
- 0x7e, 0x34, 0x26, 0x26, 0xd8, 0x7e, 0x03, 0xdb, 0x36, 0xf1, 0xcf, 0x99,
- 0x7a, 0xfc, 0x53, 0x26, 0x88, 0x7f, 0xa4, 0x1e, 0xbf, 0x93, 0xf1, 0xe3,
- 0x60, 0x66, 0x16, 0xbe, 0x9d, 0xf1, 0xe1, 0x5b, 0x9c, 0xbf, 0xc7, 0x33,
- 0x2d, 0xb4, 0x7d, 0x0d, 0x07, 0x32, 0xa2, 0xff, 0x22, 0x8e, 0xb7, 0x14,
- 0xdd, 0x83, 0xb5, 0xc1, 0x63, 0xb4, 0xad, 0x7f, 0x34, 0xaf, 0x41, 0xb6,
- 0xba, 0xc1, 0xb6, 0xc9, 0xad, 0xbc, 0xbe, 0x6d, 0xb0, 0x36, 0x7a, 0x89,
- 0x62, 0x59, 0x6a, 0xa8, 0x2e, 0x7c, 0x54, 0x55, 0x31, 0xe9, 0xd5, 0xfd,
- 0x59, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82, 0xbe, 0x11, 0xaf, 0xd1, 0x87,
- 0xe2, 0xb4, 0x29, 0xaf, 0x31, 0xcc, 0xf1, 0xe8, 0xfe, 0xb8, 0xea, 0xc6,
- 0x96, 0x94, 0xbe, 0x3b, 0xae, 0x7a, 0x10, 0xcf, 0x94, 0xe2, 0x17, 0x83,
- 0x7a, 0x6f, 0x5c, 0xfd, 0x3c, 0xe2, 0xd5, 0x96, 0xf5, 0xad, 0x10, 0x36,
- 0xce, 0x88, 0x20, 0x5a, 0x13, 0x41, 0x6c, 0x76, 0xc4, 0x8b, 0x54, 0x0a,
- 0x78, 0xa7, 0xcf, 0xf0, 0xfd, 0x9b, 0xd2, 0x82, 0xbf, 0x69, 0xd1, 0xfd,
- 0x7e, 0xb5, 0x2e, 0x3e, 0xac, 0x2e, 0xa2, 0x4b, 0xc3, 0xef, 0x8b, 0x2c,
- 0x43, 0x87, 0x7d, 0x4d, 0x81, 0x66, 0x78, 0xd0, 0x9d, 0xba, 0x02, 0x31,
- 0x6f, 0x6d, 0xeb, 0x0e, 0xb5, 0xf6, 0x8c, 0xa9, 0xea, 0x13, 0x2d, 0xaa,
- 0x65, 0xfd, 0x72, 0xe1, 0x3b, 0x96, 0x7f, 0xba, 0x65, 0x2d, 0x58, 0x28,
- 0x7d, 0xfa, 0x51, 0x15, 0x31, 0xb1, 0xd2, 0x9e, 0xc3, 0x52, 0x9c, 0x1a,
- 0xac, 0x66, 0x1f, 0x1a, 0xfe, 0xf5, 0x72, 0x3d, 0xb8, 0x4e, 0x2d, 0xc5,
- 0x9b, 0x23, 0xa5, 0x38, 0xc9, 0xf1, 0xfc, 0xe7, 0xa0, 0x0f, 0xbf, 0x1e,
- 0xb4, 0xac, 0x2f, 0x99, 0x7f, 0x89, 0x81, 0xea, 0x7e, 0xfc, 0xd3, 0xb8,
- 0x17, 0xbf, 0xe0, 0xdc, 0xbc, 0x91, 0x88, 0xde, 0x35, 0x0d, 0x7a, 0x74,
- 0x5c, 0x39, 0xf6, 0xd5, 0x0a, 0xd4, 0xb5, 0x54, 0x28, 0x7a, 0xf3, 0x76,
- 0xe8, 0xbe, 0x4b, 0x14, 0x2f, 0x4e, 0xa7, 0x35, 0xfc, 0x34, 0x5d, 0x1b,
- 0xfe, 0x21, 0xfb, 0xfc, 0xad, 0xf9, 0x84, 0x95, 0x9d, 0x2e, 0x7a, 0x13,
- 0x1d, 0x51, 0xcf, 0x29, 0xea, 0x39, 0x45, 0x3d, 0xa7, 0xa8, 0x67, 0xca,
- 0x70, 0x30, 0x45, 0x3d, 0x53, 0x77, 0xdf, 0xa2, 0x4d, 0x3d, 0xce, 0x79,
- 0x3c, 0x60, 0xcf, 0x63, 0x98, 0xf3, 0xf5, 0x17, 0xf8, 0x5f, 0x36, 0xb6,
- 0x3e, 0x6f, 0xfd, 0xad, 0x57, 0xc6, 0xd4, 0x3d, 0x3d, 0x87, 0x5f, 0x32,
- 0xb6, 0xe7, 0xac, 0x98, 0x26, 0xe3, 0x92, 0xf1, 0xd9, 0xfa, 0xf3, 0x6f,
- 0x54, 0xb6, 0x28, 0x28, 0xb5, 0xac, 0x9d, 0x66, 0xfe, 0xbe, 0xb7, 0x30,
- 0xbe, 0x1b, 0x94, 0x9c, 0x5d, 0xed, 0x74, 0x53, 0xdf, 0xc1, 0xa8, 0xba,
- 0x8c, 0xe7, 0x7a, 0x3c, 0x8a, 0xb9, 0xc5, 0xe7, 0x9f, 0x5f, 0x5b, 0x23,
- 0xf3, 0xe1, 0x3f, 0x7b, 0x4e, 0x7b, 0xb4, 0xfb, 0xbb, 0x8d, 0xe7, 0x32,
- 0x16, 0xb1, 0x45, 0xb1, 0x01, 0x2f, 0xed, 0xe5, 0xf2, 0xfc, 0x3d, 0xc4,
- 0xd5, 0xc8, 0x46, 0xb4, 0x34, 0x3c, 0x6a, 0xf7, 0x51, 0x94, 0x14, 0xbf,
- 0x51, 0xf0, 0xce, 0x15, 0x0a, 0x8e, 0x86, 0x0c, 0xda, 0xcc, 0x10, 0x71,
- 0x01, 0x28, 0x4e, 0xc2, 0xed, 0x89, 0x44, 0x90, 0xe8, 0x83, 0xbb, 0x24,
- 0x12, 0xc6, 0xfc, 0xbe, 0xda, 0xf6, 0x53, 0xd0, 0x83, 0x7d, 0x8a, 0xde,
- 0x02, 0xd4, 0x99, 0x63, 0xd4, 0xe3, 0x25, 0x8a, 0xee, 0x2f, 0x52, 0xe0,
- 0x56, 0x58, 0x2e, 0x90, 0x1e, 0xc2, 0x96, 0x8c, 0xfc, 0x0e, 0xc3, 0x48,
- 0xff, 0xb6, 0xd0, 0x17, 0xed, 0x7e, 0x23, 0xed, 0xfe, 0x14, 0xc7, 0xae,
- 0xfb, 0x89, 0xaf, 0x6e, 0x57, 0xa4, 0x1d, 0x7b, 0x13, 0x70, 0x17, 0x45,
- 0x36, 0xe0, 0xa9, 0x44, 0xf5, 0xf4, 0x42, 0x39, 0x85, 0xe5, 0xfc, 0xe9,
- 0xa9, 0xb2, 0xbc, 0x66, 0x45, 0xbd, 0x39, 0x59, 0x4a, 0x93, 0x43, 0xd8,
- 0x9e, 0x92, 0xba, 0x11, 0xbb, 0xae, 0x93, 0x7d, 0xf4, 0x24, 0x6a, 0x9b,
- 0xaf, 0x55, 0xf4, 0xf0, 0x23, 0xa8, 0x8b, 0xbe, 0xcd, 0x39, 0xec, 0x82,
- 0x7e, 0xa6, 0x1d, 0x39, 0x59, 0xe6, 0xa5, 0x73, 0x72, 0x2c, 0x4e, 0x43,
- 0xb9, 0x29, 0x05, 0x8f, 0xcf, 0x98, 0x96, 0xf7, 0x65, 0x28, 0xd7, 0x71,
- 0xfe, 0x54, 0xc3, 0x8f, 0xeb, 0x68, 0x43, 0x1b, 0x76, 0x5a, 0xe8, 0x0e,
- 0x55, 0xd3, 0x57, 0x5b, 0x50, 0x41, 0xbf, 0xbc, 0x53, 0x43, 0xb4, 0x32,
- 0x12, 0x56, 0xae, 0xcf, 0x0c, 0xe7, 0xf5, 0x7f, 0xb4, 0x9a, 0xf2, 0x29,
- 0x4d, 0xa9, 0x0b, 0xaf, 0x57, 0xe6, 0xe3, 0xde, 0x85, 0xd7, 0x3d, 0x45,
- 0x1f, 0x5f, 0xbe, 0x4e, 0x1b, 0x81, 0xc2, 0x78, 0x53, 0x42, 0xfd, 0xea,
- 0x26, 0xab, 0x05, 0x5d, 0xf6, 0x35, 0x07, 0x86, 0x9c, 0x51, 0x9f, 0x03,
- 0x1f, 0x58, 0xd1, 0x55, 0x72, 0xad, 0x14, 0xb1, 0x96, 0x3a, 0x9f, 0x13,
- 0x75, 0xe1, 0x4d, 0xf4, 0xb7, 0xc9, 0x55, 0x8d, 0xbc, 0x17, 0x30, 0x8f,
- 0xa1, 0xd6, 0xbf, 0x09, 0xf2, 0xfb, 0x7d, 0xda, 0x48, 0xa3, 0xd4, 0x65,
- 0x19, 0xb1, 0x39, 0x5d, 0x3b, 0x06, 0x2f, 0x36, 0xd1, 0xfe, 0x8a, 0x23,
- 0xba, 0xb9, 0xcc, 0xe1, 0xc4, 0x7e, 0xe2, 0xb8, 0xc3, 0xe8, 0x45, 0x31,
- 0xc7, 0xc8, 0xf8, 0x8a, 0x47, 0x12, 0xc0, 0xb3, 0xfd, 0x16, 0x1a, 0x43,
- 0x1e, 0x2c, 0xb1, 0x6d, 0xf3, 0x90, 0x72, 0x75, 0xea, 0x43, 0x6b, 0xc8,
- 0x59, 0x12, 0x55, 0x23, 0x01, 0xdf, 0x49, 0xb2, 0x81, 0xa2, 0x48, 0x9d,
- 0xe6, 0x44, 0x5c, 0x69, 0xce, 0xf4, 0x28, 0xcb, 0x33, 0xbd, 0xca, 0x92,
- 0x8c, 0xb4, 0x7d, 0x48, 0x59, 0x9a, 0xf1, 0x20, 0xdd, 0xaf, 0x60, 0x7b,
- 0x88, 0x72, 0xd5, 0xe4, 0xec, 0x38, 0xd3, 0xaf, 0x12, 0x63, 0xdf, 0x21,
- 0xc6, 0xea, 0x61, 0xb0, 0xef, 0x27, 0x12, 0xd5, 0x38, 0x44, 0x2c, 0xfd,
- 0x71, 0x5a, 0x57, 0x51, 0x7a, 0x11, 0x5e, 0x19, 0xa9, 0xc0, 0xd8, 0xa0,
- 0xc9, 0xdf, 0xf5, 0x78, 0x61, 0xc4, 0xb2, 0x7a, 0x4c, 0xcb, 0xda, 0x6b,
- 0x1e, 0x52, 0x1a, 0xd9, 0x67, 0xd4, 0x19, 0x8f, 0x16, 0x47, 0x02, 0xe6,
- 0x16, 0xf6, 0xe9, 0x88, 0xc4, 0x95, 0x28, 0xfb, 0xbb, 0x9a, 0xfd, 0x2d,
- 0xcd, 0xf7, 0x97, 0xeb, 0x57, 0x64, 0x91, 0x7a, 0x85, 0x3a, 0x61, 0xd6,
- 0x01, 0xf6, 0x25, 0x02, 0xc1, 0x42, 0xbd, 0xa5, 0xac, 0x73, 0xf5, 0xd9,
- 0x3a, 0xc0, 0x70, 0x22, 0xc8, 0x39, 0x15, 0x5b, 0xf7, 0x33, 0x76, 0x7d,
- 0x83, 0x18, 0xdb, 0x80, 0xb6, 0x61, 0xc1, 0xdf, 0x6b, 0xd4, 0xdc, 0x3c,
- 0xe5, 0xb0, 0x56, 0x62, 0x5e, 0x0e, 0x6f, 0x83, 0xe8, 0xa3, 0x5f, 0x77,
- 0xa5, 0xc4, 0xc6, 0xef, 0xf9, 0x72, 0x22, 0xa0, 0xe0, 0xb1, 0x40, 0xb6,
- 0xa5, 0x1c, 0x95, 0x68, 0x0f, 0x89, 0x6d, 0x6e, 0xfc, 0xf2, 0x53, 0x86,
- 0x1e, 0x5e, 0xa1, 0x70, 0xce, 0x02, 0x7a, 0xf3, 0x52, 0x05, 0x08, 0x8c,
- 0x01, 0x6f, 0xa4, 0x2b, 0xb1, 0xda, 0x74, 0x40, 0xad, 0x0a, 0xa2, 0x37,
- 0x33, 0x35, 0x2e, 0x98, 0xc4, 0x78, 0x69, 0x2f, 0x48, 0xbf, 0x2e, 0xc3,
- 0x32, 0x2d, 0x67, 0xd3, 0x6e, 0xb6, 0xed, 0x0e, 0x64, 0x83, 0x2a, 0xe3,
- 0xdd, 0x7e, 0x5e, 0x38, 0x46, 0xfc, 0x6f, 0x34, 0x5c, 0xc4, 0xff, 0x4a,
- 0x34, 0x9a, 0xbf, 0xb3, 0x96, 0xad, 0x92, 0x7b, 0x85, 0x76, 0xe0, 0x2e,
- 0x66, 0xbf, 0x6f, 0x19, 0xba, 0x7f, 0x94, 0x27, 0xd9, 0x74, 0xee, 0x7a,
- 0x9c, 0x31, 0xab, 0x9b, 0xed, 0x6e, 0x66, 0xbb, 0xeb, 0x34, 0x3d, 0x1a,
- 0x3f, 0x5b, 0x2e, 0x1b, 0x74, 0x40, 0xd7, 0xa4, 0x6c, 0x13, 0xdb, 0x5d,
- 0xcd, 0x76, 0x7b, 0x35, 0x91, 0xef, 0x77, 0xd6, 0xba, 0x55, 0x72, 0x2f,
- 0x67, 0x1f, 0xb9, 0x76, 0xef, 0x91, 0x76, 0xcd, 0xd1, 0x7c, 0x5f, 0x47,
- 0x13, 0xe8, 0x77, 0x44, 0x18, 0x63, 0x1b, 0x02, 0xfe, 0x2e, 0xc6, 0xdb,
- 0x26, 0xc6, 0x8e, 0x9c, 0x4d, 0x4c, 0x8d, 0x77, 0x88, 0x9f, 0x2b, 0x23,
- 0xd7, 0xa4, 0x9c, 0xd8, 0xda, 0x24, 0xf5, 0x2c, 0xf1, 0xc5, 0x47, 0xfd,
- 0x0a, 0xb6, 0x38, 0x71, 0x20, 0x41, 0xfc, 0xc7, 0x37, 0x68, 0x77, 0x7e,
- 0xb4, 0x64, 0x6a, 0xb1, 0x66, 0x27, 0xe3, 0xa0, 0x59, 0x45, 0x5b, 0xcf,
- 0xd9, 0xdb, 0x32, 0xb6, 0x3d, 0x69, 0xb7, 0x1d, 0x57, 0x5a, 0x32, 0x75,
- 0x5a, 0x15, 0x63, 0xee, 0x91, 0xb3, 0xd8, 0x39, 0x27, 0x5a, 0x1a, 0x09,
- 0x34, 0xaf, 0xe7, 0x24, 0xb9, 0x19, 0xdf, 0xbe, 0x37, 0xaf, 0x87, 0x76,
- 0xd1, 0x4b, 0x3b, 0xcc, 0xcd, 0x6f, 0x73, 0x66, 0x8f, 0x2a, 0x18, 0x07,
- 0xb5, 0x16, 0xeb, 0x76, 0xca, 0x7f, 0x72, 0x95, 0x86, 0xc7, 0x78, 0xad,
- 0x16, 0xab, 0x87, 0xbf, 0x47, 0x3b, 0xd3, 0x7d, 0x62, 0x87, 0x5d, 0x67,
- 0xe5, 0x12, 0x99, 0x44, 0x36, 0x91, 0xa9, 0x8f, 0xe5, 0x66, 0x51, 0x3f,
- 0x82, 0x8d, 0xd5, 0x94, 0x67, 0x2b, 0xf9, 0xd0, 0x21, 0xe5, 0xf3, 0x94,
- 0x27, 0xeb, 0xf2, 0xe2, 0xa1, 0x94, 0xc8, 0xa3, 0x44, 0x67, 0x46, 0x66,
- 0xe1, 0x4c, 0x2a, 0x10, 0x7f, 0x02, 0x22, 0x5b, 0x8f, 0xd2, 0x2a, 0xf5,
- 0x53, 0xbd, 0xbc, 0x57, 0x90, 0x11, 0x5a, 0xa5, 0x2d, 0x5b, 0x4e, 0xa6,
- 0xeb, 0x39, 0xd7, 0x2e, 0xe3, 0x6f, 0xcb, 0x51, 0xe1, 0xa4, 0xad, 0x49,
- 0xdb, 0xff, 0x61, 0x45, 0xb5, 0x6e, 0x5e, 0xf3, 0x72, 0x9e, 0xdc, 0xe4,
- 0x05, 0x7a, 0xf0, 0x3a, 0x87, 0xd2, 0xe2, 0x91, 0x78, 0x4d, 0xfb, 0x4c,
- 0xa7, 0x9d, 0x38, 0x9e, 0x58, 0xba, 0xb4, 0xcc, 0xf8, 0x34, 0x1e, 0x1b,
- 0xf1, 0x61, 0x84, 0x73, 0xfb, 0x6c, 0x42, 0xe2, 0xeb, 0x2c, 0x3c, 0x9a,
- 0xf6, 0xe0, 0x99, 0x84, 0x1f, 0x8f, 0x30, 0xfe, 0x4c, 0x24, 0x0c, 0xec,
- 0x4f, 0x7b, 0xf1, 0x34, 0xed, 0x79, 0x34, 0xed, 0xa3, 0xbd, 0xd4, 0x63,
- 0x38, 0xdd, 0x66, 0x8f, 0xe1, 0xc9, 0xc4, 0xbf, 0xcb, 0x58, 0x83, 0x32,
- 0xd6, 0xcd, 0xf6, 0x58, 0x0b, 0x71, 0x7e, 0xd6, 0xd9, 0x79, 0x38, 0x91,
- 0xb0, 0x71, 0xa0, 0x77, 0x99, 0x43, 0xe6, 0x81, 0x36, 0x3b, 0x20, 0x58,
- 0xa0, 0xf7, 0xc7, 0x61, 0x61, 0x8f, 0x39, 0x93, 0xfe, 0xdf, 0x4b, 0x79,
- 0xa9, 0x53, 0x8e, 0x1f, 0xae, 0x8a, 0x68, 0x79, 0x24, 0x10, 0xeb, 0xa3,
- 0xde, 0x9d, 0x11, 0xd1, 0x43, 0x4e, 0xef, 0x2b, 0x32, 0x87, 0x14, 0xe1,
- 0x7a, 0x97, 0x0c, 0xc4, 0xad, 0x32, 0x43, 0xf4, 0x1d, 0x20, 0xce, 0x02,
- 0xf3, 0xf7, 0x38, 0x39, 0xbe, 0x9b, 0x38, 0x66, 0x13, 0x45, 0x46, 0x9d,
- 0x56, 0x4d, 0xd9, 0x8f, 0x7c, 0x24, 0x06, 0x8a, 0x8e, 0xfe, 0x36, 0x3f,
- 0x5f, 0xba, 0x83, 0xf2, 0xfa, 0x81, 0xc2, 0xbc, 0x58, 0xd6, 0x0e, 0xb3,
- 0x30, 0x37, 0x35, 0xf0, 0x57, 0xeb, 0xf1, 0x21, 0x5a, 0xc4, 0x48, 0x62,
- 0x1a, 0xe2, 0x9a, 0x9a, 0x6f, 0x3b, 0xaa, 0x14, 0x31, 0xff, 0xc0, 0xb8,
- 0xf8, 0x7e, 0x39, 0xa2, 0x4e, 0xa9, 0x8f, 0x68, 0x51, 0x24, 0x10, 0x9c,
- 0xab, 0x4e, 0xb5, 0x19, 0xc1, 0x01, 0xe9, 0x2b, 0x4e, 0x59, 0xcf, 0xc7,
- 0x82, 0x91, 0x44, 0x01, 0x37, 0xfe, 0x3b, 0xf5, 0x2e, 0xd4, 0xa9, 0xc8,
- 0x29, 0x7a, 0x55, 0x71, 0x74, 0x50, 0xf4, 0xe7, 0xc4, 0x4a, 0x73, 0x7a,
- 0x5e, 0xe6, 0x59, 0x9c, 0x17, 0x62, 0x0e, 0xe7, 0xeb, 0x85, 0x7e, 0x2f,
- 0xe5, 0xb6, 0x90, 0x0e, 0x5d, 0x8c, 0x4d, 0x36, 0xe7, 0x5c, 0x95, 0xcf,
- 0x5b, 0x38, 0x4f, 0xea, 0x76, 0xea, 0xfa, 0xb3, 0x8e, 0xdc, 0x79, 0x9d,
- 0xef, 0xa3, 0xfa, 0xd2, 0xb5, 0x18, 0x0a, 0x3a, 0x03, 0x86, 0xd2, 0x88,
- 0xb9, 0x23, 0xf5, 0x4d, 0xce, 0xbe, 0xb6, 0x0d, 0xf4, 0xef, 0x7b, 0x4f,
- 0x35, 0x7c, 0x16, 0x9b, 0xa9, 0x17, 0xa7, 0x6d, 0x67, 0x51, 0xc5, 0x65,
- 0x2c, 0xb1, 0xfd, 0x49, 0x1d, 0x5f, 0x91, 0xef, 0x23, 0x6a, 0xe7, 0x2c,
- 0x50, 0x5b, 0xf2, 0xe7, 0x77, 0x53, 0xdf, 0x32, 0x0e, 0x15, 0x3f, 0x20,
- 0x97, 0x7d, 0x27, 0xf4, 0x59, 0x64, 0x6d, 0xcc, 0x76, 0xd2, 0xdf, 0xaf,
- 0x62, 0x5d, 0xe2, 0xdf, 0xb8, 0xc4, 0x52, 0xc4, 0x4b, 0xe8, 0xd7, 0x45,
- 0xf4, 0xd5, 0x6b, 0x32, 0xf7, 0xa0, 0x3d, 0x15, 0x08, 0x97, 0x28, 0xf7,
- 0xe0, 0xd6, 0x8c, 0x0b, 0xb1, 0x61, 0x0f, 0xd6, 0x51, 0x27, 0xce, 0xa4,
- 0xf8, 0xb9, 0x86, 0x75, 0xa3, 0x47, 0x67, 0x3a, 0xe9, 0x37, 0xeb, 0x46,
- 0xbd, 0x3c, 0xa6, 0xf3, 0x70, 0x63, 0x35, 0x8f, 0x3d, 0xb4, 0xcb, 0x36,
- 0xc6, 0x86, 0x23, 0x09, 0x13, 0x9d, 0xd4, 0xd5, 0x13, 0x89, 0x06, 0xdc,
- 0x4b, 0xbd, 0x1d, 0x4a, 0x7c, 0x8a, 0x3a, 0x0a, 0xa3, 0x83, 0x73, 0xfc,
- 0x58, 0x42, 0xb5, 0xf3, 0xab, 0xdb, 0x33, 0xff, 0x62, 0x45, 0xa7, 0x8b,
- 0x9c, 0xa2, 0x0b, 0x99, 0xcf, 0x8f, 0xe8, 0x81, 0xfe, 0x3b, 0x55, 0x17,
- 0xf5, 0xd8, 0xb6, 0xcb, 0xc0, 0xf6, 0x5d, 0x75, 0xb4, 0xbb, 0x8c, 0xe5,
- 0xaf, 0x1a, 0xa0, 0x0e, 0xa6, 0xea, 0xe1, 0x08, 0x79, 0x81, 0xe8, 0x41,
- 0xda, 0xbc, 0x8f, 0x63, 0xee, 0xe6, 0x3d, 0x1f, 0x1e, 0x4f, 0x7c, 0x97,
- 0xbf, 0xc3, 0xca, 0x5d, 0x19, 0xf1, 0x79, 0xf1, 0xb7, 0x7f, 0x70, 0xe4,
- 0x62, 0x6f, 0xa1, 0xdc, 0x16, 0x96, 0xb3, 0xac, 0xcd, 0x67, 0xe3, 0x4a,
- 0x51, 0xb4, 0x84, 0x71, 0x65, 0x7f, 0x22, 0x10, 0x7e, 0xc6, 0x8e, 0x7d,
- 0x4e, 0xda, 0x8e, 0xd8, 0x47, 0x8f, 0x6d, 0x1b, 0xcb, 0xce, 0xda, 0xc6,
- 0xe4, 0x59, 0x0e, 0xd5, 0x9f, 0x9a, 0xea, 0x73, 0x39, 0xbb, 0x70, 0x26,
- 0xf5, 0x5e, 0xdb, 0x8e, 0xd3, 0x82, 0x8f, 0x0e, 0x38, 0x06, 0x9c, 0x68,
- 0x33, 0x2f, 0xa5, 0xbe, 0xab, 0x19, 0x6f, 0x8a, 0x78, 0x30, 0x4f, 0x1d,
- 0xfe, 0x0b, 0x94, 0x0e, 0x64, 0xad, 0x12, 0xfe, 0x6e, 0x0e, 0x89, 0xbe,
- 0xaf, 0xc2, 0xad, 0xc3, 0x0e, 0x14, 0x0d, 0x28, 0x78, 0xd2, 0xac, 0xc7,
- 0x90, 0x37, 0x87, 0xbb, 0x6a, 0xf2, 0x52, 0x7b, 0x9e, 0x2e, 0x1e, 0x3f,
- 0xfa, 0x8c, 0xc4, 0x85, 0x7b, 0x47, 0x3d, 0xf0, 0x25, 0x15, 0x78, 0x88,
- 0x2b, 0x65, 0x46, 0x3d, 0xf5, 0xaa, 0xa1, 0x32, 0x69, 0xe2, 0x6b, 0x19,
- 0xd2, 0xa6, 0x07, 0xc2, 0xb8, 0x93, 0xf3, 0x52, 0xfe, 0xc0, 0x95, 0xb8,
- 0x83, 0xe5, 0x36, 0xf0, 0xde, 0x86, 0xd1, 0x6a, 0x1e, 0x5e, 0x1e, 0xd3,
- 0x79, 0x34, 0xe0, 0xf6, 0xe1, 0x5a, 0x44, 0xab, 0xf5, 0xa0, 0x5f, 0x75,
- 0xa0, 0x7a, 0x40, 0xf4, 0xae, 0x62, 0xe5, 0x02, 0x05, 0xe6, 0xa7, 0x8b,
- 0xa1, 0xce, 0xfd, 0x38, 0xdf, 0xfd, 0x53, 0xb2, 0xbe, 0x6c, 0x0d, 0xd9,
- 0x98, 0x2e, 0x3a, 0x16, 0x3b, 0xf9, 0x57, 0xce, 0x85, 0xc8, 0x2b, 0x7d,
- 0x48, 0xac, 0x15, 0x1d, 0x7f, 0x12, 0x36, 0x30, 0xb2, 0x54, 0x74, 0xb1,
- 0xcc, 0x47, 0x7d, 0x01, 0x67, 0xe7, 0x7f, 0x2a, 0x67, 0x95, 0xb8, 0xaf,
- 0x87, 0x87, 0x6c, 0x8e, 0xe3, 0x67, 0xbe, 0xa8, 0xc7, 0x45, 0xe7, 0xe4,
- 0x34, 0x6e, 0xd5, 0x80, 0xbf, 0xc8, 0xb8, 0x19, 0xb7, 0x71, 0x9e, 0xf6,
- 0x26, 0xd4, 0xa5, 0x2e, 0xa8, 0xb3, 0x5c, 0x4c, 0x9c, 0x47, 0x4c, 0x1d,
- 0xed, 0xc3, 0xcc, 0xb5, 0x86, 0xcb, 0xd1, 0xa5, 0x29, 0xee, 0x6d, 0xf5,
- 0x8b, 0x24, 0xa7, 0xf6, 0x57, 0x1a, 0x50, 0xcb, 0x18, 0xff, 0xb7, 0x6b,
- 0x70, 0x16, 0x19, 0x8a, 0x9a, 0xa8, 0x6f, 0x42, 0xbc, 0x0a, 0xce, 0x0a,
- 0x03, 0x0a, 0x73, 0x66, 0xf4, 0x69, 0x10, 0xec, 0x89, 0x16, 0x19, 0xf7,
- 0xe0, 0xb6, 0x14, 0xac, 0xd2, 0x08, 0xf3, 0xa1, 0x88, 0x41, 0x8e, 0x1b,
- 0xf0, 0x15, 0xd1, 0x3f, 0x56, 0x93, 0x57, 0xac, 0x1d, 0x16, 0x39, 0x3c,
- 0xe4, 0x1b, 0x86, 0xbf, 0x0d, 0xcc, 0xe1, 0x5b, 0xf4, 0xe0, 0x24, 0xf3,
- 0xd8, 0xd5, 0xd4, 0xfd, 0x48, 0xe2, 0x1e, 0x34, 0xa6, 0x8e, 0x58, 0x1e,
- 0xf2, 0xc8, 0x22, 0xa3, 0xf6, 0x4c, 0x17, 0x62, 0xf4, 0x0d, 0xe1, 0x47,
- 0x6b, 0xe8, 0x1b, 0x3e, 0x64, 0x12, 0xea, 0x71, 0xb2, 0x0b, 0x74, 0x8c,
- 0xae, 0xc7, 0xd7, 0x46, 0x67, 0x61, 0x3c, 0xb1, 0x01, 0x77, 0x66, 0xc8,
- 0x95, 0xfa, 0xaf, 0xc2, 0x1d, 0xc3, 0x57, 0xe1, 0xf6, 0x9d, 0x46, 0x70,
- 0x03, 0x75, 0xbd, 0x76, 0x98, 0x81, 0x72, 0xba, 0xb4, 0x5b, 0xd0, 0x95,
- 0xf0, 0x45, 0xea, 0x22, 0xaf, 0xa7, 0x2c, 0x0a, 0x1c, 0xe6, 0x5f, 0x2d,
- 0x5e, 0x8a, 0x17, 0x35, 0x28, 0xfe, 0xdd, 0xf5, 0x2f, 0x31, 0xb7, 0x17,
- 0xd9, 0x11, 0x9d, 0x69, 0xfc, 0xc0, 0x7a, 0x50, 0xa3, 0x7f, 0x47, 0x10,
- 0x9f, 0xd3, 0xf0, 0xbc, 0xf5, 0xd0, 0x2a, 0xb9, 0x7e, 0x9b, 0x13, 0xa5,
- 0x2a, 0xaf, 0x49, 0x9b, 0x82, 0x4b, 0x75, 0x44, 0xe2, 0x8f, 0x6b, 0x33,
- 0x6b, 0x25, 0xcf, 0x96, 0x27, 0x2f, 0x24, 0x16, 0x3f, 0x91, 0xf0, 0xa2,
- 0x37, 0x95, 0xe3, 0x56, 0x37, 0x65, 0x84, 0x53, 0xb9, 0x51, 0xda, 0x27,
- 0x71, 0x25, 0x8a, 0xf5, 0xfc, 0x5d, 0xd2, 0xa7, 0xb7, 0xc4, 0x91, 0x60,
- 0x9b, 0x4d, 0x9c, 0x0b, 0xda, 0x6b, 0x9f, 0x03, 0x25, 0x46, 0x73, 0xce,
- 0x56, 0xfb, 0x56, 0xd0, 0x56, 0x35, 0x54, 0xf4, 0xf5, 0x70, 0xac, 0xb4,
- 0x55, 0xd6, 0xbb, 0x83, 0xba, 0xf0, 0xf4, 0xad, 0xa2, 0xbd, 0xce, 0x42,
- 0x59, 0x5f, 0x2b, 0xf1, 0x01, 0x8c, 0xeb, 0x16, 0x8e, 0x9a, 0x95, 0x79,
- 0x7e, 0xda, 0x8c, 0x5b, 0x53, 0x51, 0xb4, 0xa5, 0x6a, 0xa3, 0x27, 0x65,
- 0xad, 0xca, 0x95, 0xc3, 0xb0, 0x68, 0x8d, 0xe8, 0x62, 0x32, 0x8f, 0xa7,
- 0x7a, 0x73, 0x8e, 0xd3, 0xe9, 0x9a, 0x5f, 0x29, 0xc8, 0xde, 0x83, 0x18,
- 0xf3, 0x8f, 0x39, 0x91, 0x16, 0x58, 0x29, 0x91, 0x3b, 0x6e, 0xf9, 0x98,
- 0x53, 0x7a, 0x22, 0xfa, 0xc6, 0xc5, 0x0e, 0xa3, 0xe3, 0x15, 0x25, 0x88,
- 0xeb, 0x29, 0x43, 0x59, 0x5f, 0x27, 0x5e, 0x08, 0xe9, 0xbe, 0xef, 0x2a,
- 0xfa, 0x99, 0x0d, 0x78, 0x05, 0x3f, 0xe3, 0xb5, 0xa2, 0xbe, 0x09, 0x3c,
- 0x94, 0x79, 0x15, 0xa7, 0x28, 0xab, 0xda, 0xf7, 0xa1, 0xb5, 0xcc, 0x78,
- 0x86, 0xe3, 0x77, 0x2b, 0x6f, 0x65, 0xa6, 0xda, 0xe2, 0x55, 0x58, 0xbd,
- 0x53, 0xec, 0x4f, 0x0f, 0xc6, 0x89, 0xbd, 0x6d, 0x66, 0x85, 0x70, 0x79,
- 0x89, 0x4f, 0x94, 0xbf, 0x45, 0xb0, 0x85, 0xfe, 0x41, 0x3b, 0xb0, 0xc7,
- 0xd0, 0x6a, 0x63, 0xb2, 0x33, 0x09, 0x1b, 0x4b, 0x73, 0x7a, 0x8e, 0x28,
- 0x6d, 0xa3, 0xbe, 0x52, 0x94, 0xfa, 0xf2, 0x7e, 0x90, 0x5b, 0xb3, 0x38,
- 0x57, 0xf7, 0x3f, 0xad, 0x11, 0xef, 0xf9, 0x75, 0x2b, 0x98, 0x83, 0x55,
- 0x72, 0x3c, 0xef, 0xf6, 0xc5, 0xad, 0xd2, 0xdc, 0x58, 0x9a, 0x7f, 0xa0,
- 0x88, 0x4d, 0x06, 0xc9, 0xed, 0x3b, 0x71, 0x69, 0x48, 0x6f, 0xfd, 0xae,
- 0x22, 0x65, 0xf5, 0xf0, 0x06, 0xa5, 0xd0, 0xcf, 0xcb, 0x38, 0x39, 0x22,
- 0x7d, 0x48, 0x5f, 0x13, 0xcc, 0xc9, 0x72, 0x63, 0x10, 0x5f, 0x7a, 0xc4,
- 0x9e, 0x4b, 0xf1, 0x27, 0x3f, 0x96, 0x73, 0x4c, 0xae, 0x3e, 0x1f, 0x0f,
- 0x17, 0xed, 0xd5, 0x87, 0xb5, 0x99, 0x15, 0x58, 0xcd, 0xbc, 0x76, 0x75,
- 0xa6, 0x85, 0xba, 0xdf, 0x48, 0x7c, 0x67, 0x46, 0xa0, 0xe5, 0x74, 0x7c,
- 0xce, 0x3e, 0x74, 0xff, 0x24, 0x56, 0xf0, 0xfe, 0xcf, 0x9d, 0xa8, 0x68,
- 0x61, 0x79, 0xfb, 0xbe, 0x29, 0xf8, 0x7d, 0xae, 0xcc, 0x47, 0x78, 0x98,
- 0x1d, 0xe7, 0xf7, 0xda, 0x1c, 0xb1, 0xc5, 0xce, 0xbd, 0xae, 0xb6, 0xe7,
- 0x5c, 0x38, 0x82, 0x85, 0x63, 0x66, 0x31, 0xf3, 0xaf, 0xba, 0xe0, 0xf9,
- 0x9c, 0x50, 0x67, 0x16, 0x5a, 0xc0, 0x03, 0xe9, 0x4b, 0xf4, 0x72, 0xa2,
- 0x26, 0xa7, 0x97, 0x4f, 0x2a, 0x7b, 0x3e, 0x76, 0xec, 0x49, 0x48, 0xdf,
- 0x45, 0x36, 0x2f, 0x6d, 0xcc, 0x94, 0x22, 0xee, 0x15, 0x1d, 0x49, 0x7b,
- 0xba, 0x5f, 0x64, 0x5a, 0xbb, 0x53, 0xec, 0xd8, 0xc2, 0x08, 0x65, 0xe8,
- 0xb6, 0xe7, 0x2d, 0xc7, 0x25, 0x8f, 0x9c, 0x17, 0x9f, 0x65, 0x4c, 0x85,
- 0xbe, 0x6f, 0x73, 0xe5, 0xf8, 0x66, 0x81, 0x2b, 0x58, 0xd6, 0x80, 0x59,
- 0xe0, 0x0a, 0x32, 0xe6, 0xbf, 0x00, 0x63, 0x9d, 0x3d, 0xde, 0x35, 0xf9,
- 0xb6, 0xbb, 0xcc, 0x00, 0xed, 0x5a, 0xb8, 0x54, 0x44, 0x59, 0xb3, 0x2b,
- 0xc3, 0xb9, 0x95, 0xdc, 0x06, 0xb8, 0x93, 0xf7, 0xcb, 0x79, 0xff, 0xc5,
- 0x90, 0x0b, 0x97, 0x4e, 0x97, 0xbe, 0xaf, 0x42, 0xc7, 0xce, 0x28, 0x2a,
- 0x17, 0x06, 0x30, 0x69, 0x73, 0x89, 0x02, 0xef, 0x75, 0xe1, 0x8e, 0x9d,
- 0x1f, 0x5a, 0x15, 0x36, 0x17, 0x33, 0x62, 0xe3, 0x8a, 0x8a, 0xed, 0x8b,
- 0x84, 0xff, 0xba, 0x88, 0xef, 0xe4, 0xa2, 0xc2, 0xad, 0x5d, 0x65, 0xe4,
- 0xb0, 0xc2, 0xe1, 0x02, 0xd9, 0x9b, 0x54, 0x68, 0x5a, 0x44, 0xb8, 0xdc,
- 0x2c, 0x9b, 0xc3, 0x0a, 0x97, 0xfd, 0x56, 0xea, 0xd0, 0x14, 0x2e, 0x7b,
- 0x96, 0x73, 0x30, 0xf7, 0x69, 0x61, 0x7e, 0xef, 0x81, 0x3b, 0xa2, 0xb7,
- 0x6c, 0x52, 0x3a, 0xb1, 0x3c, 0x64, 0x98, 0x92, 0x53, 0x5f, 0xa9, 0xe8,
- 0xc1, 0xd3, 0x08, 0x12, 0x6f, 0x5f, 0xc6, 0xc8, 0x60, 0xdc, 0x25, 0x76,
- 0xb4, 0x29, 0x73, 0x4e, 0x9e, 0x5b, 0x29, 0x8f, 0x3b, 0x27, 0x8f, 0x79,
- 0x1a, 0x2a, 0x9e, 0x6c, 0x70, 0x11, 0xb7, 0xfe, 0x0e, 0x6d, 0x3b, 0x55,
- 0x2c, 0xb1, 0xb9, 0xf9, 0xdf, 0x11, 0x7f, 0x2f, 0x2a, 0xcd, 0x95, 0x07,
- 0x3a, 0xe9, 0xdf, 0xef, 0x2f, 0x2c, 0x41, 0x68, 0x9a, 0x82, 0x2a, 0xa3,
- 0x83, 0xf9, 0xf1, 0x87, 0x56, 0xdc, 0x49, 0x3a, 0x6b, 0x40, 0x2b, 0x89,
- 0x44, 0x29, 0x5b, 0x93, 0x72, 0xcd, 0xf0, 0x20, 0xfb, 0xe9, 0x20, 0xef,
- 0xf7, 0xe0, 0x2e, 0xda, 0xce, 0x5d, 0x8c, 0x65, 0x77, 0x31, 0x96, 0xdd,
- 0x35, 0xfa, 0x2f, 0xbc, 0x3e, 0xdd, 0xfe, 0xbd, 0x29, 0x55, 0xb0, 0x65,
- 0x27, 0xe3, 0x82, 0xe8, 0x77, 0x33, 0x7d, 0x47, 0xe2, 0x02, 0x28, 0x93,
- 0x85, 0x93, 0x9c, 0xc7, 0x25, 0x9a, 0x1e, 0xcc, 0xe2, 0xeb, 0xae, 0x73,
- 0x79, 0x5f, 0x21, 0xb6, 0xc8, 0x3c, 0xba, 0x70, 0x1b, 0x65, 0x0c, 0x86,
- 0xfe, 0xcb, 0x42, 0x95, 0xf8, 0xee, 0x85, 0xf7, 0x73, 0xf3, 0x7a, 0xe4,
- 0x2c, 0x07, 0x54, 0xc4, 0x4e, 0xe9, 0xf3, 0x7b, 0x6c, 0x4e, 0xf1, 0xa2,
- 0xc9, 0xdc, 0x6d, 0xe7, 0xd1, 0xf9, 0x62, 0x2a, 0x6b, 0x47, 0xa3, 0xe8,
- 0xe6, 0xb8, 0x57, 0x0f, 0x3f, 0x96, 0xd7, 0x4b, 0x61, 0xbc, 0x0a, 0xd5,
- 0xe2, 0xa1, 0xff, 0xe4, 0x72, 0x95, 0xb6, 0x51, 0xe1, 0xb6, 0xd5, 0xfc,
- 0x2f, 0xdc, 0xd6, 0xcb, 0xff, 0xc2, 0x73, 0xa7, 0xf3, 0xbf, 0x13, 0xfe,
- 0xe9, 0x62, 0xc7, 0xf5, 0xe8, 0xdd, 0x65, 0x59, 0xc5, 0x81, 0x7a, 0x6c,
- 0x19, 0xfd, 0x48, 0xbc, 0xbc, 0x40, 0x1e, 0x7b, 0x0e, 0xe8, 0x47, 0x2e,
- 0xc1, 0x22, 0xbf, 0x5f, 0x95, 0xbe, 0x2d, 0x6c, 0x34, 0xaf, 0x62, 0x9f,
- 0x8c, 0x80, 0xd5, 0x53, 0xfd, 0xa2, 0xd0, 0x46, 0x41, 0xdf, 0xc5, 0xf4,
- 0x73, 0x68, 0x2e, 0xea, 0x7b, 0x65, 0x46, 0xea, 0x36, 0x29, 0x4b, 0x87,
- 0xa7, 0x96, 0xef, 0x20, 0x1f, 0x3e, 0x4d, 0x5d, 0x17, 0xfc, 0xc8, 0x9b,
- 0xcf, 0x2b, 0x98, 0x4b, 0xa4, 0x44, 0x97, 0x32, 0xbe, 0x5c, 0xae, 0x28,
- 0xb6, 0x74, 0xe4, 0x6c, 0x1f, 0xa2, 0xb7, 0xf8, 0xf4, 0x12, 0x43, 0xec,
- 0x28, 0x48, 0x5c, 0xd1, 0xc3, 0xcd, 0x84, 0xed, 0x53, 0x09, 0xc4, 0x1c,
- 0x91, 0xe6, 0xa6, 0xb5, 0x89, 0xb9, 0xda, 0xf1, 0x7c, 0x2e, 0xba, 0x87,
- 0x38, 0xae, 0x1a, 0xb2, 0x0e, 0x42, 0x5b, 0x19, 0x16, 0xdd, 0x75, 0x28,
- 0xe7, 0xf2, 0xce, 0x28, 0x79, 0x97, 0x6a, 0xcb, 0xe8, 0x8c, 0x88, 0x6c,
- 0x52, 0x87, 0xb2, 0x5f, 0xc0, 0xbf, 0x72, 0xba, 0xa8, 0x80, 0x67, 0x40,
- 0x78, 0x97, 0x8e, 0x0d, 0x8c, 0xf3, 0x65, 0x03, 0x7e, 0xfa, 0x42, 0x35,
- 0x4a, 0x1f, 0x88, 0x60, 0xfd, 0xa8, 0x86, 0x92, 0x07, 0x2c, 0x6b, 0x6e,
- 0xa8, 0x87, 0x5c, 0xf6, 0xb2, 0x22, 0xc9, 0x9d, 0x9c, 0x49, 0x62, 0x16,
- 0xf1, 0xad, 0x3d, 0xa5, 0xe0, 0x6a, 0xc6, 0xd3, 0x28, 0x71, 0xa8, 0xdd,
- 0xc6, 0x39, 0xab, 0x73, 0x4e, 0xc4, 0x45, 0x1b, 0x5a, 0xc5, 0xfb, 0xad,
- 0xc4, 0xc0, 0x56, 0x62, 0x9a, 0x65, 0xbd, 0x7f, 0x39, 0x3a, 0xcb, 0x22,
- 0x37, 0x13, 0x0b, 0x6b, 0xc9, 0x89, 0x25, 0x7e, 0x5f, 0x8e, 0x35, 0x8c,
- 0xfd, 0xc5, 0x49, 0x3b, 0x9f, 0xa2, 0xee, 0x18, 0xa3, 0x32, 0x8c, 0x71,
- 0x94, 0xfd, 0x69, 0x72, 0x5c, 0xe1, 0xbb, 0x95, 0xc9, 0x0d, 0x8c, 0x75,
- 0x1e, 0x54, 0x0c, 0x5c, 0x86, 0x3b, 0x19, 0xcf, 0xef, 0xd8, 0xe9, 0x47,
- 0x7a, 0xd1, 0x55, 0x94, 0xef, 0x1e, 0xac, 0x4f, 0x19, 0x92, 0x43, 0x45,
- 0x83, 0x8b, 0xc8, 0xb7, 0x33, 0x82, 0x3b, 0x92, 0x8f, 0x95, 0x61, 0x49,
- 0x0b, 0x10, 0x4c, 0x16, 0xf0, 0x2d, 0x2a, 0x6b, 0x47, 0x30, 0x92, 0xe7,
- 0x63, 0xdb, 0x39, 0x5e, 0x24, 0xeb, 0x70, 0x2d, 0x98, 0xcf, 0x58, 0x20,
- 0xf6, 0xa5, 0x31, 0xc7, 0x2c, 0x51, 0x0c, 0xdf, 0x1e, 0xfa, 0xa9, 0xe4,
- 0x3d, 0x57, 0x24, 0x0b, 0xb1, 0x4f, 0xcf, 0x2e, 0x76, 0x74, 0x12, 0x47,
- 0xf4, 0x8d, 0xbf, 0x53, 0xf4, 0xf6, 0x13, 0xca, 0x2b, 0xd8, 0x37, 0xf6,
- 0x2a, 0x86, 0xc6, 0xdc, 0xca, 0xe8, 0x98, 0xf4, 0x35, 0x81, 0xbe, 0xcc,
- 0x9f, 0xea, 0x6b, 0xea, 0xfa, 0xcb, 0xa2, 0xf3, 0xd6, 0x6c, 0xae, 0xce,
- 0xe7, 0x89, 0x4b, 0xcf, 0xe3, 0xc7, 0x32, 0x27, 0x62, 0x97, 0x5e, 0xf4,
- 0xa4, 0xce, 0xad, 0x0b, 0xf4, 0x27, 0xb6, 0xd9, 0xfe, 0xd9, 0x92, 0x11,
- 0x7b, 0x55, 0x19, 0x33, 0x2f, 0xce, 0xe7, 0x2c, 0xb5, 0xd4, 0x41, 0x9f,
- 0x7d, 0x6f, 0x9f, 0xf9, 0x29, 0x64, 0xed, 0x6b, 0x8b, 0xe9, 0x9b, 0xd5,
- 0x28, 0x26, 0x26, 0x06, 0x43, 0x3e, 0x14, 0x57, 0xc9, 0x3a, 0xce, 0xb9,
- 0xdc, 0x7f, 0xc3, 0x4e, 0x86, 0x64, 0x1b, 0x73, 0x1a, 0x89, 0x7f, 0xb5,
- 0x9c, 0xef, 0x1c, 0xce, 0xac, 0xa7, 0x0d, 0x5d, 0x27, 0x36, 0xe4, 0xca,
- 0xd9, 0xd0, 0x47, 0xd7, 0x17, 0x54, 0x90, 0xfb, 0x69, 0x15, 0x76, 0xde,
- 0xd7, 0xa4, 0x5c, 0x9f, 0xb7, 0xab, 0xcf, 0x67, 0x1e, 0x2d, 0xca, 0xe7,
- 0x66, 0x17, 0x94, 0xff, 0x38, 0x1d, 0x5c, 0xf6, 0x67, 0xe8, 0x40, 0xe2,
- 0x81, 0xe4, 0x04, 0xa2, 0x83, 0xf3, 0xf3, 0xf2, 0xfe, 0x44, 0x35, 0x71,
- 0xef, 0x42, 0x5d, 0xcc, 0xcc, 0xeb, 0x62, 0x31, 0xb1, 0x4b, 0xfe, 0x5b,
- 0x38, 0x65, 0x7a, 0xf1, 0xa2, 0x26, 0xe3, 0x5e, 0x8c, 0xf5, 0x1c, 0xaf,
- 0x9b, 0xba, 0x58, 0x1e, 0xaa, 0x44, 0xf0, 0xbc, 0x78, 0x50, 0xcb, 0xd8,
- 0xf1, 0x21, 0x79, 0xa6, 0xfc, 0xf6, 0xe3, 0x05, 0xea, 0xe2, 0x8e, 0xe1,
- 0xc5, 0xb8, 0x8b, 0xfe, 0x94, 0xe3, 0x90, 0xb9, 0xd8, 0xb0, 0x76, 0x58,
- 0xda, 0x14, 0x8c, 0xfb, 0xd9, 0xd9, 0x71, 0xfe, 0x71, 0x5e, 0xfe, 0x0a,
- 0xe5, 0x97, 0x67, 0x07, 0xb2, 0x16, 0x2d, 0xcf, 0x11, 0x64, 0x2c, 0xc6,
- 0x14, 0xdc, 0xb1, 0xac, 0x83, 0xe6, 0x3c, 0xc4, 0xaa, 0xf5, 0x7e, 0x89,
- 0x8f, 0xfd, 0xc4, 0x03, 0x07, 0xf3, 0xc8, 0xa2, 0x48, 0x94, 0xfe, 0xac,
- 0x5e, 0xe5, 0x80, 0x5a, 0xef, 0x40, 0x27, 0xde, 0x30, 0x8d, 0xde, 0x75,
- 0xf8, 0x14, 0xba, 0xbc, 0x16, 0xf6, 0xb2, 0x9d, 0xee, 0x54, 0x09, 0xda,
- 0xeb, 0x69, 0x56, 0x2b, 0x3d, 0xd8, 0x91, 0x8a, 0xb7, 0x12, 0x16, 0x18,
- 0x73, 0x1a, 0xfe, 0x2a, 0x11, 0xd0, 0x5b, 0x36, 0x90, 0xb7, 0x2c, 0xef,
- 0x73, 0xc3, 0xaf, 0xe4, 0x72, 0xb4, 0x01, 0x55, 0xd6, 0x09, 0x23, 0x94,
- 0xbd, 0xc7, 0xce, 0xf7, 0xfc, 0xd3, 0xa5, 0x1f, 0x3f, 0xe2, 0x19, 0xa9,
- 0xeb, 0x47, 0xe9, 0x5c, 0x05, 0xcb, 0xe7, 0xea, 0xf1, 0xa8, 0x62, 0x59,
- 0x0b, 0x42, 0x4e, 0xfb, 0xfe, 0xb6, 0x4c, 0x5d, 0xeb, 0x0d, 0xea, 0xab,
- 0x56, 0x6e, 0x6d, 0x52, 0xd7, 0xa2, 0x4c, 0x0a, 0x8e, 0xfc, 0xd1, 0xf5,
- 0xf9, 0x20, 0xe4, 0xb9, 0x89, 0xdb, 0x58, 0x89, 0xfd, 0xf9, 0xf5, 0x39,
- 0x57, 0xe4, 0xbd, 0x2f, 0xef, 0x35, 0x24, 0x6f, 0x11, 0x9d, 0x4b, 0x7f,
- 0x62, 0x0b, 0xd7, 0x15, 0x0b, 0x06, 0x76, 0x65, 0x16, 0xd2, 0x16, 0x7f,
- 0x6b, 0x8d, 0x7a, 0xa7, 0x96, 0xbd, 0x51, 0xcd, 0xad, 0xb7, 0x4b, 0xd9,
- 0x42, 0xb9, 0x8b, 0x89, 0x09, 0x8d, 0x18, 0x3e, 0xaf, 0x4d, 0xc9, 0x75,
- 0x0b, 0x6d, 0xde, 0xc6, 0x72, 0xd2, 0xae, 0xe0, 0xef, 0x7f, 0x59, 0xfb,
- 0xce, 0x6b, 0xaf, 0xd5, 0x95, 0x6b, 0xef, 0xee, 0x62, 0xc9, 0xdd, 0xfb,
- 0x53, 0x45, 0xac, 0xf3, 0x4e, 0x9e, 0x07, 0x16, 0xca, 0x7c, 0xea, 0x82,
- 0x32, 0xc4, 0x79, 0xe3, 0x4d, 0x6b, 0xcf, 0x79, 0x65, 0x96, 0x3b, 0xcf,
- 0x2f, 0xe3, 0xc4, 0x1c, 0xe3, 0x55, 0xeb, 0xc8, 0x79, 0x65, 0xd2, 0x17,
- 0x94, 0xb9, 0x1c, 0x63, 0xf5, 0x8f, 0x58, 0x43, 0xb9, 0xb9, 0xc9, 0xd2,
- 0x7d, 0xdc, 0x33, 0x23, 0xad, 0x7f, 0x75, 0xc5, 0x3c, 0xbd, 0x63, 0xa6,
- 0x43, 0x9e, 0xd9, 0xb8, 0x91, 0xcd, 0xcd, 0x4d, 0x5c, 0xe6, 0xc6, 0xb5,
- 0xa0, 0x30, 0x37, 0xd7, 0xe5, 0xeb, 0x17, 0xda, 0xbd, 0xae, 0xe8, 0xfc,
- 0x76, 0x0b, 0xd7, 0xaf, 0xb8, 0x40, 0xee, 0xef, 0x5c, 0x50, 0xee, 0xb7,
- 0x7f, 0xa4, 0xde, 0x2f, 0x1c, 0xe7, 0x5f, 0x3f, 0xa0, 0x9e, 0x7f, 0xde,
- 0x9c, 0x3f, 0x2f, 0xe8, 0xbf, 0xea, 0x82, 0xf2, 0x35, 0x17, 0x94, 0x7f,
- 0x59, 0xfd, 0xf8, 0x7e, 0xd6, 0x5d, 0x50, 0xcf, 0x5e, 0xab, 0xc6, 0x53,
- 0x67, 0x7d, 0x1e, 0x4d, 0x45, 0x08, 0x98, 0x4e, 0x05, 0x7e, 0xfa, 0xbe,
- 0xff, 0xe9, 0x0b, 0xd6, 0xac, 0x9b, 0xce, 0xfa, 0xfe, 0x79, 0x9c, 0x33,
- 0x56, 0x1c, 0x91, 0x18, 0x56, 0x44, 0xee, 0x2c, 0x3c, 0xb0, 0x4e, 0x3b,
- 0x97, 0x67, 0x15, 0x62, 0x65, 0x45, 0xac, 0x24, 0xd2, 0x00, 0xff, 0xd8,
- 0x2c, 0xff, 0x9b, 0x09, 0x59, 0xb7, 0xfc, 0x80, 0x5c, 0xca, 0xf0, 0xed,
- 0xc7, 0x2c, 0xff, 0x4f, 0xd3, 0x6f, 0x15, 0xa3, 0xc2, 0x83, 0xab, 0x13,
- 0x1f, 0x5f, 0x4f, 0x8d, 0x40, 0x59, 0xd6, 0xe0, 0x63, 0x7e, 0x05, 0xe7,
- 0x35, 0xf3, 0x30, 0xe5, 0xaf, 0x45, 0xf2, 0x3d, 0xf5, 0x58, 0x43, 0x98,
- 0xf1, 0x39, 0xf7, 0xbc, 0x76, 0x49, 0x46, 0xf7, 0x45, 0x95, 0xdc, 0x33,
- 0xd9, 0xf6, 0xd0, 0x1f, 0xc8, 0x77, 0x3a, 0x29, 0x97, 0xc5, 0xbe, 0x80,
- 0x0d, 0x09, 0xcb, 0x7a, 0x8a, 0x79, 0xaa, 0x3c, 0xeb, 0xff, 0x79, 0xfa,
- 0xf7, 0xd6, 0x84, 0xd7, 0x89, 0xb7, 0x8c, 0xa9, 0xed, 0xf9, 0x51, 0x19,
- 0x31, 0x99, 0x2f, 0xd9, 0x27, 0xea, 0x98, 0x51, 0xb7, 0x71, 0x2f, 0xfd,
- 0x6e, 0x7e, 0x40, 0xf7, 0x27, 0xf1, 0xef, 0x96, 0xbf, 0x46, 0x0f, 0x0e,
- 0x29, 0x85, 0x75, 0xe2, 0x0b, 0xd7, 0x83, 0x2b, 0x62, 0x2e, 0x8e, 0x6f,
- 0x8f, 0xcd, 0xf7, 0x8b, 0x88, 0x71, 0x88, 0x39, 0x23, 0xb3, 0xfc, 0x5b,
- 0x12, 0xf6, 0x38, 0xc9, 0x17, 0x15, 0x1c, 0x6b, 0x98, 0xe5, 0xef, 0x4e,
- 0x7b, 0xb1, 0x9d, 0xf1, 0xb8, 0xc4, 0x68, 0xc0, 0x23, 0x69, 0x15, 0xb7,
- 0xdd, 0xef, 0xc5, 0x5a, 0x72, 0xd1, 0x8d, 0x7d, 0xdf, 0x80, 0x71, 0xa9,
- 0x13, 0xb7, 0xd2, 0xfe, 0xd6, 0xf5, 0x15, 0xdb, 0x39, 0xc8, 0xfa, 0x3e,
- 0x27, 0xea, 0x2f, 0xad, 0x40, 0xbc, 0xa6, 0x18, 0xdf, 0x37, 0x1d, 0xcc,
- 0x7b, 0xca, 0x30, 0x64, 0x63, 0xa2, 0xe4, 0xb2, 0x82, 0x73, 0xa2, 0x37,
- 0x87, 0xbd, 0x2e, 0xf9, 0xf1, 0x58, 0xfe, 0x5b, 0x2b, 0x5b, 0xb3, 0xdd,
- 0xc6, 0x5f, 0x47, 0xc4, 0xb4, 0xe3, 0x25, 0x90, 0xe3, 0x69, 0x5d, 0xe7,
- 0x3d, 0x57, 0x6e, 0x51, 0xe6, 0x44, 0x02, 0x13, 0x8b, 0x15, 0x07, 0xc2,
- 0x81, 0x8a, 0x58, 0x65, 0x24, 0x8c, 0x65, 0x99, 0x2e, 0x9f, 0xcf, 0x7e,
- 0x56, 0x1d, 0xc1, 0xe9, 0x45, 0x26, 0x73, 0x60, 0x38, 0x97, 0x51, 0xf7,
- 0x4d, 0xd4, 0xeb, 0x66, 0xf3, 0x0f, 0x56, 0xd6, 0xf6, 0x7b, 0x37, 0x62,
- 0x9a, 0x65, 0xad, 0xa3, 0x7e, 0x1d, 0xd4, 0xe3, 0xcf, 0xf2, 0xfa, 0x15,
- 0x9d, 0x96, 0x8d, 0xfd, 0xde, 0x3a, 0x46, 0xfd, 0xba, 0xd9, 0x9e, 0x9b,
- 0xed, 0x95, 0x8c, 0x9d, 0xaf, 0xe7, 0x62, 0xca, 0xb3, 0xcc, 0x96, 0xa1,
- 0x52, 0x9e, 0xf5, 0xf9, 0xa3, 0x4a, 0x01, 0xb7, 0xff, 0xd4, 0x98, 0x5e,
- 0x99, 0x92, 0x83, 0x88, 0xfe, 0xfd, 0xd4, 0xbf, 0x60, 0xb8, 0xcc, 0x41,
- 0xbd, 0xac, 0xfb, 0xf4, 0x02, 0xa3, 0x4c, 0xd6, 0x15, 0x4c, 0x33, 0x22,
- 0xf8, 0x76, 0x8b, 0x07, 0x6f, 0x26, 0xca, 0xed, 0x71, 0x5f, 0x3a, 0xd7,
- 0xb2, 0x1e, 0x0f, 0xf9, 0xf1, 0x73, 0xa3, 0x2e, 0xbc, 0x40, 0xd5, 0x31,
- 0xa9, 0x79, 0x91, 0x20, 0xce, 0x76, 0xa5, 0x66, 0x73, 0xbe, 0xbc, 0xd8,
- 0x92, 0xc2, 0x46, 0xda, 0x93, 0xdf, 0x11, 0x01, 0xde, 0x48, 0x18, 0xc1,
- 0xcd, 0xec, 0x7f, 0xd8, 0xdb, 0x40, 0xfe, 0xad, 0x36, 0x91, 0xaa, 0xc5,
- 0x4b, 0x22, 0x46, 0x7c, 0x2b, 0xfe, 0xc3, 0x1a, 0x22, 0xce, 0x17, 0x85,
- 0x64, 0x6d, 0x6e, 0x0e, 0x8e, 0x6b, 0x0e, 0x3c, 0x1b, 0x9c, 0x8e, 0x28,
- 0xdd, 0xb1, 0xcc, 0x78, 0xcb, 0xfa, 0xa1, 0x57, 0xfa, 0x91, 0xb1, 0xfc,
- 0x86, 0xe3, 0x50, 0x6c, 0x2c, 0xdc, 0x92, 0x6a, 0xa0, 0xbe, 0x2f, 0xec,
- 0xff, 0xdf, 0xad, 0x49, 0xaf, 0xf4, 0xcf, 0x5c, 0x9e, 0xf1, 0xec, 0xc8,
- 0x1f, 0xc5, 0xee, 0x97, 0xac, 0xe7, 0xec, 0x36, 0x17, 0xb9, 0x73, 0x71,
- 0x50, 0xda, 0xfb, 0x17, 0x8e, 0x4f, 0xda, 0x2c, 0xf4, 0x23, 0x7a, 0xcb,
- 0xba, 0xc5, 0x9f, 0xb7, 0xa4, 0x44, 0x7f, 0x82, 0x57, 0xc7, 0x2c, 0x4c,
- 0x97, 0xf3, 0x87, 0xed, 0xb2, 0x71, 0xea, 0xab, 0x8b, 0x36, 0xc4, 0xd8,
- 0xcb, 0x3c, 0x4e, 0x76, 0x51, 0x68, 0x76, 0x9e, 0xb6, 0x89, 0xdc, 0x7e,
- 0xc8, 0x5b, 0x89, 0x2d, 0x26, 0xed, 0xce, 0x50, 0x2f, 0x76, 0x42, 0x72,
- 0x53, 0x39, 0x77, 0x61, 0xd2, 0xeb, 0xc0, 0x56, 0xd3, 0x89, 0x76, 0x43,
- 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x6b, 0x14, 0x6c, 0x0f,
- 0xab, 0x58, 0x6f, 0x74, 0xf9, 0xe5, 0xfa, 0x92, 0x90, 0x9c, 0x2b, 0x58,
- 0x43, 0x9d, 0xc4, 0x35, 0x05, 0x1b, 0x0c, 0x79, 0xbe, 0x98, 0xe3, 0xbe,
- 0x31, 0x58, 0xd6, 0x76, 0xb3, 0xf1, 0x8a, 0x32, 0x48, 0x9c, 0x17, 0x2e,
- 0xf7, 0xde, 0xcd, 0xf3, 0x03, 0x71, 0x12, 0x31, 0x3d, 0x56, 0x42, 0x3f,
- 0xdd, 0xd2, 0x37, 0x87, 0xf5, 0x14, 0x72, 0x1c, 0xa7, 0x6f, 0x1b, 0x24,
- 0x7e, 0x06, 0xfc, 0x3f, 0x65, 0xf2, 0x34, 0xe4, 0x9d, 0x47, 0xcd, 0x1a,
- 0xfe, 0x93, 0x9c, 0xb7, 0x4a, 0xc3, 0xb9, 0xf1, 0x07, 0xd0, 0xdb, 0x4b,
- 0x94, 0x79, 0xc1, 0x0a, 0xe6, 0x00, 0x71, 0xe2, 0xfb, 0xc8, 0x98, 0x13,
- 0x9b, 0x53, 0x86, 0xb6, 0xcf, 0xe6, 0x6e, 0x4e, 0xea, 0xc2, 0xc9, 0x1c,
- 0x3f, 0xa0, 0x4d, 0x28, 0x85, 0xf3, 0x39, 0x82, 0x0d, 0xe4, 0xe2, 0x82,
- 0x6f, 0x71, 0xeb, 0xc9, 0x06, 0x49, 0xdb, 0xdc, 0xfe, 0x58, 0xda, 0xc3,
- 0x43, 0xe3, 0xe1, 0xf5, 0xaf, 0x4d, 0xfb, 0xfc, 0x6b, 0xd2, 0xf0, 0xb7,
- 0xa5, 0x0b, 0x76, 0x59, 0xf0, 0x6d, 0xc1, 0x36, 0x8b, 0x7c, 0x33, 0x97,
- 0x73, 0x75, 0x49, 0x4e, 0x03, 0x79, 0x3e, 0xf6, 0xde, 0xcd, 0x4f, 0xd1,
- 0xd6, 0x5d, 0xe4, 0xf2, 0x5b, 0x8d, 0x78, 0x54, 0x9e, 0xd7, 0x19, 0x21,
- 0xdd, 0x57, 0xa4, 0xf8, 0xb1, 0xa5, 0xfe, 0x77, 0x9c, 0x4f, 0x72, 0xdc,
- 0xf4, 0xa7, 0x4a, 0x72, 0xf3, 0x21, 0x7e, 0x26, 0x18, 0xe0, 0x67, 0x1e,
- 0xe4, 0xf3, 0x77, 0xb1, 0x9f, 0x4d, 0xe9, 0xa9, 0x3e, 0xa0, 0xe0, 0x1a,
- 0xb6, 0xd5, 0x18, 0x82, 0x73, 0x69, 0xfd, 0x7f, 0x59, 0x59, 0xef, 0xd4,
- 0x7d, 0x11, 0x20, 0x87, 0x80, 0xb3, 0xad, 0x5e, 0xce, 0x15, 0x34, 0x86,
- 0xe5, 0x5c, 0x41, 0x9b, 0x91, 0x93, 0x4f, 0x7c, 0xb7, 0x9b, 0xb8, 0x7d,
- 0xee, 0xfc, 0x42, 0x2c, 0x32, 0x71, 0x7b, 0x0a, 0xb1, 0xa2, 0x88, 0x60,
- 0x91, 0xdb, 0xff, 0x5c, 0xba, 0x9e, 0x5c, 0x5c, 0x9e, 0x7f, 0xbb, 0x39,
- 0xe7, 0x1e, 0xff, 0xb3, 0xe9, 0x2b, 0x71, 0xdb, 0xae, 0x30, 0xda, 0x77,
- 0xc9, 0x86, 0x23, 0xe6, 0x60, 0xa1, 0x80, 0x7f, 0x14, 0x9a, 0xff, 0x38,
- 0x75, 0x72, 0x94, 0x72, 0x1e, 0x3b, 0x4f, 0x4e, 0xd1, 0x21, 0xfc, 0x77,
- 0x24, 0xdc, 0x48, 0x87, 0xde, 0xb7, 0xe2, 0x36, 0xe7, 0xf0, 0xfa, 0xef,
- 0x4c, 0xf8, 0x91, 0xb5, 0xb9, 0xe7, 0xbf, 0xbb, 0x25, 0x47, 0xec, 0x49,
- 0xc5, 0xa3, 0x4c, 0x79, 0xf3, 0xf3, 0xab, 0x87, 0x65, 0x6e, 0xdf, 0x48,
- 0xc8, 0xbd, 0xe8, 0x37, 0x54, 0xe8, 0x7e, 0x95, 0xb1, 0xb4, 0xdf, 0x14,
- 0xfb, 0xb5, 0xec, 0x67, 0xfb, 0xac, 0x18, 0xf7, 0x44, 0x02, 0xad, 0xf5,
- 0xbc, 0xae, 0x2d, 0x40, 0xac, 0x8a, 0x7a, 0x2a, 0x35, 0xbc, 0xfe, 0xba,
- 0x71, 0x9f, 0xdf, 0x1c, 0x87, 0xff, 0x92, 0xf1, 0xa9, 0x22, 0x90, 0xa3,
- 0xab, 0x1f, 0x87, 0x05, 0x5e, 0xff, 0xba, 0xc4, 0x1c, 0xa8, 0x91, 0xb8,
- 0xb5, 0xa4, 0xe1, 0xb4, 0x35, 0x27, 0x62, 0x64, 0x8f, 0x51, 0x86, 0xf7,
- 0x2f, 0xd7, 0xe3, 0x33, 0x1d, 0x47, 0xef, 0xd5, 0xa6, 0xf4, 0xf1, 0x5e,
- 0xe8, 0xff, 0x6f, 0x1f, 0x85, 0x38, 0x47, 0x7b, 0x68, 0x90, 0x31, 0x48,
- 0xbc, 0x2b, 0x62, 0xce, 0x29, 0x63, 0xf9, 0x54, 0xe1, 0xb9, 0x47, 0x7e,
- 0x5c, 0x0a, 0xe7, 0x1a, 0x36, 0x0f, 0xce, 0xc5, 0x30, 0xcb, 0xea, 0x36,
- 0x7c, 0xf9, 0xe7, 0x67, 0x9c, 0xb3, 0xcc, 0xd1, 0x2b, 0x9c, 0x58, 0x4c,
- 0x3f, 0x68, 0xfc, 0x4b, 0x27, 0xa2, 0xbe, 0x62, 0xc6, 0x56, 0x59, 0x17,
- 0x3a, 0x5e, 0x3f, 0x69, 0x4d, 0x18, 0xf5, 0x68, 0xcc, 0xc8, 0xf3, 0x4c,
- 0x07, 0xed, 0xdb, 0xc2, 0x23, 0xa6, 0xdc, 0x17, 0x9c, 0x89, 0xc7, 0x1c,
- 0xb4, 0x15, 0xb7, 0xa1, 0xb7, 0xfe, 0xbd, 0x52, 0x81, 0xd2, 0x88, 0x33,
- 0x38, 0x01, 0x3d, 0xbc, 0x5e, 0xa1, 0x1f, 0x56, 0xcd, 0x33, 0x65, 0x0a,
- 0xde, 0x4e, 0x04, 0xcc, 0x40, 0x3e, 0x2e, 0x9d, 0xe2, 0xdc, 0xbd, 0x93,
- 0x30, 0xda, 0x9f, 0xca, 0x9f, 0xff, 0x22, 0x3d, 0x35, 0xa7, 0x15, 0x7b,
- 0x74, 0xbb, 0x37, 0x25, 0xf0, 0x9e, 0xa3, 0x01, 0xef, 0xed, 0x31, 0x8b,
- 0x98, 0x8b, 0x89, 0x9d, 0xba, 0xdd, 0x5b, 0x12, 0x98, 0x74, 0xf2, 0xda,
- 0x29, 0x73, 0x36, 0x31, 0x4d, 0xe5, 0xb5, 0xb0, 0xd8, 0x59, 0x4c, 0x63,
- 0x7c, 0x2d, 0x8d, 0x78, 0xdd, 0xa5, 0xe3, 0xd0, 0x4a, 0x8c, 0x0a, 0xe6,
- 0xba, 0x68, 0x72, 0x24, 0x75, 0x7f, 0xb3, 0xa3, 0x9e, 0x39, 0xaf, 0x5f,
- 0x71, 0x19, 0xdf, 0x63, 0x5e, 0x2f, 0x6b, 0x61, 0x61, 0xda, 0xa4, 0x93,
- 0x15, 0x76, 0x4c, 0x57, 0x23, 0x0a, 0xb1, 0xb0, 0x02, 0xb7, 0x6b, 0x1b,
- 0x3e, 0xab, 0x46, 0xfa, 0x71, 0x7d, 0x83, 0xbb, 0xa9, 0x72, 0xbc, 0xa0,
- 0x13, 0xc4, 0x3c, 0x11, 0xe6, 0x25, 0x06, 0xd4, 0xf2, 0x88, 0xe8, 0xc6,
- 0xdf, 0x94, 0x1c, 0x13, 0x59, 0x35, 0x77, 0xdf, 0xd8, 0x3b, 0x25, 0x28,
- 0x0d, 0x13, 0xab, 0x7e, 0xe2, 0xfb, 0xef, 0xd5, 0x3b, 0x5a, 0x22, 0x78,
- 0xef, 0x32, 0xe4, 0xbf, 0x6d, 0x5b, 0x6e, 0x77, 0xe4, 0x83, 0x98, 0x3b,
- 0x60, 0x59, 0x8c, 0x93, 0x3e, 0x28, 0xb3, 0x39, 0x1e, 0xfa, 0x1a, 0xe7,
- 0x66, 0x4d, 0xfa, 0x0f, 0xd6, 0xe7, 0x9c, 0x36, 0x07, 0x70, 0x17, 0x47,
- 0x3a, 0x6e, 0x79, 0xcb, 0xf8, 0xc0, 0x7a, 0x33, 0xc1, 0x5c, 0xd9, 0x90,
- 0x67, 0x43, 0x73, 0xb0, 0xcd, 0x74, 0x36, 0x2f, 0x55, 0x14, 0xf4, 0x18,
- 0xf3, 0xb4, 0x12, 0xc6, 0xa9, 0x6e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0xf7,
- 0x80, 0xe5, 0xd2, 0xeb, 0xd6, 0xb9, 0x22, 0x77, 0xde, 0x32, 0xd2, 0x20,
- 0x58, 0x10, 0x6e, 0x7b, 0xca, 0x68, 0x41, 0x4f, 0x66, 0x10, 0xbd, 0x99,
- 0x5c, 0x3f, 0x59, 0xcc, 0xf9, 0x98, 0x7e, 0xd6, 0xad, 0x2b, 0x8e, 0x08,
- 0xf7, 0x3a, 0x73, 0xcb, 0x5e, 0x23, 0x8a, 0xcd, 0x99, 0x3b, 0x6f, 0x39,
- 0xd5, 0xd0, 0xcf, 0xff, 0xb9, 0x3a, 0x43, 0xa8, 0xfc, 0xd8, 0x3a, 0x65,
- 0x11, 0xe9, 0xa3, 0xe3, 0x96, 0xa7, 0x8c, 0x3b, 0x6f, 0x69, 0x5f, 0xf4,
- 0x4d, 0x6c, 0xca, 0xb4, 0xff, 0xc9, 0x7e, 0xca, 0x59, 0xa7, 0x34, 0x72,
- 0xa8, 0xed, 0x9a, 0xc0, 0x9d, 0xb7, 0xa4, 0x17, 0xf5, 0xb2, 0x8f, 0x55,
- 0x8c, 0x2f, 0xb9, 0x3a, 0x51, 0xc6, 0xf6, 0x8f, 0xd3, 0x41, 0x49, 0x64,
- 0xa2, 0x6d, 0x7e, 0xe0, 0x03, 0x6b, 0x5e, 0x5f, 0x91, 0xad, 0x03, 0x17,
- 0x75, 0xf0, 0xa0, 0xe9, 0xcc, 0x06, 0x1c, 0xb6, 0x0e, 0x3a, 0x7c, 0xd4,
- 0x41, 0x92, 0x3a, 0xc8, 0xd6, 0x18, 0xe1, 0x77, 0xa9, 0x83, 0x79, 0x63,
- 0xeb, 0xd6, 0x95, 0x44, 0xe0, 0x74, 0x18, 0xaf, 0x3a, 0x9c, 0x9c, 0x0b,
- 0x97, 0xb1, 0x8e, 0x7a, 0xbb, 0xf3, 0x96, 0x8b, 0x17, 0xd9, 0x3a, 0xff,
- 0xb2, 0x3b, 0xb0, 0xc1, 0xde, 0x3b, 0xd7, 0x9d, 0x59, 0xc3, 0xa3, 0x99,
- 0xc7, 0x7d, 0x3c, 0x7a, 0x98, 0xb3, 0xdc, 0x4c, 0x5d, 0x35, 0x71, 0x1c,
- 0x2b, 0x28, 0xd7, 0x46, 0xfe, 0x6e, 0xe5, 0xef, 0x0e, 0xfe, 0x96, 0xf9,
- 0x51, 0xcf, 0xca, 0x16, 0x3b, 0x2b, 0x9b, 0x83, 0xf2, 0x78, 0x88, 0x57,
- 0x32, 0x26, 0xf7, 0x57, 0xae, 0x09, 0xc4, 0xd8, 0xc6, 0xfd, 0xa5, 0xb2,
- 0x6f, 0xc8, 0x65, 0xc4, 0x7d, 0x4e, 0x88, 0x7c, 0x7a, 0x6b, 0x3b, 0xb2,
- 0xc4, 0xde, 0xdf, 0xe7, 0xb0, 0x97, 0xb2, 0x55, 0x70, 0x7e, 0x5e, 0x58,
- 0x34, 0x34, 0xc3, 0x63, 0xc0, 0xe7, 0x36, 0xe2, 0xcc, 0xf9, 0x13, 0xd4,
- 0x81, 0xd8, 0xc9, 0x3d, 0xd4, 0x5f, 0x27, 0xeb, 0x1c, 0x65, 0x2c, 0xdb,
- 0xcd, 0xfe, 0xed, 0xf5, 0xdb, 0xb0, 0xfd, 0x9c, 0x0c, 0xba, 0x79, 0x9c,
- 0xed, 0xed, 0x35, 0x7e, 0x53, 0x76, 0xb4, 0x5e, 0xf6, 0x53, 0x3a, 0x31,
- 0x6c, 0xcf, 0xbb, 0x42, 0x2e, 0x73, 0x11, 0x79, 0x82, 0x65, 0xfd, 0xd4,
- 0x68, 0x9c, 0xef, 0xb0, 0xed, 0xea, 0x50, 0x9b, 0x3b, 0xe0, 0xc6, 0x90,
- 0xbd, 0x06, 0x6e, 0x59, 0x45, 0xb6, 0x7d, 0x89, 0x2c, 0x75, 0xcd, 0x9b,
- 0x68, 0x78, 0xeb, 0xd2, 0x1f, 0x90, 0x27, 0x8a, 0xfc, 0x73, 0x70, 0x92,
- 0x31, 0x35, 0xaa, 0xc5, 0xdb, 0x45, 0xd6, 0x32, 0xc3, 0x19, 0xbe, 0x16,
- 0xf1, 0x16, 0x27, 0xfb, 0x6b, 0x26, 0xa7, 0x3c, 0x95, 0xc7, 0xee, 0x7d,
- 0x69, 0x3d, 0xb6, 0x5f, 0xc9, 0xf1, 0xd3, 0xde, 0xb1, 0x42, 0xfc, 0x09,
- 0x92, 0xcf, 0x7a, 0xe0, 0x8c, 0xe8, 0xfe, 0x26, 0x47, 0x57, 0xd0, 0x05,
- 0xfa, 0x58, 0xa9, 0xc8, 0x1b, 0xa7, 0xec, 0x82, 0xc7, 0x6e, 0x6d, 0x8d,
- 0x8d, 0xd1, 0xf1, 0xf9, 0x2e, 0x78, 0xb4, 0xb5, 0xe9, 0x42, 0xec, 0xf2,
- 0x68, 0x6d, 0x09, 0xf1, 0x77, 0x59, 0xab, 0x0f, 0xdb, 0xdc, 0xe3, 0x48,
- 0xe6, 0xa5, 0x52, 0xd9, 0x8b, 0x47, 0xdf, 0xaf, 0x70, 0x1a, 0xb9, 0x76,
- 0x35, 0xb6, 0xdb, 0xe2, 0xd0, 0x70, 0xce, 0x77, 0x75, 0xad, 0xc5, 0x21,
- 0xfb, 0x5f, 0x89, 0x4a, 0xe9, 0x7c, 0xbd, 0x1c, 0x7e, 0x2d, 0x76, 0xd9,
- 0xf8, 0xc5, 0x36, 0x4a, 0x81, 0x25, 0x89, 0x0b, 0xfb, 0x97, 0xfe, 0xa4,
- 0xdf, 0xae, 0x2a, 0x15, 0x13, 0xf6, 0xb3, 0x92, 0x83, 0x99, 0x18, 0x06,
- 0x53, 0x53, 0xf7, 0xe8, 0xe9, 0x87, 0xd8, 0xfe, 0x81, 0x38, 0xe7, 0x69,
- 0xb6, 0x21, 0xfb, 0xf7, 0x64, 0xcf, 0xde, 0xd4, 0xfd, 0x7a, 0x22, 0x5b,
- 0x65, 0x19, 0x81, 0x0d, 0x7b, 0x89, 0x7f, 0xd1, 0x16, 0xa9, 0x6f, 0x59,
- 0xaf, 0xcd, 0x0b, 0x22, 0x3b, 0xcd, 0x89, 0xc1, 0xb9, 0xc0, 0x40, 0x52,
- 0xf6, 0x53, 0x9d, 0x89, 0xad, 0x66, 0x1e, 0x19, 0xad, 0xae, 0xd3, 0xba,
- 0x55, 0xd9, 0x0b, 0xf5, 0xc1, 0x97, 0x7b, 0x8c, 0x5a, 0xad, 0x47, 0xcd,
- 0xee, 0x67, 0x7c, 0xd9, 0x0d, 0xcc, 0x2e, 0x13, 0x0c, 0xa8, 0x32, 0xa2,
- 0xbd, 0x55, 0x98, 0x0b, 0x7f, 0xb5, 0x8d, 0xcb, 0xf1, 0x6f, 0xab, 0x46,
- 0x70, 0xa5, 0xf0, 0x4a, 0xf5, 0x7d, 0x6b, 0x88, 0xdc, 0xe4, 0xee, 0xb9,
- 0xff, 0xa7, 0x34, 0xbf, 0xee, 0xd4, 0x3e, 0x9d, 0xf3, 0xf2, 0xf3, 0x05,
- 0xba, 0x3f, 0xad, 0x88, 0x8e, 0x84, 0x4b, 0x25, 0xb0, 0x95, 0x71, 0xf6,
- 0xbf, 0xe6, 0x46, 0xb0, 0x8f, 0xff, 0x7f, 0x76, 0xa5, 0xec, 0x4d, 0xb5,
- 0xac, 0x60, 0x60, 0x5e, 0xb8, 0x8a, 0x63, 0x78, 0x96, 0xf7, 0x7b, 0x33,
- 0x6f, 0x59, 0xa7, 0xa6, 0x1b, 0xfd, 0xcb, 0x18, 0xec, 0x06, 0xc6, 0x75,
- 0x6d, 0x52, 0xfd, 0xef, 0xee, 0x95, 0x83, 0xbb, 0x82, 0x63, 0xf9, 0x7e,
- 0xa0, 0x4e, 0x4b, 0xaa, 0xa5, 0x65, 0xa2, 0xd7, 0x81, 0xf1, 0x57, 0xa6,
- 0x3c, 0x3b, 0x28, 0xf0, 0x59, 0x7b, 0x5d, 0xa5, 0x77, 0x88, 0xbe, 0x3e,
- 0xa4, 0x45, 0xe3, 0xd4, 0xbb, 0x7b, 0x1a, 0xc7, 0x7c, 0xf7, 0xdc, 0x2f,
- 0xd9, 0xe3, 0xac, 0x36, 0x66, 0x72, 0x8c, 0x0a, 0xb4, 0xb9, 0xff, 0x99,
- 0x5f, 0x7f, 0x6d, 0x24, 0xfb, 0x1a, 0xb2, 0x9a, 0xe8, 0x1b, 0x45, 0xac,
- 0x73, 0xb5, 0xf9, 0xf0, 0x8c, 0xae, 0x7a, 0xdd, 0x77, 0x37, 0x6d, 0x34,
- 0x34, 0xf7, 0xd7, 0x16, 0x6d, 0xda, 0xfc, 0x16, 0x47, 0x7d, 0x5b, 0xc2,
- 0x8e, 0x55, 0x9c, 0x57, 0x23, 0x3a, 0x57, 0x79, 0xc7, 0x42, 0x4d, 0x20,
- 0x3c, 0xd7, 0x1e, 0x3f, 0x70, 0x6b, 0x3a, 0x81, 0x6d, 0x29, 0x69, 0x53,
- 0xc1, 0xb2, 0xc0, 0xdb, 0x96, 0x7f, 0x7a, 0x02, 0x5b, 0x32, 0x9f, 0xc4,
- 0x4d, 0x07, 0xc9, 0x8d, 0xf5, 0xd6, 0x38, 0xf4, 0x68, 0xee, 0xd9, 0xd4,
- 0x1c, 0x59, 0xdb, 0x96, 0xbd, 0x45, 0xb7, 0x24, 0x02, 0x70, 0x97, 0x13,
- 0x83, 0xc7, 0x02, 0xf2, 0x2c, 0xd3, 0x8b, 0x6c, 0x8b, 0x94, 0xa9, 0xd5,
- 0xc6, 0x90, 0x25, 0x73, 0x94, 0xb5, 0xd0, 0xfe, 0xb2, 0xdc, 0x3e, 0x09,
- 0x1a, 0x5e, 0x8d, 0xae, 0xbd, 0x41, 0xae, 0xd7, 0x6c, 0x48, 0x1b, 0x0a,
- 0xe6, 0x07, 0xa6, 0xa1, 0x6e, 0xe5, 0xab, 0xaf, 0x17, 0x05, 0x8a, 0x18,
- 0x4f, 0xc4, 0xb7, 0x8c, 0x8d, 0xc7, 0xf0, 0x1b, 0x62, 0x90, 0xec, 0x19,
- 0x4b, 0x4a, 0x3d, 0xb6, 0x35, 0x17, 0x69, 0xf1, 0x53, 0x43, 0xf6, 0x2f,
- 0x5b, 0xd6, 0x35, 0x81, 0x37, 0xad, 0x68, 0x0d, 0xe5, 0x21, 0x5f, 0xcb,
- 0xd5, 0x95, 0x32, 0xf9, 0xbd, 0x40, 0x4a, 0xe3, 0x2d, 0xa2, 0x93, 0x27,
- 0xcd, 0x38, 0xb3, 0x01, 0xc1, 0xfd, 0x0f, 0x62, 0x6f, 0x19, 0x8a, 0xfd,
- 0x8c, 0x71, 0x99, 0x52, 0xc9, 0x38, 0xea, 0xf4, 0x8f, 0xd8, 0xeb, 0x05,
- 0x1d, 0xc4, 0x68, 0xe1, 0x97, 0x92, 0xf3, 0x39, 0xf1, 0x94, 0x51, 0x85,
- 0x27, 0xb5, 0x1c, 0x57, 0x23, 0xd6, 0xe1, 0x07, 0x89, 0x79, 0x59, 0x7a,
- 0x08, 0x39, 0xaf, 0xd1, 0x7e, 0x46, 0xf9, 0x0d, 0xfd, 0x1c, 0x78, 0x21,
- 0xbd, 0x11, 0x0f, 0xca, 0x1a, 0xa2, 0x52, 0xdb, 0x5c, 0xe7, 0x90, 0xfe,
- 0x36, 0x62, 0x6b, 0x46, 0xda, 0xfa, 0x20, 0xb6, 0xd7, 0xd8, 0x9d, 0x97,
- 0x55, 0xb0, 0xfc, 0x83, 0xd8, 0x53, 0xc6, 0xe3, 0xf6, 0xdc, 0xc9, 0x73,
- 0xaf, 0x5e, 0x53, 0x30, 0xaf, 0x14, 0x2a, 0xf3, 0x06, 0x87, 0x71, 0x33,
- 0x1c, 0x55, 0xdf, 0xa4, 0xed, 0xc9, 0xbe, 0x9a, 0xaf, 0xc2, 0x59, 0xe5,
- 0xa2, 0x6f, 0xde, 0x0a, 0x57, 0x95, 0x70, 0xf5, 0x02, 0x8f, 0x8e, 0xf2,
- 0xbe, 0xe8, 0x36, 0xdc, 0x26, 0xba, 0x75, 0x12, 0x87, 0x7a, 0x24, 0xaf,
- 0x33, 0x2a, 0xa9, 0x23, 0xbd, 0x95, 0x9c, 0x1e, 0xe5, 0xc4, 0x4c, 0xc6,
- 0x47, 0x37, 0xf3, 0xb7, 0xb6, 0x77, 0xa9, 0xf7, 0x79, 0x7d, 0x65, 0xe4,
- 0xf0, 0x96, 0xf5, 0x3e, 0x39, 0xfc, 0xfc, 0x40, 0x5d, 0xd6, 0x20, 0x4e,
- 0xe1, 0x06, 0xbd, 0x39, 0x4e, 0xbc, 0x59, 0x6d, 0x9c, 0xb1, 0x62, 0xab,
- 0xa4, 0x8c, 0xee, 0x8b, 0x29, 0x85, 0x3e, 0x16, 0xc0, 0x3f, 0xcd, 0x82,
- 0x2b, 0x22, 0xcf, 0x14, 0x64, 0xbd, 0xb8, 0x51, 0x9e, 0xf5, 0xb5, 0xc8,
- 0xf8, 0x5d, 0xb2, 0xee, 0x86, 0xe8, 0x84, 0x0b, 0x46, 0x76, 0x9f, 0xcc,
- 0xd9, 0x0c, 0x0b, 0x81, 0x85, 0xbf, 0x67, 0x2e, 0x24, 0xf3, 0x53, 0x9b,
- 0xad, 0x57, 0xb2, 0x41, 0x1f, 0x39, 0xfd, 0xa3, 0xd0, 0x5b, 0x12, 0xd4,
- 0x75, 0x53, 0x48, 0x9e, 0xdf, 0x3b, 0x7d, 0x09, 0xd8, 0x3c, 0xde, 0x3c,
- 0x89, 0xcf, 0xa1, 0x9c, 0xb9, 0xeb, 0xdc, 0xb1, 0x15, 0xa8, 0xa8, 0x8a,
- 0xfa, 0x4a, 0x71, 0x19, 0xcf, 0xd7, 0x30, 0x3f, 0xf9, 0x22, 0x2a, 0x56,
- 0xb6, 0x22, 0xc1, 0xb1, 0x97, 0x1b, 0x7f, 0xc5, 0x6b, 0xf7, 0x21, 0x99,
- 0x72, 0x71, 0x1c, 0x3f, 0xb1, 0x2a, 0x6a, 0x44, 0x36, 0xd3, 0x5b, 0x66,
- 0x30, 0x9f, 0xb6, 0x75, 0x41, 0xdc, 0x4e, 0x09, 0x47, 0xaa, 0x8b, 0xae,
- 0x07, 0x73, 0xfb, 0x1a, 0xbd, 0x75, 0x8d, 0xd2, 0x41, 0x9b, 0xed, 0xa1,
- 0xce, 0xa5, 0xac, 0x65, 0x2d, 0x0f, 0x9c, 0xa6, 0x8e, 0x3b, 0x78, 0x6e,
- 0xf8, 0xdf, 0x84, 0x7a, 0x59, 0x31, 0x4e, 0x58, 0x71, 0xcd, 0x47, 0xbb,
- 0x54, 0x57, 0x09, 0x9f, 0x5a, 0x1a, 0x7a, 0x8f, 0xf7, 0xb5, 0xbc, 0x9d,
- 0x9e, 0xb9, 0x25, 0xa7, 0xcb, 0x30, 0x75, 0xf9, 0x6f, 0xf6, 0x75, 0x87,
- 0x7d, 0xbd, 0x23, 0x7f, 0xfd, 0xcc, 0x2d, 0x3d, 0xc6, 0xcb, 0xbc, 0xde,
- 0x4b, 0xdd, 0xab, 0x17, 0x49, 0xfd, 0x75, 0xa6, 0xd4, 0x67, 0x4a, 0x65,
- 0xf4, 0xe4, 0xe7, 0xe3, 0x50, 0x7e, 0x3e, 0x26, 0xf2, 0x6d, 0x38, 0xd9,
- 0x46, 0x3c, 0x5a, 0x0a, 0x13, 0x65, 0x01, 0xc1, 0x79, 0x91, 0x8b, 0x73,
- 0x97, 0x11, 0xb9, 0xd6, 0x30, 0xde, 0x75, 0x3d, 0x53, 0x8a, 0x78, 0xc7,
- 0x4c, 0xdb, 0x0e, 0xcf, 0xdc, 0x22, 0xfb, 0xde, 0xde, 0x52, 0x1a, 0x7d,
- 0xb2, 0x65, 0x23, 0x45, 0x2e, 0x7b, 0xaf, 0xe9, 0x0c, 0xd7, 0x3b, 0xe6,
- 0x65, 0x8b, 0x61, 0xc4, 0xce, 0x28, 0x2e, 0x8f, 0xe0, 0x43, 0x22, 0xdd,
- 0xc8, 0xcc, 0x2b, 0x1e, 0x64, 0xce, 0x14, 0xcc, 0x50, 0xb7, 0x6d, 0x44,
- 0xec, 0x43, 0xf6, 0xde, 0x37, 0xe7, 0xc4, 0x0a, 0x34, 0xea, 0x0e, 0xcc,
- 0x0b, 0xcf, 0x64, 0xe6, 0x45, 0xbb, 0x34, 0x8b, 0x1d, 0xba, 0xff, 0x7a,
- 0x2c, 0xb7, 0xeb, 0xed, 0x4b, 0x67, 0xdb, 0x4b, 0x39, 0xa7, 0x8f, 0x51,
- 0x8e, 0x6d, 0x01, 0x91, 0xe3, 0x9b, 0x79, 0x39, 0x5a, 0x19, 0x4b, 0x4d,
- 0xed, 0xda, 0x40, 0xef, 0x59, 0xbd, 0x3d, 0x63, 0xeb, 0xed, 0x3e, 0x9e,
- 0x17, 0x33, 0xbf, 0x2f, 0xc2, 0xd1, 0x7a, 0x6f, 0x7e, 0x1f, 0x9b, 0xe4,
- 0x6a, 0x82, 0xbf, 0x0d, 0x7f, 0xbd, 0xda, 0xd0, 0xc3, 0x0e, 0x9b, 0xd7,
- 0xbb, 0x11, 0xb7, 0x39, 0xb3, 0x3c, 0xf3, 0xae, 0xc0, 0x23, 0x76, 0x39,
- 0x17, 0x75, 0x52, 0x86, 0x47, 0xf3, 0xfe, 0x22, 0x7b, 0x0e, 0x1e, 0xb3,
- 0x7f, 0xef, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0x85, 0x18, 0x25, 0xeb, 0xed,
- 0xff, 0xc3, 0xf6, 0xfd, 0x21, 0x1c, 0xb7, 0xff, 0x67, 0x73, 0xf9, 0x16,
- 0x7a, 0x4c, 0xd9, 0x3b, 0x53, 0x86, 0x6e, 0x7b, 0x0f, 0xb9, 0xac, 0x01,
- 0x5c, 0x89, 0xcd, 0x9a, 0xac, 0x07, 0x93, 0xfb, 0x68, 0x62, 0x13, 0x9d,
- 0x48, 0x6a, 0xa6, 0x37, 0x53, 0x3f, 0x35, 0x57, 0x32, 0xb1, 0xa7, 0xfe,
- 0x03, 0x2b, 0x6a, 0xe7, 0x4f, 0x27, 0xac, 0xbd, 0xc6, 0xd1, 0x10, 0x3d,
- 0xb8, 0xbd, 0xc8, 0xd6, 0x6f, 0xb8, 0xcd, 0xde, 0xff, 0x47, 0x99, 0x9f,
- 0x49, 0x48, 0x1c, 0x9d, 0x83, 0xb4, 0x69, 0xc7, 0xe2, 0x96, 0xed, 0x9c,
- 0x93, 0x9e, 0x54, 0x20, 0x7a, 0x09, 0xef, 0x4d, 0x30, 0x96, 0x75, 0x53,
- 0x9f, 0xb1, 0x16, 0xe1, 0x67, 0x6b, 0xb0, 0x9b, 0x36, 0x36, 0x6e, 0x5a,
- 0xd6, 0x3e, 0x62, 0x44, 0xe5, 0x3c, 0x15, 0xd9, 0x9a, 0x35, 0x48, 0x31,
- 0x36, 0xed, 0x33, 0x1a, 0x3f, 0x57, 0x84, 0xb8, 0xdf, 0x0d, 0xdd, 0xb7,
- 0x85, 0xa3, 0xb9, 0x97, 0xf3, 0x75, 0xd4, 0x14, 0xde, 0xe8, 0x3c, 0xb3,
- 0x14, 0x46, 0x78, 0xb1, 0xe3, 0x27, 0xd6, 0xa4, 0xfd, 0xec, 0xb8, 0xeb,
- 0x5f, 0x28, 0xc3, 0x46, 0x71, 0xde, 0x4a, 0xce, 0xf1, 0xbb, 0x01, 0x79,
- 0x7e, 0x0d, 0xd4, 0xf5, 0x35, 0xb6, 0x8b, 0x0c, 0x7b, 0x43, 0xce, 0xd8,
- 0x3e, 0x04, 0x5a, 0x36, 0x28, 0xe7, 0x72, 0x83, 0x4b, 0xc6, 0x4c, 0x8c,
- 0xd6, 0x3f, 0x4b, 0x1e, 0x23, 0xf5, 0x8b, 0xf1, 0x84, 0xf9, 0xb4, 0x55,
- 0x3b, 0xe3, 0xfb, 0xd6, 0x7e, 0x43, 0x5d, 0x4f, 0x6d, 0xc7, 0xca, 0xd9,
- 0x56, 0x19, 0xdb, 0xba, 0x3d, 0xa0, 0x9b, 0xdb, 0xd9, 0xd6, 0xf1, 0xc4,
- 0xd1, 0xa0, 0x9b, 0x6d, 0x3d, 0x6a, 0x4a, 0x6e, 0xe0, 0x6c, 0x6e, 0xe6,
- 0xdc, 0x76, 0xa5, 0x02, 0xbe, 0xad, 0x94, 0x4b, 0xf2, 0xb7, 0xaf, 0x26,
- 0xe4, 0x5d, 0x8f, 0x6f, 0x72, 0x3c, 0xd1, 0x8d, 0x2e, 0x34, 0xde, 0x5b,
- 0x41, 0xfb, 0xa9, 0x44, 0xc1, 0xd6, 0x75, 0x1f, 0xf1, 0x0e, 0xb7, 0xb3,
- 0xcc, 0xeb, 0x81, 0x39, 0x78, 0x21, 0xd4, 0xb8, 0x72, 0x0e, 0x9c, 0xe4,
- 0x21, 0x81, 0xe6, 0x0d, 0x4a, 0x5c, 0x13, 0x5b, 0xbc, 0x2d, 0xad, 0x07,
- 0x9b, 0x20, 0xd8, 0xdd, 0x4a, 0x7d, 0xcc, 0xc1, 0xfb, 0x0b, 0x45, 0x2e,
- 0x67, 0x38, 0xe8, 0x08, 0x74, 0x3c, 0xcd, 0xf9, 0xad, 0x98, 0x97, 0xcb,
- 0x53, 0x33, 0xf6, 0x7e, 0xcd, 0x56, 0x24, 0x33, 0x27, 0xde, 0xdd, 0x6b,
- 0xc0, 0x79, 0xa8, 0xfe, 0x41, 0x0b, 0xf6, 0xbb, 0x21, 0x8d, 0x32, 0x0f,
- 0xad, 0x32, 0x0f, 0xa5, 0xf4, 0xa7, 0x6b, 0x28, 0xf7, 0x7a, 0x5b, 0xee,
- 0x39, 0x18, 0x36, 0x65, 0xfd, 0xcb, 0xa9, 0xdd, 0x86, 0x5e, 0x62, 0x67,
- 0xe0, 0x4c, 0x17, 0xfb, 0x79, 0x9d, 0x32, 0xcf, 0xa3, 0xde, 0x27, 0x5b,
- 0x84, 0xb7, 0xde, 0x87, 0xbe, 0x54, 0xe1, 0xdd, 0x11, 0x05, 0xe9, 0x80,
- 0xf4, 0x71, 0x1f, 0x79, 0x5c, 0x97, 0x35, 0x59, 0x23, 0xd7, 0x77, 0x33,
- 0xf7, 0x8f, 0x6a, 0xf4, 0x07, 0xea, 0x1d, 0xfa, 0x1c, 0xe8, 0x13, 0x6f,
- 0x38, 0xa2, 0xf4, 0x01, 0xd3, 0x7b, 0x86, 0xd8, 0x70, 0x08, 0x1d, 0x16,
- 0xaa, 0x6c, 0x7b, 0xf8, 0xd9, 0x88, 0xf1, 0xa1, 0x22, 0xb1, 0x3d, 0x4b,
- 0x1d, 0xa8, 0x9c, 0x13, 0xd1, 0x41, 0x39, 0x7d, 0x76, 0x2c, 0xa0, 0xfb,
- 0x5f, 0xa0, 0x3c, 0xdb, 0x29, 0xcf, 0x8a, 0xdc, 0x1c, 0xfa, 0x36, 0x2b,
- 0xe2, 0xd3, 0x81, 0x96, 0xd5, 0xbc, 0xbe, 0x8d, 0xf2, 0x04, 0xfa, 0x14,
- 0x0c, 0xb5, 0xf4, 0x90, 0x2b, 0x76, 0x50, 0x07, 0xe7, 0xe4, 0x71, 0xdb,
- 0x73, 0xd6, 0x41, 0x2e, 0x50, 0x8c, 0xbd, 0xa6, 0xe0, 0xb7, 0x86, 0x61,
- 0xda, 0xe9, 0x1e, 0xce, 0x48, 0xd4, 0xab, 0xa2, 0xd8, 0x10, 0x0c, 0xa8,
- 0xe1, 0x35, 0x17, 0xe7, 0xa6, 0x12, 0xfb, 0xb5, 0xdd, 0xf6, 0x5e, 0xe5,
- 0x1c, 0xb7, 0xfb, 0x83, 0x35, 0xea, 0x15, 0x7e, 0x26, 0xeb, 0x63, 0xb2,
- 0x86, 0xd4, 0xeb, 0xc9, 0xed, 0xd7, 0x72, 0x51, 0x27, 0xb9, 0xeb, 0xcf,
- 0x68, 0xc2, 0x7d, 0x0b, 0xe5, 0x7f, 0x69, 0x3d, 0x69, 0x97, 0x97, 0x72,
- 0x2e, 0x9b, 0xa3, 0x97, 0xda, 0xe5, 0x7e, 0x69, 0x3d, 0xab, 0x39, 0xa7,
- 0x94, 0x2b, 0x3c, 0x2f, 0x3c, 0xfa, 0x0d, 0x27, 0x31, 0xaf, 0x78, 0xee,
- 0x62, 0x1c, 0x33, 0x4e, 0xd4, 0x9e, 0xac, 0xef, 0x64, 0x1c, 0x9b, 0xba,
- 0x7f, 0xcb, 0xc2, 0xe3, 0x76, 0x1e, 0xde, 0x45, 0x3e, 0x7b, 0x74, 0x47,
- 0x11, 0x84, 0xa3, 0xca, 0xfa, 0x5d, 0x73, 0xd9, 0xb9, 0x5c, 0x56, 0xf6,
- 0x35, 0x5d, 0x66, 0x73, 0xc3, 0xa8, 0x2a, 0xb8, 0xfb, 0x49, 0x7b, 0xf8,
- 0x84, 0xbb, 0x74, 0x62, 0x8f, 0x51, 0xe0, 0x2c, 0x47, 0x1f, 0x54, 0x89,
- 0x93, 0x03, 0xe6, 0x62, 0x89, 0xcd, 0x7e, 0xd6, 0x0f, 0xc6, 0xd4, 0xa9,
- 0xdc, 0xe6, 0x76, 0x0f, 0x2a, 0xba, 0xb6, 0x3a, 0x20, 0xfb, 0x47, 0x65,
- 0x2f, 0xa8, 0xf4, 0x55, 0x92, 0x5f, 0x97, 0xfa, 0x38, 0xae, 0x51, 0xe8,
- 0x4b, 0xf8, 0xc6, 0xfb, 0xa5, 0x85, 0x7d, 0x86, 0x51, 0x5b, 0xce, 0x5f,
- 0x59, 0x2b, 0xb5, 0xec, 0x4c, 0x0d, 0xe7, 0xcb, 0x1e, 0xcd, 0xcb, 0x1e,
- 0xfb, 0xd8, 0x75, 0xb5, 0xa9, 0xfb, 0xee, 0x82, 0xf9, 0xe7, 0x5d, 0xf2,
- 0x0c, 0x46, 0xd6, 0x5c, 0xe5, 0x9e, 0x82, 0x2e, 0xe2, 0x50, 0x54, 0x6b,
- 0x64, 0x9c, 0xd7, 0x7d, 0x6b, 0x39, 0x1f, 0x71, 0xaf, 0xec, 0x51, 0x2f,
- 0xc4, 0xc8, 0x62, 0xe4, 0xd6, 0x3e, 0x65, 0x9f, 0x45, 0x6e, 0xbd, 0x93,
- 0x76, 0x8f, 0xae, 0xf4, 0xef, 0xad, 0xac, 0xd7, 0xc9, 0x58, 0x78, 0x6e,
- 0x7f, 0xf4, 0x10, 0xf5, 0x3a, 0xcc, 0x7b, 0x9b, 0xcf, 0xae, 0xa7, 0xc8,
- 0x9a, 0x92, 0xc4, 0xde, 0xdf, 0x59, 0x6d, 0xe7, 0x95, 0x9d, 0xba, 0x57,
- 0xbc, 0x26, 0x26, 0xcf, 0xdc, 0x46, 0xf3, 0xeb, 0xee, 0x4d, 0x1f, 0x79,
- 0xe6, 0x36, 0x41, 0x5b, 0x42, 0x74, 0x33, 0xb9, 0x5d, 0x1c, 0x3d, 0x18,
- 0x4d, 0xd4, 0x69, 0x5b, 0xa0, 0xc9, 0x7a, 0x33, 0xff, 0x7a, 0xb0, 0x3f,
- 0x81, 0x68, 0xd1, 0xa5, 0x95, 0xe4, 0x5b, 0x88, 0x3a, 0x18, 0xa3, 0x1e,
- 0x4d, 0xd4, 0x35, 0x6f, 0xe3, 0x98, 0xfc, 0x2b, 0x7b, 0x30, 0x9c, 0x68,
- 0xfc, 0x2b, 0xc6, 0x11, 0x7f, 0x99, 0xcd, 0x75, 0xe2, 0x7f, 0xbd, 0x97,
- 0x38, 0xb0, 0x29, 0xbf, 0xe6, 0xd5, 0x96, 0xf8, 0x35, 0xe5, 0xb7, 0x85,
- 0x64, 0xbd, 0x4f, 0x2a, 0x37, 0xc1, 0x3c, 0xff, 0x04, 0xd6, 0xf5, 0x2b,
- 0x78, 0xd2, 0x38, 0x81, 0xb5, 0x43, 0x22, 0xcf, 0x09, 0xac, 0xe9, 0x7f,
- 0x09, 0x7b, 0xfa, 0x67, 0xa0, 0xc9, 0xd6, 0x4d, 0x07, 0x36, 0xec, 0x3c,
- 0x88, 0xed, 0x29, 0x0b, 0xdb, 0x42, 0x1e, 0xac, 0x7f, 0x58, 0xc1, 0xf2,
- 0xc0, 0x61, 0x6c, 0xd9, 0x69, 0xe1, 0xe2, 0x50, 0x27, 0x9a, 0xcd, 0x32,
- 0x14, 0x57, 0xcd, 0x6b, 0x57, 0x59, 0xae, 0x6d, 0xb8, 0x23, 0xbf, 0x2f,
- 0x79, 0x3f, 0xb1, 0x40, 0x85, 0xcf, 0x90, 0x3d, 0xc7, 0x51, 0xe5, 0xa6,
- 0x4c, 0x93, 0xd2, 0x9a, 0x7f, 0x66, 0x79, 0x7d, 0xa6, 0xa8, 0x02, 0xa5,
- 0x71, 0xec, 0x09, 0x9d, 0xc0, 0xd0, 0xd0, 0x07, 0xe5, 0x39, 0x7f, 0x99,
- 0x20, 0x77, 0x90, 0x9c, 0xc3, 0xa4, 0x4d, 0x7d, 0xd2, 0xfb, 0x40, 0x62,
- 0x77, 0x93, 0xf8, 0xe9, 0xe0, 0x49, 0x9c, 0x1c, 0xfc, 0x37, 0x2c, 0xd1,
- 0x24, 0x7f, 0xb4, 0x3a, 0x9d, 0x11, 0xcb, 0xda, 0xd5, 0x10, 0xb7, 0x6a,
- 0x8c, 0x5f, 0xb0, 0xed, 0x0a, 0x4c, 0x8f, 0xbc, 0x88, 0x6d, 0x1a, 0xdb,
- 0x4a, 0xed, 0xc7, 0x0e, 0xc6, 0x75, 0x5f, 0xe4, 0x66, 0xf8, 0x52, 0x59,
- 0xb3, 0x1a, 0xd1, 0x1d, 0xd5, 0xd0, 0x37, 0x56, 0x39, 0x8c, 0x8e, 0x7f,
- 0x55, 0xea, 0x71, 0x7d, 0xe6, 0x24, 0x7e, 0x3e, 0x68, 0xef, 0xa5, 0x6a,
- 0xfd, 0xae, 0x62, 0x75, 0x6e, 0x0b, 0xe9, 0xcd, 0xff, 0x43, 0x89, 0xc6,
- 0x4b, 0x69, 0x53, 0x25, 0xcc, 0x09, 0x6e, 0x18, 0x94, 0x1c, 0xb1, 0x15,
- 0xee, 0x3e, 0x3d, 0xbb, 0x94, 0x3c, 0xfb, 0xee, 0x05, 0xf1, 0x99, 0xd3,
- 0x68, 0x97, 0x0e, 0x45, 0x0f, 0x1a, 0x6a, 0x27, 0x8e, 0x98, 0xfa, 0xc4,
- 0xef, 0x1c, 0xc6, 0xd0, 0x77, 0x50, 0x8f, 0x55, 0x19, 0x7d, 0xe8, 0x32,
- 0xe6, 0x61, 0x5b, 0x92, 0x26, 0x52, 0x49, 0xbd, 0xb5, 0xc3, 0xd1, 0x8b,
- 0x3b, 0x02, 0xb5, 0x1b, 0xdf, 0x25, 0x97, 0xf3, 0x10, 0x53, 0x92, 0xe3,
- 0x23, 0xcc, 0x5f, 0x7b, 0xb1, 0xe1, 0xe1, 0x08, 0xd6, 0xef, 0x32, 0xd1,
- 0x93, 0x1c, 0xa1, 0x6c, 0x3f, 0x2c, 0x97, 0xbd, 0x34, 0x2d, 0xa1, 0xf8,
- 0xb5, 0x2a, 0x02, 0x51, 0xf6, 0xd9, 0xa8, 0x46, 0x02, 0x7e, 0x55, 0x61,
- 0xf4, 0x1f, 0x77, 0xa2, 0x9b, 0x65, 0xfa, 0x52, 0xb4, 0xb9, 0xa4, 0x9b,
- 0xf1, 0x72, 0x16, 0x86, 0xc7, 0x7c, 0xd8, 0x37, 0xe6, 0xc1, 0xd0, 0x98,
- 0xc6, 0xa3, 0x14, 0x0f, 0x0d, 0xc8, 0x9e, 0x14, 0x2f, 0x9e, 0xd8, 0xeb,
- 0xc6, 0xa6, 0x07, 0x3c, 0x98, 0x13, 0x99, 0x8e, 0xbd, 0x7b, 0x4b, 0xb1,
- 0x9b, 0xd7, 0xab, 0x16, 0xfa, 0xf1, 0x38, 0xaf, 0xf7, 0x3f, 0xe0, 0xe2,
- 0x3c, 0x5c, 0x8c, 0x03, 0x34, 0xec, 0xa1, 0xb1, 0x32, 0xa4, 0x06, 0x68,
- 0xf2, 0xe4, 0xac, 0x6f, 0x31, 0xc3, 0x18, 0xdd, 0xcb, 0xd8, 0xf8, 0xb0,
- 0x89, 0x04, 0xfb, 0xd9, 0x4e, 0x5d, 0xf5, 0x10, 0xd7, 0x36, 0x8c, 0x09,
- 0xc6, 0xaf, 0xc2, 0x35, 0x7d, 0x7a, 0x73, 0x93, 0x62, 0x44, 0x17, 0xd9,
- 0xfb, 0xb4, 0xe4, 0xbd, 0xad, 0x55, 0x68, 0x4c, 0xe8, 0x66, 0x13, 0x3a,
- 0x71, 0x8c, 0xe3, 0xfe, 0x7f, 0xe8, 0xb7, 0x8b, 0x1d, 0x7a, 0xef, 0xd5,
- 0xea, 0x41, 0xec, 0xc8, 0x1c, 0x22, 0x57, 0x07, 0xc2, 0x7b, 0x0e, 0x92,
- 0xbf, 0x1d, 0x21, 0xfe, 0xbc, 0x6e, 0xf9, 0x0c, 0x15, 0xd7, 0xdf, 0x6f,
- 0x84, 0xdf, 0x53, 0x02, 0x1b, 0x7f, 0x45, 0x1d, 0x7c, 0x7e, 0xaf, 0x8a,
- 0xeb, 0x76, 0x2c, 0x46, 0x3a, 0x14, 0xc5, 0xf6, 0x45, 0x2a, 0xae, 0x7d,
- 0xf8, 0x20, 0x71, 0x7f, 0xc2, 0xe6, 0xc9, 0xd9, 0xf4, 0x7d, 0x08, 0xf6,
- 0xc9, 0x9a, 0xbc, 0x9b, 0xf1, 0xbb, 0x1c, 0xc7, 0xfb, 0x3b, 0xe9, 0xb7,
- 0xe5, 0x38, 0x3a, 0x74, 0x90, 0xf6, 0x58, 0x8e, 0x23, 0xfd, 0xc6, 0xc4,
- 0x4f, 0x1d, 0xe5, 0x78, 0x82, 0xe7, 0x3b, 0x78, 0xbe, 0x70, 0xc0, 0xe8,
- 0xef, 0x50, 0xcb, 0xb1, 0x60, 0x4f, 0x03, 0xfa, 0x93, 0x62, 0x9b, 0x1a,
- 0x36, 0x8e, 0xd5, 0xe7, 0x75, 0x2f, 0x3a, 0xf7, 0xe2, 0x4e, 0xea, 0xea,
- 0x8e, 0x1d, 0x9d, 0xec, 0xcf, 0x47, 0x9d, 0x1f, 0xc4, 0x43, 0xcc, 0xeb,
- 0xb6, 0x25, 0x7d, 0x38, 0x9d, 0x32, 0xfc, 0x5f, 0x52, 0x0c, 0xb3, 0x44,
- 0x09, 0x68, 0xc7, 0xe1, 0xc3, 0xc9, 0x4c, 0x29, 0xba, 0x07, 0x66, 0xe1,
- 0xa7, 0xb4, 0xcf, 0x07, 0x1f, 0x90, 0xfe, 0x26, 0x18, 0x1f, 0x66, 0xe3,
- 0x89, 0x11, 0x93, 0x6d, 0xcb, 0x3c, 0x49, 0xcc, 0xe9, 0x81, 0x2b, 0x25,
- 0xbe, 0x11, 0xdd, 0x41, 0xb3, 0x20, 0x26, 0x1e, 0x46, 0xa6, 0x5f, 0xef,
- 0xbd, 0x41, 0x15, 0x5e, 0xad, 0x52, 0x97, 0x0e, 0x4c, 0x6a, 0x7a, 0xbc,
- 0x4a, 0x8d, 0xf7, 0x33, 0x7f, 0x8d, 0x57, 0xab, 0x87, 0xf1, 0x44, 0xbf,
- 0x13, 0xf3, 0x16, 0xaa, 0xbc, 0x1e, 0x3f, 0xc3, 0xd8, 0x16, 0x9f, 0xa3,
- 0x9a, 0xd8, 0x6d, 0xcb, 0x8a, 0x78, 0x11, 0xb9, 0x7d, 0xe5, 0xc2, 0x5a,
- 0xc6, 0x2f, 0x87, 0xd8, 0x5e, 0xac, 0x5c, 0x75, 0x52, 0xef, 0x27, 0x31,
- 0x42, 0xbb, 0x7e, 0x94, 0xc7, 0x81, 0x41, 0xab, 0x73, 0x39, 0x39, 0xf7,
- 0xc5, 0x01, 0xab, 0xf3, 0x06, 0xd3, 0xf0, 0x15, 0xa9, 0x81, 0xe8, 0xdd,
- 0x38, 0x89, 0xfd, 0x23, 0x52, 0x06, 0x6e, 0x6f, 0x84, 0x79, 0x75, 0xd2,
- 0xea, 0xdc, 0x61, 0x5e, 0x8c, 0x06, 0x3b, 0x37, 0xfe, 0x55, 0x79, 0x0e,
- 0x33, 0xc5, 0x8f, 0x64, 0x0d, 0x64, 0x12, 0xbf, 0x62, 0x3b, 0xef, 0x0d,
- 0x56, 0x62, 0x5a, 0xb5, 0xf8, 0xc1, 0x09, 0xbc, 0xdd, 0xff, 0x22, 0x4e,
- 0xf7, 0x5b, 0x58, 0x10, 0xb2, 0xe0, 0x0c, 0xd5, 0x99, 0x4d, 0xea, 0x65,
- 0xc4, 0x08, 0x05, 0xd7, 0xcc, 0x7d, 0x09, 0xef, 0xd0, 0xff, 0xaf, 0x9d,
- 0x6b, 0xd9, 0xb2, 0xf4, 0x61, 0xa1, 0xb5, 0xbd, 0x46, 0xfc, 0xc6, 0xb4,
- 0xf7, 0xf5, 0x7c, 0x72, 0x1e, 0x5c, 0xd8, 0xb7, 0x26, 0xb9, 0xf0, 0x49,
- 0x0c, 0x0f, 0x1a, 0xd1, 0x75, 0x05, 0x39, 0xfb, 0x4f, 0x52, 0x07, 0x16,
- 0x76, 0x98, 0x47, 0x1f, 0xae, 0xc2, 0xbc, 0x33, 0xcc, 0x1a, 0xaf, 0x98,
- 0x43, 0xdb, 0x59, 0xb0, 0x30, 0x60, 0x2e, 0x53, 0xdf, 0xa4, 0x9f, 0x9e,
- 0xc4, 0xbe, 0xa1, 0x02, 0x5e, 0xfb, 0xd0, 0x44, 0x3f, 0xcf, 0xed, 0x65,
- 0xf7, 0xa2, 0x31, 0x75, 0xc8, 0x5e, 0x7f, 0x38, 0x40, 0x7c, 0xcc, 0x3d,
- 0xd3, 0xd4, 0x30, 0x92, 0x69, 0x22, 0x36, 0x44, 0xf1, 0xcf, 0x99, 0x08,
- 0xf1, 0x21, 0x4c, 0x7c, 0x68, 0x20, 0x3e, 0x98, 0xc4, 0x87, 0x7a, 0xe2,
- 0x43, 0xd0, 0x7e, 0xd6, 0x2f, 0x6b, 0xe6, 0x43, 0xa3, 0x2f, 0xa2, 0x68,
- 0xe0, 0x04, 0x5c, 0xf4, 0x81, 0xe3, 0xa6, 0x45, 0x7e, 0x52, 0xa7, 0xad,
- 0xc1, 0xc5, 0x4a, 0x54, 0xf3, 0x62, 0x28, 0x73, 0x02, 0x25, 0x03, 0x1a,
- 0xc7, 0x22, 0xfb, 0x33, 0x6a, 0xc3, 0xbd, 0xc4, 0xea, 0x5f, 0x1b, 0x75,
- 0xbd, 0x5e, 0xd4, 0xed, 0xae, 0x81, 0xd1, 0xbf, 0x50, 0x9d, 0xab, 0x44,
- 0xbf, 0xe0, 0xe5, 0x38, 0xab, 0x31, 0xfb, 0x01, 0x0d, 0x73, 0x78, 0xfc,
- 0x53, 0xaa, 0x76, 0xe2, 0x75, 0x07, 0xbc, 0x33, 0x48, 0x77, 0x66, 0x92,
- 0x09, 0x90, 0xd5, 0x7a, 0x7d, 0xb8, 0xe4, 0xc0, 0x49, 0x55, 0x41, 0xf6,
- 0x0b, 0x12, 0xf3, 0xea, 0x82, 0x3d, 0xaa, 0x2a, 0x6b, 0x48, 0xc4, 0x70,
- 0x1e, 0x2a, 0x22, 0x64, 0x11, 0xb3, 0x98, 0x5f, 0x58, 0x6b, 0xcc, 0x12,
- 0x6c, 0xae, 0x57, 0x65, 0x6f, 0xc8, 0x21, 0x89, 0x51, 0x33, 0x18, 0x23,
- 0x4a, 0x93, 0xf1, 0xdb, 0x66, 0xc0, 0x83, 0x92, 0xa4, 0x65, 0x3d, 0x16,
- 0xd2, 0xe0, 0x89, 0x04, 0xa2, 0x1b, 0x98, 0x46, 0x7e, 0x61, 0x5e, 0x18,
- 0xd7, 0x64, 0x0e, 0x60, 0x80, 0xe3, 0x5b, 0x9e, 0x29, 0xbc, 0xe3, 0xf9,
- 0xc9, 0x7f, 0xe7, 0xde, 0x15, 0xbd, 0x64, 0xf7, 0x0c, 0x18, 0xda, 0x5d,
- 0x6a, 0xbc, 0x92, 0x1c, 0xfc, 0x00, 0xe3, 0x9e, 0x32, 0x79, 0xa3, 0x82,
- 0xd6, 0x81, 0x38, 0xa6, 0x85, 0x7e, 0xa0, 0xc4, 0xaa, 0x75, 0xbf, 0x5f,
- 0xa9, 0xc6, 0x8d, 0x0f, 0x50, 0xd7, 0x0b, 0x26, 0x68, 0x2b, 0x3e, 0x7c,
- 0x67, 0x54, 0x74, 0x5b, 0x3b, 0xb4, 0x83, 0xe3, 0x98, 0x98, 0x7b, 0x40,
- 0x70, 0xf2, 0xa0, 0x1b, 0x8e, 0x83, 0xd3, 0x99, 0x9b, 0xd6, 0xcf, 0xbd,
- 0xa4, 0xe3, 0xdf, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0xbd, 0x3f, 0xae, 0x18,
- 0xda, 0x2f, 0x95, 0x03, 0xe4, 0x6c, 0x5e, 0x3c, 0x96, 0x39, 0x4c, 0x5d,
- 0xee, 0xcf, 0xe7, 0x4b, 0xab, 0x90, 0xe8, 0x93, 0x7d, 0x81, 0x27, 0x30,
- 0x7b, 0x40, 0x6f, 0xd9, 0xaa, 0x18, 0xc1, 0x6b, 0x95, 0x13, 0x98, 0x39,
- 0x10, 0xe4, 0x5c, 0x6a, 0x58, 0x96, 0x2c, 0xe0, 0xa7, 0x60, 0xf0, 0x2a,
- 0x62, 0xb0, 0xb5, 0xf8, 0xa7, 0x66, 0x9c, 0x39, 0x8e, 0x6e, 0x3a, 0x15,
- 0xbd, 0x75, 0xae, 0x22, 0xfb, 0x80, 0x8c, 0x33, 0x6d, 0xac, 0xe3, 0x19,
- 0xa8, 0xc7, 0x57, 0x39, 0xe6, 0x66, 0xce, 0xdb, 0x8b, 0x0b, 0x2d, 0x2c,
- 0x5a, 0xa8, 0xef, 0x2e, 0x71, 0x44, 0xef, 0xaa, 0x42, 0xb6, 0xa3, 0x86,
- 0x76, 0x73, 0xc7, 0x02, 0x3d, 0xfc, 0x03, 0xe2, 0x2e, 0x71, 0x1a, 0xdd,
- 0x8c, 0x3b, 0x6b, 0x18, 0x8b, 0x4a, 0x23, 0x7a, 0x2f, 0x73, 0xd4, 0xf7,
- 0x6e, 0x75, 0x44, 0x43, 0xf2, 0x1e, 0xd1, 0xdf, 0x63, 0x31, 0xdc, 0xa1,
- 0x0a, 0xe2, 0xa0, 0x9e, 0x7d, 0x11, 0xfa, 0xee, 0xaf, 0x92, 0x93, 0xfe,
- 0x98, 0xfc, 0xae, 0xe6, 0xd2, 0x43, 0xc4, 0xa8, 0x11, 0x3c, 0x98, 0x39,
- 0x88, 0xdd, 0x99, 0x34, 0x76, 0x66, 0xb6, 0x29, 0x43, 0xf6, 0xb3, 0x45,
- 0x45, 0xde, 0x99, 0x8b, 0x56, 0x28, 0x5f, 0x46, 0x79, 0xe8, 0x5b, 0xd6,
- 0x50, 0x95, 0x8a, 0xca, 0x50, 0x10, 0xd7, 0x24, 0xe3, 0x70, 0x44, 0xde,
- 0xb5, 0xe4, 0x7d, 0xed, 0xf5, 0xe3, 0x06, 0xae, 0x4e, 0x96, 0x22, 0xb6,
- 0xc7, 0xb2, 0x7a, 0x1b, 0x9c, 0x58, 0x3b, 0x5e, 0x8f, 0x65, 0x03, 0x0f,
- 0x59, 0x73, 0x18, 0x73, 0x3e, 0xbc, 0xdc, 0x83, 0x5b, 0xf7, 0x78, 0xd0,
- 0x96, 0x8c, 0xc2, 0x17, 0x29, 0xe3, 0xef, 0x80, 0xb9, 0x04, 0xc6, 0xc4,
- 0x04, 0x8c, 0xde, 0xab, 0x1c, 0x81, 0xfd, 0x61, 0xd5, 0x83, 0xbf, 0x21,
- 0x8e, 0x2f, 0x27, 0xee, 0xc4, 0xc6, 0x2d, 0x54, 0x46, 0xbc, 0xb8, 0x8d,
- 0xf5, 0xaf, 0xe3, 0xdc, 0xbf, 0xb3, 0x68, 0x3f, 0xb1, 0x40, 0xf6, 0x42,
- 0x6a, 0xd8, 0x30, 0xee, 0xa6, 0xae, 0xdc, 0x88, 0xed, 0xab, 0xc6, 0xd5,
- 0x0f, 0xf8, 0x71, 0xeb, 0xb8, 0x07, 0x8d, 0x49, 0x6b, 0xf1, 0x01, 0x33,
- 0xbe, 0x52, 0x83, 0x81, 0xb6, 0x71, 0x2f, 0xbe, 0x92, 0xd4, 0x7d, 0xd7,
- 0x32, 0xe7, 0x1f, 0x31, 0x83, 0xf8, 0x5f, 0xe3, 0x3e, 0xdc, 0x94, 0x3c,
- 0x2a, 0x79, 0xe4, 0x12, 0x27, 0x63, 0xcf, 0xbd, 0xe3, 0xb3, 0xb0, 0x32,
- 0xa9, 0x9f, 0x99, 0x20, 0xb7, 0xeb, 0xdc, 0x67, 0xe2, 0xae, 0x71, 0x15,
- 0xad, 0x6c, 0xe7, 0xc6, 0xe4, 0x6c, 0x74, 0xec, 0x6b, 0xa0, 0x0c, 0x0b,
- 0xb1, 0x7c, 0xc0, 0x09, 0x93, 0x2c, 0x1e, 0x5f, 0x04, 0x5a, 0x06, 0x26,
- 0x98, 0xc7, 0xdd, 0x87, 0xed, 0x7d, 0x26, 0x6e, 0x1f, 0x97, 0xf3, 0x83,
- 0xf6, 0x3b, 0xae, 0xef, 0x3d, 0xbc, 0x10, 0x9f, 0x1f, 0x50, 0x89, 0x03,
- 0xc5, 0x18, 0x5a, 0xa9, 0xe0, 0x2b, 0xbc, 0xbe, 0x35, 0x25, 0x7b, 0x90,
- 0x81, 0xd0, 0x8e, 0xc0, 0xfe, 0x2a, 0x72, 0x86, 0x45, 0x0f, 0xe7, 0xae,
- 0x3f, 0x48, 0x9c, 0x2f, 0x21, 0xce, 0x97, 0x91, 0xc3, 0x5e, 0x35, 0x7c,
- 0x10, 0xf7, 0x13, 0x97, 0x0f, 0x0d, 0x74, 0x32, 0xee, 0x94, 0xe3, 0x71,
- 0xc6, 0x81, 0x24, 0xcf, 0x4f, 0xec, 0x30, 0x3a, 0x4a, 0x88, 0xd3, 0x3f,
- 0x20, 0xfe, 0xf6, 0x12, 0x33, 0xee, 0x48, 0x32, 0xdc, 0xef, 0x60, 0x0e,
- 0x70, 0x69, 0x74, 0xbe, 0x87, 0x39, 0xd6, 0xb5, 0x4a, 0xc0, 0xf7, 0x26,
- 0xca, 0xe1, 0x78, 0xb8, 0x1a, 0x8d, 0x0f, 0x48, 0x19, 0xc1, 0x2f, 0x15,
- 0xea, 0x5e, 0x27, 0x75, 0x7e, 0x18, 0x56, 0xbf, 0x83, 0xe3, 0xad, 0x35,
- 0xc9, 0xc0, 0xf1, 0x9a, 0xa9, 0x6b, 0xff, 0x4c, 0xac, 0x7d, 0x9f, 0x98,
- 0xea, 0x9f, 0xd1, 0x80, 0x26, 0xc3, 0xe4, 0x71, 0x18, 0x27, 0xfb, 0x0d,
- 0x53, 0xf6, 0xe4, 0xbd, 0x4e, 0x9e, 0x37, 0x39, 0x83, 0x31, 0xd3, 0x10,
- 0x3f, 0x1c, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x03, 0xde, 0x7e,
- 0x78, 0x31, 0xc7, 0x25, 0xb1, 0x54, 0xe2, 0xdd, 0x08, 0x65, 0x5d, 0x8c,
- 0x15, 0xd4, 0x47, 0x53, 0x52, 0x45, 0x7a, 0x5f, 0x04, 0xb7, 0xef, 0xca,
- 0xc5, 0xe1, 0x8d, 0xa1, 0xf8, 0x0d, 0x8c, 0xc3, 0xe1, 0x52, 0xc6, 0x61,
- 0x57, 0x44, 0x64, 0x73, 0x62, 0x98, 0x71, 0x7b, 0x73, 0x2a, 0x8c, 0x66,
- 0xce, 0xe1, 0x44, 0x9a, 0xfd, 0x26, 0x67, 0xe1, 0x78, 0xda, 0xc3, 0x98,
- 0xa5, 0xf1, 0x20, 0xaa, 0x8d, 0x4c, 0xe7, 0xe1, 0xe7, 0x71, 0x31, 0x0f,
- 0xc3, 0xbe, 0xb6, 0x26, 0xa9, 0x20, 0xde, 0xa2, 0xd8, 0x7c, 0xfe, 0x78,
- 0x5a, 0xb0, 0x59, 0xd6, 0x32, 0xef, 0xae, 0x94, 0x3d, 0xa8, 0xfd, 0xa9,
- 0x97, 0x50, 0x49, 0x7c, 0xaa, 0xc8, 0xe3, 0xd0, 0xcf, 0x42, 0x82, 0xbb,
- 0xb5, 0xc4, 0x5d, 0xd9, 0x4f, 0x64, 0x59, 0xab, 0x02, 0x53, 0xf1, 0xe8,
- 0xff, 0xfb, 0x30, 0x6a, 0xef, 0xab, 0x15, 0x4c, 0x22, 0xfe, 0xa5, 0x88,
- 0x7f, 0x1c, 0x43, 0xd7, 0x95, 0xc4, 0x40, 0xca, 0xf4, 0x8f, 0x29, 0x62,
- 0x20, 0x71, 0xfa, 0x20, 0x71, 0xfa, 0xdb, 0xc4, 0xe9, 0x6f, 0x11, 0xa7,
- 0x1f, 0x27, 0x26, 0xe4, 0xd6, 0xf4, 0x9a, 0xe5, 0xb9, 0x0a, 0xe7, 0xe3,
- 0x1d, 0x7b, 0x6d, 0xb1, 0x86, 0xba, 0x9a, 0x3d, 0xa0, 0x60, 0x8e, 0xa1,
- 0xef, 0x17, 0xbb, 0xff, 0x31, 0xe7, 0xc9, 0x3f, 0x2d, 0xb7, 0xe7, 0xb7,
- 0x29, 0xd9, 0x03, 0x77, 0xb2, 0x4e, 0xeb, 0x85, 0xfd, 0x0d, 0x01, 0x53,
- 0xb8, 0x68, 0x51, 0x72, 0x0d, 0x1c, 0xc9, 0xba, 0xfd, 0xc7, 0xe4, 0xf9,
- 0xed, 0x74, 0xc9, 0xeb, 0xd7, 0xc8, 0x1e, 0xed, 0xfd, 0xb2, 0x37, 0x6c,
- 0x19, 0xef, 0xb9, 0x92, 0x75, 0xe6, 0x9b, 0xb0, 0xb1, 0xcd, 0x3f, 0x69,
- 0xdf, 0xab, 0x7d, 0xef, 0x7e, 0xea, 0x2b, 0xcb, 0x36, 0xd3, 0x29, 0xd9,
- 0x17, 0x3b, 0x0b, 0x8f, 0x66, 0xe4, 0x77, 0x5d, 0x6b, 0x42, 0xdd, 0x8f,
- 0x58, 0x8d, 0xf0, 0xf1, 0x30, 0xae, 0x4f, 0x7a, 0x68, 0x07, 0x71, 0x54,
- 0xd0, 0xb7, 0xbe, 0x36, 0xde, 0x40, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81,
- 0xd6, 0x71, 0x72, 0x9e, 0xf5, 0xe3, 0x8b, 0xb1, 0x74, 0xc0, 0xb2, 0x3c,
- 0x97, 0x19, 0xe1, 0x0d, 0x8a, 0x1f, 0x2e, 0xfa, 0xa0, 0x83, 0x7e, 0xb5,
- 0x6e, 0x4f, 0x40, 0x7b, 0x93, 0x78, 0xda, 0xde, 0x70, 0x80, 0xf6, 0x61,
- 0x9c, 0x69, 0x26, 0x96, 0x3a, 0x23, 0x01, 0xe6, 0x89, 0x1e, 0xda, 0xbe,
- 0x17, 0x67, 0x12, 0xe2, 0x5f, 0x7a, 0xc7, 0x3f, 0x33, 0x37, 0xe9, 0xa0,
- 0x6f, 0xfc, 0x32, 0x31, 0x8b, 0x3e, 0xe0, 0xc6, 0xdb, 0x09, 0x83, 0xfe,
- 0xe6, 0xc1, 0x3b, 0x89, 0x7a, 0xf6, 0x15, 0x64, 0x19, 0x3f, 0xee, 0x1c,
- 0x0f, 0xd3, 0xcf, 0xae, 0xe4, 0x21, 0xef, 0x53, 0xd7, 0xc6, 0xbf, 0xa3,
- 0xd4, 0xf6, 0xcf, 0x56, 0xab, 0x10, 0xad, 0xd6, 0xf0, 0xf5, 0xf1, 0xcf,
- 0xe2, 0x3f, 0x18, 0xb7, 0xd7, 0x26, 0xc1, 0x39, 0x44, 0x88, 0x3c, 0x70,
- 0x62, 0x9f, 0x3c, 0x4b, 0x44, 0x5d, 0x74, 0xae, 0x43, 0x67, 0x6e, 0xab,
- 0x67, 0x4f, 0x3b, 0x9c, 0xec, 0x93, 0xac, 0x98, 0x65, 0x7f, 0xd9, 0x5f,
- 0x8a, 0xbb, 0xf6, 0x1c, 0xa0, 0x8f, 0x14, 0x61, 0xc1, 0xfd, 0x6e, 0x7c,
- 0x7d, 0xdf, 0x08, 0xb9, 0x83, 0x8a, 0x99, 0xcc, 0x95, 0x86, 0x48, 0x14,
- 0x66, 0x0e, 0x47, 0x70, 0xdb, 0xae, 0x11, 0x0c, 0xe4, 0x79, 0x5e, 0x28,
- 0x14, 0xff, 0x9f, 0x2a, 0x0e, 0x90, 0x47, 0x04, 0xda, 0x3f, 0x43, 0x1b,
- 0xab, 0x88, 0x04, 0xe2, 0x32, 0xee, 0x16, 0xda, 0x58, 0x0f, 0xe7, 0x33,
- 0xcd, 0x71, 0x24, 0x68, 0x63, 0x8f, 0x51, 0xfe, 0xed, 0xb4, 0xb1, 0x38,
- 0x6d, 0x2c, 0x4e, 0x7b, 0x8a, 0xd3, 0xc6, 0xe4, 0x9d, 0xfd, 0x38, 0x6d,
- 0x2c, 0x4e, 0x1b, 0x8b, 0xa7, 0x17, 0x63, 0x94, 0x4c, 0x63, 0xcb, 0x48,
- 0x03, 0x71, 0x4c, 0xb1, 0xa3, 0x52, 0xf6, 0x86, 0xcf, 0x92, 0xb3, 0x5f,
- 0xc5, 0x43, 0x41, 0x33, 0x7d, 0xb2, 0x77, 0x68, 0x84, 0x9c, 0xc7, 0x8d,
- 0xdf, 0x64, 0x84, 0xe3, 0x37, 0x30, 0x8f, 0x3d, 0x4c, 0x9e, 0xaf, 0xe2,
- 0x49, 0x53, 0xf2, 0x60, 0x93, 0xe7, 0x8c, 0x35, 0x29, 0xe1, 0x6b, 0x87,
- 0x71, 0x47, 0x3f, 0x70, 0x2d, 0x79, 0x61, 0x35, 0x79, 0xc9, 0xde, 0x05,
- 0xfc, 0xfd, 0xf0, 0x01, 0xda, 0xbc, 0xf8, 0x63, 0x6e, 0xaf, 0xeb, 0xf1,
- 0xfe, 0x5a, 0xdf, 0xd5, 0xf4, 0xc1, 0x7b, 0x59, 0xd7, 0xf9, 0xb0, 0xd4,
- 0x39, 0xc0, 0xb6, 0xf5, 0xf0, 0x6f, 0x38, 0xff, 0xad, 0xf7, 0x57, 0xe3,
- 0xed, 0x5d, 0x7a, 0xf8, 0x7d, 0x62, 0x5e, 0xb5, 0xc3, 0x5a, 0xfc, 0x99,
- 0x50, 0x60, 0xe3, 0x67, 0xd4, 0x1c, 0xdf, 0x6b, 0xd9, 0xe1, 0xc4, 0xfe,
- 0xd0, 0x62, 0x78, 0x16, 0x14, 0x38, 0x1f, 0x6d, 0xa9, 0x5a, 0x38, 0x96,
- 0x1e, 0x3e, 0x4d, 0xae, 0x92, 0x64, 0xfb, 0xa3, 0xe9, 0x23, 0xc4, 0x90,
- 0xfb, 0xf0, 0x02, 0xf3, 0xf3, 0x91, 0x4f, 0xbf, 0x4e, 0xee, 0xe8, 0xc6,
- 0x18, 0x39, 0xe0, 0x81, 0xfe, 0xe8, 0xe7, 0x9c, 0xc4, 0x7d, 0xcf, 0x82,
- 0x72, 0xa4, 0x87, 0x84, 0x2b, 0x96, 0xe3, 0xd9, 0x7e, 0x43, 0xbb, 0x56,
- 0xc9, 0xf1, 0xc2, 0x2d, 0x3c, 0x7f, 0xb3, 0xdf, 0x38, 0x33, 0x8c, 0xc0,
- 0xc4, 0x69, 0x72, 0xc3, 0xf7, 0x87, 0x24, 0x86, 0x1d, 0xa4, 0x8f, 0xfb,
- 0x11, 0x4e, 0x6a, 0x38, 0x34, 0x66, 0x60, 0x7e, 0xd2, 0x8b, 0x47, 0xc6,
- 0x82, 0xf8, 0x0c, 0x7d, 0x37, 0x43, 0x7e, 0xf8, 0xe9, 0xa4, 0xf8, 0xe2,
- 0x2c, 0x8c, 0x8f, 0xcd, 0xb2, 0xf7, 0x54, 0x7a, 0x8c, 0x5f, 0xc0, 0x53,
- 0x2d, 0x3e, 0x49, 0x6e, 0x9d, 0xd2, 0x7b, 0x63, 0x1c, 0x4f, 0xcc, 0xab,
- 0xef, 0x8f, 0x41, 0x1f, 0x02, 0xae, 0xf8, 0x70, 0xe8, 0x8b, 0x12, 0x1f,
- 0xc5, 0x1f, 0x35, 0x8c, 0x93, 0xef, 0x14, 0x13, 0x53, 0x4b, 0x23, 0xb5,
- 0xef, 0xbd, 0xac, 0xe8, 0xd9, 0xa7, 0x55, 0xcb, 0x7a, 0x69, 0xa1, 0x06,
- 0xdf, 0x3e, 0x8d, 0xdc, 0xc3, 0x64, 0xec, 0x16, 0x3f, 0xd5, 0x30, 0xe3,
- 0x81, 0x6a, 0x4c, 0x7b, 0x20, 0x89, 0xbf, 0xad, 0x8e, 0x7f, 0x6e, 0x3a,
- 0xe3, 0xfc, 0x74, 0xe2, 0x7a, 0x65, 0xf2, 0xd8, 0x0c, 0x37, 0xf9, 0xf2,
- 0x84, 0x5a, 0xd7, 0xba, 0x1f, 0xfa, 0xfe, 0x93, 0x8a, 0xee, 0x7b, 0x8c,
- 0xb1, 0xc1, 0x45, 0x1b, 0x75, 0x8c, 0x6b, 0xf4, 0xdd, 0xba, 0x43, 0xd3,
- 0x60, 0xc4, 0x2f, 0x57, 0x5d, 0x16, 0x6c, 0x79, 0xae, 0xa8, 0xcc, 0xe5,
- 0x45, 0x82, 0x3b, 0x12, 0x17, 0x1c, 0xb2, 0xff, 0x13, 0xed, 0xf4, 0x97,
- 0x15, 0x76, 0x2c, 0x3a, 0x60, 0xef, 0x8f, 0xdb, 0x30, 0x1e, 0xa7, 0x8f,
- 0x2c, 0x46, 0xd9, 0x80, 0x07, 0x5f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x15,
- 0xfd, 0xe5, 0xf6, 0x3d, 0x81, 0xf6, 0xab, 0xe9, 0x2f, 0xb5, 0x97, 0x49,
- 0x0c, 0x63, 0xdc, 0x4e, 0x19, 0xe6, 0x30, 0xb1, 0xe5, 0xa1, 0x06, 0x63,
- 0xe2, 0x75, 0xe4, 0x7c, 0x66, 0x6b, 0x5f, 0x35, 0xfe, 0xe1, 0xfe, 0xfd,
- 0xf6, 0x5a, 0xc8, 0x6d, 0x3c, 0x4f, 0xf6, 0xf9, 0x6c, 0xff, 0x88, 0xf1,
- 0xf7, 0x9d, 0x8c, 0x79, 0x31, 0xfa, 0xd1, 0x96, 0x3e, 0x6b, 0xf1, 0xf7,
- 0x17, 0xc6, 0x57, 0x56, 0x20, 0xc8, 0x98, 0xe4, 0x46, 0x6f, 0x9f, 0xde,
- 0xdf, 0xca, 0x18, 0x74, 0x62, 0xa1, 0x49, 0x59, 0x3c, 0xd8, 0xd1, 0x27,
- 0x98, 0x7a, 0xf4, 0xa6, 0x6a, 0xc4, 0xff, 0xa7, 0xc6, 0xf1, 0x7d, 0xcd,
- 0x7e, 0xf6, 0x37, 0x0b, 0x6b, 0xf7, 0x5d, 0x46, 0x99, 0xeb, 0xe9, 0x83,
- 0xcc, 0xab, 0x99, 0xef, 0xac, 0xde, 0x25, 0x7e, 0x81, 0x46, 0xc9, 0xd3,
- 0x3a, 0xcd, 0x80, 0xf9, 0x06, 0x7d, 0xa8, 0x88, 0x5c, 0xe7, 0x41, 0x62,
- 0x59, 0x31, 0x21, 0xb3, 0xcc, 0x08, 0x63, 0x21, 0x6d, 0x54, 0xde, 0xe1,
- 0x98, 0x46, 0x5e, 0x37, 0x9f, 0xf3, 0x51, 0x92, 0xf1, 0x00, 0xe4, 0x10,
- 0x20, 0x3e, 0x61, 0x94, 0x20, 0x38, 0xea, 0xe7, 0x71, 0x31, 0x0f, 0x2a,
- 0x22, 0xa3, 0xa2, 0x66, 0x94, 0x75, 0x87, 0x47, 0x6c, 0x5b, 0xfc, 0x07,
- 0xce, 0x7b, 0x82, 0xb6, 0x7e, 0x23, 0xb1, 0x7e, 0x62, 0x27, 0xd0, 0xfb,
- 0x70, 0xce, 0xb6, 0x53, 0x6c, 0xbf, 0x85, 0x98, 0xf7, 0x1e, 0x6d, 0xb6,
- 0x87, 0xf3, 0xbd, 0x63, 0xd0, 0x08, 0xd6, 0xa9, 0x01, 0x6d, 0x9c, 0xf3,
- 0xdc, 0x35, 0xa2, 0xa2, 0xaf, 0x7f, 0x31, 0x86, 0x99, 0x07, 0x75, 0x0f,
- 0x89, 0x8f, 0x48, 0x99, 0xc3, 0xe8, 0xa4, 0x8f, 0xfc, 0x6a, 0xa1, 0x82,
- 0xd8, 0x17, 0xe4, 0x1d, 0x51, 0x27, 0xf3, 0xfd, 0xfb, 0xb0, 0x36, 0x71,
- 0xc4, 0x2a, 0x37, 0xf4, 0xde, 0x21, 0x95, 0x79, 0x16, 0x6d, 0xb3, 0x8b,
- 0xf9, 0xc9, 0x12, 0xe6, 0x27, 0xdd, 0x79, 0xbb, 0x3c, 0x4e, 0x3b, 0xec,
- 0x63, 0x1c, 0x7b, 0x7d, 0x28, 0x17, 0xf7, 0x7e, 0xbc, 0xc3, 0x8f, 0xf9,
- 0x97, 0x97, 0xe3, 0x99, 0x87, 0x73, 0xb2, 0xed, 0xa4, 0x4d, 0x3e, 0x4d,
- 0x3d, 0xdf, 0x4a, 0xbd, 0xbe, 0x92, 0x12, 0x8c, 0x0a, 0xe2, 0x59, 0xf2,
- 0xe8, 0xf5, 0xe4, 0x02, 0x2f, 0xa5, 0x72, 0x36, 0xf9, 0xf5, 0xf1, 0x2b,
- 0xab, 0x72, 0xf1, 0xc1, 0x0b, 0xf5, 0x01, 0x79, 0x27, 0xcf, 0xb2, 0x96,
- 0x98, 0xd9, 0x76, 0xf2, 0x1a, 0xb6, 0x1d, 0x21, 0x37, 0x72, 0x62, 0x66,
- 0x32, 0x82, 0xa5, 0xa9, 0xda, 0xe6, 0xb9, 0xb2, 0x89, 0x63, 0x66, 0x8e,
- 0x03, 0xba, 0x92, 0xf2, 0xcd, 0x0f, 0x0d, 0x65, 0xcc, 0x9d, 0xfe, 0x26,
- 0xff, 0x9d, 0x91, 0x1b, 0xff, 0x0c, 0xee, 0xb8, 0x82, 0x32, 0xa5, 0xc8,
- 0x1d, 0x27, 0xf3, 0xdf, 0x19, 0xb9, 0xc1, 0xfe, 0xce, 0x88, 0x1b, 0xd3,
- 0xc6, 0x9d, 0xce, 0x2f, 0xa5, 0x3c, 0x98, 0x31, 0x7e, 0x96, 0x83, 0xba,
- 0x8b, 0x22, 0x4d, 0x78, 0x2a, 0xa1, 0x60, 0xba, 0xf1, 0xbf, 0xf1, 0xb2,
- 0xbd, 0x26, 0x50, 0x8d, 0x99, 0x0f, 0xc8, 0x7a, 0x42, 0x54, 0xde, 0x89,
- 0x69, 0x7e, 0x82, 0xe7, 0x25, 0xc4, 0xd3, 0x8a, 0x07, 0x14, 0x3c, 0x1d,
- 0xf0, 0xa2, 0x98, 0xbf, 0x7d, 0xe4, 0x9a, 0xce, 0x85, 0xcb, 0xad, 0xcd,
- 0xab, 0xc4, 0xbe, 0x39, 0x87, 0xfb, 0xa6, 0x55, 0x0a, 0x06, 0xee, 0x35,
- 0x65, 0xdd, 0xd2, 0x40, 0x4f, 0xa2, 0x9a, 0xfc, 0xba, 0xb6, 0xbd, 0x09,
- 0xb5, 0xe6, 0x2f, 0x1c, 0xd5, 0x28, 0xda, 0x77, 0x63, 0x95, 0xac, 0xd9,
- 0x7f, 0x9b, 0x73, 0xd6, 0x4d, 0xec, 0xea, 0x4a, 0xe5, 0xe2, 0x67, 0x53,
- 0xfa, 0x17, 0x9a, 0xe8, 0xa5, 0x9b, 0xfc, 0x44, 0x4d, 0x9e, 0xb2, 0xcb,
- 0x94, 0x45, 0x0e, 0x11, 0x7f, 0x66, 0xe1, 0x10, 0xf3, 0x1a, 0x89, 0xa5,
- 0x65, 0x3c, 0xca, 0xc9, 0x1b, 0x7f, 0xc9, 0x58, 0x7a, 0x67, 0x28, 0x1b,
- 0x94, 0x2f, 0xd0, 0x54, 0x91, 0x8b, 0xd3, 0x07, 0xb0, 0x2f, 0xa4, 0xb7,
- 0xac, 0x76, 0x44, 0x9f, 0x61, 0x0e, 0x16, 0x5e, 0xcc, 0x9c, 0x7c, 0x79,
- 0x60, 0x04, 0x5b, 0xc9, 0x03, 0xb7, 0x30, 0x17, 0x6f, 0xa5, 0x6d, 0xb6,
- 0xef, 0x62, 0x6c, 0x73, 0x9c, 0xcb, 0xc5, 0xb5, 0x50, 0x7c, 0x35, 0x39,
- 0x40, 0x87, 0x47, 0x15, 0x7b, 0x15, 0xdf, 0x09, 0xb4, 0xbe, 0x41, 0x8c,
- 0xae, 0x63, 0xdc, 0x10, 0x7b, 0xdf, 0x9e, 0xd2, 0xdb, 0xa9, 0x80, 0xaa,
- 0x72, 0xe6, 0x8e, 0x77, 0x8d, 0x35, 0xd0, 0x6f, 0xac, 0x4e, 0x37, 0xed,
- 0xda, 0xb9, 0x68, 0x16, 0x73, 0xce, 0xab, 0xd0, 0xbd, 0x83, 0xf6, 0x4f,
- 0x5f, 0xba, 0xb7, 0x0f, 0xe4, 0x67, 0xea, 0x16, 0xce, 0x5f, 0x76, 0x1f,
- 0x02, 0x67, 0x5a, 0x50, 0xd7, 0x5c, 0xe4, 0x10, 0x19, 0xf4, 0x96, 0xb7,
- 0xc9, 0xd3, 0x3a, 0x98, 0x9f, 0xae, 0x67, 0x2e, 0x1f, 0x63, 0x2e, 0x1f,
- 0x63, 0xbd, 0xd4, 0x0e, 0x79, 0x4e, 0x64, 0xb4, 0x1c, 0x67, 0xfe, 0xf3,
- 0x35, 0xf2, 0x9f, 0x1d, 0xf7, 0x8b, 0x5c, 0xd3, 0x71, 0xd7, 0xde, 0xab,
- 0x90, 0xa4, 0x3d, 0xdd, 0xc9, 0x6b, 0x7d, 0xf7, 0x5f, 0x8c, 0x3b, 0x98,
- 0xc7, 0xc7, 0xc6, 0x16, 0xa3, 0x9f, 0x99, 0xe8, 0xc6, 0xbd, 0x9f, 0x45,
- 0x17, 0xf9, 0xd4, 0x12, 0x62, 0xf4, 0xea, 0x87, 0x47, 0x6c, 0xcc, 0x16,
- 0xcc, 0x7f, 0x2d, 0x0d, 0xbc, 0x49, 0x4e, 0xd6, 0x9f, 0x3a, 0x60, 0xf3,
- 0x34, 0x17, 0xe3, 0x43, 0x31, 0x71, 0x29, 0xbc, 0xcb, 0xe8, 0x58, 0xa6,
- 0x5a, 0x8b, 0x4b, 0x16, 0x06, 0x7a, 0xdf, 0xa6, 0xaf, 0x56, 0xed, 0x53,
- 0x51, 0x3d, 0x20, 0xb9, 0x3a, 0xf9, 0x11, 0x31, 0xfa, 0x05, 0x62, 0x74,
- 0xf9, 0x9e, 0x5c, 0x5e, 0x9e, 0x60, 0xde, 0x55, 0x6d, 0xe4, 0x72, 0xf3,
- 0xed, 0x7d, 0xb2, 0xf7, 0xc6, 0x8d, 0xe7, 0x68, 0xfb, 0x47, 0xf3, 0xb6,
- 0x7f, 0x2c, 0x8f, 0xc1, 0x16, 0x73, 0xf3, 0x37, 0x6d, 0xfc, 0xcd, 0xe5,
- 0xe6, 0xf3, 0x07, 0x8c, 0x8e, 0x30, 0x31, 0xfa, 0x33, 0x7b, 0xa4, 0x7f,
- 0x0d, 0xd5, 0xc4, 0x93, 0x1a, 0x62, 0x49, 0xc5, 0x80, 0xac, 0xcf, 0x04,
- 0xda, 0xc7, 0x55, 0x9f, 0xdd, 0xc7, 0x26, 0xca, 0xd6, 0x9d, 0x92, 0x77,
- 0x6c, 0x0d, 0x6d, 0x83, 0x12, 0x30, 0xaf, 0xa1, 0x3e, 0xf7, 0xa5, 0xaf,
- 0x42, 0x7b, 0xff, 0x2c, 0xec, 0x1f, 0x92, 0xf8, 0x22, 0xed, 0x4b, 0x2e,
- 0xee, 0xc4, 0xfb, 0xbb, 0x66, 0xe3, 0xfd, 0x91, 0x73, 0x79, 0xf8, 0xe6,
- 0x54, 0xf4, 0x5e, 0x86, 0xd7, 0xe5, 0x92, 0x87, 0xbf, 0xc4, 0x3c, 0xfc,
- 0x6d, 0x45, 0xd6, 0x10, 0x55, 0xdc, 0xb8, 0xc0, 0xc1, 0xf8, 0xa2, 0xfb,
- 0x5f, 0x74, 0xc4, 0xe5, 0x39, 0xb2, 0xff, 0x7e, 0xde, 0x7f, 0x9e, 0xf1,
- 0x7c, 0x80, 0x33, 0x11, 0xad, 0x76, 0xe0, 0x99, 0x85, 0xf1, 0xa8, 0x8b,
- 0xd7, 0x7b, 0xc9, 0x53, 0x66, 0x1a, 0x07, 0xe9, 0x9b, 0xb5, 0xe1, 0xf9,
- 0x0e, 0x07, 0xce, 0x98, 0x7a, 0xcb, 0x6e, 0x5e, 0x7b, 0x36, 0x23, 0xbe,
- 0x18, 0x26, 0x7e, 0x2d, 0xca, 0xfb, 0xa2, 0xbc, 0x8f, 0x01, 0xf7, 0x6c,
- 0xda, 0xeb, 0x6b, 0x29, 0xbd, 0xff, 0x59, 0xda, 0x69, 0xf5, 0x59, 0x3b,
- 0x2d, 0xec, 0xd3, 0x82, 0xbb, 0x2a, 0xd2, 0x82, 0x50, 0xb2, 0xb0, 0x5f,
- 0x6b, 0x3f, 0x7a, 0x32, 0xf7, 0x60, 0xe3, 0x4e, 0x7d, 0xa3, 0xac, 0x11,
- 0xbd, 0x10, 0x8a, 0x5b, 0x95, 0x46, 0x27, 0x5c, 0x0b, 0x8c, 0x16, 0xe6,
- 0x2f, 0xb1, 0xef, 0x2a, 0xa5, 0xb4, 0xdf, 0xc3, 0xd8, 0x34, 0xac, 0x07,
- 0xb7, 0x2b, 0x06, 0xe3, 0x86, 0x86, 0xfd, 0x83, 0x45, 0xb8, 0x75, 0x57,
- 0x1b, 0xf6, 0xf5, 0x9b, 0xc4, 0xcf, 0x5a, 0xff, 0x69, 0xbc, 0x87, 0x63,
- 0xa6, 0xbc, 0xaf, 0x54, 0x82, 0x36, 0x4d, 0xf6, 0x29, 0x31, 0xfb, 0x9c,
- 0x7e, 0xde, 0x3b, 0xe0, 0x9e, 0x12, 0xa3, 0xf0, 0x2e, 0xbf, 0xc1, 0x7c,
- 0x71, 0x12, 0x7b, 0x06, 0x65, 0x6d, 0x60, 0x9a, 0x72, 0xa4, 0x7f, 0xae,
- 0xaf, 0x8b, 0xd8, 0x7f, 0xaf, 0x99, 0xc5, 0x99, 0x85, 0xd5, 0xc0, 0x0c,
- 0x05, 0xa1, 0xcf, 0x04, 0xe4, 0x5b, 0x35, 0xfc, 0x7b, 0xd7, 0xf2, 0x7f,
- 0x51, 0xda, 0xa9, 0xa9, 0xc8, 0xad, 0x17, 0xbc, 0x5e, 0x2d, 0xef, 0xf2,
- 0x1d, 0x49, 0xcd, 0xac, 0xcc, 0x3d, 0x77, 0xfe, 0xa4, 0x3e, 0x5e, 0xb3,
- 0xfc, 0x76, 0x1b, 0x85, 0xba, 0xaf, 0x5a, 0x51, 0xaf, 0x94, 0x2f, 0x62,
- 0xdb, 0xe2, 0x9f, 0xd3, 0x94, 0x76, 0xe2, 0xa9, 0x1a, 0x9a, 0xa6, 0xb4,
- 0x0d, 0x5d, 0xd8, 0xee, 0x8b, 0x56, 0xb4, 0x45, 0xce, 0x0b, 0xe5, 0xdc,
- 0xd3, 0x50, 0x2a, 0x65, 0x0b, 0xf7, 0x9f, 0xc9, 0xb7, 0x55, 0x4c, 0xae,
- 0x9a, 0x2b, 0x73, 0x6b, 0xbf, 0xec, 0xad, 0x8a, 0xe2, 0x68, 0xc3, 0xd4,
- 0xf6, 0x0a, 0x7d, 0x7f, 0xef, 0xbc, 0xf6, 0x72, 0x65, 0x67, 0xb1, 0x4d,
- 0x29, 0x9f, 0xc5, 0xff, 0x6b, 0xaf, 0x23, 0xbc, 0x61, 0xef, 0x93, 0xdc,
- 0x6a, 0x36, 0x46, 0x4b, 0xf0, 0x39, 0xa8, 0x97, 0xc6, 0xe7, 0x97, 0xd8,
- 0xfc, 0x36, 0xda, 0x52, 0xc2, 0x1c, 0xd7, 0x6d, 0x44, 0xef, 0x75, 0x23,
- 0x9b, 0x65, 0x5c, 0x6e, 0x3d, 0xa3, 0xec, 0x57, 0x6e, 0x0d, 0xe8, 0x1b,
- 0xdf, 0x25, 0xdf, 0x78, 0x3e, 0x10, 0x27, 0xd6, 0x1b, 0xbe, 0x3e, 0x45,
- 0x37, 0xd7, 0x32, 0xa6, 0x3d, 0xcb, 0x1c, 0x72, 0x4d, 0xa0, 0xd7, 0x7e,
- 0xc6, 0xa8, 0x44, 0x56, 0xe0, 0x12, 0xfb, 0xbb, 0x2c, 0x2d, 0x30, 0xd2,
- 0xcf, 0xcb, 0x9a, 0x17, 0x7f, 0xc7, 0x30, 0xdf, 0xbe, 0xb6, 0x06, 0x41,
- 0xfb, 0xff, 0xaa, 0xfc, 0xb7, 0x5b, 0x5a, 0x51, 0x6b, 0xff, 0xbf, 0x19,
- 0x73, 0xd3, 0x67, 0xd7, 0x86, 0xd1, 0x6d, 0x5a, 0xd6, 0x53, 0xa6, 0x85,
- 0x37, 0xce, 0xed, 0xd1, 0x5e, 0xe1, 0x60, 0xce, 0x41, 0x17, 0x8e, 0xe5,
- 0xbe, 0x5d, 0x75, 0xee, 0xfd, 0x8c, 0xa5, 0xe7, 0xed, 0xd1, 0x96, 0xf7,
- 0xe2, 0xab, 0xed, 0x6f, 0x93, 0xcd, 0x5b, 0xe4, 0xc4, 0x73, 0x89, 0x8a,
- 0x98, 0x87, 0xbf, 0x37, 0x2d, 0x2a, 0xc2, 0xfa, 0x10, 0x39, 0xdf, 0xa5,
- 0xc7, 0x71, 0xda, 0xfe, 0x46, 0x43, 0x3c, 0x24, 0xdf, 0x66, 0x38, 0x9a,
- 0x50, 0x71, 0x6c, 0xb0, 0x27, 0xb4, 0xc7, 0xee, 0xfb, 0x55, 0x74, 0x8f,
- 0xca, 0x73, 0xbf, 0x16, 0xac, 0x4e, 0x4c, 0xda, 0x7b, 0xda, 0x36, 0xa7,
- 0x24, 0xf7, 0xd6, 0xb3, 0x6b, 0x98, 0xaf, 0xaa, 0x8e, 0x20, 0x6e, 0x62,
- 0x7c, 0x79, 0x21, 0x41, 0x3b, 0x5d, 0xa8, 0x77, 0x7c, 0x97, 0x1c, 0xa1,
- 0x22, 0xa2, 0x07, 0xdf, 0x51, 0x5a, 0xc9, 0xc5, 0xdc, 0x98, 0x48, 0x88,
- 0x2d, 0xca, 0xb7, 0x9d, 0x6e, 0xc6, 0x7e, 0x72, 0xd2, 0xe7, 0x13, 0x1a,
- 0x4e, 0x37, 0x78, 0x90, 0x26, 0x47, 0x7d, 0x2e, 0xe1, 0xc6, 0x63, 0xe4,
- 0xa8, 0x8f, 0x0e, 0xca, 0x1a, 0x61, 0x13, 0x1a, 0x13, 0xb2, 0x3e, 0x4c,
- 0xde, 0x35, 0xe2, 0xa5, 0x3d, 0x5a, 0x56, 0x37, 0x6d, 0xb7, 0x4d, 0x9b,
- 0x60, 0x9f, 0xb2, 0xae, 0x18, 0xc5, 0x35, 0xe4, 0x1d, 0x8f, 0x8e, 0xf8,
- 0xf0, 0x7d, 0x72, 0xf3, 0x24, 0xeb, 0xbd, 0x90, 0xf0, 0xa3, 0x2f, 0xed,
- 0xc3, 0xd3, 0xe4, 0xe8, 0x5b, 0x78, 0x2e, 0xdf, 0x09, 0x2b, 0x32, 0x82,
- 0xe4, 0xc1, 0x87, 0x51, 0xd6, 0x77, 0x11, 0xd6, 0xad, 0x3c, 0x08, 0xb5,
- 0xef, 0x10, 0x8f, 0x2b, 0x19, 0xb3, 0xaf, 0x44, 0x6a, 0x30, 0x82, 0xd4,
- 0xc8, 0x8f, 0xd0, 0x3b, 0x28, 0xe3, 0x92, 0xef, 0x3d, 0xc9, 0xbe, 0x27,
- 0x72, 0xbd, 0x3e, 0x2f, 0x86, 0x46, 0xa4, 0x9f, 0x6a, 0xf6, 0xfd, 0xe7,
- 0xb6, 0xff, 0x1f, 0xd6, 0xba, 0x1b, 0xa5, 0xed, 0x83, 0x9f, 0xd0, 0xbe,
- 0xe8, 0xaa, 0xf0, 0x9e, 0xa1, 0xac, 0x75, 0xb8, 0xd9, 0xa6, 0x07, 0x8e,
- 0x48, 0x76, 0x65, 0x39, 0xf4, 0xe8, 0x36, 0xc5, 0x68, 0x2e, 0x53, 0x26,
- 0xb1, 0x2d, 0x23, 0xef, 0x8d, 0x15, 0xe3, 0x69, 0xe2, 0xa3, 0x2b, 0xa4,
- 0x6b, 0xdf, 0xa5, 0xed, 0x2c, 0x21, 0xa6, 0xbc, 0x61, 0x7e, 0x06, 0x71,
- 0x4d, 0xf4, 0x57, 0x8c, 0x1f, 0xf4, 0xbb, 0xf1, 0x4e, 0x28, 0x82, 0xdc,
- 0xb7, 0xbd, 0x3c, 0xf8, 0x71, 0xc2, 0xcb, 0xf9, 0xaa, 0xcb, 0x1a, 0x8e,
- 0xb9, 0xc0, 0xb4, 0xdc, 0xb5, 0xa3, 0x89, 0x35, 0xd8, 0x43, 0x79, 0x5f,
- 0x48, 0x9c, 0xe1, 0xfc, 0xb4, 0x53, 0xff, 0xa2, 0xef, 0x78, 0x5e, 0xd7,
- 0x3d, 0xd4, 0xf5, 0x2c, 0x3c, 0x9b, 0xb8, 0x0f, 0x8f, 0x52, 0xfe, 0x47,
- 0xfa, 0x8d, 0xe8, 0xc5, 0xca, 0x61, 0xe2, 0x65, 0x31, 0x8e, 0xb1, 0xed,
- 0x5b, 0x99, 0x29, 0x4f, 0x4a, 0x5f, 0x29, 0x59, 0x9f, 0x54, 0xf0, 0xce,
- 0xa2, 0xc3, 0x18, 0xe7, 0xbd, 0x1f, 0xf3, 0x77, 0x78, 0x61, 0x25, 0xfb,
- 0x10, 0xfd, 0xf8, 0xed, 0x5c, 0xa0, 0x8b, 0x3c, 0x67, 0x79, 0xc3, 0x61,
- 0x6c, 0x1d, 0x92, 0x6b, 0x6d, 0xe8, 0xed, 0x7f, 0x0f, 0x8e, 0x10, 0x71,
- 0xc8, 0xdb, 0x40, 0x5b, 0xcf, 0x62, 0x5b, 0xfa, 0xc3, 0x69, 0x39, 0x0e,
- 0xfa, 0xca, 0x34, 0xd9, 0x8b, 0x7c, 0x34, 0x51, 0x8c, 0xe7, 0x58, 0x67,
- 0x5d, 0xc8, 0x95, 0x7f, 0x66, 0x72, 0x98, 0xfc, 0xc9, 0x89, 0x34, 0xfb,
- 0x48, 0xd8, 0x6d, 0x4c, 0x53, 0x76, 0xd3, 0x0f, 0x2b, 0x17, 0x4e, 0x53,
- 0x52, 0x43, 0xc2, 0xed, 0x7f, 0x84, 0x27, 0xef, 0xcf, 0xe9, 0x70, 0x8f,
- 0xb9, 0x06, 0x43, 0xe9, 0x1f, 0x17, 0xda, 0x9b, 0xf2, 0x2e, 0x9c, 0xbc,
- 0x9f, 0x53, 0x78, 0x57, 0x27, 0xf7, 0x4c, 0xeb, 0xdb, 0x99, 0x0a, 0xf2,
- 0xe7, 0x52, 0xda, 0x5a, 0x51, 0xcc, 0xcb, 0xb8, 0xba, 0x66, 0x81, 0x86,
- 0x9d, 0x97, 0xd5, 0x4d, 0x43, 0x85, 0xe6, 0xfc, 0x75, 0xc3, 0xf3, 0xec,
- 0xa7, 0x22, 0x56, 0x15, 0xd9, 0x63, 0xef, 0x83, 0x0a, 0x5d, 0x56, 0xc3,
- 0xb8, 0x22, 0xcf, 0x86, 0x63, 0x78, 0x2b, 0x51, 0x1d, 0xab, 0x8e, 0x54,
- 0x12, 0x6f, 0x4f, 0xa3, 0x6f, 0xd8, 0x89, 0x0a, 0xf2, 0xe6, 0xf2, 0x64,
- 0x35, 0xdc, 0xf6, 0x3a, 0xde, 0x45, 0xe4, 0x2b, 0xb3, 0xc9, 0x49, 0x66,
- 0xa1, 0x92, 0xbc, 0xc4, 0x13, 0xb2, 0xac, 0x9f, 0x2d, 0xb4, 0xac, 0x4b,
- 0x78, 0x94, 0xf0, 0x38, 0x15, 0x12, 0x3f, 0x8d, 0xa2, 0xce, 0xf6, 0x57,
- 0x03, 0xf5, 0xf6, 0xff, 0x26, 0xfa, 0x7a, 0x47, 0x68, 0xfe, 0xf8, 0x7d,
- 0xa1, 0xb9, 0xe3, 0x35, 0x50, 0x07, 0xa6, 0xc3, 0xc1, 0xb6, 0xbe, 0x70,
- 0x99, 0x85, 0x26, 0xfa, 0xf0, 0x5a, 0x53, 0x78, 0xd1, 0x1a, 0xf2, 0xa2,
- 0xde, 0x90, 0x31, 0x7e, 0x10, 0x57, 0x33, 0xce, 0xb9, 0x07, 0x7c, 0xec,
- 0x47, 0x72, 0x6c, 0x67, 0x76, 0x0e, 0xf9, 0xf6, 0x67, 0x16, 0x0a, 0x47,
- 0x6a, 0x25, 0x47, 0x3a, 0x84, 0xd6, 0xf1, 0xc3, 0xb8, 0x9e, 0x65, 0x3c,
- 0xe4, 0x2a, 0xc9, 0xcc, 0x8f, 0xd0, 0x97, 0xb1, 0xb0, 0x3d, 0x94, 0xc5,
- 0xb5, 0x6c, 0xbb, 0x74, 0xa0, 0x99, 0xdc, 0x70, 0x05, 0xd6, 0x8d, 0xcb,
- 0xbb, 0x52, 0x13, 0x58, 0x3e, 0x4e, 0xce, 0x39, 0x5e, 0xf0, 0x57, 0xe1,
- 0x4b, 0x2b, 0xc8, 0x97, 0x64, 0x2d, 0x6d, 0x95, 0xbd, 0x96, 0xa6, 0xd2,
- 0x0f, 0x1b, 0x13, 0xf2, 0x9e, 0x50, 0x1c, 0xab, 0xc7, 0x05, 0xab, 0xef,
- 0x41, 0xf7, 0xb8, 0xac, 0xcd, 0x7e, 0x33, 0x74, 0xf1, 0xf8, 0xab, 0x68,
- 0x1c, 0x1f, 0x0a, 0xcd, 0x1b, 0x1f, 0xa1, 0xdc, 0x09, 0xca, 0xd6, 0x1f,
- 0xaa, 0x1d, 0x1f, 0x0c, 0x05, 0xc7, 0x77, 0x87, 0x02, 0xe3, 0x2d, 0xd8,
- 0x32, 0xbe, 0x0a, 0x9b, 0xc7, 0x37, 0x62, 0xd3, 0xb8, 0xe0, 0xfc, 0x24,
- 0x96, 0x8d, 0xbf, 0x81, 0xa5, 0xe3, 0xcf, 0xa3, 0x69, 0xfc, 0x04, 0x96,
- 0x8c, 0xff, 0x08, 0xcd, 0xe3, 0xaf, 0x70, 0x2c, 0xb2, 0xd6, 0x2b, 0xeb,
- 0xbc, 0x85, 0xe7, 0x6a, 0x53, 0xf7, 0x24, 0xcb, 0x5a, 0x86, 0x7c, 0xbf,
- 0x43, 0xe6, 0xd0, 0x85, 0x95, 0xda, 0x6b, 0xe8, 0xd9, 0x25, 0xdf, 0x24,
- 0xac, 0xd3, 0xba, 0xe5, 0xf9, 0xa3, 0xf7, 0x79, 0xd9, 0x63, 0x4f, 0x1b,
- 0x3b, 0xff, 0xbd, 0xbc, 0xc9, 0xb3, 0xcf, 0x18, 0xe5, 0x1b, 0x18, 0xf2,
- 0xec, 0x73, 0x12, 0x5d, 0x99, 0xdf, 0x5a, 0x51, 0x4d, 0xca, 0xca, 0xf7,
- 0x3f, 0xc4, 0x1e, 0x5e, 0xc3, 0x43, 0xbb, 0x26, 0xc9, 0x59, 0xb2, 0xf6,
- 0x5a, 0xcd, 0xbb, 0xf3, 0xe4, 0x9b, 0x56, 0xf2, 0xce, 0xfe, 0x6b, 0x48,
- 0x8d, 0x02, 0xe3, 0x0f, 0x8b, 0x1f, 0xae, 0xa1, 0x1f, 0x66, 0xc5, 0x27,
- 0xe3, 0xc4, 0xe4, 0xaf, 0x78, 0x70, 0x0f, 0x79, 0x49, 0x11, 0xb2, 0x23,
- 0xa5, 0x78, 0x66, 0x30, 0x6e, 0xcd, 0x31, 0x3c, 0x28, 0x8f, 0x18, 0xd9,
- 0x4b, 0x18, 0x67, 0x5f, 0xe1, 0xb5, 0x89, 0x7e, 0xf8, 0x7d, 0x46, 0xc0,
- 0x37, 0x87, 0xe7, 0xc7, 0x86, 0xb2, 0xe4, 0x14, 0x1d, 0x98, 0xe4, 0x7f,
- 0xc9, 0x41, 0x81, 0x6e, 0x0c, 0x0d, 0x89, 0x3e, 0x5b, 0xa8, 0x4f, 0xc1,
- 0x45, 0xbd, 0xa3, 0x89, 0x78, 0x68, 0x29, 0x82, 0x87, 0x2a, 0xca, 0x1e,
- 0xe8, 0xa4, 0xbf, 0xea, 0xb1, 0x9f, 0x30, 0x16, 0xf4, 0x29, 0x3f, 0xc2,
- 0x73, 0xcc, 0x19, 0x4a, 0x1f, 0x20, 0xff, 0x20, 0x56, 0x56, 0x44, 0x14,
- 0x63, 0x79, 0xe0, 0x14, 0x9e, 0x19, 0x71, 0xc2, 0x9d, 0x74, 0x62, 0x82,
- 0x38, 0xe9, 0x48, 0xca, 0xf3, 0x7a, 0x8d, 0xb2, 0xc8, 0xba, 0xd0, 0x09,
- 0x64, 0xed, 0xe7, 0x69, 0xf2, 0x3c, 0xe4, 0x45, 0xbb, 0x1f, 0x27, 0x65,
- 0xef, 0x21, 0x96, 0x76, 0xa5, 0x5e, 0x42, 0xd3, 0x90, 0x07, 0x73, 0x92,
- 0x13, 0xcc, 0x5f, 0x5e, 0x45, 0x6a, 0xd7, 0x2c, 0x7c, 0x95, 0x3c, 0x70,
- 0x66, 0xd2, 0x84, 0x46, 0xbd, 0xdd, 0x34, 0x66, 0x22, 0xba, 0x77, 0x15,
- 0x56, 0xee, 0xfd, 0x22, 0x8f, 0xe9, 0xb8, 0x7e, 0x6f, 0x3b, 0x3e, 0x3f,
- 0x16, 0x47, 0xeb, 0x58, 0x0f, 0x8f, 0x36, 0x5c, 0xb7, 0xa3, 0x12, 0xe9,
- 0x90, 0xc6, 0x9c, 0xba, 0x8d, 0x39, 0xb5, 0xf0, 0xa1, 0xd5, 0x78, 0x86,
- 0xb8, 0x13, 0x0c, 0xad, 0xc6, 0x84, 0xed, 0x8b, 0xb2, 0x97, 0x71, 0x35,
- 0x36, 0x31, 0x5f, 0x1e, 0xc6, 0x6a, 0x74, 0xf1, 0xda, 0x0e, 0x7b, 0x0e,
- 0x0e, 0x63, 0x31, 0xf3, 0xa1, 0xf7, 0x2f, 0x3f, 0x8c, 0x2b, 0xf6, 0x48,
- 0xdf, 0xa7, 0x91, 0xda, 0xb9, 0x86, 0x6d, 0x66, 0xd1, 0x32, 0xf6, 0x43,
- 0x7c, 0x7e, 0x07, 0x6e, 0xab, 0x44, 0x25, 0x9e, 0x0f, 0x05, 0x5a, 0xfb,
- 0x94, 0x1f, 0xda, 0x6d, 0x6f, 0xa2, 0x1f, 0x6f, 0x65, 0xb9, 0x47, 0xd2,
- 0x27, 0xd0, 0x9b, 0x9a, 0x3a, 0xa7, 0xf6, 0x7b, 0xed, 0x8c, 0x07, 0x2f,
- 0x63, 0xdf, 0xc8, 0x24, 0xb1, 0xf7, 0x24, 0x8f, 0x0b, 0x9f, 0x5f, 0x7b,
- 0xed, 0x7c, 0x26, 0x67, 0x37, 0x92, 0xbf, 0xc8, 0x3a, 0x70, 0x0b, 0x7c,
- 0x29, 0xe1, 0x44, 0xd9, 0xad, 0x33, 0xa1, 0x6f, 0x0c, 0xdb, 0x1c, 0xc9,
- 0x88, 0x91, 0x1b, 0xb5, 0x7c, 0x57, 0xf1, 0x90, 0x1b, 0x05, 0xb1, 0x22,
- 0xa3, 0x47, 0xaf, 0xa5, 0xbe, 0x4b, 0xee, 0x7f, 0x19, 0xce, 0xfb, 0x9d,
- 0x28, 0x4e, 0xca, 0xda, 0xc9, 0x04, 0x7a, 0x33, 0xf2, 0xfe, 0x6e, 0x56,
- 0x2f, 0x26, 0xae, 0x16, 0x25, 0xb3, 0x8c, 0xfd, 0xd9, 0xf9, 0x45, 0x90,
- 0x77, 0xf1, 0xaf, 0xc2, 0x9a, 0xfe, 0x28, 0xba, 0x4c, 0x79, 0x57, 0x27,
- 0x37, 0xfe, 0x39, 0x0d, 0x2f, 0xa3, 0x9b, 0xf1, 0xa7, 0x8d, 0x98, 0xf8,
- 0x55, 0xfb, 0x59, 0xe8, 0xcb, 0xe8, 0x19, 0x2c, 0xbc, 0xbb, 0x2e, 0x6d,
- 0x3e, 0x4f, 0xbd, 0xb9, 0xf2, 0xdf, 0xec, 0x91, 0x36, 0x75, 0xd3, 0xaf,
- 0x4e, 0xcb, 0xbd, 0x8b, 0x03, 0xfb, 0x19, 0x36, 0xed, 0xe3, 0x35, 0xf4,
- 0xee, 0x2a, 0x8c, 0x99, 0xb9, 0x41, 0xe0, 0x35, 0xf4, 0x8f, 0xca, 0xd8,
- 0xaf, 0x9f, 0x96, 0x7b, 0xc7, 0x78, 0xaa, 0x3e, 0x0a, 0x75, 0x1d, 0xb4,
- 0xe7, 0xc2, 0xfd, 0x8f, 0xfb, 0x6e, 0xd0, 0xa7, 0xec, 0x6f, 0xf0, 0xe4,
- 0xbe, 0x81, 0x04, 0x3c, 0x99, 0x90, 0x77, 0xfb, 0xd5, 0xc5, 0x2e, 0xa8,
- 0x5e, 0x17, 0x8a, 0x19, 0x2f, 0x6a, 0xd0, 0xed, 0xb5, 0x70, 0x35, 0xc7,
- 0xb2, 0xbf, 0xfe, 0x3a, 0x66, 0x1a, 0xf1, 0x56, 0x97, 0xfd, 0xce, 0xe1,
- 0x8a, 0xbf, 0xfe, 0xe8, 0x3b, 0x87, 0x6f, 0x10, 0x67, 0x15, 0x94, 0x1b,
- 0x37, 0xe1, 0x05, 0x3b, 0xa6, 0x28, 0x28, 0x9b, 0x2b, 0xeb, 0x98, 0x7e,
- 0x3c, 0x6b, 0xd4, 0xf9, 0xab, 0xe4, 0xf9, 0x94, 0x72, 0xca, 0x92, 0x6f,
- 0x06, 0x6c, 0xcb, 0xfc, 0xb1, 0x3d, 0xf1, 0x4f, 0x61, 0xcb, 0xce, 0x30,
- 0xe4, 0xfd, 0x15, 0xa7, 0xa1, 0x79, 0x73, 0xfc, 0x4a, 0x64, 0x93, 0xbd,
- 0xe4, 0xb7, 0x12, 0x9c, 0xde, 0xa0, 0x9f, 0xbe, 0x21, 0x7b, 0xa6, 0xc8,
- 0x99, 0xfe, 0x12, 0xc1, 0xaa, 0xc2, 0x38, 0x65, 0xaf, 0xa9, 0x92, 0x1b,
- 0xab, 0x5d, 0x47, 0xca, 0x4a, 0xbd, 0x37, 0xec, 0x35, 0x5c, 0x97, 0xf1,
- 0x5b, 0xeb, 0x4d, 0x6f, 0x35, 0xcb, 0x1e, 0xce, 0xdf, 0x9f, 0x14, 0x9f,
- 0x33, 0xe5, 0x1b, 0x56, 0x4e, 0xbb, 0x8e, 0xe8, 0xf7, 0x5c, 0x9d, 0xee,
- 0x94, 0x83, 0xb8, 0x79, 0xc2, 0xea, 0xf4, 0xca, 0x18, 0xee, 0xbc, 0xa0,
- 0x8e, 0xac, 0x2b, 0x68, 0xd2, 0x6f, 0x58, 0xc6, 0xdc, 0x95, 0xf9, 0x68,
- 0x9f, 0xb2, 0xde, 0x5b, 0x64, 0x94, 0xe1, 0x54, 0x55, 0x6e, 0x1d, 0xe6,
- 0x9c, 0x8c, 0x3d, 0x35, 0xb2, 0x4f, 0xaf, 0xd8, 0x3e, 0xb7, 0xfb, 0x35,
- 0xcf, 0xd5, 0xfb, 0xbb, 0xfc, 0x78, 0xab, 0xed, 0x77, 0x86, 0x1e, 0xb4,
- 0x79, 0x91, 0x63, 0xca, 0xb8, 0x4b, 0x6a, 0xce, 0xef, 0xe7, 0x2b, 0xf9,
- 0x7e, 0x45, 0x1e, 0xef, 0x94, 0x3e, 0x44, 0xae, 0x87, 0xf3, 0x75, 0xf4,
- 0x70, 0xd4, 0xee, 0x5f, 0x65, 0xbe, 0x55, 0xe8, 0x93, 0xfe, 0xb8, 0xb0,
- 0xd0, 0x46, 0x56, 0xec, 0xb3, 0xb3, 0x98, 0xb1, 0xed, 0x54, 0xc3, 0x3d,
- 0xd8, 0x94, 0x10, 0x3d, 0xcb, 0xb7, 0x60, 0x89, 0xe1, 0x36, 0x57, 0x73,
- 0xd1, 0x5f, 0x2f, 0xc3, 0x90, 0x16, 0xc7, 0x9e, 0x7a, 0x79, 0x47, 0xce,
- 0x45, 0x9f, 0x88, 0xa3, 0xc4, 0x28, 0x96, 0xfd, 0xc7, 0xf6, 0x1e, 0x94,
- 0x7d, 0xa6, 0x1e, 0x7d, 0x52, 0xbe, 0x55, 0x76, 0xa9, 0xbd, 0x5e, 0xd5,
- 0x3c, 0x04, 0xb9, 0x6e, 0xe2, 0xda, 0xf3, 0xf2, 0xfe, 0x12, 0xda, 0x8e,
- 0xbd, 0x27, 0xda, 0x94, 0x77, 0xe8, 0xfa, 0x12, 0xf2, 0x2e, 0x57, 0x5d,
- 0x8c, 0xfc, 0x12, 0x2f, 0xa4, 0x65, 0xbf, 0xc2, 0xef, 0xac, 0x78, 0x8d,
- 0xec, 0x8b, 0x9c, 0x5a, 0xa7, 0x88, 0xb8, 0x16, 0x08, 0x57, 0x28, 0x85,
- 0xf7, 0xb9, 0xce, 0xfd, 0x5d, 0x4f, 0x9b, 0x39, 0x6d, 0xbf, 0x83, 0x27,
- 0x67, 0x11, 0x34, 0xa6, 0xe4, 0x9b, 0xa7, 0xfa, 0xc4, 0x72, 0xd4, 0x65,
- 0x6b, 0x1d, 0xce, 0x3c, 0x7f, 0x09, 0x63, 0x05, 0xed, 0x66, 0x73, 0x20,
- 0x6c, 0xbf, 0x6b, 0xb6, 0x2c, 0x55, 0x1b, 0x7c, 0x04, 0x7a, 0xfb, 0xdb,
- 0x2c, 0x7f, 0x5d, 0xe6, 0xfb, 0xd6, 0x90, 0x57, 0xc6, 0x54, 0xc0, 0x88,
- 0x13, 0xf4, 0x0d, 0xea, 0x31, 0x22, 0xfe, 0xe1, 0x41, 0x55, 0x24, 0x4c,
- 0x3f, 0x96, 0xf8, 0x2f, 0xef, 0xa9, 0xe9, 0xbb, 0xe3, 0x30, 0xd1, 0xc8,
- 0x1c, 0xdd, 0x65, 0xef, 0x73, 0xd6, 0xfd, 0x2b, 0x19, 0x87, 0x8e, 0x9c,
- 0xdd, 0x13, 0x20, 0x7c, 0xe1, 0xc7, 0x35, 0xf9, 0xbd, 0xd0, 0xee, 0x39,
- 0x8c, 0x8f, 0x96, 0xfd, 0x9c, 0x7f, 0x8d, 0x8d, 0x2d, 0x9a, 0xa1, 0xef,
- 0xff, 0x95, 0xa3, 0x13, 0x4f, 0x2c, 0x30, 0x3a, 0x0e, 0xa8, 0xd9, 0x21,
- 0x1f, 0x71, 0xe6, 0x4a, 0x47, 0x74, 0x07, 0xff, 0xfb, 0x5f, 0xb4, 0xbf,
- 0xa1, 0x22, 0x75, 0xf5, 0xe0, 0x2a, 0x55, 0xf6, 0x0f, 0xb5, 0x60, 0xac,
- 0x4f, 0xde, 0x7d, 0xd0, 0x5b, 0xbf, 0xad, 0x74, 0x62, 0x43, 0xc8, 0x68,
- 0xd9, 0xa8, 0xe8, 0xcd, 0x7f, 0xaf, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0x82,
- 0xb2, 0xb6, 0x77, 0x36, 0xf6, 0xba, 0xd8, 0xc7, 0xde, 0x84, 0x1e, 0x9e,
- 0xc6, 0xb2, 0xa7, 0x4c, 0xc3, 0xf7, 0x1e, 0xdb, 0xfc, 0x09, 0x8f, 0x1d,
- 0xf6, 0x3b, 0xec, 0x52, 0x3e, 0x3a, 0xdf, 0x65, 0x7f, 0x8f, 0xb8, 0x95,
- 0x31, 0x45, 0xbe, 0x35, 0x1c, 0x83, 0x96, 0x9c, 0x45, 0x13, 0xd3, 0x7b,
- 0x6f, 0x80, 0xe4, 0xc0, 0x37, 0x4f, 0x47, 0xa9, 0x07, 0xde, 0x48, 0x27,
- 0xe6, 0x2e, 0x30, 0x7c, 0x8b, 0x54, 0xbb, 0x7e, 0x30, 0xaa, 0x4a, 0x7d,
- 0xdd, 0x3f, 0x08, 0x69, 0x23, 0x6b, 0x69, 0x73, 0x2b, 0xed, 0x3a, 0x0b,
- 0xd4, 0xcf, 0xc1, 0xf5, 0xe9, 0x5f, 0xcb, 0x37, 0x8b, 0xb4, 0x6a, 0x43,
- 0xea, 0xc4, 0x77, 0x68, 0xf8, 0x63, 0xf5, 0x04, 0x57, 0x7e, 0x65, 0x61,
- 0xba, 0xd4, 0x93, 0x3d, 0x66, 0x37, 0xe3, 0x76, 0xfb, 0xbb, 0x2b, 0xe2,
- 0x8f, 0x7a, 0xf4, 0x6e, 0x72, 0xd5, 0x52, 0x45, 0x78, 0xaa, 0xc4, 0xa2,
- 0x36, 0xe2, 0x61, 0x27, 0xb4, 0x90, 0xde, 0x7b, 0x91, 0xea, 0x41, 0x71,
- 0x64, 0x54, 0xf6, 0xd9, 0xec, 0x9e, 0xa7, 0xe6, 0xf6, 0xe3, 0xc4, 0xd8,
- 0xee, 0x91, 0x3f, 0xfa, 0xdc, 0x97, 0x7d, 0x95, 0x9a, 0xf2, 0xce, 0x8e,
- 0xfd, 0x9e, 0x48, 0x5b, 0xc2, 0x91, 0xdf, 0x5f, 0x58, 0x98, 0x5b, 0x0d,
- 0x6b, 0x98, 0x17, 0xac, 0x95, 0x6f, 0x63, 0x72, 0xac, 0xeb, 0x12, 0xb2,
- 0x0a, 0xf5, 0x7f, 0x01, 0x28, 0xfc, 0xfc, 0x40, 0x38, 0x5a, 0x00, 0x00,
- 0x00 };
+ 0x9d, 0xbc, 0x0d, 0x7c, 0x1b, 0xe5, 0x95, 0x2e, 0xfe, 0xcc, 0x48, 0xb2,
+ 0x65, 0x5b, 0xb6, 0xc7, 0x8e, 0x92, 0x28, 0xac, 0x37, 0xd1, 0xc4, 0x23,
+ 0x47, 0xc1, 0xa6, 0x8c, 0x12, 0x27, 0xa8, 0xac, 0x4a, 0x54, 0xc7, 0x24,
+ 0x4e, 0x48, 0xc1, 0x29, 0x69, 0x6b, 0xb8, 0x2d, 0xa8, 0xf9, 0xc2, 0x84,
+ 0x40, 0x43, 0xcb, 0xde, 0x6b, 0xee, 0xed, 0xae, 0x55, 0xdb, 0x49, 0x9c,
+ 0x44, 0x96, 0x6c, 0xc7, 0x24, 0xa1, 0xdb, 0xff, 0xa2, 0xc4, 0xce, 0x07,
+ 0x54, 0xb6, 0xd2, 0x96, 0xee, 0x86, 0xde, 0x74, 0xd1, 0x4d, 0x02, 0x18,
+ 0xca, 0x47, 0xda, 0xe5, 0x76, 0x69, 0x7f, 0xbd, 0xc5, 0x97, 0x42, 0x08,
+ 0x5b, 0x0a, 0xe9, 0xe7, 0x86, 0x7e, 0x30, 0xf7, 0x39, 0x23, 0x29, 0x31,
+ 0x2c, 0xdb, 0x76, 0xff, 0xfa, 0xfd, 0xe6, 0x27, 0xcd, 0xe8, 0xfd, 0x38,
+ 0xef, 0x79, 0xcf, 0x79, 0xce, 0x73, 0xde, 0x79, 0x67, 0xfc, 0x40, 0x39,
+ 0x0a, 0x9f, 0x4a, 0x1e, 0x1f, 0x6a, 0xde, 0xb6, 0x61, 0x69, 0xe8, 0x43,
+ 0x4b, 0xe5, 0xdc, 0xa9, 0x95, 0x38, 0xf1, 0x67, 0x7e, 0xfc, 0x7f, 0x6e,
+ 0xc1, 0xc2, 0x47, 0xe1, 0xd1, 0x58, 0xf8, 0xed, 0x00, 0xb4, 0x62, 0xff,
+ 0x72, 0xc0, 0xad, 0x46, 0xc6, 0x3a, 0x5a, 0x0c, 0xb8, 0x1d, 0x91, 0x6d,
+ 0xb7, 0x6f, 0x30, 0x80, 0x68, 0xa6, 0xd1, 0xbf, 0x1c, 0x7f, 0xb0, 0xe2,
+ 0x5e, 0x27, 0xe4, 0xfa, 0x5f, 0x46, 0x7e, 0xdf, 0xfd, 0xed, 0x6b, 0xf4,
+ 0x0b, 0x69, 0x07, 0xdc, 0x5a, 0x24, 0x0e, 0xad, 0x01, 0xee, 0x3a, 0xd6,
+ 0xf9, 0xca, 0x82, 0xaf, 0x28, 0xa8, 0x2a, 0xb6, 0x75, 0xde, 0xfa, 0xf6,
+ 0x02, 0x5f, 0xac, 0x2c, 0xa2, 0xe1, 0xf1, 0x2c, 0xda, 0x9b, 0x06, 0xba,
+ 0xad, 0x4a, 0x23, 0x04, 0xb7, 0x61, 0x74, 0x0c, 0x28, 0x9e, 0xf0, 0x96,
+ 0x25, 0xf0, 0x94, 0x1a, 0x88, 0x5f, 0x11, 0x41, 0xfb, 0x95, 0xe3, 0xe5,
+ 0x71, 0x67, 0xc4, 0x8d, 0xb6, 0xac, 0x3b, 0xfe, 0x17, 0x11, 0x03, 0x2b,
+ 0xb3, 0x46, 0x19, 0xaa, 0x34, 0xf4, 0x65, 0x5f, 0x77, 0xe7, 0xdb, 0x6b,
+ 0x2e, 0x7c, 0xdf, 0x56, 0x9b, 0xff, 0x9e, 0x15, 0x73, 0x46, 0x80, 0xed,
+ 0x09, 0xcb, 0x2a, 0x89, 0xdc, 0x7c, 0xb3, 0x1a, 0x31, 0x7c, 0x47, 0xb0,
+ 0x0c, 0xeb, 0x35, 0x7c, 0x71, 0x47, 0xf3, 0x2f, 0x94, 0x53, 0x23, 0x4d,
+ 0x88, 0x1f, 0x75, 0x20, 0xaa, 0x3d, 0xcb, 0xef, 0xb9, 0x73, 0x3b, 0xc2,
+ 0x4d, 0x38, 0x70, 0xf4, 0x22, 0xaf, 0x3b, 0xed, 0x6b, 0xbd, 0xfb, 0xe7,
+ 0xce, 0xbd, 0x25, 0xfc, 0x2c, 0x1e, 0x3c, 0x2a, 0xbf, 0xef, 0x40, 0x77,
+ 0x93, 0x82, 0xa9, 0x9b, 0x37, 0xc3, 0x61, 0x34, 0xa1, 0x6f, 0xbf, 0xe2,
+ 0xec, 0x69, 0x52, 0x11, 0xf5, 0xea, 0xc1, 0x18, 0x27, 0xc1, 0x69, 0x20,
+ 0x56, 0x1a, 0x09, 0x3b, 0xdf, 0x48, 0x44, 0x34, 0x87, 0x61, 0x59, 0xc1,
+ 0xd0, 0x6c, 0x38, 0x6a, 0x2c, 0xeb, 0x31, 0xd3, 0x03, 0xff, 0xa7, 0x9e,
+ 0x47, 0x7c, 0xb4, 0x1d, 0xaa, 0xf1, 0x3c, 0x7a, 0x46, 0x9f, 0xc7, 0x43,
+ 0x7b, 0xcb, 0x31, 0x35, 0x83, 0xe3, 0x4d, 0xf9, 0xf0, 0xed, 0x05, 0xd2,
+ 0xb7, 0xc8, 0xd1, 0xcc, 0xc3, 0x8d, 0x29, 0xc7, 0x39, 0x7e, 0x4b, 0x99,
+ 0x8b, 0xd6, 0xd4, 0xec, 0xcb, 0x65, 0xb6, 0xb3, 0x4c, 0xdf, 0xfb, 0xca,
+ 0xc4, 0x47, 0x23, 0xf8, 0x4e, 0x42, 0xc1, 0x96, 0x50, 0x15, 0xa2, 0x35,
+ 0x32, 0x5e, 0xcb, 0x3a, 0x6a, 0x9e, 0xb3, 0xa6, 0x34, 0xe9, 0x6b, 0x12,
+ 0xcf, 0xf2, 0xbf, 0x1d, 0xa1, 0x57, 0xad, 0x9c, 0x57, 0xda, 0xfb, 0x3c,
+ 0x6d, 0x68, 0x2d, 0xaf, 0x3b, 0x91, 0x4a, 0x20, 0x56, 0x15, 0xf9, 0x04,
+ 0xcf, 0x75, 0xf3, 0x2d, 0xc5, 0xed, 0x7e, 0x3b, 0xe1, 0xfe, 0x54, 0xa5,
+ 0xa1, 0xde, 0x57, 0x0d, 0x27, 0x9e, 0xa3, 0xcc, 0x27, 0xcc, 0xcd, 0x70,
+ 0x19, 0x5f, 0x10, 0x9b, 0xe3, 0xb8, 0x5e, 0xb4, 0x30, 0xbb, 0x58, 0x5f,
+ 0xda, 0xd5, 0xb0, 0x23, 0x65, 0x59, 0xbb, 0xcc, 0xe8, 0x87, 0xcb, 0x68,
+ 0x10, 0xa7, 0x13, 0xed, 0x70, 0x47, 0x02, 0xfe, 0xf3, 0x08, 0x63, 0x79,
+ 0xd6, 0x8b, 0x27, 0x12, 0x70, 0xb6, 0x2c, 0xa8, 0x43, 0x4f, 0x36, 0x82,
+ 0xeb, 0xb3, 0x26, 0x5a, 0xb3, 0x7f, 0xda, 0xca, 0x6e, 0x48, 0xf9, 0x39,
+ 0x86, 0x3f, 0x58, 0xf9, 0x31, 0xc8, 0xf8, 0xe4, 0x9b, 0xf3, 0x9a, 0xba,
+ 0x02, 0xbb, 0x47, 0x0c, 0xec, 0xe4, 0xfc, 0xad, 0x0a, 0xe5, 0xa2, 0x65,
+ 0xd0, 0xcd, 0xf3, 0x88, 0x60, 0x45, 0xd6, 0xe0, 0x9c, 0x46, 0xb0, 0x3c,
+ 0x55, 0xaf, 0x8d, 0x62, 0x21, 0xa2, 0xbe, 0xbc, 0x6d, 0xef, 0xe1, 0x78,
+ 0xd7, 0x07, 0xda, 0x51, 0x49, 0x1b, 0xc9, 0x2c, 0x09, 0xa3, 0x85, 0xfd,
+ 0xaf, 0xf9, 0x33, 0xfa, 0xbf, 0x89, 0xfd, 0xbf, 0xc5, 0xfe, 0x73, 0x76,
+ 0xff, 0x70, 0xae, 0xe6, 0xb9, 0x9b, 0xf6, 0xb8, 0x3b, 0xe3, 0x74, 0xae,
+ 0x4a, 0x79, 0xb1, 0x2b, 0x63, 0xd2, 0xe6, 0xe4, 0x2f, 0x1f, 0x76, 0x8c,
+ 0xd4, 0x61, 0xe7, 0x88, 0xee, 0x7b, 0x8a, 0xbf, 0x7b, 0xc7, 0xae, 0xc0,
+ 0xf6, 0x11, 0x05, 0x87, 0x8c, 0x2b, 0xd0, 0xc3, 0xdf, 0x07, 0x46, 0xe6,
+ 0xe2, 0xc1, 0x11, 0x07, 0xc2, 0x33, 0xa6, 0x8f, 0x43, 0xbe, 0xaf, 0x40,
+ 0x7c, 0xcc, 0x8f, 0x9e, 0xc4, 0xb3, 0xb6, 0x0e, 0x2b, 0x23, 0xdf, 0x2e,
+ 0xfa, 0x33, 0x7d, 0xc7, 0x8f, 0x0d, 0x09, 0x1f, 0x7a, 0x52, 0xe2, 0x07,
+ 0x6e, 0xda, 0xa6, 0xf8, 0xc1, 0xaf, 0x80, 0x2a, 0xb6, 0x9f, 0x2d, 0xfe,
+ 0xaf, 0xc0, 0xc9, 0x79, 0xdb, 0xc8, 0xff, 0x76, 0xa5, 0xc4, 0x26, 0xa4,
+ 0x4d, 0xb1, 0x0b, 0xf9, 0x5d, 0x4b, 0xbb, 0x2b, 0x87, 0xff, 0x70, 0x39,
+ 0x82, 0x0f, 0x68, 0x78, 0xad, 0x59, 0xae, 0xd3, 0xde, 0x43, 0x52, 0x66,
+ 0x10, 0x47, 0x32, 0xe2, 0xa7, 0x7e, 0xb4, 0x24, 0x26, 0xd9, 0x7e, 0x33,
+ 0xdb, 0x36, 0xf1, 0x4f, 0xd9, 0x26, 0xfc, 0x63, 0x36, 0x88, 0x7f, 0xa0,
+ 0x1e, 0xbf, 0x99, 0xf5, 0xe3, 0xd1, 0x6c, 0x1d, 0xbe, 0x91, 0xf5, 0xe1,
+ 0xeb, 0x9c, 0xbf, 0xaf, 0x65, 0xdb, 0x69, 0xfb, 0x1a, 0x8e, 0x67, 0x45,
+ 0xff, 0x25, 0x1c, 0x6f, 0x39, 0x7a, 0x47, 0xea, 0x83, 0xa7, 0x69, 0x5b,
+ 0xff, 0x60, 0xae, 0x46, 0xae, 0xb6, 0xd9, 0xb6, 0xc9, 0x5d, 0xbc, 0xbe,
+ 0x7b, 0xa4, 0x3e, 0x7a, 0xa5, 0x62, 0x59, 0x6a, 0xa8, 0x31, 0x7c, 0x4a,
+ 0x55, 0x31, 0xe5, 0xd5, 0xfd, 0x39, 0x55, 0xf7, 0x47, 0xe1, 0x42, 0x82,
+ 0xbe, 0x11, 0x9f, 0xa9, 0xa7, 0xe3, 0xb4, 0x29, 0xaf, 0x31, 0xca, 0xf1,
+ 0xe8, 0xfe, 0xb8, 0xaa, 0x61, 0x67, 0x4a, 0x3f, 0x10, 0x57, 0xbd, 0x88,
+ 0x67, 0xcb, 0xf1, 0xb3, 0x11, 0xbd, 0x3f, 0xae, 0xde, 0x88, 0x78, 0xad,
+ 0x65, 0x7d, 0x3d, 0x84, 0x6d, 0xb3, 0x23, 0x88, 0xce, 0x8c, 0x20, 0x36,
+ 0x37, 0x52, 0x87, 0x54, 0x0a, 0x78, 0x6b, 0xc0, 0xf0, 0xfd, 0x8b, 0xd2,
+ 0x8e, 0xbf, 0x6e, 0xd7, 0xfd, 0x7e, 0xb5, 0x31, 0x3e, 0xaa, 0x2e, 0xa1,
+ 0x4b, 0xc3, 0xef, 0x8b, 0xac, 0x44, 0x97, 0x7d, 0x4d, 0x81, 0x66, 0x78,
+ 0xd1, 0x9b, 0xfa, 0x30, 0x62, 0xde, 0xfa, 0x8e, 0x21, 0xb5, 0xfe, 0xa2,
+ 0xa9, 0xea, 0x93, 0xed, 0xaa, 0x65, 0xfd, 0x7c, 0xf1, 0x5b, 0x96, 0x7f,
+ 0x96, 0x65, 0x2d, 0x5a, 0x2c, 0x7d, 0xfa, 0x51, 0x13, 0x31, 0xb1, 0xd6,
+ 0x9e, 0xc3, 0x72, 0x9c, 0x1b, 0xa9, 0x65, 0x1f, 0x1a, 0xfe, 0xf7, 0x35,
+ 0x7a, 0x70, 0xb3, 0x5a, 0x8e, 0xd7, 0xc6, 0xca, 0xf1, 0x0a, 0xc7, 0xf3,
+ 0x8b, 0x11, 0x1f, 0x7e, 0x35, 0x62, 0x59, 0x9f, 0x32, 0xff, 0x0a, 0xc3,
+ 0xb5, 0x83, 0xf8, 0xc7, 0x09, 0x2f, 0x7e, 0x96, 0xd0, 0xf0, 0x6a, 0x22,
+ 0x7a, 0xef, 0x0c, 0xe8, 0xd1, 0x09, 0xe5, 0xf4, 0xed, 0x55, 0x68, 0x6c,
+ 0xaf, 0x52, 0xf4, 0xb6, 0x3d, 0xd0, 0x7d, 0x57, 0x2a, 0x5e, 0x9c, 0xcf,
+ 0x68, 0xf8, 0x49, 0xa6, 0x3e, 0xfc, 0xcf, 0xec, 0xf3, 0x37, 0xe6, 0x63,
+ 0x56, 0x6e, 0x96, 0xe8, 0x4d, 0x74, 0x44, 0x3d, 0xa7, 0xa8, 0xe7, 0x14,
+ 0xf5, 0x9c, 0xa2, 0x9e, 0x29, 0xc3, 0xa3, 0x29, 0xea, 0x99, 0xba, 0xfb,
+ 0x3a, 0x6d, 0xea, 0x6b, 0x9c, 0xc7, 0xe3, 0xf6, 0x3c, 0x86, 0x39, 0x5f,
+ 0x7f, 0x81, 0xbf, 0xb5, 0xb1, 0xf5, 0x59, 0xeb, 0xbf, 0x79, 0x65, 0x4c,
+ 0x0f, 0xcf, 0xcc, 0xe3, 0x97, 0x8c, 0xed, 0x3b, 0x56, 0x4c, 0x93, 0x71,
+ 0xc9, 0xf8, 0x6c, 0xfd, 0xf9, 0xb7, 0x29, 0x3b, 0x15, 0x94, 0x5b, 0xd6,
+ 0x5e, 0xb3, 0xf0, 0xbf, 0xb7, 0x38, 0xbe, 0x9b, 0x95, 0xbc, 0x5d, 0xfd,
+ 0x5d, 0x29, 0xf5, 0x1d, 0x8c, 0xaa, 0x2b, 0x79, 0xae, 0xc7, 0xa3, 0xf8,
+ 0xa8, 0xe3, 0xbd, 0xe7, 0xf7, 0x7a, 0x65, 0x3e, 0xfc, 0x97, 0xce, 0x69,
+ 0x8f, 0x76, 0x7f, 0x77, 0xf2, 0x5c, 0xc6, 0x22, 0xb6, 0x28, 0x36, 0xe0,
+ 0xa5, 0xbd, 0x5c, 0x53, 0xf8, 0x0f, 0x71, 0x35, 0xb2, 0x0d, 0xed, 0xcd,
+ 0x8f, 0xd8, 0x7d, 0x94, 0x24, 0xc5, 0x6f, 0x14, 0xbc, 0xf5, 0x61, 0x05,
+ 0xa7, 0x42, 0x06, 0x6d, 0xe6, 0x18, 0x71, 0x01, 0x28, 0x4d, 0xc2, 0xed,
+ 0x89, 0x44, 0x90, 0x18, 0x80, 0xbb, 0x2c, 0x12, 0xc6, 0xc2, 0x81, 0xfa,
+ 0xce, 0x73, 0xd0, 0x83, 0x03, 0x8a, 0xde, 0xce, 0x58, 0x62, 0x8e, 0x53,
+ 0x8f, 0x57, 0x2a, 0xba, 0xbf, 0x44, 0x81, 0x5b, 0x61, 0xb9, 0x40, 0xe6,
+ 0x18, 0x76, 0x66, 0xe5, 0x77, 0x18, 0x46, 0xe6, 0x37, 0xc5, 0xbe, 0x24,
+ 0xa6, 0xd0, 0xee, 0xcf, 0x71, 0xec, 0xba, 0x9f, 0xf8, 0xea, 0x76, 0x45,
+ 0x3a, 0x71, 0x38, 0x01, 0x77, 0x49, 0x64, 0x2b, 0x9e, 0x4c, 0x84, 0x67,
+ 0x16, 0xcb, 0x29, 0x2c, 0xe7, 0xcf, 0x4c, 0x97, 0xe5, 0xc7, 0x56, 0xd4,
+ 0x9b, 0x97, 0xa5, 0x3c, 0x79, 0x0c, 0x7b, 0x52, 0x52, 0x37, 0x62, 0xd7,
+ 0x75, 0xb2, 0x8f, 0xbe, 0x44, 0x7d, 0xdb, 0x0d, 0x8a, 0x1e, 0x7e, 0x98,
+ 0xf3, 0xd7, 0x83, 0xc6, 0xe8, 0x1b, 0xd0, 0xb5, 0x4e, 0xe4, 0x65, 0x59,
+ 0x90, 0xc9, 0xcb, 0x31, 0x3f, 0x03, 0xe5, 0xf6, 0x14, 0xac, 0x39, 0x06,
+ 0x3c, 0x3e, 0xc3, 0xf0, 0xbf, 0xe3, 0xa8, 0xc5, 0x01, 0xce, 0x4f, 0x1f,
+ 0x7d, 0x45, 0xf0, 0xec, 0xee, 0xbd, 0x7e, 0x78, 0x0c, 0x0b, 0x47, 0x42,
+ 0xb5, 0x78, 0x96, 0x58, 0x5b, 0x45, 0xdf, 0x7c, 0x5e, 0x43, 0x74, 0x4e,
+ 0x24, 0xac, 0xdc, 0x92, 0x1d, 0x2d, 0xcc, 0xc1, 0x8b, 0x35, 0x05, 0x19,
+ 0xdf, 0x77, 0xbd, 0x5a, 0xf9, 0xe0, 0xeb, 0x50, 0x3a, 0x52, 0x7a, 0x30,
+ 0x0e, 0x0b, 0xd5, 0x8b, 0x75, 0xff, 0x94, 0xf2, 0x96, 0x8a, 0x2a, 0x62,
+ 0x75, 0xf6, 0xfd, 0xe5, 0x1a, 0xb5, 0x31, 0xc6, 0x65, 0x07, 0x43, 0x5f,
+ 0x54, 0xd3, 0x4d, 0x36, 0x13, 0x74, 0xd9, 0xd7, 0x1c, 0x48, 0x3b, 0xa3,
+ 0x3e, 0x07, 0x7e, 0x6f, 0x45, 0xd7, 0xc9, 0xb5, 0x72, 0xc4, 0xda, 0x1b,
+ 0x7d, 0x4e, 0x34, 0x86, 0xb7, 0xd3, 0x07, 0xa7, 0xd6, 0xb5, 0xf0, 0xbf,
+ 0x80, 0x79, 0x1a, 0xf5, 0xfe, 0xed, 0x90, 0xdf, 0xef, 0xd0, 0x6e, 0x5a,
+ 0xa4, 0x2e, 0xcb, 0x88, 0x1d, 0xea, 0x9a, 0xf8, 0x78, 0x9f, 0x69, 0x59,
+ 0x87, 0xcd, 0x13, 0x4a, 0x4b, 0xea, 0x5d, 0x2b, 0xea, 0x8c, 0x47, 0x4b,
+ 0x23, 0x01, 0x73, 0x27, 0xc1, 0xd8, 0x11, 0x89, 0x2b, 0xd1, 0x6c, 0x9f,
+ 0x72, 0x7d, 0xb6, 0x5f, 0x59, 0x91, 0x95, 0xf2, 0x27, 0x94, 0xe5, 0x59,
+ 0x29, 0x5f, 0x2c, 0x1b, 0x66, 0x59, 0xe0, 0x48, 0x22, 0x10, 0x2c, 0x96,
+ 0x5f, 0xc1, 0xb2, 0xd7, 0x5f, 0x2a, 0x1b, 0xa6, 0xad, 0x9a, 0x9c, 0x97,
+ 0x0a, 0x6c, 0xd6, 0xf4, 0x68, 0x9c, 0x3a, 0x2f, 0x8d, 0xf8, 0x6e, 0x7d,
+ 0xdd, 0xc8, 0x05, 0x1d, 0x9c, 0x83, 0xa3, 0x1c, 0x59, 0x2b, 0x71, 0x6e,
+ 0x83, 0xe1, 0x42, 0xbf, 0x56, 0x8d, 0x0d, 0xe6, 0x6f, 0xad, 0xcd, 0xeb,
+ 0xe4, 0xbf, 0xbc, 0x6c, 0xb0, 0xcb, 0xd7, 0xb1, 0xbc, 0x6e, 0x1e, 0x2d,
+ 0x60, 0xeb, 0xa9, 0x04, 0x06, 0x1d, 0x11, 0x62, 0x7e, 0x73, 0xc0, 0xdf,
+ 0x03, 0x99, 0x1b, 0x3f, 0xae, 0xa7, 0x2c, 0x69, 0xe7, 0x74, 0xfc, 0x45,
+ 0xfc, 0x72, 0x19, 0xb9, 0x26, 0xe5, 0xa6, 0x68, 0xdf, 0x82, 0x75, 0x96,
+ 0x35, 0x64, 0x8a, 0x9d, 0xfb, 0x68, 0xe7, 0x33, 0xe1, 0xaf, 0xd5, 0xe3,
+ 0x69, 0x56, 0x38, 0x9c, 0x98, 0x81, 0xb4, 0xa6, 0x12, 0x73, 0xef, 0xf2,
+ 0xa0, 0x2a, 0xaa, 0x94, 0x90, 0xdb, 0x60, 0x42, 0xc6, 0x59, 0x89, 0xa8,
+ 0x53, 0x0f, 0xca, 0xdc, 0x95, 0x30, 0xe6, 0x35, 0xa8, 0xac, 0x77, 0xc9,
+ 0x97, 0x65, 0xcc, 0x7e, 0xfa, 0x72, 0xdc, 0xd6, 0x51, 0xeb, 0xa5, 0x71,
+ 0x4b, 0x7b, 0x45, 0x1d, 0xfd, 0x67, 0xea, 0x59, 0xd6, 0x8e, 0x4b, 0xba,
+ 0x2d, 0x89, 0x96, 0x51, 0xb7, 0xc7, 0x12, 0x81, 0xf0, 0xd3, 0x88, 0x2b,
+ 0x6d, 0x59, 0x27, 0xc6, 0x12, 0x52, 0xaf, 0x8f, 0xe5, 0xfb, 0x95, 0x95,
+ 0x97, 0xea, 0x4c, 0x15, 0xfc, 0x56, 0xc6, 0x23, 0xe3, 0xbb, 0x0e, 0x1b,
+ 0xf6, 0xea, 0xf1, 0x38, 0xc4, 0xae, 0xa2, 0x58, 0x6f, 0xea, 0x7e, 0xda,
+ 0x1f, 0xed, 0x06, 0xa8, 0x49, 0xc6, 0xdc, 0x79, 0x0c, 0x00, 0xee, 0xd8,
+ 0xdb, 0xce, 0xb1, 0x5a, 0x78, 0xcd, 0xac, 0xc5, 0x18, 0xbd, 0xb4, 0x3a,
+ 0x29, 0xd7, 0xa7, 0xcb, 0x18, 0x51, 0xd6, 0x1f, 0xf5, 0x97, 0xa1, 0x5c,
+ 0xe4, 0xfc, 0x1b, 0x35, 0x6f, 0xbf, 0x1f, 0x54, 0xff, 0x17, 0xd6, 0x98,
+ 0x37, 0x7f, 0xad, 0x3a, 0x29, 0x9c, 0xaf, 0x1d, 0x5a, 0xd2, 0xc3, 0x78,
+ 0x17, 0xb7, 0x2a, 0x0c, 0xbd, 0xfd, 0x82, 0xd2, 0x8d, 0x1b, 0x43, 0x7a,
+ 0xec, 0x87, 0x8a, 0x1e, 0x1d, 0x50, 0x0c, 0xfa, 0x61, 0x10, 0xab, 0xb2,
+ 0xef, 0xef, 0xeb, 0xfb, 0x50, 0x0f, 0x4b, 0x3f, 0xd2, 0xdf, 0x59, 0xf4,
+ 0xdb, 0x63, 0x2a, 0x8e, 0x47, 0xc6, 0xa6, 0x60, 0xb3, 0x3d, 0xa6, 0x15,
+ 0xb6, 0x7f, 0x7c, 0xd7, 0x74, 0x61, 0xe3, 0xde, 0x53, 0x0b, 0xc5, 0x40,
+ 0x36, 0x1d, 0x8d, 0xa2, 0xb7, 0xd9, 0x85, 0x0d, 0xa3, 0x37, 0xa9, 0x22,
+ 0x1b, 0xd4, 0xf9, 0x65, 0xf9, 0x6f, 0x85, 0xbc, 0xc5, 0x83, 0xf5, 0x59,
+ 0xce, 0x1d, 0x31, 0x74, 0xfd, 0x51, 0x99, 0xdb, 0x5a, 0x7e, 0xcb, 0xdc,
+ 0x7a, 0xf9, 0x2d, 0xf3, 0x3c, 0x8b, 0xdf, 0xd5, 0xf0, 0xcf, 0x12, 0x59,
+ 0x9a, 0x91, 0xd8, 0x0f, 0x77, 0x45, 0xa4, 0x0b, 0x77, 0x0d, 0x58, 0x56,
+ 0x7f, 0xc0, 0xb2, 0xca, 0x42, 0xe4, 0x59, 0x81, 0xc6, 0xf0, 0x95, 0x4a,
+ 0x09, 0xa6, 0xb4, 0x66, 0xf4, 0x1f, 0x2d, 0x89, 0x55, 0x47, 0x66, 0xd1,
+ 0xf7, 0x35, 0xfc, 0x6c, 0x49, 0x3b, 0x26, 0xc6, 0xa7, 0x8f, 0x21, 0x6f,
+ 0x67, 0xdf, 0x5e, 0x50, 0xb4, 0x33, 0x91, 0x5f, 0x64, 0xd7, 0xfb, 0xd3,
+ 0xf4, 0xcb, 0xb8, 0x86, 0x18, 0xfd, 0x83, 0x32, 0xd5, 0xa2, 0xe7, 0x12,
+ 0xa7, 0xfe, 0xa0, 0xfa, 0x17, 0x1b, 0x3b, 0x13, 0xef, 0x5a, 0x0c, 0xa7,
+ 0xfc, 0xe4, 0x1a, 0xef, 0xcd, 0xbc, 0xd7, 0x6e, 0xca, 0x6c, 0xbb, 0x91,
+ 0xb2, 0x17, 0x1b, 0xef, 0xcc, 0xac, 0xb0, 0xc7, 0x9c, 0x66, 0xe1, 0x4d,
+ 0x7b, 0x45, 0xa7, 0xa2, 0x03, 0x0b, 0xc7, 0xcd, 0xeb, 0x88, 0x15, 0xaf,
+ 0x5b, 0x8e, 0x59, 0xd2, 0x46, 0x97, 0xd2, 0x4a, 0x7b, 0x8a, 0x3b, 0x4b,
+ 0x41, 0x4e, 0xad, 0x95, 0x44, 0xa2, 0xca, 0x5a, 0x5b, 0xff, 0xad, 0xca,
+ 0xca, 0xd1, 0xe9, 0x6d, 0x77, 0xd1, 0x77, 0x1f, 0x57, 0xf3, 0xf3, 0x7d,
+ 0xde, 0x1e, 0x43, 0x5e, 0x7e, 0x3f, 0xda, 0x53, 0xd2, 0x8e, 0xe8, 0x35,
+ 0xef, 0x6f, 0xed, 0x12, 0x23, 0x2e, 0xc9, 0x9c, 0xe7, 0x1e, 0x97, 0x31,
+ 0x61, 0xc9, 0x7b, 0xf0, 0xe3, 0x7a, 0xe2, 0x47, 0xf4, 0x3f, 0xc4, 0x8f,
+ 0xa5, 0x7f, 0xa2, 0xec, 0x59, 0xca, 0x21, 0x3c, 0x45, 0xe2, 0x9e, 0xf0,
+ 0x16, 0xe1, 0x2b, 0x41, 0xca, 0x25, 0xfc, 0xa5, 0x68, 0x1b, 0x96, 0xf5,
+ 0x4d, 0x73, 0x01, 0x62, 0xb5, 0xfa, 0x20, 0x50, 0x87, 0x41, 0xca, 0xea,
+ 0x48, 0x22, 0xce, 0x71, 0x52, 0xd7, 0xea, 0x75, 0x0e, 0xa8, 0x4d, 0x0e,
+ 0x74, 0xe3, 0x55, 0xd3, 0xe8, 0xdf, 0x8c, 0xbf, 0x44, 0x8f, 0xd7, 0xc2,
+ 0x61, 0x33, 0x48, 0x5c, 0x2a, 0x47, 0x67, 0x13, 0x27, 0x62, 0xad, 0x17,
+ 0x43, 0xa9, 0x78, 0x07, 0x61, 0x83, 0x31, 0xec, 0xd9, 0x4f, 0x26, 0x02,
+ 0x7a, 0xfb, 0x56, 0xa6, 0x40, 0xab, 0x06, 0xdc, 0xf0, 0x4b, 0x2a, 0xc4,
+ 0x98, 0xf1, 0x75, 0xc6, 0xf9, 0x4d, 0xe6, 0x15, 0xd4, 0x6d, 0x1f, 0x6d,
+ 0x48, 0xa5, 0xbd, 0x48, 0x3f, 0x41, 0xf2, 0x19, 0xa9, 0xcb, 0xb8, 0xd0,
+ 0xa0, 0xe0, 0x86, 0x06, 0xda, 0x27, 0x79, 0xd1, 0xe7, 0x43, 0x4e, 0xfb,
+ 0xff, 0x44, 0xb6, 0x31, 0x7a, 0xb3, 0xfa, 0x23, 0x0b, 0x33, 0xed, 0x36,
+ 0xb4, 0xa8, 0x4a, 0xb9, 0xff, 0x28, 0x27, 0x30, 0x21, 0x5c, 0xad, 0xd2,
+ 0xf8, 0x0d, 0xc6, 0xbd, 0x52, 0xa7, 0x0a, 0x15, 0xc3, 0xf1, 0x59, 0xe5,
+ 0xb4, 0xe1, 0xd2, 0x88, 0x8e, 0xbb, 0x46, 0x2b, 0xe1, 0x18, 0xd6, 0x2f,
+ 0xae, 0x74, 0x20, 0x56, 0x22, 0xfc, 0x70, 0xb4, 0x16, 0x35, 0xfb, 0xac,
+ 0x6e, 0x77, 0xc4, 0xb2, 0x3c, 0x4b, 0x22, 0xb8, 0xf7, 0xa8, 0x06, 0x75,
+ 0x9f, 0x0b, 0x15, 0xcc, 0x43, 0xd6, 0x99, 0x7d, 0xb8, 0x8f, 0xfc, 0x6e,
+ 0x4e, 0x32, 0x88, 0xd5, 0xc4, 0xa2, 0x8b, 0xa9, 0xb6, 0xd6, 0x17, 0x12,
+ 0x0d, 0xdb, 0xe6, 0x38, 0x84, 0xfb, 0xaf, 0xc1, 0xe6, 0xec, 0x1a, 0xdc,
+ 0xc9, 0xd8, 0xf9, 0x9c, 0x81, 0xee, 0x39, 0xf4, 0xd7, 0x3b, 0xc9, 0xff,
+ 0x36, 0xa6, 0xd6, 0x61, 0x63, 0x76, 0x1b, 0xff, 0xeb, 0xc0, 0xdd, 0x3c,
+ 0x36, 0xa5, 0xc4, 0xbf, 0x3f, 0x8d, 0x4d, 0xd9, 0x7a, 0xc4, 0x46, 0x37,
+ 0x62, 0x2b, 0x39, 0xc1, 0x5d, 0xa3, 0x5e, 0xea, 0xb6, 0x0d, 0x1b, 0xb2,
+ 0x6d, 0xb8, 0x97, 0x63, 0xb9, 0x97, 0xf3, 0xa1, 0x26, 0xb7, 0xd2, 0xc7,
+ 0x3c, 0xf0, 0x0e, 0x2f, 0xc5, 0x7d, 0xa3, 0xd7, 0x61, 0x0b, 0xe3, 0xe4,
+ 0xed, 0x4b, 0xae, 0x43, 0xf7, 0xe8, 0x7d, 0xe8, 0x4a, 0x19, 0x5d, 0x73,
+ 0x98, 0x6a, 0xbd, 0xb5, 0xe4, 0x3e, 0xdc, 0x43, 0x39, 0xb6, 0xed, 0xb5,
+ 0x50, 0xb6, 0x68, 0xb1, 0x6a, 0xd4, 0xc4, 0x2d, 0x9f, 0x21, 0xb1, 0xf9,
+ 0xc0, 0xad, 0x7d, 0xc6, 0xee, 0x02, 0xb6, 0x38, 0x51, 0x62, 0x28, 0x62,
+ 0xa3, 0xf9, 0xeb, 0x89, 0xbf, 0xc1, 0xe6, 0x51, 0x17, 0xee, 0x18, 0xed,
+ 0x52, 0x56, 0x8b, 0xad, 0xb8, 0x54, 0xce, 0x67, 0x94, 0xd8, 0xd7, 0xaa,
+ 0xb4, 0x8c, 0xda, 0xf3, 0xac, 0x79, 0x23, 0x5d, 0xca, 0xba, 0xec, 0x9d,
+ 0x0e, 0x94, 0xcb, 0x5c, 0x5c, 0x83, 0xf1, 0xa6, 0xaf, 0x58, 0xe9, 0xfc,
+ 0x7c, 0xa6, 0xe9, 0x3e, 0x6e, 0x5f, 0xe4, 0x57, 0x9f, 0xf4, 0x2d, 0xd0,
+ 0xbb, 0x0e, 0xa8, 0xc2, 0x2b, 0xdd, 0xc8, 0xd9, 0xf3, 0x59, 0xc2, 0x7e,
+ 0x6a, 0x70, 0xc4, 0x9b, 0xe7, 0x12, 0xf3, 0xd8, 0x97, 0x95, 0x72, 0x71,
+ 0xac, 0x94, 0x9b, 0xe3, 0x99, 0x93, 0xf4, 0xe1, 0x7e, 0xea, 0xa7, 0x8b,
+ 0x73, 0xd4, 0x45, 0xbd, 0x7c, 0x2e, 0x75, 0x8a, 0x31, 0x62, 0x1b, 0x3e,
+ 0x57, 0xe8, 0xa7, 0x2f, 0x5b, 0x8a, 0x72, 0xa3, 0x0f, 0x8f, 0x68, 0x25,
+ 0xf4, 0x31, 0xe1, 0x19, 0x07, 0x6e, 0x3d, 0x6c, 0xac, 0xe3, 0x18, 0xbe,
+ 0xc4, 0x36, 0x44, 0xae, 0x46, 0xad, 0x06, 0xf9, 0xb2, 0x3d, 0xc4, 0xec,
+ 0x72, 0xe3, 0x37, 0xd6, 0x23, 0xde, 0x76, 0xbb, 0x6c, 0x15, 0xcb, 0x3e,
+ 0x3f, 0xe0, 0xc7, 0x8d, 0xb4, 0xef, 0xb2, 0x64, 0x94, 0x7a, 0x77, 0x93,
+ 0x53, 0xb5, 0x52, 0xe7, 0x9c, 0x63, 0xea, 0xf5, 0x0e, 0xda, 0xb3, 0x33,
+ 0xb9, 0x86, 0xf3, 0xa0, 0xa1, 0x32, 0xd9, 0xc7, 0x79, 0xf0, 0xc2, 0x9d,
+ 0x6c, 0x47, 0x27, 0xe5, 0x72, 0x25, 0xd7, 0x71, 0x2e, 0xea, 0xe0, 0x49,
+ 0x76, 0x70, 0x2e, 0x80, 0xbb, 0xa8, 0xcb, 0xfb, 0x42, 0xbf, 0x56, 0x7a,
+ 0x6b, 0x65, 0x18, 0x6d, 0x9c, 0xbf, 0x28, 0x36, 0xa7, 0xea, 0xc3, 0x3b,
+ 0x24, 0xee, 0x3b, 0x99, 0x90, 0x19, 0x3f, 0x26, 0x17, 0xa6, 0xf5, 0x1b,
+ 0x3d, 0xfc, 0x5d, 0x94, 0xb3, 0x88, 0xe3, 0x22, 0xa7, 0xc4, 0xd7, 0xa2,
+ 0x9c, 0x2e, 0x94, 0x19, 0xcf, 0x5a, 0x0f, 0x7b, 0xe1, 0x77, 0xb1, 0x6c,
+ 0x39, 0xcb, 0xae, 0xa6, 0x9c, 0xab, 0x29, 0xff, 0xbc, 0xe4, 0xa7, 0xd1,
+ 0x4d, 0x39, 0xe7, 0x0c, 0xbb, 0xc9, 0x51, 0x75, 0xdc, 0x4f, 0xdd, 0x1f,
+ 0x48, 0x95, 0xa1, 0x9a, 0xf3, 0xfc, 0x39, 0xfe, 0xde, 0x41, 0x3f, 0x7a,
+ 0x7e, 0xd0, 0xc2, 0x99, 0x90, 0x86, 0x41, 0xad, 0x0c, 0xbd, 0xc1, 0xad,
+ 0xe4, 0xe5, 0x32, 0x57, 0xcc, 0xa7, 0x8c, 0x0a, 0xc6, 0x75, 0xc4, 0x5d,
+ 0xcd, 0x3a, 0xb6, 0x07, 0xdd, 0x48, 0x7b, 0x11, 0x75, 0x19, 0x51, 0xda,
+ 0xb8, 0x0b, 0x03, 0x9a, 0x02, 0x17, 0xf1, 0xb0, 0x94, 0xfe, 0xb4, 0x93,
+ 0x71, 0xd7, 0x15, 0x91, 0xff, 0x68, 0x27, 0xe4, 0x60, 0xd5, 0x11, 0x23,
+ 0xfe, 0x82, 0x12, 0x68, 0x73, 0xa9, 0xf7, 0x51, 0x47, 0x15, 0x38, 0x33,
+ 0xf8, 0x25, 0x6c, 0x64, 0x5f, 0x7d, 0x29, 0x0f, 0x73, 0x93, 0xbf, 0x53,
+ 0x72, 0x36, 0x7e, 0x7a, 0x90, 0x1c, 0x79, 0xdc, 0x9a, 0x67, 0x88, 0xdd,
+ 0x44, 0x70, 0xcf, 0xd1, 0x2a, 0x0c, 0x0e, 0x5e, 0x87, 0x6d, 0x2c, 0xb7,
+ 0x2b, 0x55, 0x0d, 0x63, 0x68, 0x99, 0x5d, 0x67, 0x84, 0xfe, 0x35, 0x90,
+ 0xbc, 0x0f, 0x2b, 0x53, 0xf5, 0xc1, 0xa3, 0x4a, 0x8c, 0x3a, 0xf4, 0xa2,
+ 0x3f, 0xb9, 0xd1, 0xd6, 0x69, 0x62, 0x5f, 0x27, 0xb6, 0x1e, 0xbd, 0x02,
+ 0x7b, 0xf6, 0x6d, 0xc1, 0x5d, 0x47, 0x99, 0xbf, 0xda, 0xb6, 0xac, 0xa2,
+ 0x77, 0xdf, 0x75, 0xca, 0x06, 0xb6, 0xb7, 0x7b, 0x98, 0xf6, 0x4c, 0x9b,
+ 0xbe, 0x7f, 0xaf, 0x91, 0x5b, 0xe6, 0xd8, 0xa2, 0xf8, 0x6b, 0xaf, 0x43,
+ 0x97, 0x6d, 0x7b, 0x79, 0xbd, 0xed, 0xc8, 0xce, 0x67, 0x9e, 0xf3, 0xb7,
+ 0xd6, 0xa3, 0xde, 0x52, 0x7b, 0x7e, 0x55, 0xea, 0xad, 0x25, 0xc1, 0xdc,
+ 0xbf, 0x96, 0xb9, 0x57, 0xc1, 0x5e, 0x7a, 0xb3, 0x8b, 0xc9, 0x1b, 0xbd,
+ 0xc8, 0x68, 0x41, 0xea, 0xa3, 0x38, 0x0f, 0x0d, 0x05, 0x7b, 0x79, 0x8b,
+ 0x65, 0x6c, 0x5b, 0x7e, 0x9f, 0x2f, 0xc8, 0xfc, 0xb6, 0xa3, 0x86, 0xf1,
+ 0x75, 0x43, 0x68, 0x9d, 0x72, 0xaf, 0x76, 0x69, 0xce, 0x7c, 0xc5, 0x39,
+ 0x93, 0x3c, 0xd1, 0x6e, 0x2b, 0xf1, 0x25, 0xdb, 0x76, 0xaf, 0xcf, 0x36,
+ 0xa3, 0x73, 0x74, 0x7a, 0xfb, 0xc5, 0x3a, 0x65, 0x9c, 0x8b, 0xe2, 0x3c,
+ 0xeb, 0xfd, 0x82, 0x65, 0x81, 0x45, 0x45, 0x2c, 0xbb, 0xb3, 0xd0, 0xff,
+ 0x41, 0x8b, 0x31, 0xc9, 0xe9, 0x32, 0x1c, 0x18, 0x09, 0xfe, 0x57, 0x25,
+ 0x5e, 0xeb, 0xa4, 0xcc, 0x0a, 0xb1, 0xe4, 0xef, 0xac, 0x3d, 0xeb, 0x64,
+ 0x5e, 0x3e, 0x42, 0x43, 0x86, 0xe2, 0xba, 0xe4, 0xb3, 0x6b, 0xb0, 0x3e,
+ 0x25, 0xb2, 0xb6, 0x63, 0x43, 0xca, 0x96, 0xcb, 0x5f, 0x94, 0xab, 0x8f,
+ 0x36, 0xa3, 0x25, 0x77, 0xdb, 0x32, 0xb5, 0xd3, 0xae, 0xee, 0xd9, 0xab,
+ 0xe2, 0xe9, 0xd0, 0x26, 0xc5, 0x3f, 0x53, 0xe2, 0x70, 0x3d, 0xba, 0xf6,
+ 0xca, 0xb7, 0x9f, 0x7c, 0x37, 0xa6, 0x4c, 0xcd, 0x1c, 0x60, 0xb9, 0x65,
+ 0x58, 0xbf, 0xb7, 0x16, 0x73, 0x38, 0xd6, 0xdb, 0xcd, 0xff, 0xa2, 0xbc,
+ 0x33, 0x43, 0xc6, 0xb3, 0xa2, 0x10, 0xcb, 0xeb, 0x71, 0xdf, 0x5e, 0xf1,
+ 0x21, 0xf9, 0xdd, 0x82, 0xde, 0xa5, 0xf5, 0x85, 0x38, 0xff, 0x37, 0x9c,
+ 0x97, 0x2e, 0xe5, 0x06, 0xe2, 0x42, 0x8c, 0xb8, 0x40, 0x9b, 0x52, 0xda,
+ 0x89, 0x0b, 0xd7, 0x17, 0x70, 0xc1, 0x43, 0x5c, 0x58, 0x93, 0x7d, 0x9b,
+ 0xf2, 0x88, 0x2f, 0xbe, 0x57, 0x9e, 0xbb, 0x29, 0xcf, 0xb1, 0xd0, 0x1c,
+ 0xc0, 0x96, 0x67, 0x19, 0x79, 0x4c, 0x2d, 0xe7, 0xd0, 0x62, 0x7c, 0x50,
+ 0x94, 0x11, 0x5b, 0xcf, 0xcb, 0x28, 0xb3, 0xd8, 0x94, 0x45, 0xb9, 0x7f,
+ 0x8f, 0x06, 0x7b, 0x7d, 0xe0, 0xb2, 0x3c, 0xeb, 0xf7, 0xbe, 0xcb, 0x1c,
+ 0x41, 0x7e, 0x13, 0x2f, 0x9a, 0xeb, 0x89, 0x73, 0xcb, 0x88, 0x7b, 0x2e,
+ 0x8e, 0x4b, 0xb0, 0x4e, 0x64, 0x73, 0xd1, 0x2f, 0xa4, 0x6d, 0xd1, 0xc9,
+ 0x52, 0x47, 0x7e, 0x1e, 0x8a, 0xf3, 0xec, 0xa4, 0x1f, 0xbb, 0x51, 0x1d,
+ 0xd1, 0xa3, 0x37, 0x39, 0x64, 0xce, 0x88, 0xf2, 0x43, 0xed, 0x85, 0xbe,
+ 0xfe, 0xbb, 0xd2, 0x50, 0xd3, 0x4f, 0x39, 0x4f, 0x28, 0xb7, 0x70, 0x5c,
+ 0xfe, 0xd2, 0xaa, 0xa8, 0x27, 0x12, 0xe8, 0x48, 0xbc, 0x2f, 0x36, 0xde,
+ 0x90, 0xcd, 0xf3, 0x4b, 0x75, 0x28, 0x6e, 0x95, 0xd3, 0xf6, 0x9d, 0x46,
+ 0xe0, 0xe2, 0x6a, 0xf6, 0x30, 0xef, 0xa0, 0xf0, 0x19, 0x93, 0x6d, 0x15,
+ 0xfb, 0xaa, 0x23, 0x96, 0x84, 0x0a, 0x76, 0xb0, 0x46, 0x61, 0xde, 0xd0,
+ 0x16, 0xb5, 0xed, 0x61, 0x17, 0xf5, 0x75, 0x42, 0xf9, 0x98, 0x70, 0x66,
+ 0x9b, 0x63, 0xc4, 0x95, 0x55, 0xc4, 0x95, 0xea, 0xa4, 0x12, 0xf5, 0x46,
+ 0x1a, 0xb7, 0xd5, 0x20, 0xd0, 0xf6, 0x28, 0xfb, 0xac, 0x21, 0xcf, 0xbc,
+ 0x89, 0xb1, 0x36, 0xc9, 0x3e, 0x57, 0xb1, 0xcf, 0xb5, 0xd9, 0x2d, 0x6c,
+ 0x57, 0xb0, 0x55, 0xc5, 0x9c, 0x7d, 0x70, 0x7b, 0x69, 0x07, 0x23, 0x0d,
+ 0x4e, 0x84, 0x17, 0xff, 0x02, 0x98, 0x81, 0x98, 0xca, 0xfc, 0x7d, 0x5e,
+ 0x52, 0x72, 0xa9, 0x03, 0xb7, 0x2e, 0xcb, 0x08, 0x96, 0x6a, 0xf0, 0x0c,
+ 0x7b, 0x25, 0x1e, 0xa1, 0x2f, 0x54, 0xa7, 0xec, 0xb1, 0xf1, 0x56, 0x45,
+ 0xd9, 0x3e, 0x05, 0x57, 0x85, 0xbe, 0xae, 0xa4, 0x67, 0xe6, 0x31, 0x5f,
+ 0xa5, 0x3e, 0x7a, 0x26, 0x04, 0x1b, 0xd3, 0xc4, 0xc6, 0x63, 0x4a, 0x7e,
+ 0x3d, 0x86, 0x7e, 0x9f, 0x42, 0xbc, 0x2a, 0x22, 0x6b, 0x20, 0x81, 0xce,
+ 0x0f, 0x29, 0xf7, 0x11, 0x0b, 0x5d, 0x8c, 0x43, 0x1e, 0x62, 0xa3, 0xc4,
+ 0xe9, 0xf4, 0xad, 0x89, 0x81, 0x3a, 0xf4, 0xd3, 0xb7, 0x37, 0x1e, 0x3d,
+ 0x75, 0x8b, 0x07, 0xb5, 0xfc, 0xf6, 0xf2, 0x98, 0xc5, 0xc3, 0x4d, 0x5f,
+ 0x76, 0xc3, 0x31, 0x20, 0x7c, 0xaf, 0x89, 0xb1, 0xca, 0x83, 0xf2, 0x01,
+ 0x13, 0x5b, 0x28, 0x4f, 0xe9, 0x50, 0x33, 0xe3, 0x09, 0xfd, 0x3c, 0x55,
+ 0x83, 0xeb, 0x07, 0x97, 0x60, 0x93, 0x8d, 0x5f, 0xb5, 0x38, 0x3b, 0xb8,
+ 0xd4, 0xc6, 0x8d, 0x87, 0x52, 0x33, 0xf0, 0xce, 0xde, 0x6b, 0x6c, 0x8c,
+ 0x1b, 0x64, 0x6c, 0xf6, 0xed, 0x0b, 0xa3, 0x8b, 0x6d, 0x7a, 0xf7, 0x5d,
+ 0x8b, 0xfb, 0x8e, 0xfa, 0xa8, 0x23, 0x83, 0x71, 0x40, 0x7d, 0xd7, 0xff,
+ 0x49, 0xb1, 0xf3, 0xe9, 0xd8, 0x2f, 0x73, 0x2d, 0x75, 0x32, 0x34, 0x56,
+ 0xf9, 0xed, 0xb4, 0xb9, 0x70, 0x5e, 0x47, 0x79, 0x9d, 0x5c, 0x4d, 0x9d,
+ 0xdc, 0x94, 0xa5, 0x39, 0x0c, 0x3b, 0x39, 0xd7, 0xe4, 0x10, 0x35, 0xb5,
+ 0xf4, 0xcb, 0x12, 0x1e, 0xb4, 0xff, 0xd1, 0xbf, 0x60, 0x6c, 0xcf, 0x71,
+ 0x3e, 0xf9, 0xdb, 0x94, 0xf9, 0x94, 0xf8, 0xe9, 0x20, 0xe6, 0x2a, 0xd4,
+ 0xef, 0xff, 0x02, 0x66, 0xe7, 0x73, 0x9b, 0xa2, 0xae, 0x54, 0x8e, 0xbf,
+ 0x25, 0x91, 0xb3, 0x39, 0x3d, 0x33, 0x22, 0x5d, 0xe5, 0x7f, 0x1b, 0x8f,
+ 0x92, 0x73, 0x27, 0xc5, 0x67, 0xbd, 0xb4, 0xe7, 0x26, 0xea, 0x4b, 0x63,
+ 0xec, 0x30, 0x89, 0x73, 0xb3, 0xe0, 0xe2, 0x38, 0x36, 0x51, 0x3f, 0x1e,
+ 0x8e, 0x63, 0x2b, 0xcb, 0xdd, 0xc5, 0xff, 0xee, 0x3a, 0x5a, 0xcb, 0xc3,
+ 0xcb, 0x63, 0x16, 0x8f, 0x9f, 0x12, 0xb3, 0x9a, 0x69, 0xc7, 0x0e, 0x94,
+ 0x0c, 0xab, 0x78, 0xca, 0x54, 0x70, 0xa1, 0x89, 0xfd, 0x35, 0x5c, 0xc6,
+ 0x3a, 0x89, 0x65, 0xde, 0xe4, 0x97, 0x88, 0x73, 0x7e, 0xac, 0x23, 0x27,
+ 0xe8, 0xdc, 0xab, 0xc1, 0x15, 0xca, 0x30, 0x67, 0x12, 0x19, 0x4e, 0x14,
+ 0x38, 0xe6, 0x3c, 0xe6, 0x3a, 0x8d, 0x61, 0xda, 0x90, 0xb6, 0xd9, 0xb6,
+ 0xa1, 0x38, 0xe3, 0x73, 0x90, 0xb9, 0x7e, 0xde, 0x76, 0x5b, 0xde, 0x63,
+ 0x47, 0xf4, 0x31, 0x8e, 0x67, 0x4e, 0x44, 0xf7, 0xdf, 0x42, 0x5f, 0x10,
+ 0xce, 0x57, 0x9a, 0x04, 0x0e, 0x0c, 0xb6, 0xa3, 0x9a, 0x36, 0xe3, 0x5d,
+ 0x7c, 0x14, 0xa9, 0xda, 0x7e, 0xdb, 0x56, 0xf3, 0x6d, 0x97, 0x45, 0x2b,
+ 0x23, 0x8d, 0x31, 0x69, 0x7b, 0xbc, 0xd0, 0xf6, 0x0a, 0xb6, 0x9d, 0x60,
+ 0xdb, 0x2b, 0xff, 0x5d, 0xdb, 0xd3, 0xe3, 0x5d, 0x4f, 0x21, 0x2e, 0x4b,
+ 0xde, 0x5c, 0xc4, 0xed, 0x22, 0xc7, 0xf8, 0x8d, 0xf7, 0x32, 0x4e, 0xee,
+ 0x90, 0xb9, 0xf3, 0xe5, 0x7d, 0xf6, 0xbd, 0xd8, 0x7c, 0xb9, 0xad, 0x3d,
+ 0xc5, 0x18, 0x6f, 0xd6, 0x4c, 0x6b, 0x6b, 0x0e, 0xff, 0xff, 0x70, 0x4a,
+ 0xb8, 0x44, 0x3b, 0x2c, 0xca, 0xfa, 0xac, 0xa1, 0x77, 0x2d, 0x73, 0x18,
+ 0xdb, 0x2e, 0x32, 0xd7, 0xb9, 0xf1, 0x52, 0x5f, 0xb2, 0x36, 0xd2, 0x8e,
+ 0x85, 0x03, 0x7a, 0xe7, 0x2e, 0xf2, 0xd1, 0xc3, 0x21, 0x3d, 0xfa, 0x2d,
+ 0xe8, 0xf1, 0x52, 0xe5, 0x25, 0x94, 0x4c, 0x9c, 0xc5, 0x60, 0xf6, 0x47,
+ 0x92, 0x6f, 0xb2, 0x4d, 0xb7, 0xe2, 0x99, 0xe8, 0x43, 0x8c, 0xf5, 0xdc,
+ 0xac, 0xe7, 0x1e, 0x80, 0xbb, 0x92, 0xf5, 0xc6, 0x07, 0xe2, 0x96, 0x8b,
+ 0x5c, 0x50, 0x8d, 0xe8, 0x1d, 0x95, 0x8a, 0x11, 0xdb, 0xc4, 0xb6, 0xd7,
+ 0x30, 0x96, 0x95, 0x27, 0xbb, 0xc9, 0x03, 0x74, 0xdf, 0x97, 0x55, 0xbd,
+ 0x6b, 0x3d, 0x5e, 0xc2, 0xbf, 0x92, 0x3c, 0xce, 0x4b, 0x9e, 0x45, 0x8a,
+ 0xed, 0x59, 0xe3, 0x1a, 0xf9, 0xcc, 0xbb, 0x56, 0x78, 0x41, 0x85, 0x53,
+ 0xda, 0xbd, 0x38, 0xbe, 0xe0, 0xdd, 0xc4, 0x65, 0x3c, 0xd7, 0x5c, 0x46,
+ 0xe3, 0xfb, 0xf0, 0xa9, 0xa9, 0x75, 0x45, 0x62, 0xfd, 0x56, 0x57, 0x64,
+ 0xdb, 0xfd, 0xc7, 0x9b, 0xf3, 0x76, 0xeb, 0xcf, 0xb8, 0x71, 0xd6, 0x2b,
+ 0xbe, 0xc4, 0xfc, 0x67, 0x7f, 0x13, 0x76, 0xef, 0x67, 0x5e, 0xa9, 0x36,
+ 0x86, 0xcb, 0x95, 0x1a, 0xe6, 0x44, 0xc3, 0x36, 0x1f, 0x76, 0x1a, 0xbb,
+ 0xec, 0x9c, 0x59, 0xe2, 0x83, 0xd4, 0x99, 0x9f, 0x91, 0xf8, 0x27, 0xeb,
+ 0x39, 0x07, 0x6e, 0xdd, 0x90, 0xa0, 0xdf, 0x6a, 0xbd, 0x2c, 0xb3, 0xae,
+ 0xb0, 0x4e, 0x2f, 0x6b, 0x18, 0xbd, 0xd3, 0x38, 0xc9, 0xba, 0x69, 0xb1,
+ 0xaa, 0xd1, 0x5f, 0x73, 0x29, 0x8e, 0x74, 0x14, 0xca, 0x33, 0xd9, 0xb3,
+ 0x65, 0x73, 0x4f, 0xc3, 0xb3, 0x1d, 0xbc, 0x96, 0xf7, 0x85, 0xcb, 0xf1,
+ 0x6e, 0x67, 0x61, 0x6e, 0x0e, 0xb9, 0xf2, 0xb8, 0xff, 0x69, 0x77, 0x71,
+ 0xbd, 0x28, 0x5f, 0xe6, 0xda, 0x12, 0x94, 0xef, 0xb9, 0x14, 0x5b, 0xe2,
+ 0xc4, 0xf2, 0x6d, 0x7b, 0xf3, 0xeb, 0x93, 0x95, 0x4b, 0x05, 0xb7, 0xeb,
+ 0x71, 0xb7, 0xed, 0xf7, 0x5f, 0x75, 0xe5, 0xed, 0xc0, 0x59, 0x18, 0x97,
+ 0x49, 0x1b, 0xbc, 0x52, 0xd6, 0xfc, 0x0b, 0xf8, 0x39, 0x9b, 0xff, 0xf7,
+ 0x42, 0xe6, 0xc2, 0x45, 0xff, 0x7c, 0xdc, 0x74, 0x60, 0x6a, 0x46, 0x9e,
+ 0xaf, 0xab, 0xfb, 0x9a, 0xd0, 0x33, 0x46, 0xbc, 0xa1, 0x0f, 0xb5, 0x85,
+ 0xd6, 0x5a, 0xa8, 0x91, 0x75, 0x83, 0x5a, 0x54, 0xec, 0x13, 0xde, 0x4c,
+ 0x9e, 0x31, 0x76, 0xca, 0x1e, 0x4b, 0x6f, 0x26, 0xbf, 0x2e, 0xb2, 0x33,
+ 0xd5, 0xf7, 0xee, 0x1d, 0x9a, 0xe0, 0x85, 0xd8, 0x46, 0xdd, 0xad, 0x0b,
+ 0x03, 0x39, 0xbf, 0x03, 0xba, 0xb9, 0x4b, 0x56, 0x92, 0x12, 0xb7, 0x61,
+ 0x7b, 0xad, 0x82, 0x2e, 0xa3, 0x1a, 0x8e, 0xc5, 0xbf, 0xb5, 0xee, 0x58,
+ 0x27, 0xff, 0xbd, 0x5b, 0xc0, 0x97, 0x0f, 0xb2, 0x6f, 0x19, 0xb7, 0x70,
+ 0x3a, 0x37, 0x2a, 0xe8, 0x53, 0x37, 0x38, 0x84, 0x73, 0x2a, 0x8c, 0x9d,
+ 0xf6, 0x5c, 0xa0, 0x37, 0xad, 0x60, 0x77, 0x5a, 0x30, 0xd3, 0x49, 0x1c,
+ 0xf4, 0x61, 0x67, 0x5a, 0x70, 0xd0, 0x45, 0x1c, 0x9c, 0x83, 0xed, 0x69,
+ 0xc1, 0xc1, 0x12, 0xbc, 0x3c, 0x78, 0x05, 0x1e, 0xe2, 0xef, 0x07, 0x53,
+ 0xa5, 0x08, 0xef, 0xfd, 0x0b, 0x1c, 0x48, 0x0b, 0x7f, 0x72, 0x23, 0x35,
+ 0x5c, 0x87, 0x54, 0x3a, 0xcf, 0x25, 0xaa, 0x86, 0xff, 0x12, 0x49, 0xfe,
+ 0x1e, 0x20, 0xef, 0xcb, 0x0c, 0xcd, 0x45, 0x82, 0xbf, 0x65, 0xbd, 0xcd,
+ 0x43, 0xf9, 0x13, 0x81, 0x0a, 0x6c, 0x18, 0x92, 0x1c, 0xda, 0x77, 0xeb,
+ 0x5d, 0x81, 0x79, 0xec, 0xb3, 0x0e, 0xbb, 0xc9, 0xd9, 0xda, 0x86, 0xfc,
+ 0xe8, 0xe7, 0xef, 0x9d, 0xa9, 0x4a, 0xbc, 0x36, 0xa8, 0xdb, 0xfd, 0xf5,
+ 0xa4, 0x56, 0xac, 0x70, 0x19, 0x55, 0x58, 0x31, 0x38, 0x1f, 0x3b, 0xd2,
+ 0x82, 0xbd, 0xd5, 0xc4, 0xde, 0x7a, 0x3c, 0x98, 0x16, 0x7e, 0xa9, 0xc1,
+ 0xbb, 0xd7, 0xc0, 0x48, 0x5a, 0xd6, 0x84, 0x6b, 0x70, 0x61, 0x28, 0x80,
+ 0x41, 0xbb, 0x7f, 0x13, 0xc9, 0x54, 0x98, 0xf2, 0x79, 0x51, 0xb9, 0x2f,
+ 0xe7, 0xab, 0x82, 0x82, 0xc9, 0x40, 0x10, 0x03, 0x63, 0xb3, 0x50, 0xbe,
+ 0x4f, 0x37, 0xb7, 0x42, 0xbf, 0x78, 0x17, 0xae, 0xc4, 0xee, 0x31, 0x1f,
+ 0x4a, 0xf7, 0x55, 0xc3, 0x1d, 0x6a, 0xc2, 0xce, 0xb1, 0x0f, 0x61, 0xfb,
+ 0x58, 0x1d, 0xb1, 0x13, 0x78, 0x3a, 0x63, 0xa2, 0x9f, 0x18, 0x3c, 0x87,
+ 0x31, 0xe6, 0x95, 0xac, 0xcc, 0xa3, 0xcc, 0x8f, 0x02, 0x4f, 0xa0, 0x9a,
+ 0x31, 0x4a, 0x7e, 0xcb, 0xb5, 0xb0, 0x8d, 0xed, 0xf9, 0x75, 0x2a, 0x3d,
+ 0xbe, 0x13, 0xb6, 0xbe, 0x91, 0xcb, 0x88, 0xee, 0x65, 0x4d, 0x68, 0xba,
+ 0x3d, 0xed, 0xb4, 0xd7, 0xe8, 0x2f, 0xdb, 0xe5, 0x5f, 0x15, 0xec, 0xd2,
+ 0x5e, 0x53, 0xc3, 0x93, 0x97, 0xf2, 0x5c, 0xb4, 0x96, 0x20, 0x60, 0x3a,
+ 0x15, 0xf8, 0x99, 0xef, 0xfa, 0x9f, 0x7a, 0xdf, 0xda, 0xda, 0xe5, 0xf5,
+ 0x9f, 0xe9, 0x6b, 0xb0, 0x72, 0x6f, 0x49, 0x65, 0x3c, 0x2f, 0x41, 0x5c,
+ 0x93, 0x35, 0xaa, 0x46, 0x8d, 0x5a, 0x79, 0x5f, 0xde, 0x5d, 0x15, 0x2b,
+ 0x8b, 0x34, 0xc3, 0x3f, 0x5e, 0xe7, 0x7f, 0x2d, 0x21, 0x3a, 0xfd, 0xbd,
+ 0xe5, 0x36, 0x0c, 0xdf, 0x31, 0xd4, 0xf9, 0x7f, 0x92, 0x79, 0xbb, 0x04,
+ 0x55, 0x1e, 0x5c, 0x9f, 0xf8, 0xe0, 0x7a, 0x6a, 0x04, 0xca, 0xca, 0x66,
+ 0x1f, 0x79, 0x3f, 0x9c, 0xab, 0x17, 0x60, 0xda, 0x87, 0x7c, 0x24, 0x02,
+ 0xf5, 0x74, 0x73, 0x98, 0xb9, 0x7e, 0xfe, 0x7e, 0xce, 0xf2, 0xac, 0xee,
+ 0x8b, 0x2a, 0xf9, 0x7b, 0x36, 0x9d, 0xa1, 0x3f, 0xd0, 0xae, 0xbb, 0x85,
+ 0xb3, 0xb0, 0x2f, 0x60, 0x6b, 0xc2, 0xb2, 0x9e, 0xa4, 0x0e, 0xe4, 0x5e,
+ 0xe0, 0x9b, 0x99, 0xdf, 0x59, 0x93, 0x5e, 0x27, 0x5e, 0x37, 0xa6, 0xb7,
+ 0x47, 0xae, 0x17, 0x31, 0x19, 0xfb, 0xec, 0x13, 0x75, 0xdc, 0x68, 0xdc,
+ 0x76, 0x98, 0x79, 0xf2, 0xc2, 0x80, 0xee, 0x4f, 0xe2, 0xff, 0x5a, 0xc2,
+ 0x0b, 0xd3, 0x4a, 0x71, 0xdd, 0xee, 0xfd, 0x6b, 0x27, 0x55, 0x31, 0x17,
+ 0xc7, 0x77, 0x28, 0xa1, 0xf7, 0xc7, 0x99, 0xb7, 0x45, 0xbd, 0x88, 0x39,
+ 0x23, 0x75, 0xfe, 0x9d, 0x09, 0x7b, 0x9c, 0xe6, 0x79, 0xce, 0xdd, 0xe9,
+ 0xe6, 0x3a, 0x7f, 0x6f, 0x46, 0x6c, 0x50, 0xe1, 0x58, 0x9a, 0xf1, 0x70,
+ 0x46, 0xc5, 0x9d, 0x0f, 0x78, 0xb1, 0x69, 0xc0, 0x83, 0x6d, 0x03, 0x5f,
+ 0x82, 0x71, 0x95, 0x13, 0x77, 0x30, 0xf7, 0xdb, 0x3c, 0x50, 0x4a, 0x3d,
+ 0x6a, 0xd8, 0x32, 0xe0, 0x44, 0xd3, 0x55, 0x55, 0x88, 0xcf, 0x2c, 0xc5,
+ 0xf3, 0xf4, 0xdd, 0xab, 0x42, 0x15, 0x48, 0xdb, 0x9c, 0x43, 0xb0, 0x41,
+ 0x78, 0x9b, 0xe8, 0x8d, 0x71, 0xd0, 0x10, 0x0c, 0xf9, 0xa0, 0xf5, 0x99,
+ 0xdf, 0x58, 0xb9, 0x99, 0x7b, 0x6c, 0x3e, 0xe9, 0x88, 0x88, 0x6e, 0xa4,
+ 0xae, 0xac, 0x35, 0x79, 0x19, 0x23, 0xdf, 0xa3, 0x47, 0x65, 0x5e, 0x24,
+ 0x30, 0xb9, 0x4c, 0x71, 0x20, 0x1c, 0xa8, 0x8a, 0x55, 0x47, 0xc2, 0x58,
+ 0x99, 0xed, 0xf1, 0xf9, 0xec, 0x7b, 0x59, 0x11, 0x9c, 0x5f, 0x62, 0xe2,
+ 0x96, 0x2c, 0x9c, 0x2b, 0xa9, 0xfb, 0x56, 0xea, 0x75, 0x87, 0xf9, 0x07,
+ 0x2b, 0x9f, 0xd7, 0xb8, 0x89, 0x97, 0x96, 0xb5, 0x99, 0xfa, 0x65, 0x4e,
+ 0x81, 0x9f, 0x16, 0xf4, 0x2b, 0x3a, 0xad, 0x18, 0xff, 0x9d, 0x75, 0x9a,
+ 0xfa, 0x75, 0xb3, 0x3d, 0x37, 0xdb, 0x2b, 0x1b, 0x7f, 0xaf, 0x9e, 0x4b,
+ 0x29, 0xcf, 0x4a, 0x5b, 0x86, 0xd9, 0x72, 0x2f, 0xc0, 0x1f, 0x55, 0x8a,
+ 0x3c, 0xf4, 0x4f, 0x8d, 0xe9, 0x25, 0x7b, 0xbd, 0xed, 0xeb, 0x59, 0xcb,
+ 0x1a, 0x36, 0x45, 0xff, 0x7e, 0xea, 0x5f, 0xd6, 0x5d, 0x64, 0x0e, 0x9a,
+ 0x10, 0xad, 0xd5, 0xfb, 0x01, 0x49, 0x7c, 0x15, 0xcc, 0x60, 0xae, 0xf5,
+ 0x8d, 0x76, 0x0f, 0x5e, 0x4b, 0x54, 0xda, 0xe3, 0xbe, 0xaa, 0xc1, 0xb2,
+ 0xbe, 0x16, 0xf2, 0xe3, 0x4d, 0xa3, 0x31, 0xbc, 0x48, 0xd5, 0x19, 0x13,
+ 0x64, 0xed, 0x83, 0xba, 0x48, 0xcd, 0xe5, 0x7c, 0x89, 0xcf, 0x63, 0x1b,
+ 0xed, 0xc9, 0xef, 0x88, 0x00, 0xaf, 0x26, 0x8c, 0xe0, 0x0e, 0xf6, 0x3f,
+ 0xea, 0x8d, 0x60, 0x7b, 0x4a, 0x6d, 0x75, 0x92, 0x7c, 0x96, 0x31, 0xd7,
+ 0xdb, 0x85, 0x7f, 0xb5, 0xd2, 0x5e, 0x0b, 0x25, 0x21, 0x89, 0x25, 0xf3,
+ 0x70, 0x46, 0x73, 0xe0, 0x99, 0xe0, 0x2c, 0x44, 0x6b, 0x1c, 0xe4, 0x33,
+ 0xaf, 0x5b, 0xff, 0xec, 0x95, 0x7e, 0x64, 0x2c, 0x7f, 0xe0, 0x38, 0x14,
+ 0x1b, 0xef, 0x76, 0xa6, 0x22, 0xd4, 0xf7, 0xfb, 0xfb, 0xff, 0xbf, 0xd6,
+ 0x94, 0x57, 0xfa, 0xd7, 0x35, 0x3f, 0xf9, 0xf9, 0xe3, 0x1f, 0xb8, 0xce,
+ 0x12, 0xe4, 0x78, 0xbf, 0x67, 0x7d, 0xc7, 0x6e, 0xf3, 0x23, 0xa5, 0x79,
+ 0x5e, 0x2f, 0xed, 0x3d, 0xcd, 0xf1, 0x49, 0x9b, 0xc5, 0x7e, 0x44, 0x6f,
+ 0x93, 0xa5, 0x82, 0xd7, 0x3b, 0x53, 0xa2, 0x3f, 0xc9, 0x97, 0x4e, 0x5b,
+ 0x98, 0x25, 0xe7, 0x0f, 0xdb, 0x65, 0xe3, 0xd4, 0x57, 0x0f, 0x6d, 0x88,
+ 0xb1, 0x81, 0xf1, 0x42, 0xee, 0xb2, 0x6a, 0xc4, 0x5c, 0x0b, 0xdb, 0x19,
+ 0xb2, 0xd2, 0xde, 0x6a, 0xec, 0x34, 0x69, 0x77, 0x86, 0x3a, 0xdf, 0x09,
+ 0x0b, 0xa7, 0x4d, 0x39, 0x77, 0x61, 0xca, 0xeb, 0xc0, 0x2e, 0xd3, 0x89,
+ 0x4e, 0x43, 0xd5, 0xe5, 0xba, 0x23, 0x24, 0xe7, 0x2e, 0xf8, 0x67, 0x2a,
+ 0xd8, 0x13, 0x56, 0xb1, 0xc5, 0xe8, 0xf1, 0xcb, 0xf5, 0xe5, 0x21, 0x39,
+ 0x57, 0xb0, 0x91, 0x3a, 0x89, 0x33, 0x57, 0xde, 0xca, 0x76, 0x7b, 0x43,
+ 0xf9, 0x75, 0xf1, 0x18, 0x2c, 0x6b, 0x8f, 0xd9, 0xf2, 0xe1, 0x0a, 0x96,
+ 0x3b, 0x67, 0x4a, 0xec, 0x38, 0x70, 0xcb, 0xc2, 0x40, 0x3c, 0x5a, 0x02,
+ 0x3d, 0x56, 0x46, 0x3f, 0xdd, 0x39, 0x30, 0x8f, 0xf5, 0x04, 0xfb, 0x9d,
+ 0xbe, 0xdd, 0x90, 0xf5, 0xae, 0x80, 0xff, 0x27, 0xe4, 0xde, 0x69, 0xef,
+ 0x02, 0x6a, 0xd6, 0xf0, 0xbf, 0xc2, 0x79, 0xab, 0x36, 0x9c, 0xdb, 0x5e,
+ 0x80, 0xde, 0x59, 0xa6, 0x2c, 0x08, 0x56, 0xc1, 0x85, 0x38, 0xf9, 0xf9,
+ 0xd8, 0x38, 0xf3, 0xeb, 0x94, 0xa1, 0x1d, 0xb1, 0xd7, 0xcc, 0x3d, 0xd4,
+ 0x85, 0x87, 0xf1, 0x22, 0xa0, 0x4d, 0x2a, 0xc5, 0xf3, 0x79, 0x82, 0x0d,
+ 0x31, 0x47, 0x44, 0xf0, 0x2d, 0x6e, 0x3d, 0xd1, 0x4c, 0xd5, 0x19, 0x6e,
+ 0x7f, 0x2c, 0xe3, 0xe1, 0xa1, 0xf1, 0xf0, 0xfa, 0x37, 0x65, 0x7c, 0xfe,
+ 0x8d, 0x19, 0xf8, 0xd7, 0x67, 0x8a, 0x76, 0x59, 0xf4, 0x6d, 0xc1, 0x36,
+ 0xcb, 0x92, 0x7b, 0xc9, 0x8f, 0x67, 0xa5, 0xad, 0x7c, 0x1c, 0x2b, 0xa1,
+ 0xec, 0x4f, 0xd2, 0xd6, 0x5d, 0x8c, 0x55, 0xbb, 0x8c, 0x38, 0xa1, 0xd2,
+ 0xb2, 0x0c, 0xf2, 0x99, 0x12, 0xc5, 0x8f, 0x9d, 0x4d, 0xbf, 0xe5, 0x7c,
+ 0x02, 0x9b, 0x32, 0x01, 0x77, 0x7e, 0x3e, 0xc4, 0xcf, 0x04, 0x03, 0xfc,
+ 0x8c, 0xbf, 0x3e, 0x7f, 0x0f, 0xfb, 0xd9, 0x9e, 0x99, 0xee, 0x03, 0x0a,
+ 0x56, 0xb3, 0xad, 0x96, 0x10, 0x9c, 0x2b, 0x9a, 0xfe, 0xcd, 0xca, 0x79,
+ 0xa7, 0xdf, 0x37, 0x75, 0x33, 0xe6, 0xc2, 0xb9, 0xbe, 0x49, 0xce, 0x15,
+ 0xb4, 0x84, 0xe5, 0x5c, 0xc1, 0x7a, 0x43, 0xce, 0x89, 0xd9, 0x59, 0x39,
+ 0xb7, 0xac, 0xcb, 0xe7, 0xef, 0xc7, 0x22, 0x13, 0x77, 0xa5, 0x64, 0xed,
+ 0x4d, 0xb0, 0xc8, 0xed, 0xff, 0x4e, 0xa6, 0x09, 0x5b, 0x52, 0x72, 0x7f,
+ 0x8c, 0xb9, 0x86, 0xe1, 0xf1, 0x3f, 0x93, 0xb9, 0x16, 0x77, 0xee, 0x0f,
+ 0xa3, 0x73, 0x3f, 0x9a, 0xca, 0x38, 0x86, 0xd2, 0x50, 0xc0, 0x7f, 0x14,
+ 0x9a, 0xff, 0x0c, 0x75, 0x72, 0x8a, 0x72, 0x9e, 0x7e, 0x8f, 0x9c, 0xa2,
+ 0x43, 0xf8, 0xef, 0x4e, 0xb8, 0x91, 0x09, 0xbd, 0x63, 0xc5, 0xed, 0x5c,
+ 0xc8, 0xeb, 0xbf, 0x27, 0xe1, 0x47, 0xce, 0xce, 0xc9, 0xde, 0x28, 0x15,
+ 0xec, 0xee, 0x4b, 0xc5, 0xa3, 0x2a, 0x8a, 0xf3, 0xab, 0x87, 0x65, 0x6e,
+ 0x5f, 0x4d, 0xc8, 0x7f, 0xd1, 0x2f, 0xa9, 0x8c, 0x4b, 0x2a, 0x73, 0xf9,
+ 0x41, 0x59, 0xdf, 0x57, 0x4b, 0x45, 0x3f, 0x72, 0x8f, 0x22, 0x2e, 0x39,
+ 0x63, 0x13, 0xaf, 0x6b, 0x8b, 0x10, 0xab, 0xa1, 0x9e, 0xca, 0x0d, 0xaf,
+ 0xbf, 0x71, 0xc2, 0xe7, 0x37, 0x27, 0xe0, 0xbf, 0x72, 0x62, 0xba, 0x08,
+ 0xe4, 0x0a, 0xea, 0x07, 0x61, 0x81, 0xd7, 0xbf, 0x39, 0x31, 0x8f, 0x3c,
+ 0x33, 0x6e, 0x2d, 0x6f, 0x3e, 0x6f, 0xcd, 0x8b, 0x18, 0xb9, 0xd3, 0x94,
+ 0xe1, 0x9d, 0x6b, 0xf4, 0xf8, 0x1c, 0xc7, 0xa9, 0xfb, 0xb5, 0x69, 0x7d,
+ 0x5c, 0x08, 0xfd, 0xff, 0xed, 0xa3, 0x18, 0xe7, 0x68, 0x0f, 0xcd, 0x32,
+ 0x06, 0x89, 0x77, 0xcc, 0x85, 0x6a, 0x65, 0x2c, 0x81, 0x02, 0x6f, 0x2b,
+ 0x8e, 0x4b, 0xe1, 0x5c, 0xbb, 0xa9, 0x8b, 0x62, 0x0c, 0xb3, 0xac, 0x5e,
+ 0xc3, 0x57, 0x58, 0x03, 0xe7, 0x9c, 0x65, 0x4f, 0x7d, 0xd8, 0xc9, 0x9c,
+ 0xfd, 0x9c, 0xd9, 0xf2, 0x57, 0x4e, 0x44, 0x7d, 0xa5, 0x8c, 0xad, 0xb2,
+ 0xf6, 0x74, 0xa6, 0x69, 0xca, 0x9a, 0x64, 0x1e, 0xd4, 0x92, 0x95, 0xfb,
+ 0x4b, 0x0e, 0xda, 0xb7, 0x85, 0x87, 0x4d, 0xf9, 0x5f, 0x70, 0x26, 0x1e,
+ 0x73, 0xd0, 0x56, 0xdc, 0x86, 0xde, 0xf1, 0x65, 0xa5, 0x8a, 0xae, 0xec,
+ 0x0c, 0x4e, 0x42, 0x0f, 0x6f, 0x51, 0xe8, 0x87, 0x35, 0x0b, 0x4c, 0x99,
+ 0x82, 0x37, 0x12, 0x01, 0x33, 0x50, 0x88, 0x4b, 0xe7, 0x38, 0x77, 0x6f,
+ 0x25, 0x8c, 0xce, 0x27, 0x0b, 0xe7, 0x3f, 0xcb, 0x4c, 0x5f, 0x1f, 0x17,
+ 0x7b, 0x74, 0xbb, 0xb7, 0x27, 0x70, 0xc1, 0xd1, 0x8c, 0x0b, 0x87, 0xcc,
+ 0x12, 0x2c, 0x6f, 0x17, 0x3b, 0x75, 0xbb, 0x77, 0x26, 0x30, 0xe5, 0xe4,
+ 0xb5, 0x73, 0xe6, 0x5c, 0x62, 0x9a, 0xbd, 0x7e, 0x29, 0x31, 0x22, 0xa6,
+ 0x31, 0xbe, 0x96, 0x47, 0xbc, 0xee, 0xf2, 0x09, 0x68, 0x65, 0xe4, 0x40,
+ 0xee, 0x08, 0x5a, 0x1d, 0x49, 0xdd, 0xdf, 0xe6, 0x68, 0xc2, 0xaa, 0xac,
+ 0x9f, 0x3c, 0xfa, 0x05, 0xf2, 0x4e, 0xfb, 0x3e, 0x1f, 0x6d, 0xd2, 0xc9,
+ 0x0a, 0x43, 0xb3, 0xd4, 0x88, 0xe4, 0x76, 0x55, 0xb8, 0x4b, 0xdb, 0xfa,
+ 0x11, 0x35, 0x32, 0x88, 0x9b, 0x9a, 0xdd, 0xad, 0xd5, 0x13, 0x45, 0x9d,
+ 0x20, 0xe6, 0x89, 0x40, 0xab, 0x32, 0xa0, 0x56, 0x46, 0x44, 0x37, 0xfe,
+ 0xd6, 0xe4, 0xb8, 0xc8, 0xaa, 0xb9, 0x07, 0xc6, 0x7f, 0xe3, 0x46, 0x79,
+ 0x94, 0x58, 0xf5, 0x43, 0xdf, 0x7f, 0xae, 0xde, 0x33, 0x6e, 0xc1, 0x7b,
+ 0x97, 0x21, 0xdf, 0xb6, 0x6d, 0x31, 0x1f, 0x19, 0xfb, 0x8c, 0x3b, 0x60,
+ 0x59, 0x8c, 0x93, 0x3e, 0x28, 0x73, 0x39, 0x1e, 0xfa, 0x1a, 0xe3, 0xd2,
+ 0xc6, 0xcc, 0x1f, 0xac, 0x8f, 0x3a, 0x6d, 0x0e, 0x40, 0xde, 0xe4, 0xbf,
+ 0xed, 0x75, 0xe3, 0xf7, 0x96, 0xf0, 0x11, 0x27, 0x7d, 0xba, 0x84, 0x78,
+ 0xbe, 0xdb, 0x74, 0xb6, 0xad, 0x50, 0x14, 0xf4, 0x19, 0x0b, 0xb4, 0x32,
+ 0xc6, 0xa9, 0x5e, 0xfa, 0x75, 0xcc, 0x6b, 0x04, 0x0f, 0x81, 0xe5, 0x32,
+ 0x9b, 0x37, 0xbb, 0x22, 0xf7, 0x7c, 0x76, 0xac, 0x59, 0xb0, 0x60, 0xea,
+ 0xb6, 0x27, 0x8d, 0x0e, 0xf2, 0xaf, 0xaf, 0x90, 0xa7, 0xe5, 0xfb, 0xc9,
+ 0x61, 0xde, 0x07, 0xf4, 0xb3, 0x79, 0x73, 0x69, 0x44, 0x78, 0x58, 0xfa,
+ 0xb6, 0xc3, 0x46, 0x1b, 0x73, 0xb0, 0x7b, 0x3e, 0x7b, 0xae, 0xf9, 0x00,
+ 0xbf, 0xf3, 0x75, 0xd2, 0xa8, 0xfe, 0xc0, 0x3a, 0x15, 0x11, 0xe9, 0xc3,
+ 0xcf, 0x3e, 0xee, 0xf9, 0x6c, 0xe7, 0x92, 0x31, 0x6c, 0xcf, 0x6e, 0xfb,
+ 0x93, 0xfd, 0x54, 0x46, 0x64, 0x3d, 0x34, 0x76, 0xfb, 0xea, 0xc0, 0x3d,
+ 0x9f, 0xcd, 0x2c, 0x19, 0x64, 0x1f, 0x9f, 0x66, 0x7c, 0xc9, 0xd7, 0x89,
+ 0x2a, 0x8e, 0x0f, 0xd4, 0x41, 0x59, 0x64, 0xdb, 0xed, 0x0b, 0x03, 0xbf,
+ 0xb7, 0x16, 0x0c, 0x94, 0xd8, 0x3a, 0x70, 0x51, 0x07, 0x0f, 0x9a, 0xce,
+ 0x5c, 0xc0, 0x61, 0xeb, 0xa0, 0xcb, 0x47, 0x1d, 0x24, 0xa9, 0x83, 0xdc,
+ 0x4c, 0x23, 0xfc, 0x36, 0x75, 0xb0, 0x60, 0x7c, 0xf3, 0xe6, 0xb2, 0x08,
+ 0x9c, 0x0e, 0xe3, 0x47, 0x0e, 0xe6, 0x45, 0xaa, 0xcb, 0xd8, 0x4c, 0xbd,
+ 0xdd, 0xf3, 0xd9, 0xf9, 0x4b, 0x6c, 0x9d, 0xdf, 0xea, 0x0e, 0xdc, 0x47,
+ 0xbb, 0x69, 0xa5, 0xad, 0x6f, 0xe5, 0xd1, 0xce, 0xa3, 0x8f, 0x47, 0x02,
+ 0xbb, 0xb3, 0x1b, 0xa9, 0xab, 0x35, 0x1c, 0xc7, 0x3a, 0xca, 0xd5, 0xc5,
+ 0xdf, 0x31, 0xfe, 0x8e, 0xf3, 0xb7, 0xcc, 0x8f, 0x7a, 0x49, 0xb6, 0xd8,
+ 0x25, 0xd9, 0x1c, 0x94, 0xc7, 0x63, 0xaf, 0x55, 0x96, 0x47, 0x8e, 0xdf,
+ 0xba, 0x3a, 0xd0, 0xc9, 0x36, 0xfe, 0xbf, 0x32, 0xd9, 0x57, 0xe0, 0x32,
+ 0xe2, 0x3e, 0x27, 0x44, 0x3e, 0xbd, 0xa3, 0x13, 0x39, 0x62, 0xef, 0xef,
+ 0xf2, 0xd8, 0x4b, 0xd9, 0xaa, 0x38, 0x3f, 0xcf, 0x2d, 0x49, 0xcf, 0xf6,
+ 0x18, 0xf0, 0xb9, 0x8d, 0x7e, 0x0c, 0x64, 0x47, 0xa8, 0x03, 0xb1, 0x93,
+ 0x2f, 0x52, 0x7f, 0xdd, 0xac, 0x73, 0x8a, 0xb1, 0x4c, 0x8f, 0xd2, 0x67,
+ 0x69, 0xb3, 0x7a, 0x98, 0x07, 0xed, 0xe5, 0x51, 0xb6, 0x9b, 0xa6, 0x4c,
+ 0x25, 0xb4, 0x5f, 0x05, 0x72, 0x0f, 0xf7, 0x0c, 0xdb, 0x3f, 0x6c, 0xfc,
+ 0xba, 0xe2, 0x14, 0xc7, 0x1e, 0xf5, 0x6e, 0xc6, 0x68, 0x93, 0xe8, 0x2a,
+ 0x46, 0x5d, 0xe9, 0x3e, 0xff, 0x34, 0x5d, 0x5e, 0x96, 0xf7, 0x0a, 0xf2,
+ 0x09, 0xcb, 0xfa, 0x89, 0xd1, 0xb2, 0x90, 0x49, 0x21, 0xd2, 0x76, 0xae,
+ 0x64, 0x59, 0x25, 0xf6, 0xfe, 0xb3, 0xd8, 0xed, 0x1b, 0x0c, 0x91, 0xb7,
+ 0xb1, 0x7d, 0x3b, 0x8d, 0x73, 0x73, 0x86, 0xfe, 0x1c, 0xf8, 0x9d, 0x15,
+ 0x9d, 0x29, 0xf5, 0xe6, 0xe1, 0x15, 0xc6, 0xde, 0xa8, 0x16, 0xef, 0x74,
+ 0x0b, 0xbf, 0x37, 0x9c, 0xe1, 0x35, 0x88, 0x33, 0xa1, 0xd4, 0x83, 0x77,
+ 0x92, 0x7b, 0x9e, 0x33, 0xf2, 0x7e, 0x7c, 0x24, 0xa3, 0x47, 0x1f, 0xe6,
+ 0x39, 0x39, 0x30, 0xb9, 0x54, 0x31, 0x4e, 0x05, 0xc9, 0x7b, 0x3d, 0x70,
+ 0x32, 0x87, 0x6a, 0x75, 0xf4, 0x04, 0x5d, 0xa0, 0x2f, 0x96, 0xcb, 0xb8,
+ 0xe2, 0x1c, 0xa3, 0xe0, 0xb6, 0x5b, 0xdb, 0x68, 0x63, 0x79, 0x7c, 0xa1,
+ 0x0b, 0x1e, 0x6d, 0x53, 0xa6, 0x18, 0xe3, 0x3c, 0xda, 0xfa, 0x84, 0xe0,
+ 0x82, 0xdc, 0x77, 0x0d, 0x53, 0xcf, 0x82, 0x0f, 0xaf, 0xda, 0x7b, 0xd5,
+ 0x88, 0x11, 0x55, 0x4e, 0x23, 0xdf, 0xae, 0xc6, 0x76, 0xdb, 0x1d, 0x1a,
+ 0x2e, 0xfb, 0xb8, 0xae, 0xb5, 0x3b, 0x64, 0x1f, 0x1d, 0xd1, 0x2b, 0x53,
+ 0xa8, 0x97, 0xc7, 0xb9, 0x65, 0x2e, 0x1b, 0xe7, 0xd8, 0x06, 0xf3, 0x8e,
+ 0xe5, 0x89, 0xf7, 0xf7, 0x2f, 0xfd, 0x49, 0xbf, 0x3d, 0x35, 0x2a, 0x64,
+ 0x9f, 0x8f, 0xdc, 0x13, 0xeb, 0x64, 0xbe, 0x36, 0x7d, 0xaf, 0x8f, 0x7e,
+ 0x82, 0xed, 0x1f, 0x8f, 0x73, 0x3e, 0xe7, 0x1a, 0xb2, 0x0f, 0x48, 0xee,
+ 0xa1, 0x4d, 0xdf, 0xf7, 0x63, 0xdf, 0x9f, 0x2c, 0x17, 0x2e, 0x73, 0x98,
+ 0x38, 0x19, 0x6d, 0x97, 0xfa, 0x96, 0xf5, 0xe3, 0x05, 0x41, 0xe4, 0x66,
+ 0x38, 0x31, 0xd2, 0x00, 0x0c, 0x27, 0x45, 0xd7, 0xe9, 0xcf, 0x6c, 0x30,
+ 0xfe, 0xcd, 0x8a, 0xd6, 0x36, 0x6a, 0xbd, 0xaa, 0xac, 0x67, 0x8c, 0xdd,
+ 0xda, 0x67, 0xd4, 0x6b, 0x7d, 0x6a, 0xee, 0x18, 0xe3, 0xd0, 0x01, 0xe6,
+ 0xe8, 0xe5, 0x82, 0x15, 0x35, 0x46, 0xb4, 0xbf, 0x06, 0x0d, 0xf0, 0xdb,
+ 0xf7, 0x24, 0xf4, 0xf8, 0x37, 0x54, 0x23, 0xb8, 0x56, 0xf8, 0xa7, 0xfa,
+ 0x8e, 0x95, 0xa6, 0x0d, 0x7c, 0xa1, 0xe1, 0x67, 0x65, 0x79, 0x6c, 0x8f,
+ 0x76, 0xce, 0xe2, 0xbc, 0xbc, 0xb9, 0x48, 0xf7, 0x67, 0x14, 0xd1, 0x91,
+ 0x70, 0xae, 0x11, 0xec, 0x62, 0x3c, 0xfe, 0xb7, 0x86, 0x08, 0x8e, 0xf0,
+ 0xfb, 0xa7, 0xd7, 0xca, 0x1e, 0x37, 0xcb, 0x0a, 0x06, 0x16, 0x84, 0x6b,
+ 0x38, 0x86, 0x67, 0xf8, 0x7f, 0x7f, 0xf6, 0x75, 0xeb, 0xdc, 0x2c, 0x63,
+ 0x70, 0x25, 0x83, 0xe2, 0xf0, 0x84, 0xae, 0x4d, 0xa9, 0xff, 0xd9, 0x3d,
+ 0x37, 0xf6, 0x3a, 0xe3, 0x67, 0x9e, 0x0f, 0x34, 0x6a, 0x49, 0xb5, 0xae,
+ 0x5c, 0xf4, 0x3a, 0x3c, 0xf1, 0x52, 0x21, 0xce, 0xe7, 0xef, 0x75, 0x3e,
+ 0x7e, 0x49, 0x3f, 0x72, 0xdf, 0x76, 0x1e, 0x6d, 0x2e, 0x1a, 0xa7, 0xde,
+ 0xdd, 0x33, 0x38, 0xe6, 0x2f, 0x34, 0xdc, 0x69, 0x8f, 0xb3, 0xd6, 0x98,
+ 0xc3, 0x31, 0x2a, 0xd0, 0x1a, 0x9c, 0xe5, 0x79, 0xfe, 0xd8, 0x42, 0x96,
+ 0x96, 0xb6, 0x5a, 0xe9, 0x43, 0x25, 0xac, 0x73, 0xbd, 0x79, 0x70, 0x76,
+ 0x4f, 0x93, 0xee, 0xfb, 0x02, 0x6d, 0x35, 0xd4, 0xf0, 0x2b, 0x2b, 0xaa,
+ 0x39, 0xcd, 0xaf, 0x73, 0xd4, 0x77, 0x26, 0xa4, 0xac, 0xcc, 0xab, 0x11,
+ 0x6d, 0x50, 0xde, 0xb2, 0x30, 0x33, 0x10, 0x6e, 0xb0, 0xc7, 0x0f, 0xdc,
+ 0x91, 0x19, 0x61, 0xae, 0x2c, 0x6d, 0x2a, 0x58, 0x19, 0x78, 0xc3, 0xf2,
+ 0xcf, 0x1a, 0xc1, 0xce, 0xec, 0x1f, 0xe3, 0xb0, 0x5f, 0x21, 0x87, 0xd6,
+ 0x3b, 0xe2, 0x79, 0xbf, 0x6b, 0x03, 0xfb, 0x2d, 0x37, 0xec, 0x3c, 0xfc,
+ 0xb6, 0x44, 0x40, 0xd6, 0x8c, 0xc6, 0x3e, 0x33, 0x1e, 0x90, 0xbd, 0x19,
+ 0x5e, 0xe4, 0xda, 0xa5, 0x4c, 0xbd, 0x36, 0x8e, 0x1c, 0x19, 0xa6, 0xec,
+ 0x23, 0x39, 0x54, 0x9e, 0x5f, 0x47, 0x70, 0xc8, 0x3a, 0xb8, 0xf6, 0x2a,
+ 0x39, 0x61, 0x9b, 0x21, 0x6d, 0x28, 0x58, 0x18, 0x98, 0x81, 0xc6, 0xb5,
+ 0x3f, 0x7a, 0xb9, 0x24, 0x90, 0xf7, 0xdb, 0x3e, 0xc3, 0xd8, 0x76, 0x1a,
+ 0xbf, 0x26, 0x56, 0xc9, 0x3e, 0x93, 0xb4, 0xd4, 0x63, 0x5b, 0x0d, 0xc8,
+ 0x68, 0x4e, 0x8c, 0x1a, 0xb2, 0x0f, 0xd2, 0xb2, 0x56, 0x07, 0x5e, 0xa3,
+ 0xdf, 0x51, 0x9e, 0xac, 0xb3, 0x50, 0x57, 0xca, 0x14, 0xf6, 0x70, 0x28,
+ 0x2d, 0x9f, 0x15, 0x9d, 0x3c, 0x61, 0xc6, 0x99, 0x35, 0x48, 0x7c, 0x18,
+ 0xfb, 0xcc, 0xeb, 0x86, 0x70, 0x78, 0xdd, 0x5c, 0xa9, 0x54, 0x33, 0xde,
+ 0x3a, 0xfd, 0x63, 0xf6, 0x7a, 0x86, 0x9f, 0x58, 0x2e, 0x3c, 0x54, 0x72,
+ 0x43, 0x27, 0x9e, 0x34, 0x6a, 0xf0, 0x84, 0x96, 0xe7, 0x74, 0xc4, 0x44,
+ 0xbc, 0x90, 0x58, 0x90, 0xa3, 0x87, 0x90, 0x1b, 0x1b, 0x9d, 0x17, 0x95,
+ 0x5f, 0x33, 0x6f, 0x04, 0x9e, 0xcb, 0x74, 0xe1, 0x41, 0xb9, 0x8f, 0xa5,
+ 0xd4, 0xb7, 0x35, 0x3a, 0xa4, 0xbf, 0x2e, 0xec, 0xb2, 0xd7, 0x65, 0xc7,
+ 0x3e, 0x73, 0xd8, 0x78, 0xa4, 0x20, 0xab, 0x60, 0xfe, 0xd8, 0x67, 0x9e,
+ 0x34, 0x4e, 0xdb, 0x73, 0x27, 0x7b, 0x16, 0xfa, 0x4d, 0xc1, 0xc6, 0x72,
+ 0xa8, 0xcc, 0x2f, 0x1c, 0xc6, 0xa7, 0xe1, 0xa8, 0x19, 0xa3, 0xed, 0xc9,
+ 0x7a, 0xcf, 0xed, 0x70, 0xd6, 0xb8, 0xe8, 0x9b, 0x77, 0xc0, 0x55, 0x23,
+ 0x9c, 0xbe, 0xc8, 0xb7, 0xdb, 0xf8, 0xbf, 0xe8, 0x76, 0xca, 0xd6, 0xad,
+ 0x93, 0xd8, 0xd3, 0x27, 0xf9, 0x9f, 0x51, 0x4d, 0x1d, 0xe9, 0x1d, 0xb2,
+ 0xae, 0x5d, 0x49, 0x6c, 0x65, 0x1c, 0x75, 0x57, 0xb3, 0xcc, 0xdb, 0xd4,
+ 0xfb, 0x82, 0x81, 0x0a, 0x72, 0x7d, 0xcb, 0x7a, 0x87, 0x5c, 0x7f, 0x61,
+ 0xa0, 0x31, 0x67, 0x30, 0xfe, 0xe1, 0x66, 0xbd, 0x4d, 0xee, 0x11, 0x6f,
+ 0x30, 0x2e, 0x5a, 0xb1, 0x75, 0x52, 0x46, 0xf7, 0xc5, 0x94, 0x62, 0x1f,
+ 0x8b, 0xe0, 0x9f, 0x61, 0xc1, 0x15, 0xb1, 0x88, 0x5d, 0xba, 0x19, 0x45,
+ 0x8b, 0xec, 0xf5, 0x69, 0x97, 0xf1, 0xbb, 0xe4, 0x7e, 0x03, 0xa2, 0x93,
+ 0x2e, 0x18, 0xb9, 0x23, 0x32, 0x67, 0xb3, 0x2d, 0x04, 0x16, 0xff, 0x8e,
+ 0x39, 0x93, 0xcc, 0x4f, 0x7d, 0xae, 0x49, 0xc9, 0x05, 0x7d, 0xe4, 0xfe,
+ 0x8f, 0x40, 0x6f, 0x4f, 0x50, 0xd7, 0xad, 0x21, 0x1b, 0xf3, 0x7c, 0x09,
+ 0xd8, 0x7c, 0xdf, 0x7c, 0x05, 0x1f, 0x45, 0x25, 0x73, 0xdc, 0x86, 0xf1,
+ 0x35, 0xa8, 0xaa, 0x89, 0xfa, 0xca, 0xb1, 0x94, 0xe7, 0x5b, 0x99, 0xc7,
+ 0x7c, 0x12, 0x55, 0x6b, 0x63, 0x48, 0x70, 0xec, 0x95, 0xc6, 0xad, 0xbc,
+ 0xd6, 0x87, 0x64, 0xca, 0xc5, 0x71, 0xfc, 0xd0, 0xaa, 0x9a, 0x29, 0xb2,
+ 0x99, 0xde, 0x0a, 0x83, 0x79, 0xb7, 0xad, 0x0b, 0x62, 0x79, 0x4a, 0xb8,
+ 0x54, 0x63, 0x74, 0x0b, 0xfe, 0x40, 0xdb, 0xd5, 0x3b, 0x36, 0x2a, 0x71,
+ 0xda, 0x6c, 0x82, 0x3a, 0x97, 0xb2, 0x96, 0xb5, 0x2a, 0xf0, 0x5b, 0xea,
+ 0x38, 0xce, 0x73, 0xc3, 0xff, 0x1a, 0xd4, 0xa5, 0xa5, 0x38, 0x6b, 0xc5,
+ 0x35, 0x1f, 0xed, 0x52, 0x5d, 0x27, 0xbc, 0x6b, 0x45, 0x48, 0xad, 0x40,
+ 0xb9, 0x56, 0xb0, 0xd3, 0x74, 0x41, 0x97, 0x53, 0xb7, 0xf5, 0x19, 0x6f,
+ 0x94, 0xcb, 0x75, 0x87, 0x7d, 0xdd, 0x5f, 0xb8, 0x9e, 0xe6, 0xf5, 0xf3,
+ 0xbc, 0x3e, 0x48, 0xdd, 0xab, 0x57, 0x48, 0xfd, 0xcd, 0xa6, 0xd4, 0x27,
+ 0x1d, 0x31, 0x12, 0x85, 0xf9, 0x88, 0xdd, 0x9e, 0x2f, 0xbb, 0xed, 0xf6,
+ 0x7c, 0x1b, 0x4e, 0xb6, 0x11, 0x8f, 0x96, 0xc3, 0x44, 0x45, 0x40, 0x70,
+ 0x5e, 0xe4, 0xe2, 0xdc, 0x65, 0x45, 0xae, 0xad, 0x8c, 0x8b, 0x3d, 0x4f,
+ 0x97, 0x23, 0xde, 0x35, 0xc7, 0xb6, 0xc3, 0x34, 0x79, 0x8a, 0xee, 0x7f,
+ 0x5d, 0x69, 0xf1, 0xc9, 0xb2, 0x4e, 0x8a, 0x9c, 0xf7, 0x7e, 0xd3, 0x19,
+ 0x6e, 0x72, 0x2c, 0xc8, 0x95, 0xc2, 0x88, 0x5d, 0x54, 0x66, 0x57, 0x08,
+ 0x3e, 0x24, 0x32, 0x2d, 0xcc, 0xd0, 0xe2, 0x41, 0xe6, 0x56, 0xc1, 0x2c,
+ 0x75, 0xbb, 0x9e, 0x88, 0x7d, 0xc2, 0xde, 0xb3, 0xe4, 0x9c, 0x5c, 0x83,
+ 0x16, 0xdd, 0x81, 0x05, 0xe1, 0x39, 0xcc, 0xd0, 0x68, 0x97, 0x66, 0xa9,
+ 0x43, 0xf7, 0xdf, 0x84, 0xff, 0x62, 0xd7, 0x3b, 0x92, 0xc9, 0x75, 0x96,
+ 0x73, 0x4e, 0xbf, 0x4a, 0x39, 0x76, 0x07, 0x44, 0x8e, 0xb1, 0x82, 0x1c,
+ 0x31, 0xc6, 0x5c, 0x53, 0xbb, 0x21, 0x30, 0x78, 0x49, 0x6f, 0x4f, 0xdb,
+ 0x7a, 0xeb, 0xe3, 0x79, 0x29, 0x76, 0x90, 0x3f, 0x9e, 0x6a, 0xf2, 0x16,
+ 0xd6, 0xf6, 0x25, 0xa7, 0x13, 0xfc, 0x3d, 0xfb, 0xa9, 0x0d, 0x86, 0x1e,
+ 0x76, 0xd8, 0xfc, 0xdf, 0x8d, 0xb8, 0xcd, 0xad, 0x1d, 0x10, 0xee, 0xf8,
+ 0xb0, 0x5d, 0xce, 0x45, 0x9d, 0x54, 0xe0, 0x91, 0x82, 0xbf, 0x54, 0x30,
+ 0xbe, 0x7d, 0xd5, 0xfe, 0x9d, 0xe6, 0xdc, 0xba, 0xe8, 0xab, 0xc5, 0x18,
+ 0x25, 0xeb, 0x83, 0xfd, 0xb6, 0xef, 0xa7, 0xf1, 0x7d, 0xfb, 0x3b, 0x97,
+ 0xcf, 0xcb, 0xd0, 0x47, 0x9f, 0x70, 0xb0, 0x8d, 0x5e, 0x7b, 0x2f, 0xaa,
+ 0xac, 0x15, 0x5c, 0x8b, 0x1d, 0x1c, 0x95, 0xdb, 0xe8, 0x44, 0xbf, 0x26,
+ 0x36, 0xd1, 0x8d, 0xa4, 0x66, 0x7a, 0xb3, 0x4d, 0xd3, 0x73, 0x2a, 0x13,
+ 0x87, 0x9a, 0x7e, 0xcf, 0x58, 0x2e, 0xd7, 0xce, 0x5a, 0x87, 0x8d, 0x53,
+ 0x21, 0x7a, 0x70, 0x67, 0x89, 0xad, 0xdf, 0xa9, 0xdb, 0xec, 0x7d, 0x5b,
+ 0x94, 0xf9, 0xe9, 0x84, 0xc4, 0xd1, 0x79, 0xc8, 0x98, 0x22, 0x9b, 0xb3,
+ 0x7d, 0x0f, 0xe7, 0xa4, 0x2f, 0x15, 0x88, 0x5e, 0xc9, 0xff, 0x26, 0x19,
+ 0xcb, 0x7a, 0xa9, 0xcf, 0x58, 0xbb, 0xf0, 0xb8, 0xad, 0x38, 0x40, 0x1b,
+ 0x9b, 0x30, 0x2d, 0xeb, 0x08, 0x31, 0xa2, 0x7a, 0x81, 0x8a, 0xdc, 0xcc,
+ 0xad, 0x48, 0x31, 0x36, 0x1d, 0x31, 0x5a, 0x3e, 0x5a, 0x82, 0xb8, 0x9f,
+ 0x31, 0xdc, 0xb7, 0x93, 0xa3, 0xb9, 0x9f, 0xf3, 0x75, 0xca, 0x14, 0x7e,
+ 0xe9, 0xbc, 0xb8, 0x02, 0x46, 0x78, 0x99, 0xe3, 0x87, 0xd6, 0x94, 0xc8,
+ 0x9e, 0xea, 0xf9, 0x5f, 0x94, 0x61, 0x9b, 0x38, 0x6f, 0x35, 0xe7, 0xf8,
+ 0xed, 0x80, 0xde, 0xf6, 0x02, 0xfb, 0x69, 0x1c, 0x68, 0xe9, 0x14, 0x19,
+ 0x0e, 0x87, 0x9c, 0xb1, 0x23, 0x08, 0xb4, 0x6f, 0x55, 0x8a, 0x39, 0x04,
+ 0x70, 0xe5, 0xb8, 0x89, 0xa3, 0x4d, 0xcf, 0x90, 0xef, 0x48, 0xfd, 0x52,
+ 0x3c, 0x66, 0x3e, 0x65, 0xd5, 0xcf, 0x7e, 0xde, 0x3a, 0x66, 0xa8, 0x5b,
+ 0xa8, 0xed, 0x58, 0x25, 0x64, 0x4d, 0x33, 0x7d, 0xdb, 0x5d, 0x01, 0xdd,
+ 0xdc, 0xc3, 0xb6, 0xce, 0x24, 0x4e, 0x05, 0xdd, 0x6c, 0xeb, 0x11, 0x53,
+ 0x72, 0x08, 0x67, 0x5b, 0x1b, 0xe7, 0xb6, 0x27, 0x15, 0xf0, 0xc9, 0xba,
+ 0xad, 0xe4, 0x79, 0xb7, 0x27, 0x64, 0xcf, 0xf8, 0x18, 0xc7, 0x13, 0xdd,
+ 0xe6, 0x42, 0xcb, 0xfd, 0x55, 0xb4, 0x9f, 0x6a, 0x14, 0x6d, 0x5d, 0xf7,
+ 0x11, 0xef, 0x70, 0x17, 0xcb, 0xbc, 0x1c, 0x98, 0x87, 0xe7, 0x42, 0x2d,
+ 0x6b, 0xe7, 0xc1, 0x19, 0x3b, 0xa6, 0x04, 0xda, 0xb6, 0x2a, 0x71, 0x4d,
+ 0x6c, 0xf1, 0xce, 0x8c, 0x1e, 0x6c, 0x85, 0x60, 0x77, 0x8c, 0xfa, 0x98,
+ 0x87, 0x77, 0x16, 0x8b, 0x5c, 0xce, 0x70, 0xd0, 0x11, 0xe8, 0x7a, 0x8a,
+ 0xf3, 0x5b, 0xb5, 0x40, 0x64, 0x07, 0xb2, 0x19, 0x91, 0x3f, 0x86, 0x64,
+ 0xf6, 0xec, 0xdb, 0x87, 0x0d, 0x38, 0x4f, 0x34, 0x3d, 0x68, 0xc1, 0xde,
+ 0x63, 0xde, 0x22, 0xf3, 0xd0, 0x21, 0xf3, 0x50, 0x4e, 0x7f, 0x5a, 0x4d,
+ 0xb9, 0xb7, 0xd8, 0x72, 0xcf, 0xc3, 0xa8, 0x29, 0xeb, 0x64, 0x4e, 0xed,
+ 0x4e, 0x0c, 0x12, 0x3b, 0x03, 0x17, 0x7b, 0xd8, 0xcf, 0xcb, 0x94, 0x79,
+ 0x01, 0xf5, 0x3e, 0xd5, 0x2e, 0xfc, 0xb6, 0x0f, 0x03, 0xa9, 0xe2, 0x1e,
+ 0x74, 0x05, 0x92, 0x7a, 0x4f, 0x39, 0xfa, 0xc8, 0xf7, 0x7a, 0xac, 0xa9,
+ 0x99, 0x72, 0x3d, 0x8d, 0x1d, 0xa9, 0xa8, 0x46, 0x7f, 0xa0, 0xde, 0xa1,
+ 0xcf, 0x83, 0x3e, 0xf9, 0xaa, 0x23, 0x4a, 0x1f, 0x30, 0xbd, 0x17, 0x89,
+ 0x0d, 0x27, 0xd0, 0x65, 0xa1, 0xc6, 0xb6, 0x87, 0x9f, 0x8e, 0x19, 0x0e,
+ 0x59, 0x6b, 0x0f, 0xe6, 0xa8, 0x03, 0x95, 0x73, 0x22, 0x3a, 0xa8, 0xa4,
+ 0xcf, 0x8e, 0x07, 0x74, 0xff, 0x73, 0x94, 0x67, 0x0f, 0xe5, 0x59, 0x93,
+ 0x9f, 0x43, 0xdf, 0x0e, 0x45, 0x7c, 0x3a, 0xd0, 0xbe, 0x81, 0xd7, 0x77,
+ 0x53, 0x9e, 0xc0, 0x80, 0x82, 0x34, 0xd1, 0xac, 0x8f, 0x7c, 0xf6, 0xc0,
+ 0x34, 0x79, 0xdc, 0xf6, 0x9c, 0xc5, 0xc9, 0x05, 0x4a, 0x71, 0xd8, 0x14,
+ 0xfc, 0xd6, 0x30, 0x4a, 0x3b, 0x3d, 0xc4, 0x19, 0x89, 0x7a, 0x55, 0x94,
+ 0x1a, 0x82, 0x01, 0x33, 0x79, 0xcd, 0xc5, 0xb9, 0xa9, 0xc6, 0x31, 0x2d,
+ 0xcd, 0x38, 0x59, 0xe4, 0x76, 0x7f, 0xb0, 0x8e, 0x7a, 0x85, 0x9f, 0xc9,
+ 0x3a, 0x9a, 0xac, 0x35, 0x7d, 0xb9, 0x22, 0xbf, 0xbf, 0x52, 0xf6, 0x3f,
+ 0xe4, 0xaf, 0x3f, 0xad, 0x09, 0x47, 0x2e, 0x96, 0xff, 0xb9, 0xf5, 0x84,
+ 0x5d, 0x5e, 0xca, 0xb9, 0x6c, 0x2e, 0x5f, 0x6e, 0x97, 0xfb, 0xb9, 0xf5,
+ 0x8c, 0xe6, 0x9c, 0x56, 0xae, 0xb8, 0x07, 0xef, 0xd4, 0x97, 0x5c, 0xc4,
+ 0x3c, 0x47, 0xc3, 0x32, 0x3c, 0x61, 0x9c, 0xad, 0x5f, 0xdf, 0xd4, 0xcd,
+ 0x38, 0x56, 0xe4, 0x5a, 0x75, 0xf4, 0x2b, 0x0b, 0x43, 0xe6, 0xa9, 0xa1,
+ 0x12, 0xf4, 0x90, 0x3b, 0x0a, 0x17, 0x10, 0x8e, 0x2a, 0xeb, 0x7c, 0xb7,
+ 0x96, 0x5f, 0xce, 0x79, 0xf5, 0xa0, 0x5f, 0x6d, 0xb3, 0xb9, 0x61, 0x54,
+ 0x15, 0xdc, 0xad, 0xb3, 0xc7, 0x7e, 0x39, 0xfe, 0x4b, 0xac, 0x98, 0xbe,
+ 0x6e, 0xd7, 0x8d, 0x43, 0x46, 0x91, 0xb3, 0x9c, 0x7a, 0x50, 0x25, 0x4e,
+ 0x0e, 0x9b, 0xcb, 0x24, 0x36, 0xfb, 0x59, 0x3f, 0x18, 0x53, 0xa7, 0x73,
+ 0x9b, 0xbf, 0xa9, 0x40, 0x55, 0xcf, 0x2e, 0x07, 0x64, 0xff, 0xaf, 0xec,
+ 0xd9, 0x96, 0xbe, 0xca, 0x0a, 0xeb, 0x57, 0x1f, 0xc4, 0x35, 0x8a, 0x7d,
+ 0x09, 0xdf, 0xa8, 0x28, 0xca, 0x18, 0x8c, 0xda, 0x72, 0xfe, 0xd2, 0x5a,
+ 0xab, 0xe5, 0xe6, 0x68, 0x78, 0xaf, 0xec, 0xd1, 0x82, 0xec, 0xb1, 0x0f,
+ 0x5c, 0x7f, 0x93, 0x7e, 0xa6, 0xb7, 0x59, 0xdc, 0x7b, 0x2a, 0x6b, 0xb3,
+ 0xf2, 0x9f, 0x82, 0x1e, 0xe2, 0x50, 0x54, 0x6b, 0x61, 0x9c, 0xd7, 0x7d,
+ 0x9b, 0x38, 0x1f, 0x71, 0xaf, 0xec, 0x6b, 0x2d, 0xc6, 0xc8, 0x52, 0xe4,
+ 0xd7, 0x48, 0x81, 0x43, 0x85, 0x75, 0x51, 0xda, 0x3d, 0x7a, 0x32, 0xbf,
+ 0xb3, 0x72, 0x5e, 0x27, 0x63, 0xe1, 0xe5, 0xfd, 0xf7, 0x69, 0xea, 0x75,
+ 0x94, 0xff, 0xed, 0xb8, 0xb4, 0xee, 0x22, 0x6b, 0x4f, 0x12, 0x7b, 0x7f,
+ 0x6b, 0xad, 0x7f, 0x4f, 0xd9, 0xe9, 0x7b, 0x5f, 0x67, 0xc6, 0x64, 0x3f,
+ 0xda, 0xd1, 0xc2, 0xfa, 0x7c, 0xeb, 0xbf, 0xdf, 0x8f, 0x46, 0x5b, 0x42,
+ 0x74, 0x07, 0xb9, 0x5d, 0x1c, 0x7d, 0x38, 0x9a, 0x68, 0xd4, 0x76, 0x42,
+ 0x93, 0x75, 0x69, 0x7e, 0xfa, 0x70, 0x2c, 0x81, 0x68, 0xc9, 0x55, 0xd5,
+ 0xe4, 0x5b, 0x88, 0x3a, 0x64, 0x8f, 0x50, 0xa2, 0xb1, 0x6d, 0x37, 0xc7,
+ 0xe4, 0x5f, 0xdb, 0x87, 0xd1, 0x44, 0xcb, 0xad, 0x8c, 0x23, 0xfe, 0x8a,
+ 0x3c, 0xd7, 0xe9, 0x38, 0x4c, 0x1c, 0xd8, 0x5e, 0x58, 0x1b, 0x5b, 0x9f,
+ 0xf8, 0x15, 0xe5, 0xb7, 0x85, 0x64, 0xbd, 0x3f, 0x56, 0xee, 0x2c, 0x7a,
+ 0x53, 0x67, 0xb1, 0x79, 0x50, 0x11, 0xfb, 0xc2, 0xa6, 0xb4, 0xc8, 0x73,
+ 0x16, 0x1b, 0x07, 0xbf, 0x87, 0x43, 0x83, 0xb3, 0xd1, 0x6a, 0xeb, 0xa6,
+ 0x0b, 0x5b, 0xf7, 0x9e, 0xc4, 0x9e, 0x94, 0x85, 0xdd, 0x21, 0x0f, 0xb6,
+ 0x1c, 0x54, 0xb0, 0x2a, 0x70, 0x06, 0x3b, 0xf7, 0x5a, 0x98, 0x1f, 0xea,
+ 0x46, 0x9b, 0x59, 0x81, 0xd2, 0x9a, 0x05, 0x9d, 0x2a, 0xcb, 0xad, 0x1f,
+ 0xed, 0x52, 0x6e, 0xe4, 0xb8, 0x73, 0xae, 0xe3, 0xc4, 0x02, 0x15, 0x3e,
+ 0x03, 0x5a, 0x75, 0x24, 0xaa, 0xdc, 0x92, 0x6d, 0x55, 0x3a, 0x46, 0x6d,
+ 0x3e, 0xa5, 0xdc, 0x94, 0xf5, 0x55, 0x4a, 0x4c, 0x3f, 0x14, 0x3a, 0x8b,
+ 0x74, 0xba, 0xaa, 0x32, 0xef, 0x2f, 0x67, 0xc9, 0x1d, 0x24, 0xe7, 0x30,
+ 0x69, 0x53, 0x7f, 0xec, 0xb9, 0x02, 0xb1, 0xbb, 0x29, 0xfc, 0x64, 0xe4,
+ 0x15, 0xbc, 0x32, 0xf2, 0x2f, 0x58, 0xae, 0x49, 0x9e, 0x69, 0x75, 0x3b,
+ 0x23, 0x96, 0xb5, 0xbf, 0x39, 0x6e, 0xcd, 0x34, 0x2c, 0xb6, 0x57, 0x85,
+ 0x59, 0x91, 0xef, 0x62, 0xb7, 0xc6, 0xb6, 0x52, 0xc7, 0xed, 0x7b, 0xb7,
+ 0xbe, 0xc8, 0xa7, 0xe1, 0x4b, 0xe5, 0xcc, 0x5a, 0x44, 0x87, 0x6a, 0xa1,
+ 0x6f, 0xab, 0x71, 0x18, 0x5d, 0xff, 0x5b, 0x69, 0xc2, 0x4d, 0xd9, 0x57,
+ 0xf0, 0xe6, 0x48, 0x37, 0x31, 0x53, 0xef, 0xf8, 0x96, 0x62, 0x75, 0xef,
+ 0x0e, 0xe9, 0x6d, 0xff, 0x55, 0x89, 0xc6, 0xcb, 0x69, 0x53, 0x65, 0xcc,
+ 0x09, 0x6e, 0x1e, 0x91, 0x7c, 0xb9, 0x03, 0xee, 0x01, 0x3d, 0xb7, 0x82,
+ 0x3c, 0xfb, 0x0b, 0x8b, 0xe2, 0x73, 0x66, 0xd0, 0x2e, 0x1d, 0x8a, 0x1e,
+ 0x34, 0xd4, 0x6e, 0x3c, 0x6e, 0xea, 0x93, 0xbf, 0x75, 0x18, 0xe9, 0x6f,
+ 0xa2, 0x09, 0xeb, 0xb2, 0x7a, 0x7a, 0x29, 0xf3, 0xb0, 0x9d, 0x49, 0x13,
+ 0xa9, 0xa4, 0xde, 0xd1, 0xe5, 0xe8, 0xc7, 0xdd, 0x81, 0xfa, 0x6d, 0x6f,
+ 0x93, 0xcb, 0x79, 0x88, 0x29, 0xc9, 0x89, 0x0c, 0xf3, 0xdc, 0x7e, 0x6c,
+ 0x3d, 0x18, 0xc1, 0x96, 0xfd, 0x26, 0xfa, 0x92, 0x19, 0xca, 0xf6, 0x1a,
+ 0x6d, 0xdb, 0xb2, 0xda, 0x43, 0xf1, 0x1b, 0x54, 0x04, 0xa2, 0xec, 0xb3,
+ 0x45, 0x8d, 0x04, 0xfc, 0xaa, 0xc2, 0xe8, 0x3f, 0xe1, 0x44, 0x2f, 0xcb,
+ 0x0c, 0xa4, 0x68, 0x73, 0x49, 0x37, 0xe3, 0x65, 0x1d, 0x46, 0xc7, 0x7d,
+ 0x38, 0x32, 0xee, 0x41, 0x7a, 0x5c, 0xe3, 0x51, 0x8e, 0x87, 0x86, 0x2d,
+ 0x62, 0xb9, 0x17, 0x8f, 0x1d, 0x76, 0x63, 0xfb, 0x3e, 0x0f, 0xe6, 0x45,
+ 0x66, 0xe1, 0xf0, 0xe1, 0x72, 0x1c, 0xe0, 0xf5, 0x9a, 0xc5, 0x7e, 0x7c,
+ 0x8d, 0xd7, 0x07, 0xf7, 0xb9, 0x38, 0x0f, 0xf3, 0x71, 0x9c, 0x86, 0x9d,
+ 0x1e, 0xaf, 0x40, 0x6a, 0x98, 0x26, 0x4f, 0xce, 0xfa, 0x3a, 0x33, 0x8c,
+ 0xa3, 0x87, 0x19, 0x1b, 0x0f, 0x9a, 0x48, 0xb0, 0x9f, 0x3d, 0xd4, 0x55,
+ 0x1f, 0x71, 0x6d, 0xeb, 0xb8, 0x60, 0xfc, 0x3a, 0xac, 0x1e, 0xd0, 0xdb,
+ 0x5a, 0x15, 0x23, 0xba, 0x44, 0x09, 0xca, 0x73, 0x2b, 0x6e, 0x95, 0xd7,
+ 0x5a, 0x12, 0xba, 0xd9, 0x8a, 0x6e, 0x9c, 0xe6, 0xb8, 0xff, 0x3b, 0xfd,
+ 0x76, 0x99, 0x43, 0xef, 0xbf, 0x5e, 0x3d, 0x89, 0xa1, 0x6c, 0x8e, 0x5c,
+ 0x1d, 0x08, 0x1f, 0x3a, 0x49, 0xfe, 0xf6, 0x38, 0xf1, 0xe7, 0x65, 0xcb,
+ 0x67, 0xa8, 0xb8, 0xe9, 0x01, 0x23, 0x7c, 0x41, 0x09, 0x6c, 0xfb, 0x25,
+ 0x75, 0x70, 0xe3, 0x61, 0x15, 0x1f, 0x1b, 0x5a, 0x86, 0x4c, 0x28, 0x8a,
+ 0x3d, 0x4b, 0x54, 0xdc, 0x70, 0xf0, 0x24, 0x71, 0xff, 0xac, 0xcd, 0x93,
+ 0x73, 0x99, 0x2f, 0x22, 0x38, 0x20, 0x6b, 0xf7, 0x6e, 0xc6, 0xef, 0x4a,
+ 0x9c, 0x19, 0xec, 0xa6, 0xdf, 0x56, 0xe2, 0x54, 0xfa, 0x24, 0xed, 0xb1,
+ 0x12, 0x8f, 0x0f, 0x1a, 0x93, 0x3f, 0x71, 0x54, 0xe2, 0x31, 0x9e, 0x0f,
+ 0xf1, 0x7c, 0xf1, 0xb0, 0x31, 0xd8, 0xa5, 0x56, 0x62, 0xd1, 0xa1, 0x66,
+ 0x0c, 0x26, 0xc5, 0x36, 0x35, 0x6c, 0x1b, 0x6f, 0x2a, 0xe8, 0x5e, 0x74,
+ 0xee, 0xc5, 0x3d, 0xd4, 0xd5, 0xdd, 0x43, 0xdd, 0xec, 0xcf, 0x47, 0x9d,
+ 0x9f, 0xc4, 0x43, 0xcc, 0xeb, 0x76, 0x27, 0x7d, 0x38, 0x9f, 0x32, 0xfc,
+ 0x9f, 0x52, 0x0c, 0xb3, 0x4c, 0x09, 0x68, 0x67, 0xe0, 0xc3, 0x2b, 0xd9,
+ 0x72, 0xf4, 0x0e, 0xd7, 0xe1, 0x27, 0xb4, 0xcf, 0x07, 0xf7, 0x9d, 0xb4,
+ 0xed, 0xff, 0x40, 0x6a, 0x2e, 0x1e, 0x1b, 0x33, 0xd9, 0xb6, 0xcc, 0x93,
+ 0xc3, 0xde, 0xdb, 0xe4, 0x4a, 0x89, 0x6f, 0x44, 0x87, 0x68, 0x16, 0xc4,
+ 0xc4, 0x93, 0xc8, 0x0e, 0xea, 0xfd, 0x37, 0xab, 0xc2, 0xab, 0x55, 0xea,
+ 0xd2, 0x81, 0x29, 0x4d, 0x8f, 0xd7, 0xa8, 0xf1, 0x41, 0xe6, 0xaf, 0xf1,
+ 0x5a, 0xea, 0xe4, 0xb1, 0x41, 0x27, 0x16, 0x2c, 0x56, 0x79, 0x3d, 0x7e,
+ 0x91, 0xb1, 0x2d, 0x3e, 0x4f, 0x35, 0x71, 0xc0, 0x96, 0x15, 0xf1, 0x12,
+ 0x72, 0xfb, 0xea, 0xc5, 0xf5, 0x8c, 0x5f, 0x0e, 0xb1, 0xbd, 0x58, 0xa5,
+ 0xea, 0xa4, 0xde, 0x5f, 0xc1, 0x18, 0xed, 0xfa, 0x11, 0x1e, 0xc7, 0x47,
+ 0xac, 0xee, 0x55, 0xe4, 0xdc, 0xf3, 0x03, 0x56, 0xf7, 0xcd, 0xa6, 0xe1,
+ 0x2b, 0x51, 0x03, 0xd1, 0x2f, 0xe0, 0x15, 0x1c, 0x1b, 0x93, 0x32, 0xb2,
+ 0x0f, 0x24, 0x86, 0x91, 0xa4, 0xd5, 0x3d, 0x64, 0xce, 0x47, 0xb3, 0x9d,
+ 0x1b, 0xbb, 0x2a, 0xf3, 0x98, 0x29, 0x7e, 0x24, 0x6b, 0x25, 0x53, 0xf8,
+ 0x25, 0xdb, 0xb9, 0x30, 0x52, 0x8d, 0x19, 0xb5, 0xe2, 0x07, 0x67, 0xf1,
+ 0xc6, 0xe0, 0x77, 0x71, 0x7e, 0xd0, 0xc2, 0xa2, 0x90, 0x05, 0x67, 0xa8,
+ 0xd1, 0x6c, 0x55, 0x97, 0x12, 0x23, 0x14, 0xac, 0x6e, 0xf8, 0x1e, 0xde,
+ 0x1a, 0x94, 0xfd, 0xa6, 0x96, 0x2d, 0xcb, 0x00, 0x16, 0x5b, 0x7b, 0x66,
+ 0x8a, 0xdf, 0x48, 0xbd, 0x3f, 0x95, 0x07, 0xeb, 0x8c, 0x86, 0xc5, 0x5c,
+ 0xf8, 0x15, 0x8c, 0x8e, 0x18, 0xd1, 0xcd, 0x45, 0x39, 0x07, 0x5f, 0xa1,
+ 0x0e, 0xec, 0xf8, 0x74, 0xb0, 0x06, 0x0b, 0x2e, 0x32, 0x6b, 0xfc, 0xf0,
+ 0x3c, 0xda, 0xce, 0xa2, 0xc5, 0x01, 0x73, 0xa5, 0xfa, 0x6f, 0xf4, 0xd3,
+ 0x57, 0x70, 0x24, 0x5d, 0xc4, 0x6b, 0x1f, 0x5a, 0xe9, 0xe7, 0xf9, 0x7d,
+ 0xfe, 0x5e, 0xb4, 0xa4, 0x4e, 0xd8, 0xeb, 0x0f, 0xc7, 0x89, 0x8f, 0x83,
+ 0x29, 0x29, 0xa3, 0x61, 0x2c, 0xdb, 0x4a, 0x6c, 0x88, 0xe2, 0x9f, 0xb2,
+ 0x11, 0xe2, 0x43, 0x98, 0xf8, 0xd0, 0x4c, 0x7c, 0x30, 0x89, 0x0f, 0x4d,
+ 0xc4, 0x87, 0x20, 0xf1, 0xc1, 0xb0, 0xd7, 0xd6, 0xd3, 0x47, 0xbf, 0x8b,
+ 0x92, 0xe1, 0xb3, 0x70, 0xd1, 0x07, 0xce, 0x98, 0x16, 0xf9, 0x49, 0xa3,
+ 0xb6, 0x11, 0xf3, 0x95, 0xa8, 0xe6, 0x45, 0x9a, 0xed, 0x95, 0x0d, 0x6b,
+ 0x1c, 0x8b, 0x85, 0x60, 0xa8, 0x3e, 0xdc, 0x4f, 0xac, 0xfe, 0x95, 0xd1,
+ 0xd8, 0xef, 0x45, 0xe3, 0x81, 0x99, 0x30, 0x06, 0x17, 0xab, 0x0d, 0x4a,
+ 0xf4, 0xe3, 0x5e, 0x8e, 0xb3, 0x16, 0x73, 0xf7, 0x69, 0x98, 0xc7, 0xe3,
+ 0x1f, 0x53, 0xf5, 0x93, 0x2f, 0x3b, 0xe0, 0x9d, 0x4d, 0xba, 0x33, 0x87,
+ 0x4c, 0x80, 0xac, 0xd6, 0xeb, 0xc3, 0x95, 0xc7, 0x5f, 0x51, 0x15, 0xe4,
+ 0x3e, 0x2e, 0x31, 0xaf, 0x31, 0xd8, 0xa7, 0xaa, 0xb2, 0x96, 0x44, 0x0c,
+ 0xe7, 0xa1, 0x22, 0x42, 0x16, 0x51, 0xc7, 0xfc, 0xc2, 0xda, 0x68, 0x96,
+ 0x61, 0x47, 0x13, 0x39, 0xa7, 0x57, 0x3f, 0x21, 0x31, 0x6a, 0x36, 0x63,
+ 0x44, 0x79, 0x32, 0x7e, 0xe7, 0x6c, 0x78, 0x50, 0x96, 0xb4, 0xac, 0xaf,
+ 0x86, 0x34, 0x78, 0x22, 0x81, 0xe8, 0x56, 0xa6, 0x91, 0x1f, 0x5f, 0x10,
+ 0xc6, 0xea, 0xec, 0x09, 0x0c, 0x73, 0x7c, 0xab, 0xb2, 0xc5, 0x67, 0xc5,
+ 0xfe, 0xf8, 0xe7, 0xf2, 0x33, 0x67, 0x57, 0x1e, 0x98, 0x0d, 0x43, 0xbb,
+ 0x57, 0x1d, 0xae, 0x22, 0x07, 0x3f, 0xce, 0xb8, 0xa7, 0x4c, 0x7d, 0x42,
+ 0x41, 0xc7, 0x70, 0x1c, 0x33, 0x42, 0x2f, 0x28, 0xb1, 0x5a, 0xdd, 0xef,
+ 0x57, 0x6a, 0xf1, 0x89, 0x7d, 0xd4, 0xf5, 0xa2, 0x1f, 0x7a, 0xe4, 0xb9,
+ 0xb0, 0x6f, 0x1e, 0x15, 0xdd, 0xd6, 0xa7, 0x87, 0x38, 0x8e, 0xc9, 0x86,
+ 0x13, 0x82, 0x93, 0x8f, 0xba, 0xe1, 0x78, 0x74, 0x16, 0xa2, 0x68, 0x6a,
+ 0xb8, 0xb2, 0xeb, 0x5f, 0x54, 0xd1, 0x8b, 0xf0, 0x6b, 0x7d, 0x30, 0xae,
+ 0x18, 0xda, 0xcf, 0x95, 0x13, 0xf6, 0x7d, 0xb8, 0xaf, 0x66, 0x4f, 0x52,
+ 0x97, 0xc7, 0x0b, 0xf9, 0xd2, 0x3a, 0x24, 0x06, 0x64, 0x5f, 0xfe, 0x59,
+ 0xcc, 0x1d, 0xd6, 0xdb, 0x77, 0x29, 0x46, 0xf0, 0x06, 0xe5, 0x2c, 0xe6,
+ 0x0c, 0x07, 0x39, 0x97, 0x1a, 0x56, 0x26, 0x8b, 0xf8, 0x29, 0x18, 0xbc,
+ 0x8e, 0x18, 0x6c, 0x2d, 0xfb, 0x89, 0x19, 0xd7, 0x65, 0x4f, 0x82, 0x53,
+ 0xd1, 0x3b, 0x1a, 0x94, 0x38, 0x63, 0xa8, 0x71, 0x71, 0x3d, 0xeb, 0x78,
+ 0x86, 0x9b, 0x70, 0x3b, 0xc7, 0xdc, 0xc6, 0x79, 0xfb, 0xee, 0x62, 0x0b,
+ 0x4b, 0x16, 0xeb, 0x07, 0xca, 0x1c, 0xd1, 0x7b, 0x6b, 0x90, 0xeb, 0x9a,
+ 0x49, 0xbb, 0xb9, 0x7b, 0x91, 0x1e, 0x7e, 0x81, 0xb8, 0x4b, 0x9c, 0x46,
+ 0x2f, 0xe3, 0xce, 0x46, 0xc6, 0xa2, 0xf2, 0x88, 0xde, 0xcf, 0x1c, 0xf5,
+ 0xc2, 0x1d, 0x8e, 0x68, 0x48, 0x9e, 0xff, 0xf8, 0x32, 0x96, 0xc1, 0x1d,
+ 0xaa, 0x22, 0x0e, 0xea, 0xb9, 0xef, 0x42, 0x3f, 0x70, 0x3b, 0xfa, 0xf1,
+ 0x03, 0xf2, 0xbb, 0x99, 0x57, 0xe5, 0x88, 0x51, 0x19, 0x3c, 0x98, 0x3d,
+ 0x89, 0x03, 0xd9, 0x47, 0xb1, 0x37, 0xbb, 0x5b, 0x49, 0xdb, 0xf7, 0x20,
+ 0x15, 0x79, 0xee, 0x26, 0x5a, 0xa5, 0x7c, 0x06, 0x95, 0xa1, 0xaf, 0x5b,
+ 0xe9, 0x1a, 0x15, 0xd5, 0xa1, 0x20, 0x56, 0x27, 0xe3, 0x70, 0x44, 0xde,
+ 0xb6, 0xe4, 0xb9, 0xcf, 0x2d, 0x13, 0x06, 0xae, 0x4f, 0x96, 0x23, 0x76,
+ 0xc8, 0xb2, 0xfa, 0x9b, 0x9d, 0xd8, 0x34, 0xd1, 0x84, 0x95, 0xc3, 0x0f,
+ 0x59, 0xf3, 0x18, 0x73, 0xde, 0xbd, 0xc6, 0x83, 0x3b, 0x0e, 0x79, 0xb0,
+ 0x3e, 0x19, 0x85, 0x2f, 0x52, 0xc1, 0xdf, 0x01, 0x73, 0x39, 0x8c, 0xc9,
+ 0x49, 0x18, 0xfd, 0xd7, 0x39, 0x02, 0xc7, 0xc2, 0xaa, 0x07, 0x7f, 0x4d,
+ 0x1c, 0x5f, 0x45, 0xdc, 0x89, 0x4d, 0x58, 0xa8, 0x8e, 0x78, 0x71, 0x27,
+ 0xeb, 0x7f, 0x8c, 0x73, 0xff, 0xd6, 0x92, 0xe3, 0xc4, 0x02, 0x23, 0x36,
+ 0xa1, 0x68, 0xd8, 0x3a, 0xe1, 0xa6, 0xae, 0xdc, 0x88, 0x1d, 0xa9, 0xc5,
+ 0xf5, 0xfb, 0xfc, 0xb8, 0x63, 0xc2, 0x83, 0x96, 0xa4, 0xb5, 0xec, 0xb8,
+ 0x19, 0x5f, 0xab, 0xc1, 0xc0, 0xfa, 0x09, 0x2f, 0x6e, 0x4b, 0xea, 0xbe,
+ 0x1b, 0x98, 0xf3, 0x8f, 0x99, 0x41, 0xfc, 0xed, 0x84, 0x0f, 0xb7, 0x24,
+ 0x4f, 0x49, 0x1e, 0xb9, 0xdc, 0xc9, 0xd8, 0x73, 0xff, 0x44, 0x1d, 0xd6,
+ 0x26, 0xf5, 0x8b, 0x93, 0xe4, 0x76, 0xdd, 0x47, 0x4c, 0xdc, 0x3b, 0xa1,
+ 0xa2, 0x83, 0xed, 0x7c, 0x22, 0x39, 0x17, 0x5d, 0x47, 0x9a, 0x29, 0xc3,
+ 0x62, 0xac, 0x1a, 0x76, 0xc2, 0x24, 0x8b, 0xc7, 0x27, 0x81, 0x76, 0xfa,
+ 0x47, 0x22, 0xf5, 0x45, 0xec, 0x19, 0x30, 0x71, 0xd7, 0x84, 0x9c, 0x9f,
+ 0xb4, 0x9f, 0x95, 0xbb, 0x70, 0x70, 0x31, 0x6e, 0x1c, 0x56, 0x89, 0x03,
+ 0xa5, 0x48, 0xaf, 0x55, 0x70, 0x1b, 0xaf, 0xef, 0x4a, 0xd9, 0x7b, 0xab,
+ 0x11, 0x1a, 0x0a, 0x1c, 0xab, 0x21, 0x67, 0x58, 0x72, 0x30, 0x7f, 0xfd,
+ 0x41, 0xe2, 0x7c, 0x19, 0x71, 0xbe, 0x82, 0x1c, 0xf6, 0xba, 0xd1, 0x93,
+ 0x78, 0x80, 0xb8, 0x7c, 0x62, 0xb8, 0x9b, 0x71, 0xa7, 0x12, 0x5f, 0x63,
+ 0x1c, 0x48, 0xf2, 0xfc, 0xec, 0x90, 0xd1, 0x55, 0x46, 0x9c, 0x7e, 0x81,
+ 0xf8, 0xdb, 0x4f, 0xcc, 0xb8, 0x3b, 0x49, 0xb7, 0x1f, 0x62, 0x0e, 0x70,
+ 0x55, 0x74, 0xa1, 0x87, 0x39, 0xd6, 0x0d, 0x4a, 0xc0, 0xf7, 0x1a, 0x2a,
+ 0xe1, 0x38, 0x58, 0x8b, 0x96, 0x7d, 0x52, 0x46, 0xf0, 0x4b, 0x85, 0x7a,
+ 0xd8, 0x49, 0x9d, 0x9f, 0x84, 0x35, 0xe8, 0xe0, 0x78, 0xeb, 0x4d, 0x32,
+ 0x70, 0xfc, 0xd8, 0xd4, 0xb5, 0x7f, 0x22, 0xd6, 0xbe, 0x43, 0x4c, 0xf5,
+ 0xcf, 0x6e, 0x46, 0xab, 0x61, 0xf2, 0x38, 0x89, 0x57, 0x06, 0x0d, 0xf3,
+ 0x10, 0x9c, 0x78, 0x99, 0x3c, 0x6f, 0x6a, 0x36, 0x63, 0xa6, 0x21, 0x7e,
+ 0x98, 0xe1, 0x78, 0x54, 0xc9, 0x4b, 0xe0, 0x18, 0x07, 0xde, 0x38, 0xb8,
+ 0x8c, 0xe3, 0x92, 0x58, 0x2a, 0xf1, 0x2e, 0x43, 0x59, 0x97, 0x61, 0x0d,
+ 0xf5, 0xd1, 0x9a, 0x54, 0x91, 0x39, 0x12, 0xc1, 0x5d, 0xfb, 0xf3, 0x71,
+ 0x78, 0x5b, 0x28, 0x7e, 0x33, 0xe3, 0x70, 0xb8, 0x9c, 0x71, 0xd8, 0x15,
+ 0x11, 0xd9, 0x9c, 0x18, 0x65, 0xdc, 0xde, 0x91, 0x0a, 0xa3, 0x8d, 0x73,
+ 0x38, 0x99, 0x61, 0xbf, 0xc9, 0x3a, 0x9c, 0xc9, 0x78, 0x18, 0xb3, 0x34,
+ 0x1e, 0x44, 0xb5, 0xb1, 0x59, 0x3c, 0xfc, 0x3c, 0xe6, 0xf3, 0x30, 0xec,
+ 0x6b, 0x1b, 0x93, 0x0a, 0xe2, 0xed, 0x8a, 0xcd, 0xe7, 0xcf, 0x64, 0x04,
+ 0x9b, 0x65, 0x2d, 0x73, 0x7b, 0x95, 0x3c, 0x8b, 0x32, 0x98, 0xfa, 0x1e,
+ 0xaa, 0xa9, 0xff, 0xaa, 0x02, 0x0e, 0xfd, 0x34, 0x24, 0xb8, 0x5b, 0x4f,
+ 0xdc, 0x95, 0xe7, 0x04, 0x2c, 0x6b, 0x5d, 0x60, 0x3a, 0x1e, 0xfd, 0x9f,
+ 0x77, 0xa3, 0xf6, 0x33, 0x17, 0x82, 0x49, 0xc4, 0xbf, 0x14, 0xf1, 0x8f,
+ 0x63, 0xe8, 0xb9, 0x96, 0x18, 0x48, 0x99, 0xfe, 0x21, 0x45, 0x0c, 0x24,
+ 0x4e, 0x3f, 0x4a, 0x9c, 0xfe, 0x06, 0x71, 0xfa, 0xeb, 0xc4, 0xe9, 0xaf,
+ 0x11, 0x13, 0xf2, 0x6b, 0x7a, 0x6d, 0x72, 0xff, 0x85, 0xf3, 0xf1, 0x96,
+ 0xbd, 0xb6, 0x38, 0x93, 0xba, 0x9a, 0x3b, 0xac, 0x60, 0x9e, 0xa1, 0x1f,
+ 0x13, 0xbb, 0xff, 0x01, 0xe7, 0xc9, 0x3f, 0xa3, 0xce, 0x7e, 0x26, 0xa6,
+ 0x35, 0xd9, 0x07, 0x77, 0xb2, 0x51, 0xeb, 0x87, 0xfd, 0x2c, 0xb2, 0x29,
+ 0x5c, 0xb4, 0x24, 0xb9, 0x11, 0x8e, 0x64, 0xe3, 0xb1, 0xd3, 0x72, 0x9f,
+ 0x77, 0x96, 0xe4, 0xf5, 0x1b, 0xe1, 0x4c, 0xea, 0xc7, 0xe2, 0x94, 0x65,
+ 0x25, 0xff, 0x73, 0x25, 0x1b, 0xcd, 0xd7, 0x60, 0x63, 0x9b, 0x7f, 0xca,
+ 0xfe, 0xaf, 0xfe, 0xc2, 0x03, 0xd4, 0x57, 0x8e, 0x6d, 0x66, 0xa8, 0xfb,
+ 0x72, 0xf2, 0x95, 0x47, 0xb2, 0xf2, 0xbb, 0xb1, 0x23, 0xa1, 0x1e, 0x43,
+ 0x6c, 0xa6, 0xf0, 0xf1, 0x30, 0x6e, 0x4a, 0x7a, 0x68, 0x07, 0x71, 0x54,
+ 0xd1, 0xb7, 0x3e, 0x37, 0xd1, 0x4c, 0x5f, 0x7b, 0xc8, 0xd2, 0x22, 0x81,
+ 0x8e, 0x09, 0x72, 0x9e, 0x2d, 0x13, 0xcb, 0xb0, 0x62, 0xd8, 0xb2, 0x3c,
+ 0x4b, 0x8d, 0xf0, 0x56, 0xc5, 0x0f, 0x17, 0x7d, 0xd0, 0x41, 0xbf, 0xda,
+ 0x7c, 0x28, 0xa0, 0xbd, 0x46, 0x3c, 0xed, 0x6c, 0x3e, 0x41, 0xfb, 0x30,
+ 0x2e, 0xb6, 0x11, 0x4b, 0x9d, 0x91, 0x00, 0xf3, 0x44, 0x0f, 0x6d, 0xdf,
+ 0x8b, 0x8b, 0x09, 0xf1, 0x2f, 0xbd, 0xeb, 0x9f, 0x98, 0x9b, 0x74, 0xd1,
+ 0x37, 0x7e, 0x9e, 0xa8, 0xa3, 0x0f, 0xb8, 0xf1, 0x46, 0xc2, 0xa0, 0xbf,
+ 0x79, 0xf0, 0x56, 0xa2, 0x89, 0x7d, 0x05, 0x59, 0xc6, 0x8f, 0x7b, 0x26,
+ 0xc2, 0xf4, 0xb3, 0x6b, 0x79, 0xc8, 0x73, 0x99, 0xf5, 0xf1, 0x6f, 0x2a,
+ 0xf5, 0x83, 0x73, 0xd5, 0x1a, 0x44, 0x6b, 0x35, 0x7c, 0x7e, 0xe2, 0x23,
+ 0xf8, 0x57, 0xc6, 0xed, 0x4d, 0x49, 0x70, 0x0e, 0x11, 0x22, 0x0f, 0x9c,
+ 0x3c, 0x22, 0xf7, 0x1c, 0xd1, 0x18, 0x6d, 0x70, 0xe8, 0xcc, 0x6d, 0xf5,
+ 0xdc, 0x79, 0x87, 0x93, 0x7d, 0x92, 0x15, 0xb3, 0xec, 0xcf, 0x07, 0xcb,
+ 0x71, 0xef, 0xa1, 0x13, 0xf4, 0x91, 0x12, 0x2c, 0x7a, 0xc0, 0x8d, 0xcf,
+ 0x1f, 0xc9, 0x90, 0x3b, 0xa8, 0x90, 0xfd, 0xbc, 0x69, 0x12, 0x85, 0x39,
+ 0xa3, 0x11, 0xdc, 0xb9, 0x3f, 0x83, 0xe1, 0x02, 0xcf, 0x0b, 0x85, 0xe2,
+ 0xff, 0x43, 0xc5, 0x09, 0xf2, 0x88, 0x40, 0xe7, 0xd5, 0xb4, 0xb1, 0xaa,
+ 0x48, 0x20, 0x2e, 0xe3, 0x6e, 0xa7, 0x8d, 0xf5, 0x71, 0x3e, 0x33, 0x1c,
+ 0x47, 0x82, 0x36, 0xf6, 0x55, 0xca, 0xbf, 0x87, 0x36, 0x16, 0xa7, 0x8d,
+ 0xc5, 0x69, 0x4f, 0x71, 0xda, 0x98, 0x3c, 0xfb, 0x1b, 0xa7, 0x8d, 0xc5,
+ 0x69, 0x63, 0xf1, 0xcc, 0x32, 0x1c, 0x25, 0xd3, 0xd8, 0x39, 0xd6, 0x4c,
+ 0x1c, 0x53, 0xec, 0xa8, 0x94, 0xbb, 0xf9, 0x23, 0xe4, 0xec, 0xd7, 0xf1,
+ 0x50, 0xd0, 0x46, 0x9f, 0xec, 0x4f, 0x67, 0xc8, 0x79, 0xdc, 0xf8, 0x75,
+ 0x56, 0x38, 0x7e, 0x33, 0xf3, 0xd8, 0x93, 0xe4, 0xf9, 0x2a, 0x9e, 0x30,
+ 0x25, 0x0f, 0x36, 0x79, 0xce, 0x58, 0x93, 0x12, 0xbe, 0x76, 0x12, 0x77,
+ 0x0f, 0x02, 0x37, 0x90, 0x17, 0xd6, 0x92, 0x97, 0x1c, 0x5e, 0xc4, 0xdf,
+ 0x07, 0x4f, 0xd0, 0xe6, 0x4f, 0xda, 0x7b, 0xbb, 0x54, 0xb6, 0x75, 0x66,
+ 0xb0, 0xde, 0x77, 0x3d, 0x7d, 0xf0, 0x7e, 0xd6, 0x75, 0x1e, 0x94, 0x3a,
+ 0x27, 0xd8, 0xb6, 0x1e, 0xfe, 0x35, 0xe7, 0xbf, 0xe3, 0x81, 0x5a, 0xbc,
+ 0xb1, 0x5f, 0x0f, 0xbf, 0x43, 0xcc, 0xab, 0x75, 0x58, 0xcb, 0xae, 0x0e,
+ 0x05, 0xb6, 0x5d, 0xad, 0xe6, 0xf9, 0x5e, 0xfb, 0x90, 0x13, 0xc7, 0x42,
+ 0xcb, 0xe0, 0x59, 0x54, 0xe4, 0x7c, 0xb4, 0xa5, 0x5a, 0xe1, 0x58, 0x7a,
+ 0xf8, 0x3c, 0xb9, 0x4a, 0x92, 0xed, 0x1f, 0xcd, 0x3c, 0x4e, 0x0c, 0xf9,
+ 0x22, 0x9e, 0x63, 0x7e, 0x3e, 0xf6, 0xa1, 0x97, 0xc9, 0x1d, 0xdd, 0x18,
+ 0x27, 0x07, 0x3c, 0x3e, 0x18, 0xfd, 0xa8, 0x93, 0xb8, 0xef, 0x59, 0x54,
+ 0x89, 0x4c, 0x5a, 0xb8, 0x62, 0x25, 0x9e, 0x19, 0x34, 0xb4, 0x1b, 0x94,
+ 0x3c, 0x2f, 0xcc, 0xef, 0xfd, 0x32, 0x2e, 0x8e, 0x22, 0x30, 0x79, 0x9e,
+ 0xdc, 0xf0, 0x9d, 0xb4, 0xc4, 0xb0, 0x93, 0xf4, 0x71, 0x3f, 0xc2, 0x49,
+ 0x0d, 0x27, 0xc6, 0x0d, 0x2c, 0x4c, 0x7a, 0xf1, 0xf0, 0x78, 0x10, 0x57,
+ 0xd3, 0x77, 0xb3, 0xe4, 0x87, 0x1f, 0x4a, 0x8a, 0x2f, 0xd6, 0x61, 0x62,
+ 0xbc, 0x8e, 0x3e, 0x22, 0xbc, 0xfc, 0x67, 0xf0, 0xd4, 0x9e, 0xb5, 0xf7,
+ 0x36, 0x8f, 0xa6, 0xf4, 0xfe, 0x18, 0xc7, 0x13, 0xf3, 0xea, 0xc7, 0x62,
+ 0xd0, 0xd3, 0xc0, 0x87, 0xdf, 0x4d, 0x7f, 0x52, 0xe2, 0xa3, 0xf8, 0xa3,
+ 0x86, 0x09, 0xf2, 0x9d, 0x52, 0x62, 0x6a, 0x79, 0xa4, 0xfe, 0xc2, 0xf7,
+ 0x15, 0x3d, 0xf7, 0x94, 0x6a, 0x59, 0xdf, 0x5b, 0xac, 0xc1, 0x77, 0x44,
+ 0x23, 0xf7, 0x30, 0xed, 0xe7, 0x62, 0xe4, 0x79, 0xf3, 0xd9, 0xfb, 0x6a,
+ 0x31, 0x63, 0x5f, 0x12, 0xff, 0xad, 0x36, 0xfe, 0xd1, 0x59, 0x8c, 0xf3,
+ 0xb3, 0x64, 0x7f, 0x76, 0xf2, 0xf4, 0x6c, 0xb9, 0x57, 0x34, 0xa9, 0x36,
+ 0x76, 0x1c, 0x83, 0x7e, 0xec, 0x15, 0x45, 0xf7, 0x7d, 0x95, 0xb1, 0xc1,
+ 0x45, 0x1b, 0x75, 0x4c, 0x68, 0xf4, 0xdd, 0xc6, 0x13, 0x33, 0x60, 0xc4,
+ 0xaf, 0x51, 0x5d, 0x16, 0x6c, 0x79, 0x6e, 0xa8, 0xca, 0xe7, 0x45, 0x82,
+ 0x3b, 0x12, 0x17, 0xc8, 0x17, 0x89, 0xc1, 0x9d, 0xf4, 0x97, 0x35, 0x76,
+ 0x2c, 0x3a, 0x61, 0xef, 0xfd, 0xde, 0x3a, 0x11, 0xa7, 0x8f, 0x2c, 0x43,
+ 0xc5, 0xb0, 0x07, 0x9f, 0xb3, 0xe3, 0xd0, 0x43, 0x56, 0x0d, 0xfd, 0xe5,
+ 0xae, 0x43, 0x81, 0xce, 0xeb, 0xe9, 0x2f, 0xf5, 0x4b, 0x25, 0x86, 0x31,
+ 0x6e, 0xa7, 0x0c, 0x73, 0x94, 0xd8, 0xf2, 0x50, 0xb3, 0x31, 0xf9, 0x32,
+ 0xf2, 0x3e, 0xb3, 0x6b, 0xa0, 0x16, 0x7f, 0xff, 0xc0, 0x71, 0x7b, 0x2d,
+ 0xe4, 0x4e, 0x9e, 0x27, 0x07, 0x7c, 0xb6, 0x7f, 0xc4, 0xf8, 0xfb, 0x1e,
+ 0xc6, 0xbc, 0x18, 0xfd, 0x68, 0xe7, 0x80, 0xb5, 0xec, 0xf9, 0xc5, 0xf1,
+ 0xb5, 0x55, 0x08, 0x32, 0x26, 0xb9, 0xd1, 0x3f, 0xa0, 0x0f, 0x76, 0x30,
+ 0x06, 0x9d, 0x5d, 0x6c, 0x52, 0x16, 0x0f, 0x86, 0x06, 0x04, 0x53, 0x4f,
+ 0xdd, 0x52, 0x8b, 0xf8, 0xff, 0xd0, 0x38, 0xbe, 0xcf, 0xd9, 0xf7, 0x08,
+ 0xeb, 0xb0, 0xe9, 0xc8, 0x52, 0xca, 0xdc, 0x44, 0x1f, 0x64, 0x5e, 0xcd,
+ 0x7c, 0x67, 0xc3, 0x7e, 0xf1, 0x0b, 0xb4, 0x48, 0x9e, 0xd6, 0x6d, 0x06,
+ 0xcc, 0x57, 0xe9, 0x43, 0x25, 0xe4, 0x3a, 0x0f, 0xa6, 0xec, 0xe7, 0x73,
+ 0x72, 0x15, 0x46, 0x18, 0x8b, 0x69, 0xa3, 0x25, 0x86, 0x0f, 0x33, 0xc8,
+ 0xeb, 0x16, 0x72, 0x3e, 0xca, 0xb2, 0x1e, 0x80, 0x1c, 0x02, 0xc4, 0x27,
+ 0x1c, 0x25, 0x08, 0x1e, 0xf5, 0xf3, 0x98, 0xcf, 0x83, 0x8a, 0xc8, 0xaa,
+ 0x98, 0x79, 0x94, 0x75, 0x47, 0x33, 0xb6, 0x2d, 0xfe, 0x3d, 0xe7, 0x3d,
+ 0x41, 0x5b, 0xff, 0x04, 0xb1, 0x7e, 0x72, 0x2f, 0xd0, 0x7f, 0x30, 0x6f,
+ 0xdb, 0x29, 0xb6, 0xdf, 0x4e, 0xcc, 0xbb, 0x40, 0x9b, 0xed, 0xe3, 0x7c,
+ 0x0f, 0x8d, 0x18, 0xc1, 0x46, 0x35, 0xa0, 0x4d, 0x70, 0x9e, 0x7b, 0xc6,
+ 0x54, 0x0c, 0x0c, 0x2e, 0xc3, 0x28, 0xf3, 0xa0, 0xde, 0xb4, 0xf8, 0x88,
+ 0x94, 0x39, 0x89, 0x6e, 0xfa, 0xc8, 0x2f, 0x17, 0x2b, 0x88, 0x7d, 0x5c,
+ 0xf6, 0xbe, 0x3b, 0x99, 0xef, 0x7f, 0x11, 0x9b, 0x12, 0x8f, 0x5b, 0x95,
+ 0x86, 0xde, 0x9f, 0x56, 0x99, 0x67, 0xd1, 0x36, 0x7b, 0x98, 0x9f, 0x2c,
+ 0x67, 0x7e, 0xd2, 0x5b, 0xb0, 0xcb, 0x33, 0xb4, 0xc3, 0x01, 0xc6, 0xb1,
+ 0x97, 0xd3, 0xf9, 0xb8, 0xf7, 0x83, 0x21, 0x3f, 0x16, 0x5e, 0x53, 0x89,
+ 0xa7, 0x0f, 0xe6, 0x65, 0xdb, 0x4b, 0x9b, 0x7c, 0x8a, 0x7a, 0xbe, 0x83,
+ 0x7a, 0x7d, 0x29, 0x25, 0x18, 0x15, 0xc4, 0x33, 0xe4, 0xd1, 0x5b, 0xc8,
+ 0x05, 0xbe, 0x97, 0xca, 0xdb, 0xe4, 0xe7, 0x27, 0xd6, 0x68, 0xf9, 0xf8,
+ 0xe0, 0x85, 0xba, 0x4f, 0xf6, 0x00, 0x5a, 0xd6, 0x72, 0x33, 0xd7, 0x49,
+ 0x5e, 0xc3, 0xb6, 0x23, 0xe4, 0x46, 0x4e, 0xcc, 0x49, 0x46, 0xb0, 0x22,
+ 0x55, 0xdf, 0xd6, 0x20, 0x9b, 0x3d, 0xe6, 0xe4, 0x39, 0xa0, 0x2b, 0x29,
+ 0xef, 0x0e, 0xd0, 0x50, 0xc1, 0xdc, 0xe9, 0xaf, 0x0b, 0xef, 0x2b, 0xf8,
+ 0xc4, 0x9f, 0xc1, 0x1d, 0xd7, 0x50, 0xa6, 0x14, 0xb9, 0xe3, 0x54, 0xe1,
+ 0x7d, 0x05, 0x37, 0xdb, 0xef, 0x2b, 0x70, 0x63, 0xc6, 0x84, 0xd3, 0xf9,
+ 0xa9, 0x94, 0x07, 0xb3, 0x27, 0x2e, 0x71, 0x50, 0x77, 0x49, 0xa4, 0x15,
+ 0x4f, 0x26, 0x14, 0xcc, 0x32, 0xfe, 0x27, 0xbe, 0x6f, 0xaf, 0x09, 0xd4,
+ 0xda, 0x7b, 0xf6, 0x5d, 0x91, 0x28, 0x0e, 0x27, 0xf4, 0xb6, 0xc7, 0x78,
+ 0x5e, 0x46, 0x3c, 0xad, 0xda, 0xa7, 0xe0, 0xa9, 0x80, 0x17, 0xa5, 0x47,
+ 0x64, 0xaf, 0xbb, 0x65, 0x39, 0x17, 0xaf, 0xb2, 0x76, 0xac, 0x13, 0xfb,
+ 0xe6, 0x1c, 0x1e, 0x09, 0x54, 0x09, 0x06, 0x1e, 0x36, 0x65, 0xdd, 0xd2,
+ 0x40, 0x5f, 0xa2, 0x96, 0xfc, 0xba, 0xbe, 0xb3, 0x15, 0xf5, 0xe6, 0xcf,
+ 0x1c, 0xb5, 0x28, 0x39, 0x72, 0x87, 0x26, 0x6b, 0xf6, 0xdf, 0xe0, 0x9c,
+ 0xf5, 0x12, 0xbb, 0x7a, 0x52, 0xf9, 0xf8, 0xd9, 0x9a, 0xb1, 0xaa, 0x45,
+ 0x2f, 0xbd, 0xe4, 0x27, 0x6a, 0xf2, 0xa2, 0x5d, 0xa6, 0x22, 0x92, 0x23,
+ 0xfe, 0xd4, 0xe1, 0x04, 0xf9, 0x82, 0xc4, 0xd2, 0x0a, 0x1e, 0x95, 0xe4,
+ 0x8d, 0x3f, 0x67, 0x2c, 0xbd, 0x27, 0x94, 0x0b, 0xca, 0x9b, 0x2c, 0x6a,
+ 0xc8, 0xc5, 0xe9, 0x03, 0x38, 0x12, 0xd2, 0xdb, 0x37, 0x38, 0xa2, 0x4f,
+ 0x33, 0x07, 0x0b, 0x2f, 0x63, 0x4e, 0xbe, 0x2a, 0x90, 0xc1, 0x2e, 0xf2,
+ 0xc0, 0x9d, 0xcc, 0xc5, 0x3b, 0x68, 0x9b, 0x9d, 0xfb, 0x19, 0xdb, 0x1c,
+ 0x97, 0x73, 0x71, 0x2d, 0x14, 0xdf, 0x40, 0x0e, 0xd0, 0xe5, 0x51, 0xc5,
+ 0x5e, 0xc5, 0x77, 0x02, 0x1d, 0xaf, 0x12, 0xa3, 0x1b, 0x19, 0x37, 0xc4,
+ 0xde, 0xf7, 0xa4, 0xf4, 0x4e, 0x2a, 0xa0, 0xa6, 0x92, 0xb9, 0xe3, 0xbd,
+ 0xe3, 0xcd, 0xf4, 0x9b, 0xfc, 0x33, 0x73, 0xce, 0x25, 0x75, 0xcc, 0x39,
+ 0xaf, 0x43, 0xef, 0x10, 0xed, 0x9f, 0xbe, 0x74, 0xff, 0x00, 0xc8, 0xcf,
+ 0xd4, 0x9d, 0x9c, 0xbf, 0xdc, 0x11, 0x04, 0x2e, 0xb6, 0xa3, 0xb1, 0xad,
+ 0xc4, 0x21, 0x32, 0xe8, 0xed, 0x6f, 0x90, 0xa7, 0x75, 0x31, 0x3f, 0xdd,
+ 0xc2, 0x5c, 0x3e, 0xc6, 0x5c, 0x3e, 0xc6, 0x7a, 0xa9, 0x21, 0xb9, 0x4f,
+ 0x64, 0xb4, 0x9f, 0x61, 0xfe, 0xf3, 0x39, 0xf2, 0x9f, 0xa1, 0x07, 0x44,
+ 0xae, 0x59, 0xb8, 0xf7, 0xf0, 0x75, 0x48, 0xd2, 0x9e, 0xee, 0xe1, 0xb5,
+ 0x81, 0x07, 0xe6, 0xe3, 0x6e, 0xe6, 0xf1, 0xb1, 0xf1, 0x65, 0x18, 0x64,
+ 0x26, 0xba, 0xed, 0xf0, 0x47, 0xd0, 0x43, 0x3e, 0xb5, 0x9c, 0x18, 0xbd,
+ 0xe1, 0x60, 0xc6, 0xc6, 0x6c, 0xc1, 0xfc, 0x1f, 0x67, 0x80, 0xd7, 0xc8,
+ 0xc9, 0x06, 0x53, 0x27, 0x6c, 0x9e, 0xe6, 0x62, 0x7c, 0x28, 0x25, 0x2e,
+ 0x85, 0xf7, 0x1b, 0x5d, 0x2b, 0x55, 0x6b, 0x59, 0xd9, 0xe2, 0x40, 0xff,
+ 0x1b, 0xf4, 0xd5, 0x9a, 0x23, 0x2a, 0x6a, 0x87, 0x25, 0x57, 0x27, 0x3f,
+ 0x22, 0x46, 0x3f, 0x47, 0x8c, 0xae, 0x3c, 0x94, 0xcf, 0xcb, 0x13, 0xcc,
+ 0xbb, 0x6a, 0x8d, 0x7c, 0x6e, 0xbe, 0x67, 0x40, 0xf6, 0xe8, 0xb8, 0xf1,
+ 0x1d, 0xda, 0xfe, 0xa9, 0x82, 0xed, 0x9f, 0x2e, 0x60, 0xb0, 0xc5, 0xdc,
+ 0xfc, 0x35, 0x1b, 0x7f, 0xf3, 0xb9, 0xf9, 0xc2, 0x61, 0xa3, 0x2b, 0x4c,
+ 0x8c, 0xbe, 0xfa, 0x90, 0xf4, 0xaf, 0xa1, 0x96, 0x78, 0x32, 0x93, 0x58,
+ 0x52, 0x35, 0x2c, 0xeb, 0x33, 0x81, 0xce, 0x09, 0xd5, 0x67, 0xf7, 0xb1,
+ 0x9d, 0xb2, 0xf5, 0xd2, 0x07, 0xbe, 0x9a, 0x30, 0xb4, 0xad, 0x4a, 0xc0,
+ 0x5c, 0x4d, 0x7d, 0x1e, 0xc9, 0x5c, 0x87, 0xce, 0xc1, 0x3a, 0x1c, 0x4b,
+ 0x4b, 0x7c, 0x91, 0xf6, 0x25, 0x17, 0x77, 0xe2, 0x9d, 0xfd, 0x73, 0xf1,
+ 0xce, 0xd8, 0xe5, 0x3c, 0x7c, 0x47, 0x2a, 0x7a, 0x3f, 0xc3, 0xeb, 0x2a,
+ 0xc9, 0xc3, 0xbf, 0xc7, 0x3c, 0xfc, 0x0d, 0x45, 0xd6, 0x10, 0x55, 0x7c,
+ 0x62, 0x91, 0x83, 0xf1, 0x45, 0xf7, 0x7f, 0xd7, 0x11, 0x97, 0xfb, 0xc8,
+ 0xfe, 0x07, 0xf8, 0xff, 0xb3, 0x8c, 0xe7, 0xc3, 0x9c, 0x89, 0x68, 0xad,
+ 0x03, 0x4f, 0x2f, 0x8e, 0x47, 0x65, 0x9d, 0xb4, 0x9f, 0x3c, 0x65, 0x0e,
+ 0xe3, 0xe1, 0xdf, 0xa7, 0xea, 0xc3, 0x0b, 0x1d, 0x0e, 0x5c, 0x34, 0xf5,
+ 0xf6, 0x03, 0xbc, 0xf6, 0x4c, 0x56, 0x7c, 0x31, 0x4c, 0xfc, 0x5a, 0x59,
+ 0xf0, 0xc5, 0x5a, 0x94, 0xd3, 0xce, 0xe7, 0xd2, 0x5e, 0x7f, 0x9c, 0xd2,
+ 0x07, 0x9f, 0xa1, 0x9d, 0xd6, 0x5e, 0xb2, 0x53, 0x59, 0xa3, 0x95, 0xbc,
+ 0xa6, 0x9d, 0x79, 0xcd, 0xf4, 0xe7, 0xa5, 0x8f, 0xa3, 0x2f, 0x7b, 0x1f,
+ 0xee, 0xdd, 0xab, 0x77, 0x39, 0x1d, 0x71, 0x4b, 0x33, 0xba, 0x99, 0xa3,
+ 0x75, 0x23, 0xb0, 0xc8, 0xe8, 0xb8, 0xa0, 0xe8, 0x9d, 0x3f, 0x54, 0xca,
+ 0x99, 0xf3, 0x9d, 0xc1, 0xf6, 0x51, 0x3d, 0x98, 0x51, 0x0c, 0xdc, 0x40,
+ 0x8c, 0x7b, 0x78, 0xa4, 0x84, 0x76, 0xb8, 0x1e, 0x47, 0x06, 0xf5, 0x70,
+ 0x1c, 0x26, 0x31, 0xb4, 0xde, 0x5f, 0xa6, 0x5c, 0xc0, 0x69, 0xf3, 0x2c,
+ 0xb6, 0x67, 0xe7, 0x60, 0xbd, 0x26, 0x7b, 0x9a, 0xd6, 0x63, 0x62, 0xf0,
+ 0x02, 0x71, 0xa8, 0x9d, 0xdc, 0x4a, 0xf2, 0x06, 0x0b, 0x7b, 0x42, 0x57,
+ 0x63, 0x8b, 0xed, 0xbf, 0xa5, 0xf2, 0x4e, 0x0b, 0xcf, 0x3c, 0xc3, 0x20,
+ 0x4e, 0x48, 0x6e, 0xee, 0x9b, 0xb6, 0x3f, 0x57, 0xd6, 0x75, 0x1b, 0xab,
+ 0xf2, 0xf7, 0x95, 0xff, 0x58, 0x99, 0x29, 0x1c, 0x1a, 0x91, 0xf5, 0x85,
+ 0x19, 0xca, 0xe3, 0x83, 0x0d, 0xbe, 0x1e, 0xc6, 0x8f, 0xfb, 0xcd, 0x1c,
+ 0x5e, 0x5f, 0x5c, 0x86, 0x29, 0xaf, 0x82, 0xd0, 0xd5, 0x61, 0xe9, 0x83,
+ 0x9f, 0x73, 0x96, 0xff, 0x93, 0xd2, 0xce, 0x82, 0xc2, 0x9a, 0xc3, 0x3b,
+ 0x35, 0x8c, 0x55, 0x3c, 0x97, 0xe7, 0x03, 0xe5, 0xbc, 0x78, 0xfd, 0x47,
+ 0x56, 0xd4, 0x2b, 0xd7, 0x89, 0xd9, 0xb3, 0xc4, 0x7f, 0x67, 0x28, 0x77,
+ 0x12, 0x6f, 0xe7, 0x87, 0x66, 0x28, 0xeb, 0xd3, 0xc5, 0x3a, 0x2f, 0x22,
+ 0x3b, 0xf2, 0x22, 0xe7, 0x53, 0x0f, 0x4e, 0xc1, 0x55, 0x78, 0x56, 0x5e,
+ 0xf6, 0x81, 0xb9, 0xc8, 0x43, 0x65, 0x2d, 0xfe, 0x1c, 0x86, 0xf6, 0x0b,
+ 0x6f, 0xb4, 0xac, 0x40, 0xc3, 0x39, 0x6c, 0x3f, 0x7a, 0x42, 0xe9, 0x48,
+ 0xbd, 0x6b, 0xa1, 0x74, 0x46, 0x6c, 0x8e, 0xbd, 0xdf, 0x59, 0xda, 0xe8,
+ 0x53, 0xda, 0xb3, 0x81, 0xf0, 0xfd, 0x0c, 0xbe, 0x5a, 0x44, 0x9e, 0x63,
+ 0x97, 0xb1, 0x9d, 0xe0, 0x35, 0xc3, 0x7e, 0x66, 0xe8, 0xb8, 0x3d, 0xce,
+ 0xf7, 0xeb, 0xe1, 0x9b, 0x56, 0xb4, 0x5d, 0xea, 0x16, 0xe5, 0x9a, 0xcf,
+ 0x89, 0x16, 0xd9, 0x8a, 0xff, 0x8f, 0x17, 0x64, 0x2f, 0x25, 0x77, 0xce,
+ 0x97, 0xe9, 0xa4, 0xec, 0x25, 0xa1, 0x28, 0x4e, 0x35, 0x4f, 0x97, 0xbf,
+ 0x38, 0xd6, 0x83, 0xef, 0x69, 0x2f, 0x5f, 0xf6, 0xe3, 0xb5, 0xb2, 0x4f,
+ 0xea, 0x54, 0xf3, 0x24, 0xfe, 0xce, 0x5e, 0xd7, 0x78, 0xd3, 0xde, 0xdf,
+ 0xb9, 0xcb, 0x6c, 0x89, 0x96, 0xe1, 0xa3, 0x50, 0xaf, 0x8a, 0x2f, 0x2c,
+ 0xb3, 0xf9, 0x76, 0xb4, 0xbd, 0x8c, 0x39, 0xb7, 0xdb, 0x88, 0xde, 0xef,
+ 0x46, 0x2e, 0x47, 0x9e, 0xd0, 0x71, 0x51, 0x39, 0xa6, 0xdc, 0x11, 0xd0,
+ 0xb7, 0xbd, 0x4d, 0xfe, 0xf3, 0x6c, 0x20, 0xce, 0x39, 0x37, 0x7c, 0x03,
+ 0x8a, 0x6e, 0x6e, 0x62, 0x8c, 0x7d, 0x86, 0x39, 0xed, 0xc6, 0x40, 0xbf,
+ 0x7d, 0xcf, 0x53, 0x89, 0xac, 0xc1, 0x95, 0xf6, 0xfb, 0x26, 0xda, 0x61,
+ 0x64, 0x5e, 0x94, 0x35, 0x38, 0xfe, 0x8e, 0x61, 0xa1, 0x7d, 0x6d, 0x23,
+ 0x82, 0xf6, 0xf7, 0xba, 0xc2, 0x3b, 0x29, 0x3a, 0x50, 0x6f, 0x7f, 0x7f,
+ 0x1a, 0x0d, 0x99, 0x4b, 0x6b, 0xd5, 0xe8, 0x35, 0x2d, 0xeb, 0x49, 0x53,
+ 0x9e, 0x57, 0xbb, 0xb4, 0xb7, 0x7c, 0x8d, 0x83, 0x39, 0x10, 0x21, 0x25,
+ 0x96, 0x7f, 0x27, 0xcf, 0xe5, 0xe7, 0xc5, 0x56, 0xbc, 0x67, 0x6f, 0xb9,
+ 0xfd, 0xac, 0x93, 0xfd, 0xce, 0xa5, 0x05, 0x4b, 0x9c, 0xf8, 0x4e, 0xa2,
+ 0x2a, 0xe6, 0xe1, 0xef, 0xed, 0x4b, 0x4a, 0xb0, 0x25, 0x44, 0x0e, 0x7a,
+ 0xd5, 0x19, 0x9c, 0xcf, 0x38, 0x71, 0x26, 0x11, 0x0f, 0x8d, 0xb1, 0xbf,
+ 0x53, 0x09, 0x15, 0xa7, 0x47, 0xfa, 0x42, 0x87, 0xec, 0xbe, 0x5f, 0x45,
+ 0xef, 0x51, 0xb9, 0x0f, 0xd9, 0x8e, 0x0d, 0x89, 0xf3, 0x8c, 0xbb, 0xd2,
+ 0x96, 0xac, 0x05, 0xe8, 0xb9, 0x8d, 0xcc, 0x9f, 0x55, 0x47, 0x10, 0xb7,
+ 0x30, 0xde, 0x3d, 0x97, 0xe8, 0x86, 0x6b, 0xb1, 0xde, 0xf5, 0x2d, 0x72,
+ 0x96, 0xaa, 0x88, 0x1e, 0x7c, 0x4b, 0xe9, 0x20, 0x37, 0x74, 0x63, 0x32,
+ 0x21, 0x7e, 0x21, 0xef, 0xac, 0xf9, 0x34, 0x8e, 0x91, 0x23, 0x3f, 0x9b,
+ 0xd0, 0x70, 0xbe, 0xd9, 0x83, 0x0c, 0x39, 0xf3, 0x77, 0x12, 0x6e, 0x7c,
+ 0x95, 0x9c, 0xf9, 0x91, 0x11, 0x59, 0xb3, 0x6c, 0x45, 0x4b, 0x42, 0xd6,
+ 0xab, 0xc9, 0x03, 0xc7, 0xbc, 0xb4, 0x6d, 0xcb, 0xea, 0x35, 0x67, 0xd3,
+ 0x9f, 0xce, 0xb2, 0x4f, 0x59, 0xe7, 0x8c, 0x62, 0x35, 0x79, 0xd0, 0x23,
+ 0x63, 0x3e, 0x3c, 0xcf, 0x5c, 0x21, 0xc9, 0x7a, 0xcf, 0x25, 0xfc, 0x18,
+ 0xc8, 0xf8, 0xf0, 0x14, 0x73, 0x86, 0x9d, 0x3c, 0x97, 0xf7, 0x1f, 0x95,
+ 0x18, 0x41, 0xf2, 0xf2, 0x93, 0xa8, 0x18, 0xb8, 0x02, 0x9b, 0xd7, 0x3e,
+ 0x0a, 0x75, 0xe0, 0x04, 0x8f, 0x6b, 0xc9, 0x21, 0xae, 0x45, 0x6a, 0x24,
+ 0x82, 0xd4, 0xd8, 0x8b, 0xe8, 0x1f, 0x91, 0x71, 0xc9, 0x7b, 0x6c, 0x64,
+ 0x0f, 0x12, 0xb9, 0xe7, 0x80, 0x17, 0xe9, 0x31, 0xe9, 0xa7, 0x96, 0x7d,
+ 0xff, 0xb9, 0xed, 0xff, 0xab, 0xb5, 0xf9, 0x13, 0xd2, 0xf6, 0xa3, 0x7f,
+ 0xa4, 0x7d, 0xd1, 0x95, 0xac, 0xbd, 0xb4, 0x17, 0xd6, 0x5e, 0xdc, 0x6c,
+ 0xd3, 0x03, 0x47, 0x24, 0xb7, 0xb6, 0x12, 0x7a, 0x74, 0xb7, 0x62, 0xb4,
+ 0x55, 0x28, 0xe7, 0xb1, 0x3b, 0x2b, 0xef, 0x45, 0x28, 0xc5, 0x53, 0xc4,
+ 0x6b, 0x57, 0x48, 0xd7, 0xbe, 0x45, 0xdb, 0x59, 0x4e, 0x8c, 0x7b, 0xd5,
+ 0xbc, 0x1a, 0x71, 0x4d, 0xf4, 0x57, 0x8a, 0x17, 0x06, 0xdd, 0xc4, 0xa6,
+ 0x08, 0xf2, 0xcf, 0xc8, 0x79, 0xf0, 0x83, 0x84, 0x97, 0xf3, 0xd5, 0x98,
+ 0x33, 0x1c, 0x0d, 0xf2, 0x0c, 0x9e, 0x7d, 0xed, 0x54, 0x62, 0x23, 0x0e,
+ 0x51, 0xde, 0xe7, 0x12, 0x17, 0x39, 0x3f, 0x9d, 0xd4, 0xbf, 0xe8, 0x3b,
+ 0x5e, 0xd0, 0x75, 0x1f, 0x75, 0x5d, 0x87, 0x67, 0x12, 0x5f, 0xc4, 0x23,
+ 0x94, 0xff, 0xe1, 0x41, 0x23, 0x3a, 0x5f, 0x39, 0x49, 0xfc, 0x2e, 0xc5,
+ 0x69, 0xb6, 0x7d, 0x07, 0x33, 0xf7, 0x29, 0xe9, 0x2b, 0x25, 0xeb, 0xa5,
+ 0x0a, 0xde, 0x5a, 0x72, 0x12, 0x13, 0xfc, 0xef, 0x07, 0x83, 0xf2, 0x1c,
+ 0x5a, 0x35, 0xfb, 0x10, 0xfd, 0xf8, 0xed, 0xdc, 0xa4, 0x87, 0xbc, 0x6b,
+ 0x55, 0xf3, 0x49, 0xec, 0x4a, 0xcb, 0xb5, 0xf5, 0xe8, 0x1f, 0xbc, 0x00,
+ 0x47, 0xa8, 0x04, 0x77, 0x78, 0x9b, 0x69, 0xeb, 0x39, 0xec, 0xce, 0x34,
+ 0xcf, 0xc8, 0x73, 0xe2, 0xaa, 0x19, 0xf2, 0x4c, 0xd6, 0xa9, 0x44, 0x29,
+ 0xbe, 0xc3, 0x3a, 0x9b, 0x89, 0x15, 0xf9, 0x7b, 0x38, 0xe4, 0xfe, 0xc4,
+ 0xfa, 0x0c, 0xfb, 0x48, 0xd8, 0x6d, 0xcc, 0x50, 0x0e, 0xd0, 0x0f, 0xab,
+ 0x17, 0xcf, 0x50, 0x52, 0x69, 0xc9, 0x35, 0x5e, 0xc4, 0x13, 0x0f, 0xe4,
+ 0x75, 0x78, 0xc8, 0xdc, 0x88, 0x74, 0xa6, 0xba, 0xd0, 0xde, 0x4b, 0x85,
+ 0x7b, 0x6d, 0xf2, 0x3c, 0x88, 0x51, 0x78, 0x17, 0xc0, 0xe5, 0x7b, 0x6c,
+ 0xdf, 0xc8, 0x56, 0x91, 0xcf, 0x97, 0xd3, 0xd6, 0x4a, 0x62, 0x5e, 0xc6,
+ 0xf9, 0x8d, 0x8b, 0x34, 0xec, 0x5d, 0xfa, 0xd9, 0x5a, 0x54, 0x69, 0xce,
+ 0x5f, 0x35, 0xbf, 0xc8, 0x7e, 0xaa, 0x62, 0x35, 0x91, 0x47, 0xec, 0x7d,
+ 0x59, 0xa1, 0xa5, 0x33, 0x19, 0xe7, 0xe4, 0x5e, 0x75, 0x0c, 0xaf, 0x27,
+ 0x6a, 0x63, 0xb5, 0x91, 0x6a, 0xe6, 0xf6, 0x17, 0x30, 0x30, 0xea, 0x44,
+ 0x15, 0x79, 0x7c, 0x65, 0xb2, 0x16, 0x6e, 0x7b, 0x5d, 0xf1, 0x0a, 0xf2,
+ 0xa7, 0xb9, 0xe4, 0x48, 0x75, 0xa8, 0x26, 0x4f, 0xf2, 0x84, 0x2c, 0xeb,
+ 0xa7, 0x8b, 0x2d, 0xeb, 0x4a, 0x1e, 0x65, 0x3c, 0xce, 0x85, 0xc4, 0x4f,
+ 0xa3, 0x68, 0xb4, 0xfd, 0xd5, 0x40, 0x93, 0xfd, 0xdd, 0x4a, 0x5f, 0xef,
+ 0x0a, 0x2d, 0x9c, 0xf8, 0x62, 0xa8, 0x61, 0x62, 0x26, 0xd4, 0xe1, 0x59,
+ 0x70, 0xb0, 0xad, 0x8f, 0x2f, 0xb5, 0xd0, 0x6a, 0xca, 0xfb, 0x04, 0x84,
+ 0xa7, 0x6d, 0x24, 0x4f, 0xeb, 0x0f, 0x19, 0x13, 0x8f, 0xe2, 0x7a, 0xc6,
+ 0x5d, 0xf7, 0xb0, 0x8f, 0xfd, 0x48, 0xce, 0xef, 0xcc, 0xcd, 0x23, 0xff,
+ 0xbf, 0x7a, 0xb1, 0x70, 0xb6, 0x0e, 0x79, 0x97, 0x08, 0x3a, 0x26, 0x4e,
+ 0xe2, 0x26, 0x96, 0xf1, 0x0c, 0xbf, 0x84, 0x64, 0xf6, 0x47, 0x18, 0xc8,
+ 0x4a, 0x3c, 0xc9, 0xe1, 0x06, 0xb6, 0x5d, 0x3e, 0xdc, 0x46, 0xae, 0xba,
+ 0x06, 0x9b, 0x27, 0x2c, 0xac, 0x0a, 0x4d, 0x62, 0xd5, 0x04, 0x39, 0xf0,
+ 0x44, 0xd1, 0x5f, 0x85, 0xbf, 0xad, 0x81, 0x3c, 0x7f, 0xe6, 0x26, 0xb6,
+ 0xc8, 0xda, 0x9e, 0x4a, 0x3f, 0x6c, 0xa1, 0x7d, 0x3f, 0x9e, 0x8a, 0x63,
+ 0xc3, 0x84, 0x60, 0xee, 0x7d, 0xe8, 0x9d, 0x90, 0xb5, 0xe2, 0xaf, 0x84,
+ 0xe6, 0x4f, 0xfc, 0x08, 0x2d, 0x13, 0xe9, 0xd0, 0x82, 0x89, 0x31, 0xca,
+ 0x9d, 0xa0, 0x6c, 0x83, 0xa1, 0xfa, 0x89, 0x91, 0x50, 0x70, 0xe2, 0x40,
+ 0x28, 0x30, 0xd1, 0x8e, 0x9d, 0x13, 0xeb, 0xb0, 0x63, 0x62, 0x1b, 0xb6,
+ 0x4f, 0x08, 0x6e, 0x4f, 0x61, 0xe5, 0xc4, 0xab, 0x58, 0x31, 0xf1, 0x2c,
+ 0x5a, 0x27, 0xce, 0x62, 0xf9, 0xc4, 0x8b, 0x68, 0x9b, 0x78, 0x89, 0x63,
+ 0x91, 0xb5, 0x67, 0x59, 0x77, 0x2e, 0xde, 0xe7, 0x9b, 0xbe, 0x97, 0x5a,
+ 0xd6, 0x56, 0xe4, 0x59, 0x30, 0x99, 0x43, 0x17, 0xd6, 0x6a, 0xe7, 0xd0,
+ 0xb7, 0x5f, 0xde, 0xb5, 0xd6, 0xa8, 0xf5, 0x42, 0xee, 0xe1, 0xbe, 0x28,
+ 0xcf, 0x06, 0xd0, 0xc6, 0xa6, 0xef, 0x1b, 0xd6, 0xb5, 0xa9, 0x4b, 0xf7,
+ 0x3c, 0xe5, 0x99, 0x2c, 0x89, 0x3d, 0xe7, 0xd1, 0x93, 0xfd, 0x8d, 0x15,
+ 0xd5, 0xa4, 0xac, 0x3c, 0x2b, 0x26, 0xf6, 0x70, 0x0e, 0x0f, 0xed, 0x3f,
+ 0x4f, 0x0e, 0x35, 0x69, 0xaf, 0x1d, 0xbd, 0xbd, 0x40, 0xde, 0xd3, 0xe3,
+ 0x27, 0x36, 0x9d, 0x43, 0xea, 0x28, 0x30, 0x71, 0x50, 0xfc, 0x70, 0x23,
+ 0xfd, 0x70, 0x52, 0x7c, 0x32, 0x4e, 0x4c, 0xbe, 0xcd, 0x83, 0xfb, 0xc8,
+ 0x93, 0x4a, 0x90, 0x1b, 0x2b, 0xc7, 0xd3, 0x23, 0x71, 0x6b, 0x9e, 0x21,
+ 0xef, 0x2e, 0x31, 0x72, 0x57, 0x32, 0xee, 0xbf, 0xc4, 0x6b, 0x93, 0x83,
+ 0xf0, 0xfb, 0x8c, 0x80, 0x6f, 0x1e, 0xcf, 0x4f, 0xa7, 0x27, 0xc9, 0x71,
+ 0xba, 0x30, 0xc5, 0x6f, 0xc9, 0x89, 0x81, 0x5e, 0xa4, 0xd3, 0xa2, 0xcf,
+ 0x76, 0xea, 0x53, 0x70, 0x51, 0xef, 0x6a, 0x25, 0x1e, 0x5a, 0x8a, 0xe0,
+ 0xa1, 0x8a, 0x8a, 0x7d, 0xc2, 0x25, 0xec, 0x77, 0x9f, 0x98, 0x03, 0xca,
+ 0x8b, 0xf8, 0x0e, 0x73, 0x98, 0xf2, 0x7d, 0xe4, 0x43, 0xc4, 0xca, 0xaa,
+ 0x88, 0x62, 0xac, 0x0a, 0x9c, 0xc3, 0xd3, 0x63, 0x4e, 0xb8, 0x93, 0x4e,
+ 0x4c, 0x12, 0x27, 0x1d, 0x49, 0xd9, 0x3f, 0xa0, 0x51, 0x16, 0x59, 0xa7,
+ 0x3a, 0x8b, 0x9c, 0x7d, 0x7f, 0x4f, 0xee, 0xcf, 0x7c, 0xd7, 0xee, 0xc7,
+ 0x49, 0xd9, 0xfb, 0x88, 0xa5, 0x3d, 0xa9, 0xef, 0xa1, 0x35, 0xed, 0xb1,
+ 0x9f, 0xf3, 0xdb, 0x9d, 0x7a, 0x15, 0xa9, 0xfd, 0x75, 0xb8, 0xdd, 0x7e,
+ 0xd6, 0xcf, 0x84, 0x46, 0xbd, 0xdd, 0x32, 0x6e, 0x22, 0x7a, 0x78, 0x1d,
+ 0xd6, 0x1e, 0xfe, 0x24, 0x8f, 0x59, 0xb8, 0xe9, 0x70, 0x27, 0x6e, 0x1c,
+ 0x8f, 0xa3, 0x63, 0xbc, 0x8f, 0xc7, 0x7a, 0x7c, 0x6c, 0xa8, 0x1a, 0x99,
+ 0x90, 0xc6, 0x1c, 0x7f, 0x3d, 0x73, 0x7c, 0xe1, 0x67, 0x1b, 0xf0, 0x34,
+ 0x71, 0x27, 0x18, 0xda, 0x80, 0x49, 0xdb, 0x17, 0x65, 0x8f, 0xe5, 0x06,
+ 0x6c, 0x67, 0xfe, 0x3e, 0x8a, 0x0d, 0xe8, 0xe1, 0xb5, 0x21, 0x7b, 0x0e,
+ 0x4e, 0x62, 0x19, 0xf3, 0xb3, 0x77, 0xae, 0x39, 0x89, 0x0f, 0x1f, 0x92,
+ 0xbe, 0x2f, 0x20, 0xb5, 0x77, 0x23, 0xdb, 0xcc, 0xa1, 0x7d, 0xfc, 0x9f,
+ 0x71, 0xe3, 0x10, 0xee, 0xac, 0x46, 0x35, 0x9e, 0x0d, 0x05, 0x3a, 0x06,
+ 0x94, 0x7f, 0xb6, 0xdb, 0xde, 0x9e, 0xfa, 0x11, 0x76, 0xa5, 0xce, 0xe3,
+ 0xe1, 0xcc, 0x4b, 0xe8, 0x4f, 0x4d, 0x9f, 0x53, 0x99, 0xcb, 0x37, 0x19,
+ 0x0f, 0xbe, 0x8f, 0x23, 0x63, 0x53, 0xc4, 0xde, 0x57, 0x78, 0xbc, 0xff,
+ 0x7e, 0x7a, 0xfe, 0x39, 0xdc, 0xbc, 0xdd, 0x48, 0x3e, 0x55, 0xe4, 0x6f,
+ 0x71, 0xab, 0xda, 0xc8, 0xed, 0x9a, 0x03, 0x7d, 0x5b, 0x58, 0x95, 0xfb,
+ 0x81, 0x46, 0xec, 0x05, 0x45, 0x6f, 0xff, 0x96, 0xe2, 0x61, 0xae, 0x21,
+ 0xcf, 0x45, 0xea, 0xd1, 0x1b, 0xa8, 0xef, 0xb2, 0x07, 0xbe, 0x0f, 0xe7,
+ 0x03, 0x4e, 0x94, 0x26, 0x65, 0x2d, 0x47, 0xde, 0x2b, 0x23, 0xef, 0x30,
+ 0xc9, 0xe9, 0xa5, 0xf2, 0xae, 0x89, 0xe4, 0x24, 0x63, 0x7f, 0x6e, 0x61,
+ 0x09, 0xe4, 0x39, 0xec, 0xeb, 0xb0, 0x71, 0x30, 0x8a, 0x1e, 0x53, 0x9e,
+ 0x31, 0xca, 0x8f, 0x7f, 0x5e, 0xf3, 0xf7, 0xd1, 0xcb, 0xf8, 0xb3, 0x9e,
+ 0x98, 0x78, 0xbb, 0x7d, 0x6f, 0xf6, 0xfb, 0xe8, 0x1b, 0xf9, 0x47, 0xb7,
+ 0xf0, 0x9d, 0x3e, 0x53, 0x9e, 0xe3, 0xd6, 0xcd, 0xf7, 0xbe, 0xc3, 0x66,
+ 0xbe, 0xec, 0x69, 0xa3, 0x4d, 0xe4, 0x16, 0xba, 0xb0, 0xbd, 0x36, 0xff,
+ 0x1e, 0x95, 0x0f, 0x7a, 0xe7, 0xd0, 0x5f, 0xda, 0xef, 0x1c, 0x92, 0xfb,
+ 0xfa, 0xf2, 0xbe, 0xaa, 0x27, 0x12, 0xf2, 0x1e, 0x09, 0x75, 0x99, 0x0b,
+ 0xaa, 0xd7, 0x45, 0x5e, 0xf8, 0xaa, 0x39, 0x13, 0xbd, 0x5e, 0x0b, 0xd7,
+ 0x53, 0x96, 0x63, 0x4d, 0x1f, 0x63, 0xe6, 0x12, 0xef, 0x70, 0xd9, 0xef,
+ 0x26, 0x39, 0xff, 0xa9, 0x7f, 0xff, 0x6e, 0x92, 0x37, 0x89, 0x93, 0x0a,
+ 0x2a, 0x8d, 0x5b, 0xf0, 0x9c, 0x1d, 0x13, 0x14, 0x54, 0x34, 0xc8, 0xba,
+ 0xa8, 0x1f, 0xcf, 0x18, 0x8d, 0xfe, 0x1a, 0xb9, 0xdf, 0xa5, 0x9c, 0xb3,
+ 0xe2, 0xde, 0x3a, 0xc6, 0x97, 0xff, 0x68, 0x2f, 0xfe, 0xf3, 0xd8, 0xb9,
+ 0x37, 0x4c, 0xce, 0xe8, 0x95, 0x67, 0x23, 0x67, 0x14, 0x9f, 0xc5, 0xdc,
+ 0x91, 0x92, 0x3d, 0xec, 0x0c, 0x8a, 0xe5, 0x6f, 0xd2, 0xcf, 0xde, 0x94,
+ 0x3d, 0x58, 0xe4, 0x3c, 0x7f, 0x85, 0x60, 0xcd, 0x8c, 0xfc, 0x73, 0x52,
+ 0xf6, 0x5e, 0x5f, 0x59, 0x0f, 0xd8, 0x5e, 0x78, 0xef, 0xa2, 0x94, 0x95,
+ 0x7a, 0x6f, 0xda, 0x6b, 0xc2, 0x2e, 0xe3, 0x37, 0xd6, 0x6b, 0xde, 0x5a,
+ 0x96, 0xfd, 0x45, 0xe1, 0xff, 0xf3, 0xe2, 0x33, 0x66, 0x14, 0x72, 0x4d,
+ 0xea, 0x88, 0xae, 0x2e, 0xd7, 0xe9, 0x4d, 0x39, 0x88, 0x7b, 0x67, 0xad,
+ 0x6e, 0xaf, 0x8c, 0x61, 0xec, 0x7d, 0x75, 0x54, 0xfb, 0x1d, 0x84, 0x79,
+ 0xfd, 0x8a, 0x3c, 0xff, 0xbe, 0x4f, 0x59, 0x3f, 0x2e, 0x31, 0x2a, 0x70,
+ 0xae, 0x26, 0xbf, 0xae, 0x73, 0x59, 0xc6, 0x47, 0xbc, 0xb2, 0xef, 0xaf,
+ 0xd4, 0x3e, 0xb7, 0xfb, 0x35, 0x2f, 0xd7, 0xfb, 0x46, 0x61, 0xbc, 0xb5,
+ 0xf6, 0xb3, 0x4a, 0x0f, 0xda, 0xbc, 0xc6, 0x31, 0x6d, 0xdc, 0xcb, 0xbc,
+ 0xef, 0xed, 0x67, 0xa4, 0xd0, 0xaf, 0x6a, 0x3f, 0xef, 0x75, 0xb9, 0x0f,
+ 0x91, 0xeb, 0xa9, 0x42, 0x1d, 0x3d, 0x1c, 0xb5, 0xfb, 0x57, 0x99, 0xbf,
+ 0x15, 0xfb, 0xa4, 0x3f, 0x2d, 0x2e, 0xb6, 0x31, 0x29, 0xf6, 0xd5, 0x5d,
+ 0xca, 0xd8, 0x74, 0xae, 0xf9, 0x3e, 0x6c, 0x4f, 0x88, 0x9e, 0xe5, 0x1d,
+ 0x95, 0xc4, 0x60, 0x9b, 0x6b, 0xb9, 0xe8, 0x6f, 0x4b, 0x91, 0xd6, 0xe2,
+ 0x38, 0xd4, 0x24, 0xcf, 0xe6, 0xb9, 0x68, 0xd3, 0x71, 0x94, 0x91, 0xdb,
+ 0x46, 0x79, 0x4d, 0xf6, 0xb4, 0x1c, 0x31, 0xf5, 0xe8, 0x13, 0xf8, 0x12,
+ 0x1c, 0x57, 0xd9, 0xeb, 0x5f, 0x6d, 0x69, 0xc8, 0x75, 0x93, 0xb9, 0xc9,
+ 0xf4, 0x15, 0x83, 0x32, 0xda, 0x8e, 0xbd, 0x17, 0xdb, 0x94, 0x67, 0xf7,
+ 0x06, 0x12, 0xf2, 0x0c, 0x59, 0x63, 0x8c, 0xfc, 0x10, 0xcf, 0x65, 0x64,
+ 0xff, 0xc3, 0x6f, 0xad, 0xf8, 0x4c, 0xd9, 0x67, 0x39, 0xbd, 0x4e, 0x09,
+ 0x71, 0x29, 0x10, 0xae, 0x52, 0x8a, 0xcf, 0x91, 0x5d, 0xfe, 0xdc, 0x44,
+ 0x9b, 0x39, 0x6f, 0x3f, 0xfb, 0x27, 0x67, 0x11, 0xb4, 0xa4, 0xe4, 0x5d,
+ 0x8c, 0xfa, 0xe4, 0x2a, 0x34, 0xe6, 0xea, 0x1d, 0xce, 0x02, 0xff, 0x08,
+ 0x63, 0x0d, 0xed, 0x66, 0x47, 0x20, 0x6c, 0x3f, 0xe3, 0x26, 0xef, 0xdc,
+ 0x78, 0x18, 0x7a, 0xe7, 0x1b, 0x2c, 0xff, 0xb1, 0xec, 0xf3, 0x56, 0xda,
+ 0x2b, 0x63, 0x2a, 0xfa, 0xb8, 0xbc, 0xdb, 0x87, 0x7a, 0x8c, 0x88, 0x7f,
+ 0x78, 0x50, 0x13, 0x09, 0xd3, 0x0f, 0x25, 0x7e, 0xcb, 0xf3, 0x71, 0xfa,
+ 0x01, 0xc9, 0xab, 0x5a, 0xb2, 0xf2, 0xfc, 0xb7, 0xec, 0x9b, 0xd6, 0xfd,
+ 0x6b, 0x1d, 0xc1, 0xc2, 0xfe, 0xe5, 0x62, 0xbc, 0xb7, 0xbc, 0x85, 0xbd,
+ 0xd5, 0xee, 0x79, 0x8c, 0x6f, 0x96, 0xbd, 0x6f, 0x60, 0xa3, 0x8d, 0x0d,
+ 0x9a, 0xa1, 0x1f, 0xfb, 0xa5, 0xa3, 0x1b, 0x8f, 0x2d, 0x32, 0xba, 0x8e,
+ 0xab, 0xb9, 0xb4, 0x8f, 0x38, 0x71, 0xad, 0x23, 0x3a, 0xc4, 0x6f, 0xff,
+ 0x77, 0x89, 0xcd, 0x37, 0xd9, 0x75, 0xf5, 0xe0, 0x3a, 0xb5, 0xf8, 0x6c,
+ 0xb5, 0x3c, 0x73, 0xa1, 0x77, 0x7c, 0x43, 0xe9, 0xc6, 0xd6, 0x90, 0xd1,
+ 0xbe, 0x4d, 0xd1, 0xdb, 0xbe, 0xac, 0xe8, 0xfe, 0x90, 0x22, 0xe5, 0xec,
+ 0x77, 0xe8, 0x5c, 0x8a, 0x9d, 0x2e, 0xf6, 0x71, 0x38, 0xa1, 0x87, 0x67,
+ 0xb0, 0xec, 0x39, 0xd3, 0xf0, 0x5d, 0x60, 0x9b, 0x3f, 0xe4, 0x31, 0x84,
+ 0x20, 0x96, 0xdb, 0xed, 0x46, 0x17, 0xba, 0xec, 0xf7, 0xa4, 0x76, 0x30,
+ 0x26, 0xc8, 0xfb, 0xb0, 0x62, 0xd0, 0x92, 0x75, 0x34, 0x31, 0xbd, 0xff,
+ 0x66, 0x48, 0x4e, 0xdd, 0xc3, 0x80, 0xed, 0x81, 0x37, 0xd2, 0x8d, 0x86,
+ 0x45, 0x86, 0x6f, 0x89, 0x6a, 0xd7, 0x0f, 0xca, 0xfb, 0x81, 0x96, 0x73,
+ 0x9c, 0x23, 0x90, 0x36, 0x72, 0x96, 0xd6, 0x50, 0x6d, 0xd7, 0x59, 0xa4,
+ 0x7e, 0x14, 0xae, 0x0f, 0xfd, 0xca, 0x4a, 0x6b, 0xd0, 0x6a, 0x0d, 0xa9,
+ 0x13, 0x1f, 0xd2, 0xf0, 0x1f, 0xd5, 0x13, 0x5c, 0xf9, 0xa5, 0x85, 0x59,
+ 0x52, 0x4f, 0xf6, 0xac, 0x7d, 0x1a, 0x77, 0x0d, 0xc8, 0x7b, 0x22, 0xc4,
+ 0x1f, 0xf5, 0xe8, 0x17, 0xc8, 0x35, 0xcb, 0xed, 0xf7, 0x6f, 0x49, 0x2c,
+ 0x59, 0x4f, 0x3c, 0xeb, 0x86, 0x16, 0xd2, 0xfb, 0xaf, 0x50, 0xe5, 0x1d,
+ 0x43, 0x8f, 0xc9, 0xbe, 0x9d, 0x03, 0x0b, 0xd4, 0xfc, 0xfe, 0x9e, 0xd8,
+ 0x1f, 0x7d, 0x5f, 0x11, 0xfb, 0x2a, 0x97, 0xf7, 0x15, 0xd5, 0xd9, 0xcf,
+ 0xa7, 0xac, 0x4f, 0x38, 0x0a, 0xfb, 0x15, 0x2f, 0xbf, 0xc7, 0x73, 0x23,
+ 0x79, 0xfd, 0x26, 0x79, 0x67, 0x1f, 0xc7, 0xba, 0x39, 0x21, 0x4b, 0x5a,
+ 0xff, 0x0f, 0xdd, 0x0f, 0x6b, 0xf2, 0xd0, 0x56, 0x00, 0x00, 0x00 };
static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
@@ -2137,50 +2119,51 @@ static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000000 };
-static const u32 bnx2_CP_b06FwRodata[(0x130/4) + 1] = {
- 0x08001e8c, 0x08001d18, 0x08001e68, 0x08001e44, 0x08001e20, 0x08001dfc,
- 0x08001dd4, 0x08001dac, 0x08001d80, 0x08001f84, 0x08001f74, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001eb4, 0x08001eb4, 0x08001d34, 0x08001d34,
- 0x08001f64, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f54,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001f44, 0x08001d34, 0x08001d34, 0x08001f34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34,
- 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001d34, 0x08001f1c,
- 0x08001d34, 0x08001d34, 0x08001f0c, 0x08001efc, 0x08003208, 0x08003210,
- 0x080031d8, 0x080031e4, 0x080031f0, 0x080031fc, 0x08005694, 0x08005654,
- 0x08005620, 0x080055f4, 0x080055d0, 0x0800558c, 0x00000000 };
+static const u32 bnx2_CP_b06FwRodata[(0x134/4) + 1] = {
+ 0x08000f30, 0x08000d88, 0x08000fc4, 0x0800106c, 0x08000f58, 0x08000f98,
+ 0x080011a4, 0x08000da4, 0x080011c8, 0x08000df4, 0x08001498, 0x08001440,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08001254, 0x08001254, 0x08000da4,
+ 0x08000da4, 0x080016e0, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x080013d4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000fb8, 0x08000da4, 0x08000da4,
+ 0x08001690, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4, 0x08000da4,
+ 0x080015bc, 0x08000da4, 0x08000da4, 0x08001348, 0x080012b8, 0x08002e50,
+ 0x08002e58, 0x08002e20, 0x08002e2c, 0x08002e38, 0x08002e44, 0x0800532c,
+ 0x080052ec, 0x080052b8, 0x0800528c, 0x08005268, 0x08005224, 0x00000000
+};
static struct fw_info bnx2_cp_fw_06 = {
- /* Firmware version: 4.4.22 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x16,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x08000080,
.text_addr = 0x08000000,
- .text_len = 0x5a34,
+ .text_len = 0x56cc,
.text_index = 0x0,
.gz_text = bnx2_CP_b06FwText,
.gz_text_len = sizeof(bnx2_CP_b06FwText),
- .data_addr = 0x08005b80,
+ .data_addr = 0x08005820,
.data_len = 0x84,
.data_index = 0x0,
.data = bnx2_CP_b06FwData,
- .sbss_addr = 0x08005c04,
- .sbss_len = 0xe9,
+ .sbss_addr = 0x080058a4,
+ .sbss_len = 0xf1,
.sbss_index = 0x0,
- .bss_addr = 0x08005cf0,
+ .bss_addr = 0x08005998,
.bss_len = 0x5d8,
.bss_index = 0x0,
- .rodata_addr = 0x08005a34,
- .rodata_len = 0x130,
+ .rodata_addr = 0x080056cc,
+ .rodata_len = 0x134,
.rodata_index = 0x0,
.rodata = bnx2_CP_b06FwRodata,
};
@@ -2202,761 +2185,747 @@ static const struct cpu_reg cpu_reg_cp = {
};
static u8 bnx2_RXP_b06FwText[] = {
- 0xec, 0x5b, 0x5f, 0x6c, 0x5b, 0xd7, 0x79, 0xff, 0xee, 0x21, 0x25, 0x51,
- 0xb2, 0xfe, 0x5c, 0xc9, 0x8c, 0x43, 0x27, 0x4a, 0x43, 0x4a, 0x57, 0x12,
- 0x13, 0x69, 0xe9, 0x95, 0xc6, 0x26, 0x2a, 0x46, 0x34, 0x2c, 0x29, 0xdb,
- 0x4a, 0xe3, 0x07, 0xc5, 0xf5, 0xda, 0xac, 0xeb, 0x30, 0x81, 0xb2, 0xb1,
- 0xec, 0x61, 0x83, 0x67, 0xac, 0x41, 0xb6, 0xb9, 0x30, 0x41, 0x29, 0x8e,
- 0x92, 0xd2, 0x22, 0x67, 0x2b, 0x73, 0xb1, 0x65, 0x80, 0x42, 0x49, 0x76,
- 0xb6, 0xd1, 0x62, 0xda, 0xbd, 0x74, 0x45, 0x1c, 0x0b, 0x8a, 0xe7, 0xe5,
- 0xa1, 0x0f, 0x69, 0x17, 0x60, 0xed, 0xd0, 0x61, 0x86, 0xe2, 0xda, 0x79,
- 0x28, 0xb6, 0x6c, 0x40, 0x96, 0x6c, 0x71, 0x73, 0xf7, 0xfb, 0x9d, 0x7b,
- 0xaf, 0x4c, 0x2b, 0x1a, 0x9a, 0x87, 0x3d, 0xde, 0x03, 0x08, 0xe7, 0x9e,
- 0x73, 0xbe, 0xf3, 0x9d, 0xef, 0xfb, 0xce, 0xf7, 0xf7, 0xd0, 0xfe, 0xc3,
- 0x76, 0x69, 0x13, 0xaf, 0x75, 0xe0, 0x2f, 0x75, 0xec, 0x99, 0xe3, 0x63,
- 0x0f, 0xa5, 0x1e, 0xe2, 0x38, 0xa4, 0xc2, 0x61, 0xf6, 0x86, 0x04, 0x2d,
- 0x68, 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68,
- 0x41, 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41,
- 0x0b, 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b,
- 0x5a, 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a,
- 0xd0, 0x82, 0x16, 0xb4, 0xa0, 0x05, 0x2d, 0x68, 0x41, 0x0b, 0x5a, 0xd0,
- 0x82, 0x16, 0xb4, 0xa0, 0x05, 0xed, 0xff, 0xb3, 0x85, 0x44, 0x4c, 0xf6,
- 0x1d, 0xde, 0x9f, 0x44, 0x54, 0x3a, 0x7e, 0x3c, 0x6b, 0x49, 0x24, 0x94,
- 0xbe, 0xf2, 0xf4, 0x8c, 0x25, 0x92, 0xa9, 0x0d, 0xc7, 0x73, 0xf2, 0x0b,
- 0xa7, 0x10, 0x0d, 0x0b, 0xe7, 0xef, 0x4b, 0xdf, 0x3a, 0x79, 0xe9, 0x91,
- 0xc4, 0x7b, 0x4b, 0x21, 0x89, 0x98, 0xe9, 0xb7, 0x46, 0xcd, 0x41, 0x89,
- 0xf4, 0x62, 0xcf, 0x4b, 0x43, 0x97, 0xbb, 0xa4, 0xd3, 0xc7, 0x25, 0x52,
- 0x2d, 0x25, 0xec, 0xfd, 0x32, 0x6c, 0x6e, 0x48, 0x58, 0x32, 0x38, 0xe3,
- 0x7c, 0x4d, 0xa4, 0x58, 0x32, 0x88, 0x43, 0x8a, 0xb5, 0x88, 0x5c, 0x0b,
- 0x11, 0xea, 0x7b, 0x46, 0xb6, 0xfc, 0xb1, 0x93, 0x09, 0xe3, 0x5c, 0x0b,
- 0xdf, 0x75, 0x7f, 0x3e, 0x22, 0x2a, 0x9d, 0x48, 0x66, 0x43, 0x93, 0x52,
- 0x5d, 0x74, 0x9c, 0x39, 0xfb, 0x5e, 0xe0, 0xe8, 0x91, 0x39, 0xcb, 0x1d,
- 0x67, 0xed, 0x07, 0xcd, 0x09, 0xb9, 0x1b, 0x73, 0x21, 0x51, 0xd6, 0x3d,
- 0xf8, 0x8b, 0x1b, 0xb9, 0xb3, 0xdf, 0x32, 0xb2, 0xcb, 0xed, 0x52, 0x2c,
- 0x3b, 0x32, 0x63, 0x4b, 0x26, 0x6b, 0xb7, 0x62, 0xfd, 0x63, 0x67, 0x66,
- 0x6b, 0xcf, 0xb0, 0x99, 0x93, 0x26, 0xc9, 0x44, 0x63, 0x80, 0x59, 0x34,
- 0x72, 0x17, 0xfe, 0xae, 0x5d, 0xda, 0x40, 0x4f, 0x8a, 0xe3, 0x8f, 0x9d,
- 0x90, 0x65, 0x61, 0x9d, 0xe7, 0x63, 0x5c, 0x27, 0x5e, 0x7e, 0x13, 0xe7,
- 0x35, 0xe7, 0xd2, 0x50, 0x4c, 0xbe, 0x5b, 0x8f, 0xca, 0x77, 0xea, 0xa6,
- 0xbc, 0x5a, 0xef, 0x95, 0xcb, 0x75, 0xc7, 0xf9, 0x8e, 0xed, 0x38, 0x6f,
- 0xe1, 0xef, 0x3f, 0xed, 0x2d, 0x1e, 0xd0, 0x0a, 0xc6, 0x44, 0xfd, 0x2f,
- 0xda, 0xa5, 0x33, 0x11, 0x17, 0xd5, 0x2e, 0xb3, 0xe5, 0x98, 0xcc, 0x95,
- 0x4b, 0xc6, 0x13, 0x17, 0x16, 0x8c, 0xa9, 0x0b, 0x15, 0x9c, 0x19, 0xc6,
- 0x9c, 0x14, 0x8a, 0xf6, 0x2b, 0x46, 0xae, 0x3e, 0x6f, 0x1c, 0xba, 0xd0,
- 0x09, 0x1a, 0x79, 0xfe, 0x1e, 0x23, 0x7b, 0xf6, 0x96, 0x64, 0x6d, 0xca,
- 0x38, 0x61, 0x7e, 0x0d, 0x62, 0xcf, 0x96, 0x48, 0x73, 0xb3, 0x47, 0xaf,
- 0xe3, 0xa8, 0xb4, 0x73, 0x32, 0x9b, 0xb2, 0xcc, 0xa2, 0x90, 0x3e, 0x3d,
- 0x77, 0xd9, 0xa5, 0xf9, 0xbc, 0x91, 0xbd, 0xd0, 0x6e, 0xe4, 0xce, 0x85,
- 0x41, 0x87, 0xf4, 0x86, 0x84, 0xfb, 0x06, 0x62, 0x79, 0xa9, 0xe1, 0x0c,
- 0x31, 0x55, 0x9a, 0x72, 0x05, 0xcd, 0xa0, 0xe5, 0xbb, 0x65, 0xf0, 0x50,
- 0x06, 0x0f, 0x65, 0xf2, 0x16, 0x97, 0x4b, 0x43, 0x3e, 0x6f, 0x8e, 0xf3,
- 0x23, 0x9b, 0xb4, 0x27, 0xe2, 0x19, 0xe5, 0xf3, 0xe9, 0x38, 0xff, 0x61,
- 0x93, 0x57, 0xf2, 0xe3, 0x38, 0xaf, 0xda, 0x31, 0xd0, 0xee, 0x5c, 0x56,
- 0x56, 0x09, 0xbc, 0x58, 0xc0, 0x4f, 0x59, 0x2f, 0x80, 0x87, 0x79, 0xf0,
- 0x77, 0x1e, 0xbc, 0x55, 0x40, 0xc7, 0x2f, 0x3b, 0xaf, 0x60, 0xe4, 0x86,
- 0xb6, 0xe4, 0x15, 0xa7, 0x8c, 0xf3, 0x2b, 0x0a, 0xb2, 0xde, 0x25, 0xf9,
- 0x25, 0x53, 0xa6, 0x57, 0xfc, 0xfd, 0xbe, 0x1e, 0x1c, 0x93, 0x83, 0xe5,
- 0x1e, 0xc8, 0x86, 0xb2, 0x4c, 0xd8, 0x22, 0x0e, 0x64, 0x54, 0x4c, 0x2a,
- 0x11, 0x23, 0x6f, 0x9f, 0xd4, 0xf7, 0xbf, 0x62, 0x49, 0x26, 0x6f, 0x53,
- 0x8e, 0x12, 0xcf, 0xdb, 0x85, 0x58, 0x18, 0xfa, 0xb6, 0x62, 0x15, 0xcc,
- 0xb0, 0x50, 0x8e, 0x89, 0xd8, 0x1f, 0x43, 0x96, 0x47, 0x4b, 0x92, 0xf9,
- 0x52, 0xc9, 0x97, 0xb1, 0x2b, 0xdf, 0xc7, 0x4b, 0x5f, 0xec, 0x90, 0x36,
- 0xf5, 0x99, 0x26, 0xf9, 0x3d, 0xec, 0x25, 0xee, 0x3b, 0xf6, 0x62, 0x9f,
- 0x0b, 0xe7, 0xee, 0x4d, 0x3c, 0x29, 0x42, 0xd8, 0x62, 0x7f, 0x93, 0xb6,
- 0x11, 0x31, 0xb2, 0x56, 0x21, 0x16, 0x02, 0x5c, 0x5e, 0x8a, 0xa3, 0xde,
- 0x5c, 0x53, 0xd6, 0xba, 0x15, 0x9a, 0xb3, 0x13, 0xf1, 0xa2, 0xdc, 0x0a,
- 0x5d, 0xb5, 0xf5, 0x5c, 0x6b, 0xd6, 0x72, 0x64, 0x15, 0xd8, 0x9f, 0x83,
- 0x3d, 0x6c, 0x80, 0xa3, 0xdf, 0x2d, 0xe9, 0xf9, 0x0e, 0xec, 0x4f, 0x36,
- 0x01, 0x67, 0x9b, 0x24, 0x92, 0x55, 0xcc, 0x5f, 0x75, 0xe7, 0xbb, 0x5d,
- 0xbc, 0xc5, 0xfe, 0x36, 0x8d, 0x5b, 0xe4, 0x15, 0x77, 0xfe, 0x2e, 0x17,
- 0x77, 0xf1, 0x01, 0xcc, 0x03, 0xff, 0xe0, 0xe4, 0x90, 0xa1, 0xe7, 0xf7,
- 0xd2, 0x9e, 0x7e, 0xa7, 0x74, 0x2b, 0xb4, 0x6a, 0x3b, 0x92, 0x1b, 0x1d,
- 0x9c, 0x1c, 0x34, 0x5c, 0x7c, 0xa7, 0xdc, 0x7d, 0xf7, 0xb9, 0xf8, 0x06,
- 0x27, 0x93, 0x86, 0x8b, 0x6f, 0xa5, 0xa4, 0xf7, 0x4a, 0xbe, 0x44, 0xd8,
- 0xc1, 0x49, 0xcb, 0xb8, 0x4f, 0xa6, 0xbb, 0x07, 0x27, 0xfb, 0x0c, 0xf5,
- 0x99, 0x5d, 0x2e, 0x1f, 0x09, 0x9f, 0x86, 0x5d, 0x9a, 0x06, 0x9e, 0xab,
- 0xe7, 0x07, 0xb2, 0x56, 0xf1, 0x81, 0x5d, 0xfa, 0x7c, 0x9e, 0xa9, 0xe7,
- 0x1e, 0x20, 0x5d, 0x3c, 0x7b, 0x66, 0xf4, 0x8e, 0x73, 0x7f, 0xe5, 0xb6,
- 0x7c, 0x76, 0x3a, 0x93, 0xe7, 0x49, 0x24, 0x9c, 0x0e, 0x8f, 0xce, 0x95,
- 0x8e, 0x49, 0xb6, 0x1c, 0x97, 0xd9, 0x91, 0x56, 0x99, 0x36, 0xfb, 0xa7,
- 0x0f, 0x0a, 0x7d, 0x4f, 0x64, 0x74, 0xc6, 0xbb, 0xc3, 0x9c, 0x18, 0x32,
- 0x0b, 0x1e, 0x0f, 0xd6, 0x24, 0x62, 0x00, 0xbe, 0xbf, 0x16, 0x96, 0xe7,
- 0xeb, 0x86, 0x34, 0x6b, 0xfb, 0x4c, 0x98, 0xeb, 0xd0, 0xc3, 0x67, 0xcb,
- 0xd4, 0x63, 0xea, 0xac, 0x64, 0xaa, 0x5a, 0x67, 0x7d, 0x7b, 0x6d, 0xe3,
- 0xdd, 0x16, 0x0a, 0x02, 0x73, 0x4c, 0x5b, 0x66, 0x55, 0x5a, 0x24, 0x33,
- 0x25, 0x85, 0xaa, 0xbd, 0x65, 0x3f, 0xb1, 0x65, 0xd9, 0x80, 0x1e, 0x88,
- 0x99, 0x4d, 0x71, 0x9e, 0xf0, 0x0d, 0xb0, 0xa6, 0x6b, 0x7b, 0x21, 0xd8,
- 0xde, 0x4c, 0x8a, 0xb0, 0x52, 0xd0, 0xfe, 0xa2, 0x0e, 0x7d, 0xac, 0xdf,
- 0xd7, 0xe1, 0xfa, 0xbb, 0x08, 0x6c, 0xb4, 0x1d, 0x76, 0xfe, 0x19, 0xd8,
- 0x60, 0xaf, 0x91, 0x3d, 0xe7, 0x38, 0xf0, 0x3f, 0x51, 0x25, 0xb4, 0x41,
- 0xd8, 0x7b, 0x9d, 0x6b, 0xed, 0x98, 0x17, 0x73, 0xd6, 0xee, 0x06, 0x8f,
- 0x8e, 0x33, 0x69, 0xc7, 0xa5, 0x68, 0x77, 0x61, 0x5f, 0x93, 0xf4, 0x58,
- 0xd4, 0x79, 0xda, 0xf5, 0x2e, 0x9c, 0x67, 0x70, 0xdc, 0x89, 0xf3, 0x3a,
- 0x30, 0x17, 0x9b, 0xa5, 0x2d, 0xa7, 0xe8, 0xb7, 0x5c, 0x1f, 0x2a, 0x72,
- 0x1d, 0xb4, 0x72, 0x8f, 0x86, 0x8b, 0xb4, 0xa4, 0x53, 0x72, 0xb3, 0xb4,
- 0x57, 0xae, 0x45, 0x29, 0x03, 0xe0, 0x2c, 0xc3, 0x27, 0x46, 0x0d, 0xd0,
- 0x4f, 0xba, 0xe9, 0x03, 0x77, 0x7b, 0x63, 0xe3, 0x7e, 0xf7, 0x0c, 0x31,
- 0x43, 0xe9, 0x4e, 0xc9, 0xe9, 0x39, 0x51, 0x6a, 0x74, 0x97, 0xb7, 0xde,
- 0x69, 0xec, 0x3f, 0xa7, 0xe4, 0xc0, 0xc3, 0xf0, 0x5b, 0x38, 0xeb, 0xaa,
- 0xe5, 0x38, 0x57, 0xed, 0xf7, 0x61, 0xf7, 0x4a, 0x9a, 0xac, 0x6b, 0x9d,
- 0xd2, 0x46, 0x7b, 0x36, 0x1a, 0x64, 0x18, 0x93, 0x53, 0x65, 0xee, 0x29,
- 0x48, 0xd8, 0x22, 0x0c, 0xe1, 0xff, 0x05, 0x70, 0x21, 0x69, 0x81, 0x3d,
- 0x6e, 0xd8, 0x51, 0xd2, 0xdb, 0xe5, 0xc2, 0x77, 0xe3, 0x0c, 0xd2, 0x4e,
- 0xfb, 0x73, 0xb4, 0xfd, 0x65, 0x43, 0x2a, 0x33, 0xb1, 0x08, 0x6b, 0x1a,
- 0xa1, 0xbc, 0xb3, 0xdd, 0x70, 0xff, 0x32, 0x3b, 0x54, 0x30, 0x95, 0xbe,
- 0x6f, 0x91, 0x5c, 0xe9, 0x7e, 0x99, 0xb3, 0x71, 0x9e, 0x15, 0x06, 0xcd,
- 0xf4, 0x35, 0x03, 0x85, 0x90, 0x82, 0x95, 0xf5, 0x50, 0x56, 0x3e, 0xad,
- 0xff, 0x8c, 0xf3, 0x0a, 0x46, 0xd8, 0xe2, 0x19, 0xbf, 0xe5, 0xc9, 0x87,
- 0xba, 0x67, 0x4b, 0xb6, 0xd4, 0xce, 0x31, 0xe8, 0x68, 0xd3, 0x74, 0x84,
- 0xd2, 0xfa, 0xee, 0x0c, 0x95, 0xf6, 0x63, 0x00, 0x41, 0xef, 0xc0, 0x03,
- 0x3e, 0xb8, 0xd7, 0xc2, 0xde, 0x08, 0x68, 0xec, 0x68, 0xa0, 0xbf, 0x8d,
- 0xf0, 0x90, 0x55, 0xc4, 0x3b, 0x43, 0xf3, 0x6d, 0xb8, 0x7c, 0xfb, 0xb2,
- 0x7a, 0x1d, 0xb2, 0xfa, 0xc8, 0x39, 0x30, 0x46, 0x1c, 0x29, 0xe0, 0x80,
- 0xdc, 0x4d, 0xfa, 0x2c, 0xfa, 0x29, 0x73, 0x0b, 0x17, 0x6c, 0x41, 0x85,
- 0xd2, 0xed, 0x92, 0x33, 0x75, 0x1c, 0x00, 0xec, 0xb8, 0x68, 0x3f, 0x6f,
- 0x91, 0x47, 0x6f, 0x6c, 0x25, 0xb4, 0xde, 0xe4, 0x2b, 0x8c, 0x05, 0x45,
- 0xd0, 0xb6, 0x9e, 0x50, 0x9a, 0xb5, 0x76, 0xc8, 0x5c, 0x22, 0x4d, 0xe9,
- 0xb7, 0x64, 0xb5, 0xa4, 0xf6, 0x34, 0x4b, 0x97, 0x4c, 0x41, 0x46, 0xd5,
- 0x71, 0xc4, 0xb0, 0x91, 0x76, 0x09, 0x3d, 0xc4, 0x58, 0x10, 0x03, 0xad,
- 0xeb, 0x09, 0x53, 0x6e, 0x39, 0x6a, 0x10, 0xfb, 0x47, 0x70, 0x0f, 0x87,
- 0x79, 0xa7, 0xca, 0x83, 0x23, 0x4c, 0x88, 0x32, 0xef, 0x69, 0x16, 0xe2,
- 0xe6, 0xda, 0x70, 0xcc, 0x14, 0xce, 0x23, 0x5e, 0x4e, 0x71, 0x2f, 0xf9,
- 0x73, 0xf7, 0x7c, 0x92, 0x3f, 0x7f, 0x9d, 0x32, 0xa3, 0xec, 0xa0, 0x63,
- 0xa0, 0xa9, 0x1b, 0x72, 0x1b, 0x5d, 0x80, 0x4f, 0xb4, 0x1f, 0xd7, 0x3a,
- 0xdc, 0x37, 0x76, 0xaf, 0x5c, 0x83, 0xdd, 0xc5, 0x95, 0x18, 0x55, 0x7b,
- 0xaf, 0x9e, 0x53, 0x96, 0x2f, 0x4f, 0xca, 0x60, 0xf7, 0x36, 0x19, 0x10,
- 0xe7, 0xce, 0x72, 0x38, 0x52, 0x21, 0x0d, 0x2e, 0x2d, 0x73, 0xd6, 0x7a,
- 0x22, 0x2c, 0x8d, 0xf4, 0x7c, 0xec, 0x28, 0xcb, 0x2a, 0xf4, 0x29, 0xe2,
- 0x6f, 0x16, 0xb5, 0x27, 0x2c, 0x4f, 0x8c, 0x19, 0x12, 0x3f, 0xa4, 0xe4,
- 0xd0, 0xc3, 0xc4, 0xf9, 0x13, 0xf2, 0x38, 0x9e, 0xe1, 0xfa, 0x18, 0x75,
- 0x21, 0x8c, 0x5e, 0xf3, 0x87, 0xb9, 0x46, 0x5d, 0x7f, 0xdd, 0xd3, 0xf5,
- 0x8f, 0x9c, 0x43, 0x63, 0x61, 0x0f, 0x36, 0xd2, 0x00, 0x2b, 0xb8, 0xef,
- 0x9d, 0x60, 0x09, 0xd3, 0xa8, 0x17, 0x84, 0x2d, 0xec, 0x00, 0x8b, 0xe0,
- 0xf4, 0x15, 0xda, 0x50, 0xb7, 0xe7, 0x33, 0x7c, 0x9b, 0xe2, 0x39, 0xec,
- 0x77, 0xb2, 0x3f, 0xee, 0xe3, 0x7e, 0xc2, 0x6f, 0x8f, 0xa7, 0xb8, 0x06,
- 0xd9, 0x31, 0xa6, 0xa2, 0x4d, 0xe2, 0x5b, 0xc1, 0xff, 0x34, 0xc6, 0x56,
- 0xce, 0x99, 0x18, 0x4f, 0xa0, 0xb7, 0x24, 0x5f, 0xa3, 0x1d, 0x71, 0x3f,
- 0x63, 0xed, 0xbb, 0x9e, 0xef, 0x6c, 0x9f, 0x0e, 0xa7, 0xa3, 0xf0, 0x9d,
- 0x32, 0x55, 0x2c, 0x9d, 0x44, 0x3e, 0x24, 0x85, 0x7b, 0xd2, 0xd4, 0x8b,
- 0xf6, 0x71, 0xf8, 0xc6, 0xa9, 0x62, 0x8d, 0x39, 0x11, 0xdc, 0x17, 0xf6,
- 0x21, 0x3e, 0x47, 0xd4, 0x42, 0xa4, 0x70, 0x6f, 0x9a, 0x3e, 0x39, 0x2e,
- 0xf1, 0xda, 0x7b, 0xc8, 0x39, 0x4c, 0xc9, 0x6a, 0x1d, 0xfb, 0xf6, 0x5e,
- 0xd2, 0x5c, 0x44, 0xfe, 0x10, 0x4e, 0x4b, 0x58, 0xa5, 0x9b, 0x23, 0xb3,
- 0xa9, 0x76, 0xe4, 0x59, 0x93, 0x7b, 0xd5, 0xda, 0xc1, 0xbd, 0xa1, 0xb5,
- 0x3d, 0xd3, 0x4d, 0xe9, 0xc2, 0x5e, 0xb5, 0x20, 0xb2, 0x5c, 0x12, 0x85,
- 0x9c, 0x26, 0x76, 0x44, 0x30, 0x5e, 0xfb, 0xf2, 0x97, 0x55, 0x3a, 0x24,
- 0xf9, 0xa8, 0x9c, 0x58, 0x49, 0x85, 0x99, 0x3f, 0xc6, 0xa7, 0xe4, 0x04,
- 0x72, 0xc6, 0x67, 0x64, 0xb6, 0x04, 0xba, 0x34, 0xdf, 0x31, 0xf0, 0xdb,
- 0x0b, 0xdc, 0xa4, 0x3d, 0x0a, 0xdf, 0xea, 0xd2, 0x0e, 0x9a, 0x33, 0x39,
- 0xe6, 0x48, 0x29, 0xc6, 0x94, 0xf7, 0xa0, 0x27, 0xb4, 0x93, 0x9f, 0xcb,
- 0xaa, 0xd5, 0x2a, 0x79, 0xd7, 0x2f, 0x68, 0x3d, 0x0d, 0xa7, 0xdf, 0xf5,
- 0xd6, 0xae, 0x63, 0x8d, 0xfa, 0xba, 0xab, 0xe1, 0xee, 0xbe, 0xa5, 0xf3,
- 0x9c, 0xab, 0x36, 0xbf, 0x09, 0xfb, 0x83, 0x51, 0x17, 0xf6, 0xcd, 0xd1,
- 0x55, 0xeb, 0x2b, 0x5d, 0xd2, 0x86, 0x73, 0xca, 0x3c, 0x27, 0x4a, 0xdf,
- 0x8a, 0xf5, 0x6b, 0x1e, 0xae, 0x9f, 0x02, 0x57, 0x3b, 0xe9, 0x46, 0x0b,
- 0x63, 0x1d, 0xf4, 0x21, 0xdf, 0xc9, 0x6f, 0xf9, 0x18, 0xc2, 0xbe, 0xe6,
- 0xe1, 0xfa, 0x5e, 0x03, 0x2e, 0xae, 0xb1, 0xe7, 0x99, 0x38, 0xbb, 0x8d,
- 0xbc, 0x91, 0x1f, 0xde, 0x01, 0xef, 0x23, 0x69, 0x4c, 0xc1, 0xa7, 0x4f,
- 0xd5, 0x75, 0x5e, 0x67, 0xe4, 0xca, 0xc8, 0xb7, 0xea, 0x2f, 0x82, 0x46,
- 0xe4, 0x61, 0xf5, 0x01, 0x2f, 0xd7, 0xa6, 0xad, 0xac, 0x6b, 0x9f, 0x45,
- 0x7f, 0x53, 0xd4, 0xf6, 0x74, 0x05, 0x63, 0x9d, 0x67, 0xe3, 0x6e, 0xae,
- 0x48, 0x5f, 0xad, 0xdc, 0xe5, 0xfe, 0xbf, 0x6d, 0x53, 0x42, 0xfa, 0x3e,
- 0x19, 0xd7, 0xa8, 0x67, 0x77, 0xc3, 0x9f, 0x3b, 0x1f, 0x30, 0xbe, 0x4c,
- 0x31, 0xf6, 0x4c, 0x31, 0x66, 0x18, 0x9e, 0x1f, 0x8c, 0x37, 0xe0, 0x88,
- 0x03, 0xc7, 0x79, 0x4f, 0x6f, 0x4f, 0x7b, 0xb8, 0xfc, 0xdc, 0xd3, 0xf7,
- 0xa5, 0x2f, 0xdd, 0x73, 0xe7, 0xba, 0x61, 0xba, 0xe3, 0x66, 0xed, 0x87,
- 0x61, 0xf7, 0xa0, 0x3f, 0x3e, 0xad, 0xa0, 0x5f, 0xb9, 0x9a, 0x7b, 0x1f,
- 0xb0, 0x71, 0xe8, 0x1e, 0x3f, 0xfd, 0xbb, 0x75, 0x73, 0x6f, 0x57, 0x06,
- 0xbc, 0xd3, 0x0c, 0xf9, 0xce, 0x84, 0x49, 0x4b, 0x7d, 0x12, 0xfb, 0xe5,
- 0x18, 0x63, 0x62, 0x1e, 0x7c, 0x1c, 0x31, 0x87, 0xcd, 0x59, 0xe2, 0x8e,
- 0x0a, 0x70, 0x22, 0x8f, 0x4c, 0xb7, 0x78, 0xf7, 0xfc, 0x7d, 0x9e, 0x0f,
- 0xdc, 0xbb, 0x38, 0x46, 0xff, 0x7d, 0x8f, 0x9e, 0x1b, 0x9d, 0x2e, 0x3d,
- 0xfe, 0xfa, 0x80, 0x79, 0xe7, 0x78, 0x75, 0xaf, 0x27, 0x4f, 0x7c, 0x3f,
- 0xe3, 0xd1, 0xc5, 0xbb, 0x69, 0xa4, 0x89, 0xf7, 0xf2, 0x5f, 0xc0, 0xa3,
- 0xf3, 0x8c, 0x82, 0x4a, 0x23, 0x6f, 0x49, 0x31, 0x56, 0xc1, 0xe6, 0xc5,
- 0xc2, 0x9d, 0x24, 0xec, 0x69, 0xec, 0x7a, 0xb7, 0xc4, 0x7b, 0xbe, 0x05,
- 0x1f, 0xcd, 0x7b, 0xff, 0x50, 0xe6, 0x4a, 0xfd, 0x76, 0xb3, 0x41, 0x7b,
- 0x4d, 0x24, 0xcf, 0xcb, 0xb0, 0x7d, 0x5e, 0xe7, 0x4f, 0x89, 0xf8, 0x29,
- 0xa1, 0x6c, 0x6f, 0xc9, 0x80, 0xce, 0x6b, 0x3e, 0x14, 0x0b, 0x72, 0x99,
- 0x2a, 0xc3, 0xc6, 0xc6, 0xfe, 0xcd, 0xd1, 0xf9, 0x28, 0xf2, 0xa5, 0x1b,
- 0x3b, 0xe0, 0x7a, 0x53, 0xe3, 0x21, 0xbe, 0x46, 0x5c, 0x86, 0xb4, 0x8c,
- 0xf9, 0xf8, 0x2c, 0x99, 0xaf, 0xfb, 0x38, 0xc3, 0xf0, 0xc3, 0xf0, 0x01,
- 0x63, 0xbf, 0xe1, 0xe9, 0x0b, 0xbf, 0x7f, 0xe8, 0x30, 0x07, 0x52, 0xe9,
- 0x3f, 0xf7, 0xe6, 0xae, 0x50, 0x06, 0x18, 0xfb, 0x72, 0x7f, 0xd1, 0xf3,
- 0x39, 0x05, 0x23, 0x53, 0xa7, 0x0c, 0xa8, 0x2b, 0xb8, 0x7f, 0xad, 0x9f,
- 0xb0, 0x99, 0xf2, 0x17, 0x10, 0x1f, 0xbb, 0xdd, 0xbc, 0x01, 0xb5, 0x55,
- 0xa6, 0xce, 0xb9, 0xf5, 0x96, 0xac, 0xdd, 0xe4, 0xd9, 0xd2, 0x41, 0xcc,
- 0x4d, 0xe1, 0x8f, 0xb2, 0x23, 0xcc, 0x61, 0x7c, 0x67, 0x3c, 0x38, 0x19,
- 0xcf, 0x22, 0x66, 0x65, 0x0e, 0x4f, 0x60, 0x6c, 0x78, 0x35, 0x96, 0x96,
- 0x7b, 0x05, 0x39, 0x0a, 0xe4, 0x39, 0x00, 0x7e, 0xe2, 0x32, 0x51, 0xc7,
- 0x9d, 0x6f, 0xf9, 0xb3, 0x2d, 0x98, 0xc2, 0x6d, 0x18, 0xd7, 0xf7, 0x4d,
- 0xd4, 0x7f, 0xec, 0xd0, 0x1f, 0xfc, 0xad, 0xb6, 0x97, 0x78, 0x43, 0xde,
- 0x97, 0x31, 0x9e, 0x28, 0x4f, 0x1a, 0x87, 0xca, 0xdc, 0xa3, 0x5e, 0xea,
- 0x11, 0x2b, 0x9e, 0x55, 0xc8, 0x51, 0xc7, 0x3a, 0x71, 0xe6, 0x29, 0xe8,
- 0x46, 0xc1, 0x98, 0x1a, 0xea, 0x92, 0x7c, 0xb2, 0x07, 0x34, 0x3f, 0x82,
- 0x1e, 0xb1, 0xc3, 0xfa, 0x35, 0xcc, 0x43, 0x8f, 0x92, 0xb4, 0x8f, 0x56,
- 0x5d, 0x57, 0x4e, 0xeb, 0xb8, 0x35, 0xe0, 0xe9, 0xd6, 0x3f, 0x99, 0xae,
- 0x2e, 0x3d, 0x8d, 0xf1, 0x2e, 0xcc, 0xff, 0x26, 0x7a, 0xc4, 0xac, 0x31,
- 0x7f, 0x9e, 0x36, 0x38, 0x8e, 0xf9, 0xcf, 0x01, 0xc7, 0x9f, 0xe0, 0xfb,
- 0x7e, 0x7c, 0xff, 0xd1, 0xb6, 0xbd, 0xdf, 0xe0, 0xd9, 0x98, 0xcf, 0x6e,
- 0x9b, 0xf7, 0xfd, 0xb7, 0x8e, 0x93, 0xd2, 0xbd, 0x06, 0xc6, 0xd7, 0x22,
- 0xb2, 0xfb, 0x7c, 0x9b, 0xa8, 0xaa, 0xeb, 0xc3, 0x55, 0xd5, 0x94, 0x9e,
- 0xf3, 0xf4, 0xdf, 0x3f, 0xc2, 0x1e, 0x4b, 0xd4, 0x1a, 0x2e, 0x8d, 0x77,
- 0xab, 0x6d, 0xf4, 0x99, 0xe3, 0x7d, 0x4b, 0xec, 0x0b, 0xc7, 0x47, 0x6b,
- 0x84, 0xe1, 0xf7, 0x89, 0xe3, 0x7d, 0xb5, 0x9f, 0x00, 0x16, 0x72, 0x29,
- 0xfb, 0xf8, 0x09, 0xff, 0xda, 0xb6, 0x33, 0xb5, 0x6c, 0x71, 0x26, 0xed,
- 0xfe, 0x99, 0xe3, 0xd9, 0x0a, 0xf3, 0x83, 0x44, 0x4c, 0x74, 0x1e, 0x5e,
- 0x38, 0x3e, 0x53, 0x0a, 0x4b, 0x48, 0xd3, 0xe2, 0xaf, 0x73, 0x8d, 0xf7,
- 0xb0, 0x13, 0x6d, 0xa4, 0xab, 0x11, 0x0f, 0xe3, 0x0c, 0xf1, 0x9c, 0x00,
- 0x9e, 0x24, 0xf0, 0x30, 0xde, 0xb8, 0xf4, 0xc6, 0x97, 0x76, 0xa2, 0x8d,
- 0xb8, 0x78, 0x96, 0x8f, 0xaf, 0x47, 0xd4, 0xf9, 0xb7, 0x49, 0xaf, 0xc9,
- 0x9c, 0xd6, 0xf5, 0x35, 0x4d, 0x92, 0x3f, 0x8b, 0xdc, 0xc6, 0x1e, 0xf3,
- 0xc6, 0x77, 0x9b, 0xac, 0xb7, 0xe3, 0x8a, 0xf3, 0xec, 0xb1, 0x96, 0x8a,
- 0x63, 0x0e, 0xe3, 0x65, 0x1f, 0x56, 0x79, 0xb0, 0x1d, 0x0d, 0x7c, 0x37,
- 0x79, 0xb2, 0xe6, 0x99, 0x7e, 0xdd, 0xd9, 0x48, 0x0b, 0x40, 0x71, 0x0f,
- 0xdd, 0x5b, 0xf7, 0xe0, 0xf3, 0x89, 0x85, 0x35, 0xd2, 0x96, 0x04, 0xaf,
- 0x3e, 0x6d, 0x9f, 0xf6, 0xfe, 0xb8, 0x37, 0x89, 0x3f, 0xff, 0x3c, 0x5f,
- 0x06, 0xa4, 0x8b, 0x3d, 0x74, 0xf9, 0x13, 0x75, 0x73, 0x12, 0x76, 0xc7,
- 0x37, 0x10, 0xc7, 0x59, 0xb5, 0x29, 0xfb, 0x16, 0xdc, 0xbb, 0xf6, 0xb1,
- 0xa8, 0x21, 0x14, 0x73, 0xb9, 0x38, 0xeb, 0xd5, 0xa3, 0xb2, 0x09, 0x5c,
- 0x19, 0xd4, 0x94, 0x6e, 0x5d, 0x34, 0x0d, 0xff, 0xb8, 0x0e, 0xfd, 0xbc,
- 0x6a, 0xf1, 0x2d, 0x26, 0xcc, 0x78, 0x27, 0xc5, 0xda, 0xcf, 0x01, 0xc3,
- 0x3c, 0xea, 0xf6, 0x3b, 0xcb, 0x12, 0x60, 0x96, 0xb1, 0x76, 0xca, 0xf5,
- 0xcb, 0xf4, 0xed, 0xc8, 0xa9, 0x50, 0xc3, 0x58, 0xff, 0xe3, 0xe4, 0xa3,
- 0x8d, 0xb0, 0x3b, 0xbd, 0x83, 0x20, 0xe6, 0x2c, 0x26, 0xe6, 0x97, 0xe0,
- 0xc3, 0x2b, 0x96, 0xda, 0xad, 0xb4, 0x46, 0x26, 0x2a, 0xf0, 0x49, 0xa8,
- 0x78, 0x13, 0xf1, 0x25, 0x79, 0x5f, 0xdf, 0x43, 0x93, 0x35, 0x6c, 0xf6,
- 0xa8, 0xaf, 0x52, 0xaf, 0x34, 0xe5, 0xa1, 0x33, 0x88, 0xcb, 0x23, 0x4f,
- 0x20, 0xe6, 0x40, 0x5e, 0x67, 0x0a, 0xa8, 0xe2, 0xa9, 0x23, 0x3f, 0xf8,
- 0x83, 0x19, 0xcb, 0xcd, 0xff, 0x75, 0x3c, 0x13, 0x97, 0xc7, 0xd0, 0x99,
- 0x76, 0xed, 0x67, 0xf2, 0xda, 0xdf, 0xf4, 0x9b, 0x53, 0xaa, 0x0d, 0x39,
- 0x06, 0x12, 0x4f, 0x64, 0x38, 0xe6, 0xa0, 0x48, 0x1f, 0xf3, 0x4e, 0xf8,
- 0xe1, 0xbe, 0x35, 0x78, 0xb7, 0x33, 0x84, 0x57, 0x12, 0x3e, 0x13, 0x92,
- 0xa6, 0x33, 0x7c, 0x0b, 0x91, 0x3d, 0xa8, 0xc3, 0x88, 0xb3, 0x2f, 0x8c,
- 0x7e, 0x02, 0x7f, 0xfb, 0x90, 0x5f, 0x99, 0xc8, 0x8d, 0x77, 0x80, 0x07,
- 0x2c, 0xf7, 0xec, 0x04, 0xdf, 0xd5, 0x2d, 0x6d, 0x11, 0xec, 0x21, 0x3c,
- 0xf2, 0x43, 0x6b, 0x0f, 0xe8, 0x71, 0xcf, 0x27, 0x8e, 0xf0, 0x19, 0x91,
- 0xfe, 0x05, 0xe9, 0x51, 0x7a, 0x4f, 0x58, 0x66, 0x52, 0x5c, 0x6b, 0x07,
- 0x3c, 0xf7, 0x61, 0x4d, 0xef, 0x73, 0xdf, 0x94, 0xf2, 0xb7, 0xe9, 0xc6,
- 0x9c, 0x81, 0x6f, 0xe4, 0x53, 0x29, 0x53, 0xfa, 0xab, 0x2e, 0x6c, 0xdf,
- 0xda, 0x53, 0xdd, 0x7c, 0x97, 0x52, 0x96, 0x4b, 0x9b, 0x42, 0xee, 0x9b,
- 0x87, 0x54, 0xc3, 0x83, 0x7c, 0x9b, 0x21, 0x0c, 0xeb, 0xd9, 0x2e, 0x0d,
- 0x63, 0x0e, 0x52, 0x7e, 0xee, 0x9c, 0x52, 0xff, 0xd7, 0x9b, 0x4b, 0x63,
- 0x4e, 0xa1, 0x6d, 0x05, 0xfb, 0xbf, 0xa9, 0x6d, 0x45, 0x54, 0xdc, 0xb3,
- 0x15, 0x8c, 0x97, 0x39, 0xf6, 0x63, 0xf1, 0xf1, 0x7b, 0x5c, 0x7f, 0xef,
- 0xc8, 0xac, 0xcd, 0xf7, 0x0b, 0x47, 0xae, 0xda, 0x05, 0xe3, 0xc0, 0x1d,
- 0x79, 0x66, 0x52, 0xc7, 0xe7, 0x19, 0xc8, 0x7e, 0xb3, 0xa6, 0x6b, 0x35,
- 0xb9, 0x56, 0x8b, 0xc8, 0x3b, 0x2b, 0x6d, 0xb2, 0xb9, 0xe4, 0xea, 0xfc,
- 0xe6, 0x12, 0xf5, 0xdc, 0x94, 0x9f, 0xad, 0x58, 0x58, 0x4b, 0xe2, 0xaf,
- 0x47, 0x6e, 0xac, 0xdc, 0x99, 0x77, 0x5e, 0xae, 0x3f, 0x0a, 0x5a, 0x7a,
- 0x24, 0x64, 0x39, 0xba, 0xee, 0xca, 0x21, 0xf6, 0x15, 0x64, 0x42, 0xf2,
- 0xe5, 0x7e, 0xd4, 0x7e, 0x08, 0xce, 0x61, 0xc6, 0x20, 0xdc, 0x7f, 0xf9,
- 0xf3, 0xc8, 0x4d, 0x12, 0x30, 0x9e, 0x7e, 0xfd, 0xa6, 0xf8, 0xc5, 0x70,
- 0x8f, 0x34, 0x5b, 0xdf, 0xec, 0x76, 0x63, 0x95, 0xe9, 0xd6, 0xa7, 0x96,
- 0x1f, 0xaf, 0xdf, 0x04, 0xee, 0x11, 0xe8, 0x29, 0x75, 0xd3, 0x86, 0xce,
- 0x9a, 0xb2, 0x3a, 0x94, 0xa8, 0x14, 0x84, 0xfe, 0x21, 0xc5, 0x7c, 0x11,
- 0xfb, 0x92, 0x90, 0x47, 0xab, 0xce, 0x85, 0x32, 0x0a, 0x77, 0xbb, 0x30,
- 0x27, 0xf9, 0xfa, 0xef, 0x63, 0x3e, 0x23, 0xd3, 0xf5, 0x71, 0x9c, 0x75,
- 0x1a, 0x7a, 0xfb, 0x60, 0x8f, 0xb4, 0xf1, 0x9c, 0x14, 0x68, 0x7c, 0x44,
- 0x66, 0xce, 0xce, 0xc9, 0x91, 0x32, 0xe9, 0xe4, 0x1b, 0x63, 0x22, 0x99,
- 0x93, 0xe1, 0xf8, 0x0a, 0x72, 0x27, 0xd7, 0x1e, 0xd3, 0x32, 0x73, 0x0e,
- 0x38, 0xca, 0xac, 0xff, 0xfb, 0xa1, 0x37, 0xc3, 0xba, 0x7e, 0x99, 0xd6,
- 0x7e, 0x87, 0xf3, 0x6f, 0xe3, 0x9e, 0xfa, 0x0b, 0xfb, 0x00, 0x97, 0x47,
- 0xad, 0x33, 0x85, 0x7c, 0x79, 0xb9, 0x8c, 0x3a, 0xcf, 0x0e, 0x31, 0xf7,
- 0x52, 0xea, 0xa1, 0x5e, 0xa9, 0x96, 0x87, 0x4d, 0xa5, 0x98, 0x53, 0xf1,
- 0x2e, 0xb8, 0x46, 0xfb, 0x8e, 0xa9, 0xb0, 0xd5, 0x2b, 0x2b, 0xe5, 0x02,
- 0xea, 0x65, 0xe5, 0xbd, 0x67, 0x14, 0xc4, 0xb4, 0x5c, 0xbf, 0xa7, 0x6b,
- 0x1b, 0xe6, 0x9f, 0xf5, 0x2f, 0x80, 0xc6, 0x0c, 0x2e, 0xf3, 0x24, 0xe8,
- 0xc3, 0xf7, 0x32, 0x74, 0x7c, 0x81, 0x39, 0x5c, 0x06, 0x6b, 0x69, 0x39,
- 0x76, 0x61, 0x0a, 0x34, 0x74, 0x4a, 0xff, 0x9f, 0xd1, 0xc6, 0x9e, 0xc4,
- 0x1c, 0xc7, 0x09, 0xe8, 0xeb, 0xd7, 0xf1, 0x4d, 0xd8, 0x18, 0x7a, 0xca,
- 0xa1, 0x17, 0xbd, 0x09, 0x5a, 0x58, 0x07, 0x43, 0xfe, 0x87, 0xe3, 0x52,
- 0x3d, 0xfb, 0xb0, 0x4c, 0x2f, 0x3f, 0x0c, 0xfc, 0xff, 0x8a, 0xba, 0x00,
- 0xf1, 0x6d, 0x99, 0x67, 0x31, 0xff, 0xe3, 0x39, 0x10, 0x10, 0x6d, 0x63,
- 0x81, 0xf3, 0xec, 0x0f, 0x62, 0x3f, 0x6a, 0x8c, 0x72, 0x46, 0x66, 0xca,
- 0x3c, 0x0b, 0x77, 0x87, 0x7c, 0x2a, 0x7f, 0x76, 0xca, 0xbb, 0xe3, 0x1e,
- 0xc9, 0x45, 0x0b, 0xac, 0x2f, 0x10, 0x27, 0x96, 0x46, 0xb3, 0xa5, 0x84,
- 0x99, 0x55, 0xc4, 0x95, 0x14, 0xc6, 0x06, 0x77, 0x2e, 0x22, 0xd6, 0x02,
- 0x6a, 0xda, 0x34, 0xd7, 0x4e, 0x7a, 0x6f, 0x06, 0xc4, 0xf5, 0x63, 0x99,
- 0x80, 0x8e, 0xf5, 0x2f, 0x8c, 0x20, 0x17, 0xfe, 0x29, 0x72, 0xc9, 0xb8,
- 0x27, 0x83, 0x71, 0x4f, 0x37, 0xda, 0x1a, 0x74, 0x02, 0xf7, 0x5c, 0xc6,
- 0xdd, 0x97, 0xa1, 0x07, 0xf0, 0xd5, 0xaf, 0x6e, 0xe9, 0xc7, 0x78, 0x43,
- 0x8e, 0xd9, 0x21, 0xff, 0x50, 0x49, 0x24, 0xd7, 0xa1, 0x3f, 0x37, 0x50,
- 0x0b, 0xac, 0xa3, 0x3e, 0xdc, 0xb4, 0x23, 0xa8, 0x4b, 0x0e, 0x83, 0x7e,
- 0xe6, 0x94, 0x1c, 0xc7, 0x74, 0xae, 0xd3, 0x62, 0x3d, 0x7f, 0x8f, 0x7e,
- 0xd7, 0x95, 0xaf, 0xf6, 0xb0, 0xa6, 0x64, 0x3d, 0xce, 0x37, 0xe9, 0x77,
- 0x70, 0x8f, 0xeb, 0x26, 0xd7, 0xfd, 0x7d, 0xac, 0x05, 0x7c, 0xfd, 0x21,
- 0x2d, 0xd4, 0x1f, 0xee, 0x21, 0x4c, 0x8f, 0xb6, 0x93, 0xbc, 0xc6, 0x47,
- 0x9d, 0xfd, 0x9b, 0x6e, 0xd7, 0xce, 0x74, 0x9e, 0x65, 0x5e, 0x13, 0x5f,
- 0x7f, 0x3f, 0x74, 0x58, 0xd7, 0x65, 0x87, 0xe0, 0xbb, 0xeb, 0x8e, 0xbc,
- 0x60, 0xdf, 0x69, 0x77, 0xfb, 0xcb, 0xbe, 0x9c, 0x28, 0xc7, 0xc3, 0x72,
- 0xaa, 0x9e, 0x80, 0x4d, 0x50, 0x86, 0x56, 0x83, 0x0c, 0x45, 0xfe, 0xaa,
- 0x2c, 0xf2, 0x4a, 0x99, 0x6b, 0x5a, 0x86, 0xb1, 0x6c, 0xa8, 0x8d, 0xef,
- 0xea, 0xd0, 0xcb, 0xb7, 0xe5, 0xc8, 0xa2, 0xc8, 0x05, 0xac, 0xaf, 0x96,
- 0x69, 0xab, 0x23, 0xc8, 0x5f, 0x77, 0x49, 0x75, 0x09, 0x35, 0x59, 0x59,
- 0xa6, 0xb3, 0x9f, 0x63, 0xbc, 0x89, 0xc8, 0xa6, 0x7e, 0x8f, 0x15, 0x19,
- 0xbc, 0x18, 0x96, 0xf0, 0x45, 0x14, 0x7f, 0x90, 0xfd, 0xa5, 0x21, 0xff,
- 0x7d, 0xd6, 0xb5, 0xf9, 0x62, 0x09, 0x7b, 0xcb, 0xfd, 0xda, 0x4f, 0x16,
- 0x6b, 0x33, 0x92, 0xaf, 0xf0, 0x2c, 0xf4, 0x4b, 0x71, 0xac, 0xa5, 0x64,
- 0xf6, 0xec, 0x88, 0x3c, 0x8b, 0x33, 0x50, 0xff, 0xe1, 0x8c, 0x09, 0x29,
- 0x5c, 0xc0, 0x7c, 0xed, 0xba, 0x2c, 0xad, 0xcc, 0x48, 0xb5, 0x72, 0xb9,
- 0xe1, 0xdd, 0x1d, 0xe3, 0xa5, 0xc6, 0x5a, 0xf6, 0x30, 0xeb, 0x19, 0xd4,
- 0xaa, 0x16, 0xc6, 0x90, 0x59, 0x6d, 0x76, 0xfa, 0xce, 0xf7, 0xe2, 0xc6,
- 0x1a, 0x76, 0x52, 0xe6, 0xcb, 0x29, 0x29, 0x9e, 0x1d, 0xd1, 0x6f, 0x0a,
- 0x2d, 0xe9, 0xca, 0xd3, 0x37, 0x11, 0x2b, 0x26, 0xf5, 0x7b, 0xf1, 0x2d,
- 0x79, 0xcc, 0x9e, 0x97, 0xa3, 0xd6, 0x41, 0x39, 0x85, 0xfc, 0xfa, 0x4b,
- 0x76, 0xab, 0xc4, 0xbb, 0x79, 0x8f, 0xa0, 0xd7, 0x62, 0x0d, 0xea, 0xc8,
- 0x84, 0xfd, 0xa0, 0xf9, 0x3c, 0x24, 0xfb, 0x4e, 0x8d, 0x71, 0xf2, 0xbf,
- 0x9d, 0x0c, 0xe2, 0xde, 0x4d, 0xd4, 0x8e, 0x19, 0x0d, 0x67, 0xb8, 0x70,
- 0x15, 0xc2, 0x0d, 0x9b, 0x2f, 0x10, 0x6e, 0xc9, 0xf0, 0xe0, 0x0c, 0xc0,
- 0x85, 0x64, 0xc3, 0x0e, 0x43, 0x47, 0x26, 0xc1, 0x27, 0x7c, 0xfc, 0x68,
- 0x87, 0x97, 0x07, 0xb7, 0x22, 0xb6, 0xde, 0xde, 0xff, 0x86, 0xb7, 0xff,
- 0x59, 0x6f, 0xff, 0xd5, 0xad, 0xfd, 0x7e, 0x7c, 0xfd, 0x85, 0x23, 0x0d,
- 0x74, 0xbd, 0x51, 0x72, 0xe1, 0xe7, 0x3d, 0xba, 0xae, 0x6e, 0xd1, 0xe5,
- 0xc3, 0x43, 0x9e, 0x9a, 0x67, 0xfa, 0x66, 0xfa, 0xe8, 0x7e, 0xc8, 0xd1,
- 0x91, 0x9c, 0x0d, 0xdb, 0x28, 0x27, 0xc6, 0x0b, 0xfa, 0x2d, 0x4d, 0xc9,
- 0x7a, 0x74, 0x5e, 0x26, 0xad, 0xc4, 0xf8, 0xac, 0x84, 0xa0, 0xcb, 0xf4,
- 0x2d, 0x21, 0xa9, 0xd2, 0xe7, 0xa0, 0xcf, 0xdb, 0x3b, 0xd3, 0xfa, 0x4e,
- 0x03, 0xad, 0xa1, 0x97, 0x49, 0xa3, 0x4b, 0x6b, 0x64, 0xe0, 0x36, 0xad,
- 0x2e, 0xbc, 0x4b, 0xeb, 0x3b, 0xa5, 0x06, 0xf8, 0x8b, 0x61, 0x0f, 0x3e,
- 0xdc, 0x00, 0x4f, 0x7d, 0x66, 0x5e, 0x41, 0x7d, 0x26, 0x6d, 0x9f, 0x85,
- 0x6d, 0x48, 0xa4, 0x35, 0x5d, 0x39, 0xfe, 0xc0, 0x80, 0x23, 0x11, 0xe4,
- 0x1b, 0xcd, 0x58, 0xdb, 0xac, 0x30, 0x17, 0x51, 0x7d, 0xcd, 0x32, 0x08,
- 0x9d, 0xe5, 0xdd, 0xb9, 0x6f, 0x82, 0x8f, 0xe9, 0x9c, 0xc0, 0x91, 0xa3,
- 0x36, 0x69, 0x79, 0xdf, 0x79, 0x25, 0x3a, 0x68, 0x17, 0x65, 0xc8, 0x6c,
- 0xc6, 0xf9, 0xd5, 0xba, 0xc6, 0x99, 0x24, 0x2d, 0xe7, 0x87, 0xfa, 0xcd,
- 0xbf, 0x07, 0x9f, 0x13, 0x15, 0x43, 0xaa, 0x56, 0x22, 0x76, 0x09, 0x38,
- 0xf6, 0xe1, 0x6e, 0xaa, 0x23, 0xa4, 0x47, 0xe4, 0x08, 0xf4, 0xbb, 0xaa,
- 0xe3, 0x22, 0xf5, 0x38, 0x31, 0x59, 0x40, 0xae, 0xf3, 0xd7, 0x3a, 0xb6,
- 0x39, 0xce, 0x4d, 0xc4, 0xb7, 0xc9, 0x6d, 0xba, 0xa7, 0x2e, 0xba, 0xba,
- 0xa7, 0x2e, 0xa2, 0x06, 0x3e, 0x1d, 0x91, 0x96, 0x55, 0xd8, 0xcf, 0xcb,
- 0x7b, 0xdc, 0x7c, 0xee, 0x65, 0xfe, 0xe6, 0x04, 0x7f, 0x77, 0x3a, 0x2c,
- 0xd6, 0x69, 0x1d, 0x0f, 0x20, 0xef, 0x09, 0x99, 0x3d, 0x47, 0x9f, 0x6a,
- 0xc9, 0xc0, 0x69, 0xde, 0x07, 0xf3, 0x9a, 0xa5, 0xd1, 0x19, 0xd8, 0xc8,
- 0x1c, 0xfc, 0x82, 0x5a, 0x7d, 0x57, 0x66, 0x2c, 0xca, 0xa1, 0x53, 0xda,
- 0x56, 0x51, 0x8f, 0xaf, 0xc2, 0x37, 0xac, 0xc6, 0xa4, 0x09, 0xb6, 0xa5,
- 0x2e, 0x46, 0x8d, 0xe2, 0xe2, 0x07, 0xb0, 0x07, 0xfe, 0x7e, 0x83, 0xdc,
- 0xf2, 0x62, 0xcc, 0xa0, 0x6d, 0xa9, 0x8b, 0xd4, 0x73, 0xa4, 0x53, 0x17,
- 0xa9, 0xe7, 0xa4, 0xc3, 0xb7, 0x17, 0x7c, 0x5f, 0x1c, 0xd1, 0xef, 0xd3,
- 0x37, 0x6d, 0xf2, 0xf2, 0x8f, 0x92, 0xad, 0x30, 0x47, 0x24, 0x3f, 0xd2,
- 0x8d, 0x5c, 0xa6, 0x2b, 0x6b, 0x0f, 0x8c, 0x6f, 0xca, 0xa7, 0xe5, 0xeb,
- 0xee, 0x4f, 0xc1, 0x17, 0xf9, 0x68, 0xe4, 0x8b, 0x3c, 0x75, 0x4a, 0x93,
- 0xe6, 0xcb, 0xe7, 0x07, 0x82, 0x06, 0x3f, 0x7d, 0xa7, 0x63, 0xc0, 0xff,
- 0x75, 0xf8, 0x80, 0x5e, 0xf4, 0x4f, 0xa2, 0x47, 0x48, 0xbb, 0x48, 0xde,
- 0xc9, 0xeb, 0x0d, 0xe4, 0x8d, 0x3e, 0x9f, 0xd3, 0xf8, 0x7e, 0x5d, 0x66,
- 0x17, 0x9d, 0x93, 0x88, 0xab, 0x7c, 0x3b, 0xef, 0x71, 0xdf, 0x81, 0xb7,
- 0xf3, 0xfe, 0xba, 0xb8, 0xf2, 0x49, 0x98, 0x55, 0xc1, 0xf7, 0xca, 0x76,
- 0x59, 0x34, 0xfa, 0x8e, 0x98, 0xce, 0xc3, 0x8f, 0xd4, 0xe8, 0x27, 0x28,
- 0xa3, 0x1b, 0x92, 0x5d, 0xe4, 0xfb, 0x97, 0x8b, 0x6f, 0xba, 0xe6, 0xfb,
- 0x8d, 0xc6, 0x3d, 0x36, 0xe0, 0x7a, 0x01, 0x47, 0xba, 0xd6, 0x29, 0x3f,
- 0xf8, 0x9c, 0xbd, 0x0d, 0xbe, 0xa6, 0x71, 0xdf, 0xb8, 0x3c, 0x87, 0x3c,
- 0xe0, 0x0d, 0xfb, 0x0e, 0xb9, 0x4e, 0x33, 0x17, 0xaa, 0xd6, 0xa6, 0x60,
- 0x93, 0x4d, 0xf0, 0x65, 0xa6, 0x6c, 0x96, 0x9a, 0xa5, 0x8a, 0x7c, 0x67,
- 0x79, 0x85, 0xbe, 0x90, 0xb4, 0xb7, 0x61, 0xde, 0xf5, 0x5f, 0xf4, 0xb5,
- 0x9b, 0x25, 0xc4, 0x59, 0xd8, 0xf6, 0x66, 0x29, 0x8a, 0xbe, 0x17, 0xbd,
- 0x85, 0x3e, 0x8e, 0x3e, 0x89, 0x7e, 0x04, 0xfd, 0x08, 0x7a, 0x0b, 0x7b,
- 0x63, 0xe8, 0xfd, 0x9a, 0x81, 0xb8, 0x6e, 0xf3, 0x5d, 0xd4, 0xe7, 0x21,
- 0x57, 0xb4, 0x18, 0xd3, 0xc2, 0x76, 0x0e, 0x75, 0x44, 0x76, 0x84, 0xb9,
- 0x1e, 0x73, 0xbe, 0x8f, 0x1d, 0xd3, 0x62, 0x5d, 0x5e, 0x30, 0xf6, 0x0d,
- 0x31, 0x2e, 0x54, 0x10, 0x17, 0x3e, 0xd8, 0x8d, 0xfa, 0xd1, 0xdc, 0xaf,
- 0xdf, 0x8e, 0x16, 0x31, 0xe6, 0x37, 0x6a, 0xde, 0xe8, 0x1c, 0xe2, 0x14,
- 0xfd, 0xa7, 0x83, 0x3d, 0x79, 0xf8, 0xf1, 0x2e, 0xd8, 0x5f, 0x06, 0x7e,
- 0x1b, 0xdf, 0x4b, 0x6f, 0xec, 0x76, 0x63, 0x2a, 0xf2, 0x77, 0xb5, 0xfd,
- 0xbd, 0xc6, 0xc6, 0x9e, 0x9d, 0x6a, 0x83, 0x0e, 0xe0, 0x48, 0x54, 0x96,
- 0x60, 0x83, 0x3f, 0xb4, 0x4f, 0xea, 0xdc, 0x8e, 0x77, 0xf1, 0x2c, 0x72,
- 0xd4, 0xdc, 0x02, 0x73, 0x98, 0x13, 0xa8, 0x4b, 0x50, 0x9f, 0x45, 0x59,
- 0x93, 0x33, 0x16, 0xe8, 0x5c, 0x34, 0x2a, 0x6d, 0x8c, 0x03, 0x37, 0x70,
- 0x1e, 0xf8, 0x5a, 0x76, 0x20, 0xb3, 0x03, 0xc8, 0x09, 0x1d, 0x27, 0x6c,
- 0xed, 0x93, 0xf8, 0x21, 0xfa, 0x1c, 0xc1, 0x7e, 0x53, 0xdc, 0xf7, 0x74,
- 0xf8, 0xdd, 0x29, 0xfd, 0x5b, 0x31, 0x94, 0xeb, 0xb3, 0xd8, 0x7b, 0x17,
- 0x70, 0x71, 0x9e, 0x6f, 0xd9, 0x22, 0xfb, 0x16, 0xdc, 0x9c, 0x56, 0x59,
- 0x8d, 0xf8, 0x7e, 0xd5, 0xc3, 0xc7, 0x75, 0xe5, 0xfd, 0xa6, 0xb1, 0xc7,
- 0x7d, 0x1b, 0xc6, 0x1d, 0x9f, 0x42, 0xfe, 0xbc, 0x81, 0x7b, 0x79, 0x03,
- 0x77, 0x72, 0xa5, 0x44, 0x5d, 0x1f, 0x86, 0xde, 0x43, 0x86, 0x53, 0xc4,
- 0x35, 0xa2, 0xcf, 0xde, 0x28, 0xc1, 0x77, 0xd2, 0xff, 0x29, 0x64, 0x77,
- 0x6d, 0x6e, 0x4c, 0x77, 0xf1, 0xf4, 0xba, 0x70, 0xe2, 0xaf, 0xed, 0xd6,
- 0xf4, 0x54, 0xf5, 0x3b, 0x18, 0xe5, 0x04, 0x1d, 0xe4, 0x6f, 0x03, 0x1a,
- 0xe6, 0x6b, 0x51, 0xfd, 0xfe, 0xae, 0x38, 0x47, 0x3e, 0x46, 0x24, 0xbb,
- 0xe0, 0xef, 0xeb, 0xc6, 0xbe, 0xd6, 0x06, 0x5c, 0x77, 0x6f, 0xe3, 0x41,
- 0x79, 0x3c, 0x70, 0xfd, 0x93, 0x6f, 0xc3, 0x85, 0xad, 0xb7, 0x61, 0xc6,
- 0x5f, 0xde, 0x4d, 0x0a, 0xfb, 0xfd, 0xfb, 0xe9, 0xf5, 0x6a, 0x81, 0xc4,
- 0x7c, 0x41, 0x98, 0xab, 0xf0, 0x8e, 0xc6, 0x61, 0xd7, 0x5d, 0xc0, 0x6f,
- 0x4b, 0xa5, 0xd4, 0x22, 0xaa, 0x87, 0xb5, 0x31, 0x73, 0xe5, 0xc6, 0x33,
- 0x7f, 0xdb, 0x3b, 0x13, 0xf5, 0xf4, 0x19, 0xe6, 0xcd, 0x3a, 0xce, 0x00,
- 0xa6, 0x7d, 0x1b, 0x6d, 0xbf, 0xee, 0xc1, 0x71, 0x3d, 0x29, 0x05, 0xe4,
- 0xa1, 0xb9, 0x05, 0x64, 0xf4, 0xf0, 0xdf, 0x2a, 0xcd, 0xdf, 0xb3, 0xf8,
- 0x86, 0x37, 0x1c, 0x9f, 0x05, 0x8d, 0x05, 0x33, 0xc3, 0x77, 0x33, 0xe0,
- 0xd8, 0xbb, 0x0d, 0xc7, 0x84, 0x87, 0x63, 0x42, 0x8a, 0xe7, 0x26, 0x61,
- 0x6b, 0x19, 0xc4, 0xf7, 0x7e, 0xf3, 0x80, 0x7c, 0x1e, 0xc5, 0x35, 0xe6,
- 0x2e, 0x8c, 0xe0, 0x9e, 0x1c, 0x67, 0x9f, 0x7d, 0x18, 0x74, 0xbf, 0x86,
- 0xd8, 0xea, 0xe7, 0x3c, 0xc5, 0x58, 0x08, 0x31, 0xec, 0x98, 0xfe, 0x0d,
- 0xb6, 0x60, 0x9a, 0xd0, 0x57, 0x65, 0x0c, 0x27, 0x51, 0xde, 0x23, 0xbe,
- 0xcd, 0x23, 0x56, 0x91, 0xcf, 0x0e, 0x29, 0x9a, 0xc6, 0xa3, 0x21, 0xe4,
- 0x35, 0xd9, 0x05, 0xda, 0x91, 0x0c, 0x84, 0xd2, 0xcd, 0xc8, 0x49, 0x1d,
- 0xf9, 0x99, 0xcd, 0x7f, 0xa3, 0x30, 0x2f, 0x1b, 0x35, 0x13, 0xfd, 0x3a,
- 0xee, 0xe1, 0xdb, 0xf8, 0xbe, 0xde, 0x83, 0xbc, 0x0f, 0x2b, 0x19, 0xe8,
- 0x6e, 0x52, 0xe7, 0x33, 0xcc, 0x23, 0xaa, 0x88, 0xb7, 0x0a, 0xb1, 0x06,
- 0x79, 0xd5, 0x38, 0x73, 0xd7, 0xe7, 0x96, 0xaf, 0xcb, 0x95, 0x45, 0xfe,
- 0x06, 0xca, 0xb8, 0x7c, 0x90, 0xfe, 0xc0, 0x9c, 0x4b, 0x61, 0x6e, 0x85,
- 0xbe, 0x0c, 0xe3, 0x3a, 0x0c, 0xa8, 0x07, 0x39, 0x02, 0x72, 0xed, 0x4d,
- 0x2b, 0x09, 0x3e, 0xaf, 0xcb, 0xc6, 0x62, 0x58, 0x96, 0x2d, 0xe6, 0x45,
- 0x12, 0xcf, 0x02, 0x76, 0x63, 0xe5, 0x9a, 0xab, 0x13, 0x84, 0x47, 0xcd,
- 0x53, 0x40, 0x5e, 0x77, 0x40, 0xef, 0xfd, 0x65, 0xf7, 0x4c, 0x9a, 0x1a,
- 0xeb, 0xbc, 0x19, 0xd9, 0xa0, 0x3d, 0xd9, 0x7c, 0x93, 0x62, 0x6e, 0x70,
- 0x02, 0x3a, 0xcb, 0xdc, 0x9d, 0xf5, 0x00, 0xbe, 0x6b, 0x5c, 0x27, 0xef,
- 0xe8, 0x97, 0xfa, 0x21, 0x1b, 0xda, 0x3d, 0xdf, 0xc4, 0x10, 0x47, 0x15,
- 0x6d, 0xbd, 0xa8, 0x7d, 0x41, 0xb1, 0x3c, 0x83, 0x98, 0x02, 0x1f, 0xc0,
- 0xdf, 0x70, 0xa6, 0xa6, 0x70, 0x97, 0xe3, 0x80, 0xdb, 0x16, 0x4b, 0xd6,
- 0x8a, 0x3a, 0x2f, 0x53, 0xe7, 0x6f, 0xbf, 0xdf, 0xe4, 0x61, 0x3f, 0x6a,
- 0x0d, 0xba, 0x05, 0x1b, 0x52, 0x6b, 0x51, 0xf4, 0xf0, 0xc7, 0x6b, 0xa8,
- 0x2f, 0x4a, 0x7c, 0x1f, 0x42, 0x6d, 0x50, 0xe2, 0xdb, 0x49, 0x12, 0xfd,
- 0x08, 0xdf, 0x8b, 0x3c, 0xbf, 0x46, 0xfc, 0xa4, 0xc3, 0xf7, 0x2f, 0xcc,
- 0x25, 0xe9, 0x5f, 0xfc, 0x7c, 0xd2, 0xd5, 0x85, 0x53, 0x65, 0xfa, 0x10,
- 0xea, 0x75, 0x3f, 0xfc, 0x16, 0x75, 0xc1, 0xcd, 0x25, 0x57, 0x2a, 0xae,
- 0xcc, 0x66, 0xeb, 0x97, 0x75, 0x8c, 0xd8, 0x2f, 0x16, 0x74, 0x8c, 0xb2,
- 0xc3, 0x9a, 0x8e, 0x01, 0x97, 0x24, 0xa3, 0x7b, 0xca, 0xec, 0x75, 0xc9,
- 0xac, 0x8c, 0xc8, 0x0b, 0xda, 0x6f, 0xf9, 0x3e, 0x8b, 0x39, 0x64, 0x0c,
- 0xf2, 0x4b, 0xca, 0xf3, 0x67, 0xaf, 0x4b, 0xf6, 0x45, 0xfa, 0xad, 0xe1,
- 0x58, 0xab, 0x41, 0x5f, 0xe5, 0x48, 0x0d, 0xb1, 0xe9, 0x80, 0xcd, 0x7f,
- 0x07, 0x10, 0x42, 0x4d, 0xe7, 0x48, 0xf3, 0x68, 0xc2, 0x8e, 0x1b, 0xfd,
- 0x4f, 0xb6, 0x1a, 0x8c, 0x8d, 0xc3, 0xe6, 0x53, 0xe2, 0xbf, 0x47, 0xb5,
- 0xc8, 0x53, 0xfa, 0xad, 0x02, 0x66, 0xbb, 0xf0, 0x91, 0xfe, 0x1d, 0xe5,
- 0x66, 0x8a, 0xb2, 0xc6, 0x78, 0x8d, 0xf3, 0x85, 0xc8, 0xcd, 0x54, 0x93,
- 0x14, 0xef, 0x72, 0x9c, 0xa3, 0xa3, 0xa9, 0xdd, 0xee, 0xbf, 0x15, 0xf9,
- 0xc6, 0x5d, 0xae, 0x2f, 0x38, 0xea, 0x8d, 0x5f, 0x41, 0x4f, 0xdd, 0x66,
- 0xbc, 0x65, 0x7c, 0xe4, 0xbd, 0xa1, 0x5f, 0xe1, 0x37, 0x63, 0xef, 0x3c,
- 0x62, 0x2f, 0xe3, 0x65, 0x97, 0xe4, 0x0e, 0x6b, 0x9f, 0xc1, 0xf9, 0x82,
- 0x9b, 0x4b, 0x7b, 0x70, 0x95, 0x69, 0x99, 0xad, 0x30, 0x87, 0xda, 0x40,
- 0x2c, 0x1b, 0x82, 0xae, 0x32, 0xa6, 0x9d, 0x44, 0x3c, 0xe7, 0xef, 0xd2,
- 0x58, 0x5b, 0xe2, 0xbe, 0x44, 0x32, 0xae, 0xc0, 0xf3, 0x96, 0x4e, 0xdd,
- 0x8c, 0xf2, 0x3d, 0xea, 0xd2, 0x10, 0xee, 0xfd, 0x4f, 0x59, 0x5b, 0x0c,
- 0x68, 0x1d, 0xc9, 0xbe, 0x4c, 0xd9, 0xbb, 0xbf, 0x5b, 0x4b, 0xb7, 0x6b,
- 0x03, 0xcc, 0x03, 0x1e, 0x87, 0x5c, 0xf6, 0xdb, 0xd7, 0x19, 0xbb, 0xff,
- 0x5d, 0x59, 0xc3, 0xc9, 0xa7, 0x0c, 0xda, 0x36, 0xc6, 0x2b, 0x21, 0x59,
- 0x8a, 0x92, 0x7f, 0xc8, 0xcb, 0xa0, 0xed, 0xec, 0x24, 0x87, 0xed, 0x32,
- 0xf8, 0x4b, 0xc8, 0x80, 0xb2, 0xf4, 0x65, 0xc0, 0xef, 0x49, 0xdc, 0x17,
- 0x6b, 0x86, 0x7e, 0x5d, 0x47, 0x16, 0xeb, 0xee, 0xd9, 0xc5, 0x72, 0x23,
- 0xcd, 0xa4, 0x97, 0x77, 0x7a, 0x49, 0x72, 0xfa, 0x7e, 0xe7, 0x25, 0x57,
- 0xb9, 0x24, 0xfb, 0x2a, 0xf3, 0xf2, 0x98, 0xf5, 0x28, 0xf8, 0xbd, 0xe6,
- 0xcc, 0x58, 0xba, 0x56, 0x19, 0xcf, 0xff, 0x6f, 0xe7, 0x56, 0x1b, 0xdb,
- 0x56, 0x75, 0x86, 0x5f, 0x5f, 0xdb, 0x69, 0x1a, 0x9a, 0x70, 0xeb, 0x3a,
- 0x89, 0x9b, 0x66, 0xad, 0x1d, 0xdf, 0x7e, 0x88, 0xa4, 0xe8, 0x36, 0x64,
- 0x34, 0xea, 0x82, 0x62, 0x9c, 0x50, 0xc2, 0xe8, 0x44, 0xda, 0x75, 0x55,
- 0xb5, 0x31, 0x64, 0x39, 0xe9, 0x07, 0xd3, 0x06, 0xa3, 0xb0, 0x82, 0x18,
- 0x52, 0x8d, 0xdb, 0x6a, 0x9d, 0x96, 0xc6, 0xe9, 0x07, 0x6b, 0x37, 0x69,
- 0x9a, 0xe5, 0xa4, 0x2d, 0x48, 0x11, 0x2e, 0x88, 0x6e, 0xfb, 0xb1, 0x8d,
- 0x2a, 0x65, 0xec, 0xff, 0xf6, 0x67, 0xda, 0xd0, 0x16, 0x15, 0x18, 0xfc,
- 0xd8, 0xa4, 0xfe, 0xe0, 0x47, 0x25, 0xe8, 0xbc, 0xe7, 0x79, 0xcf, 0xbd,
- 0x8e, 0x6d, 0x82, 0x26, 0x2d, 0x52, 0xe4, 0x7b, 0xce, 0x3d, 0xf7, 0x9c,
- 0x73, 0xcf, 0xfb, 0xfd, 0xbe, 0xcf, 0xc5, 0xda, 0x13, 0x7d, 0x6b, 0xe5,
- 0x63, 0xf8, 0x1d, 0x27, 0x67, 0x6d, 0xc9, 0xd8, 0x83, 0xf2, 0x63, 0xcd,
- 0xe5, 0x33, 0x3e, 0x09, 0xc0, 0x27, 0x35, 0xb8, 0x02, 0x69, 0x77, 0x62,
- 0x37, 0x85, 0x3e, 0x65, 0x18, 0xb4, 0x8e, 0x1b, 0xbf, 0xd9, 0x36, 0xf7,
- 0x37, 0x9d, 0x81, 0xef, 0xee, 0x0e, 0xb4, 0xfb, 0x39, 0x5f, 0xe3, 0xdf,
- 0xfe, 0xc5, 0xab, 0xa1, 0x0d, 0xca, 0x0c, 0xf6, 0xf3, 0x96, 0xea, 0x59,
- 0x07, 0xbc, 0xc4, 0xdc, 0x74, 0x4c, 0xf3, 0x0f, 0xe1, 0x69, 0xea, 0xa8,
- 0xab, 0xd0, 0x51, 0x43, 0xd4, 0x5d, 0xc3, 0xb3, 0x2e, 0xf3, 0x03, 0x51,
- 0xf9, 0xf3, 0x14, 0xf5, 0x70, 0x5c, 0xfe, 0x34, 0xf5, 0x02, 0xf6, 0x93,
- 0x28, 0x32, 0x47, 0x79, 0x63, 0x26, 0x47, 0x3f, 0x49, 0xfd, 0xf9, 0xb4,
- 0xfb, 0xac, 0xda, 0x81, 0xb8, 0x95, 0x5f, 0x13, 0x56, 0x7d, 0xf3, 0xb4,
- 0xd6, 0x74, 0xe3, 0x56, 0xb7, 0xdc, 0x38, 0x6f, 0x74, 0x6c, 0x78, 0x3a,
- 0x1a, 0x18, 0x99, 0xa3, 0x5d, 0x4a, 0xc6, 0xb2, 0xd6, 0x0a, 0x39, 0x10,
- 0x65, 0xee, 0x39, 0x45, 0xfd, 0x0c, 0x5b, 0xd8, 0x6b, 0x67, 0xad, 0x66,
- 0xcf, 0xfe, 0xc4, 0x1a, 0xf4, 0xec, 0xd3, 0x9e, 0x9e, 0xe5, 0xbd, 0x14,
- 0x68, 0x4a, 0x5b, 0x94, 0x98, 0x19, 0xb5, 0x92, 0xb0, 0x79, 0xb8, 0x9e,
- 0xe7, 0xfc, 0x71, 0x39, 0x32, 0x7f, 0x18, 0xfe, 0x77, 0xaf, 0xbd, 0x87,
- 0x76, 0xd5, 0x1e, 0x22, 0x16, 0x07, 0xeb, 0x7f, 0xa9, 0x61, 0xae, 0xc7,
- 0xbd, 0xb9, 0x78, 0x1f, 0x72, 0x3e, 0xed, 0xc8, 0x04, 0x6c, 0xc9, 0x88,
- 0x6d, 0xf6, 0x5a, 0x3f, 0x76, 0x77, 0x75, 0xdd, 0x13, 0x05, 0xc7, 0xc3,
- 0x85, 0xe1, 0x17, 0xbe, 0xd0, 0xd7, 0x23, 0x5c, 0x93, 0xeb, 0xb5, 0x49,
- 0x7a, 0x1f, 0xf4, 0xcb, 0x34, 0xff, 0x73, 0x5e, 0xed, 0x0a, 0xf1, 0x4a,
- 0xb4, 0x6b, 0x19, 0xdb, 0xf4, 0x80, 0x37, 0xdf, 0xb6, 0x0e, 0x69, 0x89,
- 0xd6, 0x8c, 0x67, 0x6e, 0x85, 0xed, 0xb8, 0xe4, 0xe6, 0xf9, 0x5b, 0xa9,
- 0x44, 0x9c, 0x26, 0xd9, 0x63, 0xaf, 0x6b, 0x98, 0x63, 0x2b, 0xfa, 0x8c,
- 0x4f, 0x10, 0x9c, 0x0e, 0x78, 0xbe, 0xc5, 0x06, 0xfa, 0x4d, 0xde, 0x75,
- 0xb3, 0xe6, 0x64, 0xe2, 0x56, 0x57, 0xc3, 0x7b, 0x6c, 0xa8, 0xda, 0xe1,
- 0xb8, 0x45, 0xdd, 0xd9, 0x14, 0x95, 0x36, 0xf2, 0x50, 0x45, 0xfd, 0xf8,
- 0x90, 0x63, 0xb0, 0x16, 0x51, 0xe7, 0x60, 0x07, 0x73, 0xf6, 0x6f, 0xeb,
- 0xb9, 0xb5, 0xd2, 0x27, 0xc0, 0x35, 0xf8, 0xe4, 0x73, 0xf9, 0x5e, 0xe6,
- 0x7a, 0x31, 0x7f, 0x0b, 0xe7, 0x77, 0xbd, 0x73, 0x4e, 0xb8, 0x39, 0xeb,
- 0x7e, 0xc9, 0x9e, 0x37, 0xfc, 0x97, 0x76, 0xc0, 0x7b, 0x6d, 0x68, 0xcf,
- 0xd1, 0x26, 0x7c, 0xd1, 0x3c, 0xbe, 0x6d, 0xd8, 0xa2, 0xb6, 0xe1, 0x78,
- 0x81, 0xfc, 0x49, 0xbe, 0xf4, 0xf9, 0xd1, 0xd7, 0x79, 0xe4, 0x51, 0xea,
- 0xd9, 0x41, 0x39, 0x53, 0xe0, 0xd9, 0xa4, 0xb4, 0xa6, 0xb5, 0xf1, 0xec,
- 0x84, 0xe2, 0xb1, 0x7a, 0xa6, 0x13, 0x17, 0x73, 0x32, 0x2c, 0x57, 0x5d,
- 0x9e, 0x59, 0xa2, 0x98, 0x09, 0xb6, 0xd6, 0xbc, 0xff, 0x3e, 0x3d, 0xb3,
- 0xb0, 0xfa, 0x8c, 0x31, 0x8c, 0x7d, 0xc9, 0xa3, 0x77, 0x9b, 0x9e, 0x6d,
- 0xa6, 0x8e, 0x3e, 0x8f, 0xea, 0x39, 0x85, 0xa1, 0x13, 0x59, 0xc7, 0x0f,
- 0x47, 0xf8, 0x0c, 0xd7, 0xa5, 0xcf, 0xc7, 0xb5, 0xc8, 0x7b, 0x3d, 0xb0,
- 0xd8, 0xfd, 0x12, 0xdc, 0x01, 0xd1, 0xdf, 0xc1, 0x3a, 0x72, 0x00, 0xb2,
- 0xba, 0xd1, 0x60, 0x5f, 0xc6, 0x8d, 0xaf, 0x91, 0xb1, 0xde, 0xc2, 0x39,
- 0x22, 0x56, 0x81, 0x1f, 0x7d, 0xfc, 0xa7, 0x77, 0x30, 0x5f, 0xc6, 0xf3,
- 0xd7, 0x07, 0x30, 0x3f, 0xcf, 0x82, 0x32, 0x36, 0xb5, 0x8d, 0xbc, 0x3a,
- 0xaa, 0xf5, 0x41, 0x3e, 0x43, 0x39, 0xe6, 0x99, 0x91, 0x2e, 0x7f, 0xc3,
- 0xf3, 0x6c, 0x6f, 0x6d, 0xa0, 0x63, 0xd2, 0xdb, 0x9f, 0x7f, 0x3f, 0x2c,
- 0xe1, 0x0e, 0xea, 0xb8, 0xa8, 0x24, 0xa7, 0x19, 0xb3, 0xc0, 0x76, 0x8d,
- 0x73, 0xae, 0xff, 0xad, 0x8b, 0x33, 0xff, 0xa7, 0x2e, 0xce, 0x58, 0x1f,
- 0x29, 0xef, 0x84, 0x35, 0x8f, 0xf5, 0xc5, 0x74, 0x2d, 0xd6, 0xd1, 0xd5,
- 0xaf, 0xdd, 0x47, 0xab, 0x74, 0xfc, 0x51, 0x81, 0xf6, 0x2a, 0xa5, 0x39,
- 0xe5, 0x7f, 0x4e, 0xf1, 0x6c, 0xb9, 0xc7, 0xab, 0xdc, 0xe3, 0xf0, 0x82,
- 0x62, 0x20, 0xbf, 0xa6, 0x32, 0x7c, 0xb2, 0x40, 0x1d, 0xd3, 0x2a, 0xb3,
- 0x33, 0xbe, 0x9e, 0x19, 0xf3, 0x7c, 0xdc, 0xfc, 0x9a, 0x26, 0xd5, 0x33,
- 0xf0, 0x6e, 0x9c, 0x11, 0xcf, 0xbe, 0x74, 0x4b, 0xe9, 0x3c, 0xed, 0x6e,
- 0x12, 0x7d, 0xd1, 0x40, 0x69, 0x8e, 0xb5, 0x49, 0x62, 0x50, 0x86, 0x85,
- 0x75, 0xff, 0x11, 0xfb, 0x38, 0xe4, 0x2d, 0x26, 0xef, 0x4f, 0xd1, 0xa7,
- 0x6f, 0x82, 0x6f, 0xdc, 0xd6, 0x70, 0xbe, 0xdb, 0xab, 0x3e, 0x61, 0x3d,
- 0xdd, 0x37, 0x74, 0x4a, 0x0b, 0xf9, 0xdc, 0xb1, 0x6f, 0x08, 0x7d, 0x30,
- 0x5e, 0x67, 0x11, 0x0b, 0x30, 0xf6, 0x88, 0x6b, 0xec, 0x51, 0x2a, 0xb2,
- 0xaf, 0xd5, 0xcb, 0x2b, 0xb5, 0x2a, 0xaf, 0x90, 0xdf, 0x32, 0xea, 0x7f,
- 0x0f, 0xa9, 0xce, 0xca, 0x4f, 0xf5, 0x1a, 0xfc, 0x8a, 0x1d, 0x53, 0xde,
- 0x93, 0x3a, 0xde, 0x8b, 0x79, 0x6b, 0x3f, 0xdc, 0x69, 0x7c, 0x2b, 0x5b,
- 0xf5, 0x4d, 0x58, 0xc7, 0xd1, 0xae, 0x70, 0x7e, 0xf2, 0x06, 0x79, 0x84,
- 0x3a, 0xcf, 0x1f, 0xe7, 0xd3, 0xc3, 0x6f, 0x73, 0x3c, 0xf9, 0xbf, 0x16,
- 0x8b, 0xe0, 0xcb, 0xaa, 0xdf, 0xe7, 0xcb, 0x1d, 0xef, 0xd5, 0xda, 0x04,
- 0xca, 0x5d, 0x6d, 0x7d, 0xd2, 0x96, 0xc8, 0xf4, 0x12, 0x5d, 0xd2, 0xfd,
- 0xdc, 0xff, 0x4b, 0xcc, 0xed, 0x42, 0xde, 0x96, 0xa3, 0xcd, 0x51, 0xa5,
- 0x4d, 0x06, 0xb4, 0x89, 0x28, 0x6d, 0x18, 0xef, 0x3d, 0xe3, 0xf1, 0x5b,
- 0x2b, 0xce, 0x8b, 0xb9, 0x5a, 0xe8, 0xba, 0xbd, 0xd4, 0xf9, 0xcf, 0x77,
- 0x6a, 0x7d, 0xd0, 0xa1, 0xee, 0x5b, 0x05, 0x7d, 0xc6, 0xf6, 0x66, 0xf5,
- 0x47, 0x4c, 0xbc, 0x15, 0xd7, 0x3c, 0x68, 0x10, 0xfa, 0xb9, 0x34, 0x05,
- 0x5f, 0x8d, 0x78, 0xb7, 0x3a, 0x5a, 0x7d, 0xc7, 0x3b, 0xaf, 0x92, 0xd2,
- 0x86, 0x32, 0x40, 0xbd, 0xb9, 0x1a, 0xf3, 0xed, 0x8e, 0xf6, 0x81, 0xbf,
- 0x7e, 0x81, 0xfe, 0x8d, 0x1a, 0x4f, 0x04, 0x21, 0xf3, 0x37, 0xa7, 0x3a,
- 0xbc, 0x18, 0xce, 0x41, 0x1b, 0x71, 0xeb, 0x54, 0x84, 0x31, 0x05, 0xda,
- 0x5b, 0xa4, 0x69, 0x1a, 0xf1, 0x2b, 0xf4, 0xf8, 0x82, 0xda, 0xa3, 0x3e,
- 0xdc, 0xbf, 0x8b, 0x18, 0x3f, 0x5c, 0x1f, 0xc6, 0x73, 0xbd, 0x06, 0x8b,
- 0x10, 0xdd, 0xa4, 0x67, 0x5a, 0x9a, 0x4a, 0xc4, 0x0e, 0x8a, 0xd7, 0x37,
- 0xee, 0xaa, 0x3e, 0x58, 0xda, 0xd7, 0x43, 0xb2, 0xbb, 0x6a, 0x2f, 0x18,
- 0x47, 0xc3, 0x87, 0x9f, 0x31, 0xf6, 0x20, 0x5f, 0xec, 0x53, 0x5c, 0x54,
- 0x70, 0x68, 0x1e, 0x67, 0x49, 0x9f, 0x74, 0x11, 0x7e, 0xb8, 0x8b, 0x33,
- 0xa4, 0xdf, 0x5d, 0x39, 0x76, 0xc2, 0x4d, 0xb1, 0x3e, 0x06, 0x7d, 0x70,
- 0x4c, 0x46, 0x10, 0x17, 0x8c, 0x04, 0xdb, 0x98, 0x57, 0x86, 0x6f, 0x98,
- 0xf3, 0x72, 0x8f, 0x7d, 0xcc, 0x99, 0xca, 0xd9, 0x39, 0xee, 0x9d, 0xb2,
- 0x6d, 0x62, 0xef, 0xd2, 0x14, 0xf7, 0x6b, 0xf2, 0x10, 0x6c, 0x5b, 0xd3,
- 0x2e, 0x7e, 0x79, 0x16, 0x03, 0xf8, 0x1d, 0x84, 0x3c, 0x70, 0x2c, 0x7e,
- 0xe7, 0x16, 0xe5, 0xdd, 0xf3, 0xbe, 0x6d, 0x0f, 0xc8, 0x3b, 0x4e, 0xe5,
- 0xd8, 0x71, 0x77, 0x0d, 0xcf, 0xc0, 0xcd, 0xb1, 0x66, 0xed, 0x38, 0x6e,
- 0x5e, 0x2a, 0x95, 0x05, 0x77, 0x61, 0x8d, 0xa5, 0xb4, 0xa4, 0xfc, 0xff,
- 0x03, 0x67, 0x78, 0xfd, 0x3e, 0x4b, 0x0c, 0xfd, 0x48, 0x9b, 0xcf, 0xd7,
- 0xfe, 0x6a, 0x6d, 0x81, 0xaf, 0xff, 0xc8, 0x8f, 0xe4, 0xcb, 0x45, 0xd9,
- 0xa9, 0xfa, 0x7f, 0xb9, 0xe7, 0x6a, 0x75, 0xbf, 0xef, 0xdf, 0x52, 0xbf,
- 0x93, 0x17, 0x63, 0x1a, 0x1f, 0x6c, 0x9a, 0x6e, 0xd4, 0x09, 0x4f, 0x78,
- 0x75, 0x85, 0xe5, 0x78, 0x6f, 0xbf, 0xa7, 0x17, 0x52, 0xea, 0x3b, 0xa7,
- 0x6c, 0xea, 0x07, 0xee, 0xa7, 0x45, 0x26, 0x2e, 0xdc, 0x01, 0x4d, 0x7c,
- 0x1d, 0xcc, 0xb8, 0xcf, 0xd7, 0x1d, 0x6d, 0x9e, 0x2f, 0x6c, 0x49, 0xcf,
- 0x59, 0xfa, 0x4e, 0x0e, 0xf4, 0x68, 0xbb, 0x64, 0xc6, 0x83, 0x92, 0x3c,
- 0x1b, 0x8b, 0x19, 0x5f, 0x97, 0xfc, 0x07, 0x79, 0xd3, 0x3e, 0xad, 0x45,
- 0xa1, 0xff, 0x6e, 0xe1, 0xda, 0x86, 0x9f, 0x21, 0xcf, 0x7b, 0xfd, 0x7b,
- 0x76, 0x03, 0x8f, 0xee, 0xf0, 0x78, 0x94, 0xf7, 0x2d, 0x53, 0xff, 0xc0,
- 0xd8, 0x9e, 0xb3, 0xdc, 0xa3, 0x79, 0xae, 0xe7, 0xac, 0x89, 0xd7, 0xeb,
- 0x9f, 0xeb, 0xab, 0x3e, 0x87, 0xfb, 0xf0, 0x7d, 0xcd, 0xdc, 0x3b, 0x07,
- 0xe1, 0xd3, 0xf5, 0xd1, 0xe6, 0xd0, 0x7e, 0x6f, 0x74, 0x77, 0x0a, 0xf9,
- 0x3d, 0xe1, 0xf1, 0x1c, 0xf5, 0x4d, 0xc4, 0xd3, 0x37, 0x4b, 0xf6, 0x65,
- 0xc4, 0xe0, 0x4f, 0x98, 0x13, 0xa9, 0xb1, 0x2f, 0x4f, 0x98, 0x77, 0xab,
- 0xb3, 0x2f, 0x77, 0x7b, 0xf3, 0xf8, 0xf7, 0x7c, 0xbd, 0xe2, 0xb7, 0x7d,
- 0xbd, 0xd2, 0xe8, 0xd3, 0xfa, 0xb4, 0xaf, 0xed, 0xaf, 0x8f, 0xf9, 0xf2,
- 0xcb, 0xe6, 0x5d, 0xb2, 0x88, 0xd9, 0xe8, 0x53, 0x26, 0x72, 0x06, 0x2f,
- 0x6d, 0x9d, 0xb1, 0x88, 0xfb, 0x70, 0x7e, 0x22, 0xe9, 0xc8, 0x1d, 0x8d,
- 0xad, 0x4f, 0x5e, 0x18, 0xd3, 0x3c, 0x4f, 0xc9, 0xf5, 0xf4, 0x4e, 0x74,
- 0x17, 0xe4, 0xea, 0x4a, 0x64, 0x09, 0x53, 0x34, 0x73, 0x34, 0x0d, 0x3b,
- 0x94, 0xd2, 0x7a, 0xd9, 0xf7, 0xb0, 0xdf, 0x41, 0xc5, 0x73, 0xad, 0x74,
- 0x5e, 0x94, 0x47, 0xec, 0x8a, 0xd6, 0x6e, 0x9a, 0x87, 0x8a, 0x47, 0x9b,
- 0x4f, 0xfb, 0x7c, 0x4f, 0x7e, 0x9a, 0x39, 0x3a, 0x31, 0x53, 0x19, 0x0e,
- 0x6d, 0xeb, 0xb5, 0xf3, 0x42, 0xbc, 0xfe, 0xb0, 0x1c, 0x52, 0xdc, 0xf0,
- 0xab, 0xb8, 0xbf, 0x97, 0xf1, 0x65, 0x22, 0xa4, 0x78, 0xe0, 0x44, 0x6c,
- 0x12, 0xb2, 0x98, 0x75, 0x89, 0xef, 0x5f, 0xa5, 0x38, 0xff, 0x92, 0xd0,
- 0xcf, 0x22, 0xa6, 0xe0, 0x05, 0x39, 0xe8, 0x6e, 0x74, 0x17, 0xc4, 0xf8,
- 0xbf, 0x59, 0xad, 0x09, 0xad, 0x90, 0x49, 0x37, 0xd4, 0x9c, 0x2e, 0x1b,
- 0x19, 0x18, 0x0d, 0xa6, 0x56, 0x9e, 0x70, 0xa2, 0xcd, 0x3b, 0xcb, 0x90,
- 0xf1, 0x32, 0xf4, 0x7f, 0x39, 0x16, 0x18, 0x51, 0x6c, 0xda, 0x57, 0x24,
- 0xdd, 0x41, 0x3f, 0x9f, 0xfa, 0xe4, 0x01, 0xb9, 0x69, 0x6f, 0x96, 0x9b,
- 0x5b, 0x88, 0xc3, 0xec, 0x47, 0x9b, 0xba, 0x64, 0x10, 0x7d, 0x49, 0xf4,
- 0x35, 0x2b, 0x3f, 0x6a, 0x7c, 0x06, 0x9d, 0x75, 0xd3, 0xa6, 0xae, 0x5a,
- 0xcf, 0x5f, 0xbc, 0xeb, 0x22, 0x68, 0x42, 0x6c, 0xc7, 0x56, 0xb4, 0xa9,
- 0xe3, 0xec, 0x86, 0xfe, 0x2e, 0xb4, 0xef, 0xc3, 0x1c, 0x4d, 0xfa, 0x7e,
- 0x96, 0xb3, 0xcd, 0xd4, 0x39, 0xeb, 0xc6, 0xac, 0x6e, 0x68, 0xff, 0xb1,
- 0xdd, 0xe0, 0x13, 0x3e, 0x25, 0xbd, 0x73, 0x29, 0xd9, 0xd5, 0x59, 0xdf,
- 0xfe, 0x77, 0x43, 0xbb, 0x4d, 0x56, 0xb6, 0x93, 0x0c, 0x4f, 0x75, 0xd4,
- 0xf7, 0xfb, 0xfc, 0xe4, 0xb7, 0x3b, 0xf1, 0xbe, 0x09, 0x18, 0xbc, 0xa4,
- 0xc6, 0x52, 0x37, 0xa3, 0x5c, 0xeb, 0x83, 0x86, 0x67, 0x78, 0xcd, 0x67,
- 0xf8, 0x2c, 0xf3, 0x7a, 0x9f, 0xb1, 0x1f, 0xcf, 0x30, 0x27, 0xc0, 0xbc,
- 0x06, 0x79, 0x76, 0xb9, 0x38, 0x8b, 0x63, 0x3e, 0x9f, 0x6f, 0xc8, 0x54,
- 0x79, 0xcf, 0xd7, 0x2b, 0xb1, 0x2a, 0x56, 0x6d, 0x67, 0xc1, 0xcf, 0x09,
- 0x93, 0x76, 0x5a, 0x93, 0x8a, 0xdd, 0x00, 0x9d, 0x0f, 0x80, 0xce, 0x0f,
- 0x05, 0x19, 0x17, 0xb6, 0x78, 0xb4, 0x76, 0x64, 0xa4, 0xfc, 0x5b, 0xc8,
- 0x38, 0x79, 0x14, 0x3e, 0x45, 0xd9, 0xf2, 0xf0, 0x19, 0x03, 0xb0, 0x69,
- 0xae, 0x04, 0x35, 0xef, 0x80, 0xf8, 0x7e, 0xf6, 0xba, 0x8c, 0x4c, 0x31,
- 0x27, 0x40, 0x7e, 0x66, 0x5c, 0x9f, 0xc2, 0xbd, 0x5b, 0x18, 0xeb, 0x42,
- 0x86, 0xc7, 0xc0, 0xaf, 0x21, 0x71, 0xa6, 0xb7, 0x4a, 0x6e, 0x7c, 0x4c,
- 0x7d, 0x80, 0x1e, 0xd8, 0xa8, 0xe3, 0xee, 0xa8, 0x9c, 0xb8, 0xb2, 0x01,
- 0xb2, 0xca, 0xb8, 0x5f, 0x73, 0x1a, 0x95, 0xb0, 0xfa, 0xe6, 0xf4, 0x39,
- 0x98, 0x87, 0x33, 0x35, 0x66, 0x23, 0xb7, 0x93, 0x31, 0x69, 0x1b, 0x95,
- 0x99, 0x0b, 0xb6, 0xe2, 0x5d, 0x52, 0x72, 0xa7, 0x42, 0xda, 0x65, 0xf7,
- 0xc6, 0xa1, 0xab, 0xe8, 0xcb, 0x9f, 0x8c, 0x98, 0xb3, 0x7c, 0x74, 0x2d,
- 0x63, 0xe2, 0xe4, 0x74, 0xed, 0x1c, 0x8a, 0x91, 0xc1, 0xbd, 0xd7, 0xda,
- 0x8d, 0xcc, 0x30, 0x3e, 0xfe, 0xa0, 0x92, 0x8a, 0x72, 0x4d, 0x8e, 0x65,
- 0xed, 0x96, 0x3c, 0xc2, 0xbd, 0x7d, 0xea, 0xf1, 0xf2, 0xcf, 0x30, 0x5f,
- 0x5c, 0x7a, 0x5e, 0x1f, 0xd3, 0xb8, 0xfe, 0x78, 0x5d, 0x0c, 0x6b, 0xf2,
- 0x05, 0x26, 0x8e, 0xbd, 0x2e, 0x93, 0xf3, 0xa4, 0x0f, 0x6d, 0x7c, 0x40,
- 0x5e, 0x73, 0x7a, 0xed, 0x27, 0xb5, 0xd6, 0x98, 0x48, 0xb1, 0x3e, 0xd3,
- 0xe2, 0x24, 0xed, 0x59, 0x09, 0x0d, 0x7e, 0x15, 0xd7, 0x8c, 0x6b, 0xf3,
- 0x6e, 0xaf, 0xfb, 0xa4, 0xf8, 0x38, 0x90, 0x8d, 0xa9, 0x15, 0x81, 0xdb,
- 0x95, 0xeb, 0x7b, 0x39, 0xc6, 0xe0, 0x40, 0x24, 0x40, 0x5a, 0xbd, 0xb7,
- 0x9e, 0xf8, 0x99, 0xfa, 0xfc, 0xdf, 0x83, 0x4f, 0xef, 0x19, 0x48, 0x9c,
- 0x62, 0x0c, 0x1b, 0x76, 0xbe, 0xb5, 0xd6, 0xbc, 0x6b, 0x2e, 0xb7, 0x5a,
- 0xb4, 0x7e, 0x76, 0xe4, 0x23, 0x87, 0x78, 0x88, 0x44, 0x6c, 0x85, 0xc5,
- 0x3c, 0x38, 0x75, 0x1c, 0x6b, 0x2a, 0xcc, 0xb9, 0x11, 0xc7, 0xdf, 0x2c,
- 0x97, 0xfb, 0x2c, 0x79, 0x30, 0x94, 0x8a, 0x5b, 0xb2, 0x29, 0x7e, 0x56,
- 0xb0, 0x26, 0xeb, 0x2b, 0xf3, 0x89, 0x1c, 0xc7, 0x87, 0xa6, 0x39, 0x5f,
- 0x5c, 0xe3, 0x95, 0xe4, 0xa6, 0x4a, 0xe5, 0x19, 0x57, 0x02, 0xc9, 0x7b,
- 0x3f, 0xac, 0xb0, 0x16, 0x6e, 0xbd, 0xfe, 0x45, 0x38, 0x05, 0xea, 0x8a,
- 0x55, 0x93, 0x06, 0x73, 0x78, 0xe2, 0x48, 0xcf, 0x3c, 0xdb, 0xdf, 0x7d,
- 0xc4, 0xb4, 0x4f, 0xa1, 0xdd, 0xe4, 0x61, 0x9d, 0xa6, 0x8e, 0xf4, 0x14,
- 0x9f, 0x5a, 0x6b, 0xe2, 0xef, 0x45, 0xc5, 0x7f, 0xbd, 0x5d, 0x17, 0xd3,
- 0xa4, 0x02, 0xe3, 0x85, 0xb1, 0xc0, 0x58, 0xc1, 0xea, 0x6b, 0x06, 0xad,
- 0xe6, 0x5c, 0xe6, 0x6a, 0xfc, 0x9c, 0x15, 0xf3, 0xfd, 0x22, 0xdf, 0x57,
- 0x8c, 0x14, 0x6b, 0x8a, 0x96, 0xfa, 0x42, 0x07, 0xe6, 0x98, 0xe3, 0x8f,
- 0xa8, 0x3e, 0x38, 0x38, 0xdf, 0x26, 0x79, 0x7b, 0x8d, 0xe4, 0x55, 0xc6,
- 0xa3, 0xaa, 0x03, 0x2c, 0xe7, 0x5e, 0xf4, 0x71, 0xdf, 0x4f, 0x28, 0x2e,
- 0xe2, 0xcd, 0x42, 0x17, 0xda, 0xcc, 0x35, 0x6f, 0x6f, 0xe8, 0xaf, 0xad,
- 0xcb, 0x26, 0x6c, 0xcb, 0x6a, 0xac, 0xc9, 0xb2, 0xaf, 0xb1, 0x16, 0x7b,
- 0x52, 0xae, 0x93, 0x6f, 0xca, 0x7e, 0xce, 0xdd, 0xf5, 0x72, 0xee, 0xdf,
- 0xee, 0x32, 0x18, 0x61, 0xc9, 0x84, 0x86, 0x9a, 0xfb, 0x8e, 0x4f, 0x05,
- 0x6f, 0x2d, 0xe5, 0x4f, 0xd1, 0x9e, 0xaf, 0xd6, 0xca, 0x71, 0xef, 0x39,
- 0x62, 0xc5, 0xe1, 0x57, 0xe4, 0xbc, 0xef, 0x0e, 0x78, 0xbf, 0xfa, 0xfc,
- 0xff, 0xd8, 0x53, 0x8b, 0xd6, 0xd9, 0xad, 0xba, 0x3a, 0xfb, 0xe3, 0x78,
- 0x96, 0x35, 0xf6, 0x5c, 0xa5, 0x09, 0xbc, 0xdb, 0x44, 0x9c, 0x48, 0x75,
- 0x3c, 0x75, 0xbc, 0xea, 0x72, 0x9d, 0x6b, 0xa7, 0x37, 0x57, 0x10, 0x7a,
- 0x7e, 0x62, 0xca, 0x1f, 0x73, 0x4c, 0x56, 0xf4, 0x27, 0x62, 0x41, 0x8b,
- 0x63, 0x8c, 0xbe, 0x4f, 0xbb, 0xc7, 0xa0, 0xc7, 0xa9, 0xf3, 0xf9, 0xde,
- 0x0e, 0x7c, 0x3d, 0xea, 0x02, 0xea, 0x73, 0xb5, 0x01, 0xf1, 0x3c, 0x74,
- 0xfd, 0x48, 0x59, 0x73, 0xf9, 0xb1, 0x87, 0x83, 0x89, 0x99, 0xac, 0xea,
- 0x06, 0xf8, 0x7b, 0xe5, 0x6b, 0xcc, 0x07, 0x9d, 0x92, 0x40, 0x6d, 0x9d,
- 0x86, 0xb1, 0x19, 0x6b, 0x1a, 0xad, 0xd0, 0x0d, 0x22, 0x57, 0xc1, 0x1b,
- 0x6f, 0xcc, 0x91, 0x5f, 0x83, 0x1d, 0x26, 0xbe, 0x5a, 0xd8, 0x6e, 0x49,
- 0x87, 0xd6, 0x3e, 0xf3, 0x4e, 0x84, 0xfe, 0xc9, 0x70, 0xb2, 0x1f, 0x7e,
- 0xb6, 0x62, 0x0f, 0x98, 0xaf, 0x9c, 0x40, 0x3c, 0x56, 0x9b, 0x63, 0x81,
- 0x7c, 0x8d, 0xb3, 0x3f, 0x0b, 0xbf, 0x72, 0xa9, 0xee, 0x91, 0x2f, 0x9e,
- 0xd0, 0xdc, 0x66, 0x69, 0xae, 0x55, 0x75, 0x6c, 0xa9, 0xf8, 0x30, 0xce,
- 0x45, 0x36, 0x5b, 0x43, 0x79, 0xaf, 0x3f, 0x2c, 0xc5, 0x22, 0xdb, 0xd2,
- 0xdd, 0xa4, 0xe7, 0xee, 0xd7, 0x76, 0x6c, 0x99, 0x85, 0xaf, 0x58, 0x9c,
- 0x77, 0xf0, 0xbf, 0x05, 0xff, 0x7d, 0xf8, 0xdf, 0x25, 0xe9, 0x69, 0xfa,
- 0xaf, 0xac, 0xe5, 0xb4, 0x36, 0xac, 0x1f, 0xf6, 0x70, 0xe0, 0xf4, 0x6b,
- 0x4d, 0x9c, 0x93, 0x2f, 0x36, 0xca, 0x09, 0xf3, 0xa4, 0xbe, 0x8e, 0x60,
- 0xbe, 0xd4, 0xaf, 0xf5, 0xd5, 0xd6, 0xb0, 0x2c, 0xaf, 0xee, 0x45, 0x9e,
- 0x6e, 0x91, 0x83, 0x45, 0xbf, 0x76, 0x15, 0x93, 0x43, 0xd5, 0xda, 0x95,
- 0x64, 0x82, 0x43, 0xb7, 0x1f, 0xcb, 0x4e, 0x29, 0x9e, 0xc0, 0xb2, 0x86,
- 0xae, 0x3f, 0x36, 0x39, 0xff, 0xce, 0x63, 0x4b, 0x98, 0x70, 0xdc, 0x9b,
- 0x5f, 0x0e, 0x33, 0x44, 0x2c, 0x1d, 0xbf, 0x93, 0x53, 0xdf, 0x0d, 0xfb,
- 0xf6, 0x63, 0x1e, 0xe2, 0xec, 0xe2, 0xf6, 0x12, 0x7e, 0xd9, 0x8f, 0x47,
- 0x89, 0x23, 0xe5, 0x73, 0xb5, 0xd8, 0x8f, 0x10, 0xce, 0x5f, 0x02, 0x96,
- 0x93, 0xc3, 0x3e, 0x2e, 0x76, 0x19, 0x3f, 0x90, 0x38, 0xd3, 0x44, 0x0d,
- 0xf6, 0xc8, 0xc7, 0x9a, 0x5e, 0xc4, 0x5c, 0x19, 0xf9, 0x7d, 0xf9, 0x71,
- 0xf9, 0x75, 0x79, 0x0c, 0xf2, 0x3d, 0x89, 0x39, 0xf7, 0xcb, 0xaf, 0xca,
- 0x7b, 0xe5, 0x5a, 0x79, 0x5c, 0xde, 0x2a, 0xef, 0x42, 0x4c, 0x35, 0x4a,
- 0xac, 0xa7, 0x87, 0x95, 0x1e, 0x96, 0x89, 0x73, 0x8a, 0x01, 0xbc, 0x45,
- 0xbf, 0xe7, 0x88, 0xfa, 0xd9, 0x01, 0xf2, 0xf4, 0x6f, 0x18, 0xcf, 0x13,
- 0x9b, 0x59, 0x2c, 0xfb, 0x18, 0x8e, 0x43, 0xdd, 0x58, 0xdb, 0xe6, 0x37,
- 0x29, 0x23, 0xe7, 0x22, 0x81, 0xd1, 0x73, 0xa1, 0xc0, 0x43, 0xfa, 0x7d,
- 0x0b, 0xeb, 0x9d, 0x15, 0x39, 0xe1, 0x3a, 0xe4, 0xcd, 0xc1, 0x11, 0xc8,
- 0xc2, 0x28, 0x54, 0xfd, 0x23, 0xce, 0x1a, 0x01, 0x49, 0x53, 0x1f, 0xc3,
- 0xcf, 0x4c, 0x9e, 0x76, 0x25, 0x5b, 0x98, 0x0d, 0x18, 0x3c, 0x9a, 0x8d,
- 0x76, 0x1f, 0xda, 0xbf, 0xf4, 0xda, 0x3b, 0x24, 0x7b, 0x41, 0x52, 0xef,
- 0xab, 0x3f, 0xfc, 0x73, 0xaf, 0x6f, 0x10, 0x7d, 0xe0, 0xcc, 0x57, 0xd8,
- 0xf7, 0x8a, 0xd7, 0xc7, 0x33, 0x61, 0xad, 0x3e, 0xae, 0x7c, 0x95, 0xb5,
- 0xc7, 0x85, 0xdf, 0x2f, 0x18, 0x4c, 0xe8, 0xfb, 0x5d, 0x46, 0xb7, 0x11,
- 0x13, 0xf8, 0xaf, 0x2e, 0xc6, 0x60, 0x45, 0xc8, 0xd7, 0x7a, 0xe8, 0xc4,
- 0xbf, 0x6f, 0x5e, 0x6a, 0x5b, 0x43, 0x9f, 0xd4, 0x60, 0xb4, 0x3f, 0x91,
- 0x9e, 0xf9, 0xdb, 0x1e, 0x9e, 0xf7, 0x30, 0xde, 0x0d, 0x67, 0x55, 0x20,
- 0x6e, 0x3c, 0x0e, 0xd9, 0x6e, 0x95, 0x35, 0x67, 0x48, 0xaf, 0x5e, 0xe8,
- 0xea, 0x14, 0xe4, 0xd6, 0x95, 0xb9, 0x72, 0x28, 0x30, 0x52, 0x48, 0x89,
- 0xc1, 0x53, 0x5b, 0x92, 0x89, 0xa6, 0xe4, 0xe4, 0x40, 0x62, 0x0b, 0xf3,
- 0x90, 0xd9, 0x7e, 0x57, 0x2e, 0x95, 0x69, 0x8f, 0x73, 0x72, 0x79, 0x20,
- 0xe1, 0x16, 0x85, 0xb8, 0x18, 0x57, 0x2e, 0x43, 0x36, 0xff, 0x70, 0x6e,
- 0x97, 0x1c, 0x2a, 0xa8, 0x1f, 0xdc, 0x1b, 0x96, 0x97, 0xe5, 0xd2, 0xc0,
- 0xcb, 0xb7, 0x2e, 0xb9, 0x93, 0x38, 0x53, 0xf2, 0xe1, 0x81, 0x6e, 0xb3,
- 0x6f, 0xc5, 0x21, 0x09, 0xf3, 0x21, 0x5a, 0x53, 0x73, 0x56, 0x48, 0x7a,
- 0x5f, 0xc4, 0x8b, 0xcb, 0xe1, 0x73, 0x07, 0xee, 0x33, 0xf5, 0x94, 0x80,
- 0xbf, 0xcf, 0x30, 0xfc, 0x18, 0x3e, 0xe7, 0xd3, 0xc6, 0x9f, 0xa7, 0x2b,
- 0x90, 0xbe, 0xd0, 0x26, 0xa1, 0x57, 0xbe, 0x0c, 0xba, 0x86, 0xe4, 0x40,
- 0x7f, 0xa5, 0xf2, 0x0d, 0x37, 0x14, 0x9f, 0x44, 0x8c, 0x82, 0xfd, 0xcb,
- 0xea, 0xd3, 0xed, 0xa0, 0x49, 0xb3, 0x44, 0x4f, 0xfb, 0xeb, 0xad, 0xf0,
- 0xb0, 0x0c, 0xe7, 0x57, 0x1b, 0x5b, 0xe6, 0x63, 0x1b, 0xfc, 0xf9, 0x0c,
- 0xa6, 0xac, 0xc7, 0xea, 0x0f, 0x78, 0xdf, 0x49, 0x78, 0xed, 0x7b, 0x03,
- 0x0f, 0x86, 0x3a, 0x24, 0xe4, 0xfc, 0x70, 0x1d, 0xb1, 0x91, 0x0b, 0x05,
- 0xbf, 0x1f, 0x7e, 0x62, 0xc8, 0xf7, 0x87, 0x65, 0xdb, 0xd2, 0x59, 0xcb,
- 0xb6, 0x9e, 0xf9, 0x6f, 0x7a, 0x73, 0xa6, 0xbc, 0xb1, 0x88, 0x39, 0x62,
- 0xab, 0xd4, 0x3e, 0x99, 0xb1, 0x9f, 0xc9, 0xb3, 0xfd, 0x89, 0x57, 0x15,
- 0x27, 0x5b, 0x7d, 0x86, 0xf7, 0x11, 0x43, 0x96, 0xf5, 0x99, 0xd8, 0x6e,
- 0xd0, 0x37, 0x13, 0xbb, 0xc7, 0x9e, 0xb5, 0x82, 0x01, 0xe3, 0x8f, 0x34,
- 0xc9, 0x0f, 0xa2, 0xb0, 0xdb, 0x88, 0xf1, 0xb2, 0xcc, 0x7f, 0xb9, 0x77,
- 0x3c, 0x3f, 0x85, 0x7d, 0x89, 0x53, 0x49, 0x6b, 0x02, 0xfb, 0xe3, 0x19,
- 0x10, 0x03, 0x6a, 0x81, 0x4e, 0x5d, 0x78, 0x3f, 0xc4, 0x4f, 0xfd, 0xfe,
- 0xfb, 0xaf, 0x86, 0x0e, 0xe3, 0xfe, 0x0d, 0x2e, 0x4c, 0x2c, 0xe6, 0x42,
- 0x86, 0x3d, 0x0c, 0x6c, 0xad, 0xdc, 0xfa, 0xd8, 0x58, 0x1f, 0x4f, 0x47,
- 0x8c, 0x52, 0x0c, 0x7e, 0x20, 0x65, 0x82, 0xbc, 0xd9, 0x89, 0xfe, 0x95,
- 0xb7, 0x53, 0xfa, 0xea, 0x7e, 0xdf, 0x87, 0x55, 0x6c, 0xf7, 0x64, 0x61,
- 0xaf, 0xc1, 0xe6, 0x59, 0x8b, 0x92, 0xea, 0x4e, 0xda, 0x27, 0xb0, 0xdf,
- 0x74, 0x28, 0x51, 0xcc, 0x49, 0x4c, 0x66, 0xa1, 0x2f, 0xde, 0x80, 0xec,
- 0x5f, 0x2b, 0xc7, 0x03, 0x69, 0xec, 0xe9, 0x60, 0x61, 0x48, 0x26, 0x2f,
- 0xe8, 0x37, 0x5f, 0xd0, 0xfb, 0x43, 0x52, 0x2a, 0x24, 0xb6, 0xcc, 0x82,
- 0xff, 0x66, 0x0b, 0xc4, 0x17, 0xf5, 0xc6, 0x47, 0x31, 0xe3, 0x42, 0x61,
- 0x23, 0xec, 0x83, 0xa4, 0x2e, 0xc1, 0xff, 0xb9, 0x54, 0xde, 0x02, 0x3e,
- 0xc3, 0xfd, 0xb2, 0x83, 0x5f, 0xe8, 0xcc, 0xf2, 0x00, 0xe4, 0x9c, 0x7b,
- 0xb1, 0x65, 0x6e, 0x33, 0xce, 0x8e, 0x38, 0x22, 0xc5, 0x8f, 0xff, 0x07,
- 0xe7, 0xeb, 0xbf, 0xf7, 0x76, 0xb5, 0xd3, 0xb3, 0xba, 0x2f, 0xd8, 0x65,
- 0xc4, 0x00, 0xd9, 0x7e, 0x63, 0xb7, 0xd3, 0x91, 0x76, 0x49, 0xdf, 0x43,
- 0x3b, 0xde, 0xa1, 0x31, 0xa2, 0xf2, 0x62, 0x84, 0xf7, 0xdf, 0x59, 0x67,
- 0xe8, 0x17, 0x6e, 0x68, 0xbf, 0x8d, 0xdf, 0x36, 0xe9, 0x74, 0xf8, 0x6b,
- 0xe3, 0xf7, 0xc6, 0x3a, 0xd6, 0x77, 0x3b, 0x9d, 0x24, 0xd6, 0xfa, 0x9d,
- 0x97, 0x2f, 0xc0, 0xf5, 0x2c, 0x9f, 0x59, 0xeb, 0xad, 0xcb, 0x79, 0xdb,
- 0x30, 0x4f, 0xab, 0xb7, 0x56, 0x9b, 0xe6, 0x27, 0xcd, 0x5a, 0x88, 0x71,
- 0x0b, 0xef, 0xad, 0xd3, 0xef, 0x8c, 0x61, 0x2f, 0xea, 0xdb, 0x7f, 0x5d,
- 0x47, 0xdc, 0x5c, 0xa7, 0xd3, 0xa6, 0x18, 0xcf, 0x9b, 0x1d, 0x1d, 0xb8,
- 0xe6, 0x9a, 0x1c, 0x63, 0xf2, 0xe1, 0xa5, 0x32, 0xe7, 0x67, 0x3b, 0x25,
- 0x47, 0x35, 0x9f, 0x61, 0xb0, 0x7c, 0xa5, 0xc2, 0xfd, 0x32, 0x79, 0x4e,
- 0xf1, 0x75, 0x33, 0x79, 0x8b, 0xdf, 0xbd, 0xf0, 0x3b, 0x39, 0xfa, 0x12,
- 0x63, 0x32, 0x81, 0xf3, 0xbb, 0x0c, 0x9f, 0x6a, 0xc1, 0x7c, 0x13, 0x8b,
- 0xbf, 0xfd, 0x38, 0x97, 0x10, 0x64, 0x8c, 0x32, 0x4a, 0x99, 0xc2, 0xf9,
- 0x8d, 0xdb, 0xf2, 0xee, 0x00, 0xe5, 0x79, 0x40, 0xae, 0x54, 0xe5, 0x39,
- 0x07, 0x79, 0xa6, 0x2c, 0xe7, 0x20, 0xd3, 0x86, 0xaf, 0xf7, 0xf1, 0x1b,
- 0x6b, 0x84, 0xeb, 0x25, 0xf5, 0x21, 0x2e, 0x82, 0xaf, 0x6d, 0x13, 0x97,
- 0x2b, 0x2e, 0xfe, 0x30, 0xf4, 0x5a, 0x93, 0xf7, 0x1d, 0x00, 0xae, 0xaf,
- 0xbc, 0x28, 0xe9, 0x0b, 0x2d, 0xd8, 0x77, 0xbc, 0x9b, 0x67, 0x96, 0xbd,
- 0xc2, 0x7f, 0x9f, 0x17, 0x89, 0x37, 0xa5, 0x3f, 0xcb, 0x6b, 0xc6, 0x79,
- 0xeb, 0x31, 0x66, 0x10, 0x74, 0x6e, 0xc1, 0xfc, 0xdc, 0xe3, 0x72, 0xe3,
- 0x78, 0x3f, 0x54, 0x83, 0x4f, 0xf5, 0xe9, 0xbd, 0x4a, 0xd7, 0xcc, 0xea,
- 0x37, 0x5a, 0x46, 0x06, 0x27, 0x0a, 0xe4, 0xfb, 0x18, 0xf8, 0x96, 0x3e,
- 0x31, 0xf9, 0x25, 0xa5, 0xe7, 0x50, 0x2a, 0x90, 0x7f, 0x43, 0x9a, 0xc3,
- 0xc8, 0xc2, 0xb6, 0xec, 0xd1, 0xf1, 0xb1, 0x25, 0xf9, 0xee, 0x0e, 0x68,
- 0xdc, 0x9d, 0x2d, 0xac, 0x94, 0x1e, 0xd5, 0x41, 0xdd, 0x1e, 0x6f, 0xc3,
- 0x5e, 0x28, 0x96, 0x7b, 0xbf, 0x1c, 0x29, 0x0f, 0x82, 0x0e, 0x31, 0x79,
- 0x06, 0x7e, 0xf3, 0x73, 0xe5, 0xbb, 0x64, 0x31, 0x82, 0x7d, 0x55, 0x65,
- 0x6c, 0x58, 0x9e, 0x9f, 0x8d, 0x7b, 0xd7, 0x09, 0x77, 0xd1, 0xda, 0x8e,
- 0x3d, 0x50, 0x9e, 0x28, 0x57, 0x1c, 0x17, 0x44, 0x2c, 0xc2, 0x79, 0x8f,
- 0x18, 0xdd, 0x86, 0x79, 0x8b, 0x11, 0xca, 0x2f, 0xf7, 0x16, 0xf2, 0x64,
- 0x96, 0x71, 0x15, 0xdf, 0xd9, 0xd8, 0xa4, 0x4c, 0xdd, 0x59, 0x24, 0x14,
- 0x07, 0xba, 0x74, 0x06, 0xfe, 0x3c, 0xbe, 0x5c, 0xfa, 0xdf, 0x51, 0x50,
- 0x8f, 0xc2, 0x56, 0x16, 0x60, 0x2b, 0x0b, 0xb0, 0x91, 0x90, 0x85, 0x6b,
- 0x05, 0xd8, 0xc8, 0x02, 0x6c, 0x24, 0xf4, 0xd9, 0x9b, 0x88, 0xed, 0xde,
- 0x00, 0x0f, 0x19, 0x5f, 0xfb, 0x30, 0x7d, 0x6d, 0xfc, 0xfd, 0x17, 0xea,
- 0x52, 0x61, 0x78, 0xd0, 0x71, 0x00, 0x00, 0x00 };
+ 0xec, 0x5b, 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x24, 0x57,
+ 0x14, 0x45, 0x8e, 0xa8, 0x15, 0xb5, 0xb2, 0x99, 0x64, 0x97, 0x1c, 0x89,
+ 0x1b, 0x93, 0x50, 0x86, 0xec, 0x5a, 0x66, 0x92, 0x45, 0xbc, 0x59, 0x52,
+ 0x16, 0x53, 0x08, 0xf0, 0xda, 0x56, 0x5c, 0xa3, 0x31, 0x90, 0xc5, 0x92,
+ 0x76, 0xd2, 0x37, 0xc9, 0xa9, 0x5d, 0x21, 0xb1, 0xab, 0xf5, 0x92, 0x91,
+ 0x15, 0x75, 0xc5, 0x61, 0x24, 0x26, 0x72, 0x1b, 0xb7, 0xa0, 0xf9, 0x23,
+ 0xaa, 0xc1, 0x4a, 0xe3, 0x9f, 0xd8, 0xf5, 0x43, 0x64, 0x31, 0xb2, 0xad,
+ 0xfa, 0xa5, 0x80, 0xd3, 0x1f, 0xc0, 0x28, 0x8c, 0x56, 0x90, 0x6b, 0xd9,
+ 0x68, 0x81, 0x42, 0x6d, 0x51, 0xd4, 0x6d, 0x64, 0x4d, 0xbf, 0xef, 0xce,
+ 0x0c, 0xb9, 0x22, 0x94, 0xc6, 0x2f, 0x7d, 0x9b, 0x0b, 0x2c, 0xee, 0xdc,
+ 0x3b, 0xe7, 0x9e, 0x7b, 0xce, 0xb9, 0xe7, 0xf7, 0x0e, 0xf9, 0x44, 0x9b,
+ 0xb4, 0x4a, 0xd0, 0x36, 0xe1, 0x97, 0x3d, 0x70, 0xe8, 0xb1, 0xc1, 0x5d,
+ 0xbb, 0x77, 0xe1, 0x71, 0x77, 0xcc, 0x6c, 0x36, 0x38, 0xaf, 0x49, 0xd4,
+ 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2,
+ 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16,
+ 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5,
+ 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8,
+ 0x45, 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45,
+ 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xfe, 0x3f, 0x5a, 0x4c, 0xc4, 0x64,
+ 0xbf, 0x29, 0xf8, 0x49, 0x5c, 0xcf, 0xa5, 0x0e, 0x16, 0x2c, 0x89, 0xc7,
+ 0x72, 0x6f, 0x3f, 0x3e, 0x6e, 0x89, 0xe4, 0xeb, 0xfd, 0xa9, 0x11, 0xf9,
+ 0xc4, 0xab, 0x24, 0x0c, 0xe1, 0xfc, 0x67, 0x72, 0xd7, 0x0f, 0x9f, 0xbf,
+ 0x2b, 0x7d, 0x6d, 0x2e, 0x26, 0x71, 0x33, 0xf7, 0xee, 0xa0, 0xb9, 0x53,
+ 0xe2, 0xdd, 0x58, 0xf3, 0x5c, 0xdf, 0xc4, 0x66, 0x69, 0x0f, 0x71, 0x79,
+ 0xde, 0x92, 0xed, 0xc9, 0x25, 0xbb, 0xa2, 0x8d, 0xf4, 0xbd, 0xa6, 0x15,
+ 0x9c, 0x1b, 0x5e, 0xde, 0xd0, 0x45, 0x07, 0xbe, 0x89, 0x7a, 0x5c, 0x1e,
+ 0x59, 0x6c, 0x95, 0x47, 0xe7, 0x36, 0x4a, 0x79, 0x4e, 0x4c, 0x3d, 0x97,
+ 0x94, 0x6f, 0x61, 0xee, 0x72, 0x0c, 0x70, 0xae, 0x94, 0x62, 0xb9, 0x8f,
+ 0xef, 0x2d, 0xd7, 0x08, 0x2f, 0xba, 0x9e, 0x5b, 0xb9, 0x77, 0xa2, 0xfe,
+ 0xe6, 0xbd, 0xe5, 0x3a, 0xe1, 0x08, 0x83, 0x77, 0xf5, 0x8f, 0xbc, 0xf3,
+ 0x7d, 0x09, 0xb9, 0xe0, 0x9a, 0xf2, 0x82, 0xfb, 0x32, 0xf6, 0x4c, 0x57,
+ 0x2a, 0xd2, 0x24, 0xe5, 0x93, 0x37, 0xbc, 0x98, 0x95, 0x4e, 0x61, 0x13,
+ 0x73, 0x44, 0xf0, 0xde, 0xc1, 0x7b, 0x07, 0xf3, 0x0b, 0x3f, 0xdf, 0x2c,
+ 0xad, 0x49, 0x39, 0xdf, 0xc7, 0x75, 0x5c, 0xc3, 0xb5, 0x8b, 0xed, 0xfe,
+ 0x3a, 0xc1, 0xba, 0xa2, 0xc4, 0x2c, 0x4f, 0x0a, 0xb6, 0x21, 0x23, 0x09,
+ 0xd1, 0x74, 0xab, 0x02, 0x3a, 0x7e, 0xd1, 0x26, 0xad, 0xc4, 0x55, 0xd1,
+ 0xf2, 0x2e, 0xfb, 0x10, 0xdf, 0x53, 0x1d, 0x3e, 0xae, 0x67, 0x81, 0xab,
+ 0x24, 0xaf, 0xbb, 0x0f, 0xcb, 0x5f, 0xb8, 0x63, 0xf2, 0x92, 0x3b, 0x01,
+ 0x9c, 0x0f, 0xc9, 0xab, 0xee, 0x7e, 0x79, 0xc5, 0x2d, 0xca, 0xcf, 0xdc,
+ 0x7d, 0xf2, 0xb2, 0x3b, 0x2a, 0x2f, 0xba, 0x79, 0xec, 0x97, 0xd1, 0x8a,
+ 0xce, 0xdd, 0x32, 0x7e, 0x92, 0x34, 0xa6, 0xaf, 0x41, 0x36, 0xf2, 0x98,
+ 0xdd, 0x67, 0xea, 0xa2, 0x61, 0xcf, 0xf4, 0x6b, 0x22, 0x8f, 0x4a, 0x3e,
+ 0x31, 0x2c, 0x73, 0x6e, 0x97, 0x56, 0x38, 0xd9, 0xa9, 0x8d, 0x9c, 0x24,
+ 0x2d, 0x9e, 0x8c, 0xdb, 0xe9, 0x54, 0x21, 0x96, 0x36, 0x47, 0x62, 0x92,
+ 0xdf, 0x03, 0xb9, 0x55, 0x9d, 0xa4, 0xe4, 0x4d, 0xc9, 0x1f, 0xb5, 0x0c,
+ 0xc8, 0x53, 0x93, 0x58, 0x8e, 0x7c, 0x6e, 0xe1, 0x1c, 0x5a, 0x9b, 0x2c,
+ 0xd4, 0x6c, 0x29, 0x3b, 0xf3, 0x5a, 0x39, 0xa1, 0x51, 0x04, 0x18, 0x0f,
+ 0x60, 0xfc, 0x67, 0xc1, 0xf8, 0x4b, 0x52, 0x3e, 0x25, 0xf9, 0xc9, 0x59,
+ 0xcf, 0x2b, 0xd8, 0x7f, 0x1c, 0xcc, 0x0d, 0x63, 0x4e, 0x97, 0xd8, 0x8f,
+ 0x38, 0x37, 0x1b, 0xcc, 0x51, 0x1e, 0x9e, 0x8c, 0xd8, 0x14, 0x23, 0xe8,
+ 0x35, 0x8b, 0xe8, 0x9b, 0xd1, 0x73, 0x8f, 0x8d, 0x9b, 0xfc, 0xff, 0x03,
+ 0xe2, 0xf9, 0x26, 0xf0, 0x6c, 0x83, 0x66, 0x89, 0x7f, 0x36, 0x77, 0xf4,
+ 0xe0, 0x3f, 0xf4, 0xad, 0x8d, 0xf5, 0xdc, 0x7b, 0x52, 0xa8, 0x69, 0x4a,
+ 0x57, 0x34, 0x3c, 0xf7, 0xd4, 0x9f, 0xea, 0xf4, 0xf5, 0xc2, 0x69, 0x97,
+ 0x56, 0xc8, 0xc9, 0x21, 0xfd, 0x29, 0xd0, 0xbf, 0x49, 0xb6, 0xfc, 0x90,
+ 0x3c, 0xf4, 0xa7, 0x74, 0xc9, 0xa7, 0x0d, 0xb1, 0x65, 0xd1, 0x35, 0xb4,
+ 0x11, 0x27, 0x2f, 0x7a, 0xce, 0x4a, 0x96, 0x45, 0x97, 0x52, 0x22, 0x2f,
+ 0xcf, 0x64, 0xd3, 0xc3, 0x15, 0x49, 0x49, 0x79, 0xc8, 0x96, 0x65, 0x17,
+ 0x90, 0x89, 0x8a, 0x5c, 0xcd, 0xa6, 0xed, 0xcb, 0xb2, 0x51, 0x56, 0x4c,
+ 0x5b, 0x4e, 0xbb, 0x71, 0x79, 0xeb, 0xe4, 0x3e, 0xf9, 0x96, 0xc3, 0x73,
+ 0x92, 0xfe, 0x26, 0x79, 0x5a, 0x96, 0xb2, 0x4f, 0x5f, 0x5b, 0xb2, 0x8f,
+ 0xb7, 0x49, 0x3b, 0x75, 0xb0, 0xd6, 0xee, 0xd3, 0xfd, 0x15, 0xf0, 0x96,
+ 0x87, 0x6c, 0xdb, 0x21, 0x33, 0x43, 0xf1, 0x55, 0x78, 0xb0, 0x13, 0x3d,
+ 0xd7, 0xfd, 0xfd, 0x16, 0xe8, 0x83, 0x2d, 0x5a, 0x48, 0x63, 0x93, 0x14,
+ 0xba, 0xb8, 0xe6, 0x25, 0xe0, 0xc0, 0xfb, 0x55, 0xda, 0x6f, 0xd3, 0x0a,
+ 0xa7, 0xda, 0xc5, 0xf8, 0xd1, 0x9d, 0x38, 0x4f, 0x43, 0x1e, 0x19, 0xf2,
+ 0xbc, 0xaf, 0xdb, 0x46, 0x6a, 0x42, 0x72, 0xa4, 0x5d, 0x36, 0x1f, 0xdf,
+ 0x2a, 0x73, 0x66, 0x5c, 0x12, 0xc7, 0xc3, 0xbd, 0x5a, 0x82, 0xf3, 0xf9,
+ 0x32, 0xf1, 0xa7, 0x52, 0xfa, 0xa6, 0x60, 0x1c, 0xd2, 0x34, 0x8a, 0x33,
+ 0xea, 0x35, 0x7b, 0xf4, 0x21, 0x2d, 0xaf, 0xfe, 0x8f, 0x6a, 0x2c, 0x18,
+ 0xef, 0xd2, 0xbe, 0x6a, 0x74, 0x89, 0x61, 0xcd, 0x43, 0xae, 0x86, 0x5c,
+ 0x74, 0xc2, 0xf9, 0xb8, 0xf8, 0x70, 0x94, 0xb3, 0x0c, 0xae, 0xc9, 0x59,
+ 0x06, 0x7b, 0xea, 0x4f, 0x07, 0x38, 0xf3, 0x01, 0xec, 0x06, 0xc9, 0x27,
+ 0xdb, 0x78, 0xa6, 0x01, 0xec, 0x75, 0xf9, 0xce, 0x50, 0xfa, 0x0c, 0xff,
+ 0x57, 0x6b, 0x6d, 0x0d, 0xdf, 0xdb, 0x32, 0xef, 0xaa, 0x35, 0xc9, 0xfb,
+ 0x70, 0xb6, 0xa5, 0xe4, 0x1d, 0xe6, 0x82, 0x1e, 0xd3, 0xf2, 0x09, 0xe2,
+ 0x6a, 0x96, 0xc7, 0x13, 0xbd, 0x18, 0x6b, 0x52, 0xfe, 0x12, 0xf5, 0xf5,
+ 0x13, 0xf1, 0xe7, 0x39, 0x97, 0x3e, 0xda, 0xab, 0x1f, 0x03, 0x7d, 0x94,
+ 0x41, 0x3a, 0x29, 0x10, 0x7e, 0x79, 0xe8, 0x36, 0xf0, 0x67, 0xa2, 0x0f,
+ 0xf9, 0xdf, 0x2c, 0xf9, 0x22, 0xe9, 0x57, 0x76, 0x0a, 0x39, 0x27, 0xb1,
+ 0xdf, 0xdd, 0xb0, 0xc9, 0xf5, 0xf6, 0x0a, 0x1b, 0x6d, 0xa7, 0xad, 0x7e,
+ 0x11, 0x3c, 0xa7, 0x33, 0x22, 0x16, 0xe4, 0x95, 0x94, 0x66, 0x6b, 0x1a,
+ 0x3c, 0x51, 0x2f, 0xb7, 0x61, 0x7e, 0xc3, 0xc7, 0x79, 0xc5, 0x7a, 0x38,
+ 0xf7, 0x41, 0x20, 0xcb, 0x7d, 0x32, 0xe1, 0xec, 0x57, 0x3c, 0x57, 0xf5,
+ 0xcb, 0x92, 0xef, 0xee, 0x35, 0xa7, 0x40, 0x6f, 0xc1, 0x48, 0xcf, 0x55,
+ 0x24, 0x29, 0x0b, 0xf0, 0x13, 0x2f, 0xc2, 0xe6, 0x5f, 0x71, 0x53, 0xb0,
+ 0xaf, 0xbc, 0x3c, 0xea, 0xe4, 0x64, 0xe2, 0x14, 0x6d, 0x2c, 0x9d, 0x29,
+ 0xc4, 0x72, 0x32, 0xef, 0xa4, 0x33, 0x0b, 0xd0, 0xbd, 0x05, 0xc7, 0xf3,
+ 0xa6, 0xec, 0xfe, 0xd4, 0x28, 0x30, 0x5e, 0x74, 0x76, 0x24, 0x27, 0x20,
+ 0xc8, 0x25, 0x2b, 0x25, 0x4b, 0x6e, 0x06, 0x3a, 0x86, 0xf7, 0xae, 0x85,
+ 0x7e, 0x00, 0x3a, 0x9e, 0x85, 0x7d, 0x93, 0x16, 0x53, 0x16, 0xfb, 0x20,
+ 0x3b, 0x47, 0x07, 0x2e, 0x4d, 0xf2, 0xfb, 0x6f, 0x40, 0xbe, 0x21, 0xdf,
+ 0x77, 0x81, 0xb6, 0x04, 0x70, 0x92, 0xae, 0xdb, 0xa4, 0xda, 0x05, 0xf9,
+ 0x0d, 0x25, 0x94, 0x5d, 0x16, 0x3a, 0xb7, 0x4a, 0xe1, 0x8e, 0x66, 0xbc,
+ 0xef, 0xc2, 0x98, 0xf2, 0x6f, 0xc1, 0x1c, 0xdf, 0xff, 0x4b, 0x60, 0x5f,
+ 0x4d, 0xeb, 0xc6, 0x57, 0xd1, 0xb7, 0xcb, 0x36, 0x8b, 0xbd, 0x89, 0xfe,
+ 0x9f, 0xd1, 0x77, 0xa2, 0xef, 0xc5, 0x5e, 0xe7, 0x21, 0x43, 0xca, 0x0f,
+ 0xcf, 0x0b, 0x5c, 0xb3, 0x3d, 0xd8, 0x97, 0x78, 0xdb, 0x81, 0x67, 0x53,
+ 0xb0, 0x57, 0x3b, 0xc6, 0xad, 0xc1, 0x5e, 0x16, 0x68, 0x8e, 0x29, 0x19,
+ 0x16, 0xac, 0xf8, 0xba, 0xb1, 0x86, 0x3e, 0x0e, 0xdc, 0x84, 0xd7, 0xe5,
+ 0x4a, 0x57, 0x17, 0x9e, 0xb9, 0x27, 0x61, 0xf8, 0x1e, 0xbd, 0x4b, 0xfc,
+ 0x1c, 0xe7, 0xe5, 0x09, 0x07, 0xfe, 0x89, 0xfa, 0xe6, 0x52, 0x8e, 0xbb,
+ 0x65, 0x02, 0xbc, 0x8f, 0x3b, 0xe9, 0x99, 0xaa, 0xee, 0x79, 0x7a, 0xd6,
+ 0x30, 0xab, 0x92, 0x86, 0x1d, 0x8f, 0xc9, 0x38, 0xe4, 0x77, 0xda, 0x89,
+ 0xcb, 0x45, 0x65, 0x7b, 0xe4, 0xe9, 0x21, 0xc8, 0x05, 0xf1, 0xa4, 0x8b,
+ 0xf6, 0x49, 0x9b, 0x82, 0xfc, 0x8a, 0xa6, 0x5c, 0xca, 0xd2, 0x96, 0xb3,
+ 0xb2, 0xbc, 0x6a, 0xcb, 0x15, 0xd8, 0x32, 0xed, 0xb8, 0x02, 0x7b, 0xf6,
+ 0xf5, 0xfa, 0x41, 0xd9, 0x06, 0xbd, 0x4e, 0x62, 0x3f, 0xea, 0xf5, 0xb3,
+ 0xd0, 0x6b, 0xc8, 0xd4, 0x86, 0xae, 0x9b, 0xd4, 0x89, 0x6f, 0xc3, 0xa7,
+ 0x81, 0xdf, 0x44, 0xf0, 0xbc, 0xfc, 0x5d, 0x29, 0x9c, 0x6a, 0x05, 0xdd,
+ 0x7b, 0xdb, 0x29, 0xb3, 0xf2, 0x32, 0x7f, 0xa1, 0x2e, 0x3e, 0x05, 0xf9,
+ 0xc1, 0x8f, 0x2a, 0x1d, 0x04, 0x6f, 0xd9, 0x3d, 0x80, 0x19, 0xc6, 0x39,
+ 0xb7, 0x02, 0x3f, 0x69, 0xbc, 0x15, 0x1c, 0xdf, 0x83, 0xee, 0x2c, 0xf5,
+ 0x15, 0xf3, 0x0b, 0xe1, 0x79, 0xb7, 0xa9, 0x3d, 0xcb, 0x43, 0xad, 0x01,
+ 0x7f, 0x94, 0x03, 0xf5, 0x3e, 0x09, 0xbd, 0xd5, 0x64, 0x5c, 0xe9, 0x6e,
+ 0x5e, 0xc9, 0x61, 0xde, 0xa1, 0xfe, 0x02, 0x87, 0x4d, 0x19, 0x98, 0x72,
+ 0xbf, 0x82, 0x4f, 0xae, 0xd9, 0x77, 0x37, 0x69, 0xe7, 0x78, 0x83, 0xf4,
+ 0x28, 0x1f, 0xd4, 0x1d, 0xe8, 0x76, 0x13, 0x6c, 0x9f, 0xef, 0x1e, 0x92,
+ 0xc7, 0xdc, 0x61, 0x9c, 0x43, 0x52, 0x0e, 0xba, 0xdd, 0xf2, 0xfb, 0xee,
+ 0x46, 0xb9, 0xdc, 0x09, 0xba, 0x56, 0x6d, 0xec, 0x6e, 0xf9, 0x03, 0xc6,
+ 0x3c, 0xf5, 0x0c, 0x3f, 0xa9, 0xdf, 0x05, 0x1a, 0x68, 0x4f, 0xb4, 0x2b,
+ 0xc2, 0xc5, 0xa4, 0xa4, 0xf6, 0xfc, 0x89, 0xef, 0xdb, 0x80, 0x77, 0xae,
+ 0x93, 0xf6, 0x4b, 0xda, 0x8c, 0xc0, 0x66, 0xd3, 0x66, 0x49, 0xc8, 0x33,
+ 0x69, 0xe5, 0x73, 0xa3, 0x2c, 0xd8, 0x37, 0xca, 0x20, 0xc4, 0x13, 0xda,
+ 0xe5, 0xa8, 0xe4, 0x5d, 0xf6, 0xf4, 0x97, 0x88, 0x91, 0x0e, 0x62, 0xa4,
+ 0x83, 0xd8, 0x08, 0x5b, 0x78, 0xc5, 0x41, 0x6c, 0x74, 0x10, 0x1b, 0xe1,
+ 0xcf, 0x5e, 0x72, 0x10, 0x1f, 0xa1, 0x43, 0x2f, 0x38, 0x8c, 0xeb, 0xdf,
+ 0x46, 0x4c, 0x35, 0xe4, 0x99, 0x9a, 0xc8, 0x91, 0x5a, 0x1a, 0xd4, 0xa5,
+ 0x87, 0x3f, 0x90, 0xfe, 0xcc, 0x07, 0x92, 0xb6, 0x2f, 0xe2, 0xf7, 0x96,
+ 0xe0, 0x9d, 0xca, 0x11, 0xf0, 0xbe, 0x1e, 0xe6, 0x13, 0x38, 0x7f, 0x8b,
+ 0x39, 0x83, 0x3f, 0x0f, 0x97, 0x88, 0xb8, 0x41, 0x9b, 0x1e, 0x93, 0xf9,
+ 0x59, 0xda, 0xf2, 0xed, 0x38, 0x8b, 0x4e, 0x99, 0xb2, 0xfc, 0x71, 0xc1,
+ 0xbe, 0xc3, 0x1c, 0xa5, 0xee, 0x98, 0x31, 0xd0, 0x76, 0x1b, 0x7e, 0x29,
+ 0xc4, 0xda, 0x3f, 0xd2, 0x0a, 0x0b, 0x71, 0xc4, 0x56, 0xc6, 0x5b, 0xc9,
+ 0xfb, 0x7a, 0x74, 0xc3, 0x1b, 0x5f, 0x5d, 0xd3, 0x0f, 0xfd, 0x86, 0xdc,
+ 0x13, 0x09, 0xc0, 0xcc, 0x6a, 0x23, 0xcb, 0x6f, 0xfb, 0x76, 0x92, 0xe5,
+ 0xf8, 0x46, 0x60, 0x7b, 0xdc, 0x1f, 0x63, 0x97, 0x78, 0xf9, 0x4c, 0x9c,
+ 0x97, 0x91, 0x1f, 0x24, 0x91, 0x17, 0x24, 0xe0, 0x7b, 0x98, 0x73, 0x74,
+ 0x23, 0x3f, 0xf0, 0xbc, 0x17, 0x6d, 0xcf, 0x7b, 0x07, 0xbf, 0x7f, 0xb7,
+ 0x57, 0x79, 0x40, 0xab, 0x68, 0xa3, 0x6e, 0x4a, 0x46, 0xdd, 0x9f, 0xb6,
+ 0xfb, 0x72, 0x8c, 0xcb, 0xa4, 0x93, 0x90, 0x29, 0xa7, 0xa6, 0xdd, 0xb7,
+ 0x3c, 0xad, 0x15, 0x97, 0x67, 0xb0, 0xaf, 0x81, 0x39, 0xa9, 0x54, 0xed,
+ 0x33, 0xda, 0x88, 0x7b, 0x54, 0xbb, 0x7f, 0xb9, 0x5d, 0xd9, 0x79, 0xd5,
+ 0x61, 0xce, 0x70, 0x5d, 0xe5, 0x2e, 0x05, 0x2b, 0x6d, 0xfe, 0x2e, 0x14,
+ 0xaf, 0x50, 0x23, 0xdd, 0xcd, 0x01, 0xcd, 0xb0, 0xc3, 0x9c, 0x77, 0xb8,
+ 0x90, 0xb5, 0x60, 0x8b, 0xa4, 0x51, 0xcd, 0x5d, 0xf0, 0xe9, 0x3e, 0xad,
+ 0x15, 0x96, 0xdb, 0xb4, 0x91, 0x53, 0x8c, 0xc7, 0xd2, 0x1d, 0x13, 0xae,
+ 0xdb, 0x01, 0x7b, 0xad, 0x63, 0x0f, 0xe6, 0x5b, 0x94, 0x2d, 0xe8, 0x86,
+ 0x0e, 0xbf, 0x04, 0x7a, 0x5e, 0x54, 0xf9, 0x0f, 0xf9, 0x4b, 0xe1, 0xac,
+ 0x42, 0xfe, 0x3c, 0xef, 0xaf, 0xed, 0x90, 0xfe, 0x74, 0x2a, 0xaf, 0x87,
+ 0xfc, 0x7a, 0xde, 0xbf, 0xd9, 0xe4, 0x99, 0x3c, 0x79, 0xde, 0x0b, 0x76,
+ 0x02, 0xf4, 0x7b, 0x17, 0x74, 0xab, 0x06, 0x7e, 0x18, 0xdb, 0x29, 0xf3,
+ 0x69, 0xf0, 0x71, 0x14, 0x3c, 0x9e, 0x06, 0x7f, 0x33, 0xa0, 0xe5, 0x37,
+ 0xed, 0xd9, 0x98, 0x4b, 0x4a, 0x8a, 0xb2, 0x2e, 0x2f, 0x32, 0xa7, 0x64,
+ 0x1e, 0x69, 0x4a, 0x69, 0x31, 0x5c, 0x1f, 0xea, 0xc3, 0x01, 0xd9, 0xeb,
+ 0x74, 0x42, 0x3e, 0x94, 0xe7, 0x35, 0xd0, 0x4b, 0x9f, 0x5f, 0xcd, 0xe8,
+ 0x08, 0x80, 0x65, 0x1b, 0xb1, 0x5e, 0x46, 0x94, 0x2e, 0x2c, 0x5a, 0x92,
+ 0x2f, 0xdb, 0x26, 0xed, 0x36, 0x55, 0xb6, 0x2b, 0xc8, 0x0c, 0x7c, 0x39,
+ 0x8e, 0xd4, 0x0c, 0xbc, 0xe3, 0x58, 0x60, 0xf3, 0xa1, 0x6c, 0x0d, 0xd8,
+ 0x5d, 0x28, 0xf3, 0x70, 0xee, 0xc1, 0x0e, 0xfa, 0xcc, 0x79, 0xf7, 0x0b,
+ 0xc0, 0x41, 0xbc, 0xbf, 0x09, 0x47, 0x1c, 0x31, 0x84, 0x78, 0xe2, 0x72,
+ 0xc6, 0x21, 0x3c, 0xf3, 0x8b, 0xb8, 0xb4, 0x22, 0x26, 0x6f, 0xc8, 0x89,
+ 0xf6, 0xf9, 0x1d, 0x69, 0x73, 0x31, 0x16, 0x93, 0x63, 0x09, 0xb9, 0xc3,
+ 0x60, 0x00, 0xd8, 0xec, 0x67, 0xea, 0x85, 0x19, 0x0d, 0xba, 0xdc, 0x26,
+ 0x93, 0x03, 0x69, 0x73, 0x1e, 0x7b, 0xe8, 0xd8, 0xe3, 0x6b, 0x9c, 0xaf,
+ 0xfd, 0x87, 0x57, 0x4a, 0xec, 0x84, 0x9d, 0x48, 0xdc, 0xc8, 0x19, 0x83,
+ 0x53, 0xb5, 0x03, 0xc2, 0xfc, 0x6a, 0x72, 0x60, 0x03, 0xec, 0xbc, 0x77,
+ 0x78, 0xaf, 0x30, 0x97, 0x8f, 0x0f, 0x8e, 0x5b, 0x3e, 0x5d, 0x23, 0xb0,
+ 0xeb, 0x49, 0xe4, 0x79, 0x7b, 0xeb, 0xcc, 0x01, 0x8c, 0xc1, 0xde, 0xba,
+ 0x21, 0x47, 0x60, 0xaf, 0xcd, 0xd0, 0x9f, 0x15, 0xa5, 0xcb, 0x26, 0x64,
+ 0x4d, 0xdf, 0x3a, 0x0c, 0xdc, 0xef, 0x40, 0x6e, 0x16, 0x62, 0x67, 0x37,
+ 0xf2, 0xd9, 0x0c, 0xce, 0x33, 0x85, 0xd8, 0xd7, 0xa8, 0xd7, 0x12, 0xdf,
+ 0x0a, 0xb8, 0x57, 0x76, 0x32, 0x2f, 0xf3, 0xbc, 0x07, 0xac, 0xf4, 0xb3,
+ 0xe4, 0x65, 0xca, 0x91, 0x7c, 0xd5, 0x56, 0xbe, 0x10, 0x3a, 0x9b, 0x62,
+ 0x3e, 0x07, 0xfd, 0x83, 0x4e, 0x16, 0x39, 0x5e, 0xd5, 0xc1, 0xe4, 0xa4,
+ 0xcc, 0x43, 0x76, 0x62, 0x16, 0xb2, 0x84, 0x0d, 0xe1, 0x5a, 0x02, 0xdd,
+ 0xf6, 0xbc, 0x18, 0x74, 0x77, 0x3c, 0x4b, 0x38, 0xa9, 0x28, 0x9b, 0x83,
+ 0xcc, 0x26, 0xdd, 0x5d, 0x1d, 0x7e, 0x3e, 0x09, 0x5f, 0x99, 0xe0, 0x5e,
+ 0x9f, 0x85, 0x0e, 0x77, 0x23, 0x86, 0x78, 0x1e, 0x6c, 0x38, 0xa1, 0x0b,
+ 0x75, 0x18, 0xf6, 0xe2, 0xf2, 0x5d, 0x1b, 0xe6, 0xc5, 0x9c, 0x84, 0x4f,
+ 0x2b, 0x99, 0x9e, 0x77, 0x0f, 0x68, 0xa9, 0xda, 0x1d, 0x58, 0xd7, 0x24,
+ 0x08, 0x7b, 0xa6, 0xbf, 0xdf, 0x46, 0x15, 0x3b, 0x30, 0x6e, 0xc7, 0x7e,
+ 0x9b, 0x98, 0x7b, 0x4e, 0xd2, 0x16, 0xb2, 0xb4, 0x7d, 0x23, 0xf0, 0xe7,
+ 0x6f, 0x82, 0x4e, 0xae, 0x51, 0x70, 0xf1, 0xa6, 0x5c, 0x56, 0x96, 0x6a,
+ 0xdb, 0x65, 0x6e, 0x3f, 0xf7, 0xe8, 0xa6, 0x1d, 0x22, 0xfe, 0xf3, 0x99,
+ 0x74, 0xd3, 0x8f, 0x74, 0x06, 0x63, 0xed, 0x73, 0xfe, 0x1e, 0x62, 0x32,
+ 0xdf, 0x1d, 0x51, 0xf4, 0x8a, 0x7e, 0xd1, 0xde, 0xe8, 0xc7, 0xa8, 0x5c,
+ 0xbb, 0x76, 0x0f, 0x72, 0xf0, 0xbd, 0xbb, 0xa9, 0x03, 0x86, 0x5c, 0xb2,
+ 0x3c, 0xef, 0x92, 0xdd, 0x04, 0xfe, 0x74, 0x69, 0xb2, 0x8e, 0x9b, 0xd2,
+ 0x0a, 0x99, 0x3b, 0x5a, 0x20, 0x97, 0x36, 0x25, 0x97, 0x49, 0x15, 0xf7,
+ 0xde, 0xc5, 0xd9, 0x70, 0x6d, 0x45, 0xc5, 0x97, 0x82, 0x5a, 0xc7, 0x35,
+ 0x3c, 0xd3, 0x77, 0x91, 0x73, 0x1f, 0xc3, 0xda, 0x98, 0xb4, 0x28, 0xdd,
+ 0x66, 0xfc, 0x27, 0xaf, 0xd2, 0xe1, 0xe3, 0x61, 0xac, 0xa5, 0x0e, 0x87,
+ 0xfc, 0x8f, 0x06, 0x3c, 0x12, 0xaf, 0x0d, 0xbc, 0x6d, 0xaa, 0xce, 0x28,
+ 0xfb, 0xe7, 0xd7, 0x11, 0x53, 0xf2, 0x40, 0x5d, 0x94, 0x0b, 0x7d, 0x21,
+ 0x41, 0x43, 0xba, 0x9f, 0xc1, 0x3e, 0xa4, 0x61, 0x13, 0xf2, 0x5e, 0xd1,
+ 0xaa, 0xe4, 0xcb, 0x0c, 0xf7, 0x11, 0x3d, 0x96, 0x6b, 0x91, 0x11, 0x68,
+ 0x5d, 0xd5, 0xb1, 0xcc, 0x07, 0xa0, 0x7b, 0x5f, 0x07, 0x8f, 0x85, 0x19,
+ 0xfa, 0xaa, 0x2f, 0x61, 0xdd, 0x4a, 0x5a, 0xf7, 0xb7, 0x95, 0x23, 0x0e,
+ 0x65, 0xfa, 0x0e, 0x64, 0xaa, 0x77, 0x35, 0x4b, 0x87, 0x14, 0x91, 0x4f,
+ 0xcd, 0x0f, 0x83, 0xaf, 0x81, 0x36, 0x89, 0xed, 0xa2, 0xaf, 0x42, 0xed,
+ 0x93, 0x58, 0x41, 0x60, 0xb8, 0xee, 0xe9, 0x3b, 0xb1, 0x7e, 0x20, 0x01,
+ 0xf9, 0x52, 0x66, 0x7a, 0x00, 0x47, 0x18, 0x14, 0x4a, 0x66, 0xa1, 0xb3,
+ 0x59, 0x88, 0x9b, 0xef, 0xfa, 0x93, 0xa6, 0x70, 0x1e, 0x3e, 0xbd, 0xc8,
+ 0xb5, 0xa4, 0xd9, 0x5f, 0xd3, 0x64, 0x85, 0xb2, 0xfe, 0x2b, 0xf8, 0xa7,
+ 0x5f, 0x79, 0x7b, 0x87, 0xc2, 0xf7, 0xe4, 0x87, 0x7c, 0xe1, 0x0c, 0x41,
+ 0xd3, 0xe6, 0x9c, 0x25, 0x83, 0xd3, 0xa2, 0x15, 0x90, 0x7b, 0x50, 0x47,
+ 0x7a, 0x86, 0xd2, 0x95, 0x94, 0xbe, 0x0d, 0xbc, 0x1a, 0xb2, 0x7f, 0x88,
+ 0xfc, 0x6e, 0x0d, 0xf2, 0x8e, 0x46, 0x9e, 0x3b, 0x02, 0x9e, 0xd5, 0x7e,
+ 0xc3, 0x79, 0x7d, 0x8d, 0xf7, 0xd1, 0x99, 0x70, 0x5f, 0x03, 0xb6, 0xbc,
+ 0x82, 0x9a, 0x87, 0xfb, 0x93, 0x9e, 0x1b, 0x9e, 0x6e, 0x59, 0x95, 0x1e,
+ 0xfd, 0x57, 0xde, 0xfd, 0x43, 0x9a, 0xca, 0xd3, 0x74, 0xe4, 0x8c, 0xfa,
+ 0x10, 0x78, 0x1d, 0xe2, 0x79, 0xe9, 0x72, 0xff, 0x6e, 0xe2, 0x3b, 0x42,
+ 0xde, 0x80, 0xb3, 0xd5, 0xaf, 0x61, 0x86, 0xc2, 0x3d, 0x1a, 0xf5, 0x27,
+ 0xc4, 0x49, 0x5c, 0x84, 0xe1, 0x99, 0xd0, 0xdf, 0x4a, 0xbc, 0x60, 0xc7,
+ 0x83, 0xb3, 0x0e, 0xd7, 0x89, 0x66, 0x58, 0xeb, 0xd7, 0xc1, 0x68, 0x1f,
+ 0xa4, 0xde, 0xf5, 0x04, 0x76, 0x16, 0xea, 0x21, 0xf7, 0x64, 0x7f, 0x2b,
+ 0x9d, 0xe5, 0x3a, 0xae, 0x27, 0x3c, 0x61, 0xe0, 0x33, 0xe0, 0x83, 0x7e,
+ 0x06, 0xdb, 0x78, 0xf9, 0x26, 0x5f, 0xce, 0xd8, 0x4e, 0x1f, 0x63, 0xaf,
+ 0xf7, 0xe7, 0xac, 0x7d, 0xf0, 0xac, 0xc3, 0x7e, 0x1b, 0xfd, 0x3a, 0xe7,
+ 0x50, 0x4f, 0x2c, 0x8e, 0xa2, 0xb7, 0x64, 0xed, 0x1e, 0x80, 0x7e, 0x3e,
+ 0xac, 0xe7, 0xdb, 0x4a, 0x46, 0x8e, 0x35, 0xbd, 0x14, 0xab, 0xb5, 0xc3,
+ 0x88, 0xc9, 0x52, 0xb9, 0x4d, 0xd5, 0xc6, 0x6d, 0xc3, 0x85, 0x2c, 0xe6,
+ 0xea, 0x8c, 0xcb, 0x30, 0x7f, 0xac, 0x43, 0x6c, 0x88, 0xeb, 0xd3, 0xf1,
+ 0xca, 0xed, 0x39, 0xda, 0x49, 0x4a, 0x52, 0xf5, 0x6b, 0x88, 0x79, 0xc8,
+ 0x1f, 0x95, 0x0e, 0x7d, 0xf1, 0x76, 0xd2, 0x5f, 0x45, 0xec, 0x32, 0x72,
+ 0x62, 0xe8, 0xb9, 0xe6, 0xf8, 0x64, 0xb6, 0x0d, 0xb1, 0x7e, 0x6c, 0xbb,
+ 0x7e, 0x6e, 0xdf, 0xf6, 0xd8, 0xb9, 0xae, 0x52, 0x53, 0xae, 0xb2, 0x5d,
+ 0x9f, 0x86, 0x2f, 0xaf, 0x89, 0x8e, 0x98, 0x8a, 0x1a, 0x01, 0xe3, 0x73,
+ 0x0f, 0x3c, 0xa0, 0xe7, 0x62, 0x52, 0x4e, 0xc8, 0x93, 0x8b, 0x59, 0xf8,
+ 0xf5, 0x5a, 0x3a, 0x55, 0x94, 0x27, 0xa5, 0x5a, 0x3b, 0x24, 0x93, 0xb5,
+ 0xf0, 0xde, 0x80, 0x77, 0x06, 0x49, 0xe5, 0xbf, 0xe8, 0x5f, 0x27, 0x03,
+ 0xda, 0x41, 0x73, 0x7e, 0x84, 0x31, 0x3a, 0x4b, 0xdf, 0x7d, 0x0d, 0x3a,
+ 0xd1, 0x12, 0xd4, 0xda, 0xbe, 0xfe, 0x19, 0xb9, 0x8f, 0x30, 0x47, 0xfd,
+ 0xdb, 0xb0, 0x7a, 0x6e, 0x7b, 0x4e, 0xfd, 0x89, 0x8a, 0xa9, 0x4b, 0x36,
+ 0x9f, 0x09, 0xf3, 0xf6, 0xe0, 0x94, 0x75, 0xdd, 0x64, 0x6d, 0x70, 0xc1,
+ 0x21, 0x3e, 0x53, 0x9d, 0xb5, 0x91, 0xbb, 0x8c, 0xb5, 0xad, 0xa4, 0x0b,
+ 0xcd, 0xc0, 0x3c, 0xf6, 0x77, 0x9a, 0x83, 0x71, 0xb8, 0xf6, 0xb5, 0x86,
+ 0xb5, 0x9c, 0x63, 0x4f, 0xdc, 0xd8, 0xa3, 0xe1, 0xce, 0xe4, 0x82, 0x9b,
+ 0x51, 0x35, 0x7b, 0xc1, 0x55, 0xb9, 0x02, 0x6a, 0x74, 0xe8, 0x93, 0xba,
+ 0x43, 0x81, 0x3f, 0x72, 0xff, 0xce, 0xf4, 0xcf, 0x9d, 0xfe, 0x63, 0x45,
+ 0x18, 0xdf, 0xa8, 0x6f, 0x53, 0xca, 0x4f, 0xbd, 0xd9, 0x70, 0x17, 0xf0,
+ 0x26, 0xfc, 0xd2, 0x9d, 0x9b, 0xfd, 0x9a, 0xc6, 0x0c, 0x7c, 0x5a, 0xab,
+ 0xca, 0x53, 0x7c, 0x9f, 0x96, 0x6a, 0x80, 0x4d, 0xf1, 0xde, 0xa0, 0xc3,
+ 0xaf, 0xbd, 0x7f, 0x2b, 0x58, 0xc3, 0xfc, 0xc1, 0x32, 0x99, 0x3b, 0xf8,
+ 0xb2, 0xf0, 0x9e, 0x59, 0x1d, 0x27, 0x4a, 0x01, 0xbe, 0xa6, 0xe0, 0xdd,
+ 0x5b, 0x6d, 0x3e, 0x4d, 0xe1, 0xda, 0x3f, 0x0d, 0xee, 0xa6, 0x94, 0x2f,
+ 0xcc, 0x03, 0x16, 0x3c, 0xa4, 0x4a, 0x3a, 0xf4, 0x66, 0xa4, 0xee, 0xcb,
+ 0x1b, 0xf1, 0x8e, 0xf7, 0x4f, 0x8a, 0xb6, 0x0b, 0x2a, 0xe7, 0x68, 0xe4,
+ 0x3f, 0x4f, 0xbe, 0xf3, 0x06, 0x69, 0x74, 0xc7, 0xb0, 0x56, 0x0e, 0xf8,
+ 0x77, 0x14, 0xa6, 0x4c, 0x98, 0xfd, 0xe6, 0x24, 0xf1, 0x26, 0x04, 0xf8,
+ 0x90, 0x97, 0xe4, 0xc2, 0x33, 0xfc, 0x26, 0xf7, 0x06, 0xde, 0x8d, 0x1c,
+ 0xa3, 0xff, 0x66, 0x40, 0xcb, 0x8f, 0x03, 0x79, 0x85, 0xef, 0x7f, 0xb1,
+ 0xf9, 0xe6, 0xf1, 0x3d, 0xb7, 0x07, 0xf2, 0xc4, 0xf3, 0xa1, 0x5f, 0x43,
+ 0x13, 0xf5, 0xfd, 0x34, 0xf0, 0xa8, 0x18, 0x5c, 0xd1, 0x73, 0x88, 0xf9,
+ 0x59, 0x64, 0x34, 0x35, 0xd8, 0xb4, 0x20, 0xf6, 0xbb, 0x69, 0xbb, 0x84,
+ 0x55, 0x1f, 0xd5, 0xe8, 0x57, 0xaf, 0xc3, 0xaf, 0xf2, 0xac, 0x3f, 0x96,
+ 0xa9, 0x5a, 0xaf, 0xdd, 0xac, 0xa9, 0xfc, 0x3a, 0x73, 0x5a, 0xfa, 0xed,
+ 0xd3, 0xc8, 0x3d, 0x50, 0xa3, 0xa5, 0x8e, 0x08, 0x65, 0x7e, 0x5d, 0x76,
+ 0xa8, 0x9c, 0xe0, 0x63, 0xb1, 0x20, 0x93, 0x22, 0xea, 0x04, 0x7d, 0xe8,
+ 0x5f, 0x3d, 0x95, 0xd3, 0x68, 0xa8, 0x42, 0x6f, 0x81, 0xeb, 0x6d, 0x85,
+ 0x87, 0xf8, 0x1a, 0x71, 0x69, 0xd2, 0x32, 0x14, 0xe2, 0x4b, 0xc9, 0x51,
+ 0x37, 0xc4, 0x69, 0xc8, 0x65, 0x64, 0x2d, 0xfa, 0x90, 0x17, 0xf0, 0xcf,
+ 0xe7, 0x5f, 0x7a, 0xcc, 0x09, 0xf4, 0xdc, 0xdd, 0x81, 0x0c, 0x7e, 0x8f,
+ 0x32, 0xc0, 0x18, 0x3a, 0xef, 0x7c, 0xc5, 0xaf, 0x45, 0x54, 0x2d, 0x37,
+ 0x86, 0x9a, 0x82, 0x73, 0x2b, 0x2d, 0x05, 0x3b, 0x3c, 0xe3, 0x7d, 0x98,
+ 0x2b, 0xe2, 0x47, 0xb9, 0x10, 0x66, 0x3f, 0x9e, 0xf3, 0x01, 0x9c, 0x0c,
+ 0xfb, 0x35, 0x79, 0x58, 0x8b, 0x84, 0x39, 0xa1, 0xcc, 0xe8, 0x39, 0xe6,
+ 0xef, 0x3b, 0x40, 0x2b, 0x73, 0x56, 0x9c, 0xe7, 0xaa, 0xff, 0x59, 0x85,
+ 0xa9, 0xac, 0xc1, 0xf8, 0xb9, 0xe7, 0xa8, 0x1b, 0xe6, 0xbb, 0xcc, 0x69,
+ 0xc3, 0xdc, 0x27, 0xaf, 0x15, 0x9d, 0x31, 0xed, 0x3e, 0x87, 0xf0, 0xfa,
+ 0xec, 0x66, 0xb1, 0x52, 0x3d, 0xba, 0x27, 0x23, 0x43, 0xac, 0x9d, 0x8f,
+ 0xe1, 0xcc, 0x3b, 0xa4, 0x9c, 0x41, 0x1e, 0x60, 0xde, 0x85, 0xbe, 0x19,
+ 0x73, 0x5f, 0xc6, 0x1c, 0x74, 0x23, 0xc3, 0xfc, 0x66, 0x83, 0xaa, 0x41,
+ 0x4a, 0x2a, 0x76, 0xec, 0x08, 0xf4, 0xe5, 0x89, 0x4e, 0x5f, 0x3f, 0xbe,
+ 0x87, 0xf1, 0x46, 0xcc, 0x7f, 0x03, 0xbd, 0xe7, 0xf5, 0x0c, 0x85, 0xf3,
+ 0xd4, 0xfb, 0x61, 0xcc, 0xdf, 0x09, 0x1c, 0x15, 0x3c, 0x7f, 0x0e, 0xcf,
+ 0x7f, 0xb8, 0x6e, 0xed, 0x77, 0x31, 0xae, 0x60, 0xbe, 0xb0, 0x6e, 0x3e,
+ 0xf4, 0xb3, 0xdc, 0xaf, 0xa2, 0x15, 0xdd, 0x29, 0x2d, 0xaf, 0xea, 0x88,
+ 0x63, 0xa8, 0x55, 0xe8, 0x6b, 0x59, 0xb3, 0xcc, 0x20, 0x17, 0xa7, 0x9f,
+ 0x3d, 0x88, 0x35, 0x8b, 0xd0, 0xbb, 0x56, 0x95, 0x65, 0xea, 0xca, 0x1e,
+ 0x0f, 0x1d, 0xec, 0x99, 0x63, 0x5f, 0x39, 0x68, 0xd7, 0x09, 0xc3, 0xe7,
+ 0x27, 0x0f, 0xf6, 0xd4, 0x0f, 0x01, 0x96, 0xf9, 0x7a, 0xe3, 0x1d, 0xef,
+ 0x37, 0xd6, 0xed, 0xe9, 0xd7, 0x38, 0x45, 0x75, 0x37, 0x78, 0xe8, 0x60,
+ 0x61, 0x86, 0x71, 0x9a, 0xf5, 0x26, 0xf3, 0xd2, 0xca, 0xc1, 0xf1, 0xda,
+ 0x54, 0x50, 0xd3, 0x84, 0xef, 0xf9, 0x8e, 0xf2, 0xbf, 0x15, 0x6d, 0xa4,
+ 0xab, 0x11, 0x8f, 0xca, 0x6b, 0x80, 0xe7, 0x49, 0xe0, 0x61, 0x6d, 0xa4,
+ 0xee, 0x90, 0x15, 0xbd, 0xa9, 0xb9, 0x5b, 0xd1, 0x46, 0x5c, 0xdc, 0x2b,
+ 0xc4, 0x77, 0x02, 0x75, 0xc7, 0x77, 0x48, 0x2f, 0xf0, 0x7c, 0x26, 0xc8,
+ 0x6d, 0x78, 0x37, 0x65, 0xf8, 0x77, 0x38, 0x6a, 0x1c, 0xd6, 0xbe, 0x4d,
+ 0xeb, 0x6a, 0xdf, 0xa6, 0xe0, 0x1e, 0x8b, 0xb0, 0x7a, 0x00, 0xab, 0xee,
+ 0xd0, 0x31, 0x97, 0x0a, 0xee, 0x94, 0xe3, 0xbc, 0x53, 0x6e, 0x90, 0x45,
+ 0x53, 0x20, 0x7f, 0xd2, 0x11, 0xd6, 0x2b, 0x8d, 0xf4, 0xf1, 0xbe, 0x79,
+ 0x0a, 0xef, 0xc3, 0xb3, 0x09, 0x79, 0x5f, 0xc4, 0x3c, 0xe9, 0x3d, 0x03,
+ 0xf8, 0x90, 0xde, 0x4f, 0x7b, 0xa6, 0x5c, 0x7b, 0x06, 0xbf, 0x70, 0xbf,
+ 0x50, 0x2e, 0xa4, 0xf5, 0xd7, 0xd5, 0x5a, 0xa1, 0xdf, 0x5b, 0x0c, 0x62,
+ 0x3a, 0xe9, 0xa2, 0x0f, 0xa2, 0x3f, 0x0e, 0xef, 0xc0, 0x59, 0x63, 0x33,
+ 0x56, 0xf0, 0xbc, 0x5a, 0xa0, 0x2b, 0x84, 0xd3, 0x90, 0x5f, 0xeb, 0xcc,
+ 0xc3, 0x52, 0xa8, 0x35, 0x92, 0x8f, 0xc8, 0x0f, 0xb0, 0x57, 0x3e, 0xd3,
+ 0xa4, 0xec, 0x88, 0xf7, 0x08, 0xcd, 0xb2, 0x02, 0x9d, 0xbe, 0x84, 0xfa,
+ 0x63, 0x1e, 0xb5, 0xd1, 0x12, 0xef, 0xb5, 0xeb, 0x27, 0x3b, 0x79, 0x1f,
+ 0x32, 0x65, 0xad, 0xd5, 0xf1, 0x73, 0x80, 0x59, 0xb0, 0x58, 0xeb, 0x4b,
+ 0xd0, 0x10, 0x23, 0x91, 0x67, 0x8c, 0x5b, 0xff, 0xe3, 0x95, 0x13, 0x8d,
+ 0xb0, 0xb7, 0xaa, 0xb3, 0xdb, 0xa4, 0x3a, 0x9b, 0x3e, 0x3a, 0x87, 0x7a,
+ 0x77, 0xc6, 0xd2, 0xb7, 0xe8, 0x7e, 0xad, 0x34, 0x03, 0xdf, 0xa4, 0x6a,
+ 0xad, 0x39, 0x79, 0xae, 0x93, 0x67, 0xd7, 0x64, 0xf5, 0x9b, 0x9d, 0xfa,
+ 0xef, 0x50, 0x17, 0x15, 0xe5, 0xb1, 0x13, 0x1b, 0xa4, 0x3c, 0x70, 0x1f,
+ 0x72, 0x2d, 0xc8, 0xf3, 0x44, 0x05, 0x95, 0x21, 0xf5, 0xea, 0xbd, 0x03,
+ 0xe3, 0x16, 0x6b, 0x26, 0xf1, 0xe3, 0x9a, 0xf8, 0x3c, 0xc6, 0x4e, 0xb4,
+ 0x29, 0x9f, 0xe4, 0xdf, 0x99, 0xf7, 0x9a, 0x45, 0xe4, 0x63, 0x85, 0x01,
+ 0x24, 0x8d, 0xc8, 0x5e, 0xcc, 0x9d, 0x22, 0x3d, 0xcc, 0x19, 0xe1, 0x8f,
+ 0x7b, 0xce, 0xc1, 0xcb, 0x9d, 0x20, 0xbc, 0x2e, 0xc6, 0x89, 0x98, 0x34,
+ 0x9d, 0x60, 0x9d, 0x2d, 0x5d, 0xa8, 0x51, 0x88, 0xb3, 0xc7, 0x40, 0x3f,
+ 0x8a, 0xdf, 0x1e, 0xe4, 0x51, 0x26, 0xf2, 0xda, 0x5b, 0xc0, 0x03, 0x96,
+ 0x6b, 0x6e, 0x05, 0xff, 0x6a, 0x27, 0xeb, 0xce, 0x9e, 0x73, 0x84, 0xe7,
+ 0x7d, 0x76, 0x17, 0xe8, 0xf1, 0xf7, 0x27, 0x0e, 0xe3, 0x84, 0x48, 0xef,
+ 0xb4, 0x74, 0xea, 0x6a, 0x8d, 0x21, 0xe3, 0x59, 0xbe, 0x6b, 0x03, 0xfc,
+ 0xab, 0xca, 0x3e, 0x7b, 0xd5, 0x3a, 0xff, 0xce, 0xa2, 0xbc, 0x46, 0x37,
+ 0xe6, 0x34, 0x3c, 0x23, 0x57, 0xca, 0x9a, 0xd2, 0x3b, 0xef, 0xc3, 0xf6,
+ 0x9c, 0xeb, 0xd8, 0xe2, 0xdf, 0xed, 0xf8, 0xb4, 0xf1, 0x6e, 0xb0, 0x0c,
+ 0xa9, 0x1a, 0x3b, 0x59, 0xf3, 0x13, 0x86, 0xdf, 0x52, 0xd8, 0x73, 0x2d,
+ 0xe5, 0xe7, 0xcf, 0xe9, 0xfa, 0xff, 0xa5, 0x5f, 0xeb, 0xbf, 0xe1, 0x84,
+ 0x77, 0x4b, 0xa9, 0x86, 0xbb, 0xa5, 0x74, 0xc3, 0xb7, 0x97, 0x9f, 0xb4,
+ 0x05, 0x7a, 0x27, 0x93, 0xb6, 0x27, 0xe1, 0xf7, 0xa5, 0xbd, 0x37, 0xe5,
+ 0x90, 0x19, 0x15, 0xa7, 0xc7, 0x21, 0xfb, 0x2b, 0x75, 0xd2, 0x8b, 0x98,
+ 0x53, 0x8f, 0xcb, 0xfb, 0x8b, 0xad, 0x72, 0x65, 0xce, 0xcf, 0x29, 0xaf,
+ 0xa8, 0x6f, 0x4e, 0xa6, 0x7c, 0x80, 0xc2, 0xff, 0x72, 0x3d, 0x83, 0x5f,
+ 0xa7, 0x5c, 0x5d, 0xbc, 0x39, 0xa7, 0xbc, 0xe0, 0xde, 0x0d, 0x5a, 0x3a,
+ 0x03, 0x1b, 0x46, 0xdd, 0x86, 0x18, 0x58, 0x09, 0xee, 0xea, 0x55, 0xce,
+ 0x62, 0xd0, 0x16, 0x78, 0x27, 0x1f, 0xde, 0x57, 0xf7, 0x9a, 0x17, 0x21,
+ 0xe3, 0xaf, 0x1a, 0x9d, 0xa8, 0xa3, 0x79, 0xd7, 0x16, 0xc6, 0xec, 0x30,
+ 0xf6, 0x90, 0xee, 0xb7, 0x81, 0x7b, 0x00, 0x7a, 0x4a, 0xdd, 0xb4, 0xa1,
+ 0xb3, 0xa6, 0x2c, 0xf5, 0xa5, 0x67, 0x2a, 0xc2, 0xef, 0x02, 0x59, 0xec,
+ 0xb9, 0x0c, 0xbd, 0xcc, 0x40, 0x1e, 0xcc, 0xf5, 0x28, 0x57, 0x9c, 0xed,
+ 0xf4, 0x94, 0x94, 0xdd, 0xad, 0xc0, 0x97, 0x97, 0x92, 0x3b, 0x8c, 0xbd,
+ 0x8e, 0x43, 0x6f, 0x7f, 0xb9, 0x85, 0x77, 0x99, 0xcd, 0x56, 0x16, 0x34,
+ 0xde, 0x25, 0xe3, 0x27, 0xa7, 0x64, 0xc2, 0x59, 0xfd, 0x66, 0x94, 0xe1,
+ 0xf7, 0x94, 0x45, 0xd4, 0xb4, 0xbe, 0x3d, 0xe6, 0x64, 0xfc, 0x14, 0x70,
+ 0x38, 0xac, 0x8d, 0x7b, 0xa1, 0x37, 0xfd, 0xaa, 0x36, 0x2e, 0x29, 0x9f,
+ 0xc4, 0xf9, 0xef, 0x01, 0x57, 0x6f, 0x65, 0x0f, 0xe0, 0xca, 0xa8, 0x9f,
+ 0x8b, 0xc8, 0x85, 0x17, 0x1c, 0x43, 0xca, 0x36, 0x7c, 0x6b, 0x31, 0xa9,
+ 0xeb, 0xbb, 0xba, 0x65, 0xde, 0xe9, 0x37, 0x75, 0xde, 0x3d, 0x26, 0x7c,
+ 0xdf, 0x57, 0x56, 0xf6, 0x9d, 0xd4, 0x0d, 0xab, 0x5b, 0x16, 0x9d, 0x8a,
+ 0x54, 0x07, 0x38, 0xe6, 0xf9, 0x55, 0xc4, 0xb4, 0x7c, 0x5f, 0x99, 0xd7,
+ 0x35, 0x75, 0xb7, 0x5d, 0x76, 0xd5, 0xfd, 0x68, 0xca, 0x94, 0xc3, 0xa0,
+ 0x0f, 0xcf, 0x0b, 0xd0, 0xf1, 0x69, 0xe6, 0x78, 0xfe, 0x9d, 0xf1, 0x81,
+ 0xe5, 0x22, 0x68, 0x68, 0x97, 0xde, 0x1f, 0xd3, 0xc6, 0x1e, 0xc2, 0x1c,
+ 0xc7, 0x69, 0xe8, 0xeb, 0xc3, 0x78, 0x26, 0x6c, 0x12, 0x3d, 0xe5, 0xd0,
+ 0x8d, 0xde, 0x04, 0x2d, 0xd0, 0x4b, 0xd6, 0xa5, 0xfb, 0x53, 0x32, 0x7f,
+ 0x72, 0xb7, 0x94, 0x16, 0x76, 0x03, 0xff, 0x3f, 0x22, 0xe7, 0xbf, 0x33,
+ 0xb8, 0x8b, 0x65, 0xde, 0xcf, 0x7d, 0x5e, 0xdc, 0xa2, 0x6c, 0x63, 0x9a,
+ 0xf3, 0xec, 0xf7, 0x61, 0x3d, 0xea, 0x07, 0x47, 0xdd, 0x4f, 0x03, 0x06,
+ 0x67, 0xe7, 0x36, 0x7e, 0xfb, 0xeb, 0x84, 0x9f, 0xae, 0xb0, 0x76, 0x40,
+ 0x6c, 0x99, 0x1b, 0x2c, 0xd4, 0xd2, 0x66, 0x41, 0x7d, 0x97, 0xc8, 0x88,
+ 0x1f, 0x6f, 0x38, 0x17, 0x17, 0x6b, 0x1a, 0xf5, 0x68, 0x8e, 0xef, 0x0e,
+ 0xab, 0xfb, 0x1f, 0xf5, 0x7d, 0x4e, 0xde, 0x95, 0x51, 0xe8, 0x58, 0xef,
+ 0x74, 0x06, 0x39, 0xf1, 0x7b, 0xc8, 0x27, 0x7f, 0x1e, 0xc8, 0x60, 0x38,
+ 0xd0, 0x8d, 0xd6, 0x06, 0x9d, 0xc0, 0x39, 0x3b, 0x38, 0x7b, 0x07, 0x7a,
+ 0xe0, 0xe0, 0xac, 0x57, 0xf5, 0x63, 0xb8, 0xc1, 0xe7, 0x6e, 0x92, 0xbf,
+ 0x9c, 0x49, 0x67, 0x56, 0xa0, 0x3f, 0x57, 0xc1, 0xeb, 0x0a, 0xea, 0xbc,
+ 0x2b, 0x88, 0x23, 0x0b, 0x35, 0x7e, 0x4b, 0xe0, 0xb7, 0x38, 0x8e, 0xb7,
+ 0xe1, 0x3c, 0x42, 0x7f, 0xfc, 0x52, 0x60, 0x17, 0x9b, 0xd4, 0x7d, 0xe7,
+ 0xfb, 0x38, 0xc3, 0x15, 0xd3, 0xcf, 0x17, 0xfd, 0x35, 0x9b, 0x24, 0xfc,
+ 0xde, 0xe7, 0xeb, 0x0f, 0x69, 0xa1, 0xfe, 0x7c, 0xb2, 0xc5, 0xcf, 0xfb,
+ 0xf9, 0x0d, 0x8c, 0xf5, 0x0b, 0x9f, 0xef, 0xdf, 0xe2, 0xe3, 0x6a, 0xd4,
+ 0xdb, 0x8f, 0x3d, 0xd6, 0x6a, 0x85, 0x3e, 0xf8, 0x6c, 0xd7, 0x93, 0x63,
+ 0xf6, 0xcd, 0xf6, 0x76, 0x8f, 0x13, 0xca, 0x87, 0xf2, 0x2b, 0xca, 0x11,
+ 0x37, 0x0d, 0x5b, 0xa0, 0xec, 0xac, 0x06, 0xd9, 0x89, 0xfc, 0xb9, 0x23,
+ 0xbc, 0xef, 0xc2, 0x3b, 0x25, 0xbb, 0x64, 0x21, 0xd6, 0xca, 0xfb, 0x5a,
+ 0xe8, 0xe3, 0xdf, 0xca, 0xc4, 0xac, 0xc8, 0x32, 0xde, 0x2f, 0x39, 0xb4,
+ 0xd1, 0x0c, 0xf2, 0xd7, 0x8d, 0x32, 0x3f, 0x87, 0x3a, 0xcb, 0x91, 0x52,
+ 0xe1, 0x4e, 0xc6, 0x99, 0xb8, 0x5c, 0x51, 0xf7, 0x7b, 0x22, 0x3b, 0xcf,
+ 0x1a, 0x62, 0x9c, 0x45, 0x41, 0x07, 0x99, 0x9f, 0xef, 0x0b, 0xef, 0xfb,
+ 0x7c, 0x5b, 0xaf, 0xd6, 0xb0, 0xd6, 0xe9, 0x55, 0xfe, 0xb1, 0x5a, 0x1f,
+ 0x97, 0xf2, 0x0c, 0xf7, 0x42, 0x3f, 0x97, 0xc2, 0x3b, 0x5b, 0x26, 0x4f,
+ 0x66, 0xe4, 0xfb, 0xfc, 0x5e, 0x93, 0x1d, 0xc5, 0x1e, 0x05, 0xa9, 0x2c,
+ 0x63, 0xbe, 0xfe, 0x4f, 0x32, 0xb7, 0x38, 0x2e, 0xf3, 0x33, 0x17, 0x1a,
+ 0xee, 0x73, 0x31, 0x9e, 0x6b, 0xac, 0x4f, 0x8b, 0xac, 0xa9, 0x50, 0x7f,
+ 0x5a, 0x18, 0xc3, 0x06, 0xea, 0x93, 0xa5, 0x9b, 0xef, 0x1f, 0x1b, 0xeb,
+ 0xd2, 0x51, 0x39, 0x8a, 0x33, 0xae, 0x9e, 0xcc, 0xa8, 0xba, 0xa6, 0x25,
+ 0x37, 0xfb, 0xf8, 0x87, 0x88, 0x11, 0x63, 0x42, 0x3d, 0xbb, 0x2e, 0x5f,
+ 0xb3, 0x8f, 0xca, 0x23, 0x88, 0x1d, 0x47, 0x90, 0x5f, 0xff, 0x36, 0xea,
+ 0xba, 0xd4, 0x66, 0x9e, 0x21, 0xe8, 0xb5, 0x58, 0x57, 0x7a, 0x32, 0x6a,
+ 0xdf, 0x61, 0xfe, 0x00, 0x92, 0x7d, 0xbf, 0xce, 0xf8, 0xf8, 0xdf, 0x5e,
+ 0x1e, 0xf1, 0xee, 0x43, 0x0b, 0x3e, 0x41, 0xc1, 0x69, 0x3e, 0xdc, 0x0c,
+ 0xe1, 0xfa, 0xcd, 0x63, 0x84, 0x9b, 0xd3, 0x02, 0x38, 0x0d, 0x70, 0x31,
+ 0xb9, 0x68, 0x1b, 0xd0, 0x8d, 0x51, 0xf0, 0x09, 0xdf, 0x3e, 0x18, 0x7e,
+ 0x6f, 0xdc, 0x80, 0x98, 0xba, 0xb6, 0xfe, 0x8d, 0x60, 0xfd, 0xf7, 0x83,
+ 0xf5, 0x97, 0x56, 0xd7, 0x87, 0x71, 0xf5, 0x13, 0x4f, 0x1a, 0xe8, 0x7a,
+ 0xa3, 0xe6, 0xc3, 0x1f, 0x0d, 0xe8, 0xba, 0xb4, 0x4a, 0x57, 0x08, 0x0f,
+ 0x79, 0x2a, 0x9e, 0xe9, 0x93, 0xe9, 0x9b, 0x7b, 0x21, 0x47, 0x7e, 0x47,
+ 0x86, 0x4d, 0x38, 0xfc, 0x7e, 0x4b, 0x3b, 0xd1, 0x65, 0x25, 0x71, 0x54,
+ 0xc6, 0xac, 0xf4, 0xf0, 0xa4, 0xc4, 0xa0, 0xc3, 0xf4, 0x29, 0x31, 0x99,
+ 0xa7, 0xaf, 0x41, 0x5f, 0xb6, 0x6f, 0x4d, 0xeb, 0xfb, 0x0d, 0xb4, 0xc6,
+ 0x9e, 0x27, 0x8d, 0x3e, 0xad, 0xf1, 0x1d, 0x6b, 0xb4, 0xfa, 0xf0, 0x3e,
+ 0xad, 0xef, 0xd7, 0x1a, 0xe0, 0xcf, 0x1a, 0x01, 0xbc, 0xd1, 0x00, 0x4f,
+ 0x7d, 0x66, 0x3e, 0x41, 0x7d, 0x26, 0x6d, 0x5f, 0x50, 0xf7, 0x66, 0x1b,
+ 0x72, 0xb3, 0x07, 0x3f, 0xbf, 0xc3, 0x93, 0x38, 0xf2, 0x8c, 0x66, 0xbc,
+ 0xbb, 0x32, 0xc3, 0x1c, 0x44, 0xef, 0x69, 0x96, 0x9d, 0xd0, 0x59, 0x9e,
+ 0x5d, 0xe3, 0x9d, 0xab, 0x27, 0x8f, 0xd8, 0xa4, 0xe5, 0x3f, 0xbd, 0x33,
+ 0x89, 0x9d, 0x76, 0x55, 0xfa, 0xcc, 0x66, 0xe1, 0x9d, 0xae, 0xc2, 0x99,
+ 0x21, 0x2d, 0xa7, 0xfb, 0x7a, 0xcd, 0xb7, 0xc0, 0xe7, 0xe8, 0x8c, 0x26,
+ 0xf3, 0x56, 0x3a, 0x79, 0x1e, 0x38, 0xf6, 0xe0, 0x6c, 0xe6, 0x07, 0x48,
+ 0x8f, 0xc8, 0x04, 0xf4, 0x7b, 0x5e, 0xc5, 0x43, 0xea, 0x71, 0x7a, 0xac,
+ 0x82, 0x1c, 0xe7, 0xa7, 0x2a, 0xa6, 0x79, 0xde, 0x87, 0x88, 0x6b, 0x63,
+ 0xeb, 0x74, 0x4f, 0x3f, 0xeb, 0xeb, 0x9e, 0x7e, 0x16, 0xb5, 0xf1, 0xf1,
+ 0xb8, 0xb4, 0x2c, 0xc1, 0x7e, 0x9e, 0xef, 0x52, 0xfa, 0xa7, 0x3f, 0xcf,
+ 0x6f, 0x19, 0xf0, 0x73, 0xc7, 0x0d, 0xb1, 0x8e, 0xab, 0x38, 0x00, 0x79,
+ 0x17, 0x64, 0xf2, 0x14, 0x7d, 0xa9, 0x25, 0x3b, 0x8e, 0xf3, 0x3c, 0x98,
+ 0xcf, 0xcc, 0x0d, 0x8e, 0xc3, 0x46, 0xa6, 0xf8, 0x7d, 0x70, 0xe9, 0x23,
+ 0x19, 0xb7, 0x28, 0x07, 0x94, 0xfa, 0x4b, 0xa6, 0xc4, 0x96, 0xe0, 0x13,
+ 0x96, 0x92, 0xd2, 0x04, 0xdb, 0xd2, 0xcf, 0x26, 0xb4, 0xea, 0xec, 0x7f,
+ 0xc1, 0x1e, 0xf8, 0x4d, 0x20, 0x83, 0x71, 0x52, 0xab, 0xd6, 0x06, 0xd0,
+ 0x53, 0xcf, 0x91, 0x46, 0x9d, 0xa5, 0x9e, 0x93, 0x8e, 0xd0, 0x5e, 0xf0,
+ 0x7c, 0x36, 0xa3, 0xee, 0x6c, 0x3f, 0xb4, 0xc9, 0xcb, 0xdf, 0x48, 0x61,
+ 0x26, 0xfc, 0x1b, 0x10, 0xd9, 0x8c, 0x1c, 0xa6, 0xa3, 0x60, 0xef, 0x18,
+ 0xbe, 0x22, 0x9f, 0x96, 0xaf, 0x6d, 0x9f, 0x82, 0x2f, 0xf2, 0xd1, 0xc8,
+ 0x17, 0x79, 0x6a, 0x97, 0x26, 0xc5, 0x57, 0xc8, 0x0f, 0x04, 0x0d, 0x7e,
+ 0x7a, 0x8e, 0x27, 0x81, 0xff, 0x61, 0xf8, 0x80, 0x6e, 0xf4, 0x0f, 0xa1,
+ 0x47, 0x28, 0x3b, 0x4b, 0xde, 0xc9, 0xeb, 0x55, 0xe4, 0x8b, 0x21, 0x9f,
+ 0x25, 0x3c, 0xbf, 0x2e, 0x93, 0xb3, 0xde, 0x61, 0xc4, 0x53, 0xde, 0x27,
+ 0x77, 0xea, 0x4a, 0x77, 0xd7, 0xf3, 0xfe, 0xba, 0xf8, 0xf2, 0xe1, 0x5d,
+ 0x3c, 0x9e, 0x17, 0xd7, 0xcb, 0xa2, 0xd1, 0x77, 0x24, 0x83, 0xbf, 0x7b,
+ 0xa1, 0x9f, 0xa0, 0x8c, 0xae, 0x4a, 0x61, 0x96, 0x77, 0x5a, 0x3e, 0xbe,
+ 0xd2, 0xea, 0xdf, 0xbe, 0x34, 0xae, 0x19, 0x00, 0x5c, 0x37, 0xe0, 0x48,
+ 0xd7, 0x0a, 0xe5, 0x07, 0x9f, 0xb3, 0xbd, 0xc1, 0xd7, 0x34, 0xae, 0xcb,
+ 0xca, 0x33, 0x88, 0xff, 0x6f, 0xd8, 0x37, 0xc9, 0xb5, 0xc4, 0x1c, 0x68,
+ 0xbe, 0xbe, 0x0f, 0x36, 0xd9, 0x04, 0x5f, 0x66, 0xca, 0x95, 0x5a, 0xb3,
+ 0xcc, 0x23, 0xcf, 0x59, 0x58, 0xa4, 0x2f, 0x24, 0xed, 0xad, 0x98, 0xf7,
+ 0xfd, 0x17, 0x7d, 0xed, 0x95, 0x1a, 0xe2, 0x2b, 0x6c, 0xfb, 0x4a, 0x2d,
+ 0x81, 0xbe, 0x1b, 0xbd, 0x85, 0x3e, 0x85, 0x3e, 0x83, 0x7e, 0x00, 0xfd,
+ 0x00, 0x7a, 0x0b, 0x6b, 0x93, 0xe8, 0xc3, 0x5a, 0x82, 0xb8, 0xd6, 0xf8,
+ 0xae, 0xaa, 0xfd, 0xf8, 0xdd, 0x90, 0xb1, 0xcc, 0xb0, 0x47, 0x50, 0x63,
+ 0x17, 0x06, 0xc2, 0xbf, 0xb9, 0xb9, 0xe1, 0x99, 0x16, 0x6b, 0xf7, 0x8a,
+ 0xb6, 0x47, 0x7d, 0x5f, 0x98, 0x41, 0x5c, 0x78, 0x6e, 0xab, 0xb4, 0x5a,
+ 0xe6, 0x3d, 0xea, 0xee, 0x68, 0x16, 0x63, 0x3e, 0xa3, 0x3e, 0x4e, 0x4c,
+ 0x21, 0x3e, 0xd1, 0x7f, 0xfe, 0x6f, 0xe7, 0xd6, 0x1b, 0xdb, 0xc6, 0x59,
+ 0xc6, 0x1f, 0x9f, 0x9d, 0x34, 0xe9, 0x9a, 0xf6, 0x92, 0x38, 0xa9, 0x93,
+ 0x85, 0xcd, 0x8e, 0x2f, 0xad, 0x45, 0xd2, 0x71, 0xed, 0x2c, 0x16, 0xa6,
+ 0x8c, 0x78, 0x76, 0x92, 0x76, 0x30, 0xa6, 0xb4, 0x74, 0xd3, 0x84, 0x10,
+ 0x58, 0xc9, 0xba, 0x75, 0x13, 0xd2, 0x28, 0x30, 0x34, 0x89, 0xa2, 0x18,
+ 0x27, 0x61, 0x19, 0x18, 0xc7, 0x0b, 0x81, 0x4e, 0xf0, 0xc5, 0x38, 0xd1,
+ 0x06, 0x22, 0x4a, 0x3a, 0x8d, 0x0f, 0x08, 0x6d, 0x74, 0xb8, 0x83, 0xef,
+ 0xfc, 0x11, 0x62, 0x12, 0x1f, 0xaa, 0xa8, 0x63, 0x20, 0x21, 0xe0, 0x23,
+ 0xd2, 0x98, 0x8e, 0xdf, 0xef, 0x79, 0xef, 0x12, 0xc7, 0x64, 0x54, 0xf0,
+ 0xc1, 0x3a, 0xbf, 0x77, 0xf7, 0xbe, 0xf7, 0xde, 0xfb, 0x3c, 0xef, 0xef,
+ 0xf9, 0x3d, 0x7f, 0xce, 0x43, 0x9f, 0x19, 0xe0, 0xf8, 0x11, 0x61, 0x0c,
+ 0x36, 0x9b, 0xc6, 0xff, 0xea, 0xc5, 0x1e, 0x63, 0x4b, 0xc1, 0xdb, 0x77,
+ 0xb8, 0x61, 0x60, 0xab, 0x46, 0xd0, 0x67, 0x3f, 0x9f, 0x00, 0x36, 0xb0,
+ 0x92, 0xa8, 0x54, 0xb1, 0x07, 0x7f, 0xed, 0xce, 0x29, 0xa7, 0xa3, 0x2c,
+ 0x16, 0xc1, 0x4d, 0x73, 0x65, 0x72, 0x97, 0xcb, 0xf0, 0x47, 0xe0, 0xcb,
+ 0x45, 0xe9, 0xbb, 0xd3, 0x16, 0x90, 0x83, 0xfe, 0x12, 0x73, 0xa3, 0x1d,
+ 0xf8, 0x26, 0x9e, 0x87, 0xf7, 0x5a, 0xf3, 0xb0, 0x66, 0xa7, 0xc1, 0x05,
+ 0x3d, 0x2f, 0xe2, 0x4c, 0x4a, 0xfc, 0x1c, 0x31, 0x47, 0xd0, 0xdf, 0xc4,
+ 0xb2, 0xc8, 0xab, 0x32, 0xd3, 0x9a, 0x83, 0x84, 0x72, 0xfd, 0x0e, 0x7d,
+ 0x7b, 0xc4, 0xc4, 0xa7, 0x18, 0x7f, 0x16, 0x99, 0x2c, 0x1b, 0x2e, 0x0b,
+ 0xbf, 0xac, 0x61, 0xbc, 0xbb, 0xfd, 0xf1, 0x78, 0xdd, 0xd2, 0x71, 0x6a,
+ 0xd2, 0x6b, 0x62, 0xbb, 0x63, 0x23, 0xb0, 0x11, 0x51, 0xa9, 0x43, 0x2e,
+ 0xd7, 0x21, 0x93, 0x37, 0x4b, 0xd4, 0xf5, 0x61, 0xe8, 0x7d, 0x0b, 0xf3,
+ 0xb3, 0x18, 0x6b, 0x44, 0x9f, 0x5d, 0x2f, 0x01, 0x3b, 0x6d, 0xf5, 0x4f,
+ 0x7b, 0xc9, 0x0b, 0x69, 0x07, 0xcd, 0x38, 0x03, 0xe6, 0x3e, 0x09, 0xae,
+ 0x75, 0xeb, 0x7c, 0x6a, 0x1a, 0x03, 0xe3, 0x3a, 0x41, 0x07, 0x4b, 0xdd,
+ 0xfe, 0x3d, 0x5e, 0x8f, 0xa9, 0x77, 0xe2, 0x39, 0xbe, 0xc7, 0x88, 0x64,
+ 0xcb, 0x41, 0xbf, 0x4e, 0xf4, 0x6b, 0x6f, 0x18, 0xeb, 0x68, 0xd3, 0x3b,
+ 0x58, 0xfe, 0x3b, 0xf0, 0x7a, 0x33, 0xdf, 0x4f, 0xd8, 0x05, 0x09, 0x38,
+ 0x3f, 0xed, 0x2f, 0x65, 0x93, 0xd6, 0xfc, 0xb6, 0x91, 0xcf, 0x80, 0xef,
+ 0x03, 0x24, 0x96, 0x0a, 0x02, 0xbe, 0x18, 0xa5, 0x8c, 0xd2, 0xd8, 0xd7,
+ 0x3f, 0x89, 0xca, 0x61, 0x57, 0x2a, 0xa5, 0x03, 0x62, 0x75, 0xb5, 0x68,
+ 0x8d, 0x4e, 0xdc, 0x6a, 0x7c, 0xe6, 0x67, 0xfd, 0x67, 0xc2, 0xf7, 0x5e,
+ 0x69, 0xd7, 0xb8, 0x34, 0xec, 0x0c, 0xee, 0x39, 0xd4, 0x34, 0xb7, 0x87,
+ 0xfd, 0xfb, 0x78, 0xdd, 0x91, 0x02, 0xf8, 0x67, 0xae, 0x0c, 0x26, 0x0f,
+ 0xfc, 0xb6, 0xc6, 0x98, 0xe3, 0x61, 0x0c, 0x6f, 0x38, 0x3e, 0x8f, 0x39,
+ 0x16, 0xec, 0x31, 0xc6, 0xcd, 0x30, 0x46, 0x5f, 0xd3, 0x18, 0x13, 0xfe,
+ 0x18, 0x59, 0x29, 0x5e, 0x99, 0xc0, 0x5e, 0x1b, 0x83, 0x7d, 0x4f, 0xda,
+ 0xa7, 0xe5, 0x23, 0x22, 0x9d, 0x38, 0xf7, 0x72, 0x0a, 0x72, 0xf2, 0xbc,
+ 0x49, 0x77, 0x1a, 0xf3, 0x7e, 0x0d, 0xb6, 0x35, 0xe0, 0x3c, 0xc5, 0x58,
+ 0x18, 0x36, 0xec, 0xf3, 0x2e, 0xe3, 0x62, 0x05, 0x30, 0xb2, 0x84, 0x6d,
+ 0x85, 0x86, 0x53, 0x35, 0xf0, 0xba, 0x2a, 0x2c, 0x69, 0xd1, 0xe1, 0x7b,
+ 0x76, 0x48, 0xd1, 0x0e, 0x8d, 0x87, 0xc1, 0x6b, 0xb2, 0x65, 0xee, 0x23,
+ 0x19, 0x0a, 0x8f, 0xb5, 0x82, 0x8b, 0x7a, 0xf2, 0x36, 0xa0, 0xa6, 0x58,
+ 0x5a, 0x92, 0xfa, 0x86, 0x8d, 0xe3, 0x05, 0xc8, 0xe1, 0x45, 0xfc, 0x7f,
+ 0x3e, 0xaa, 0x75, 0x4a, 0xe0, 0xeb, 0x8b, 0x78, 0x1f, 0xf2, 0x19, 0xf2,
+ 0x88, 0x1a, 0xec, 0xad, 0x05, 0x5b, 0x03, 0x5e, 0x35, 0x4a, 0xde, 0xf5,
+ 0xdc, 0xda, 0x4d, 0x79, 0x73, 0x35, 0x81, 0x67, 0xd1, 0x2e, 0x9f, 0x21,
+ 0x1e, 0xd8, 0x0b, 0x69, 0x9c, 0x5b, 0x37, 0xdc, 0xb7, 0xb8, 0x85, 0x0d,
+ 0xd4, 0x05, 0x8e, 0x00, 0x8e, 0xbd, 0x0d, 0x0c, 0x2c, 0xe2, 0xfe, 0xfa,
+ 0x6a, 0x44, 0xd6, 0x1c, 0xf2, 0x22, 0x89, 0x67, 0x71, 0x6f, 0x7d, 0x7d,
+ 0xb1, 0xd7, 0xe4, 0x51, 0xd8, 0x7f, 0x42, 0x0a, 0xe0, 0x75, 0xa7, 0xb5,
+ 0xef, 0xad, 0xe4, 0xcc, 0x39, 0x35, 0xfa, 0x77, 0xb3, 0x52, 0xe7, 0x7e,
+ 0xd2, 0xdc, 0x03, 0xb9, 0xc1, 0x65, 0xe8, 0x2c, 0x39, 0x3b, 0xfd, 0x00,
+ 0xfc, 0xdf, 0xe0, 0x75, 0xbe, 0x3b, 0x8e, 0xd5, 0x24, 0xd6, 0x86, 0xfb,
+ 0xbe, 0x10, 0x9a, 0x3e, 0x0e, 0x3b, 0x6a, 0x71, 0xaf, 0x17, 0x15, 0x0b,
+ 0x8a, 0xcb, 0xb3, 0xb0, 0x29, 0xac, 0xb5, 0xe8, 0x83, 0x2e, 0x3e, 0x08,
+ 0x59, 0xa6, 0x71, 0x5f, 0x93, 0x2d, 0xd9, 0x2c, 0x2a, 0x2f, 0xb3, 0x5e,
+ 0x32, 0xb8, 0x66, 0xd5, 0xc0, 0xd1, 0xb0, 0x7f, 0xac, 0x4d, 0xe8, 0x16,
+ 0xf6, 0x90, 0xb5, 0x19, 0xc5, 0x11, 0x78, 0xbc, 0x09, 0xbf, 0x02, 0xf8,
+ 0x66, 0x6d, 0xc2, 0x27, 0x00, 0xbe, 0x59, 0x9b, 0x29, 0x1c, 0x81, 0xf1,
+ 0x9b, 0x01, 0xae, 0x71, 0xfc, 0x94, 0xe6, 0xe1, 0x0d, 0xbe, 0x90, 0x4b,
+ 0x12, 0x5f, 0x02, 0x3e, 0x69, 0x74, 0xe1, 0xeb, 0xcb, 0xc4, 0x10, 0xea,
+ 0x75, 0x12, 0xb8, 0x45, 0x5d, 0x30, 0x5c, 0x72, 0xbd, 0x62, 0xd6, 0x6c,
+ 0x7e, 0xeb, 0x9a, 0xda, 0x88, 0x29, 0x71, 0xa0, 0x63, 0x5c, 0x3b, 0x5c,
+ 0x53, 0x1b, 0xf0, 0xba, 0x64, 0xf4, 0xc8, 0x35, 0xfb, 0xb9, 0x64, 0xd6,
+ 0x53, 0xf2, 0x0d, 0xc5, 0xad, 0x00, 0xb3, 0xc8, 0x21, 0x63, 0x58, 0x3f,
+ 0x47, 0x9e, 0xff, 0xf6, 0x4d, 0xc9, 0x7e, 0x87, 0xb8, 0x35, 0x1c, 0x6b,
+ 0x0f, 0x11, 0xab, 0x3c, 0xd9, 0x80, 0x6d, 0x3a, 0xed, 0x26, 0x1e, 0x65,
+ 0xfd, 0x66, 0x1e, 0xba, 0xd2, 0x7a, 0x32, 0xe1, 0xc6, 0x43, 0xc9, 0x47,
+ 0xdb, 0x43, 0xb4, 0x8d, 0xc3, 0xf6, 0x45, 0x39, 0xe5, 0xc7, 0xa3, 0x0e,
+ 0xc8, 0x45, 0xe5, 0xfe, 0x2c, 0xcf, 0x78, 0x57, 0x73, 0x23, 0xef, 0xa4,
+ 0xb9, 0xd6, 0x68, 0x6f, 0x6a, 0xdc, 0xa8, 0xed, 0x9d, 0x74, 0x8b, 0x14,
+ 0x7b, 0x3c, 0xef, 0xc2, 0xc9, 0xb7, 0xa2, 0x26, 0xce, 0xd5, 0x7f, 0xd4,
+ 0x60, 0x01, 0x00, 0x4c, 0xdb, 0x9f, 0xc0, 0x91, 0xba, 0x4d, 0x7b, 0x4b,
+ 0xfb, 0x48, 0xb9, 0xe1, 0xb8, 0xce, 0xff, 0xb4, 0xbd, 0x4b, 0xb0, 0xbd,
+ 0xb4, 0x97, 0x47, 0x24, 0xc7, 0x9c, 0x9c, 0xa5, 0xe7, 0x0b, 0x86, 0x4b,
+ 0xfb, 0xf7, 0x55, 0xf2, 0x32, 0x5f, 0x21, 0x87, 0xaa, 0xc3, 0x96, 0xb1,
+ 0xf6, 0x91, 0x36, 0x6d, 0x0e, 0xf6, 0x9c, 0xb9, 0x5a, 0x5c, 0xab, 0xb2,
+ 0x5f, 0x22, 0x15, 0xb7, 0xf0, 0xce, 0x3b, 0x3a, 0x55, 0x82, 0xfe, 0x51,
+ 0x9f, 0x20, 0xf7, 0x17, 0xe8, 0x5b, 0x0c, 0xa9, 0x8e, 0x64, 0x7f, 0xc0,
+ 0xb5, 0xf7, 0xbc, 0x33, 0x2e, 0xd4, 0xb0, 0xd3, 0xec, 0x01, 0xf2, 0x80,
+ 0x8f, 0x63, 0x5d, 0xa6, 0xdc, 0x9b, 0xb4, 0xdd, 0x7f, 0xb7, 0x9c, 0xe1,
+ 0xd4, 0xc5, 0x10, 0xf7, 0x36, 0xda, 0xeb, 0x61, 0xa9, 0x46, 0xf9, 0xfe,
+ 0x58, 0xaf, 0x10, 0xf7, 0xce, 0x7e, 0xeb, 0xd0, 0xbc, 0x06, 0x59, 0xac,
+ 0x01, 0xd7, 0x32, 0x58, 0x03, 0xfe, 0x9f, 0x80, 0xbc, 0xe8, 0x33, 0x10,
+ 0x87, 0xf1, 0x7f, 0xcb, 0x3c, 0x9b, 0x75, 0x99, 0xbb, 0x73, 0xe6, 0x7c,
+ 0x29, 0xd3, 0xd7, 0x25, 0xa7, 0xf2, 0x5d, 0x92, 0x5c, 0xe5, 0x75, 0x99,
+ 0xac, 0x2c, 0xc9, 0x03, 0xce, 0x38, 0xde, 0xf7, 0x86, 0x37, 0xeb, 0xa8,
+ 0xaf, 0x32, 0x3a, 0x83, 0x67, 0xcf, 0x8e, 0xf4, 0xc9, 0x9f, 0x5d, 0x47,
+ 0x16, 0xd7, 0x6c, 0xc9, 0xdb, 0x69, 0x79, 0x5e, 0x63, 0xf9, 0xf4, 0x4f,
+ 0x42, 0xe0, 0xa4, 0xcc, 0xc9, 0xb7, 0x89, 0xf4, 0x38, 0xb1, 0x6d, 0x21,
+ 0xa7, 0x6c, 0x81, 0xac, 0xe3, 0x86, 0x37, 0xdb, 0xe6, 0xfa, 0xb1, 0x17,
+ 0xc0, 0xdd, 0xdd, 0xb7, 0x7a, 0x83, 0xf8, 0xb0, 0xe1, 0xb7, 0x7f, 0xf0,
+ 0xf3, 0x62, 0x69, 0xa9, 0x30, 0x07, 0xa7, 0x38, 0xeb, 0x40, 0x97, 0x98,
+ 0xc3, 0x8f, 0x69, 0xdc, 0xa1, 0xa5, 0x4c, 0x8c, 0xba, 0x0a, 0x8c, 0x1a,
+ 0x25, 0x76, 0x8d, 0xaf, 0xb9, 0x8c, 0x0b, 0x44, 0xe5, 0xb7, 0x25, 0xe2,
+ 0x70, 0x5c, 0x7e, 0x53, 0x7a, 0x16, 0xf3, 0x49, 0x54, 0x19, 0xcf, 0xbc,
+ 0x5e, 0x29, 0x90, 0x27, 0x29, 0x9f, 0xcf, 0xba, 0x5f, 0x54, 0x3b, 0x10,
+ 0xb7, 0x8a, 0xdd, 0x2d, 0x8a, 0x37, 0x4f, 0x6b, 0x1e, 0x36, 0x6e, 0x0d,
+ 0xc8, 0xf5, 0x55, 0xbe, 0x6f, 0x0a, 0x63, 0x47, 0x43, 0xb9, 0x75, 0xda,
+ 0xa5, 0x64, 0x6c, 0xc6, 0x3a, 0x20, 0x17, 0xa2, 0x8c, 0x53, 0x8f, 0x11,
+ 0x9f, 0x61, 0x0b, 0x87, 0xed, 0x19, 0xd6, 0x38, 0xa9, 0xfd, 0x89, 0x35,
+ 0xe1, 0xec, 0xd3, 0x3e, 0xce, 0xf2, 0xda, 0x18, 0x64, 0x4a, 0x5b, 0x94,
+ 0xa8, 0x4c, 0x58, 0x49, 0xd8, 0x3c, 0xfc, 0xdf, 0xe0, 0xf8, 0x71, 0xf9,
+ 0xc2, 0xc6, 0x45, 0xf0, 0xef, 0x61, 0xfb, 0x1c, 0xed, 0xaa, 0x3d, 0x8a,
+ 0x7b, 0xf9, 0xfc, 0x0f, 0x34, 0x8d, 0xf5, 0x69, 0x7f, 0x2c, 0x5e, 0xc7,
+ 0x3e, 0x2f, 0x3b, 0x32, 0x5b, 0x62, 0x2e, 0xda, 0xcc, 0x75, 0xef, 0xbd,
+ 0x67, 0x77, 0x9e, 0xbb, 0xb0, 0x4c, 0x7e, 0x63, 0xea, 0xdc, 0x8a, 0xe0,
+ 0x42, 0x9f, 0xec, 0xe2, 0x33, 0xf9, 0xbc, 0xc3, 0x92, 0x7d, 0x04, 0xf8,
+ 0x52, 0xe6, 0xaf, 0xe0, 0xd7, 0xde, 0xc2, 0x5f, 0x89, 0xf6, 0xef, 0x63,
+ 0x9b, 0xee, 0xf3, 0xc7, 0xfb, 0x3d, 0x74, 0x28, 0xda, 0x70, 0x3f, 0x63,
+ 0x2a, 0x6c, 0xc7, 0xa5, 0xb0, 0xc1, 0xa3, 0xe7, 0x75, 0x39, 0xad, 0x72,
+ 0xce, 0xbe, 0xbd, 0x69, 0x8c, 0x13, 0x38, 0x67, 0x38, 0x41, 0xb8, 0x1c,
+ 0xf2, 0xb9, 0xc5, 0x9d, 0xe4, 0x4d, 0xfe, 0xff, 0x36, 0x8d, 0xc5, 0xc4,
+ 0xad, 0xfe, 0xa6, 0xf7, 0xb8, 0x73, 0xc7, 0x0e, 0xc7, 0x2d, 0x62, 0xe7,
+ 0x8f, 0x71, 0x8d, 0x3a, 0xe4, 0x29, 0x8f, 0x8f, 0x80, 0xe7, 0xe7, 0x80,
+ 0x05, 0x51, 0xe7, 0xb6, 0x18, 0x8b, 0x4d, 0xae, 0x2d, 0x9b, 0x7a, 0x54,
+ 0x72, 0xe0, 0x6b, 0xfb, 0xe6, 0x6a, 0x53, 0xd0, 0x65, 0x8c, 0x7f, 0x90,
+ 0xe3, 0x8f, 0xf8, 0xeb, 0x9c, 0x70, 0x0b, 0xd6, 0x87, 0x65, 0x66, 0xd5,
+ 0xe8, 0x5f, 0xd6, 0x81, 0xee, 0x1d, 0x46, 0x7b, 0x9d, 0x36, 0xe1, 0xfd,
+ 0xc6, 0x09, 0x6c, 0x43, 0x4a, 0x6d, 0xc3, 0xfc, 0x32, 0xf5, 0x93, 0x7a,
+ 0x19, 0xe8, 0x63, 0x80, 0x79, 0xd4, 0x51, 0xe2, 0x6c, 0x5a, 0x5e, 0x58,
+ 0xe6, 0xda, 0x64, 0x34, 0xa7, 0x35, 0xb4, 0x32, 0xab, 0xf5, 0x3d, 0x83,
+ 0xe5, 0xc4, 0x8b, 0x05, 0x19, 0x97, 0xab, 0x2e, 0xd7, 0x2c, 0x51, 0xcd,
+ 0x87, 0x3b, 0x1a, 0xde, 0xff, 0x9c, 0xbf, 0x66, 0x29, 0xd5, 0xab, 0xc1,
+ 0xf2, 0xe5, 0x1d, 0x79, 0xe7, 0xad, 0xc3, 0x4d, 0xeb, 0x14, 0x70, 0xb8,
+ 0xb8, 0x90, 0x3f, 0x44, 0xba, 0xd8, 0x87, 0xcf, 0x25, 0xe7, 0xe3, 0xb3,
+ 0x68, 0x5b, 0xef, 0x60, 0x3d, 0x83, 0xd0, 0x8f, 0x8b, 0x3c, 0x62, 0xb8,
+ 0x45, 0xde, 0x7a, 0x18, 0xeb, 0x76, 0x50, 0xeb, 0x28, 0xe7, 0xbf, 0xfb,
+ 0x1e, 0xfa, 0xe7, 0x7d, 0x7e, 0x9e, 0xc6, 0x78, 0x7c, 0x77, 0xee, 0xa9,
+ 0xd2, 0x49, 0xea, 0xe6, 0xa4, 0xe6, 0x03, 0xd9, 0x87, 0xfb, 0x96, 0x6b,
+ 0x44, 0x39, 0x5c, 0x8e, 0x19, 0x7b, 0x7a, 0xa2, 0x69, 0x3e, 0x49, 0x7f,
+ 0x3e, 0xc1, 0xf5, 0x16, 0x89, 0xf4, 0xa6, 0xb4, 0x96, 0x24, 0x59, 0xa6,
+ 0x8f, 0x02, 0x5b, 0x35, 0xcd, 0xb1, 0x6e, 0x8d, 0xbd, 0xf9, 0xff, 0x13,
+ 0x7b, 0xf3, 0x56, 0x49, 0xe7, 0xd8, 0xe2, 0xfc, 0x2f, 0x72, 0x6c, 0xac,
+ 0xa7, 0x37, 0x72, 0x7b, 0x6e, 0x99, 0xf6, 0x29, 0xa3, 0xb1, 0xe3, 0x3f,
+ 0x95, 0xb8, 0x96, 0x9c, 0xe3, 0x55, 0xce, 0x71, 0xbc, 0xae, 0xb5, 0x74,
+ 0x0f, 0xe9, 0x9e, 0x5d, 0x5c, 0x26, 0xa6, 0x74, 0xc8, 0x5a, 0x25, 0xc0,
+ 0x95, 0x07, 0x7c, 0x4e, 0x5b, 0xec, 0x6e, 0xc5, 0x3e, 0x39, 0xe3, 0x5a,
+ 0x5a, 0x47, 0x68, 0x3d, 0xcc, 0x73, 0x03, 0x52, 0x5b, 0xa5, 0x9d, 0x4d,
+ 0xc2, 0xaf, 0x88, 0x86, 0x6a, 0xeb, 0xcc, 0x45, 0xb2, 0x4e, 0x64, 0x5c,
+ 0x98, 0xbb, 0xcf, 0xd9, 0xf3, 0xd8, 0x5f, 0x31, 0xf8, 0xfd, 0xe4, 0xf0,
+ 0x8c, 0x8f, 0x35, 0xcb, 0x7b, 0x74, 0x87, 0x03, 0xee, 0x95, 0xf3, 0x2f,
+ 0xb0, 0xde, 0xd4, 0x6b, 0xc7, 0xbe, 0x0e, 0x3b, 0x99, 0x8b, 0xf2, 0xff,
+ 0x0c, 0xb8, 0x3f, 0x7d, 0x8d, 0xb8, 0xfa, 0x1a, 0xb5, 0x6a, 0x46, 0x96,
+ 0x54, 0xf7, 0x3b, 0xfc, 0x58, 0x52, 0x87, 0xea, 0x07, 0x75, 0x2c, 0xaf,
+ 0x9c, 0x7b, 0x54, 0x71, 0xaa, 0x58, 0x1a, 0x36, 0x75, 0x26, 0x76, 0xcc,
+ 0xaf, 0x27, 0x6f, 0x7c, 0x7e, 0xcc, 0x7f, 0xfe, 0x5f, 0x7c, 0xf9, 0xda,
+ 0x8a, 0x31, 0xba, 0xd6, 0x56, 0x52, 0x7d, 0xcb, 0xf9, 0x65, 0xea, 0x07,
+ 0xf5, 0x84, 0x38, 0x17, 0xdc, 0x17, 0xc8, 0x24, 0x68, 0xf3, 0x7e, 0xea,
+ 0x7c, 0x63, 0x4d, 0x41, 0xb0, 0x3f, 0x83, 0x73, 0x81, 0x8c, 0x78, 0xad,
+ 0xd1, 0x0e, 0x70, 0xaf, 0xc5, 0x21, 0xa7, 0xdd, 0xfd, 0xd6, 0x55, 0xde,
+ 0x95, 0x4d, 0xf6, 0x14, 0xe7, 0x7f, 0x99, 0x71, 0x5c, 0xec, 0xb1, 0xfd,
+ 0xe4, 0xf3, 0x65, 0x95, 0x4f, 0x1e, 0xf2, 0xe9, 0x52, 0xdc, 0xa7, 0x8f,
+ 0x77, 0xc9, 0xd7, 0xb9, 0x0e, 0xac, 0x19, 0xe3, 0xb2, 0xc0, 0xb7, 0xf3,
+ 0xc4, 0xf9, 0xbe, 0x3e, 0xe2, 0x0b, 0x63, 0x8a, 0x99, 0xe9, 0x43, 0xc0,
+ 0x30, 0xb6, 0x8f, 0x2b, 0x07, 0x31, 0x3e, 0x56, 0x5c, 0x63, 0x8b, 0x61,
+ 0x60, 0x72, 0xad, 0x04, 0x7e, 0xc6, 0xba, 0xaf, 0x3d, 0xf2, 0x7a, 0xca,
+ 0x5f, 0xaf, 0x89, 0x3e, 0xca, 0x87, 0xfb, 0x80, 0x58, 0xd9, 0x89, 0xf1,
+ 0xce, 0x46, 0x53, 0xd0, 0xb1, 0x71, 0x9c, 0x1f, 0x52, 0x1f, 0x22, 0x8c,
+ 0x7d, 0xbe, 0x5d, 0xea, 0xf5, 0xfd, 0x36, 0x07, 0x6d, 0xf8, 0xaa, 0xa5,
+ 0x2e, 0xfa, 0x11, 0x1a, 0x47, 0x6c, 0x2d, 0xc3, 0x67, 0x05, 0x76, 0xd7,
+ 0xd5, 0x06, 0x8d, 0xe0, 0xfa, 0x6d, 0xac, 0x89, 0xd3, 0xda, 0xe0, 0x6d,
+ 0x95, 0x19, 0x7d, 0xcd, 0x63, 0xba, 0xa6, 0xb5, 0x52, 0x22, 0xf6, 0xb8,
+ 0xf8, 0xe7, 0xa6, 0xf9, 0xdc, 0xc1, 0x86, 0x79, 0x4d, 0xca, 0xd9, 0x1d,
+ 0x1b, 0x41, 0xdf, 0x19, 0xbc, 0xbd, 0x62, 0x6c, 0x40, 0xb1, 0x9a, 0xd2,
+ 0xfa, 0xa5, 0xf0, 0xd8, 0x06, 0xd6, 0x92, 0x3c, 0xf4, 0x06, 0xb8, 0xf7,
+ 0x08, 0xd6, 0x90, 0x5c, 0xdb, 0x9b, 0x5b, 0x70, 0x33, 0xcc, 0x85, 0xc1,
+ 0x86, 0xcd, 0x49, 0x0e, 0xbe, 0x40, 0x2e, 0x7c, 0x98, 0x31, 0x64, 0xf0,
+ 0xc1, 0x82, 0x1f, 0x6f, 0x1c, 0x61, 0x9c, 0x54, 0x56, 0xd6, 0x39, 0x77,
+ 0xee, 0x6f, 0xe3, 0x6f, 0xd7, 0x4a, 0x9c, 0xaf, 0x89, 0x3d, 0xb0, 0x6d,
+ 0x95, 0x5d, 0x1c, 0xb9, 0x16, 0x69, 0x1c, 0xef, 0xc5, 0x9e, 0xe0, 0xbd,
+ 0x38, 0xae, 0xdf, 0x90, 0x5f, 0xad, 0x06, 0xf6, 0x3c, 0x24, 0x6f, 0x3a,
+ 0xde, 0xdc, 0xbc, 0xdb, 0xcd, 0x35, 0x70, 0x0b, 0xcc, 0x65, 0x3b, 0x8e,
+ 0x5b, 0x14, 0xcf, 0xab, 0xbb, 0xf5, 0x6e, 0x4b, 0x65, 0x49, 0x0c, 0xf8,
+ 0x1a, 0xd6, 0xf0, 0x8d, 0xbb, 0x2d, 0x31, 0xf2, 0xa3, 0x6c, 0xae, 0xfd,
+ 0x57, 0xfc, 0x0f, 0x30, 0x90, 0xfa, 0x48, 0xbd, 0xbc, 0x21, 0x53, 0x8a,
+ 0xf9, 0xfb, 0xf5, 0x6b, 0xc4, 0x89, 0x80, 0xd3, 0x12, 0xd3, 0xa9, 0x8b,
+ 0x31, 0xf5, 0x09, 0x8e, 0x95, 0x9b, 0x71, 0xe1, 0x33, 0x7e, 0x0e, 0x61,
+ 0x3f, 0xdd, 0x7b, 0xd4, 0xc7, 0x86, 0x31, 0xe5, 0xcb, 0x19, 0x9b, 0x18,
+ 0xc1, 0xf9, 0x1c, 0x94, 0xd9, 0x2b, 0x8d, 0x38, 0x4c, 0x5f, 0xcf, 0xe0,
+ 0x87, 0x7e, 0xe3, 0xa1, 0xfc, 0xd7, 0x92, 0xc1, 0x15, 0xf2, 0x25, 0x07,
+ 0x58, 0xda, 0x23, 0xf9, 0xe9, 0xb0, 0x24, 0x57, 0x7e, 0xd6, 0x67, 0xf8,
+ 0x2d, 0xf5, 0x0f, 0xfb, 0x4d, 0xcf, 0xb1, 0x5d, 0xc7, 0xf9, 0x23, 0xc2,
+ 0x67, 0x1b, 0x7d, 0xc6, 0x7e, 0x3e, 0x1f, 0x5c, 0xb3, 0x9b, 0x74, 0xf4,
+ 0x5e, 0x5f, 0x47, 0x79, 0xdd, 0x32, 0xb9, 0x0e, 0xdc, 0x3b, 0xb8, 0xc2,
+ 0x39, 0x9a, 0x7e, 0x83, 0x2b, 0xc6, 0x47, 0xdf, 0xdb, 0x6f, 0x64, 0xa7,
+ 0x1f, 0xae, 0x83, 0xef, 0x9a, 0xb1, 0xa7, 0x46, 0xc1, 0xe3, 0x46, 0x58,
+ 0x83, 0x44, 0x9b, 0x3d, 0xe4, 0x4e, 0x09, 0xf5, 0x3d, 0xe1, 0xeb, 0x1c,
+ 0xf1, 0xa6, 0xcb, 0xc7, 0x9b, 0x5d, 0x1b, 0x93, 0x33, 0x35, 0x27, 0x8c,
+ 0x83, 0x34, 0xd8, 0x18, 0xe9, 0xff, 0x4f, 0x1b, 0x73, 0xc4, 0x1f, 0x27,
+ 0xb8, 0x16, 0xe0, 0x4a, 0xd0, 0x0e, 0x70, 0xa5, 0x99, 0xc7, 0x06, 0xb2,
+ 0x6f, 0x3c, 0xdf, 0xe8, 0xe7, 0x65, 0x7c, 0x7f, 0xde, 0xd2, 0xfd, 0xf3,
+ 0xca, 0x8e, 0x1f, 0x4f, 0x19, 0x27, 0xa0, 0x7a, 0x25, 0xec, 0xed, 0xf7,
+ 0xd4, 0x6f, 0x5e, 0xbc, 0x32, 0xa1, 0xb1, 0x9c, 0x9a, 0xca, 0xfa, 0xab,
+ 0x58, 0x9f, 0x33, 0xd8, 0x47, 0x0f, 0x46, 0x77, 0xeb, 0x86, 0x56, 0x9f,
+ 0xc9, 0xfa, 0xbc, 0x25, 0x23, 0x5d, 0x98, 0x5f, 0x5a, 0xeb, 0xb0, 0xda,
+ 0x9d, 0xaf, 0xc8, 0x03, 0x66, 0xee, 0x6d, 0x6d, 0x63, 0xeb, 0xcf, 0xb4,
+ 0x7d, 0x2b, 0xd0, 0x73, 0xea, 0xcf, 0xea, 0x33, 0xb3, 0x15, 0x6f, 0x3c,
+ 0x72, 0x72, 0xd8, 0x2e, 0x0a, 0x6b, 0xbd, 0xc7, 0xe5, 0x09, 0x97, 0xd7,
+ 0x7f, 0x88, 0xeb, 0xd3, 0xf4, 0x21, 0x13, 0x11, 0xfd, 0xfe, 0x20, 0x11,
+ 0x7b, 0x0c, 0x7b, 0x6f, 0x46, 0xbf, 0xf7, 0x38, 0xa4, 0x35, 0xe2, 0x35,
+ 0x21, 0x97, 0x62, 0x8d, 0xc1, 0xb3, 0xf2, 0xb8, 0x3b, 0xe4, 0xd6, 0xc5,
+ 0x70, 0xdc, 0x19, 0xcd, 0xf7, 0x1c, 0x90, 0xc7, 0xdc, 0x48, 0x5b, 0x76,
+ 0xcb, 0xe8, 0xfc, 0x44, 0x38, 0xd3, 0xbe, 0xe0, 0x44, 0xdb, 0xa6, 0xb6,
+ 0xb0, 0xa7, 0xb7, 0x80, 0xf7, 0x5b, 0xb1, 0x50, 0x6e, 0x83, 0xef, 0x1e,
+ 0x36, 0x35, 0x1d, 0xea, 0x5f, 0x11, 0x43, 0xee, 0x93, 0x6d, 0xfb, 0xb8,
+ 0x6c, 0xa7, 0xf8, 0x4d, 0xd6, 0x29, 0xb4, 0x07, 0x35, 0xe7, 0xb2, 0x0d,
+ 0xbc, 0xd9, 0x4e, 0xb5, 0xa9, 0x0e, 0xaa, 0x1f, 0x06, 0x9c, 0xda, 0xb6,
+ 0x89, 0x4f, 0x77, 0xf0, 0x88, 0x77, 0x9e, 0x83, 0x1c, 0x58, 0xef, 0x71,
+ 0x02, 0x6d, 0xe2, 0x9a, 0xdd, 0x74, 0xbe, 0x1f, 0xed, 0xbb, 0x31, 0x46,
+ 0xab, 0xbe, 0xa3, 0xe5, 0x9c, 0x34, 0x79, 0xcc, 0x3d, 0xf7, 0x74, 0x36,
+ 0xb5, 0x3f, 0x77, 0xd4, 0x7c, 0x6f, 0xf4, 0x3d, 0xca, 0xb8, 0x90, 0x91,
+ 0xbf, 0xc5, 0xf6, 0xb6, 0x97, 0xfb, 0xf6, 0xb6, 0x0f, 0x4b, 0x7b, 0x0f,
+ 0x45, 0xd1, 0xdd, 0x74, 0x5f, 0xa0, 0x43, 0x41, 0xfb, 0x28, 0x71, 0x85,
+ 0x76, 0x4b, 0x7d, 0xa6, 0xed, 0x28, 0x9f, 0xb5, 0xd8, 0xd4, 0x87, 0xff,
+ 0xd9, 0x87, 0x7d, 0x19, 0xbf, 0xfb, 0xbe, 0xd1, 0x33, 0x8b, 0xbe, 0x3f,
+ 0xe3, 0x17, 0xd4, 0xd3, 0xfd, 0xfc, 0xa9, 0x84, 0x7e, 0x1f, 0xb4, 0xbf,
+ 0xae, 0x05, 0x38, 0x12, 0xf3, 0x63, 0x0a, 0x26, 0xef, 0x64, 0xe2, 0xbe,
+ 0x94, 0x9d, 0xe6, 0x9d, 0x62, 0xd7, 0x21, 0xe7, 0x0b, 0x90, 0xf3, 0x64,
+ 0x98, 0xbe, 0x1f, 0xf3, 0x4b, 0x8e, 0xe4, 0xb6, 0x28, 0x6f, 0xda, 0x75,
+ 0xea, 0x26, 0x78, 0xc4, 0x16, 0x31, 0xc5, 0x02, 0x07, 0xca, 0x60, 0x8e,
+ 0xaf, 0xe1, 0xbc, 0xe5, 0xd7, 0x6f, 0xa4, 0x61, 0xd3, 0x5c, 0xfc, 0x28,
+ 0x77, 0xf8, 0xf4, 0x6b, 0x94, 0x31, 0xeb, 0xd9, 0x18, 0x0b, 0xe0, 0xfc,
+ 0x98, 0x63, 0x77, 0xa1, 0xd3, 0x13, 0xd0, 0xdd, 0x88, 0x38, 0xe5, 0x13,
+ 0x52, 0x98, 0x9e, 0x50, 0xfb, 0x3f, 0x08, 0xfb, 0x34, 0xef, 0x66, 0x65,
+ 0xe1, 0xe5, 0x3b, 0xb1, 0x4f, 0xe9, 0xe7, 0x6b, 0x0c, 0xc3, 0x6b, 0x51,
+ 0x9d, 0x26, 0xe7, 0x60, 0xdc, 0xcd, 0xe4, 0x92, 0xfd, 0xef, 0xaa, 0xfa,
+ 0xe5, 0x70, 0x56, 0x2a, 0x57, 0x6c, 0xad, 0x85, 0xc9, 0xc8, 0x7b, 0x1e,
+ 0x65, 0x38, 0x73, 0x3e, 0x0e, 0x9c, 0x22, 0x77, 0xff, 0x60, 0xd4, 0xac,
+ 0xe9, 0x5f, 0xfb, 0xe9, 0x03, 0x27, 0xcb, 0x8d, 0x63, 0x68, 0xfd, 0x0c,
+ 0xae, 0x3d, 0x74, 0xd4, 0xec, 0x1f, 0xfa, 0xc3, 0x37, 0xbd, 0x4c, 0x94,
+ 0xcf, 0xe4, 0xbd, 0xcc, 0xd1, 0x52, 0x57, 0x38, 0xb7, 0x77, 0x7d, 0xbd,
+ 0xfe, 0x28, 0xc6, 0x8b, 0xcb, 0xe0, 0xe6, 0x84, 0xfa, 0xf1, 0xf3, 0x7b,
+ 0x7c, 0x56, 0x13, 0x1f, 0x30, 0x7e, 0xeb, 0x1b, 0xf2, 0xd8, 0x06, 0xe5,
+ 0x44, 0xfb, 0x1e, 0x92, 0x1f, 0x39, 0xc3, 0xf6, 0x93, 0x5a, 0x77, 0x9c,
+ 0xc8, 0x30, 0x1f, 0x73, 0xd0, 0x49, 0xda, 0x6b, 0x12, 0x19, 0xfd, 0x98,
+ 0xf0, 0x9b, 0x16, 0xd6, 0x7a, 0x0c, 0xbb, 0x4f, 0x4a, 0x50, 0xef, 0x31,
+ 0x94, 0x39, 0x10, 0xfa, 0xa7, 0xf7, 0xc6, 0x79, 0xde, 0x63, 0xea, 0x3d,
+ 0x24, 0x44, 0xb9, 0xfd, 0xf1, 0x0e, 0x7e, 0xe3, 0xb9, 0x37, 0xde, 0x77,
+ 0xff, 0xd3, 0xe7, 0xd2, 0x89, 0x25, 0xfa, 0xac, 0x2d, 0xce, 0xbf, 0xfa,
+ 0xcd, 0xbb, 0x16, 0x0a, 0x9d, 0xa2, 0xf9, 0xb2, 0x4b, 0xef, 0x38, 0xac,
+ 0x7b, 0x48, 0xc4, 0x0e, 0x58, 0x8c, 0x7b, 0x13, 0xdf, 0x98, 0x43, 0x61,
+ 0x8c, 0x0d, 0x6d, 0x70, 0x86, 0x97, 0x46, 0x2c, 0xb9, 0x3f, 0x92, 0x89,
+ 0x5b, 0x72, 0x2c, 0xbe, 0x22, 0x78, 0x26, 0xf3, 0x29, 0x1b, 0x89, 0x02,
+ 0xef, 0x8f, 0x94, 0x39, 0x5e, 0x5c, 0xfd, 0x93, 0xe4, 0x31, 0xcf, 0xbb,
+ 0xe4, 0x4a, 0x28, 0x79, 0xd7, 0xdb, 0x1e, 0x73, 0xde, 0xd6, 0xe6, 0xfb,
+ 0xd5, 0x23, 0x10, 0x37, 0x16, 0x9e, 0x32, 0xb5, 0x87, 0x4b, 0x97, 0x06,
+ 0x37, 0xf4, 0x9b, 0xb9, 0x69, 0xd3, 0x2e, 0xa1, 0xdd, 0xea, 0xd7, 0x41,
+ 0x55, 0x2e, 0x0d, 0x56, 0x8f, 0xdc, 0x6e, 0xfc, 0x6d, 0xf2, 0xab, 0xc0,
+ 0x87, 0x89, 0xef, 0xa9, 0x0b, 0x3b, 0xbb, 0x7c, 0x26, 0x74, 0x66, 0xd9,
+ 0x5a, 0x6d, 0x63, 0x0e, 0xec, 0x94, 0x27, 0xdd, 0x27, 0x83, 0x38, 0x15,
+ 0xe3, 0x5a, 0x22, 0x9d, 0x9b, 0x13, 0x26, 0xe7, 0xb1, 0x69, 0x29, 0x17,
+ 0xea, 0x7a, 0x89, 0xb1, 0xaa, 0xa8, 0x62, 0x43, 0xf7, 0x26, 0xeb, 0xc1,
+ 0x7a, 0x64, 0x46, 0x31, 0xa3, 0x47, 0xf1, 0xc0, 0xe8, 0x5d, 0x97, 0xc6,
+ 0x61, 0xc9, 0x97, 0xae, 0x2d, 0xbb, 0x03, 0xac, 0xe1, 0x79, 0x75, 0xf9,
+ 0x09, 0xb4, 0x89, 0x33, 0xf7, 0x34, 0x9d, 0x6f, 0xcc, 0xc9, 0x26, 0xec,
+ 0x41, 0xab, 0x39, 0x1f, 0xcb, 0x73, 0xcd, 0x79, 0xd8, 0x57, 0x25, 0xdf,
+ 0xcb, 0xdc, 0x6b, 0x10, 0x6f, 0x77, 0xfd, 0x78, 0xfb, 0x87, 0x06, 0xa8,
+ 0x83, 0xf0, 0x6f, 0xf2, 0x91, 0xb1, 0xb6, 0x91, 0xf9, 0x52, 0xf8, 0x1f,
+ 0xbb, 0xb1, 0x53, 0xb4, 0x37, 0x76, 0xf2, 0xe3, 0xb8, 0xf6, 0x25, 0x70,
+ 0x92, 0x22, 0xf8, 0x45, 0xc1, 0xaf, 0xc3, 0xe7, 0xf5, 0x9d, 0xfe, 0xb7,
+ 0x98, 0xd3, 0x41, 0xcd, 0xad, 0x0f, 0xee, 0xc9, 0xad, 0xdf, 0x35, 0xc0,
+ 0xda, 0xe3, 0xe2, 0xd6, 0x6e, 0xdf, 0x88, 0xdf, 0x77, 0xe2, 0x96, 0xef,
+ 0x63, 0xf6, 0x4c, 0x51, 0xf7, 0xcc, 0x65, 0x8d, 0x11, 0xcf, 0x6f, 0x2d,
+ 0xc9, 0x8c, 0xd3, 0x25, 0xb9, 0xd5, 0xc0, 0x4e, 0x78, 0xe3, 0xb3, 0x6e,
+ 0xa1, 0x2f, 0x2c, 0xec, 0xcf, 0xe7, 0x29, 0x47, 0x8b, 0xe5, 0xc2, 0x1c,
+ 0xff, 0x90, 0x44, 0xc6, 0x68, 0x3b, 0x68, 0x13, 0x3e, 0x05, 0x2c, 0x03,
+ 0x4f, 0xdf, 0x6a, 0xcc, 0x7d, 0xbf, 0x9f, 0x1c, 0x29, 0xc3, 0xe0, 0x9d,
+ 0x0b, 0x5e, 0x2b, 0xf6, 0xdf, 0x31, 0xd6, 0xb4, 0xec, 0xcc, 0x95, 0x36,
+ 0x4b, 0x6d, 0x93, 0xbe, 0xc7, 0x94, 0xff, 0x1e, 0x61, 0xcc, 0x67, 0xb6,
+ 0x14, 0xdc, 0x33, 0x27, 0xc7, 0x4f, 0x25, 0x62, 0x49, 0x4b, 0xe7, 0xa5,
+ 0xf6, 0x2b, 0xeb, 0xce, 0xc1, 0x2e, 0xd1, 0x86, 0x29, 0xae, 0x81, 0xab,
+ 0x12, 0xd7, 0x68, 0x9f, 0xd4, 0xa6, 0xc5, 0x8b, 0x98, 0x67, 0x6e, 0x4b,
+ 0xf3, 0x0f, 0xb1, 0xd3, 0xe1, 0x44, 0x65, 0x46, 0xb1, 0x0e, 0x7c, 0x55,
+ 0xe7, 0x0e, 0x7b, 0x1c, 0x6a, 0xcc, 0x2d, 0xd1, 0xbf, 0x64, 0x1e, 0xa6,
+ 0x43, 0xb2, 0x15, 0x91, 0x57, 0xa0, 0xdf, 0x57, 0xd7, 0xb9, 0xe7, 0xc2,
+ 0xbd, 0xc6, 0x47, 0xac, 0xdf, 0x63, 0x49, 0xaf, 0xe6, 0x6b, 0x8b, 0x58,
+ 0x2f, 0xf0, 0xab, 0xf1, 0xf0, 0x29, 0xf8, 0x09, 0x5a, 0x27, 0xc1, 0x18,
+ 0xeb, 0x2c, 0x7c, 0xca, 0xc6, 0xb8, 0x10, 0x30, 0x62, 0x9a, 0xe7, 0x67,
+ 0xc0, 0x8b, 0x77, 0x73, 0x35, 0xc5, 0xea, 0x82, 0xc6, 0x63, 0x6b, 0xeb,
+ 0x1d, 0x6a, 0x2f, 0x6a, 0xd5, 0x3e, 0xac, 0x8b, 0x1c, 0xb7, 0xc6, 0x8a,
+ 0xfe, 0xf9, 0x16, 0xa9, 0x56, 0xd9, 0x96, 0x81, 0x56, 0xd5, 0x97, 0x20,
+ 0x1f, 0x65, 0xcb, 0x1a, 0xb8, 0x6e, 0x75, 0xc3, 0xc1, 0x2f, 0x85, 0xdf,
+ 0x08, 0x7e, 0x0f, 0x4a, 0xb6, 0x4c, 0xfe, 0xcd, 0xfc, 0x53, 0x47, 0xd3,
+ 0xf3, 0x5b, 0xf4, 0xfb, 0x11, 0xd6, 0xb4, 0x15, 0x7d, 0x3f, 0xad, 0x58,
+ 0xdd, 0x8f, 0x9b, 0x32, 0xbe, 0x9b, 0xf2, 0xb1, 0xee, 0xa7, 0x7e, 0x6d,
+ 0xed, 0xbf, 0x01, 0x17, 0x24, 0x5e, 0x9d, 0xe0, 0x70, 0x00, 0x00, 0x00 };
static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
- 0x0800458c, 0x0800458c, 0x08004504, 0x0800453c, 0x08004570, 0x08004594,
- 0x08004594, 0x08004594, 0x08004474, 0x00000000 };
+ 0x08004c28, 0x08004c28, 0x08004ba0, 0x08004bd8, 0x08004c0c, 0x08004c30,
+ 0x08004c30, 0x08004c30, 0x08004b10, 0x00000000 };
static struct fw_info bnx2_rxp_fw_06 = {
- /* Firmware version: 4.4.2 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x2,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
- .start_addr = 0x080031d0,
+ .start_addr = 0x080031d8,
.text_addr = 0x08000000,
- .text_len = 0x71cc,
+ .text_len = 0x70dc,
.text_index = 0x0,
.gz_text = bnx2_RXP_b06FwText,
.gz_text_len = sizeof(bnx2_RXP_b06FwText),
@@ -2966,15 +2935,15 @@ static struct fw_info bnx2_rxp_fw_06 = {
.data_index = 0x0,
.data = bnx2_RXP_b06FwData,
- .sbss_addr = 0x08007220,
- .sbss_len = 0x58,
+ .sbss_addr = 0x08007120,
+ .sbss_len = 0x54,
.sbss_index = 0x0,
- .bss_addr = 0x08007278,
- .bss_len = 0x44c,
+ .bss_addr = 0x08007178,
+ .bss_len = 0x450,
.bss_index = 0x0,
- .rodata_addr = 0x080071cc,
+ .rodata_addr = 0x080070dc,
.rodata_len = 0x24,
.rodata_index = 0x0,
.rodata = bnx2_RXP_b06FwRodata,
@@ -2997,639 +2966,571 @@ static const struct cpu_reg cpu_reg_rxp = {
};
static u8 bnx2_rv2p_proc1[] = {
- /* Date: 05/13/2008 13:50 */
- 0xa5, 0x56, 0x4f, 0x48, 0x14, 0x61, 0x14, 0x7f, 0x3b, 0xfb, 0x67, 0xd6,
- 0xdd, 0xd9, 0x9d, 0x25, 0xff, 0x6d, 0x66, 0xb8, 0x49, 0x97, 0xd5, 0x15,
- 0xb5, 0x22, 0x3a, 0x18, 0x86, 0x17, 0x21, 0x3b, 0x84, 0x20, 0x45, 0x04,
- 0xd9, 0x12, 0xde, 0x82, 0x0e, 0xd1, 0x29, 0x68, 0xd1, 0x34, 0x8a, 0x0a,
- 0x16, 0x52, 0x30, 0xa2, 0xa4, 0x43, 0x85, 0x04, 0xed, 0x74, 0x0a, 0x12,
- 0x82, 0x8a, 0x88, 0xea, 0x12, 0x78, 0xa8, 0x4b, 0x16, 0x61, 0xd0, 0xa1,
- 0x83, 0x9d, 0xba, 0xe4, 0xf4, 0xbd, 0xef, 0xbd, 0xcf, 0x9d, 0xf9, 0x9c,
- 0x55, 0x21, 0x41, 0x7f, 0xbc, 0x6f, 0xde, 0x7b, 0xdf, 0x9b, 0xdf, 0x7b,
- 0xef, 0x37, 0x66, 0x00, 0xc0, 0x80, 0x92, 0xd3, 0x26, 0x10, 0x52, 0x46,
- 0x28, 0x2e, 0x20, 0x04, 0xf0, 0x18, 0xe8, 0x27, 0x6a, 0x49, 0xbb, 0xd4,
- 0xcd, 0x76, 0x27, 0x41, 0xa9, 0x33, 0x23, 0xfe, 0x9e, 0x85, 0xfe, 0x1c,
- 0x62, 0x18, 0xfa, 0x77, 0x21, 0x1e, 0x84, 0x17, 0xb9, 0xac, 0xc0, 0xbf,
- 0x2e, 0x94, 0xd0, 0x6e, 0xa8, 0x3c, 0x73, 0x92, 0x32, 0xff, 0x12, 0xc7,
- 0x7f, 0x0a, 0x13, 0x1e, 0x28, 0xc4, 0x29, 0x0f, 0x23, 0x74, 0x65, 0x24,
- 0x2c, 0x96, 0xd1, 0x1e, 0x19, 0x81, 0x18, 0xe6, 0x99, 0x12, 0x0e, 0x68,
- 0xb7, 0x86, 0x4a, 0x5d, 0x5c, 0x97, 0x41, 0x7e, 0x5f, 0xca, 0x36, 0x9e,
- 0xc3, 0xd7, 0x01, 0xb4, 0xb7, 0x27, 0x2e, 0x97, 0x11, 0xb3, 0x30, 0x16,
- 0xb7, 0xe8, 0x7d, 0xda, 0x28, 0xed, 0x52, 0x07, 0xc6, 0x09, 0xdf, 0x0e,
- 0xce, 0x1b, 0xc5, 0xbc, 0x3f, 0x5d, 0xca, 0x8b, 0xf9, 0xbc, 0x79, 0x5a,
- 0x45, 0x1e, 0x3c, 0x8f, 0x71, 0x5d, 0x31, 0xad, 0xae, 0x98, 0xa8, 0x83,
- 0x79, 0x00, 0x55, 0x07, 0x62, 0xa3, 0xb8, 0x17, 0xf3, 0xae, 0xf0, 0x7b,
- 0x03, 0x9c, 0xca, 0x71, 0x7e, 0x07, 0xb1, 0xc2, 0xf9, 0xc4, 0x2f, 0xbf,
- 0xc7, 0xfa, 0x3c, 0x8a, 0x27, 0x7f, 0xfd, 0x66, 0x41, 0x3d, 0x57, 0xfd,
- 0xc0, 0x7b, 0x3e, 0x8a, 0x7b, 0xbc, 0xfe, 0xb0, 0x89, 0xff, 0x7b, 0xe1,
- 0xef, 0xcf, 0x4b, 0xe7, 0x6f, 0xab, 0xe7, 0xf9, 0x20, 0xde, 0xa2, 0x1a,
- 0x6f, 0x2f, 0x99, 0xb7, 0x41, 0xd8, 0x6d, 0x64, 0xa5, 0x5f, 0x04, 0x10,
- 0x77, 0x88, 0x02, 0x10, 0x77, 0x32, 0x1e, 0x63, 0xbc, 0xc9, 0x78, 0x83,
- 0xb1, 0x91, 0xb1, 0x81, 0xb1, 0x9e, 0x71, 0x1b, 0xe3, 0x3b, 0xc6, 0x0c,
- 0xa3, 0xcd, 0x98, 0x66, 0x7c, 0xc3, 0x68, 0x31, 0x26, 0xb5, 0x7c, 0x2d,
- 0x8c, 0x71, 0xc6, 0xbb, 0x8c, 0xfb, 0xb5, 0xf8, 0xdf, 0x8c, 0x0b, 0x8c,
- 0xcd, 0x21, 0xc2, 0x43, 0x6c, 0x23, 0xa1, 0x3c, 0xf7, 0x3e, 0xbe, 0xee,
- 0xaf, 0xf5, 0x77, 0xb1, 0xcc, 0xcf, 0xf3, 0xca, 0x2f, 0x2e, 0xf9, 0x83,
- 0x0e, 0xaf, 0xff, 0x9d, 0x0d, 0xfc, 0xc9, 0x6d, 0x20, 0x1f, 0x14, 0x37,
- 0xed, 0x52, 0x1d, 0xb7, 0x38, 0xbe, 0xbe, 0xb2, 0x50, 0x63, 0x8f, 0xfa,
- 0x0a, 0xfa, 0x7c, 0x05, 0xed, 0xd1, 0x4e, 0xde, 0xa3, 0xa3, 0xeb, 0xe6,
- 0x97, 0xe6, 0xd4, 0xbb, 0x87, 0x32, 0x4f, 0x8d, 0x39, 0x7f, 0x1a, 0x2a,
- 0x16, 0xb2, 0x34, 0x17, 0xa5, 0x8d, 0xee, 0xc5, 0x78, 0x9e, 0xcb, 0xbc,
- 0x9a, 0x4f, 0xff, 0x5c, 0xd2, 0x7c, 0xc5, 0xb4, 0xf9, 0xba, 0xb0, 0x09,
- 0xbf, 0x49, 0x8d, 0xa7, 0x73, 0xae, 0xea, 0x97, 0xc1, 0xc7, 0xe3, 0xb1,
- 0x8c, 0xcc, 0x7b, 0xcd, 0x91, 0x66, 0x83, 0x35, 0x85, 0x76, 0x04, 0xae,
- 0x3b, 0x2a, 0x8e, 0xf7, 0xb2, 0x43, 0xdd, 0x43, 0xf1, 0x29, 0x20, 0x9e,
- 0xe7, 0x34, 0x9e, 0x73, 0x5b, 0xd2, 0xa9, 0x15, 0xb7, 0xaa, 0x53, 0xf4,
- 0xbc, 0x0d, 0xbc, 0x3a, 0x15, 0x87, 0xd1, 0x41, 0x5b, 0xde, 0x9b, 0x8e,
- 0x51, 0x9a, 0xe3, 0x36, 0xe1, 0x99, 0x04, 0xe1, 0x72, 0xa2, 0x4e, 0xfc,
- 0x75, 0xdd, 0xb1, 0x24, 0xd9, 0xa7, 0x53, 0x6a, 0x3f, 0x54, 0xbc, 0xaa,
- 0x6b, 0xa3, 0x7a, 0xf0, 0x7e, 0x75, 0x8f, 0xaa, 0x43, 0xdd, 0xe7, 0xe7,
- 0xbf, 0xf6, 0xbd, 0x84, 0x45, 0xc3, 0xcf, 0xc3, 0xed, 0x1e, 0xc2, 0x48,
- 0xaf, 0x84, 0xec, 0x8c, 0x45, 0x71, 0xb3, 0x56, 0x04, 0xed, 0x7d, 0xb3,
- 0x1f, 0x30, 0xbf, 0xb1, 0x67, 0xc6, 0xe1, 0xfa, 0x6c, 0xd5, 0x3f, 0x79,
- 0x0e, 0xed, 0x40, 0xf6, 0x30, 0xcf, 0xc3, 0xb0, 0x9c, 0x7b, 0xb1, 0xd7,
- 0x06, 0x62, 0x0b, 0x94, 0xa4, 0xae, 0x1b, 0x89, 0xd7, 0x32, 0x3e, 0xcc,
- 0xe7, 0xa2, 0x4f, 0xed, 0xfe, 0x7d, 0x59, 0xa2, 0xfe, 0xc7, 0xfd, 0x73,
- 0xd3, 0xed, 0x06, 0xcf, 0x63, 0xa2, 0x32, 0x57, 0x0e, 0xea, 0xd7, 0x73,
- 0xd6, 0xbd, 0x2c, 0x14, 0x7b, 0x6b, 0xe9, 0xb1, 0xfa, 0x0e, 0x2a, 0x3d,
- 0x92, 0xc7, 0x95, 0x52, 0xd8, 0xc7, 0xcb, 0x21, 0x28, 0x04, 0xe5, 0x7f,
- 0xa2, 0xbe, 0x2f, 0x01, 0x7b, 0xb4, 0xd9, 0xbd, 0xbe, 0xfc, 0x69, 0x28,
- 0x04, 0xed, 0x81, 0xa9, 0xed, 0x8d, 0xcd, 0x7b, 0xd3, 0xbc, 0x6e, 0x7e,
- 0x95, 0x4e, 0xe4, 0x36, 0xd4, 0x89, 0xff, 0xd5, 0x05, 0x03, 0x48, 0x17,
- 0x50, 0x8f, 0xfd, 0xf7, 0x9b, 0xaa, 0x7e, 0x6d, 0xff, 0xa9, 0xee, 0x3f,
- 0xab, 0x5b, 0xd3, 0x11, 0xef, 0xfb, 0x07, 0xe9, 0x48, 0x42, 0xd3, 0x85,
- 0x5f, 0xab, 0x55, 0x1d, 0xc1, 0xe7, 0xf3, 0xf3, 0xd4, 0x97, 0x8b, 0xee,
- 0x9a, 0xae, 0xfb, 0xf8, 0xac, 0x63, 0x3e, 0x85, 0x9f, 0x8c, 0x5f, 0xd6,
- 0xe2, 0x55, 0x5f, 0xcf, 0x33, 0xcf, 0x46, 0x1f, 0xcd, 0x95, 0x59, 0xfc,
- 0xa1, 0xf1, 0xdd, 0x5b, 0xc0, 0xbd, 0xb8, 0x04, 0x0e, 0xf3, 0xf6, 0xd9,
- 0xc7, 0x5f, 0x8a, 0xf5, 0xc1, 0x84, 0x47, 0x8e, 0xe2, 0x59, 0xf5, 0x87,
- 0xf0, 0xa1, 0xf4, 0xcf, 0x6c, 0xc2, 0x77, 0x06, 0x1e, 0x38, 0x6a, 0xbf,
- 0x6d, 0x99, 0xaf, 0x87, 0xf5, 0x64, 0x94, 0xf7, 0xfa, 0x5b, 0x82, 0x74,
- 0xa3, 0x38, 0x24, 0xf7, 0x14, 0x9a, 0x78, 0xbf, 0x8b, 0x29, 0xb2, 0x5b,
- 0x52, 0xf4, 0x7f, 0x5b, 0x8f, 0x69, 0x49, 0xbf, 0x96, 0x14, 0x61, 0x53,
- 0x12, 0xe3, 0xb2, 0xf0, 0xfd, 0x88, 0x74, 0x2f, 0x54, 0xf7, 0x5b, 0xdf,
- 0x6b, 0x7e, 0xdf, 0xbd, 0x78, 0xde, 0x24, 0xf6, 0xd4, 0xdb, 0x0f, 0x6b,
- 0x4d, 0x5f, 0xef, 0x71, 0xf5, 0x39, 0xdb, 0xcb, 0xb7, 0x9a, 0xdb, 0x67,
- 0x35, 0xfa, 0x34, 0xe8, 0x2a, 0xdd, 0x6b, 0x1f, 0xc4, 0x7a, 0x6d, 0x48,
- 0x9b, 0x34, 0x1f, 0x84, 0x22, 0x8f, 0x61, 0x62, 0x58, 0xeb, 0x24, 0xeb,
- 0xc4, 0xe4, 0xb8, 0x4c, 0x73, 0x64, 0x52, 0x9d, 0x0f, 0xc8, 0xc1, 0x1f,
- 0x9e, 0x7f, 0x25, 0xcf, 0xd3, 0x4e, 0x98, 0xce, 0xcd, 0x21, 0xc5, 0x97,
- 0x2d, 0xdf, 0x7f, 0x86, 0xf8, 0x3a, 0x39, 0x4d, 0x78, 0x02, 0x0e, 0x4b,
- 0x4c, 0x54, 0xf5, 0x2d, 0x2e, 0x11, 0x52, 0x5e, 0x7d, 0x8b, 0x8a, 0xf2,
- 0xd0, 0xae, 0xf3, 0xf4, 0x51, 0xff, 0x6e, 0x6c, 0xb5, 0x9f, 0x5e, 0x9d,
- 0xc4, 0x7e, 0xea, 0x7a, 0x27, 0xe7, 0x46, 0x9b, 0xcf, 0x72, 0x8d, 0xf9,
- 0xcc, 0xd5, 0x98, 0x6f, 0x5d, 0x2f, 0xae, 0xf2, 0xde, 0x45, 0x20, 0x1a,
- 0x96, 0x1f, 0x24, 0x2b, 0x32, 0x21, 0xfb, 0x6b, 0x4c, 0xd2, 0x87, 0xd4,
- 0x8a, 0x4e, 0x85, 0x24, 0x6f, 0xd6, 0x14, 0xf9, 0x45, 0xe8, 0x3c, 0xab,
- 0xf0, 0xca, 0x84, 0xfa, 0xee, 0xfe, 0x03, 0x65, 0x6c, 0x9a, 0x59, 0x40,
- 0x0c, 0x00, 0x00, 0x00 };
+ /* Date: 02/03/2009 14:20 */
+ 0xa5, 0x56, 0x4f, 0x68, 0x14, 0x67, 0x14, 0x7f, 0x33, 0xbb, 0xb3, 0xb3,
+ 0x99, 0x9d, 0xd9, 0xdd, 0x92, 0x18, 0x96, 0x18, 0xcc, 0x1a, 0x84, 0x92,
+ 0x75, 0xb7, 0x6e, 0x6c, 0x0f, 0x42, 0x03, 0x29, 0xb9, 0x08, 0x35, 0x87,
+ 0x12, 0x11, 0x8a, 0x2d, 0x68, 0xb7, 0x22, 0x14, 0x0a, 0xa5, 0x07, 0x8f,
+ 0xa5, 0x83, 0x71, 0x53, 0x5a, 0xbc, 0xe4, 0xd0, 0x80, 0x42, 0x35, 0x27,
+ 0x5b, 0x62, 0x0e, 0x3b, 0xe0, 0xa1, 0x88, 0xe0, 0x41, 0x8f, 0x7a, 0xaa,
+ 0x7f, 0x5a, 0x28, 0x46, 0x29, 0xb5, 0x87, 0x82, 0xc7, 0xde, 0x9a, 0xe9,
+ 0xf7, 0xfe, 0x7c, 0xbb, 0x33, 0x5f, 0x66, 0x13, 0xa1, 0x42, 0xfc, 0xf1,
+ 0xbd, 0x79, 0xef, 0xfb, 0xde, 0x9f, 0xdf, 0x7b, 0x6f, 0xab, 0x00, 0x60,
+ 0x43, 0x18, 0x4d, 0x29, 0x04, 0x2b, 0x67, 0x15, 0x11, 0x00, 0x36, 0x81,
+ 0xff, 0x39, 0x3e, 0x9d, 0xc3, 0x23, 0x72, 0x3e, 0xcc, 0x10, 0x1e, 0xae,
+ 0xaa, 0xff, 0x3f, 0x85, 0xf9, 0x3a, 0x62, 0x0e, 0xe6, 0x0f, 0x22, 0x1e,
+ 0x85, 0xbb, 0xf5, 0x9a, 0xc2, 0x7f, 0x63, 0x08, 0xf1, 0x1c, 0xf4, 0x7e,
+ 0x8e, 0x4a, 0x74, 0xff, 0x96, 0xd8, 0xff, 0x9a, 0x63, 0x3c, 0xd6, 0xac,
+ 0x12, 0x3e, 0x5a, 0xc5, 0xf7, 0x4e, 0x9d, 0x82, 0x02, 0xda, 0x5d, 0x50,
+ 0x17, 0x23, 0x96, 0xd4, 0x83, 0x45, 0xb2, 0x03, 0xbb, 0xa2, 0x70, 0x12,
+ 0x9e, 0x2f, 0xa0, 0xfe, 0x1b, 0xde, 0xa5, 0x55, 0xc4, 0x12, 0x74, 0x9a,
+ 0xa8, 0x77, 0x00, 0xb2, 0xf5, 0x6a, 0x4a, 0x0f, 0xe5, 0x11, 0x84, 0x4d,
+ 0xc4, 0x11, 0x80, 0x56, 0xf2, 0x3d, 0xd7, 0x0a, 0x5b, 0x68, 0xff, 0x85,
+ 0xbc, 0xb7, 0x4f, 0xee, 0x51, 0x71, 0x47, 0x88, 0x3d, 0xb1, 0x53, 0x7f,
+ 0x2d, 0x96, 0xb3, 0xfe, 0x67, 0x4a, 0x4f, 0xc7, 0xe3, 0x73, 0xde, 0xa6,
+ 0x38, 0x1e, 0x57, 0xe2, 0x79, 0xb6, 0xaa, 0xf3, 0x86, 0xfa, 0xbf, 0xc7,
+ 0x69, 0x7d, 0xd8, 0x43, 0xff, 0x89, 0xd2, 0x4f, 0xdf, 0xcb, 0xf2, 0x5f,
+ 0x06, 0xf2, 0x99, 0xf4, 0xf7, 0xad, 0x06, 0xfa, 0xe7, 0x00, 0x34, 0x24,
+ 0x8f, 0xa4, 0xff, 0x30, 0xe6, 0x78, 0xe6, 0xe0, 0x90, 0x5d, 0x23, 0xbd,
+ 0x3c, 0xd4, 0x28, 0x3f, 0x1c, 0xef, 0x01, 0xc1, 0x25, 0xc1, 0x6b, 0x82,
+ 0x3f, 0x08, 0xc2, 0xff, 0xc4, 0xad, 0x21, 0xf2, 0x7d, 0x82, 0xfb, 0x0d,
+ 0xf9, 0x2d, 0xc1, 0xb7, 0x0c, 0x7b, 0xcf, 0x62, 0x7c, 0xac, 0xbf, 0xcb,
+ 0xf9, 0x5d, 0xc3, 0xfe, 0x4b, 0xe0, 0xfc, 0x58, 0x46, 0xde, 0x36, 0x85,
+ 0x87, 0x58, 0x77, 0xf9, 0x3e, 0xa3, 0xf5, 0x84, 0x37, 0x8d, 0xa4, 0xfe,
+ 0x8d, 0x5d, 0xf4, 0x59, 0x6d, 0x61, 0x26, 0xcb, 0xee, 0x7a, 0x2c, 0x79,
+ 0x14, 0x7b, 0xaf, 0x77, 0x67, 0x08, 0xef, 0xe7, 0x32, 0x79, 0x3f, 0x2e,
+ 0x71, 0xa8, 0xa6, 0x23, 0xfb, 0xdb, 0x16, 0xf3, 0xdb, 0x11, 0x5e, 0xee,
+ 0xc6, 0x63, 0xe1, 0xd5, 0x8c, 0xe6, 0x57, 0x9a, 0x57, 0xcc, 0x8f, 0x82,
+ 0xc1, 0x8f, 0x6f, 0xf7, 0xc8, 0x4b, 0xc9, 0x88, 0x6f, 0x39, 0xd6, 0xf9,
+ 0xb6, 0x45, 0x7c, 0xb1, 0x50, 0xa5, 0x7b, 0xbf, 0x8b, 0xe8, 0x38, 0xe6,
+ 0xaf, 0xe0, 0x39, 0x0f, 0x97, 0x23, 0x6d, 0x27, 0xfd, 0xd4, 0xd0, 0xef,
+ 0xb0, 0x7d, 0x20, 0x9f, 0x6d, 0x47, 0xfb, 0xc9, 0x72, 0x0f, 0xf0, 0x3c,
+ 0xda, 0x5b, 0x37, 0xf2, 0x56, 0xa7, 0xb8, 0x41, 0xe2, 0x07, 0x23, 0x7e,
+ 0x9d, 0xbf, 0x57, 0xc2, 0xf7, 0x49, 0x95, 0x0f, 0xfe, 0x3e, 0x05, 0xfa,
+ 0x7e, 0x9c, 0x0b, 0x45, 0x38, 0x7b, 0xbc, 0x42, 0xfe, 0x94, 0x0b, 0x7c,
+ 0xcd, 0x87, 0x15, 0xc6, 0x73, 0x1e, 0xe3, 0x9f, 0x9e, 0xca, 0x2d, 0xc4,
+ 0xf1, 0xf9, 0x12, 0x9f, 0x3f, 0x09, 0xf0, 0xde, 0x51, 0xf5, 0xb0, 0xb6,
+ 0xd7, 0x7e, 0xed, 0xe6, 0x0f, 0xbe, 0xaf, 0xdf, 0xd1, 0x7e, 0xe8, 0xf7,
+ 0xd2, 0x75, 0x19, 0xfe, 0x2e, 0x63, 0xc7, 0x4e, 0xe7, 0x21, 0x3f, 0xcb,
+ 0x78, 0xb5, 0x4d, 0x50, 0x5b, 0xf3, 0xd9, 0xee, 0x8a, 0x9f, 0xc7, 0xf3,
+ 0x3b, 0x57, 0x1e, 0xe0, 0xfd, 0xf6, 0xd1, 0xb5, 0x48, 0xfc, 0xab, 0xe8,
+ 0xba, 0x92, 0x1c, 0xa6, 0x81, 0xcf, 0x4b, 0xc2, 0x93, 0x25, 0xe2, 0x71,
+ 0x59, 0x7d, 0x42, 0x9c, 0x80, 0xd0, 0x26, 0x3d, 0xef, 0x3e, 0xd9, 0xe7,
+ 0x44, 0xae, 0xea, 0x37, 0x9d, 0xe6, 0xff, 0x16, 0xf3, 0xa2, 0x98, 0xe6,
+ 0xd3, 0x7c, 0x62, 0xce, 0x25, 0xf3, 0x61, 0xf5, 0x79, 0xb4, 0xb3, 0x8e,
+ 0xe9, 0x7a, 0x3d, 0x5a, 0xd5, 0xf9, 0x61, 0xbe, 0xb2, 0x9e, 0x2a, 0x56,
+ 0x8b, 0xd5, 0xc3, 0xb6, 0x24, 0x72, 0x56, 0xbe, 0xb7, 0x4c, 0xde, 0x66,
+ 0xf1, 0xbe, 0x6a, 0xf0, 0xb8, 0x21, 0xbc, 0x1f, 0xe9, 0xad, 0xbf, 0xd6,
+ 0x7e, 0xb8, 0x29, 0xbc, 0xaf, 0x0e, 0xf6, 0xc3, 0x26, 0xed, 0x27, 0x75,
+ 0x26, 0xf5, 0x5e, 0x98, 0x4b, 0xd5, 0xe9, 0x3d, 0xc8, 0xec, 0xef, 0xab,
+ 0x72, 0x4f, 0x5b, 0xfa, 0xbc, 0x90, 0xd8, 0x23, 0xa4, 0x5e, 0x06, 0xf2,
+ 0xc3, 0x35, 0xfa, 0x74, 0x2c, 0x96, 0x77, 0x54, 0xbf, 0x65, 0xc5, 0xeb,
+ 0xc2, 0x5f, 0xc2, 0x83, 0x0e, 0xf5, 0x93, 0x33, 0xf6, 0xf9, 0xed, 0x54,
+ 0x9d, 0x00, 0x0e, 0xea, 0xfd, 0x90, 0xf4, 0x2b, 0xb9, 0xdf, 0xf0, 0xbe,
+ 0x1a, 0x74, 0x66, 0x93, 0x7b, 0xee, 0x72, 0xbf, 0xdf, 0x03, 0xea, 0xa3,
+ 0xf2, 0x8e, 0xbe, 0xd4, 0xf3, 0xac, 0xde, 0x4c, 0xf6, 0xf7, 0x98, 0xcc,
+ 0x2f, 0x5b, 0xf6, 0x73, 0xc9, 0x8c, 0x53, 0xed, 0xbd, 0xec, 0x7a, 0x71,
+ 0xbc, 0xff, 0x6c, 0xbf, 0xde, 0xbc, 0xdb, 0xab, 0xee, 0x9e, 0x51, 0xf7,
+ 0xbf, 0xb7, 0x75, 0x1e, 0x6d, 0x27, 0x6b, 0xbf, 0x7f, 0xa0, 0xee, 0x15,
+ 0x7d, 0x99, 0x1b, 0x67, 0xea, 0x59, 0x7c, 0x2d, 0xee, 0xd0, 0x4b, 0xcf,
+ 0x2f, 0xed, 0xe7, 0xc6, 0x06, 0xd7, 0xfd, 0xa3, 0xb8, 0xbf, 0x97, 0x52,
+ 0xf3, 0x75, 0x44, 0xea, 0xac, 0xf4, 0xc8, 0xbf, 0xa7, 0xdb, 0x83, 0x79,
+ 0x9c, 0xe4, 0xcd, 0x49, 0xe1, 0xab, 0x3d, 0xb7, 0x4e, 0xfd, 0xe1, 0x76,
+ 0x5e, 0x1a, 0x75, 0x98, 0x6d, 0x62, 0xfd, 0xbf, 0x86, 0x48, 0xfc, 0xfc,
+ 0x2d, 0xe5, 0x6f, 0x20, 0xfd, 0x55, 0x80, 0x9f, 0x22, 0x1d, 0x97, 0xae,
+ 0x1b, 0xe3, 0x8f, 0x4d, 0xe9, 0x93, 0x7e, 0x7c, 0xf8, 0xee, 0xa2, 0xbc,
+ 0x5b, 0x85, 0x1b, 0x91, 0x9e, 0x63, 0x38, 0xd7, 0x5c, 0x68, 0xcb, 0xdc,
+ 0x3c, 0x2b, 0xf3, 0xeb, 0x85, 0xc7, 0xf3, 0xb1, 0x73, 0x82, 0x78, 0x08,
+ 0xe3, 0x32, 0xc7, 0x3a, 0x01, 0x9f, 0x27, 0x02, 0xfe, 0x7d, 0xd8, 0x76,
+ 0x7d, 0xd2, 0x9b, 0x08, 0x18, 0xc7, 0x4b, 0x68, 0x57, 0x83, 0x3f, 0x16,
+ 0x49, 0xbd, 0x39, 0x98, 0x63, 0xe6, 0xfc, 0x92, 0x38, 0xdf, 0x46, 0xb9,
+ 0xda, 0x93, 0xd3, 0x7c, 0xe6, 0x3a, 0xfb, 0x7d, 0x5e, 0x5f, 0x97, 0xaa,
+ 0xd4, 0x2b, 0xc9, 0x3c, 0xeb, 0x3e, 0xba, 0x69, 0xe4, 0x57, 0xd7, 0xe7,
+ 0xcd, 0x58, 0xcf, 0xf7, 0xe9, 0xe3, 0xe8, 0x6f, 0x05, 0xca, 0x2e, 0xf3,
+ 0x82, 0x51, 0xdd, 0x63, 0xbb, 0x68, 0x36, 0xd9, 0x95, 0x79, 0xd8, 0xbd,
+ 0x48, 0xd7, 0x2c, 0x76, 0xb5, 0x7c, 0x81, 0x1a, 0x61, 0x69, 0xe3, 0x1e,
+ 0xc9, 0xcb, 0x51, 0x8e, 0xe5, 0xee, 0x09, 0x9d, 0xaf, 0x0a, 0xc5, 0xbf,
+ 0xc6, 0xf9, 0xfa, 0xf8, 0x7b, 0xc6, 0xd3, 0xf0, 0x3e, 0xa1, 0x37, 0x98,
+ 0xe3, 0x45, 0x42, 0x08, 0x92, 0x73, 0xdc, 0x51, 0xee, 0x55, 0xc9, 0x9f,
+ 0x41, 0xfd, 0xcc, 0xfd, 0xb8, 0x5b, 0x1d, 0x47, 0x13, 0xfc, 0xd3, 0x75,
+ 0x34, 0xe7, 0x39, 0xf1, 0xc4, 0xe0, 0x63, 0x77, 0x08, 0x1f, 0xad, 0x21,
+ 0x7c, 0x36, 0xe7, 0xd6, 0x57, 0xd2, 0xc7, 0x79, 0x70, 0x72, 0xb4, 0x70,
+ 0xfd, 0xfc, 0x32, 0xd5, 0xd5, 0xee, 0xf2, 0x0f, 0x08, 0xdf, 0x59, 0xb1,
+ 0x28, 0x5f, 0xfe, 0x0a, 0xeb, 0xe5, 0x59, 0x5e, 0xd3, 0xf8, 0xcd, 0xb2,
+ 0xfe, 0xbd, 0xf1, 0x1f, 0xb6, 0x34, 0x9b, 0xb9, 0xa0, 0x0c, 0x00, 0x00,
+ 0x00 };
static u8 bnx2_rv2p_proc2[] = {
- /* Date: 05/13/2008 13:50 */
- 0xad, 0x58, 0x4d, 0x6c, 0x54, 0x55, 0x14, 0xbe, 0x7d, 0xf3, 0xdb, 0x99,
- 0x37, 0x3f, 0xb4, 0xb5, 0xbf, 0x68, 0xa1, 0x95, 0xd2, 0x92, 0x29, 0x94,
- 0x69, 0x01, 0x95, 0x44, 0x49, 0x31, 0x05, 0x94, 0x84, 0x52, 0x5d, 0x10,
- 0x37, 0xd0, 0x22, 0xa5, 0x83, 0x2d, 0x69, 0x28, 0x61, 0xc1, 0xc6, 0x09,
- 0xc5, 0xe2, 0x62, 0x12, 0x2d, 0xb1, 0x14, 0x8c, 0xc1, 0x46, 0x37, 0xc4,
- 0xb8, 0x19, 0x83, 0x52, 0xd4, 0xc4, 0x84, 0x60, 0x43, 0x70, 0x01, 0x26,
- 0x9a, 0xe0, 0x42, 0x13, 0xa2, 0x50, 0x0b, 0x36, 0x58, 0x7e, 0x46, 0x17,
- 0xca, 0x78, 0xef, 0xf9, 0xce, 0x7d, 0x7d, 0x6f, 0x3a, 0xb5, 0x2c, 0xe8,
- 0xe6, 0xeb, 0xbd, 0xef, 0xdc, 0x73, 0xcf, 0xcf, 0x77, 0xcf, 0x39, 0x6d,
- 0x54, 0x08, 0xe1, 0x16, 0xc9, 0x74, 0xb5, 0x44, 0x11, 0x32, 0x0a, 0xfc,
- 0x12, 0xb2, 0x42, 0x78, 0xca, 0xd5, 0x5a, 0x18, 0x82, 0x7f, 0x56, 0x44,
- 0x09, 0x7e, 0x48, 0xab, 0xef, 0x3e, 0xf1, 0xaa, 0x81, 0xef, 0x6e, 0xa1,
- 0x30, 0x22, 0x44, 0x52, 0x61, 0x94, 0x71, 0x3d, 0x63, 0x86, 0x31, 0x58,
- 0x00, 0x6c, 0x66, 0x7c, 0xc0, 0xfb, 0x77, 0x78, 0x7d, 0x93, 0xf1, 0x6f,
- 0xde, 0x37, 0x19, 0x6f, 0xf3, 0xfe, 0xf3, 0x06, 0x30, 0xc1, 0xfb, 0x3f,
- 0x4b, 0xd4, 0x76, 0xa9, 0xf5, 0x74, 0x56, 0x24, 0xe5, 0x19, 0x21, 0xc5,
- 0x1b, 0xf4, 0xbe, 0x49, 0x90, 0x6c, 0x80, 0xdd, 0xaf, 0x2c, 0x51, 0x72,
- 0xbf, 0xe7, 0x91, 0x53, 0xfb, 0x37, 0xb2, 0xd0, 0x3b, 0xeb, 0xaf, 0xe1,
- 0x51, 0xe7, 0x96, 0xb6, 0x9c, 0x18, 0xc6, 0xf9, 0x9d, 0x4b, 0xb0, 0xff,
- 0x54, 0x4c, 0xf9, 0xef, 0x15, 0x49, 0x46, 0xd1, 0xa8, 0xd0, 0x28, 0x48,
- 0x36, 0xea, 0x40, 0x41, 0xfe, 0x97, 0x61, 0xac, 0x3a, 0x43, 0xd0, 0x1b,
- 0x70, 0xe8, 0x2d, 0x9d, 0xa3, 0xf7, 0x5a, 0xa1, 0x5d, 0xff, 0x67, 0xac,
- 0x3f, 0xb0, 0xa0, 0xfe, 0xae, 0x10, 0xb0, 0x38, 0x96, 0xef, 0x9e, 0xc2,
- 0x05, 0xec, 0xdf, 0xb7, 0xa0, 0xfe, 0xc3, 0x96, 0xfd, 0x3a, 0x6e, 0xfa,
- 0x3b, 0xb0, 0x1a, 0x62, 0x9f, 0x24, 0x57, 0xe9, 0x78, 0x6a, 0xbf, 0xd9,
- 0x3e, 0x17, 0x70, 0x43, 0x8c, 0x20, 0xb5, 0x9b, 0x03, 0xdc, 0x56, 0xa7,
- 0xee, 0x2d, 0x12, 0x6e, 0x43, 0xe9, 0x59, 0xee, 0xf7, 0x9e, 0xc7, 0xfe,
- 0x8e, 0x08, 0xf0, 0x75, 0x76, 0xe4, 0x46, 0x40, 0x05, 0x26, 0x9b, 0xed,
- 0x0e, 0xb2, 0x7e, 0xa4, 0x55, 0x24, 0x83, 0x38, 0x3f, 0x61, 0x2a, 0xfb,
- 0x2e, 0xcb, 0xfc, 0xa9, 0xb5, 0x4b, 0x24, 0x23, 0x4e, 0x3f, 0x3e, 0x14,
- 0x90, 0x5b, 0xb4, 0x1c, 0xbb, 0xef, 0x76, 0x63, 0x5d, 0xf5, 0x71, 0x94,
- 0xe4, 0x4f, 0xa6, 0xb5, 0x1f, 0x6a, 0x5f, 0xbe, 0x83, 0x08, 0xf4, 0x88,
- 0x1a, 0x3f, 0x5d, 0x86, 0x38, 0xc9, 0x4b, 0x1b, 0xb5, 0x3e, 0xfc, 0x9c,
- 0x58, 0xa6, 0xf9, 0x85, 0x75, 0xb7, 0x97, 0xa0, 0xbc, 0x73, 0x48, 0xd9,
- 0x1b, 0x11, 0xbb, 0x0c, 0x65, 0x88, 0xc1, 0xfe, 0xb9, 0xfc, 0xe6, 0x17,
- 0x90, 0xff, 0xa6, 0xda, 0x24, 0xdb, 0xba, 0x9b, 0x71, 0xae, 0x24, 0x0e,
- 0x1c, 0x89, 0x7b, 0x14, 0xc4, 0xba, 0x07, 0x68, 0xb9, 0xf2, 0xd7, 0xd5,
- 0x7e, 0x92, 0x4b, 0x36, 0x6a, 0xfe, 0xea, 0xb8, 0x2b, 0x7f, 0xdf, 0xc9,
- 0x5a, 0xfc, 0xaf, 0x45, 0x7c, 0x6e, 0x2e, 0x53, 0xf2, 0x32, 0x48, 0x35,
- 0xb8, 0xa7, 0x23, 0x91, 0x8f, 0xff, 0x6f, 0xdb, 0xf8, 0xff, 0x68, 0x79,
- 0xdc, 0x40, 0xfe, 0x6f, 0xe0, 0x38, 0x2c, 0x61, 0xbe, 0x2c, 0xce, 0xc3,
- 0x97, 0x08, 0xfd, 0x7e, 0xab, 0x35, 0x4a, 0x71, 0xdc, 0x86, 0xfd, 0xe3,
- 0x6d, 0xe7, 0x10, 0xef, 0x2d, 0x14, 0x07, 0x11, 0x38, 0xfa, 0x39, 0x4e,
- 0x75, 0x86, 0xd4, 0xfa, 0xb5, 0x96, 0xee, 0x2f, 0xb1, 0xee, 0x72, 0xa9,
- 0xf5, 0x0e, 0x73, 0xf7, 0x38, 0xe4, 0x3d, 0x83, 0x51, 0x8a, 0xdf, 0x36,
- 0xbe, 0x65, 0x8b, 0xab, 0x40, 0x41, 0xca, 0x3b, 0x48, 0x4b, 0x73, 0x82,
- 0xbe, 0x47, 0xc5, 0xb1, 0x34, 0xbe, 0xef, 0x0f, 0x52, 0x7d, 0x90, 0xfe,
- 0x91, 0x5c, 0x49, 0xc2, 0x8b, 0xf3, 0xa9, 0x61, 0x3f, 0xf9, 0x3b, 0x75,
- 0x56, 0xad, 0xb7, 0xc6, 0xa6, 0x20, 0x1f, 0x4b, 0x0c, 0xb1, 0x62, 0x03,
- 0xf1, 0xbb, 0x65, 0x40, 0x9e, 0xe9, 0x15, 0x70, 0x53, 0xfe, 0x0a, 0x84,
- 0xd9, 0x06, 0x7c, 0x8b, 0xbe, 0xff, 0x53, 0x90, 0xa2, 0x78, 0x6d, 0x0c,
- 0xbb, 0xcf, 0xe9, 0xf8, 0x30, 0x46, 0xb4, 0x5f, 0xc0, 0x47, 0xe5, 0xef,
- 0x90, 0xa9, 0x79, 0xcb, 0x79, 0x6b, 0x98, 0x8f, 0xb7, 0xc0, 0xb6, 0x3a,
- 0xa0, 0xb7, 0x56, 0xc9, 0x79, 0xf2, 0xf0, 0xd7, 0x99, 0x17, 0xce, 0xab,
- 0x8d, 0x67, 0x04, 0x92, 0x5f, 0x0e, 0xbe, 0x49, 0x3e, 0x53, 0x5d, 0x92,
- 0xf1, 0xd4, 0xbc, 0x51, 0x8a, 0x7c, 0xe2, 0x0d, 0xd6, 0x97, 0x60, 0xbf,
- 0x7a, 0xd9, 0xaf, 0xe9, 0x80, 0x8e, 0xbb, 0xf6, 0x07, 0x78, 0xcc, 0x04,
- 0xbf, 0x3a, 0x12, 0xda, 0x2f, 0x27, 0x7f, 0xd9, 0x9e, 0xd4, 0xb7, 0x35,
- 0xf8, 0xa5, 0xaa, 0x16, 0x68, 0xf9, 0x59, 0x47, 0xef, 0x25, 0x5c, 0x36,
- 0xae, 0xed, 0x50, 0x79, 0xfd, 0x4b, 0xe6, 0x15, 0xf9, 0x39, 0x99, 0xb6,
- 0xbf, 0xd3, 0xca, 0x3c, 0xef, 0xd4, 0xf9, 0x6e, 0xb4, 0xff, 0xfb, 0x43,
- 0x54, 0x88, 0x5a, 0xae, 0x4c, 0x3a, 0xdf, 0x05, 0xf8, 0xef, 0xb3, 0x78,
- 0x54, 0xb2, 0x96, 0xe3, 0xc4, 0x58, 0xba, 0x4e, 0xe9, 0x6b, 0x67, 0xfd,
- 0x4d, 0xac, 0xdf, 0xb4, 0xbd, 0x4b, 0x65, 0xdf, 0x93, 0xd6, 0x7b, 0xd4,
- 0xf9, 0x99, 0x7d, 0x97, 0x3a, 0x4e, 0x74, 0x7f, 0xec, 0xca, 0xa4, 0x3a,
- 0x5f, 0xb5, 0xc0, 0x3b, 0x2d, 0xb6, 0xf4, 0xfd, 0x68, 0xbd, 0x47, 0xf5,
- 0x3d, 0x28, 0x5e, 0xe0, 0xa5, 0xb3, 0xde, 0xfc, 0x29, 0xeb, 0x0d, 0xf9,
- 0xe1, 0x37, 0xcf, 0x71, 0x7d, 0x19, 0x50, 0xf7, 0x94, 0xb3, 0xdd, 0xe5,
- 0xba, 0xce, 0x4b, 0xbb, 0xb9, 0x0e, 0xed, 0xb4, 0xd7, 0x13, 0x8f, 0xad,
- 0x2e, 0xa8, 0xb5, 0x2b, 0x4f, 0x9f, 0x74, 0xc4, 0x33, 0x29, 0x22, 0x98,
- 0x03, 0x92, 0x11, 0x25, 0x7f, 0x4f, 0xcc, 0xad, 0x2b, 0xb9, 0xf6, 0x23,
- 0x1e, 0x9d, 0x46, 0x88, 0xe4, 0xae, 0xf7, 0xab, 0x73, 0xd7, 0xac, 0x3e,
- 0x8e, 0x3a, 0x73, 0x91, 0xed, 0x5d, 0xcc, 0xf6, 0x4a, 0x7d, 0x8d, 0xc4,
- 0x53, 0xff, 0xf5, 0x7e, 0xbb, 0xbd, 0x77, 0x1e, 0xce, 0x7f, 0x9f, 0x33,
- 0xef, 0xfd, 0xdc, 0x6f, 0xb8, 0x4f, 0xfa, 0x77, 0x7f, 0xa5, 0xed, 0xe1,
- 0x7b, 0x23, 0xfa, 0x7e, 0x93, 0xf2, 0x32, 0x39, 0xa0, 0xce, 0x87, 0x05,
- 0xd3, 0x44, 0xf4, 0xd5, 0xa3, 0xae, 0x4d, 0xef, 0x81, 0xfd, 0x7d, 0x75,
- 0xea, 0xfe, 0x16, 0x81, 0x7e, 0xe3, 0x96, 0x21, 0x45, 0x7d, 0xbf, 0x38,
- 0x9c, 0x2f, 0x8f, 0x5f, 0xb3, 0xdc, 0x38, 0xfb, 0x15, 0x65, 0xbf, 0x36,
- 0x4b, 0xbf, 0x28, 0xee, 0xfc, 0x3d, 0x9f, 0xdf, 0x6c, 0xa7, 0xd0, 0xfd,
- 0x9b, 0xcf, 0x91, 0x5c, 0x0f, 0xcb, 0xb9, 0xe7, 0xed, 0xdb, 0x99, 0xe5,
- 0x54, 0x87, 0x4f, 0x1f, 0xa6, 0x7a, 0x1a, 0xb2, 0xf8, 0xe6, 0xb4, 0x6f,
- 0xe2, 0x31, 0xc4, 0x51, 0xc9, 0x2d, 0x12, 0x7b, 0xc3, 0xf3, 0xc5, 0xcb,
- 0xad, 0xb6, 0xc7, 0x66, 0xc6, 0x75, 0xbc, 0x4d, 0xf2, 0x73, 0x72, 0x80,
- 0xe6, 0xc2, 0x9c, 0x38, 0x1a, 0xb6, 0x38, 0x42, 0x1e, 0xf3, 0x4a, 0xbe,
- 0xf8, 0xe5, 0xeb, 0x8b, 0x9f, 0x3e, 0xd4, 0x7c, 0x3a, 0xe2, 0xd5, 0xf6,
- 0x2b, 0x5c, 0x65, 0xe5, 0xf3, 0x00, 0xcf, 0x23, 0x19, 0x93, 0x7e, 0x89,
- 0x4f, 0xa7, 0x68, 0x69, 0x56, 0x9c, 0x51, 0x72, 0x2b, 0xe2, 0x07, 0xd8,
- 0xce, 0xcb, 0x2e, 0xf8, 0xd1, 0xb3, 0x07, 0xeb, 0x2b, 0x5c, 0xdf, 0xee,
- 0x72, 0x9d, 0xda, 0xee, 0x07, 0x4e, 0xd7, 0x93, 0x7f, 0xf1, 0x03, 0xe7,
- 0xb5, 0x7e, 0xd2, 0x6b, 0x66, 0x38, 0x3e, 0x2f, 0xba, 0xd8, 0xee, 0x1a,
- 0xca, 0x47, 0xfc, 0x0e, 0xbd, 0x4f, 0xb7, 0x68, 0x5d, 0xaa, 0xb0, 0x42,
- 0xc6, 0x81, 0xed, 0x59, 0x0f, 0xec, 0xf0, 0x71, 0x5c, 0x1b, 0x72, 0xf3,
- 0x85, 0x6d, 0x6f, 0x0d, 0x9f, 0xef, 0xc4, 0xda, 0xc7, 0xf5, 0x65, 0x94,
- 0xed, 0x7a, 0xaf, 0x1e, 0x18, 0x6e, 0x40, 0x7f, 0x9c, 0x34, 0x15, 0x46,
- 0xe2, 0x03, 0xe3, 0xf0, 0xa7, 0x77, 0x23, 0xfc, 0xbd, 0xc7, 0x71, 0x60,
- 0x0c, 0x9f, 0x1a, 0xa4, 0xbe, 0x19, 0x1e, 0x42, 0x7f, 0x0d, 0x7b, 0x07,
- 0xe1, 0x47, 0x6f, 0x06, 0xeb, 0x7b, 0xcf, 0x02, 0x1f, 0x3c, 0x87, 0x73,
- 0x07, 0x0f, 0x73, 0x7c, 0x36, 0xe6, 0x3f, 0xd7, 0x73, 0x1f, 0x72, 0x7d,
- 0xf5, 0xd4, 0xe7, 0xc7, 0xb8, 0xef, 0x8a, 0x04, 0xf7, 0xf9, 0x0c, 0xaf,
- 0xf7, 0x71, 0x1f, 0xb9, 0xcd, 0x7d, 0xb2, 0x37, 0xa7, 0x4f, 0x4e, 0xa1,
- 0x6e, 0x8e, 0x65, 0x52, 0x6a, 0x43, 0xd6, 0xaf, 0x42, 0xdd, 0x1f, 0x15,
- 0x06, 0xe2, 0x65, 0x9c, 0xaf, 0x92, 0x35, 0xc0, 0x91, 0x35, 0xe8, 0x6b,
- 0xbd, 0x87, 0x38, 0x2e, 0x2d, 0x94, 0x9f, 0x95, 0x33, 0xe3, 0x9a, 0x0f,
- 0x34, 0x3f, 0x3d, 0xd4, 0xbc, 0x43, 0xfd, 0xca, 0x58, 0xf5, 0x76, 0x8a,
- 0xec, 0xab, 0x1a, 0xcb, 0x90, 0x7c, 0xa5, 0x28, 0x26, 0x7e, 0x55, 0x84,
- 0x67, 0x60, 0x6f, 0x7c, 0x94, 0xfd, 0xec, 0x7f, 0x06, 0x78, 0x88, 0xf3,
- 0xac, 0xf3, 0x77, 0x75, 0x9d, 0x49, 0xe7, 0x26, 0x07, 0x60, 0xb7, 0xe6,
- 0x7d, 0xee, 0x9c, 0xa7, 0xf3, 0x5e, 0xd1, 0x4c, 0x6b, 0xd1, 0x73, 0x50,
- 0xdd, 0x13, 0x92, 0xf9, 0x52, 0x76, 0xc9, 0x58, 0x70, 0x7f, 0x74, 0xf2,
- 0x41, 0xf1, 0x45, 0xf3, 0xd2, 0xce, 0x23, 0x3b, 0x4f, 0x9c, 0xfc, 0x08,
- 0x53, 0x3d, 0x97, 0x8f, 0x97, 0xfa, 0xa7, 0x37, 0x3e, 0x3a, 0xfc, 0xff,
- 0xf1, 0x3a, 0x85, 0x78, 0xc5, 0xd9, 0x6e, 0x33, 0x41, 0x73, 0xd6, 0x13,
- 0x62, 0x88, 0xf3, 0x35, 0x55, 0xcf, 0xef, 0xb5, 0x06, 0xf9, 0xea, 0x7f,
- 0x1a, 0xf6, 0xf4, 0xf3, 0x3b, 0xf9, 0x83, 0xfb, 0x39, 0xf2, 0xec, 0x33,
- 0xbb, 0xc7, 0x39, 0xaf, 0xcc, 0xb7, 0x7d, 0x1c, 0x87, 0xdb, 0x88, 0x83,
- 0xa9, 0xe3, 0x90, 0xb0, 0xe2, 0xa0, 0xeb, 0x83, 0x5d, 0x4f, 0x91, 0xe4,
- 0x0b, 0xd5, 0x19, 0xf3, 0x2a, 0xcd, 0x27, 0x1e, 0xf6, 0x5b, 0xca, 0x35,
- 0x2b, 0xff, 0xc2, 0xec, 0x5f, 0x48, 0xec, 0x5d, 0x69, 0x3f, 0x17, 0xe4,
- 0x73, 0x01, 0x79, 0x0e, 0xfb, 0x78, 0x8f, 0xe6, 0x3c, 0xf1, 0x55, 0x71,
- 0xd4, 0x7a, 0x73, 0xdf, 0x9d, 0x3d, 0x9e, 0x54, 0x51, 0xe9, 0x07, 0x75,
- 0x46, 0xe6, 0x8d, 0xea, 0x91, 0x69, 0xd5, 0x99, 0xbb, 0x54, 0x7f, 0x03,
- 0xa7, 0xfb, 0x50, 0x17, 0x4e, 0xf7, 0x9d, 0xe1, 0xfe, 0xc7, 0x71, 0x69,
- 0xa7, 0xb9, 0x58, 0xc6, 0xae, 0xc6, 0x59, 0x67, 0x9c, 0x76, 0x54, 0xd9,
- 0xec, 0xd0, 0xf7, 0xce, 0xd7, 0x97, 0x31, 0xaf, 0x6d, 0xa2, 0xbe, 0xec,
- 0xb7, 0xe6, 0x49, 0x67, 0xbd, 0xf7, 0x3f, 0x72, 0xbd, 0xdf, 0xde, 0x6c,
- 0xd7, 0x5f, 0x2b, 0x26, 0xd2, 0xd0, 0xdf, 0xce, 0xfd, 0x72, 0x17, 0xbf,
- 0xdb, 0xeb, 0x81, 0x08, 0xdd, 0xd7, 0xf5, 0x32, 0xf9, 0x27, 0x4a, 0x83,
- 0xf0, 0xa7, 0x6b, 0x2b, 0xbe, 0x77, 0x85, 0xb0, 0x5f, 0x19, 0xc2, 0xdf,
- 0x5b, 0xed, 0x3e, 0x93, 0xe4, 0x2b, 0x43, 0xc0, 0x52, 0x7e, 0xef, 0x13,
- 0xd6, 0x5c, 0x0c, 0x3c, 0xe9, 0xb5, 0xcf, 0x8f, 0x6e, 0x71, 0xc1, 0x8b,
- 0xf7, 0x2f, 0x1a, 0x30, 0x07, 0xb6, 0xd6, 0x99, 0xf4, 0xbd, 0xa3, 0x01,
- 0xfd, 0x12, 0xf5, 0x75, 0xf6, 0xef, 0x33, 0x9e, 0x2b, 0x2b, 0x67, 0xe7,
- 0x67, 0xfb, 0x7c, 0x5d, 0x18, 0x1f, 0xb5, 0xe6, 0x5c, 0x7d, 0x9f, 0xfd,
- 0xfd, 0x28, 0xbd, 0xb4, 0x94, 0x73, 0xaa, 0x7d, 0xbe, 0x76, 0xe9, 0x79,
- 0x87, 0xe7, 0xd1, 0x62, 0x71, 0x29, 0x0d, 0xbf, 0x26, 0xd2, 0xf9, 0xde,
- 0xa1, 0xba, 0x4f, 0xeb, 0x83, 0xdd, 0xda, 0x8f, 0x59, 0xfd, 0xb8, 0x7f,
- 0x0f, 0xdb, 0xf9, 0x1b, 0xfd, 0x5d, 0x5c, 0xca, 0xfe, 0x28, 0xbd, 0xd8,
- 0xdf, 0xcc, 0xf3, 0x7e, 0xd2, 0x5a, 0x3b, 0xe7, 0xf4, 0x76, 0xb2, 0xab,
- 0x88, 0xfb, 0x69, 0xa9, 0xad, 0xdf, 0x43, 0xbe, 0xa4, 0x09, 0x38, 0xd2,
- 0xa4, 0xf3, 0xa0, 0xf3, 0xa5, 0xf3, 0x83, 0x3c, 0x96, 0xae, 0x26, 0xb1,
- 0x96, 0xae, 0xd5, 0xf4, 0x60, 0x9b, 0xba, 0x66, 0x9c, 0xff, 0x3f, 0xd8,
- 0x1e, 0x53, 0xf2, 0x6f, 0x8a, 0xef, 0x63, 0x68, 0x80, 0x3f, 0x31, 0xce,
- 0xce, 0xc5, 0x9c, 0x00, 0x6b, 0x1e, 0xc1, 0x7d, 0x17, 0x3c, 0xbc, 0xdd,
- 0xac, 0xe7, 0x46, 0x67, 0xff, 0xfe, 0x90, 0xea, 0xf2, 0xd9, 0x7f, 0x73,
- 0xe7, 0xce, 0xd9, 0xf9, 0x51, 0xfb, 0xa9, 0xe4, 0x1b, 0x99, 0x8f, 0x7e,
- 0xd1, 0xba, 0x09, 0x7f, 0x6f, 0x87, 0x7d, 0xe0, 0x7d, 0xd8, 0x67, 0xcf,
- 0x97, 0xe4, 0x45, 0x21, 0x3d, 0xf0, 0xc5, 0x45, 0x85, 0xe4, 0xcf, 0xf1,
- 0xcb, 0xdf, 0xd1, 0xe7, 0x8f, 0x46, 0x83, 0xd8, 0x2f, 0x6b, 0x85, 0x7a,
- 0x37, 0xf1, 0xd6, 0x25, 0x8e, 0x82, 0xd7, 0x1f, 0x8c, 0x00, 0xdf, 0x17,
- 0x2f, 0x41, 0x4f, 0xd1, 0x11, 0xea, 0x73, 0xfe, 0x32, 0x84, 0x35, 0x35,
- 0xca, 0x7c, 0x2d, 0x37, 0xe8, 0xff, 0x65, 0x59, 0x11, 0xe2, 0xff, 0xab,
- 0xf0, 0xbb, 0x03, 0x4f, 0xdd, 0xb6, 0x7c, 0x2f, 0xc4, 0x5b, 0xaa, 0x1f,
- 0x92, 0x97, 0x38, 0xce, 0xfc, 0xf5, 0xe7, 0xf2, 0x57, 0xc7, 0xa5, 0xdc,
- 0xc8, 0xcb, 0xd7, 0xb5, 0x4e, 0xbe, 0x7a, 0x99, 0xaf, 0xf7, 0xad, 0xfe,
- 0x36, 0x57, 0x2f, 0xfe, 0xae, 0xb8, 0xf4, 0xd8, 0xf8, 0x0b, 0xdc, 0x5c,
- 0xab, 0xee, 0x2f, 0x9b, 0x33, 0x77, 0x56, 0x0b, 0x7b, 0x3d, 0x3a, 0x24,
- 0xf3, 0xfd, 0x1f, 0xfe, 0xac, 0x5e, 0x92, 0x80, 0x14, 0x00, 0x00, 0x00 };
+ /* Date: 02/03/2009 14:20 */
+ 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0x3e, 0xf3, 0xe6, 0xef, 0xcd,
+ 0xcc, 0x9b, 0xcc, 0x34, 0x8d, 0x93, 0x31, 0x29, 0x26, 0x4d, 0x68, 0xea,
+ 0xc8, 0x44, 0xf3, 0x47, 0x05, 0x5d, 0x18, 0x46, 0x48, 0x7f, 0x2c, 0x34,
+ 0x8d, 0x2e, 0x8a, 0x9b, 0x36, 0x53, 0x3b, 0x3a, 0x6d, 0xed, 0xc2, 0xec,
+ 0xdc, 0xf8, 0xb0, 0x35, 0x41, 0x98, 0x45, 0x53, 0x4c, 0x13, 0x44, 0xa8,
+ 0xe8, 0xce, 0xdd, 0x88, 0x9a, 0xd6, 0x8d, 0x50, 0x68, 0x28, 0x76, 0x51,
+ 0x04, 0x05, 0xed, 0x42, 0x10, 0xad, 0xa1, 0x15, 0x41, 0x51, 0xb3, 0x92,
+ 0x8c, 0xf7, 0x9e, 0xef, 0xdc, 0x37, 0xef, 0x4d, 0xa6, 0xa4, 0x0b, 0x67,
+ 0xf3, 0xe5, 0xdc, 0x77, 0xee, 0xb9, 0xe7, 0xe7, 0x3b, 0xe7, 0xde, 0x64,
+ 0x89, 0x28, 0x42, 0x6e, 0xbd, 0x4f, 0x21, 0x85, 0xc2, 0x21, 0x5b, 0x41,
+ 0x83, 0x28, 0x9a, 0xd7, 0x32, 0x59, 0x24, 0xbf, 0x27, 0xb2, 0x0c, 0xdf,
+ 0xd6, 0x1d, 0xad, 0x46, 0x6e, 0x41, 0xeb, 0xd9, 0xf4, 0x92, 0x05, 0xbd,
+ 0x08, 0x69, 0x54, 0x3a, 0xae, 0xc6, 0x1d, 0x82, 0xcf, 0x08, 0x46, 0x42,
+ 0xc0, 0xb0, 0xa0, 0xd5, 0x82, 0x24, 0x7a, 0x5d, 0x22, 0x6f, 0x8a, 0xec,
+ 0x08, 0xe6, 0x65, 0xfd, 0xb4, 0xe0, 0xab, 0xb2, 0x7e, 0x47, 0x70, 0x5d,
+ 0xa1, 0xf1, 0x53, 0xcb, 0xbf, 0x35, 0x9a, 0xb2, 0x03, 0xf3, 0x05, 0xf8,
+ 0xff, 0x62, 0x3f, 0xeb, 0x37, 0x82, 0xfa, 0x77, 0x1b, 0xc6, 0x0f, 0x13,
+ 0xaf, 0x15, 0xd5, 0xfa, 0xbb, 0x27, 0x2e, 0x2f, 0x62, 0xdf, 0xf1, 0x7e,
+ 0xac, 0x3f, 0x56, 0xd4, 0x71, 0xc7, 0xc8, 0x15, 0xa4, 0x61, 0x9b, 0xe3,
+ 0x70, 0x87, 0x4d, 0xa2, 0xa0, 0xff, 0xe3, 0x22, 0xa4, 0xd9, 0x34, 0xec,
+ 0x26, 0x03, 0x76, 0x73, 0x5b, 0xec, 0x7e, 0x9f, 0xf0, 0xdb, 0xff, 0x54,
+ 0xec, 0x27, 0xb7, 0xb5, 0x5f, 0x4e, 0x03, 0x77, 0x16, 0xdb, 0x9d, 0x93,
+ 0xd8, 0xc6, 0xff, 0xd3, 0xdb, 0xda, 0x7f, 0xd3, 0xf3, 0xdf, 0xac, 0x03,
+ 0xfb, 0xf0, 0xf9, 0x13, 0xf7, 0x29, 0x93, 0x47, 0x13, 0xaf, 0xf8, 0x15,
+ 0x06, 0x4e, 0x16, 0x19, 0x6a, 0x27, 0x25, 0xb1, 0x53, 0x43, 0xfa, 0xbc,
+ 0x4e, 0x8a, 0x58, 0xda, 0xce, 0x5e, 0x3b, 0x76, 0x0d, 0xeb, 0xc7, 0x32,
+ 0xc0, 0x57, 0x24, 0x80, 0xbb, 0x49, 0x9d, 0x90, 0x46, 0xa3, 0x92, 0x12,
+ 0xfb, 0x28, 0x23, 0xb9, 0x29, 0xec, 0x5f, 0x73, 0xb4, 0x5f, 0xb7, 0x54,
+ 0xdd, 0xb4, 0x1c, 0x26, 0x37, 0x13, 0xf4, 0xff, 0x0a, 0x41, 0x6f, 0xc7,
+ 0x5e, 0xac, 0x5e, 0xac, 0x40, 0xee, 0xfd, 0x38, 0xcb, 0xfa, 0x2b, 0x75,
+ 0x13, 0x87, 0x5e, 0x57, 0xfc, 0xcf, 0xc0, 0x0e, 0x0d, 0xd8, 0x7c, 0x18,
+ 0xf2, 0xa3, 0x0e, 0x1d, 0x36, 0xf6, 0xf0, 0xbb, 0xbc, 0xc7, 0xf0, 0x09,
+ 0x72, 0x25, 0xc6, 0x90, 0x9f, 0x9d, 0xd7, 0xfe, 0x66, 0xe8, 0x84, 0xa5,
+ 0x1d, 0xb1, 0x24, 0xbe, 0xb0, 0xed, 0x7c, 0x01, 0xfd, 0xaf, 0xfa, 0x1c,
+ 0xf6, 0xad, 0x32, 0x8e, 0x7d, 0x5d, 0x63, 0xc0, 0xa5, 0xb1, 0xa8, 0x86,
+ 0x62, 0x65, 0x8e, 0xc5, 0x27, 0x7f, 0x1e, 0xb5, 0x59, 0xcf, 0x1d, 0x36,
+ 0x7c, 0x35, 0x79, 0xd7, 0xf1, 0x5e, 0x6c, 0xf2, 0x76, 0x10, 0xf9, 0xf9,
+ 0x75, 0x8f, 0xd6, 0x57, 0x49, 0x1a, 0xc0, 0x39, 0x33, 0xd5, 0x76, 0x7c,
+ 0x7f, 0x57, 0xed, 0x7b, 0xb8, 0xfa, 0x4d, 0x72, 0xdc, 0x93, 0x12, 0x7f,
+ 0xbf, 0xf0, 0x63, 0x57, 0x1b, 0x7e, 0x64, 0xf8, 0xef, 0xfb, 0xa5, 0x2c,
+ 0xe7, 0xef, 0x08, 0xd6, 0x2f, 0x4d, 0xad, 0x22, 0xcf, 0x07, 0x39, 0x7e,
+ 0x4a, 0x5e, 0xf8, 0x1c, 0xbb, 0x66, 0xd3, 0x5a, 0x7e, 0x79, 0xa2, 0xf2,
+ 0x25, 0xe4, 0x72, 0x58, 0xcb, 0xc7, 0x9c, 0x93, 0x57, 0xa1, 0x1f, 0x3d,
+ 0x9f, 0xe5, 0xbc, 0x1d, 0x91, 0x53, 0x0e, 0xaa, 0x51, 0xa1, 0x7e, 0xb5,
+ 0xd8, 0x79, 0x16, 0x9d, 0x35, 0xfe, 0x9e, 0xa5, 0x85, 0x3a, 0xbe, 0x9f,
+ 0x4b, 0xe9, 0xb8, 0xce, 0xa8, 0xb8, 0x58, 0xaf, 0xab, 0x1a, 0xc3, 0xfe,
+ 0xda, 0xa2, 0xb6, 0x17, 0xa2, 0x7b, 0x9f, 0x69, 0xf9, 0x70, 0xf1, 0x1e,
+ 0xf4, 0x8b, 0xd5, 0x79, 0x31, 0x6c, 0x21, 0x6f, 0xf7, 0x2d, 0xe8, 0x0b,
+ 0xad, 0x92, 0x11, 0xae, 0x5b, 0x88, 0x9c, 0x29, 0xe0, 0x3b, 0xfc, 0xfd,
+ 0xdf, 0x50, 0x8d, 0xf3, 0xf5, 0x7c, 0x47, 0x64, 0xd5, 0xe4, 0x47, 0x30,
+ 0x63, 0xe2, 0x02, 0x3e, 0x2c, 0x6f, 0xe7, 0x1d, 0xc3, 0x57, 0xa9, 0x57,
+ 0xe1, 0x41, 0x7c, 0x05, 0x4e, 0x0d, 0x01, 0x63, 0x83, 0x5a, 0x2f, 0xda,
+ 0x86, 0xb7, 0xc1, 0xba, 0x48, 0x5d, 0x7d, 0xfc, 0x62, 0x50, 0xbc, 0x0a,
+ 0xf0, 0x4c, 0xf1, 0x98, 0xe7, 0x90, 0xca, 0xa7, 0xe1, 0x8b, 0x36, 0x14,
+ 0xa7, 0x33, 0x62, 0xaf, 0x2a, 0x71, 0x9d, 0x95, 0xb8, 0x7e, 0x4f, 0x9a,
+ 0xbc, 0x9b, 0x78, 0x80, 0x0b, 0x5e, 0x3c, 0x86, 0x6f, 0xb8, 0x1f, 0x66,
+ 0xaa, 0x01, 0x7f, 0x6a, 0x37, 0x06, 0xf0, 0x47, 0xef, 0x20, 0xd0, 0x8b,
+ 0x73, 0x88, 0xfb, 0xa4, 0xa3, 0xfb, 0xaa, 0xf1, 0x43, 0xd7, 0x75, 0x43,
+ 0xf8, 0x6a, 0xa9, 0x78, 0xfd, 0xfd, 0xd9, 0xd3, 0xa6, 0x3f, 0x83, 0xfd,
+ 0x62, 0xe2, 0x3f, 0x97, 0xe6, 0x01, 0x34, 0x71, 0x7b, 0x3d, 0xd8, 0x0f,
+ 0xe0, 0x7f, 0xdc, 0xe3, 0x51, 0xd7, 0x3e, 0xc9, 0x93, 0x60, 0xee, 0x69,
+ 0x6d, 0x6f, 0x5a, 0xec, 0x8f, 0x88, 0x7d, 0xc7, 0xd7, 0x8f, 0xda, 0xbf,
+ 0x3e, 0xaf, 0x0f, 0x4d, 0x7d, 0x9a, 0xfd, 0x68, 0xf2, 0xc4, 0xe7, 0x17,
+ 0x6f, 0xaf, 0xeb, 0xfd, 0xbd, 0xdb, 0xf4, 0xe7, 0x23, 0x9e, 0xbd, 0xef,
+ 0xbc, 0x7e, 0xd4, 0xdf, 0x53, 0xf4, 0x9c, 0x88, 0xc1, 0x39, 0xf3, 0x87,
+ 0x9a, 0x33, 0x1c, 0x87, 0xed, 0xac, 0xca, 0x5c, 0x99, 0xd3, 0xe7, 0xe4,
+ 0xc5, 0xef, 0xbc, 0x99, 0xeb, 0xca, 0x6f, 0x99, 0x3f, 0xc7, 0xfd, 0x73,
+ 0x24, 0xde, 0xe6, 0x3c, 0xc0, 0x64, 0xb1, 0x35, 0x5f, 0xc8, 0x3b, 0xec,
+ 0xaa, 0xfc, 0x9b, 0x39, 0x30, 0x6e, 0xec, 0x43, 0x74, 0x47, 0xfd, 0xfa,
+ 0xad, 0xf5, 0x89, 0x3c, 0x60, 0x9e, 0x6d, 0x6c, 0xe2, 0xde, 0xfd, 0x67,
+ 0xb3, 0x79, 0x1f, 0x07, 0xea, 0xe8, 0x12, 0xd7, 0x3d, 0xae, 0xea, 0xcf,
+ 0xef, 0x03, 0xef, 0x9e, 0xb7, 0xa2, 0x7a, 0x5d, 0xe5, 0x42, 0x78, 0xf5,
+ 0xfa, 0xe3, 0xb2, 0xbf, 0x80, 0xb9, 0xf4, 0xda, 0x29, 0xce, 0xff, 0x7b,
+ 0x67, 0x37, 0x78, 0x3e, 0x7d, 0xf8, 0xc6, 0x35, 0x1d, 0xd7, 0xa3, 0xb4,
+ 0x3e, 0xe7, 0xb0, 0x3f, 0xa5, 0xdd, 0x50, 0xdf, 0x78, 0xb6, 0xb5, 0x1e,
+ 0x78, 0xd7, 0xa0, 0x5e, 0x4a, 0x6f, 0x36, 0x78, 0xaf, 0x36, 0xfd, 0x43,
+ 0xbf, 0xec, 0xcf, 0x40, 0xdf, 0xf4, 0x73, 0xb0, 0xae, 0x77, 0x36, 0x9b,
+ 0x73, 0xd7, 0xe4, 0x3b, 0xc8, 0xd3, 0xa3, 0xe3, 0x7e, 0xbb, 0x83, 0xb4,
+ 0x56, 0x87, 0xdd, 0x69, 0xe9, 0xc3, 0x13, 0x72, 0xf0, 0x4f, 0xc9, 0x0c,
+ 0x9f, 0x53, 0x7e, 0x81, 0x79, 0x46, 0xb9, 0x14, 0xe2, 0x2c, 0x1f, 0xc6,
+ 0xf7, 0x72, 0x1a, 0xeb, 0x3d, 0x69, 0xdc, 0x6f, 0xd3, 0x71, 0x87, 0xf5,
+ 0x7b, 0xd2, 0xc0, 0x9c, 0xf4, 0xeb, 0x9a, 0x37, 0x8f, 0x80, 0x2b, 0x31,
+ 0x7f, 0xff, 0x46, 0xe8, 0x7a, 0x4c, 0x2b, 0xa8, 0xcb, 0xba, 0x80, 0xfe,
+ 0x2b, 0x0d, 0x39, 0xfc, 0x7d, 0xa6, 0x80, 0xb9, 0x4a, 0x03, 0xc1, 0xfb,
+ 0x50, 0xfa, 0xb9, 0xa7, 0x39, 0xb7, 0xfc, 0x73, 0x2d, 0x31, 0xb6, 0x5c,
+ 0x0f, 0xde, 0x97, 0x2b, 0x31, 0xff, 0x9c, 0xd0, 0x76, 0x59, 0x54, 0xf3,
+ 0xc1, 0x3f, 0xd7, 0xc2, 0x52, 0xef, 0xbf, 0x64, 0x0e, 0xec, 0xa4, 0x9b,
+ 0x75, 0xc4, 0xb5, 0x56, 0x6f, 0xcd, 0xb3, 0x39, 0xcf, 0xd8, 0x83, 0xdf,
+ 0x26, 0x8e, 0xa6, 0x7d, 0x9c, 0x7f, 0x4a, 0xfc, 0xfc, 0x85, 0xdf, 0x21,
+ 0x39, 0x89, 0x47, 0xdb, 0xc5, 0xfa, 0x01, 0x99, 0xb3, 0xae, 0x27, 0x07,
+ 0xe7, 0xe3, 0x34, 0xfb, 0xd5, 0x49, 0x78, 0x77, 0xe4, 0xbc, 0xbe, 0x36,
+ 0xf1, 0x75, 0x8d, 0x00, 0x97, 0x46, 0x4c, 0x1d, 0x4c, 0xbd, 0x4c, 0x7d,
+ 0x50, 0xc7, 0xdc, 0x28, 0xab, 0x4d, 0x94, 0x47, 0x99, 0xa7, 0x23, 0xe5,
+ 0x3f, 0x83, 0xef, 0xb4, 0xa3, 0x45, 0xad, 0xff, 0x16, 0x7d, 0xc3, 0x7d,
+ 0x44, 0xf4, 0x83, 0x60, 0x73, 0x1e, 0x49, 0x01, 0x02, 0xef, 0xb2, 0x30,
+ 0x5d, 0x8f, 0xca, 0xf2, 0xb8, 0xe9, 0x9b, 0x60, 0xdf, 0x5d, 0xe1, 0x77,
+ 0xfa, 0xc2, 0xe6, 0xd6, 0xfe, 0x37, 0xf1, 0x69, 0xbd, 0x61, 0xe1, 0xa1,
+ 0x4d, 0xa5, 0xfd, 0x78, 0xd7, 0x74, 0xc4, 0xc1, 0xf3, 0x8e, 0xb8, 0xbf,
+ 0x4e, 0x8a, 0x0f, 0x89, 0xb8, 0x16, 0x77, 0x75, 0x26, 0x38, 0x8e, 0x4b,
+ 0x5f, 0xdf, 0xe2, 0xcf, 0x1f, 0x2d, 0xa7, 0xb0, 0xde, 0x5d, 0x82, 0xf9,
+ 0x08, 0xf3, 0x35, 0x4c, 0x17, 0xc0, 0xe7, 0x0f, 0x96, 0x80, 0xef, 0xd3,
+ 0x21, 0xd8, 0xe9, 0x7c, 0x9b, 0xef, 0x71, 0xbb, 0x1b, 0xe9, 0xac, 0x2d,
+ 0x0b, 0x4f, 0xf3, 0x16, 0xff, 0x3f, 0xd2, 0xa0, 0xb4, 0xbc, 0x5b, 0xa5,
+ 0xcf, 0xc0, 0xcf, 0x88, 0xaf, 0xce, 0xdb, 0xf1, 0x55, 0xa3, 0xa3, 0xf8,
+ 0x88, 0xed, 0xc2, 0x5b, 0xbb, 0x95, 0xb7, 0xa6, 0x8e, 0x79, 0xab, 0x2d,
+ 0x4f, 0xf7, 0x05, 0x79, 0x1a, 0x13, 0x9e, 0xfe, 0xed, 0xcd, 0xd3, 0xad,
+ 0x76, 0x31, 0xc7, 0x6f, 0xfe, 0x6f, 0xbc, 0x05, 0x1e, 0x18, 0xd4, 0xe7,
+ 0x77, 0xfb, 0xf8, 0x67, 0xfc, 0xf2, 0xcf, 0x9f, 0x43, 0x6a, 0xae, 0xfe,
+ 0x07, 0x92, 0xe2, 0x88, 0x7c, 0xe0, 0x0d, 0x00, 0x00, 0x00 };
static u8 bnx2_TPAT_b06FwText[] = {
- 0xbd, 0x59, 0x6d, 0x70, 0x5b, 0x55, 0x7a, 0x7e, 0xae, 0x74, 0x25, 0x5d,
- 0xdb, 0xb2, 0x75, 0x8d, 0x95, 0x20, 0xb7, 0x2e, 0xd6, 0x8d, 0xaf, 0x6c,
- 0x11, 0xb9, 0xe1, 0x2a, 0x36, 0x45, 0x19, 0xee, 0x94, 0x1b, 0x7f, 0x21,
- 0x92, 0x10, 0x94, 0x42, 0x5b, 0x67, 0x96, 0x19, 0x4c, 0xe2, 0x4d, 0x4c,
- 0x08, 0x6c, 0xba, 0xcb, 0x4c, 0xdd, 0xd9, 0x4c, 0x23, 0xfc, 0x15, 0x93,
- 0xc8, 0x16, 0x6b, 0x20, 0x26, 0x3b, 0x3b, 0x43, 0xc6, 0xf9, 0x70, 0x0a,
- 0x72, 0x14, 0xda, 0x3f, 0x3b, 0xd3, 0x65, 0xf0, 0x6c, 0x12, 0x12, 0x58,
- 0xd8, 0xb4, 0xd3, 0x3f, 0xc9, 0xf4, 0xc7, 0x7a, 0x21, 0xa1, 0x81, 0x42,
- 0x36, 0xed, 0x0c, 0x9d, 0x50, 0x68, 0x4e, 0x9f, 0x73, 0x25, 0x07, 0x13,
- 0xb2, 0xfd, 0xd9, 0xcc, 0x08, 0x4b, 0xe7, 0xde, 0x73, 0xce, 0x7b, 0xce,
- 0xfb, 0x3c, 0xcf, 0xfb, 0x9c, 0xc3, 0x0a, 0x05, 0x95, 0x28, 0xff, 0xab,
- 0xe6, 0xa7, 0xfd, 0xc9, 0x5d, 0xcf, 0xad, 0x5e, 0xd5, 0xbe, 0x8a, 0x5f,
- 0x57, 0x2b, 0xcb, 0x55, 0x15, 0xff, 0x8f, 0xff, 0xbc, 0x80, 0xbe, 0x18,
- 0x87, 0xfc, 0x40, 0xf3, 0xd8, 0xf3, 0x77, 0x75, 0x98, 0xd0, 0xbc, 0xf6,
- 0x63, 0x4d, 0x5b, 0x4d, 0xc0, 0x29, 0x24, 0xa2, 0x9d, 0xf8, 0x1f, 0x91,
- 0x0d, 0xab, 0x90, 0xed, 0x7f, 0x64, 0x7f, 0x7d, 0xcf, 0x5b, 0xf7, 0x19,
- 0xd7, 0x0e, 0x79, 0xa1, 0xe9, 0xf6, 0xb8, 0xaa, 0x37, 0x43, 0x6b, 0x60,
- 0x9f, 0x9f, 0xb5, 0xf4, 0xfb, 0x50, 0xb3, 0x38, 0x16, 0x70, 0x38, 0x67,
- 0x58, 0xdb, 0x90, 0xd0, 0x4f, 0x41, 0x85, 0xc3, 0x39, 0x8e, 0x15, 0x80,
- 0xbd, 0x39, 0x05, 0x97, 0x39, 0xe6, 0x68, 0x41, 0xc3, 0x82, 0xd7, 0x9d,
- 0xae, 0xaf, 0xc2, 0x46, 0xc6, 0x9c, 0xd8, 0x23, 0x02, 0x26, 0xb2, 0x7f,
- 0x60, 0x9b, 0xf1, 0xbd, 0x08, 0xa6, 0x66, 0xda, 0x91, 0x59, 0x31, 0xa7,
- 0x61, 0x73, 0xbe, 0xa1, 0x4f, 0xb3, 0xc1, 0x77, 0x14, 0xa4, 0xee, 0xd3,
- 0xd0, 0x5b, 0x8c, 0x23, 0x5b, 0xcc, 0xc2, 0x29, 0x8e, 0xf0, 0xa3, 0x21,
- 0x30, 0xa1, 0x69, 0xf7, 0x4c, 0x2c, 0x97, 0xef, 0x20, 0x38, 0x71, 0x4d,
- 0x5c, 0x4d, 0xea, 0x78, 0x6f, 0x8d, 0x10, 0xd5, 0x36, 0xb2, 0x55, 0xed,
- 0x59, 0x78, 0x6d, 0xc3, 0x5a, 0xef, 0x55, 0xd0, 0xf5, 0xc7, 0x66, 0x7c,
- 0x42, 0x79, 0xf4, 0x51, 0x8f, 0x0d, 0x4d, 0xb1, 0xa3, 0x6a, 0x53, 0xa1,
- 0x01, 0x63, 0x45, 0x1d, 0x7b, 0x8b, 0x61, 0x8c, 0x14, 0xb1, 0xdb, 0x7b,
- 0xaf, 0x1f, 0x33, 0x3a, 0x9c, 0xef, 0xb5, 0xec, 0xc6, 0x8e, 0xdc, 0x20,
- 0xb6, 0xe6, 0x52, 0xd8, 0x57, 0x94, 0x31, 0x46, 0x31, 0x5c, 0x54, 0xe1,
- 0x9f, 0x30, 0x22, 0xef, 0xe2, 0x76, 0xcf, 0x84, 0x18, 0xb1, 0x02, 0x18,
- 0xb2, 0xe2, 0x18, 0xcd, 0x7b, 0xb8, 0xce, 0x00, 0x86, 0xcd, 0xeb, 0xa2,
- 0xdf, 0x32, 0xac, 0x51, 0x88, 0xc6, 0xd3, 0x96, 0x11, 0xe9, 0xf2, 0xc2,
- 0xf9, 0xb1, 0x19, 0xc1, 0x28, 0x63, 0x1f, 0x71, 0xfb, 0x8d, 0xa0, 0xeb,
- 0x66, 0x3f, 0x87, 0xfd, 0x74, 0x8c, 0x7d, 0xbb, 0x6f, 0x74, 0x14, 0x89,
- 0xc8, 0x18, 0x3c, 0xe8, 0x0b, 0xb7, 0xb2, 0x5f, 0x53, 0x74, 0x0c, 0x46,
- 0x9c, 0xe3, 0x64, 0xfd, 0xed, 0x0e, 0xc7, 0xc8, 0xb2, 0xbf, 0x11, 0x3d,
- 0x06, 0x39, 0x56, 0x03, 0x7f, 0xb7, 0xb3, 0xbf, 0x02, 0x8f, 0x1d, 0x8b,
- 0x0e, 0xb1, 0xcf, 0x29, 0x4b, 0xc5, 0x19, 0x7e, 0xfa, 0x74, 0x43, 0x66,
- 0x56, 0x09, 0xb0, 0x7d, 0x2f, 0xf8, 0xdc, 0xac, 0xc2, 0xa1, 0x8c, 0x85,
- 0x21, 0xae, 0x5b, 0x63, 0xdb, 0x38, 0xdb, 0x7c, 0xa6, 0xc5, 0xf1, 0xa1,
- 0x77, 0x15, 0x97, 0x62, 0x62, 0x31, 0x37, 0xbf, 0xaf, 0x9d, 0x63, 0xe4,
- 0x4b, 0x39, 0x95, 0xef, 0x74, 0xe6, 0x6f, 0x88, 0x27, 0xd5, 0xa5, 0xcf,
- 0x07, 0x95, 0x0e, 0xb6, 0x39, 0x6a, 0x03, 0xf6, 0xe6, 0xa1, 0xf9, 0x4d,
- 0x8d, 0xf3, 0x68, 0xf8, 0x28, 0x37, 0xa8, 0xf4, 0x14, 0x1d, 0xa5, 0x7b,
- 0xb6, 0x43, 0x71, 0x66, 0x55, 0xa5, 0x6b, 0x5a, 0xc6, 0x2d, 0xc4, 0x0b,
- 0x96, 0xc2, 0x98, 0x7f, 0x22, 0xe3, 0x75, 0xa2, 0xca, 0x0d, 0xb1, 0x32,
- 0xe6, 0x41, 0x95, 0xd9, 0xa3, 0xac, 0x9f, 0x15, 0x22, 0x9d, 0x4c, 0x2b,
- 0xeb, 0x66, 0xa1, 0x05, 0x6d, 0x5b, 0xcd, 0x4d, 0xec, 0x43, 0x76, 0x99,
- 0x89, 0x83, 0xf9, 0x28, 0x3e, 0xb0, 0x3c, 0x38, 0xb4, 0xac, 0x02, 0xaa,
- 0xa9, 0xf0, 0x83, 0xe0, 0x79, 0x0b, 0x6a, 0x0d, 0xbf, 0x5f, 0xdd, 0xa4,
- 0x62, 0xa4, 0x7d, 0x9d, 0xd2, 0xc5, 0x3e, 0x3e, 0xe6, 0xf9, 0x68, 0x2e,
- 0x8d, 0x20, 0xb1, 0x53, 0x65, 0xc7, 0x22, 0x05, 0xee, 0xcd, 0x7b, 0x56,
- 0x2c, 0xfe, 0xb4, 0xc4, 0x63, 0xad, 0x11, 0x91, 0x7b, 0x53, 0x6d, 0xc7,
- 0xe2, 0x73, 0xdc, 0x07, 0xaf, 0xa9, 0xe2, 0xd7, 0x96, 0x0f, 0xf3, 0x9b,
- 0x2c, 0xe6, 0x54, 0x87, 0x9f, 0xed, 0xc7, 0xdc, 0x76, 0xf9, 0x1b, 0x7a,
- 0xf7, 0xb7, 0xf6, 0xa1, 0xb4, 0x07, 0xc3, 0xf9, 0x26, 0xc6, 0x5c, 0xda,
- 0x83, 0x47, 0xb8, 0xde, 0xdf, 0xfa, 0xe4, 0xd7, 0xbb, 0x6e, 0xb6, 0x6d,
- 0x66, 0x9c, 0x1e, 0xdb, 0x9c, 0x5f, 0xe1, 0xad, 0x07, 0xea, 0xda, 0xb1,
- 0x8f, 0x39, 0xee, 0x4a, 0x2e, 0x47, 0xd6, 0x7d, 0x1e, 0xd6, 0xd7, 0x4f,
- 0xd7, 0xa1, 0x6f, 0x99, 0xbb, 0x6f, 0xfa, 0xc6, 0x69, 0x21, 0xce, 0x24,
- 0xfd, 0x98, 0x33, 0x87, 0x22, 0xd5, 0xc8, 0x5a, 0x5e, 0xe6, 0xfb, 0x2c,
- 0xe7, 0x2f, 0x24, 0xbd, 0x38, 0x9c, 0x3c, 0x84, 0x6c, 0x2d, 0x30, 0x93,
- 0x93, 0xbc, 0x32, 0xe6, 0xcf, 0xf2, 0xbf, 0x9e, 0xa2, 0x5c, 0x9f, 0xc5,
- 0xf5, 0x29, 0x38, 0x66, 0x4a, 0x4c, 0x5b, 0x6a, 0x33, 0xf9, 0xb5, 0x83,
- 0xfb, 0x59, 0xdf, 0x1e, 0x24, 0x3e, 0x81, 0x0f, 0x73, 0xfd, 0xd8, 0x5c,
- 0x8a, 0x05, 0xd7, 0x73, 0x50, 0x7c, 0x6d, 0x69, 0x1c, 0x2a, 0xfd, 0x26,
- 0xc7, 0xd3, 0x6a, 0x47, 0xce, 0xc8, 0xa4, 0x91, 0x38, 0xd7, 0xa1, 0xc8,
- 0xfe, 0x69, 0x75, 0x65, 0xc1, 0x8f, 0x68, 0x5d, 0xe9, 0x79, 0x95, 0xbd,
- 0x41, 0x7d, 0x7a, 0x42, 0xc1, 0xf6, 0x98, 0x7c, 0xb6, 0x41, 0x6d, 0x29,
- 0x40, 0xab, 0xb6, 0x77, 0xa9, 0x73, 0x13, 0x46, 0xdf, 0x71, 0x25, 0x11,
- 0x9d, 0x70, 0xfb, 0xec, 0x52, 0x5b, 0x0b, 0x01, 0xae, 0x27, 0xce, 0x9c,
- 0x40, 0xab, 0xb1, 0x9f, 0x53, 0x7f, 0xcd, 0x07, 0xe7, 0xdc, 0x3e, 0xcf,
- 0xa9, 0xf1, 0x82, 0x6c, 0x37, 0xac, 0xa8, 0x12, 0xc0, 0xdd, 0x49, 0x0d,
- 0x2b, 0x5b, 0x44, 0x63, 0x77, 0xd2, 0x98, 0xef, 0xf6, 0x46, 0x70, 0x90,
- 0x5c, 0x20, 0xee, 0x9c, 0x3f, 0x6c, 0x19, 0x41, 0x77, 0xd1, 0x8b, 0x68,
- 0xad, 0x83, 0xfd, 0xf9, 0x00, 0x7e, 0x49, 0xfc, 0xf7, 0x58, 0x3a, 0x46,
- 0xf2, 0x46, 0xfc, 0x57, 0x48, 0xa4, 0x8e, 0x30, 0x67, 0x0b, 0xe4, 0xc0,
- 0xfe, 0x62, 0x53, 0xfc, 0x08, 0x8c, 0x81, 0x6e, 0x72, 0x40, 0x6b, 0x97,
- 0x31, 0x40, 0x57, 0x6d, 0x72, 0xa7, 0xd8, 0x80, 0x1c, 0xf9, 0xd0, 0xed,
- 0xf2, 0x6a, 0x50, 0xe9, 0x2a, 0xbe, 0x4f, 0x6d, 0xed, 0x21, 0xbe, 0x10,
- 0x8a, 0x98, 0x7e, 0xa4, 0xea, 0xa2, 0x38, 0x4d, 0xac, 0x64, 0xc3, 0x15,
- 0xcc, 0xa5, 0xcc, 0xe7, 0x45, 0x3e, 0x5f, 0xa7, 0x74, 0xce, 0x46, 0xf1,
- 0x4b, 0xeb, 0x6b, 0xe1, 0x84, 0xab, 0xd9, 0xe6, 0x5b, 0xd2, 0xae, 0xe1,
- 0xf2, 0xcb, 0x95, 0xf8, 0xf4, 0xe5, 0x20, 0xbe, 0x7c, 0x99, 0xfc, 0xce,
- 0xa3, 0xbd, 0x12, 0x42, 0xa4, 0xda, 0x84, 0x28, 0x5a, 0xad, 0xf8, 0xa8,
- 0x36, 0x16, 0xbd, 0x00, 0xa9, 0x8d, 0x8e, 0xba, 0x35, 0x67, 0xec, 0x1a,
- 0x40, 0xc2, 0x39, 0xe5, 0xee, 0x85, 0xa3, 0xae, 0x2a, 0x9c, 0x16, 0xd8,
- 0x54, 0xda, 0x0b, 0xbf, 0xdd, 0xa5, 0xbe, 0xc3, 0xdc, 0x9c, 0x77, 0x73,
- 0xd3, 0xa5, 0xde, 0x53, 0xb8, 0xdf, 0x83, 0xca, 0xd2, 0x33, 0xd5, 0xce,
- 0xa8, 0x23, 0x39, 0xa3, 0x77, 0x9c, 0xeb, 0xeb, 0x77, 0xfb, 0x66, 0xd4,
- 0x04, 0xf7, 0x7e, 0xa1, 0x9c, 0x9b, 0x6a, 0xfb, 0x31, 0xee, 0x33, 0x73,
- 0xef, 0xee, 0xe3, 0x63, 0xdc, 0x63, 0x39, 0xdf, 0xe0, 0x2d, 0xf3, 0x0d,
- 0x72, 0xbe, 0xe3, 0x4b, 0xe6, 0xdb, 0xbd, 0x64, 0xbe, 0xdd, 0x4b, 0xe6,
- 0x4b, 0x91, 0xab, 0xff, 0x22, 0x86, 0xc2, 0xa5, 0xb1, 0x55, 0x7b, 0xe0,
- 0x96, 0xb9, 0x07, 0x38, 0xf7, 0x01, 0xb1, 0x90, 0x29, 0x8d, 0x53, 0x6d,
- 0xef, 0x5c, 0x32, 0xf7, 0x4e, 0xce, 0xbd, 0x38, 0x8e, 0x4e, 0x2d, 0x12,
- 0x62, 0xa3, 0x25, 0x84, 0x6a, 0x9b, 0x7a, 0x17, 0x9a, 0x33, 0x5d, 0xc4,
- 0x4e, 0x25, 0x12, 0xf3, 0x1e, 0x98, 0x83, 0xf5, 0x5e, 0x1f, 0x16, 0x6a,
- 0x17, 0xb9, 0x51, 0x5d, 0xfe, 0xfb, 0x9a, 0x02, 0x6a, 0xfd, 0x1b, 0xb9,
- 0x10, 0xc7, 0x88, 0xe9, 0xfd, 0x8a, 0x10, 0xa7, 0xd6, 0x24, 0x06, 0xbc,
- 0x48, 0xf4, 0xd5, 0xc0, 0x24, 0x86, 0x7c, 0x65, 0x2e, 0x2c, 0xed, 0x73,
- 0xdc, 0xed, 0x53, 0x74, 0xfb, 0x08, 0xf1, 0xe1, 0xbd, 0x57, 0xc4, 0x5b,
- 0x2d, 0x61, 0xbc, 0x4d, 0x4e, 0x9e, 0x2c, 0x2e, 0xea, 0x8a, 0xd4, 0x0d,
- 0x78, 0x4e, 0x59, 0x7e, 0xc6, 0x34, 0xb4, 0xc3, 0xff, 0xad, 0xfe, 0x04,
- 0x8c, 0x29, 0xdb, 0xbc, 0x78, 0x3d, 0x89, 0x27, 0x2b, 0x61, 0xf4, 0xee,
- 0x53, 0xb2, 0xe9, 0x2a, 0x18, 0xce, 0x4a, 0x25, 0x9b, 0xd2, 0x20, 0x79,
- 0xa3, 0x36, 0x1e, 0x35, 0x8d, 0xec, 0x65, 0xbe, 0xac, 0x4e, 0xde, 0x2e,
- 0x06, 0x95, 0x63, 0x04, 0xf1, 0x6c, 0xfe, 0x7d, 0xcc, 0xfb, 0xa4, 0x86,
- 0x49, 0xed, 0xe4, 0xc0, 0x27, 0xa4, 0x86, 0x05, 0x48, 0x44, 0x15, 0x7b,
- 0xf2, 0x9e, 0xd3, 0x8d, 0x10, 0xf0, 0xb7, 0xf9, 0x70, 0xd1, 0x1c, 0xb6,
- 0xea, 0xb1, 0x16, 0xe7, 0x5b, 0xb9, 0x07, 0xcb, 0x54, 0x44, 0x66, 0x96,
- 0x8e, 0x15, 0xe1, 0x58, 0x11, 0x7c, 0x92, 0x13, 0xa2, 0xd2, 0x36, 0xe2,
- 0x0b, 0x30, 0x19, 0x47, 0x04, 0x57, 0x0a, 0x5b, 0xfc, 0xa8, 0x09, 0x43,
- 0x6d, 0x56, 0xb1, 0x3d, 0xaf, 0x29, 0xdd, 0x79, 0xe8, 0x5e, 0xdb, 0x8c,
- 0x1e, 0xc6, 0x51, 0xc6, 0xc3, 0xba, 0x76, 0x4c, 0x55, 0x36, 0x4e, 0x07,
- 0x50, 0x3d, 0xf5, 0x99, 0x78, 0x9f, 0x7a, 0xf8, 0xc6, 0xbd, 0xac, 0x17,
- 0xc9, 0x00, 0xaa, 0xdc, 0xb9, 0x85, 0xf8, 0xb8, 0xad, 0x0e, 0x17, 0x39,
- 0x5f, 0xf4, 0x2f, 0x03, 0xf0, 0x4e, 0x05, 0xe0, 0x9b, 0x52, 0x30, 0xd3,
- 0x1e, 0x80, 0x67, 0x46, 0xfe, 0x56, 0x10, 0x30, 0xa7, 0xb1, 0x5d, 0x6f,
- 0xc0, 0x78, 0x9e, 0x45, 0xda, 0xfc, 0x19, 0x06, 0xdc, 0xef, 0x2a, 0x9e,
- 0xca, 0x6b, 0x08, 0x1d, 0x10, 0xa2, 0xd1, 0x16, 0x22, 0x96, 0xf4, 0x60,
- 0xd6, 0x1c, 0x8e, 0x06, 0xb8, 0x8e, 0x61, 0x4b, 0x6a, 0x8e, 0x0f, 0xea,
- 0x8c, 0x91, 0x39, 0xc7, 0xa8, 0x37, 0x4f, 0xa8, 0x4a, 0xef, 0xf4, 0x1e,
- 0xc1, 0x98, 0xfa, 0x1e, 0xf0, 0x0a, 0x51, 0xd3, 0xd6, 0x34, 0x70, 0x9e,
- 0xda, 0x3c, 0x13, 0x8b, 0xf5, 0x0e, 0x29, 0xc0, 0xfa, 0x39, 0x1f, 0xfc,
- 0x53, 0xff, 0xc5, 0x3a, 0x2b, 0x44, 0xe1, 0x5e, 0x81, 0x77, 0xad, 0x6c,
- 0xbc, 0x02, 0x46, 0xea, 0x24, 0xc2, 0xb8, 0xf4, 0xa2, 0x10, 0xdb, 0xdb,
- 0x43, 0x78, 0xcd, 0x32, 0x76, 0x7d, 0xec, 0x15, 0xb8, 0x98, 0xcc, 0x0e,
- 0xd6, 0x53, 0xb7, 0xae, 0x29, 0x51, 0x54, 0xe5, 0x8d, 0xcc, 0x15, 0x85,
- 0x4b, 0x9f, 0x31, 0xf5, 0x9d, 0x4a, 0x10, 0x55, 0x27, 0x82, 0xe8, 0x98,
- 0xf3, 0xa3, 0x62, 0x2a, 0x08, 0xef, 0xa4, 0x79, 0xfd, 0x41, 0xb8, 0xe3,
- 0x58, 0x27, 0xd1, 0x8c, 0x8b, 0x2f, 0x1b, 0xf3, 0xc7, 0x89, 0x93, 0xed,
- 0x88, 0xe2, 0x37, 0x05, 0x13, 0x17, 0x0b, 0x41, 0xa8, 0x27, 0x74, 0xd4,
- 0xbb, 0xf5, 0x4e, 0x47, 0xb5, 0xe9, 0x61, 0x5e, 0x1c, 0xe5, 0x61, 0xb7,
- 0x9e, 0x74, 0xf1, 0xd3, 0xa3, 0x74, 0xb0, 0xae, 0x6c, 0x98, 0x26, 0x95,
- 0xf9, 0xec, 0x9c, 0x75, 0x43, 0xec, 0x8f, 0xa5, 0x59, 0x47, 0x2a, 0xe0,
- 0xb3, 0xd7, 0xb1, 0x8e, 0xb0, 0x38, 0xb9, 0xba, 0x5f, 0xa1, 0xf8, 0xec,
- 0xef, 0x6a, 0x7e, 0x88, 0x9a, 0x5f, 0xfc, 0x3f, 0x35, 0x5f, 0x85, 0x3a,
- 0xe5, 0xc1, 0x98, 0x19, 0xc0, 0x6f, 0xac, 0xa6, 0x73, 0x8d, 0x08, 0x20,
- 0xd5, 0xa6, 0x23, 0x72, 0xc2, 0xc2, 0x8b, 0xdc, 0x5b, 0xdc, 0x71, 0x6b,
- 0x3d, 0x04, 0x76, 0x92, 0x53, 0x15, 0xd4, 0x86, 0xbb, 0x27, 0x82, 0xd4,
- 0x29, 0x55, 0x59, 0x4f, 0x9d, 0xdf, 0x91, 0xbc, 0x21, 0xd2, 0x31, 0x23,
- 0x1e, 0x57, 0x12, 0xa9, 0xbf, 0x43, 0x49, 0x3b, 0x62, 0xd4, 0xd1, 0x05,
- 0x7d, 0x91, 0x83, 0x5d, 0x2e, 0x07, 0x67, 0x62, 0x25, 0xed, 0x58, 0x51,
- 0x28, 0xf1, 0xef, 0x01, 0xea, 0xe7, 0xf5, 0xb6, 0x92, 0x76, 0xbe, 0x4a,
- 0xff, 0xd3, 0xcb, 0xf1, 0x1e, 0x99, 0x36, 0xb2, 0xbd, 0xcc, 0xcf, 0x25,
- 0x62, 0x63, 0x92, 0x19, 0x9c, 0xaf, 0xa5, 0xa6, 0x36, 0x07, 0x18, 0xe3,
- 0x75, 0x71, 0x9a, 0xde, 0x62, 0x98, 0xfd, 0x46, 0xf3, 0x46, 0x74, 0x98,
- 0x7c, 0x1f, 0x2d, 0x6b, 0xe9, 0x30, 0xfd, 0xc4, 0x28, 0xf3, 0xf4, 0x36,
- 0x9f, 0x9d, 0xcc, 0x1b, 0xe9, 0x2e, 0x57, 0x53, 0xa5, 0xaf, 0x90, 0x31,
- 0x49, 0x6f, 0x11, 0xc1, 0x5b, 0x2d, 0x52, 0x5f, 0x1b, 0xa8, 0xaf, 0x8b,
- 0xba, 0x2a, 0xf1, 0x70, 0x4d, 0x84, 0x5a, 0x42, 0x5e, 0xc9, 0xcb, 0x4b,
- 0x49, 0x21, 0xaa, 0xec, 0x20, 0x2a, 0x27, 0xcc, 0xf4, 0x7a, 0x25, 0x16,
- 0x31, 0x95, 0xbb, 0xd8, 0xce, 0x1c, 0xce, 0x6d, 0xf2, 0xba, 0xde, 0xf6,
- 0x84, 0x10, 0x21, 0x5b, 0x47, 0xcd, 0x84, 0x49, 0xdc, 0xc4, 0xfa, 0x8e,
- 0xb8, 0xcf, 0x75, 0x04, 0xe7, 0x16, 0xc8, 0xe7, 0x08, 0xf9, 0x1c, 0xc6,
- 0x9b, 0xb7, 0x70, 0x9a, 0x5a, 0xeb, 0xe9, 0x27, 0xa7, 0xb3, 0xe1, 0xa1,
- 0x2d, 0xde, 0x6f, 0xf1, 0x71, 0xbf, 0xe4, 0x34, 0xdb, 0xbc, 0x78, 0x21,
- 0x89, 0xcd, 0xc4, 0x47, 0xe6, 0x29, 0x25, 0xeb, 0x90, 0xdb, 0xa9, 0x0a,
- 0x25, 0x4b, 0x17, 0xf5, 0x0d, 0xa7, 0xcf, 0xf0, 0x6d, 0x2f, 0x39, 0xdd,
- 0x17, 0xbe, 0x95, 0xd3, 0x2c, 0xbe, 0xcc, 0xf7, 0x33, 0xf9, 0x83, 0x98,
- 0xf1, 0xf9, 0x11, 0x99, 0xf2, 0x21, 0x30, 0xa5, 0x92, 0x5f, 0x0a, 0xfd,
- 0x41, 0x36, 0x1e, 0x80, 0x91, 0x3e, 0x89, 0x08, 0x12, 0x13, 0x1a, 0xfe,
- 0xaa, 0xc5, 0x87, 0x63, 0x31, 0x23, 0xb3, 0x93, 0x3c, 0x5d, 0x39, 0x37,
- 0xc4, 0x88, 0x8c, 0x68, 0xd4, 0x53, 0xe2, 0xab, 0xaf, 0xd9, 0x0f, 0x6d,
- 0xca, 0xe5, 0xe0, 0x1e, 0x8f, 0x9d, 0x8d, 0x6a, 0x30, 0x76, 0xfd, 0x84,
- 0xb8, 0xb8, 0x30, 0x21, 0x44, 0x67, 0xbb, 0x79, 0xee, 0x23, 0xaf, 0x41,
- 0x2d, 0x54, 0x71, 0x7e, 0xae, 0x34, 0x7e, 0xd5, 0x94, 0x06, 0xff, 0x01,
- 0x77, 0xfc, 0xeb, 0x6f, 0x32, 0x8a, 0xcf, 0xf3, 0x12, 0x9f, 0x42, 0x04,
- 0x6c, 0x33, 0x32, 0x4b, 0x3d, 0xdc, 0x97, 0x34, 0xb8, 0x7f, 0x4d, 0x4e,
- 0x33, 0xbf, 0x7b, 0x92, 0xb1, 0xe8, 0x16, 0xbe, 0x73, 0xa9, 0x58, 0xe2,
- 0x70, 0xbd, 0xb9, 0x15, 0x7f, 0xa3, 0x7b, 0x51, 0x63, 0xfe, 0x10, 0xcf,
- 0xba, 0x1a, 0x45, 0xec, 0x4f, 0x56, 0xa2, 0x91, 0x98, 0x7f, 0x82, 0x98,
- 0xdf, 0x3c, 0x4b, 0xad, 0x99, 0x6a, 0x67, 0x7e, 0x25, 0xdf, 0xbb, 0x94,
- 0xde, 0xd9, 0x1e, 0xd7, 0x57, 0x3d, 0x32, 0xed, 0xc1, 0x9b, 0xd6, 0x5a,
- 0x7a, 0x98, 0xb4, 0xf2, 0xc8, 0xac, 0xc4, 0xfb, 0x3a, 0xe5, 0x41, 0x62,
- 0x3f, 0x7a, 0x87, 0x8a, 0x19, 0x6b, 0xad, 0xe2, 0x77, 0xb1, 0xef, 0x83,
- 0x93, 0x29, 0xe1, 0xde, 0x6b, 0xc7, 0xac, 0x53, 0x4b, 0x70, 0xdf, 0x73,
- 0x1b, 0xaf, 0x23, 0xb5, 0x03, 0x25, 0x7d, 0xd7, 0xbb, 0x98, 0xaf, 0xe7,
- 0xcb, 0xf8, 0x7e, 0x96, 0xed, 0xbe, 0x29, 0x68, 0x95, 0xc4, 0xf0, 0x3a,
- 0x62, 0x7c, 0x92, 0x38, 0x79, 0x78, 0x5a, 0xe0, 0x0d, 0xd6, 0x89, 0x42,
- 0xd2, 0xb0, 0x76, 0x2a, 0x46, 0xba, 0x47, 0x49, 0x64, 0x57, 0x96, 0x6b,
- 0xe4, 0xdd, 0xac, 0x73, 0xb8, 0x43, 0xe0, 0xe7, 0x16, 0xb4, 0x00, 0xb1,
- 0xfd, 0x6f, 0xac, 0x59, 0xff, 0x51, 0xae, 0x91, 0xc9, 0x42, 0x25, 0x42,
- 0x2d, 0xd4, 0x7c, 0x62, 0xb9, 0x9b, 0x58, 0x3e, 0x44, 0x3e, 0x8c, 0xd0,
- 0x13, 0x6c, 0x26, 0x96, 0x57, 0xb4, 0x19, 0xd9, 0x2e, 0xfa, 0x69, 0xcf,
- 0xea, 0x08, 0x71, 0x1a, 0xa7, 0x87, 0x1d, 0x41, 0x07, 0xe7, 0x4a, 0x4f,
- 0x1b, 0x91, 0x0e, 0xe2, 0x5f, 0x65, 0x9f, 0xd7, 0xd8, 0x67, 0xa1, 0x4e,
- 0x7a, 0xed, 0x00, 0x5e, 0x60, 0x1f, 0x33, 0xe9, 0xb8, 0x3a, 0x21, 0xf1,
- 0x3f, 0x86, 0x44, 0x46, 0xe2, 0xdf, 0x59, 0xd6, 0x4a, 0xdf, 0x2f, 0xf1,
- 0x4f, 0x0c, 0xe6, 0x89, 0xc1, 0x12, 0x07, 0x06, 0x24, 0x07, 0x6a, 0xe8,
- 0x2b, 0x4e, 0xd0, 0x57, 0x54, 0xd9, 0x51, 0xe2, 0x5f, 0xf2, 0xa1, 0xe4,
- 0x2d, 0xba, 0xca, 0x1c, 0x58, 0xef, 0xce, 0x27, 0x35, 0x20, 0x88, 0xa6,
- 0x49, 0x43, 0x57, 0x95, 0xff, 0x14, 0x4f, 0x98, 0xe6, 0xfc, 0x76, 0xfa,
- 0x83, 0x2f, 0xdb, 0x62, 0xcc, 0x7b, 0x10, 0xf7, 0x9c, 0x08, 0xa9, 0x12,
- 0xe7, 0xf5, 0x93, 0x41, 0x84, 0x26, 0x25, 0x0f, 0xb2, 0xe3, 0x11, 0x62,
- 0xc4, 0xf2, 0xfc, 0x96, 0xf8, 0x8f, 0x12, 0x17, 0xaa, 0xd2, 0xcd, 0x31,
- 0x6a, 0xa6, 0x74, 0xb4, 0x4e, 0x1a, 0x03, 0x27, 0x70, 0x55, 0xbc, 0x11,
- 0x33, 0x33, 0x7b, 0x99, 0xff, 0x6d, 0xc9, 0x18, 0xf7, 0x4a, 0xc7, 0xdd,
- 0x37, 0xc7, 0x70, 0x39, 0xe1, 0x6c, 0xb1, 0x82, 0x65, 0xaf, 0xad, 0x61,
- 0x4b, 0x1e, 0xd8, 0x96, 0xa7, 0xd9, 0x35, 0x3d, 0xab, 0xfc, 0xb8, 0x86,
- 0xc3, 0x44, 0x7f, 0xbf, 0xee, 0x30, 0xff, 0x01, 0xea, 0x7d, 0xe9, 0x9d,
- 0x92, 0x07, 0xff, 0x79, 0xf9, 0x8c, 0xf9, 0x2b, 0x4f, 0xe9, 0xef, 0xdb,
- 0xde, 0xc5, 0x33, 0xe7, 0x16, 0x62, 0xb0, 0x93, 0x18, 0xec, 0x61, 0x8e,
- 0xb6, 0x5b, 0xe4, 0x36, 0xf3, 0x99, 0x55, 0x03, 0xf4, 0xd4, 0x4d, 0x7d,
- 0xd5, 0xd4, 0xb4, 0x7d, 0xd4, 0xa7, 0x77, 0xcd, 0x4a, 0x7a, 0x70, 0x87,
- 0xda, 0xd9, 0x41, 0xdd, 0xec, 0x52, 0x1e, 0x72, 0xb1, 0x95, 0x26, 0x8e,
- 0x34, 0x25, 0x4d, 0x5f, 0xeb, 0x63, 0xed, 0x38, 0x14, 0x5e, 0xf4, 0xdf,
- 0x32, 0x4e, 0xe9, 0xb9, 0x8d, 0xb8, 0x2c, 0xbf, 0xcf, 0xba, 0x3a, 0xb4,
- 0x16, 0xaa, 0xbd, 0x56, 0x51, 0x6d, 0x79, 0xc6, 0x50, 0xf1, 0x03, 0xea,
- 0xec, 0xc2, 0x26, 0x79, 0xd6, 0xe0, 0xba, 0xd8, 0x16, 0x31, 0x63, 0xd1,
- 0x83, 0xc4, 0xd5, 0xab, 0xdf, 0x39, 0x7b, 0x94, 0xf0, 0x36, 0x9c, 0x57,
- 0x6f, 0xfa, 0x68, 0xa9, 0x0f, 0x6b, 0x6f, 0xe2, 0x4d, 0xc3, 0x33, 0x2d,
- 0x51, 0xe2, 0x51, 0x62, 0x4d, 0x43, 0xe1, 0x95, 0x4a, 0xbc, 0xf1, 0x4a,
- 0x10, 0xaf, 0xbf, 0x22, 0xc4, 0x68, 0x12, 0x3c, 0xe1, 0x08, 0xf1, 0x50,
- 0x72, 0x0d, 0x8e, 0xeb, 0xb1, 0xe8, 0x0b, 0xae, 0x8f, 0x75, 0xe8, 0x63,
- 0x8d, 0x81, 0xb3, 0xb8, 0x21, 0x0a, 0x2e, 0xa7, 0x13, 0xe4, 0x5b, 0x09,
- 0x8b, 0xae, 0xdf, 0xad, 0xd5, 0x70, 0x81, 0xf8, 0x0b, 0x11, 0x7f, 0xbf,
- 0xa3, 0xe6, 0x5e, 0x2d, 0x6b, 0xee, 0xaa, 0x02, 0xf9, 0xd8, 0x16, 0x40,
- 0x8f, 0x5c, 0x0b, 0x71, 0x38, 0x7c, 0x13, 0x87, 0xac, 0xbd, 0xdc, 0xf3,
- 0xb3, 0x96, 0x11, 0xef, 0x24, 0x1e, 0x67, 0x2c, 0xc3, 0xe9, 0xa0, 0x9f,
- 0x1d, 0x76, 0x31, 0x49, 0xed, 0x8d, 0x49, 0x5c, 0x12, 0x87, 0xcc, 0xc9,
- 0x3e, 0xf6, 0x39, 0xcd, 0x3e, 0x63, 0x65, 0x3f, 0xfb, 0x1e, 0x12, 0x69,
- 0xe9, 0x67, 0xa3, 0xc4, 0xe0, 0x3e, 0xd7, 0xcf, 0x4a, 0xff, 0x2a, 0xbd,
- 0xab, 0x8c, 0xb3, 0xdd, 0x8d, 0xb3, 0xfb, 0x26, 0x0e, 0xa9, 0x61, 0xb5,
- 0x12, 0x7f, 0x0f, 0x60, 0xec, 0xa5, 0x1a, 0x84, 0xcc, 0x3b, 0x71, 0x3e,
- 0xf3, 0x80, 0x1a, 0x31, 0xa1, 0xd7, 0xdb, 0x25, 0x3c, 0x6e, 0x2e, 0xa6,
- 0x90, 0xcf, 0xbf, 0x23, 0xf2, 0x61, 0xc3, 0x39, 0xeb, 0x7a, 0xd2, 0x01,
- 0x7a, 0xc4, 0x1b, 0xc2, 0x13, 0x33, 0xce, 0x6d, 0xa1, 0x2f, 0x6b, 0xf2,
- 0x96, 0xfc, 0xdd, 0x9a, 0xc2, 0xfb, 0x02, 0x75, 0xa5, 0x75, 0xaa, 0xf4,
- 0x74, 0x23, 0xe4, 0xdc, 0xa8, 0x59, 0xf2, 0x77, 0xb1, 0xc2, 0xa7, 0xaa,
- 0xd4, 0x73, 0x4f, 0x9b, 0x1c, 0x37, 0x4d, 0x0d, 0x59, 0x1c, 0xfb, 0x1b,
- 0x5d, 0x1e, 0x21, 0x06, 0x87, 0xa5, 0xd7, 0xa2, 0x2f, 0xe1, 0x59, 0x7d,
- 0x89, 0xa6, 0xee, 0xf6, 0xc2, 0x94, 0x6d, 0x8e, 0xf2, 0x10, 0xd7, 0xa0,
- 0x99, 0x83, 0x4a, 0x9a, 0xb5, 0x79, 0x2f, 0xf1, 0xd5, 0xc3, 0x1a, 0x7c,
- 0xd9, 0x6a, 0x26, 0x87, 0x05, 0xeb, 0xd0, 0x0d, 0xb1, 0xcf, 0x5c, 0x3c,
- 0xd3, 0xc9, 0xf3, 0x5c, 0x9c, 0x71, 0x57, 0xb3, 0x76, 0xaf, 0x63, 0xbd,
- 0xe6, 0x69, 0x91, 0x39, 0xfd, 0x32, 0x26, 0x1a, 0x57, 0xb5, 0x19, 0x03,
- 0x1b, 0xbd, 0x01, 0xe4, 0x88, 0xf7, 0x57, 0x59, 0x83, 0xf2, 0xdc, 0xd3,
- 0xc9, 0xa2, 0x91, 0xca, 0x62, 0x04, 0x1b, 0xb9, 0xa7, 0x3c, 0x03, 0x39,
- 0xff, 0x18, 0x2b, 0x9d, 0x91, 0xb7, 0xb3, 0xb6, 0x8d, 0x97, 0xb9, 0x7d,
- 0x05, 0x09, 0x4b, 0x72, 0x7b, 0x9e, 0xb5, 0x6d, 0xdc, 0xe5, 0xb6, 0x91,
- 0x92, 0x7c, 0xae, 0x28, 0xd7, 0xb4, 0x4f, 0x20, 0x39, 0x7c, 0x6b, 0x3d,
- 0x93, 0x78, 0x5e, 0xeb, 0x93, 0xde, 0x36, 0x9f, 0x97, 0x35, 0x49, 0xd6,
- 0xa2, 0xc5, 0xba, 0xa4, 0xc9, 0xfb, 0x84, 0x4c, 0xe3, 0xc4, 0x1e, 0xe1,
- 0x29, 0xdd, 0x49, 0x9c, 0xfb, 0xd0, 0x1b, 0x4c, 0xa5, 0xee, 0x43, 0x26,
- 0x32, 0xa7, 0x61, 0x53, 0xbe, 0xa1, 0x2f, 0x60, 0x83, 0xef, 0x28, 0xb0,
- 0xfe, 0x44, 0x43, 0xe6, 0x96, 0x3b, 0x89, 0x8f, 0x73, 0x9a, 0x16, 0x9a,
- 0x58, 0x2e, 0xdf, 0xc1, 0x67, 0xb9, 0xdb, 0xde, 0x49, 0xa4, 0x7f, 0xdf,
- 0x9d, 0xc4, 0x0b, 0xe4, 0xc7, 0x58, 0xe9, 0x4e, 0xc2, 0xf9, 0x5e, 0x8b,
- 0x17, 0x33, 0x61, 0xec, 0xfe, 0xa8, 0x5d, 0xc5, 0xe5, 0x9c, 0x11, 0x39,
- 0x8e, 0xdd, 0xe8, 0x77, 0xef, 0x1f, 0x90, 0xf5, 0xdb, 0xbb, 0xf0, 0x4f,
- 0xed, 0xf2, 0xfe, 0x21, 0x25, 0xd7, 0x38, 0xce, 0xe5, 0x43, 0xa3, 0xde,
- 0xac, 0x67, 0x2d, 0xd8, 0xb1, 0x46, 0xc1, 0x43, 0xc9, 0x3b, 0x5d, 0x6c,
- 0x8f, 0x17, 0x8d, 0x74, 0x94, 0xcf, 0xee, 0x99, 0x90, 0x35, 0xf2, 0x71,
- 0x9e, 0x17, 0xa1, 0x35, 0xda, 0xbd, 0xaa, 0xc8, 0x37, 0x45, 0xae, 0x28,
- 0x86, 0x73, 0x18, 0xf2, 0x8e, 0x20, 0x71, 0xce, 0xab, 0x18, 0xf3, 0x1f,
- 0x7a, 0x8d, 0x54, 0xbd, 0x8b, 0x99, 0xc7, 0x79, 0x76, 0x93, 0x7f, 0x7b,
- 0xe5, 0xb9, 0x0f, 0x1b, 0x39, 0xe6, 0x07, 0x6b, 0xe4, 0x59, 0xf4, 0x73,
- 0x91, 0x5d, 0x66, 0x38, 0x0b, 0x8a, 0xc6, 0xdc, 0x80, 0xfa, 0x24, 0x35,
- 0xfc, 0x71, 0x6a, 0xb8, 0xf4, 0x2c, 0xbd, 0xf4, 0x2c, 0x4d, 0xf3, 0x71,
- 0xaf, 0x91, 0xb9, 0x4e, 0xbd, 0xe3, 0x98, 0x7d, 0xbd, 0x8a, 0xd1, 0x7b,
- 0x82, 0xfa, 0xbf, 0x53, 0x29, 0x8d, 0xb9, 0xb2, 0x3c, 0xe6, 0xdd, 0x05,
- 0x4d, 0xe9, 0xcc, 0x83, 0xba, 0x83, 0xe8, 0x36, 0x8b, 0xda, 0x51, 0xac,
- 0x24, 0xc7, 0x4c, 0xb9, 0x66, 0xc6, 0xd6, 0xca, 0xd8, 0x14, 0x5c, 0x69,
- 0x91, 0xef, 0xb6, 0xca, 0x38, 0x9c, 0x2a, 0x3b, 0x45, 0xed, 0x7d, 0xc5,
- 0x57, 0xd6, 0x2f, 0xcf, 0x16, 0x6b, 0x19, 0x9c, 0x30, 0x42, 0x3e, 0xb3,
- 0x0e, 0xa3, 0xb4, 0x81, 0x41, 0xb3, 0x19, 0x39, 0xdd, 0x8f, 0x2d, 0xd6,
- 0x17, 0x82, 0x3a, 0xc9, 0xf7, 0x81, 0xa7, 0x5e, 0xe2, 0x19, 0xde, 0xbc,
- 0x86, 0x58, 0xf2, 0x39, 0x1c, 0xd3, 0x77, 0xd1, 0x0f, 0x6e, 0xc5, 0xeb,
- 0xae, 0x9e, 0xd8, 0xc4, 0xb3, 0x42, 0x0c, 0xd9, 0xb2, 0xd6, 0xdd, 0x32,
- 0xb6, 0xbc, 0x93, 0xb8, 0x24, 0xb2, 0xa5, 0x31, 0x9c, 0x6d, 0x56, 0x86,
- 0x71, 0x7d, 0xa3, 0xbb, 0x3b, 0xa8, 0xbb, 0x15, 0xa6, 0xe7, 0xae, 0x4a,
- 0xea, 0xee, 0x56, 0xeb, 0xcf, 0xf1, 0x14, 0x39, 0x5e, 0x65, 0x7e, 0x26,
- 0x9e, 0x0e, 0xcb, 0x31, 0xa9, 0xaf, 0x35, 0x4b, 0xc7, 0xff, 0x90, 0x63,
- 0xca, 0x39, 0x64, 0x3d, 0x3c, 0x2f, 0x0e, 0xd5, 0xca, 0x31, 0x07, 0x95,
- 0x8d, 0xe4, 0xd4, 0x3c, 0x4b, 0xef, 0x0f, 0xc8, 0xa7, 0x05, 0xe6, 0xa7,
- 0xf1, 0x36, 0x7c, 0x6a, 0x24, 0x9f, 0x9e, 0x58, 0xc2, 0xa7, 0x83, 0x79,
- 0xe9, 0xbd, 0x14, 0xb4, 0xb4, 0xfd, 0x29, 0x75, 0x45, 0x08, 0x7f, 0xdb,
- 0x0d, 0x71, 0xc6, 0xf5, 0xbe, 0xd2, 0xef, 0xa6, 0x95, 0xee, 0x59, 0xa9,
- 0x4f, 0xd5, 0x08, 0x92, 0x4f, 0x1b, 0xc8, 0xa7, 0x7e, 0xf2, 0xe9, 0x69,
- 0x53, 0x34, 0xee, 0x48, 0x1a, 0xa9, 0x79, 0xfa, 0x9a, 0x75, 0xe4, 0xd4,
- 0x3b, 0xe4, 0xd4, 0x48, 0xb1, 0xa4, 0x53, 0xfb, 0xb8, 0xee, 0xfb, 0xa9,
- 0x53, 0xeb, 0x8a, 0x52, 0xdb, 0x1c, 0xe2, 0x3f, 0x80, 0xcf, 0xc9, 0xa9,
- 0xd9, 0xa4, 0xab, 0x53, 0xd6, 0xef, 0x90, 0xd8, 0x75, 0x5a, 0xf2, 0x89,
- 0x3a, 0x95, 0x2f, 0x36, 0x59, 0xa7, 0xb9, 0xa6, 0xf1, 0xbc, 0x71, 0xbd,
- 0x87, 0x9c, 0xf2, 0xb5, 0x1b, 0xe7, 0x2e, 0x13, 0xbb, 0x81, 0x18, 0xf4,
- 0x88, 0x2d, 0xd7, 0xc4, 0x1a, 0xcb, 0x3a, 0x79, 0x90, 0xf8, 0xef, 0xa1,
- 0x66, 0xf4, 0x16, 0x6d, 0xec, 0x2d, 0x2e, 0xdd, 0x53, 0xd6, 0xa1, 0xdb,
- 0xee, 0xcb, 0xb8, 0xff, 0xf6, 0xed, 0xac, 0x57, 0xb7, 0x6d, 0x97, 0x7c,
- 0x5d, 0xe6, 0x97, 0x7c, 0x1d, 0xce, 0xbf, 0xa6, 0xde, 0xfe, 0x1d, 0x79,
- 0xa7, 0x26, 0xc4, 0x51, 0x4b, 0xde, 0x49, 0x48, 0xdf, 0xa3, 0x60, 0xc8,
- 0x92, 0xf7, 0x6a, 0x1d, 0x51, 0x15, 0x46, 0xe4, 0xfb, 0xf8, 0x4a, 0x64,
- 0xc3, 0x4e, 0xdc, 0xe7, 0xd6, 0x48, 0x43, 0xef, 0x63, 0xad, 0x9b, 0x2f,
- 0x9f, 0xfd, 0x66, 0x78, 0x3e, 0x7b, 0x87, 0x75, 0xea, 0x28, 0xcf, 0x79,
- 0x43, 0x85, 0xaf, 0xc4, 0x7c, 0x58, 0xc5, 0x88, 0x79, 0xf3, 0x8e, 0xd2,
- 0xd5, 0xb1, 0xc3, 0x7c, 0x36, 0x56, 0x58, 0xac, 0x51, 0xd4, 0x4c, 0x53,
- 0x88, 0xad, 0xe6, 0x7f, 0x8b, 0x2d, 0xdf, 0x7a, 0x57, 0x88, 0x49, 0xc6,
- 0x70, 0xc1, 0xc2, 0x6e, 0x1f, 0x62, 0x7d, 0xd7, 0x59, 0xd7, 0x3f, 0x58,
- 0x63, 0x64, 0x0a, 0x4a, 0xa2, 0x77, 0x83, 0x22, 0xbd, 0x9e, 0xa7, 0xab,
- 0x82, 0xef, 0xb4, 0xd0, 0x1b, 0x5d, 0x61, 0x06, 0xfd, 0xfc, 0x7e, 0xc6,
- 0x32, 0x22, 0x47, 0xf8, 0x77, 0x4b, 0x4a, 0x8e, 0x21, 0x44, 0x87, 0x25,
- 0xef, 0xbb, 0x46, 0xd4, 0xdc, 0x44, 0x56, 0x54, 0x99, 0x17, 0xa8, 0x4d,
- 0x46, 0x66, 0x44, 0x91, 0x3e, 0x3b, 0x0a, 0x57, 0x67, 0xf9, 0x4c, 0x9b,
- 0x88, 0xe0, 0xef, 0x5d, 0xff, 0x1c, 0xa5, 0x66, 0x35, 0xe0, 0x1f, 0x5c,
- 0xdd, 0x52, 0xb1, 0xed, 0x25, 0x23, 0xa5, 0x2a, 0x7b, 0x70, 0xc9, 0x32,
- 0xf4, 0x9f, 0x32, 0x6e, 0x6a, 0xcd, 0x8b, 0x9d, 0x3c, 0x3f, 0x71, 0x8e,
- 0x6c, 0x9f, 0xb7, 0x56, 0xd1, 0x58, 0x3b, 0x7e, 0xdc, 0x22, 0x6b, 0xf7,
- 0x2e, 0xf4, 0x34, 0xef, 0xe4, 0x47, 0x45, 0xdd, 0x94, 0xaa, 0x6c, 0xa2,
- 0x27, 0x09, 0x4d, 0x85, 0xb0, 0x7d, 0xb5, 0x10, 0xab, 0x56, 0x3b, 0xf8,
- 0x3c, 0xd9, 0x14, 0x3f, 0xcb, 0x1a, 0x74, 0xa8, 0xd6, 0x48, 0x03, 0xbf,
- 0xc0, 0x66, 0x7a, 0xd9, 0x54, 0x5b, 0x0e, 0xb8, 0x53, 0xae, 0xf1, 0x17,
- 0xe8, 0x94, 0x1e, 0xd8, 0x0a, 0x49, 0xbf, 0xe5, 0xe2, 0xb7, 0x74, 0xaf,
- 0xc4, 0xd4, 0x1d, 0xc8, 0x8a, 0x4a, 0xd3, 0xe8, 0x9b, 0x65, 0xbd, 0xfd,
- 0x20, 0xb6, 0x5c, 0x7f, 0x78, 0x56, 0x7a, 0x60, 0x33, 0xba, 0x5e, 0x11,
- 0xcc, 0xc5, 0xf3, 0xcc, 0x45, 0xcc, 0x09, 0xd2, 0x32, 0xf0, 0xac, 0xe5,
- 0x84, 0x94, 0x41, 0xe5, 0x51, 0xf2, 0xa1, 0xcf, 0x5f, 0x49, 0x0f, 0xe1,
- 0xd0, 0x3f, 0x78, 0x50, 0x7d, 0x40, 0x7a, 0x8a, 0x00, 0xb5, 0xa6, 0xa9,
- 0x37, 0xc8, 0xfc, 0xec, 0x48, 0x4a, 0xff, 0x41, 0xac, 0x1f, 0xb8, 0x21,
- 0x3a, 0xe9, 0x71, 0x3b, 0xcb, 0x1e, 0xf7, 0x89, 0xe9, 0x34, 0x3d, 0xb0,
- 0xa6, 0xc8, 0x3b, 0xb6, 0x54, 0x1b, 0x0f, 0xa4, 0x8f, 0x4a, 0x1f, 0x22,
- 0xd7, 0xa0, 0xe3, 0x6a, 0x52, 0x62, 0x57, 0xc7, 0x70, 0xbb, 0x11, 0xc9,
- 0x42, 0xde, 0xe9, 0xdc, 0xea, 0x2f, 0xa0, 0xa7, 0xbf, 0xe3, 0x39, 0xa0,
- 0x6f, 0x62, 0x2c, 0x86, 0x5f, 0x88, 0xba, 0xa4, 0x17, 0x7d, 0xee, 0x59,
- 0x2e, 0xa2, 0xa7, 0xc9, 0xfb, 0x73, 0xf4, 0x09, 0x5e, 0x9e, 0x99, 0xf7,
- 0x10, 0x4b, 0x5f, 0xb6, 0x0c, 0xbd, 0x5a, 0x8f, 0xec, 0x78, 0x1d, 0xcf,
- 0xa8, 0xf7, 0x53, 0x57, 0x2f, 0xe4, 0x1e, 0x65, 0x3d, 0xf7, 0xb4, 0x47,
- 0x78, 0x06, 0x68, 0x9c, 0xca, 0x8a, 0x7a, 0xfa, 0x41, 0x9e, 0x97, 0x51,
- 0xdb, 0x16, 0xa7, 0xdf, 0x5e, 0xdc, 0x2b, 0x0f, 0x7e, 0x68, 0x99, 0x70,
- 0xdc, 0xdf, 0x41, 0xbd, 0x7b, 0x9a, 0xe7, 0x68, 0x73, 0xb9, 0xde, 0x51,
- 0x8a, 0x4b, 0xad, 0xb0, 0x2d, 0xb4, 0xdc, 0x0b, 0xfd, 0xc1, 0xdb, 0xc4,
- 0xb4, 0x4e, 0x7a, 0x1f, 0x5f, 0xa9, 0xdf, 0x9f, 0x4d, 0x37, 0xe8, 0x8f,
- 0xb0, 0xde, 0xcd, 0x13, 0x2b, 0x4f, 0xac, 0xb6, 0x64, 0x2c, 0xf3, 0x32,
- 0x16, 0xfa, 0x4b, 0xe7, 0x7e, 0x0f, 0x7d, 0x49, 0x12, 0x08, 0xcd, 0xfd,
- 0x35, 0x79, 0xe5, 0x69, 0x0d, 0x21, 0xbb, 0x8b, 0x31, 0xbe, 0xfa, 0xaf,
- 0xdc, 0x9a, 0xfe, 0x49, 0xf4, 0x7b, 0xd8, 0x67, 0xc2, 0x02, 0x9e, 0x39,
- 0x01, 0x3c, 0x3d, 0x19, 0xa3, 0x2f, 0xa7, 0x8f, 0x3c, 0xa1, 0xe1, 0xfb,
- 0xd3, 0x95, 0xf8, 0xd1, 0x74, 0x10, 0x3b, 0xa6, 0xdd, 0xbb, 0xae, 0x0d,
- 0x75, 0x7c, 0xaf, 0x83, 0x67, 0xbb, 0x59, 0x6b, 0x35, 0x3e, 0xa2, 0x87,
- 0x5a, 0xa1, 0x78, 0x10, 0x39, 0x00, 0x5d, 0x27, 0x6e, 0x6a, 0x5b, 0x7e,
- 0x44, 0x2e, 0x0b, 0x61, 0xae, 0x96, 0x3a, 0xf9, 0xbc, 0xfb, 0x7d, 0x84,
- 0xfe, 0x31, 0x23, 0x31, 0x98, 0x27, 0x06, 0xf3, 0xc4, 0xe4, 0x4d, 0x4f,
- 0x2d, 0xb1, 0x1c, 0xa7, 0x8f, 0x7e, 0x4e, 0x94, 0xb0, 0xf1, 0xb5, 0x38,
- 0x6a, 0x9e, 0x24, 0x7f, 0x55, 0x6a, 0x28, 0xf0, 0xcf, 0xb9, 0x88, 0xbe,
- 0xa9, 0x28, 0xf3, 0xff, 0xb7, 0xe5, 0xfc, 0x9f, 0xf1, 0x97, 0xf4, 0xc2,
- 0x70, 0x66, 0xd1, 0x80, 0xc9, 0x7c, 0x83, 0xbe, 0x21, 0x3f, 0x34, 0xa8,
- 0x21, 0x1b, 0x0d, 0xc1, 0x18, 0x98, 0x84, 0xa7, 0x35, 0x08, 0xb9, 0x76,
- 0xa0, 0xe0, 0xae, 0x51, 0x88, 0x31, 0xea, 0x9b, 0xcc, 0xc1, 0xbf, 0xe7,
- 0xd0, 0xea, 0x61, 0x3e, 0x1c, 0xc8, 0xb3, 0x35, 0xf0, 0x69, 0x41, 0xde,
- 0x7d, 0xc6, 0xd2, 0xdd, 0xf8, 0xc2, 0x1d, 0xf3, 0x93, 0x42, 0x0a, 0xfb,
- 0xf3, 0x1f, 0x88, 0xfd, 0xe1, 0x92, 0xc6, 0xa7, 0x79, 0x3e, 0x0a, 0x1d,
- 0x28, 0x7b, 0x21, 0x72, 0xb8, 0x9a, 0xeb, 0xbd, 0x9a, 0x74, 0xbd, 0x3f,
- 0x6b, 0xe4, 0x80, 0x7a, 0xd4, 0x64, 0xb1, 0xab, 0xb9, 0x21, 0xc6, 0x62,
- 0x89, 0x40, 0x29, 0xa6, 0x84, 0x7e, 0x04, 0x15, 0xc4, 0xae, 0x3c, 0x23,
- 0x49, 0xfd, 0x90, 0xbf, 0x79, 0x3e, 0x51, 0x9d, 0x88, 0x97, 0xeb, 0x72,
- 0x1e, 0x93, 0x6d, 0x81, 0xb2, 0x5f, 0x5d, 0xf4, 0x22, 0x1d, 0x7c, 0x26,
- 0xbd, 0xc8, 0x57, 0xa2, 0x2f, 0xdc, 0x71, 0x53, 0x73, 0xb2, 0x7c, 0x63,
- 0x34, 0x2f, 0xef, 0xb4, 0x5a, 0xe8, 0x88, 0x15, 0x9c, 0x62, 0xe4, 0x47,
- 0x5a, 0x63, 0xfa, 0x30, 0xc7, 0x73, 0x74, 0x9d, 0x5c, 0xde, 0x43, 0xbf,
- 0xcc, 0x77, 0x8a, 0x2d, 0xec, 0x23, 0xb5, 0xec, 0x2f, 0xb8, 0xd6, 0x2f,
- 0x9a, 0x25, 0xb6, 0x87, 0xf3, 0x6f, 0x79, 0x54, 0x53, 0xae, 0x33, 0x91,
- 0x1a, 0x66, 0x3c, 0x0b, 0xba, 0xf4, 0xd6, 0x0e, 0xb5, 0x2d, 0xe1, 0xf6,
- 0xcf, 0xaa, 0x32, 0x0e, 0x37, 0x1e, 0xb6, 0x49, 0xcd, 0x32, 0x32, 0xa7,
- 0x90, 0x70, 0xfa, 0xa5, 0x39, 0x58, 0x26, 0x63, 0x68, 0x8a, 0xf4, 0x33,
- 0x9e, 0x43, 0x61, 0x57, 0x0f, 0xf9, 0x8c, 0xf3, 0xe5, 0x3d, 0x1b, 0x2a,
- 0x21, 0xb0, 0x22, 0xe9, 0x9e, 0xf9, 0xcb, 0xff, 0x5f, 0x43, 0xa5, 0x0f,
- 0x91, 0x58, 0xfc, 0x5f, 0x69, 0xd7, 0x8a, 0xc0, 0xa8, 0x1a, 0x00, 0x00,
- 0x00 };
+ 0xbd, 0x58, 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xce, 0xbd, 0x77, 0xb5,
+ 0xd7, 0xd2, 0x4a, 0xba, 0xb2, 0xd6, 0x66, 0x5d, 0xdc, 0xfa, 0x1e, 0x74,
+ 0x57, 0x52, 0x58, 0x01, 0x77, 0x6d, 0x01, 0xeb, 0xe6, 0xb6, 0xbe, 0xc8,
+ 0xb2, 0xbc, 0xfe, 0x00, 0xe4, 0xc0, 0x4c, 0xe4, 0x96, 0x8e, 0x37, 0xc6,
+ 0x18, 0xd9, 0x90, 0xa9, 0x28, 0xfc, 0x58, 0x37, 0x4c, 0xbd, 0x95, 0x65,
+ 0x63, 0xc3, 0x4a, 0x6b, 0x0c, 0xb1, 0x4c, 0xda, 0x99, 0x78, 0x84, 0xb1,
+ 0x4c, 0x22, 0x7b, 0x0d, 0xe4, 0x07, 0x49, 0xc3, 0xa0, 0xc1, 0x0e, 0x08,
+ 0x06, 0xf3, 0x31, 0x6d, 0x67, 0x98, 0xe9, 0xa4, 0xf5, 0x18, 0xf3, 0x11,
+ 0x92, 0x18, 0x87, 0x4e, 0x3a, 0xa2, 0x10, 0x9f, 0x3e, 0x67, 0x77, 0xc5,
+ 0x57, 0x32, 0xd3, 0xfe, 0xaa, 0x66, 0x56, 0x7b, 0xf7, 0xec, 0xf9, 0x78,
+ 0xcf, 0xfb, 0x3e, 0xef, 0xf3, 0x3e, 0xef, 0x5e, 0x21, 0x50, 0x8f, 0xda,
+ 0x5f, 0x23, 0x5f, 0xdd, 0xdf, 0x1a, 0xba, 0x2f, 0x7d, 0xf5, 0x75, 0x57,
+ 0xf3, 0xf1, 0x3a, 0xe1, 0xd4, 0x59, 0xf8, 0x7f, 0xfc, 0x33, 0x01, 0x67,
+ 0xce, 0x0e, 0xfd, 0x82, 0x6d, 0x04, 0x85, 0xcb, 0x7b, 0x3c, 0xd8, 0x66,
+ 0x10, 0x77, 0x6f, 0xf7, 0x80, 0x70, 0x2a, 0xe5, 0xae, 0xc4, 0xef, 0x54,
+ 0x21, 0x6e, 0x41, 0x8f, 0xff, 0x71, 0xf0, 0xe9, 0x35, 0xcf, 0x5d, 0x2f,
+ 0x2f, 0x1e, 0x36, 0x61, 0x3b, 0xc1, 0x5e, 0xcb, 0x69, 0x87, 0xbd, 0x98,
+ 0x6b, 0xfe, 0xb1, 0xe3, 0x2f, 0x04, 0x9a, 0xe6, 0xf6, 0x52, 0x6a, 0xc4,
+ 0x8f, 0x62, 0xd8, 0x4f, 0x60, 0x77, 0xc9, 0x40, 0xe8, 0x44, 0xb1, 0xcb,
+ 0x9b, 0x55, 0x5b, 0x7c, 0xe9, 0xef, 0x86, 0x5a, 0x72, 0xda, 0x97, 0x89,
+ 0x5e, 0x13, 0xe1, 0x77, 0xbc, 0xc5, 0xd8, 0x5d, 0x4e, 0x60, 0xa4, 0x6c,
+ 0xe3, 0xac, 0x39, 0x82, 0xde, 0xf2, 0xdc, 0x3a, 0x97, 0xeb, 0x3a, 0xb1,
+ 0xe7, 0xcb, 0x6b, 0xdd, 0xdd, 0x48, 0x25, 0xf6, 0xc0, 0x40, 0x2e, 0xee,
+ 0x71, 0x5d, 0x9b, 0xbb, 0x07, 0xb2, 0x93, 0xfb, 0x14, 0xea, 0xba, 0x5d,
+ 0xee, 0x51, 0xe0, 0x7a, 0xe9, 0x1e, 0x85, 0xde, 0x2b, 0xc3, 0xcf, 0x6f,
+ 0xa9, 0xe7, 0x3a, 0x16, 0xe3, 0x19, 0xee, 0xff, 0x74, 0xd9, 0xc1, 0xc9,
+ 0xb2, 0x87, 0xe7, 0xcb, 0x2e, 0x7e, 0x54, 0x8e, 0xe3, 0xa9, 0xb2, 0x9d,
+ 0xb3, 0x03, 0xf4, 0xc7, 0x47, 0x77, 0xaa, 0x84, 0x87, 0xc2, 0x1f, 0x05,
+ 0xde, 0xa1, 0x43, 0x46, 0x2c, 0xf3, 0x37, 0xd7, 0xa1, 0x7f, 0xfe, 0x71,
+ 0x1b, 0x1b, 0x4a, 0x8b, 0x73, 0xd1, 0x00, 0x9c, 0x23, 0xe0, 0x5f, 0x67,
+ 0xa3, 0x9f, 0x7b, 0x14, 0xb8, 0x7f, 0x58, 0x1e, 0xe1, 0xcb, 0xc6, 0xbb,
+ 0x45, 0xdb, 0x6e, 0x1e, 0x5d, 0xa8, 0xe7, 0xe0, 0x57, 0xc5, 0x8b, 0xea,
+ 0x42, 0xda, 0xc1, 0x2b, 0xcb, 0x95, 0x6a, 0x0c, 0x50, 0x68, 0xe8, 0x2e,
+ 0xc0, 0x0c, 0x64, 0x76, 0x9d, 0x29, 0xd0, 0x7b, 0x95, 0xd7, 0x39, 0x2a,
+ 0x6e, 0xb9, 0xc5, 0x08, 0x60, 0x8b, 0xc0, 0xb5, 0xda, 0xa6, 0x32, 0xd8,
+ 0x57, 0xe6, 0xbd, 0x68, 0xcf, 0x48, 0x19, 0xe1, 0x5f, 0x76, 0x98, 0x98,
+ 0x88, 0xe3, 0xfe, 0xb7, 0xbb, 0x2d, 0x7c, 0x5c, 0x94, 0x89, 0x4e, 0xf3,
+ 0x7e, 0xec, 0x2c, 0xe6, 0x71, 0x47, 0x11, 0x05, 0x23, 0x18, 0xc2, 0x37,
+ 0xba, 0x03, 0xde, 0x33, 0xc4, 0xf7, 0xcb, 0xb0, 0x5b, 0x83, 0xd3, 0x97,
+ 0xdf, 0xdb, 0x2e, 0x0f, 0x87, 0x06, 0x90, 0x1d, 0x03, 0xfa, 0x4a, 0x02,
+ 0xa7, 0x32, 0x02, 0x5b, 0xfc, 0xcb, 0x50, 0x70, 0xba, 0xb1, 0xb7, 0x2c,
+ 0xb3, 0x05, 0x7e, 0x77, 0xd5, 0x28, 0xec, 0x45, 0xc1, 0x6d, 0xd6, 0xf2,
+ 0x12, 0xec, 0x96, 0x60, 0xc0, 0x4a, 0x8f, 0xb5, 0xcd, 0x1e, 0x13, 0x32,
+ 0xbf, 0xc2, 0x94, 0x21, 0x20, 0x33, 0x9d, 0x46, 0xaa, 0xa0, 0x84, 0x1c,
+ 0xba, 0x08, 0x6d, 0xd3, 0x6d, 0xd6, 0x35, 0x53, 0xfa, 0x7d, 0xc0, 0xba,
+ 0x7a, 0x0a, 0x58, 0xcf, 0x3d, 0x1f, 0x5a, 0x2e, 0xb0, 0x3d, 0xfd, 0x6b,
+ 0x15, 0x2e, 0x90, 0xe1, 0x61, 0xd1, 0x8d, 0xd1, 0x32, 0x70, 0xd3, 0x18,
+ 0xec, 0x18, 0xe7, 0x16, 0xb9, 0x77, 0x3d, 0xe7, 0xae, 0x1d, 0x6d, 0x1b,
+ 0x9c, 0x11, 0x92, 0x77, 0x93, 0x03, 0x40, 0xca, 0x3f, 0x0e, 0xe9, 0xae,
+ 0x13, 0xd2, 0xd9, 0x53, 0xdb, 0x33, 0x59, 0xdb, 0xf3, 0x8a, 0x29, 0x5b,
+ 0xac, 0x2a, 0x41, 0xf4, 0x96, 0xe0, 0x3e, 0xe9, 0x83, 0x77, 0x89, 0xf1,
+ 0xde, 0xf5, 0x70, 0x5b, 0xa4, 0x7f, 0x98, 0x73, 0xa3, 0x41, 0x97, 0xf5,
+ 0x5e, 0x51, 0xe0, 0x43, 0x4f, 0xcf, 0xef, 0xd2, 0xb6, 0x84, 0x4e, 0x90,
+ 0x11, 0xfd, 0xe5, 0xfd, 0x73, 0x39, 0x62, 0x9c, 0xf4, 0xe3, 0xc0, 0x42,
+ 0x34, 0xb7, 0x78, 0xf3, 0xf1, 0xb0, 0x83, 0xc6, 0xa8, 0xb7, 0xcc, 0x78,
+ 0xc0, 0xa9, 0xc3, 0x49, 0xff, 0xb7, 0x0a, 0xdf, 0xd0, 0xf3, 0x81, 0x6f,
+ 0x3f, 0xe2, 0x20, 0xe6, 0x5d, 0xc4, 0xd1, 0xf4, 0x36, 0xe3, 0x55, 0x67,
+ 0x08, 0x4d, 0xde, 0xcf, 0x8d, 0xd7, 0x9c, 0x38, 0x1e, 0xe2, 0x7d, 0xee,
+ 0x4c, 0xc6, 0xf1, 0x40, 0xf9, 0xab, 0xfb, 0x5a, 0x22, 0x3b, 0xfe, 0x8e,
+ 0x42, 0x4b, 0x65, 0x7d, 0xf8, 0xac, 0x3f, 0x01, 0x5c, 0xa6, 0xc7, 0xf3,
+ 0x62, 0x63, 0xe9, 0x92, 0x72, 0xa3, 0x19, 0x3c, 0x50, 0xb2, 0x31, 0x8f,
+ 0x76, 0x45, 0x3c, 0x1b, 0x6f, 0x17, 0xf3, 0x62, 0x55, 0x39, 0x14, 0x6b,
+ 0x26, 0x7b, 0x44, 0x38, 0x69, 0x89, 0x9e, 0x71, 0x10, 0x9b, 0x4a, 0xad,
+ 0xf1, 0x05, 0xfe, 0xc3, 0xff, 0x57, 0xe3, 0x6c, 0xab, 0x0c, 0x5d, 0x71,
+ 0x49, 0x79, 0x49, 0x03, 0xf5, 0x5e, 0x9f, 0x58, 0x3b, 0xa9, 0xd4, 0x5e,
+ 0x3f, 0x2b, 0x7a, 0x27, 0x61, 0x37, 0x04, 0x81, 0x75, 0xd7, 0xe8, 0x69,
+ 0x23, 0xb7, 0x20, 0x86, 0x52, 0xc9, 0xc5, 0x29, 0x5f, 0xe3, 0x77, 0x1e,
+ 0x2c, 0x4f, 0xf0, 0x85, 0xd8, 0x19, 0x1f, 0x56, 0x8c, 0xcf, 0x53, 0x1b,
+ 0x2c, 0x8c, 0x74, 0xaf, 0xad, 0xac, 0x89, 0x10, 0x2b, 0x4f, 0x14, 0xb3,
+ 0x30, 0x88, 0xbf, 0x45, 0x41, 0x72, 0x76, 0x82, 0x98, 0x7f, 0xcb, 0x4f,
+ 0x76, 0x7e, 0x6c, 0x92, 0x1c, 0x5a, 0x65, 0x82, 0x86, 0x0a, 0x2b, 0x48,
+ 0x76, 0x1e, 0x81, 0x80, 0xe9, 0x59, 0x78, 0xc5, 0x8f, 0x20, 0xdc, 0x60,
+ 0x63, 0x17, 0x71, 0x55, 0xc7, 0xf1, 0xa3, 0x95, 0x71, 0xfd, 0x19, 0xce,
+ 0xaa, 0xf2, 0x57, 0x73, 0x9e, 0xe3, 0xa5, 0x36, 0xe4, 0x2a, 0x79, 0x0f,
+ 0x67, 0x1d, 0xef, 0xfb, 0xad, 0x88, 0x7e, 0xfc, 0x93, 0xcf, 0xc6, 0x6e,
+ 0xa4, 0x9d, 0x66, 0xe0, 0xe5, 0x1e, 0x17, 0x8b, 0x50, 0x68, 0x01, 0xed,
+ 0x36, 0x70, 0x21, 0xbd, 0x10, 0xd3, 0x2d, 0xfa, 0xeb, 0xb8, 0xd3, 0x3f,
+ 0xde, 0xaa, 0x63, 0xa2, 0xf7, 0x72, 0x56, 0x8d, 0x2b, 0xf5, 0xbc, 0x5f,
+ 0x87, 0xd9, 0x8e, 0xe1, 0x19, 0x66, 0x89, 0xbf, 0x88, 0x39, 0xf9, 0x12,
+ 0xcf, 0x6f, 0x59, 0x66, 0xc2, 0x5c, 0xe6, 0x9a, 0xee, 0x7c, 0x60, 0xa2,
+ 0xa8, 0x39, 0x41, 0xce, 0xbe, 0xc4, 0xff, 0xe7, 0xca, 0x1a, 0x9f, 0x3e,
+ 0xf1, 0x29, 0xd0, 0xde, 0xa1, 0xe3, 0xee, 0x5b, 0xed, 0xc4, 0xde, 0x76,
+ 0xfa, 0x33, 0xc2, 0x3c, 0x78, 0x90, 0xf6, 0x9e, 0x2b, 0x7e, 0xcf, 0x58,
+ 0xe5, 0x48, 0x57, 0x9f, 0xf0, 0x4e, 0x11, 0xe2, 0x79, 0xff, 0xef, 0xb4,
+ 0x8f, 0x5d, 0x6e, 0x4b, 0xcc, 0xdc, 0x47, 0xcc, 0x68, 0xee, 0x59, 0x6f,
+ 0x39, 0x63, 0x72, 0xe0, 0x7d, 0x1a, 0x91, 0x08, 0x86, 0xac, 0x44, 0x29,
+ 0xb5, 0x77, 0x90, 0xdf, 0xdb, 0x41, 0xd6, 0xb2, 0x47, 0x65, 0x9e, 0xe7,
+ 0xe5, 0x2c, 0x43, 0x26, 0x9a, 0xcd, 0xd4, 0xd0, 0x88, 0x90, 0x83, 0xcd,
+ 0x42, 0xf6, 0xdf, 0x03, 0xe9, 0x9c, 0x10, 0xfa, 0xcc, 0xf5, 0x56, 0x57,
+ 0x05, 0xa3, 0x59, 0x62, 0x54, 0xbf, 0xdf, 0x67, 0xa5, 0x2a, 0xef, 0x43,
+ 0xd6, 0x95, 0x53, 0x09, 0x8c, 0x96, 0xa4, 0xef, 0x8a, 0x28, 0xbe, 0x96,
+ 0xb6, 0x71, 0x22, 0xa9, 0x96, 0xbc, 0x90, 0x96, 0xb9, 0x1e, 0x73, 0x31,
+ 0x73, 0x21, 0x81, 0x61, 0x62, 0xe9, 0x1f, 0x92, 0x23, 0xe8, 0x29, 0x9b,
+ 0xc4, 0xb1, 0x8b, 0xfd, 0xa5, 0x28, 0x66, 0xc8, 0x4f, 0x75, 0xe9, 0x4e,
+ 0x8c, 0x94, 0x64, 0xe7, 0x1b, 0x48, 0xe5, 0x8f, 0x30, 0x5e, 0x67, 0x17,
+ 0x78, 0xd8, 0x5f, 0x6e, 0x63, 0x8c, 0xa4, 0xbb, 0x8a, 0x1c, 0x65, 0x76,
+ 0x4b, 0x67, 0x17, 0x7d, 0x5b, 0x17, 0x90, 0xdb, 0xca, 0x19, 0xee, 0x53,
+ 0xc0, 0xaa, 0x72, 0x5e, 0xf4, 0x95, 0xe7, 0x70, 0xfa, 0x73, 0x62, 0x53,
+ 0x63, 0xd5, 0xc6, 0xe6, 0x12, 0x70, 0x67, 0xc9, 0x47, 0x8b, 0x67, 0xbc,
+ 0x18, 0xc5, 0x45, 0xfa, 0x71, 0x02, 0xf7, 0x38, 0x21, 0x16, 0x79, 0xeb,
+ 0xd4, 0x8e, 0xb8, 0x9e, 0x9f, 0x17, 0x6b, 0x19, 0xb7, 0x30, 0x02, 0x63,
+ 0xd2, 0x37, 0x71, 0x36, 0x3e, 0x3c, 0x3f, 0x52, 0xe1, 0x5d, 0xfd, 0x6e,
+ 0xa2, 0xdf, 0xc7, 0x1a, 0x07, 0x72, 0xc8, 0x17, 0x85, 0xc1, 0x26, 0xfa,
+ 0xe1, 0xa4, 0x28, 0x0c, 0xc4, 0x20, 0x0b, 0xf7, 0x0a, 0x3a, 0x6b, 0x8c,
+ 0x24, 0xb1, 0x60, 0x8e, 0xa7, 0x2d, 0xfc, 0x75, 0xe9, 0x29, 0xe3, 0x5c,
+ 0xa4, 0x0e, 0xe6, 0x81, 0x08, 0xa2, 0x07, 0x2c, 0x34, 0x1f, 0x10, 0xc4,
+ 0x5d, 0xa1, 0x33, 0xaa, 0xd7, 0x21, 0x81, 0x7d, 0xa3, 0x36, 0xee, 0xe9,
+ 0x88, 0xe0, 0x42, 0x52, 0x0e, 0x5e, 0x21, 0x86, 0xfd, 0x26, 0x8e, 0x8d,
+ 0x1e, 0x97, 0xae, 0x6b, 0x14, 0x22, 0x68, 0x8a, 0x23, 0xd2, 0x5e, 0x87,
+ 0x06, 0xae, 0xdb, 0x59, 0x52, 0x3b, 0xed, 0xa0, 0xe0, 0x36, 0x40, 0xfa,
+ 0x0f, 0x73, 0xdf, 0x53, 0x45, 0xa5, 0xea, 0xaf, 0xf5, 0x66, 0x3e, 0x30,
+ 0xe5, 0xf4, 0x0e, 0x7e, 0x7e, 0x6b, 0xaa, 0xba, 0xff, 0xbc, 0x03, 0x36,
+ 0x1a, 0x0f, 0x56, 0xf6, 0x9f, 0x7d, 0x8a, 0x16, 0x7c, 0x58, 0xd2, 0xf9,
+ 0xa4, 0x54, 0x34, 0xf0, 0xfa, 0xdf, 0x13, 0x4a, 0xdd, 0xe4, 0xcb, 0xdc,
+ 0xcb, 0xa2, 0x6d, 0x60, 0x94, 0xcf, 0x83, 0xe9, 0xa4, 0x9b, 0xa5, 0xcd,
+ 0xe7, 0xcb, 0x51, 0xda, 0xc7, 0x5c, 0xf0, 0xb6, 0x19, 0x3b, 0x1c, 0x13,
+ 0x75, 0xde, 0x0e, 0x63, 0x6b, 0x05, 0xab, 0x0e, 0x16, 0x8d, 0xd5, 0x63,
+ 0x89, 0x17, 0x8a, 0x4d, 0xcc, 0xcd, 0x8d, 0x93, 0x16, 0xe7, 0xe9, 0xdc,
+ 0x14, 0x88, 0x7a, 0xbd, 0x62, 0xe5, 0x64, 0x5f, 0x25, 0x5f, 0x07, 0xc6,
+ 0x0d, 0xbc, 0xe9, 0xdf, 0x80, 0x48, 0x90, 0x15, 0x03, 0x93, 0x3a, 0x7f,
+ 0xd6, 0x8a, 0xd5, 0x93, 0x8c, 0xdf, 0x7c, 0x9d, 0x3b, 0x37, 0x88, 0x48,
+ 0xa0, 0xf3, 0xe5, 0xf3, 0x1c, 0xb2, 0x99, 0x43, 0xc7, 0xfe, 0x97, 0x1c,
+ 0x7a, 0xa8, 0x64, 0x21, 0xd7, 0x52, 0xcd, 0x97, 0x5e, 0xc6, 0xe2, 0xef,
+ 0x6b, 0x75, 0x7b, 0x3b, 0xc7, 0xa3, 0x07, 0x74, 0x0e, 0xf7, 0x32, 0x87,
+ 0x35, 0x9e, 0x2d, 0xb1, 0x69, 0x1c, 0x76, 0x73, 0x10, 0x5a, 0x1f, 0x8e,
+ 0x2a, 0xbc, 0xed, 0x2b, 0xf5, 0xf1, 0x32, 0xed, 0x13, 0x39, 0xf8, 0x2c,
+ 0xf1, 0x08, 0x12, 0xd2, 0xbb, 0x9e, 0x52, 0x33, 0x7e, 0x2a, 0xfb, 0x2c,
+ 0x79, 0xf9, 0x9c, 0xd0, 0xf7, 0x8f, 0xc2, 0x49, 0x6b, 0x3c, 0xf6, 0x5a,
+ 0x57, 0x55, 0x70, 0x19, 0x12, 0xaf, 0xac, 0xd5, 0xf3, 0x35, 0x36, 0xa3,
+ 0x68, 0x48, 0xce, 0xd2, 0x37, 0x72, 0xa8, 0x51, 0xa8, 0x25, 0xaf, 0xa6,
+ 0xab, 0xb8, 0x2c, 0xb2, 0x36, 0xad, 0xe7, 0x59, 0xbd, 0xe3, 0xb2, 0xb0,
+ 0xde, 0xac, 0xd6, 0xd1, 0xbd, 0xc4, 0x86, 0xe6, 0xb8, 0xcb, 0xdb, 0xa3,
+ 0xd8, 0x47, 0x8c, 0x7a, 0x69, 0x17, 0xc3, 0xac, 0xab, 0xbb, 0x4b, 0xd2,
+ 0x1d, 0x26, 0x4e, 0x77, 0xd7, 0x70, 0x3a, 0xcc, 0x5a, 0xba, 0x1b, 0x72,
+ 0xaf, 0xae, 0xa5, 0x11, 0xe2, 0x94, 0x34, 0x56, 0xc1, 0xe9, 0x48, 0x0d,
+ 0xa7, 0xbd, 0x15, 0x9c, 0xee, 0x36, 0x34, 0x3e, 0x35, 0xf6, 0x36, 0xf1,
+ 0xbe, 0x67, 0xa3, 0x30, 0x7e, 0xc0, 0xfd, 0xc3, 0x05, 0xc3, 0x3d, 0x35,
+ 0xec, 0xf5, 0x68, 0xec, 0x19, 0x69, 0xdc, 0x63, 0xf0, 0x6e, 0x2f, 0x88,
+ 0x42, 0xae, 0x11, 0x32, 0x3b, 0x2c, 0x0a, 0x9d, 0xf3, 0x88, 0xbd, 0x67,
+ 0x38, 0xa3, 0x81, 0xd8, 0xab, 0xfa, 0x4c, 0xcf, 0x8f, 0x11, 0x7b, 0xff,
+ 0x29, 0xce, 0x46, 0x34, 0xd7, 0xea, 0xd8, 0x02, 0x8b, 0x4e, 0x68, 0xae,
+ 0x8d, 0x92, 0x30, 0x2c, 0xe4, 0x4b, 0xc6, 0xe2, 0x04, 0x14, 0xb6, 0x92,
+ 0xdb, 0xde, 0xf4, 0x76, 0xf9, 0x2d, 0xb8, 0x01, 0xa7, 0xbb, 0x0c, 0x68,
+ 0x1d, 0x62, 0x4e, 0x54, 0xb1, 0x7b, 0x17, 0x39, 0xa3, 0x29, 0x90, 0x9d,
+ 0x67, 0xa9, 0x37, 0xb6, 0xa4, 0x1b, 0x50, 0xf2, 0x86, 0xc3, 0x66, 0x56,
+ 0x43, 0x9b, 0xe7, 0xae, 0x86, 0xae, 0x85, 0x71, 0x58, 0xed, 0x36, 0x1a,
+ 0x8e, 0x7a, 0xb9, 0x13, 0x42, 0xe3, 0x15, 0xe8, 0x3a, 0x6e, 0xd3, 0x7e,
+ 0x38, 0xf5, 0x81, 0x97, 0xf9, 0xc0, 0x7c, 0x5c, 0x9c, 0x75, 0xaa, 0xf5,
+ 0xa0, 0x6f, 0x5c, 0x63, 0xec, 0x57, 0xea, 0x4d, 0xcf, 0xc0, 0x1d, 0xdd,
+ 0x4a, 0x79, 0x4b, 0xa3, 0x88, 0x4c, 0xd8, 0xa8, 0x3b, 0xd8, 0x8a, 0x97,
+ 0xba, 0x22, 0x38, 0x7b, 0xab, 0xfe, 0x3e, 0x8a, 0x7a, 0xe2, 0x70, 0xd3,
+ 0xb5, 0x51, 0x2c, 0x99, 0xa8, 0x62, 0xb2, 0xc1, 0xfb, 0x89, 0xb8, 0x8b,
+ 0x98, 0x9c, 0xe7, 0x9d, 0x11, 0xdb, 0x9c, 0x0c, 0xf6, 0xd2, 0xa6, 0xd7,
+ 0xc9, 0xf1, 0xe7, 0x93, 0xbb, 0x66, 0x2c, 0xda, 0xbf, 0x62, 0x59, 0xa1,
+ 0x73, 0x09, 0x22, 0x58, 0x34, 0x21, 0x07, 0x8e, 0xe9, 0x0a, 0x33, 0x6a,
+ 0x89, 0x0d, 0xc4, 0xbb, 0xe6, 0x57, 0x93, 0x71, 0xba, 0x62, 0x69, 0xdb,
+ 0xd0, 0xcd, 0xb8, 0xa4, 0xce, 0x24, 0x93, 0xd9, 0x51, 0x62, 0x7d, 0xdb,
+ 0xf1, 0x08, 0xea, 0x0e, 0xfc, 0x97, 0x32, 0x02, 0xe6, 0x42, 0xb7, 0x22,
+ 0x3e, 0x0b, 0x99, 0x7a, 0x72, 0xc8, 0x45, 0xc4, 0xf1, 0xd8, 0xfe, 0x9d,
+ 0x6a, 0x09, 0xc7, 0xdf, 0xbb, 0xbe, 0x19, 0x6d, 0xcb, 0x64, 0x7e, 0x2b,
+ 0xf7, 0x9f, 0x4d, 0x17, 0x3a, 0x13, 0x8c, 0xdd, 0x49, 0xb8, 0xb8, 0x6a,
+ 0x4c, 0xe6, 0x8e, 0xa1, 0x0e, 0xcd, 0x13, 0x5e, 0xf6, 0x84, 0x88, 0xa1,
+ 0xf1, 0x44, 0x0c, 0xfb, 0x8e, 0xeb, 0xfc, 0x8c, 0xc1, 0x1a, 0xf3, 0x66,
+ 0x3b, 0x44, 0xa1, 0x9f, 0xf9, 0x39, 0xd3, 0x2f, 0xda, 0xd1, 0x3e, 0x2e,
+ 0xa7, 0xb3, 0xc2, 0x0b, 0x1f, 0x80, 0x87, 0x76, 0xd6, 0x65, 0xfb, 0x84,
+ 0x8b, 0x15, 0xba, 0x7e, 0x94, 0x75, 0xfe, 0xe8, 0x7a, 0x6a, 0xf0, 0x4e,
+ 0xa1, 0x58, 0x5f, 0xa9, 0x79, 0xbd, 0x7c, 0xf5, 0xb1, 0xfe, 0x59, 0x62,
+ 0xdd, 0xb8, 0xce, 0x2d, 0x03, 0x33, 0xfe, 0x25, 0xb5, 0x3d, 0x99, 0x65,
+ 0xad, 0x9b, 0xc7, 0xbc, 0xaa, 0xe6, 0x13, 0x5a, 0x74, 0x6e, 0xcd, 0xab,
+ 0xe5, 0x93, 0x85, 0x33, 0x8c, 0xdd, 0xe1, 0xff, 0x73, 0x5d, 0xb2, 0x90,
+ 0x38, 0x60, 0xa0, 0xa5, 0x23, 0x8a, 0x6b, 0x96, 0xb6, 0x39, 0xcd, 0x88,
+ 0xe2, 0x26, 0xdf, 0x41, 0x13, 0x31, 0xb1, 0x9f, 0x39, 0x85, 0xf9, 0xd5,
+ 0x5c, 0x5b, 0xa9, 0xeb, 0x55, 0x2d, 0xd7, 0xf2, 0xa5, 0x04, 0x6b, 0x93,
+ 0xae, 0x05, 0xbd, 0xac, 0x05, 0x16, 0x0e, 0x95, 0xb5, 0x6f, 0x1d, 0xbc,
+ 0x4b, 0xce, 0x7e, 0xc5, 0xd7, 0xbe, 0x5d, 0x8c, 0x12, 0x73, 0xe3, 0x41,
+ 0xe6, 0xc6, 0xda, 0xf2, 0x25, 0xb5, 0xc6, 0xd3, 0xf5, 0x38, 0x64, 0x3d,
+ 0xb6, 0xc4, 0x4d, 0xe3, 0x72, 0xd0, 0x15, 0xa7, 0xee, 0x24, 0x36, 0x3b,
+ 0x1b, 0x0d, 0xa5, 0x5e, 0x4e, 0xa7, 0x42, 0xea, 0x98, 0xcc, 0xdd, 0x42,
+ 0xba, 0xef, 0x93, 0x9b, 0xd6, 0x9a, 0x51, 0x2c, 0xaf, 0xe5, 0x60, 0xb2,
+ 0x96, 0x83, 0x1e, 0x73, 0xd0, 0x6d, 0x45, 0xf8, 0x09, 0x6d, 0x6c, 0x63,
+ 0x0e, 0x6e, 0xa3, 0x4e, 0xfd, 0x7e, 0xa9, 0xc2, 0xfb, 0x99, 0x15, 0x22,
+ 0x35, 0x73, 0x9e, 0xf9, 0xe4, 0x5e, 0xe6, 0x51, 0xaf, 0xb5, 0x65, 0xce,
+ 0x33, 0x66, 0xab, 0x6b, 0xf9, 0xb4, 0xbb, 0xc6, 0xfb, 0x0f, 0xd4, 0xf2,
+ 0x69, 0xf5, 0x97, 0xf2, 0x49, 0xf3, 0xd3, 0x0b, 0xbf, 0x43, 0xab, 0xd6,
+ 0x22, 0x79, 0xa1, 0xef, 0x97, 0xb3, 0x10, 0xfe, 0xd8, 0xd7, 0x67, 0xd9,
+ 0xb0, 0x82, 0xc6, 0x0a, 0xdf, 0x58, 0x41, 0x28, 0x7a, 0x59, 0x3b, 0x6d,
+ 0x2f, 0x2f, 0xb2, 0xf4, 0x9d, 0x5e, 0xb7, 0x96, 0xb1, 0xd8, 0x99, 0xfe,
+ 0x05, 0xce, 0xb6, 0x2a, 0xd5, 0x97, 0xbe, 0xa4, 0xde, 0x60, 0x5c, 0x62,
+ 0xd4, 0x1f, 0xeb, 0x27, 0xb3, 0xa2, 0x7f, 0x52, 0xfb, 0xa6, 0x11, 0x11,
+ 0x6f, 0xad, 0x58, 0x35, 0x09, 0xdc, 0x43, 0x3d, 0x73, 0x8e, 0x7e, 0x59,
+ 0xe3, 0xcb, 0xa1, 0x35, 0xbc, 0xdb, 0x19, 0xdf, 0xc2, 0xc3, 0xe5, 0xaa,
+ 0x7f, 0xf6, 0x95, 0x65, 0x66, 0x1a, 0x23, 0x58, 0xc3, 0x9a, 0x76, 0x98,
+ 0x7c, 0xf1, 0x6f, 0xc9, 0x28, 0x5e, 0x24, 0x5f, 0xbc, 0xc4, 0xfb, 0x1d,
+ 0xaa, 0xde, 0xcf, 0x9f, 0x45, 0x2a, 0x73, 0x5a, 0xf3, 0x05, 0xb5, 0xf7,
+ 0xa1, 0x72, 0x9b, 0x7f, 0x9a, 0x78, 0x7c, 0xb0, 0x24, 0x07, 0xfa, 0x78,
+ 0x47, 0xbb, 0x5b, 0xce, 0x0e, 0x0a, 0x81, 0x8d, 0x49, 0x38, 0x66, 0xa0,
+ 0xef, 0xe1, 0x52, 0xe3, 0x66, 0xe8, 0x87, 0x02, 0xfa, 0x78, 0xd7, 0x95,
+ 0xac, 0x71, 0x8f, 0x95, 0xbf, 0xa4, 0xeb, 0xb0, 0xad, 0xa4, 0xb9, 0x4a,
+ 0xa9, 0x8e, 0xb4, 0xd6, 0x4a, 0x79, 0x71, 0xb3, 0xe6, 0x94, 0x48, 0x14,
+ 0xca, 0x6f, 0x4b, 0x2c, 0x61, 0xec, 0xf3, 0xc4, 0xd7, 0xbb, 0x5e, 0x3d,
+ 0x79, 0x21, 0x24, 0xaf, 0xf7, 0x90, 0xb7, 0x7b, 0x45, 0x5f, 0x85, 0xcf,
+ 0xb3, 0x22, 0x3b, 0x69, 0x8b, 0x1e, 0x6a, 0x94, 0x0d, 0xcc, 0x33, 0x77,
+ 0xe1, 0x3c, 0x62, 0x4a, 0xe3, 0xca, 0xc0, 0x0f, 0xfc, 0xb5, 0xe4, 0xfc,
+ 0x1b, 0xe8, 0x2b, 0xf2, 0x52, 0x05, 0x8b, 0x37, 0x50, 0x27, 0x55, 0xb1,
+ 0xf8, 0x43, 0x62, 0x31, 0x57, 0xc3, 0x62, 0x24, 0x48, 0x92, 0xef, 0x3e,
+ 0xc7, 0x62, 0xef, 0x1f, 0xe0, 0xf7, 0x2f, 0x62, 0x6e, 0xbd, 0xe6, 0xf7,
+ 0xc8, 0x1c, 0xe6, 0x58, 0x9f, 0x3b, 0x02, 0xf2, 0xb0, 0xc6, 0x9b, 0x8d,
+ 0xbe, 0x47, 0xeb, 0xb1, 0xe1, 0xd1, 0x18, 0x6e, 0x7e, 0x54, 0xa9, 0xd7,
+ 0x7c, 0x78, 0x2d, 0xe4, 0xa2, 0x5f, 0xa4, 0x27, 0x70, 0xa6, 0x25, 0xe9,
+ 0xee, 0x83, 0xee, 0xa3, 0x7a, 0xad, 0xdb, 0x8b, 0x5a, 0xa3, 0x84, 0xd4,
+ 0x28, 0xb2, 0xff, 0x7d, 0xe6, 0xfa, 0xa6, 0xa4, 0xcc, 0xef, 0xac, 0x70,
+ 0x7f, 0xca, 0xa7, 0x16, 0xdf, 0x6b, 0x98, 0x32, 0xdb, 0x6e, 0x54, 0xb1,
+ 0x76, 0x4d, 0x0d, 0x6b, 0x5f, 0x9b, 0xb2, 0xf1, 0x4b, 0xd6, 0x85, 0xcd,
+ 0xe9, 0x28, 0x56, 0xeb, 0x1a, 0xef, 0xe8, 0x5e, 0x2a, 0x8a, 0x7e, 0xc6,
+ 0xc5, 0x58, 0xaa, 0xa8, 0x37, 0xa8, 0x3b, 0x18, 0xcb, 0x55, 0xec, 0xa7,
+ 0xce, 0x50, 0x9f, 0xdc, 0x68, 0x56, 0x7b, 0xa9, 0xd1, 0x9a, 0x3e, 0xb9,
+ 0xb1, 0xac, 0xf3, 0xd1, 0x25, 0x06, 0xa2, 0x38, 0xcd, 0x35, 0x7b, 0xfc,
+ 0xaa, 0x3e, 0x79, 0x1d, 0xa9, 0xac, 0xd6, 0x27, 0x2e, 0x79, 0xbf, 0x54,
+ 0xd1, 0x27, 0x5a, 0x8f, 0x68, 0x2d, 0xa2, 0xfb, 0x85, 0x6e, 0xf6, 0x0b,
+ 0x72, 0x5a, 0xeb, 0x15, 0xa3, 0x5b, 0xfa, 0x86, 0x19, 0x61, 0x8d, 0xcc,
+ 0x30, 0x96, 0x97, 0x61, 0xd7, 0x23, 0x4d, 0x8c, 0x45, 0x23, 0x76, 0x38,
+ 0x2b, 0xac, 0x25, 0x9e, 0xe6, 0x4f, 0x6a, 0x90, 0xdf, 0xd3, 0x2e, 0x47,
+ 0x35, 0xc7, 0x32, 0xfe, 0x73, 0xe3, 0xff, 0x5e, 0x1b, 0xd7, 0xf3, 0xb3,
+ 0xac, 0xd1, 0x7a, 0xcd, 0x8f, 0xac, 0x2a, 0xee, 0xd1, 0xdc, 0xe4, 0xfd,
+ 0x19, 0x2e, 0xd0, 0xc6, 0x37, 0xbf, 0x14, 0x47, 0x9b, 0x79, 0xa1, 0xe3,
+ 0xf8, 0x09, 0xd7, 0xea, 0x78, 0xdb, 0x78, 0x87, 0x3e, 0x3e, 0x47, 0x1f,
+ 0xff, 0xf2, 0xd1, 0x80, 0xdc, 0x84, 0x4f, 0x0d, 0xfa, 0x78, 0x3b, 0x71,
+ 0xf3, 0x63, 0xff, 0x7a, 0xb4, 0xb7, 0x26, 0xdd, 0x0f, 0xcc, 0xb9, 0x7a,
+ 0x0b, 0x7b, 0x09, 0x7d, 0xa7, 0xe8, 0x67, 0xdd, 0xeb, 0x1c, 0xa3, 0x7f,
+ 0x99, 0xcb, 0x15, 0x0d, 0xd2, 0x6e, 0x56, 0xfd, 0xdb, 0x51, 0xf3, 0x6f,
+ 0x66, 0x6a, 0x1b, 0xcf, 0xd1, 0xf5, 0x54, 0xeb, 0xd1, 0xfb, 0x2b, 0xfd,
+ 0x92, 0x19, 0xdc, 0x5a, 0x89, 0x55, 0x5d, 0x90, 0xb7, 0x5e, 0x2c, 0xea,
+ 0x9a, 0xdd, 0xcf, 0x9a, 0xcd, 0x9e, 0xc9, 0x94, 0x83, 0x83, 0x48, 0x4d,
+ 0x73, 0xaf, 0xbd, 0xa7, 0x91, 0x0a, 0xd9, 0x4f, 0x0d, 0x9d, 0x67, 0xef,
+ 0x93, 0x31, 0x64, 0x6e, 0xa6, 0xa2, 0x27, 0x6f, 0xad, 0xd5, 0xe9, 0xfe,
+ 0x9a, 0xae, 0xbc, 0xbf, 0x76, 0x4e, 0x9e, 0xba, 0x72, 0xee, 0x1c, 0x7d,
+ 0x97, 0xcb, 0x2d, 0xfd, 0xac, 0xfb, 0x80, 0x37, 0xfc, 0x9f, 0x29, 0x2c,
+ 0x6c, 0xac, 0xe8, 0x8e, 0xcf, 0xef, 0x6c, 0x89, 0x8d, 0xe3, 0x17, 0x55,
+ 0xa6, 0xe3, 0x2e, 0x13, 0xf5, 0x4a, 0x59, 0xcb, 0x42, 0x14, 0x4b, 0x33,
+ 0xaa, 0x18, 0x97, 0x05, 0x0d, 0xca, 0x96, 0xe0, 0x6e, 0xc6, 0x07, 0xb6,
+ 0x15, 0x0c, 0x5a, 0x23, 0x45, 0x39, 0xc4, 0x5e, 0x2e, 0xcf, 0x3e, 0x2c,
+ 0xdc, 0x0f, 0xad, 0x6f, 0xf5, 0x79, 0x77, 0xeb, 0x3e, 0x8e, 0xef, 0x83,
+ 0xb4, 0x67, 0xee, 0xdc, 0x10, 0x8f, 0x95, 0xfe, 0x4a, 0x3d, 0x16, 0x97,
+ 0x39, 0xbd, 0x47, 0x84, 0x73, 0x9e, 0xa8, 0xe8, 0xe7, 0x41, 0xad, 0x9f,
+ 0x5d, 0x8d, 0xc7, 0x31, 0x4f, 0xce, 0x9e, 0x40, 0x6a, 0xe0, 0x82, 0x29,
+ 0xfb, 0x63, 0xd4, 0xcc, 0xeb, 0x6a, 0x7b, 0xad, 0xa8, 0xed, 0xd5, 0x36,
+ 0xf5, 0x10, 0xed, 0xd6, 0x78, 0xac, 0xd6, 0x37, 0x23, 0x88, 0xa1, 0x69,
+ 0xd4, 0x63, 0x8d, 0x4f, 0xe6, 0x8e, 0xb0, 0xce, 0xc4, 0x8e, 0xef, 0xa8,
+ 0xd8, 0xfb, 0xba, 0xff, 0xa4, 0x59, 0xc9, 0xef, 0x13, 0xba, 0x4e, 0x58,
+ 0xb0, 0x58, 0x77, 0xae, 0x1c, 0x93, 0xe1, 0x16, 0xf1, 0x91, 0x5a, 0x92,
+ 0xf4, 0x12, 0xab, 0x85, 0xd6, 0x3e, 0x49, 0x6a, 0x9f, 0x18, 0x32, 0x27,
+ 0xfe, 0x85, 0xf6, 0x69, 0xfd, 0xa6, 0x6b, 0xa1, 0x83, 0x96, 0x51, 0xaf,
+ 0xb3, 0xcd, 0x48, 0x52, 0x3b, 0x3b, 0x68, 0xfe, 0x6c, 0x3f, 0x4b, 0xac,
+ 0xe2, 0x3e, 0x75, 0x07, 0x1c, 0x5c, 0x33, 0x26, 0x9d, 0xa3, 0xb8, 0x40,
+ 0x0e, 0xf7, 0x06, 0xb5, 0x4e, 0xbc, 0x3a, 0x9d, 0x64, 0x4d, 0x77, 0xd0,
+ 0xf5, 0xd9, 0x3e, 0x31, 0xd4, 0x8d, 0xe9, 0xb3, 0x0b, 0xd3, 0x26, 0xe3,
+ 0xe4, 0x98, 0x47, 0x39, 0xee, 0xa2, 0xfd, 0x44, 0x23, 0xfb, 0x2d, 0xa5,
+ 0xfa, 0x59, 0x0f, 0x2c, 0xd6, 0xdc, 0x5e, 0xb4, 0x0f, 0x8e, 0x88, 0xd4,
+ 0x40, 0x23, 0x52, 0xfd, 0x31, 0x78, 0xce, 0x3a, 0xa1, 0x7f, 0x63, 0x98,
+ 0xd3, 0x24, 0xc0, 0xe3, 0xc5, 0x3f, 0xe7, 0xba, 0xa4, 0xb3, 0x85, 0x18,
+ 0x6b, 0xf9, 0xd3, 0x54, 0xbe, 0x05, 0xa9, 0x21, 0x07, 0x9e, 0xfb, 0x3a,
+ 0xe7, 0x15, 0xbe, 0x30, 0xef, 0xd9, 0xca, 0x3c, 0xfa, 0xe2, 0x7a, 0xad,
+ 0xb5, 0x94, 0x7a, 0x82, 0x7a, 0xab, 0xe0, 0x68, 0xce, 0x11, 0x18, 0xf6,
+ 0xf5, 0x9e, 0x3d, 0xae, 0x05, 0x99, 0xb8, 0x03, 0x9f, 0xa8, 0x42, 0x3c,
+ 0xec, 0x8c, 0x54, 0x7e, 0x97, 0x90, 0x4e, 0x8e, 0xdc, 0x36, 0x5d, 0xed,
+ 0xb3, 0xd8, 0x17, 0x29, 0xf5, 0x22, 0xb9, 0xe9, 0x09, 0x6a, 0x9f, 0xe1,
+ 0xa9, 0x4f, 0xd4, 0x34, 0xb5, 0xcd, 0x88, 0xa7, 0xe7, 0x55, 0x39, 0xe8,
+ 0xb0, 0xa3, 0xd4, 0xe3, 0xfc, 0x6e, 0xcf, 0xd4, 0x1c, 0x2f, 0xf1, 0x3c,
+ 0x72, 0xc2, 0xed, 0xde, 0x7f, 0xab, 0xcd, 0x5f, 0x9a, 0xab, 0xd4, 0x18,
+ 0x6d, 0x78, 0xcb, 0xc7, 0xfd, 0x11, 0x24, 0x73, 0xb3, 0xf4, 0xcf, 0x99,
+ 0xe5, 0xb2, 0x7f, 0x8a, 0xf7, 0x5c, 0x2f, 0x64, 0x96, 0x77, 0xec, 0x9d,
+ 0x07, 0xcd, 0xb5, 0x92, 0xf9, 0x60, 0x78, 0x75, 0x7c, 0xfe, 0x99, 0x2f,
+ 0x13, 0x47, 0xf8, 0xbe, 0x39, 0xa3, 0xf7, 0x50, 0xaa, 0xc7, 0xd7, 0x3d,
+ 0xfe, 0x08, 0x7b, 0xfc, 0x82, 0x6a, 0xf0, 0xde, 0x50, 0xcf, 0x75, 0xc8,
+ 0xfe, 0x11, 0xe1, 0x71, 0xad, 0xcb, 0xba, 0xa0, 0xfb, 0xaa, 0x11, 0xf6,
+ 0x55, 0x2e, 0x9e, 0x26, 0xc7, 0x9c, 0x2c, 0x77, 0xe2, 0xf9, 0xb2, 0x87,
+ 0x67, 0x58, 0x3f, 0x9e, 0x2a, 0x5b, 0xd8, 0xfa, 0x88, 0xcc, 0x58, 0x62,
+ 0x27, 0xce, 0xfb, 0xd2, 0xf9, 0x1e, 0xed, 0x36, 0x03, 0xb9, 0x7f, 0x25,
+ 0x79, 0x85, 0x67, 0x14, 0x72, 0x66, 0x8b, 0xb0, 0x03, 0x1b, 0xdf, 0xe9,
+ 0x30, 0x70, 0x38, 0x3e, 0x84, 0xbe, 0xf6, 0xbb, 0xf9, 0xb2, 0xd0, 0x7a,
+ 0x40, 0xd7, 0x6a, 0xdd, 0x6f, 0x34, 0xe3, 0x4e, 0xf2, 0xd9, 0xd5, 0x4b,
+ 0x43, 0xfc, 0x3a, 0xdd, 0xd6, 0xf9, 0x92, 0xa0, 0x66, 0x68, 0x91, 0x59,
+ 0xe0, 0xa7, 0xd8, 0xc8, 0x7e, 0x21, 0xb3, 0x6c, 0x7f, 0xad, 0x37, 0xff,
+ 0x29, 0x56, 0xea, 0x3e, 0xc3, 0x6f, 0x66, 0xbd, 0xab, 0xc6, 0xe1, 0x70,
+ 0xc5, 0x8f, 0x06, 0x9a, 0x0e, 0x16, 0x54, 0xbd, 0x27, 0x73, 0x93, 0x15,
+ 0x1d, 0xb5, 0xd0, 0xb9, 0x91, 0x7d, 0x40, 0xc3, 0x01, 0xcf, 0x5d, 0x27,
+ 0x14, 0x63, 0xb1, 0x9b, 0xb1, 0x48, 0x86, 0x31, 0xb6, 0xdb, 0xcd, 0x41,
+ 0x32, 0x6c, 0x16, 0x79, 0x71, 0x8b, 0xae, 0xb1, 0x75, 0xf5, 0xec, 0xbf,
+ 0x59, 0x53, 0x27, 0x0d, 0xf6, 0x23, 0xba, 0x1f, 0x8f, 0x62, 0x2a, 0xdd,
+ 0xc6, 0x3e, 0x29, 0x8a, 0xed, 0xe9, 0x1e, 0xea, 0x1a, 0x03, 0xc6, 0xc1,
+ 0x4b, 0x6a, 0xe5, 0x17, 0xfa, 0x88, 0x4d, 0xe3, 0x9a, 0xc3, 0x6c, 0xb1,
+ 0x91, 0xf9, 0x9b, 0x59, 0x46, 0xb1, 0x76, 0x8b, 0xee, 0xe1, 0xf5, 0x1d,
+ 0x1c, 0xf6, 0xc7, 0x06, 0xa6, 0x17, 0x38, 0xd8, 0xd5, 0x2d, 0x13, 0x05,
+ 0xe8, 0x5c, 0xfe, 0x6a, 0x4d, 0x81, 0x93, 0xfd, 0xbd, 0x3a, 0x03, 0x67,
+ 0x03, 0x6d, 0x91, 0x75, 0x4a, 0xb5, 0xa6, 0x4d, 0xe4, 0x2a, 0xf5, 0x26,
+ 0xe1, 0x64, 0xd9, 0xff, 0xcd, 0x4c, 0xb1, 0x27, 0x3b, 0xa8, 0xd4, 0x4e,
+ 0x62, 0xe9, 0xe3, 0x8e, 0xe1, 0x43, 0xec, 0xc4, 0xf7, 0xb6, 0xb2, 0xb7,
+ 0xfa, 0x3a, 0xdb, 0xb7, 0xb7, 0x8a, 0xdf, 0x24, 0x7f, 0x1b, 0xdd, 0x09,
+ 0xe8, 0x7e, 0xa7, 0xa0, 0x22, 0x9e, 0x37, 0xfb, 0x38, 0xb5, 0xe0, 0x6f,
+ 0x96, 0x75, 0xc1, 0x9d, 0x5f, 0xf5, 0xd5, 0x6a, 0x6a, 0xa9, 0x8f, 0xc8,
+ 0xf9, 0x61, 0xe5, 0x73, 0xcc, 0x59, 0x37, 0x7e, 0x49, 0x6d, 0xa6, 0x6f,
+ 0x7a, 0xaa, 0x76, 0x59, 0xf5, 0x01, 0x9b, 0xc4, 0x6b, 0xe1, 0xac, 0xf9,
+ 0x03, 0x36, 0x7d, 0x5e, 0xef, 0x62, 0xce, 0x9a, 0xf1, 0xc5, 0xb4, 0x51,
+ 0xba, 0xd3, 0x15, 0xfc, 0xf8, 0xf8, 0xc8, 0x1b, 0x4e, 0xcc, 0x47, 0xa1,
+ 0x93, 0x39, 0x36, 0xfb, 0x4f, 0x1c, 0x6b, 0x5f, 0x0a, 0xfc, 0xa6, 0xfc,
+ 0x5d, 0xf2, 0xbe, 0xd1, 0xd5, 0x82, 0xc2, 0x0c, 0x6d, 0x3c, 0xf4, 0x75,
+ 0x62, 0x32, 0x3f, 0x86, 0xfb, 0xd8, 0x46, 0xe0, 0x59, 0xd6, 0xdb, 0x63,
+ 0xe4, 0x8c, 0xe6, 0xb4, 0x83, 0x32, 0x9f, 0x8f, 0x94, 0x92, 0x83, 0xa7,
+ 0x99, 0xb7, 0xc7, 0xf9, 0x7c, 0x94, 0xf7, 0xdc, 0x4a, 0x7d, 0x77, 0xef,
+ 0x78, 0x3d, 0xbe, 0x3d, 0x1e, 0xc3, 0xd6, 0xf1, 0x80, 0x9a, 0x02, 0xb7,
+ 0x35, 0x72, 0xdf, 0x57, 0x89, 0xe7, 0xcd, 0x4b, 0xaf, 0xc3, 0x5a, 0x27,
+ 0xe9, 0xde, 0xcd, 0xdc, 0xab, 0x3b, 0x08, 0xc7, 0x21, 0x8e, 0xfe, 0xd9,
+ 0x5b, 0x2e, 0xd0, 0x44, 0xbd, 0xbf, 0xd4, 0x12, 0xeb, 0xc7, 0x57, 0x57,
+ 0x9e, 0x47, 0xd2, 0x79, 0x6a, 0x0b, 0x62, 0xb2, 0x44, 0x4c, 0x32, 0x36,
+ 0x4f, 0x97, 0x88, 0x4b, 0x6a, 0xc3, 0x93, 0x25, 0x8d, 0x6d, 0x1f, 0xcf,
+ 0x75, 0x0c, 0xa9, 0x2a, 0x56, 0x3e, 0x55, 0x4f, 0x78, 0xaf, 0x45, 0x50,
+ 0x6f, 0xe9, 0xdf, 0x76, 0xf0, 0x66, 0x31, 0xe1, 0x6c, 0x28, 0x6b, 0x3c,
+ 0xfc, 0x6d, 0x0d, 0x0f, 0x6f, 0x47, 0xaa, 0xfa, 0x44, 0xce, 0x4c, 0x42,
+ 0x73, 0xdd, 0x62, 0xe7, 0xa6, 0xd2, 0xf0, 0x34, 0x7d, 0x9f, 0xa7, 0xc6,
+ 0x76, 0xdf, 0x67, 0xc8, 0xc7, 0xa6, 0x8c, 0x2e, 0xf6, 0xd4, 0xf4, 0x87,
+ 0xbe, 0x33, 0xf3, 0x37, 0x2d, 0x3b, 0x75, 0x4c, 0x8e, 0x17, 0x71, 0x2b,
+ 0xfb, 0x1e, 0x3f, 0x44, 0xf5, 0x6e, 0x53, 0xbc, 0xf3, 0x43, 0xbc, 0xf3,
+ 0x0f, 0xf9, 0x3c, 0x51, 0x4a, 0x66, 0x7b, 0x78, 0xe7, 0x27, 0xf9, 0x3c,
+ 0x59, 0x6a, 0xad, 0xd3, 0x67, 0x4c, 0x4e, 0x85, 0xac, 0x03, 0x2f, 0xab,
+ 0x52, 0xbc, 0x12, 0x0e, 0xf6, 0xc0, 0x06, 0x1a, 0x0e, 0xce, 0xf1, 0xb3,
+ 0xfe, 0x6d, 0x49, 0xd7, 0x38, 0xcd, 0xf9, 0x83, 0xba, 0x26, 0x67, 0xae,
+ 0x14, 0x97, 0xd4, 0x47, 0x9e, 0x0c, 0x9f, 0xc6, 0x29, 0x35, 0x1f, 0xa9,
+ 0x99, 0xf9, 0x42, 0x4e, 0xaf, 0x30, 0xa4, 0xbb, 0xc8, 0xac, 0x72, 0x75,
+ 0x67, 0x8d, 0xab, 0xbd, 0xa9, 0x1b, 0xeb, 0xaa, 0x77, 0x48, 0x39, 0x47,
+ 0x30, 0x8f, 0xd8, 0xd7, 0x35, 0x55, 0xf3, 0x8f, 0xfe, 0x4c, 0x7d, 0x67,
+ 0x85, 0x09, 0x93, 0x7e, 0x08, 0x6f, 0xd5, 0x63, 0xd1, 0xda, 0x6f, 0x3e,
+ 0x29, 0x5f, 0xf7, 0x82, 0xd3, 0xf1, 0x1e, 0x7e, 0xa7, 0x7b, 0xc1, 0x4f,
+ 0x54, 0x2e, 0xde, 0xf3, 0x19, 0x67, 0x15, 0xd0, 0x45, 0xed, 0xf1, 0x3e,
+ 0x39, 0xa1, 0x83, 0x2a, 0x4a, 0xe0, 0x14, 0xfb, 0xb0, 0x23, 0x5d, 0x49,
+ 0x67, 0x17, 0xf7, 0x0b, 0x1d, 0x87, 0x5c, 0xb0, 0x93, 0x3a, 0x93, 0x73,
+ 0xca, 0x1d, 0x5c, 0xa3, 0xb9, 0xf0, 0x3e, 0xfa, 0xe6, 0xb7, 0xed, 0x96,
+ 0xe7, 0x63, 0x57, 0xe9, 0x39, 0xc3, 0xf2, 0xb4, 0x5f, 0x52, 0x99, 0x5d,
+ 0xb4, 0xe7, 0x2c, 0xed, 0x89, 0x78, 0x21, 0xb9, 0x31, 0x55, 0x59, 0x5f,
+ 0xb0, 0xb4, 0x1d, 0x15, 0x7b, 0x38, 0xa6, 0x39, 0x4f, 0xf6, 0x9f, 0x62,
+ 0x8d, 0xdd, 0x02, 0xfd, 0x3b, 0x85, 0xb6, 0xa1, 0x2d, 0xb1, 0x85, 0xf6,
+ 0x1c, 0x8e, 0x57, 0xf8, 0x94, 0xdf, 0xf1, 0xbc, 0x92, 0xb1, 0xbe, 0x9e,
+ 0x78, 0xbf, 0x22, 0x9d, 0x60, 0x6c, 0xbb, 0xa8, 0xef, 0xab, 0x71, 0xde,
+ 0x57, 0xc1, 0xf2, 0xff, 0x00, 0xb0, 0x60, 0x72, 0xf9, 0x60, 0x17, 0x00,
+ 0x00, 0x00 };
static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
static struct fw_info bnx2_tpat_fw_06 = {
- /* Firmware version: 4.4.22 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x16,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x08000488,
.text_addr = 0x08000400,
- .text_len = 0x1aa4,
+ .text_len = 0x175c,
.text_index = 0x0,
.gz_text = bnx2_TPAT_b06FwText,
.gz_text_len = sizeof(bnx2_TPAT_b06FwText),
@@ -3639,11 +3540,11 @@ static struct fw_info bnx2_tpat_fw_06 = {
.data_index = 0x0,
.data = bnx2_TPAT_b06FwData,
- .sbss_addr = 0x08001ec0,
+ .sbss_addr = 0x08001b80,
.sbss_len = 0x44,
.sbss_index = 0x0,
- .bss_addr = 0x08001f04,
+ .bss_addr = 0x08001bc4,
.bss_len = 0x450,
.bss_index = 0x0,
@@ -3670,862 +3571,858 @@ static const struct cpu_reg cpu_reg_tpat = {
};
static u8 bnx2_TXP_b06FwText[] = {
- 0xad, 0x7b, 0x0d, 0x70, 0x94, 0xf7, 0x79, 0xe7, 0xef, 0xbf, 0x1f, 0xd2,
- 0xae, 0xb4, 0x5a, 0xad, 0xf0, 0x82, 0x57, 0x89, 0x52, 0xf6, 0xf5, 0xbe,
- 0x2b, 0x2d, 0x96, 0x80, 0x77, 0x41, 0x04, 0x11, 0x6d, 0xcd, 0x56, 0x08,
- 0x21, 0x40, 0xd8, 0x32, 0x56, 0x92, 0x25, 0xc7, 0xd4, 0x2a, 0xc8, 0x20,
- 0xdb, 0x18, 0x8b, 0x86, 0xe6, 0xe4, 0xd6, 0xad, 0xd6, 0x92, 0xc0, 0x60,
- 0x56, 0xbc, 0x22, 0x82, 0x08, 0x77, 0xee, 0x26, 0xb2, 0x25, 0x2c, 0xec,
- 0xac, 0x58, 0x3b, 0xbd, 0xeb, 0xc5, 0x33, 0xc9, 0x58, 0x67, 0x6c, 0x4c,
- 0x72, 0xfe, 0xc8, 0x75, 0x3a, 0x3d, 0xf7, 0xe6, 0xee, 0xca, 0xf8, 0x83,
- 0xd8, 0x6e, 0x8c, 0xdd, 0x4c, 0x3a, 0x27, 0x52, 0xdb, 0xef, 0xfd, 0x9e,
- 0xf7, 0xdd, 0x05, 0xe2, 0xba, 0xd3, 0x99, 0xce, 0x69, 0x66, 0x67, 0xa5,
- 0xf7, 0xe3, 0xf9, 0x3f, 0xdf, 0xcf, 0xef, 0x79, 0xfe, 0x7f, 0xd5, 0x03,
- 0x15, 0x28, 0xfe, 0x54, 0xf1, 0xd3, 0x3c, 0x30, 0x78, 0x70, 0xd5, 0x8a,
- 0xe6, 0x15, 0xf6, 0x05, 0x97, 0xc7, 0x23, 0x37, 0xbf, 0xaa, 0x80, 0xde,
- 0x0f, 0xf0, 0x6f, 0xfa, 0xf9, 0xca, 0xbf, 0xed, 0x35, 0xfb, 0xc7, 0x0d,
- 0x84, 0x4a, 0x7c, 0xc9, 0x07, 0x3e, 0x57, 0xea, 0xd2, 0xd7, 0xda, 0x74,
- 0xf8, 0xdc, 0xa9, 0x93, 0xa9, 0xdd, 0x3a, 0x90, 0xce, 0x37, 0x46, 0x37,
- 0xe0, 0x53, 0x2b, 0x1b, 0xf6, 0x40, 0xae, 0x7f, 0x25, 0xf5, 0xc9, 0xd0,
- 0x4f, 0xd6, 0x6a, 0x1f, 0x4f, 0xb9, 0xe1, 0x0b, 0xa5, 0x4e, 0x23, 0x54,
- 0x0f, 0x5f, 0x1d, 0xdf, 0xf9, 0x0f, 0x0d, 0xd5, 0x6e, 0x04, 0x4b, 0xb4,
- 0x5a, 0x30, 0x62, 0x22, 0xeb, 0x4b, 0x0d, 0xa0, 0x7c, 0x0d, 0xf0, 0x6e,
- 0x2e, 0x6e, 0x8c, 0x00, 0xe3, 0xae, 0x54, 0x3c, 0xfa, 0x22, 0x0c, 0x1c,
- 0x2a, 0x44, 0xd1, 0xce, 0xcf, 0x66, 0xf3, 0x33, 0x2b, 0xea, 0x45, 0xd6,
- 0xcd, 0xe7, 0x76, 0x35, 0x03, 0x1b, 0x73, 0x06, 0x0e, 0x9b, 0xf0, 0xd5,
- 0xa6, 0x1e, 0xc6, 0x3a, 0x7e, 0x07, 0x53, 0x83, 0x78, 0x7d, 0x2c, 0x16,
- 0x7d, 0x0a, 0x5a, 0x46, 0x77, 0x6b, 0x83, 0x40, 0x63, 0x7f, 0x9f, 0xd2,
- 0x7a, 0xdf, 0x50, 0x5a, 0xf7, 0x98, 0x82, 0x4f, 0xf1, 0xb9, 0xc6, 0xbc,
- 0x7c, 0x0f, 0xe2, 0xd6, 0xbc, 0x0f, 0x97, 0xdc, 0xb2, 0xfe, 0xef, 0x52,
- 0xdf, 0x0a, 0x1e, 0xbd, 0x05, 0xa3, 0xe4, 0xc1, 0x9b, 0x52, 0x78, 0xb2,
- 0x39, 0x1e, 0x19, 0x86, 0xdc, 0x8f, 0x62, 0x43, 0x41, 0xbe, 0x35, 0x4a,
- 0x6d, 0x59, 0xa3, 0x86, 0x65, 0x9d, 0x31, 0xca, 0x91, 0x0d, 0x69, 0x11,
- 0x40, 0x61, 0xd8, 0x70, 0x21, 0x1d, 0x6a, 0x8b, 0x7a, 0xa0, 0x45, 0xee,
- 0xc1, 0x3f, 0x51, 0xe6, 0x74, 0xc2, 0x0b, 0xe7, 0xf9, 0x5e, 0x94, 0x63,
- 0x3e, 0xe4, 0x68, 0xed, 0xc9, 0x9c, 0x65, 0x5d, 0xd0, 0x3d, 0x38, 0x43,
- 0xfd, 0x0c, 0xe7, 0xff, 0xc9, 0x9a, 0xa7, 0x6e, 0x46, 0xf5, 0xd2, 0xfa,
- 0x3e, 0x4c, 0x85, 0x2c, 0x6b, 0x9a, 0xf7, 0x0e, 0xe7, 0x4b, 0x7a, 0xb6,
- 0x2c, 0x97, 0x6e, 0x59, 0xbb, 0xf5, 0xdf, 0x58, 0xbb, 0x7e, 0xeb, 0x59,
- 0xcb, 0x7a, 0xcc, 0xb8, 0x09, 0x67, 0x27, 0xda, 0xd5, 0x96, 0xd9, 0x25,
- 0xc1, 0xcd, 0x93, 0x16, 0x2e, 0x18, 0x08, 0xb9, 0x52, 0x1d, 0x6a, 0xf3,
- 0x6c, 0xa7, 0xda, 0x58, 0xd8, 0xae, 0x3a, 0xa6, 0xbf, 0xa5, 0x3a, 0x67,
- 0x7b, 0xd5, 0xa6, 0x42, 0x04, 0x33, 0x66, 0x18, 0xd3, 0x66, 0x46, 0xb5,
- 0xcf, 0xf6, 0x28, 0x47, 0x8e, 0x41, 0xd5, 0x56, 0x28, 0xd1, 0xba, 0xae,
- 0xc7, 0xcd, 0xb9, 0x14, 0x8e, 0x98, 0xe5, 0x5c, 0x67, 0xc1, 0xfa, 0x49,
- 0xc3, 0x02, 0xe5, 0x34, 0x70, 0xb4, 0xf0, 0x18, 0xb6, 0x4d, 0x5a, 0x56,
- 0x3e, 0x09, 0xe4, 0x0b, 0xc0, 0x0f, 0xcc, 0x58, 0x77, 0xbf, 0xb2, 0xac,
- 0x4d, 0x71, 0x6b, 0xe9, 0x65, 0xa3, 0x31, 0xf1, 0x12, 0xfe, 0xaf, 0x35,
- 0x15, 0x46, 0x36, 0x40, 0x1a, 0xc7, 0x68, 0xb3, 0xfb, 0xc6, 0xe0, 0x2b,
- 0x4f, 0x8d, 0xe2, 0x17, 0x39, 0xf8, 0xca, 0x52, 0x59, 0x5c, 0xc8, 0x0d,
- 0x87, 0x7c, 0x88, 0x45, 0x36, 0xab, 0xec, 0xa0, 0x0b, 0xda, 0xc0, 0xdb,
- 0xd0, 0xa2, 0xb4, 0xc7, 0xc5, 0xf3, 0x4a, 0x9b, 0x7f, 0x09, 0x5a, 0xfa,
- 0x37, 0x4a, 0xeb, 0xac, 0x75, 0x23, 0xed, 0x8a, 0xfb, 0xf0, 0x93, 0x06,
- 0xb1, 0xc9, 0x28, 0x56, 0xd8, 0xb6, 0xc9, 0x62, 0xd9, 0x35, 0xdb, 0xa4,
- 0x30, 0x4c, 0xbe, 0x0e, 0x93, 0xaf, 0x97, 0x0d, 0x2d, 0xf2, 0x24, 0xac,
- 0xa5, 0x7d, 0x86, 0xdc, 0x4b, 0x61, 0xb4, 0x60, 0x45, 0x83, 0xa9, 0x4b,
- 0xe4, 0x17, 0xd9, 0x2f, 0xa5, 0x7c, 0xd9, 0xea, 0xd4, 0xa7, 0xd6, 0x6b,
- 0x6b, 0x22, 0x78, 0xa1, 0x10, 0xc6, 0x73, 0x85, 0x10, 0x9e, 0x2d, 0xb4,
- 0xc3, 0x2c, 0x20, 0xb8, 0xad, 0xf0, 0x45, 0x7e, 0x6c, 0x21, 0xc0, 0xe7,
- 0xc9, 0x77, 0x70, 0x6b, 0xc1, 0xd3, 0x5b, 0x96, 0x42, 0xf7, 0x4f, 0x73,
- 0x43, 0x56, 0x85, 0x8e, 0xde, 0x9a, 0x94, 0x9e, 0xbe, 0x55, 0x05, 0x5a,
- 0xe8, 0x87, 0xdd, 0xaf, 0xe4, 0x5b, 0x3c, 0xfa, 0x71, 0x3f, 0xbc, 0xd4,
- 0xff, 0xc6, 0x82, 0x65, 0x8d, 0x18, 0x07, 0x56, 0xee, 0x6a, 0xf9, 0x8b,
- 0xf9, 0x6e, 0xbd, 0x0b, 0xd9, 0x42, 0x1f, 0x10, 0x4c, 0xf1, 0x9b, 0xa1,
- 0xb8, 0xbd, 0xa9, 0x3d, 0x7a, 0xee, 0x01, 0x8f, 0xe3, 0xcf, 0xe4, 0x81,
- 0x7a, 0x7f, 0xce, 0x24, 0x0f, 0xe6, 0xe1, 0x20, 0x2a, 0xa2, 0x94, 0xef,
- 0xe7, 0xe4, 0x33, 0x81, 0x1f, 0x16, 0x74, 0xf2, 0xd6, 0x44, 0x1e, 0xa3,
- 0xe4, 0xcf, 0x87, 0x5d, 0x13, 0xda, 0x78, 0x16, 0xda, 0x91, 0x29, 0x2c,
- 0x47, 0x3a, 0x1c, 0xa2, 0x0f, 0xfe, 0x39, 0x1c, 0x1a, 0x5d, 0x38, 0x6e,
- 0x62, 0x55, 0x28, 0x45, 0xfb, 0x26, 0xf1, 0x70, 0x19, 0xe2, 0xbd, 0x1f,
- 0x2b, 0x85, 0xd7, 0xe2, 0x5d, 0x18, 0xa3, 0x3c, 0x5d, 0x79, 0x3f, 0xee,
- 0x9f, 0xa8, 0xc0, 0xbd, 0x13, 0x16, 0xee, 0x4b, 0x22, 0x55, 0x41, 0x79,
- 0x12, 0xc9, 0x78, 0xf4, 0x3d, 0x78, 0xd0, 0x9e, 0xef, 0x62, 0x2c, 0x6d,
- 0x40, 0xba, 0xcc, 0x87, 0x0d, 0xf9, 0x00, 0xe3, 0x31, 0x8d, 0xd3, 0x93,
- 0x3e, 0x78, 0x57, 0xbb, 0x30, 0x15, 0x2e, 0x43, 0xa2, 0xde, 0xc5, 0x4f,
- 0x38, 0xd8, 0x36, 0x59, 0x17, 0xdc, 0x68, 0x7a, 0xb0, 0xd7, 0x74, 0x61,
- 0x68, 0xc2, 0xb2, 0xda, 0x0d, 0x0b, 0x57, 0x57, 0x87, 0xf0, 0x3c, 0xf5,
- 0x77, 0xc0, 0x8c, 0xe0, 0x6c, 0xe1, 0x51, 0xf2, 0x12, 0x76, 0xf8, 0x35,
- 0xc9, 0xbb, 0x49, 0xde, 0x4d, 0xf2, 0x6d, 0x0a, 0x9f, 0xe7, 0x19, 0x33,
- 0x06, 0xe5, 0xf2, 0x93, 0x87, 0x4a, 0xf4, 0x93, 0x8f, 0x58, 0xd2, 0x82,
- 0x2b, 0xa9, 0x65, 0x77, 0x31, 0x79, 0x2d, 0xad, 0xb7, 0xac, 0x8f, 0x57,
- 0x8b, 0x2c, 0xb4, 0xb9, 0xab, 0x4b, 0x62, 0xf4, 0xf7, 0xaa, 0x18, 0x57,
- 0x7f, 0x4b, 0xbd, 0x3d, 0x5e, 0xf0, 0x63, 0x70, 0xc2, 0xf6, 0xdb, 0x83,
- 0x65, 0xe4, 0x5b, 0xf8, 0x2a, 0xe8, 0x71, 0xc6, 0x68, 0x3c, 0xc3, 0x18,
- 0xc5, 0x56, 0xf2, 0x7c, 0x9f, 0x19, 0x6f, 0xd9, 0xae, 0x3c, 0xd8, 0x94,
- 0x0f, 0x07, 0xdb, 0x6f, 0xe0, 0x93, 0xf2, 0x4a, 0x0c, 0x52, 0xd6, 0x10,
- 0xf9, 0x0b, 0x63, 0x37, 0xf9, 0x7c, 0xae, 0xc8, 0xe7, 0x74, 0x41, 0xd6,
- 0xfa, 0x3c, 0xaf, 0x25, 0x3e, 0x91, 0x5d, 0x94, 0x0a, 0x2b, 0x54, 0x04,
- 0xb0, 0x3d, 0xff, 0x26, 0x6d, 0x51, 0x87, 0xbf, 0xa0, 0x0d, 0x5e, 0x60,
- 0x8c, 0xfc, 0xf0, 0x9a, 0xbf, 0x88, 0x3d, 0x1e, 0xa1, 0x1d, 0xb4, 0xd3,
- 0x59, 0x04, 0xd0, 0x5b, 0x48, 0xe3, 0xd0, 0x24, 0xd2, 0x33, 0xc6, 0x31,
- 0xc6, 0xfb, 0x12, 0xb8, 0xf5, 0xf2, 0x74, 0x48, 0xaf, 0xc0, 0xee, 0xe9,
- 0x30, 0x06, 0x0a, 0x6d, 0x30, 0x27, 0xc2, 0xd8, 0x47, 0xdf, 0xbc, 0x92,
- 0x4c, 0xdf, 0x17, 0x84, 0xf0, 0x1e, 0xc6, 0xfd, 0x7c, 0xe7, 0xb1, 0xc9,
- 0x30, 0xfa, 0xa9, 0xa3, 0xcd, 0xc9, 0x78, 0x8b, 0x9f, 0xd7, 0xf6, 0xf2,
- 0xda, 0x61, 0xea, 0xff, 0xbc, 0x31, 0x86, 0xde, 0x6e, 0x2d, 0x01, 0x84,
- 0xb1, 0xc7, 0x44, 0x88, 0x2e, 0xfc, 0x08, 0xf3, 0x5b, 0xe2, 0x3c, 0xff,
- 0xbe, 0xa7, 0x50, 0x41, 0x39, 0x83, 0x88, 0xe8, 0x9f, 0x58, 0xde, 0x66,
- 0xcb, 0xfa, 0xbe, 0x11, 0xbf, 0xf8, 0x96, 0xdb, 0x83, 0x87, 0x0a, 0x2e,
- 0x0c, 0x4e, 0x57, 0xe0, 0x0f, 0x27, 0x3c, 0xb8, 0xb3, 0xbe, 0x02, 0x07,
- 0xa6, 0xd3, 0x18, 0x99, 0xac, 0x40, 0xdf, 0x04, 0x96, 0xee, 0x31, 0x46,
- 0x6a, 0xca, 0xa0, 0x2d, 0xb4, 0x23, 0x81, 0xab, 0xb4, 0xc3, 0x43, 0xd3,
- 0x81, 0x60, 0x66, 0x32, 0x84, 0xc1, 0x59, 0x3f, 0x9f, 0x77, 0xf1, 0xf9,
- 0x72, 0x18, 0xab, 0x62, 0x83, 0x21, 0x08, 0x8f, 0x95, 0xd8, 0x3f, 0xed,
- 0xc7, 0x03, 0x13, 0x21, 0xec, 0x9b, 0x6c, 0xc6, 0xb8, 0x99, 0xc6, 0x51,
- 0xe6, 0x8e, 0x1f, 0x24, 0xb5, 0xee, 0x7d, 0x4a, 0x4b, 0x6f, 0x54, 0x69,
- 0x34, 0x24, 0xbd, 0xb8, 0xc4, 0x3c, 0xe4, 0x4d, 0x36, 0xb6, 0x3c, 0xcb,
- 0xdc, 0x50, 0x96, 0x0a, 0xf3, 0x6f, 0xed, 0x08, 0x63, 0x36, 0xed, 0x75,
- 0xad, 0x06, 0x16, 0x4b, 0xfc, 0x86, 0x83, 0x5b, 0xcc, 0x50, 0x70, 0x4b,
- 0xa1, 0x2e, 0xb8, 0xd9, 0x8c, 0x04, 0x37, 0x33, 0xbe, 0x36, 0x8a, 0x3f,
- 0x9a, 0x3e, 0x1c, 0x4b, 0x7e, 0x6a, 0xf5, 0xd6, 0xd8, 0xf9, 0x2c, 0xb8,
- 0x6d, 0x52, 0xcb, 0x4e, 0x41, 0x33, 0x58, 0x0d, 0x30, 0x36, 0xeb, 0xa1,
- 0xfd, 0x14, 0x6a, 0xf4, 0x66, 0xe6, 0xf1, 0x10, 0xf6, 0x33, 0xa7, 0xfc,
- 0x15, 0x73, 0x4a, 0xdf, 0xf1, 0x58, 0x68, 0x1c, 0x7e, 0xea, 0x1b, 0xd8,
- 0x75, 0x2e, 0x4c, 0x9b, 0x77, 0xe2, 0x51, 0xf2, 0xb5, 0x79, 0x4d, 0x18,
- 0xf7, 0x16, 0x42, 0xc1, 0x4e, 0xda, 0xef, 0xbd, 0x7c, 0x24, 0xb8, 0x81,
- 0xb6, 0x7c, 0x3b, 0xaf, 0x45, 0xe7, 0xf1, 0x8f, 0xe2, 0x4f, 0x09, 0xb8,
- 0x80, 0x3d, 0xc7, 0xbd, 0x98, 0x0f, 0xcb, 0x5a, 0xd4, 0xb9, 0xf9, 0x82,
- 0x15, 0xd0, 0xf5, 0xd3, 0xfb, 0xa8, 0xeb, 0x6f, 0x17, 0x02, 0x78, 0xc0,
- 0xd4, 0x12, 0x3f, 0x54, 0x01, 0xea, 0xd4, 0x47, 0x3d, 0x30, 0xc1, 0x2c,
- 0x91, 0xe7, 0x92, 0x88, 0x2e, 0x71, 0x72, 0xed, 0x81, 0x69, 0xf1, 0x13,
- 0xda, 0xde, 0xa4, 0x0f, 0xd0, 0x7f, 0x7e, 0x78, 0x2d, 0x56, 0xb5, 0x50,
- 0xd6, 0xce, 0xdd, 0x09, 0xfa, 0x8b, 0xa3, 0xa3, 0x13, 0x93, 0xa2, 0x07,
- 0x6d, 0x1c, 0xae, 0x34, 0x56, 0xae, 0xfa, 0x2b, 0xeb, 0xd2, 0x62, 0xd1,
- 0x47, 0x08, 0x43, 0xd4, 0xe1, 0x69, 0xd3, 0xb2, 0xae, 0xae, 0xfe, 0xd0,
- 0x6a, 0xb9, 0x59, 0xf4, 0x22, 0xb2, 0x3e, 0xaf, 0xa4, 0x8e, 0xd4, 0xe8,
- 0xc1, 0xff, 0x0f, 0xbe, 0xf2, 0x1d, 0xab, 0xd7, 0x96, 0x4f, 0xfc, 0xc5,
- 0x43, 0x5f, 0x7c, 0x94, 0xb4, 0x5d, 0xe8, 0x25, 0xbd, 0x07, 0x4d, 0xeb,
- 0xa3, 0xda, 0xd4, 0x67, 0x56, 0xcb, 0x5a, 0x7d, 0x60, 0x41, 0xfd, 0x0f,
- 0x5e, 0x0f, 0x63, 0x7f, 0xa1, 0x85, 0xba, 0x6b, 0xc7, 0x63, 0xd4, 0xe1,
- 0x61, 0x53, 0x72, 0x62, 0x84, 0xfe, 0x5c, 0x47, 0xff, 0xf6, 0xa8, 0x8d,
- 0x66, 0x1e, 0x9b, 0xc7, 0xb2, 0xd8, 0x44, 0x7f, 0xbf, 0x98, 0x8b, 0xb5,
- 0x3c, 0x0d, 0x2d, 0x4b, 0x19, 0x82, 0x9d, 0xd4, 0x71, 0xbb, 0xa9, 0x75,
- 0x8a, 0x4d, 0xdb, 0x99, 0x97, 0x5e, 0xcc, 0x45, 0x82, 0x6d, 0x05, 0xd1,
- 0x77, 0x5d, 0x70, 0x43, 0xe1, 0xab, 0xb4, 0xbd, 0xc2, 0xba, 0xe5, 0x3e,
- 0xe6, 0x99, 0x3b, 0xe1, 0xd8, 0xd5, 0xb1, 0xdd, 0x6b, 0xc9, 0xc6, 0xde,
- 0x0f, 0x99, 0x9f, 0xb2, 0x8b, 0x9d, 0x6b, 0x83, 0xbc, 0x56, 0xbd, 0x1a,
- 0xc1, 0x3b, 0xe8, 0x07, 0x77, 0xd3, 0x0f, 0xae, 0xae, 0xfe, 0xd4, 0x8a,
- 0xde, 0xe4, 0xf8, 0x41, 0xdb, 0xa4, 0x27, 0xd8, 0x41, 0x3d, 0x6d, 0x34,
- 0x14, 0xa6, 0x8d, 0x1c, 0x7a, 0xaf, 0x61, 0x87, 0xf4, 0xd4, 0x59, 0x23,
- 0xcd, 0x3c, 0xf2, 0xbb, 0xf0, 0xd4, 0x60, 0xea, 0x69, 0xe3, 0x51, 0x44,
- 0x1d, 0xdf, 0xc1, 0xbe, 0x09, 0x3f, 0xb2, 0x77, 0x86, 0x30, 0xd3, 0x10,
- 0xc2, 0x83, 0xa4, 0x7d, 0x25, 0xd9, 0xd8, 0xff, 0x3a, 0x75, 0x30, 0x55,
- 0x23, 0xd7, 0xd2, 0xf8, 0x91, 0xf1, 0x30, 0x70, 0x93, 0xb3, 0xf6, 0xac,
- 0xc4, 0xe8, 0x6c, 0x33, 0x0e, 0x17, 0x32, 0xca, 0xc9, 0x9b, 0x5a, 0x67,
- 0x1a, 0x3f, 0xb7, 0x24, 0x97, 0xce, 0x9a, 0xcc, 0x71, 0xd4, 0xc7, 0x28,
- 0xfd, 0x68, 0x38, 0x5f, 0x17, 0xdc, 0x44, 0x3f, 0x7a, 0x34, 0x2f, 0x32,
- 0xc5, 0x0d, 0xc3, 0x5d, 0xcb, 0xda, 0x4c, 0xfd, 0x98, 0x76, 0xcd, 0xaf,
- 0x0e, 0xe9, 0x47, 0x31, 0x6e, 0xf3, 0x36, 0xa8, 0x32, 0xc4, 0x18, 0x0c,
- 0x99, 0xea, 0x72, 0xfd, 0x00, 0x1e, 0xb5, 0xaf, 0x85, 0x83, 0x3b, 0x26,
- 0xd3, 0x2e, 0x97, 0x8e, 0x50, 0x65, 0xaa, 0x5d, 0xed, 0x60, 0xdd, 0xed,
- 0x98, 0xec, 0x50, 0x1d, 0xb3, 0x12, 0x03, 0x9d, 0x6a, 0x33, 0x6b, 0x6e,
- 0x9a, 0x35, 0x37, 0xcd, 0x9a, 0x9b, 0x26, 0x1f, 0x69, 0xd6, 0xda, 0xb6,
- 0xc2, 0xa0, 0xda, 0x2a, 0xfa, 0xa7, 0x7f, 0x3d, 0x6b, 0x3a, 0x38, 0x82,
- 0x39, 0x28, 0xb8, 0xa9, 0xb0, 0xc2, 0xe5, 0x60, 0xbb, 0x41, 0x55, 0xc4,
- 0x32, 0xbe, 0x0a, 0x9d, 0xb5, 0xcc, 0x1c, 0x54, 0x5b, 0x58, 0x6f, 0x33,
- 0xb6, 0x2e, 0x63, 0x03, 0xef, 0xb0, 0xce, 0xbe, 0xc6, 0x3a, 0x9b, 0x4f,
- 0x32, 0xae, 0x96, 0x5f, 0xb5, 0x7a, 0x17, 0x3b, 0x35, 0x61, 0x84, 0xfc,
- 0x7e, 0x9f, 0x36, 0x9b, 0x67, 0x2d, 0x6d, 0x77, 0x2b, 0xec, 0xd1, 0x51,
- 0x5d, 0xcb, 0x9c, 0x7a, 0xb8, 0xc0, 0x3a, 0x60, 0xc4, 0x5a, 0xde, 0xa7,
- 0x62, 0x0f, 0xeb, 0x5e, 0x5c, 0xbd, 0x89, 0x60, 0x47, 0x6f, 0xc3, 0xb1,
- 0x89, 0x72, 0xf4, 0x27, 0xd3, 0x8b, 0x7c, 0xc4, 0x2a, 0x9d, 0xcd, 0x78,
- 0x98, 0x4b, 0xab, 0x48, 0x2a, 0x4e, 0xbf, 0x41, 0xfa, 0x38, 0xeb, 0xc4,
- 0x98, 0xf9, 0x55, 0xe4, 0x59, 0x4f, 0x67, 0x0c, 0x0f, 0x5e, 0xcb, 0xaf,
- 0x60, 0x9e, 0x8b, 0x1b, 0x01, 0x55, 0xc1, 0xf8, 0x4d, 0x21, 0x67, 0x4a,
- 0x7e, 0xb2, 0xac, 0x19, 0xe1, 0x21, 0x1e, 0x4f, 0x0f, 0x43, 0x72, 0x96,
- 0xb5, 0xf4, 0x9e, 0x64, 0x19, 0xd6, 0xc5, 0x83, 0x58, 0xaa, 0xf7, 0xaa,
- 0xce, 0x42, 0xdc, 0x38, 0x8f, 0x6f, 0xa9, 0xbb, 0x67, 0x53, 0x8c, 0xed,
- 0x0c, 0x75, 0x53, 0x81, 0x4b, 0x61, 0xe1, 0x11, 0xd5, 0x5e, 0xdd, 0x85,
- 0x77, 0xef, 0x52, 0x08, 0xe9, 0x69, 0x5c, 0x68, 0x0e, 0xd1, 0xaf, 0x3a,
- 0x89, 0x31, 0xa2, 0x70, 0xcf, 0x45, 0x82, 0x5b, 0x69, 0x8b, 0xca, 0xb9,
- 0x3a, 0xda, 0x87, 0xbe, 0x47, 0x1d, 0xb6, 0x51, 0x87, 0x5b, 0xa6, 0x11,
- 0xaa, 0x48, 0xf5, 0xa8, 0x8e, 0x42, 0xbb, 0x6a, 0x2f, 0x68, 0xd4, 0x93,
- 0xe8, 0xe4, 0x3b, 0xc4, 0x4a, 0xe2, 0x2b, 0x25, 0x5b, 0x8a, 0xbf, 0xde,
- 0x68, 0xcf, 0x8c, 0x4b, 0x62, 0x6e, 0xdd, 0xf2, 0x14, 0xe3, 0xd1, 0x45,
- 0xbe, 0x84, 0x07, 0x1f, 0xaa, 0x1b, 0xac, 0xa5, 0x57, 0x92, 0x4c, 0x9e,
- 0x15, 0x29, 0x1c, 0x2f, 0x74, 0xd1, 0x2e, 0xab, 0x8b, 0xfe, 0x15, 0x0a,
- 0x6e, 0x9c, 0x6c, 0x57, 0x1b, 0x67, 0x17, 0x05, 0xbb, 0x69, 0xc3, 0xee,
- 0xd9, 0x88, 0xd0, 0xe5, 0xfa, 0x62, 0xdb, 0x34, 0x5c, 0xfa, 0xbf, 0x64,
- 0xcb, 0x6f, 0x93, 0x96, 0xd8, 0xd3, 0x5f, 0xf2, 0xd3, 0xe0, 0xdd, 0x93,
- 0x69, 0xbc, 0xbb, 0xda, 0xcb, 0x9a, 0x5a, 0xc2, 0x14, 0x55, 0xc5, 0xef,
- 0xd3, 0x2e, 0xe8, 0x83, 0xaa, 0x53, 0xfc, 0xc8, 0xeb, 0xac, 0x79, 0xc7,
- 0x24, 0xbc, 0x84, 0x0a, 0x51, 0x37, 0x31, 0xdd, 0x87, 0xc9, 0x78, 0xef,
- 0x39, 0xd5, 0xa5, 0xba, 0x0a, 0x52, 0x83, 0x1d, 0x9f, 0x6a, 0xa3, 0x4f,
- 0xb5, 0x93, 0x9f, 0x76, 0xfa, 0xd4, 0x16, 0xf2, 0xb3, 0xc5, 0xf6, 0x29,
- 0xf1, 0xcd, 0xdf, 0xe6, 0x65, 0x43, 0xe1, 0x6e, 0x5b, 0x2f, 0x5b, 0xf9,
- 0x6e, 0x27, 0xe5, 0xe8, 0xe4, 0x7b, 0x77, 0xf3, 0xbd, 0xbb, 0x67, 0xff,
- 0x97, 0xf0, 0x47, 0x59, 0x9c, 0xd8, 0xbf, 0x5e, 0xd3, 0x24, 0x07, 0xfc,
- 0xac, 0x88, 0x29, 0x90, 0x75, 0xa5, 0x24, 0x47, 0x0c, 0xa0, 0xbb, 0x19,
- 0xbe, 0x45, 0xa9, 0x67, 0x5b, 0xb7, 0xd7, 0x33, 0x9f, 0x31, 0x9f, 0xfa,
- 0x8e, 0x13, 0x4b, 0x33, 0x47, 0xcf, 0xb4, 0x28, 0x8c, 0x18, 0x37, 0x33,
- 0x4e, 0x0d, 0x1c, 0x29, 0x68, 0x9d, 0x51, 0xde, 0x6b, 0x1a, 0x13, 0x8c,
- 0xbf, 0x0f, 0x6d, 0xc4, 0x75, 0x91, 0x54, 0x3f, 0x22, 0x66, 0x2c, 0x72,
- 0x44, 0x69, 0xfd, 0x1b, 0xa0, 0x5d, 0x64, 0x6d, 0x18, 0x9c, 0x56, 0xda,
- 0x40, 0xad, 0x5b, 0x4b, 0xbf, 0x61, 0xe3, 0xeb, 0x7d, 0x58, 0x6e, 0x63,
- 0xb8, 0x7e, 0x24, 0x88, 0x65, 0xb7, 0x92, 0xe6, 0xde, 0x75, 0x0a, 0x97,
- 0x8d, 0x0f, 0x69, 0x47, 0x2d, 0x9d, 0x55, 0x06, 0x72, 0xcc, 0x13, 0x91,
- 0xe3, 0x82, 0xd5, 0xf7, 0x11, 0xab, 0xc3, 0x17, 0xe0, 0xb3, 0xb9, 0xb1,
- 0xd8, 0xa0, 0xcf, 0xad, 0x25, 0x88, 0xd3, 0xd3, 0xa4, 0x69, 0x14, 0x88,
- 0xdf, 0xb9, 0x46, 0x74, 0x4f, 0x91, 0x66, 0xbc, 0x48, 0x53, 0xcf, 0x83,
- 0x71, 0x73, 0x04, 0x9b, 0xe2, 0xac, 0x15, 0xcc, 0x79, 0x47, 0xa5, 0x27,
- 0x20, 0xbd, 0xf2, 0xe3, 0x06, 0xff, 0x1e, 0x54, 0x3b, 0x24, 0xa6, 0xca,
- 0x1d, 0x2b, 0x54, 0x73, 0x8d, 0xaa, 0xd4, 0x41, 0xcc, 0xd9, 0x6b, 0x0c,
- 0xc8, 0x1a, 0x03, 0xbf, 0x50, 0x5a, 0xe2, 0x9c, 0x92, 0x5c, 0xdd, 0x98,
- 0x39, 0xc7, 0x18, 0x3a, 0xac, 0xb4, 0x96, 0x63, 0x14, 0xdf, 0xaf, 0x0b,
- 0xfd, 0x83, 0xc5, 0x75, 0x06, 0xd0, 0x90, 0x67, 0x7c, 0x16, 0x7c, 0x6a,
- 0xc3, 0x44, 0x1b, 0x46, 0xa6, 0xdb, 0x30, 0x3c, 0xa1, 0x70, 0xb7, 0xb1,
- 0x18, 0x97, 0x6e, 0xb6, 0xfb, 0x94, 0xaa, 0xa5, 0x7a, 0x2d, 0x86, 0x42,
- 0xa8, 0x76, 0xe9, 0x5f, 0xc1, 0xae, 0x22, 0xc6, 0xdf, 0x74, 0xa2, 0x9b,
- 0x79, 0xdf, 0xc2, 0xfb, 0x8c, 0xa5, 0x58, 0x0d, 0xd2, 0xde, 0x54, 0x0b,
- 0xf1, 0x78, 0x9d, 0xdb, 0x89, 0xf7, 0x0f, 0x7d, 0x8e, 0x0d, 0x44, 0xff,
- 0x9f, 0xbf, 0xd7, 0x86, 0xc7, 0x27, 0xca, 0xd0, 0xb2, 0x1a, 0x77, 0x46,
- 0x50, 0xe5, 0x62, 0x8d, 0x7b, 0x73, 0xbb, 0x1a, 0xe4, 0x3d, 0xfb, 0x59,
- 0xdf, 0x97, 0x53, 0x46, 0xea, 0x4f, 0x1a, 0xe4, 0xba, 0x9d, 0x37, 0x6e,
- 0xb8, 0xde, 0xfd, 0x05, 0xd7, 0x15, 0x9e, 0x61, 0x22, 0xfb, 0x01, 0x6b,
- 0x4a, 0x3e, 0x67, 0xc1, 0x9d, 0xf2, 0xa0, 0x7f, 0x2c, 0x8a, 0x7d, 0x73,
- 0x61, 0xcc, 0xe5, 0xb4, 0xde, 0x4b, 0xec, 0x1f, 0x76, 0x35, 0xeb, 0x78,
- 0x60, 0x2e, 0x82, 0xd9, 0x1c, 0x2c, 0x7f, 0x4a, 0x9f, 0xf7, 0xab, 0x04,
- 0xf6, 0xce, 0xd5, 0xe1, 0x5c, 0x4e, 0xbf, 0x38, 0xac, 0xe2, 0x83, 0xb5,
- 0xc4, 0x1d, 0x0f, 0xce, 0x35, 0x61, 0xff, 0x9c, 0x8f, 0xef, 0x58, 0xd8,
- 0x92, 0xac, 0xe3, 0xf3, 0x2e, 0x3c, 0x7d, 0xd2, 0xb2, 0x04, 0x77, 0xf5,
- 0xcf, 0x01, 0xb3, 0xe3, 0xac, 0x45, 0x67, 0x58, 0x97, 0x9e, 0x00, 0xf6,
- 0x3e, 0xe1, 0xc2, 0xf4, 0xb8, 0x85, 0x5d, 0xc6, 0x70, 0xad, 0x8b, 0x0e,
- 0xdf, 0xcb, 0xba, 0xe1, 0x65, 0x0d, 0xbc, 0x27, 0xe4, 0xe4, 0xf3, 0x4b,
- 0xcc, 0x53, 0xf7, 0x3d, 0x91, 0xc0, 0x9b, 0xb9, 0x2c, 0xb6, 0x10, 0x9f,
- 0x0f, 0x92, 0x97, 0x37, 0x72, 0xac, 0x63, 0x73, 0x06, 0x5e, 0xcf, 0xf9,
- 0xb8, 0x4e, 0x13, 0x5e, 0xca, 0xc9, 0x33, 0xf2, 0x6c, 0x00, 0x7d, 0xe4,
- 0xe5, 0xb5, 0x5c, 0x84, 0x6b, 0x86, 0xf1, 0x53, 0x3e, 0x77, 0xef, 0x9c,
- 0xce, 0xba, 0xe5, 0xe3, 0xba, 0x51, 0xbc, 0x92, 0x0b, 0x90, 0xd7, 0x30,
- 0x6b, 0x55, 0x1f, 0x46, 0x72, 0x8d, 0x17, 0x37, 0x30, 0x51, 0x3b, 0xb5,
- 0x46, 0xae, 0xbd, 0x63, 0x75, 0xd9, 0xb1, 0x28, 0xeb, 0x94, 0xd6, 0xed,
- 0xc3, 0x70, 0xee, 0x75, 0x77, 0xa9, 0x9f, 0x7e, 0x66, 0x7c, 0xc1, 0xc6,
- 0x7e, 0x4f, 0x9b, 0xfc, 0x7d, 0x1a, 0x38, 0x67, 0x66, 0xad, 0xea, 0x14,
- 0xb1, 0x2e, 0x6b, 0xd4, 0x5b, 0x6b, 0x9a, 0xb8, 0xae, 0xde, 0xfb, 0xa2,
- 0x92, 0x7e, 0xc7, 0x83, 0xe8, 0x13, 0xa2, 0x2f, 0x62, 0xe6, 0x59, 0xe0,
- 0x47, 0xc4, 0x9f, 0x0d, 0x63, 0x9a, 0xf8, 0x7d, 0x86, 0xb8, 0xa6, 0x7b,
- 0x1e, 0xf5, 0x89, 0x07, 0x30, 0x64, 0x95, 0x11, 0x9f, 0x57, 0x13, 0xd7,
- 0xce, 0x35, 0xb1, 0x4e, 0xad, 0xb1, 0xac, 0xbf, 0x6d, 0x86, 0xe5, 0x4a,
- 0xe9, 0x46, 0xad, 0x7b, 0xfe, 0x2b, 0x55, 0xd0, 0x2f, 0x06, 0x95, 0x3e,
- 0xff, 0x16, 0xe2, 0x03, 0xe7, 0x21, 0x7a, 0x05, 0x56, 0xcc, 0x79, 0xb0,
- 0x92, 0xf2, 0x6c, 0x1c, 0xe3, 0xda, 0xc4, 0x27, 0x71, 0xca, 0xb4, 0x6d,
- 0x8c, 0x98, 0x4b, 0x0f, 0x60, 0x39, 0x75, 0xdc, 0x7f, 0xca, 0xb2, 0xca,
- 0xa9, 0xe3, 0x06, 0xda, 0x67, 0xcf, 0x09, 0x0b, 0x2f, 0x1a, 0x2f, 0x52,
- 0xa7, 0x8a, 0xb8, 0xb1, 0x99, 0xef, 0x84, 0xf9, 0xbc, 0x0f, 0x7b, 0xc7,
- 0xa4, 0x5f, 0xaa, 0xe3, 0x33, 0xaf, 0xe2, 0x58, 0x2e, 0x81, 0x26, 0xea,
- 0x2f, 0x4a, 0x9a, 0x8d, 0x7c, 0x27, 0x4a, 0x7a, 0xd1, 0xb9, 0xaf, 0x61,
- 0xf3, 0x29, 0x05, 0x3d, 0x2e, 0x3a, 0xf8, 0x1a, 0xda, 0xcf, 0x7c, 0x51,
- 0x4e, 0x60, 0x96, 0x1a, 0xd7, 0x8e, 0xcc, 0x13, 0x7f, 0x57, 0xa5, 0x86,
- 0xc0, 0xfa, 0x8d, 0x37, 0xa6, 0x14, 0x8e, 0x8f, 0xb3, 0xdf, 0x5b, 0x03,
- 0xab, 0x82, 0x32, 0xbd, 0x3e, 0xf5, 0x3b, 0x78, 0xea, 0x24, 0xf5, 0xf0,
- 0x64, 0x18, 0x3f, 0xc8, 0x79, 0xb0, 0xec, 0xb8, 0x60, 0x3a, 0x3d, 0xb1,
- 0x4f, 0x49, 0x7f, 0x24, 0x7d, 0x4b, 0x3c, 0xea, 0x55, 0x2e, 0xd4, 0x3f,
- 0xe5, 0x81, 0x7e, 0x2e, 0x0a, 0x6f, 0xbd, 0x0f, 0x7a, 0xfd, 0x1f, 0x32,
- 0xd7, 0xb8, 0x50, 0xc6, 0x5e, 0x76, 0xd3, 0x77, 0x13, 0xbc, 0x16, 0xe6,
- 0x35, 0xfc, 0x4e, 0x39, 0xdc, 0x4b, 0xdc, 0xac, 0xe1, 0x65, 0x3a, 0xf1,
- 0x98, 0xc7, 0xb2, 0xdc, 0xac, 0x0d, 0x3b, 0xbe, 0x67, 0x59, 0xb1, 0xd5,
- 0xf2, 0x7c, 0x08, 0xb1, 0x73, 0x3a, 0x9f, 0x73, 0xea, 0xe5, 0x75, 0x3c,
- 0xe6, 0xa6, 0x1f, 0x49, 0xac, 0xb2, 0xde, 0xdb, 0x3d, 0x94, 0x83, 0xdb,
- 0x9f, 0x2b, 0x08, 0xb6, 0x89, 0xda, 0x32, 0x9c, 0x1d, 0x57, 0xcc, 0xd9,
- 0x29, 0x3e, 0xbb, 0x1e, 0xee, 0xa4, 0x76, 0x24, 0x4b, 0x3f, 0xd8, 0x15,
- 0x6a, 0xc1, 0x33, 0xa6, 0x17, 0x95, 0xfa, 0x12, 0xdc, 0xdf, 0x1d, 0xc2,
- 0x33, 0xec, 0x0b, 0x68, 0xb3, 0xc4, 0x3c, 0xd8, 0x48, 0x07, 0x49, 0xcf,
- 0xf5, 0x63, 0xe8, 0xdf, 0x75, 0x31, 0xcf, 0xb9, 0xed, 0x3c, 0x57, 0x56,
- 0x0f, 0xcc, 0xe7, 0x3d, 0xb8, 0xa0, 0x3b, 0x98, 0xf0, 0x39, 0xbb, 0x66,
- 0x6b, 0xa1, 0xf9, 0x6b, 0x58, 0x50, 0x6b, 0x49, 0x2b, 0x32, 0x13, 0x14,
- 0xdd, 0x65, 0x3c, 0x8e, 0x2f, 0xfd, 0x8d, 0x5b, 0x7a, 0x8e, 0xeb, 0x7f,
- 0x57, 0xc0, 0x95, 0xd2, 0x22, 0x6d, 0x6e, 0xf8, 0x3c, 0xa9, 0xce, 0xd6,
- 0x51, 0xfd, 0x4b, 0x37, 0xf0, 0xde, 0x84, 0x91, 0xc2, 0xf5, 0x5e, 0xbb,
- 0x33, 0x67, 0xfb, 0x50, 0xa7, 0xe8, 0xfe, 0x31, 0x43, 0xf2, 0xec, 0xa0,
- 0x6a, 0x67, 0xde, 0xca, 0x7a, 0x90, 0xad, 0xe2, 0x33, 0xd4, 0x3f, 0x0e,
- 0x8f, 0x09, 0x9d, 0x83, 0x18, 0xcd, 0xc9, 0x6c, 0x63, 0x00, 0xeb, 0xcc,
- 0x58, 0xe2, 0x22, 0x7b, 0xe8, 0x43, 0x90, 0x39, 0x44, 0xe3, 0xfc, 0xcb,
- 0x4a, 0x1b, 0xbc, 0xc5, 0xad, 0xf5, 0x2f, 0x28, 0x27, 0x6f, 0xad, 0x28,
- 0xe6, 0xad, 0xe5, 0xf9, 0x25, 0xc1, 0x2e, 0xd6, 0x83, 0xae, 0xd9, 0x52,
- 0x7d, 0xe8, 0x52, 0x9b, 0xec, 0xda, 0x9a, 0x51, 0x5b, 0x67, 0x7d, 0xaa,
- 0x63, 0xc2, 0x87, 0x97, 0x89, 0xc5, 0xa6, 0x7a, 0x10, 0x5a, 0xb6, 0x06,
- 0xfe, 0xad, 0x13, 0xdd, 0x28, 0xd7, 0xa5, 0x87, 0x2c, 0xc7, 0x26, 0xbb,
- 0xae, 0xd5, 0x05, 0xbb, 0x58, 0x7f, 0xba, 0x0a, 0x3d, 0xcc, 0x7f, 0x08,
- 0xf9, 0x53, 0xce, 0xcc, 0x40, 0x72, 0xe1, 0xed, 0x7c, 0xf7, 0x62, 0x72,
- 0x11, 0xe0, 0xd4, 0x3f, 0x95, 0x61, 0x2f, 0x51, 0xbd, 0x5a, 0xe1, 0xd2,
- 0x9d, 0x3e, 0x90, 0x16, 0x7b, 0xfe, 0x7c, 0xeb, 0x85, 0xf1, 0x6e, 0xd5,
- 0x31, 0x3d, 0xe3, 0xdf, 0x68, 0xca, 0x2c, 0x62, 0xca, 0xdf, 0x4e, 0x1e,
- 0xda, 0x67, 0x9f, 0xf4, 0x6f, 0x20, 0x4f, 0x1b, 0x66, 0x3f, 0x4f, 0x53,
- 0xea, 0x4a, 0x7f, 0x6b, 0x1b, 0x63, 0x7b, 0x87, 0xf1, 0x91, 0x15, 0xfd,
- 0xa6, 0xd0, 0x99, 0x2b, 0xea, 0x33, 0x4d, 0xbe, 0xc2, 0xbe, 0x4d, 0x85,
- 0x90, 0x2f, 0x5d, 0x68, 0xf7, 0xb7, 0x99, 0xdd, 0xfe, 0x0d, 0x66, 0x8f,
- 0xbf, 0xdd, 0xdc, 0x49, 0xda, 0x5d, 0xfe, 0x0e, 0x93, 0x71, 0x5d, 0xe8,
- 0xa1, 0x5e, 0xbb, 0x31, 0x5a, 0xd8, 0x49, 0xec, 0x21, 0x34, 0x7b, 0x89,
- 0x83, 0xfc, 0x94, 0x71, 0x88, 0x32, 0xce, 0x47, 0xbc, 0x48, 0x6b, 0x5e,
- 0xea, 0x6b, 0xc4, 0xb6, 0xe3, 0x11, 0x7b, 0x16, 0x55, 0x91, 0x7a, 0xa0,
- 0x75, 0xcb, 0x09, 0xe6, 0xfb, 0xd4, 0x9e, 0xd6, 0x65, 0xa7, 0x50, 0xe3,
- 0x4d, 0x49, 0xef, 0xcc, 0x7e, 0x38, 0x1e, 0x37, 0xde, 0x43, 0x3c, 0xf2,
- 0x32, 0x9f, 0x1d, 0xa6, 0xef, 0x8e, 0xd8, 0xf3, 0x07, 0x1a, 0x24, 0xdf,
- 0x84, 0x2d, 0xa6, 0xcf, 0xbf, 0x8d, 0xbd, 0x59, 0x30, 0xa5, 0xb5, 0xdc,
- 0xee, 0x96, 0x79, 0xc8, 0xfc, 0xef, 0x05, 0xd0, 0x84, 0xce, 0x82, 0x8f,
- 0x72, 0x7d, 0x09, 0x7f, 0x7f, 0x92, 0x75, 0x0d, 0xe2, 0x87, 0x96, 0x75,
- 0x2f, 0xfb, 0x9a, 0xa3, 0xf9, 0x3a, 0x5c, 0xb6, 0x6d, 0xec, 0xc1, 0xe1,
- 0x7c, 0x14, 0xef, 0x50, 0x3e, 0xcf, 0x5c, 0x2d, 0xde, 0x1e, 0x77, 0x63,
- 0xb7, 0x71, 0x5b, 0xb1, 0x5e, 0xb8, 0x70, 0x4f, 0xe2, 0x00, 0xb1, 0x83,
- 0x0b, 0xd5, 0xc4, 0x6f, 0x0f, 0xda, 0xd7, 0xdc, 0xec, 0xff, 0xbe, 0x8e,
- 0x41, 0xa7, 0x9e, 0x90, 0xc7, 0x9d, 0xe4, 0xb1, 0xd9, 0xbf, 0x61, 0x42,
- 0xf3, 0xdf, 0x31, 0x01, 0x9f, 0x37, 0xb5, 0xab, 0xf5, 0xcc, 0x49, 0x0b,
- 0x7d, 0xc6, 0xad, 0xb8, 0x72, 0x72, 0xb8, 0xdf, 0x43, 0xff, 0xf9, 0x65,
- 0x32, 0x03, 0x73, 0x12, 0x17, 0x88, 0x3c, 0x5e, 0x0d, 0x30, 0xb7, 0x37,
- 0x24, 0xe3, 0x21, 0xd6, 0x62, 0x63, 0x96, 0xb1, 0xd9, 0x01, 0xad, 0x9f,
- 0x35, 0x39, 0xed, 0x4e, 0xc5, 0x7b, 0x47, 0x08, 0x1e, 0xab, 0xc8, 0x8f,
- 0x9f, 0xb9, 0x3b, 0x30, 0x17, 0xf5, 0xef, 0x60, 0xbd, 0x89, 0xb0, 0xbf,
- 0xf3, 0xc7, 0x71, 0x5b, 0x2d, 0xe2, 0x89, 0x05, 0xca, 0xed, 0x9d, 0x6b,
- 0xf2, 0xdf, 0xce, 0xfa, 0x71, 0x39, 0x6e, 0x0d, 0xbd, 0x68, 0x04, 0x10,
- 0x9c, 0x33, 0xa8, 0xef, 0x0c, 0x86, 0x67, 0xd9, 0x72, 0xc5, 0xd9, 0xf3,
- 0xcf, 0xb5, 0xf8, 0xb7, 0x31, 0x36, 0xab, 0x68, 0xa2, 0xc6, 0xb9, 0xb4,
- 0x5f, 0x7a, 0xbe, 0xa6, 0xb9, 0xb5, 0xe4, 0x4f, 0x7c, 0x74, 0x5f, 0xeb,
- 0x3a, 0xfa, 0x43, 0x74, 0x0e, 0x9b, 0x98, 0xe6, 0x5e, 0x22, 0xcd, 0x4c,
- 0x84, 0x18, 0x76, 0xef, 0x9a, 0x00, 0xf3, 0x94, 0xe8, 0x92, 0x7a, 0x2c,
- 0x94, 0x64, 0x92, 0xba, 0xbc, 0xa7, 0x75, 0xee, 0x94, 0xd4, 0xe5, 0x4c,
- 0x6b, 0xee, 0x94, 0x8e, 0x77, 0x58, 0x5b, 0x56, 0x24, 0x35, 0xe3, 0x9c,
- 0x8a, 0x45, 0x5e, 0xa5, 0x2c, 0x1e, 0xfc, 0xca, 0xda, 0xa5, 0xc7, 0xe7,
- 0x6f, 0x61, 0x3c, 0x55, 0x33, 0x37, 0x46, 0x98, 0xf3, 0xab, 0xe7, 0xa8,
- 0x98, 0x39, 0xb7, 0x17, 0x15, 0x11, 0xf8, 0xe2, 0x3a, 0xde, 0x3d, 0x99,
- 0xa0, 0x1e, 0xae, 0xd1, 0xdc, 0x47, 0xa8, 0xd5, 0xc7, 0x52, 0xf8, 0xc8,
- 0x53, 0xf4, 0xc5, 0x51, 0xae, 0x5b, 0x36, 0x27, 0x3c, 0xcb, 0xf3, 0x61,
- 0x3e, 0x7f, 0x7d, 0xed, 0x6a, 0xae, 0xfd, 0xd1, 0x29, 0xf1, 0xd7, 0x4c,
- 0xeb, 0x85, 0x93, 0xce, 0xda, 0xf1, 0x64, 0x02, 0x1f, 0x9e, 0xd4, 0x06,
- 0xde, 0x55, 0xb1, 0xde, 0x0b, 0x4a, 0xd6, 0x47, 0x5d, 0x15, 0xae, 0x58,
- 0xc3, 0xf1, 0xf8, 0xe0, 0x2e, 0xd2, 0x6c, 0x59, 0x4b, 0xfd, 0xdb, 0x7c,
- 0xd0, 0xe7, 0x99, 0x67, 0xbd, 0xe4, 0xc7, 0xe1, 0xa5, 0x8e, 0xb4, 0x4f,
- 0x16, 0x7b, 0x35, 0xf6, 0xa9, 0xd7, 0xf9, 0x09, 0x53, 0x0f, 0xbe, 0x1d,
- 0xcd, 0x01, 0xd4, 0xda, 0xcf, 0x85, 0xf8, 0x9c, 0xe8, 0xe1, 0xd7, 0xca,
- 0xa5, 0xbf, 0xc7, 0x3c, 0x26, 0xb9, 0x24, 0xcc, 0x1c, 0xb6, 0x53, 0x7a,
- 0xda, 0x6c, 0x96, 0xfe, 0xee, 0xa5, 0xbf, 0x6f, 0x14, 0x9f, 0x36, 0xe9,
- 0xd3, 0x26, 0x7d, 0xda, 0xd4, 0x22, 0x03, 0x88, 0x85, 0xfa, 0x68, 0xb7,
- 0x74, 0x44, 0x7c, 0xbd, 0x07, 0xbb, 0xf9, 0xd9, 0xc3, 0xfb, 0x87, 0xd9,
- 0xe7, 0x62, 0x91, 0xac, 0x79, 0x10, 0xed, 0xe6, 0x23, 0xe8, 0x9f, 0xc0,
- 0x6f, 0xfc, 0xcd, 0xe5, 0x28, 0x5f, 0x2e, 0x3d, 0xbc, 0x16, 0x3a, 0x8a,
- 0x47, 0xd8, 0x47, 0xfd, 0x5a, 0x55, 0xea, 0x9e, 0xee, 0x63, 0x4a, 0x0b,
- 0xb5, 0xb3, 0x1f, 0xde, 0x55, 0xd8, 0x49, 0xfb, 0xc6, 0xfa, 0x5f, 0x56,
- 0xec, 0xa5, 0x6a, 0xb9, 0x36, 0x63, 0xe9, 0x0e, 0xae, 0x63, 0x0a, 0x1f,
- 0x76, 0xbe, 0xfd, 0x7d, 0x88, 0x6e, 0x7f, 0xd2, 0xd0, 0xc7, 0xf5, 0x1d,
- 0x3e, 0x86, 0xd9, 0x53, 0xf6, 0x31, 0xc6, 0x76, 0xdb, 0xf1, 0xd5, 0x43,
- 0x1a, 0xd7, 0xf3, 0xd8, 0x86, 0x9c, 0xd4, 0x52, 0x0b, 0x8f, 0x1a, 0x16,
- 0x9e, 0xe6, 0xe7, 0x22, 0x73, 0xd9, 0xc8, 0x0d, 0xb9, 0xcc, 0xc5, 0xe7,
- 0x76, 0xf0, 0xb9, 0x16, 0xa6, 0xce, 0xd9, 0x69, 0x99, 0x0d, 0x1e, 0x94,
- 0xd9, 0x20, 0xf2, 0xa6, 0xe8, 0x7e, 0x00, 0x17, 0x72, 0xb1, 0x41, 0xb7,
- 0xdb, 0x1a, 0x62, 0x5c, 0x5d, 0xfc, 0x88, 0xbe, 0xfb, 0xda, 0x1a, 0xad,
- 0x9b, 0x3a, 0x4c, 0x8c, 0x29, 0x2d, 0xf2, 0x33, 0xcc, 0x6f, 0xf2, 0xa1,
- 0x31, 0xba, 0xd2, 0x1d, 0x0f, 0x9d, 0x85, 0x36, 0xdf, 0x47, 0x49, 0x9f,
- 0x2c, 0x38, 0xb9, 0x6e, 0x5d, 0x31, 0xd7, 0xb5, 0xe4, 0x2b, 0xd4, 0x1d,
- 0x13, 0xac, 0xcf, 0xd3, 0x56, 0x36, 0xc8, 0x7a, 0x55, 0x98, 0x16, 0xda,
- 0x43, 0x68, 0x4c, 0x0a, 0x2d, 0xbd, 0x73, 0x4c, 0xe1, 0x1b, 0x95, 0x88,
- 0xb3, 0x56, 0xc1, 0x28, 0xd7, 0xb3, 0x16, 0x6b, 0x52, 0xc8, 0x9b, 0x92,
- 0xda, 0xd9, 0xc5, 0xbe, 0xa5, 0x87, 0x79, 0x51, 0x30, 0xb5, 0xcc, 0x4b,
- 0x9d, 0x7c, 0xb4, 0xb1, 0x20, 0x76, 0x11, 0x9b, 0x88, 0x6d, 0x0e, 0xe2,
- 0x1e, 0x53, 0x7a, 0x7f, 0x0b, 0xe3, 0x46, 0x3c, 0xfa, 0x14, 0xc4, 0x4e,
- 0x07, 0xa9, 0x0b, 0x2f, 0x76, 0x33, 0x0f, 0xee, 0x6a, 0xa6, 0xae, 0x82,
- 0x5e, 0xec, 0xb2, 0x67, 0x09, 0x25, 0xfd, 0x79, 0x69, 0x43, 0xc5, 0x1a,
- 0x37, 0xeb, 0x75, 0xf4, 0xe8, 0xcc, 0x26, 0xdd, 0x29, 0xa1, 0x57, 0x9a,
- 0x4b, 0x3a, 0xba, 0xdb, 0x94, 0x13, 0xba, 0x16, 0xce, 0x1a, 0x0e, 0x6e,
- 0x2d, 0xe9, 0x2c, 0x42, 0xb9, 0x6a, 0xd6, 0x02, 0x2b, 0x6f, 0xc0, 0xae,
- 0x15, 0xbc, 0xb6, 0xe5, 0x3a, 0x76, 0xcd, 0x08, 0x3e, 0x26, 0x76, 0xed,
- 0xdc, 0x4a, 0xec, 0x5a, 0xaf, 0x4a, 0xb8, 0x55, 0xe6, 0x12, 0x25, 0xec,
- 0x5a, 0x5d, 0xcc, 0xd1, 0x07, 0xb1, 0x8b, 0xb8, 0xa6, 0xb6, 0x7e, 0x08,
- 0xbe, 0x55, 0xae, 0xcf, 0x5c, 0x18, 0x62, 0xbf, 0x52, 0x06, 0x2c, 0xb6,
- 0x70, 0xcb, 0xea, 0xac, 0x55, 0xae, 0xd7, 0x47, 0xcb, 0x5d, 0x32, 0x77,
- 0x8e, 0x67, 0x47, 0x98, 0x4b, 0x5c, 0xab, 0xb4, 0x6c, 0x1a, 0xbe, 0x50,
- 0x8d, 0xbe, 0xb3, 0xd8, 0x2f, 0x44, 0x7c, 0x9b, 0x89, 0x7b, 0xe2, 0xc9,
- 0x4f, 0xad, 0xa9, 0xb0, 0xd0, 0x98, 0x9f, 0xf7, 0x21, 0xfd, 0x90, 0x8f,
- 0x75, 0x68, 0x41, 0x1d, 0xc1, 0x6b, 0xf1, 0x88, 0x6f, 0x5b, 0x21, 0xeb,
- 0xdf, 0xd2, 0x70, 0x0b, 0xba, 0x4e, 0x49, 0xcd, 0x89, 0x62, 0xeb, 0xa9,
- 0x76, 0xd6, 0x19, 0x1d, 0x1d, 0x63, 0x9d, 0xec, 0xe3, 0xba, 0x55, 0xf7,
- 0xb4, 0xe8, 0x49, 0xf4, 0xac, 0x85, 0xa2, 0xae, 0x1b, 0xe7, 0xa2, 0xa5,
- 0x9e, 0xf8, 0x3d, 0xdb, 0x87, 0x46, 0x8d, 0x10, 0xf5, 0xf3, 0x2b, 0x2f,
- 0x82, 0x16, 0xce, 0x18, 0xe2, 0x7b, 0xfc, 0xdb, 0x4c, 0x63, 0x63, 0xf3,
- 0xb8, 0xe5, 0xd1, 0x65, 0xbe, 0x1d, 0xb1, 0xed, 0xb6, 0x81, 0xb5, 0xac,
- 0x7d, 0xba, 0x87, 0xb6, 0x2a, 0xcd, 0xb2, 0x6f, 0xb4, 0xd9, 0x7a, 0xff,
- 0x46, 0xe6, 0x35, 0xf6, 0xe9, 0x3e, 0x1f, 0x73, 0xa5, 0xef, 0x94, 0x85,
- 0x69, 0xe3, 0x4d, 0xeb, 0x51, 0xdd, 0x43, 0xbb, 0x7c, 0x95, 0x79, 0x57,
- 0x70, 0x49, 0xca, 0x7f, 0xfb, 0xa4, 0xc7, 0x55, 0x95, 0x42, 0x73, 0x19,
- 0x7d, 0xee, 0xd5, 0xa4, 0x33, 0x73, 0x3c, 0x96, 0xbf, 0xcd, 0xbf, 0x65,
- 0x82, 0xbd, 0x04, 0x7b, 0x5d, 0xa7, 0xbf, 0xfb, 0xaa, 0xff, 0xee, 0x09,
- 0xb7, 0xaa, 0x4d, 0xc1, 0xdd, 0xb2, 0xd6, 0xc2, 0xc7, 0xab, 0xe3, 0x83,
- 0x11, 0x17, 0x73, 0x24, 0x69, 0x99, 0xf9, 0x66, 0x7f, 0x86, 0x39, 0x79,
- 0xdb, 0x04, 0xd2, 0x32, 0x9f, 0x0d, 0xae, 0x1e, 0xee, 0x0d, 0x42, 0x66,
- 0x69, 0xf8, 0x06, 0xa3, 0x32, 0x4c, 0x9f, 0x8b, 0xb4, 0xa9, 0xf8, 0x42,
- 0x3f, 0xe2, 0x17, 0x3f, 0x76, 0xbf, 0x69, 0x3d, 0x9e, 0x5f, 0xcb, 0xe7,
- 0x3b, 0x99, 0x2f, 0xd3, 0xcc, 0x9f, 0xc3, 0x83, 0x5e, 0xc8, 0x3b, 0x5a,
- 0xe6, 0x0d, 0x15, 0xa3, 0xaf, 0xe3, 0x9b, 0x7c, 0x3e, 0xd4, 0xc1, 0x5c,
- 0x39, 0x6d, 0xc4, 0xd3, 0x1b, 0x90, 0xed, 0xac, 0x86, 0x66, 0x34, 0x28,
- 0x99, 0x7d, 0x89, 0x1d, 0x12, 0xf8, 0x39, 0xd7, 0xf4, 0xe8, 0xa2, 0xc7,
- 0xf5, 0xe8, 0x9b, 0x66, 0xfd, 0xbf, 0xe6, 0x6f, 0xa2, 0x03, 0xd1, 0xcb,
- 0x37, 0xcb, 0x50, 0xb1, 0x88, 0xb2, 0xfd, 0xdc, 0xce, 0x2b, 0x7e, 0x5d,
- 0xc7, 0x7f, 0x26, 0x3e, 0xfa, 0x4f, 0x05, 0x99, 0x71, 0x96, 0x30, 0x9f,
- 0xdd, 0x47, 0xb5, 0x2e, 0x9b, 0x4a, 0x14, 0x67, 0x9e, 0x3e, 0x7f, 0xe7,
- 0xa4, 0x85, 0x93, 0x46, 0x10, 0xd2, 0xe3, 0x97, 0x27, 0xe7, 0x89, 0x00,
- 0x9a, 0xd0, 0xc1, 0xeb, 0xed, 0x93, 0x95, 0xaa, 0x7d, 0xc2, 0xc2, 0x5f,
- 0x18, 0x5a, 0xb6, 0xcd, 0xcd, 0x98, 0x36, 0xb4, 0xb3, 0xc0, 0x3b, 0xc4,
- 0x4a, 0xe2, 0x63, 0x1e, 0x04, 0x74, 0x87, 0x56, 0xd3, 0xd4, 0x6d, 0xc4,
- 0x0f, 0x12, 0x63, 0xee, 0x15, 0x15, 0x48, 0xaa, 0x29, 0x8f, 0xe8, 0xad,
- 0x13, 0xe9, 0x42, 0xa5, 0xda, 0x4e, 0x5d, 0xde, 0xb1, 0xaa, 0x0c, 0x97,
- 0x6c, 0x5d, 0xde, 0x46, 0x5d, 0xe2, 0xf5, 0xa5, 0x70, 0x5f, 0xa8, 0x45,
- 0xa7, 0x82, 0xdd, 0x9f, 0x55, 0xb2, 0x4e, 0xa7, 0x89, 0x6f, 0x89, 0x07,
- 0x43, 0x3d, 0xf8, 0x2e, 0xf3, 0xcd, 0xa3, 0xf4, 0xd5, 0x5f, 0xe9, 0x4d,
- 0xa8, 0xf8, 0x5e, 0x33, 0xed, 0xb8, 0xd6, 0xbf, 0x79, 0x22, 0x83, 0xc7,
- 0x66, 0x2d, 0x3c, 0xc5, 0x38, 0x69, 0x48, 0x66, 0x43, 0xe5, 0xec, 0xd7,
- 0x58, 0xd3, 0x16, 0x4e, 0xd8, 0x7e, 0xbe, 0xab, 0x75, 0xfd, 0x4c, 0x04,
- 0xee, 0xef, 0xca, 0xef, 0x3b, 0x5b, 0xa3, 0x33, 0xf2, 0x9d, 0xe1, 0xb7,
- 0x85, 0x01, 0x43, 0x4b, 0x7f, 0xec, 0xae, 0x40, 0x65, 0xdc, 0xb2, 0x06,
- 0x92, 0x72, 0xbd, 0xaf, 0x35, 0x61, 0xdf, 0xdf, 0xc3, 0xef, 0xd2, 0x4c,
- 0xfa, 0x6f, 0x04, 0x0b, 0x46, 0xd3, 0x94, 0x79, 0x2b, 0xeb, 0x7b, 0x86,
- 0xf5, 0xbd, 0x36, 0xa5, 0xa5, 0x77, 0xb8, 0x65, 0xfe, 0x32, 0x7f, 0xa0,
- 0x9a, 0xd7, 0x6f, 0x2f, 0xd6, 0xf7, 0xaa, 0x53, 0x32, 0xd3, 0x23, 0x06,
- 0x84, 0xb3, 0x17, 0xd2, 0xc5, 0xfa, 0x5e, 0x31, 0xe6, 0xc1, 0x16, 0xd6,
- 0x76, 0x2f, 0xb1, 0xf8, 0xc6, 0x7c, 0x2d, 0xfc, 0x27, 0xdc, 0x88, 0x25,
- 0x7f, 0x82, 0x03, 0xf4, 0xb1, 0x03, 0x09, 0xb7, 0x8a, 0x2e, 0x71, 0x51,
- 0x4f, 0xff, 0x88, 0x7d, 0x21, 0x37, 0xaa, 0xf4, 0x9f, 0xe1, 0x81, 0x2f,
- 0xa8, 0xe9, 0x99, 0x09, 0x89, 0xed, 0x5d, 0xad, 0x5b, 0x4e, 0x39, 0x35,
- 0x3d, 0x70, 0x6a, 0x78, 0x41, 0x6a, 0x7a, 0xed, 0xea, 0x0c, 0x4e, 0x4f,
- 0xe2, 0x3b, 0x4b, 0x09, 0x1e, 0x6b, 0xb9, 0x66, 0x7d, 0x32, 0xce, 0xde,
- 0x5a, 0xeb, 0xef, 0x50, 0xf1, 0x23, 0x55, 0xcc, 0x01, 0xa7, 0x59, 0xd3,
- 0x7d, 0xa9, 0x78, 0x28, 0xe1, 0x42, 0x97, 0x97, 0xf6, 0x78, 0x9f, 0x7d,
- 0xf6, 0x5b, 0xf9, 0x28, 0x69, 0x96, 0xc1, 0xc3, 0x9a, 0xfe, 0xbe, 0x8e,
- 0xcf, 0xdc, 0xf4, 0xbd, 0x77, 0xdc, 0x3e, 0x5c, 0xcd, 0x3b, 0x35, 0xbd,
- 0xba, 0xc1, 0x1a, 0xba, 0x9c, 0x0c, 0xe0, 0x4a, 0xde, 0xa0, 0x0f, 0x66,
- 0x70, 0x98, 0x35, 0xfd, 0xb2, 0x1e, 0xc2, 0x87, 0xf9, 0x16, 0xfa, 0x65,
- 0x18, 0xbf, 0x24, 0xfe, 0x5d, 0xc5, 0x9a, 0x7e, 0x27, 0x7d, 0x2a, 0xc9,
- 0x9a, 0xde, 0x66, 0xe3, 0x8d, 0x7d, 0xad, 0x67, 0xc6, 0xed, 0x9a, 0xde,
- 0xe0, 0x62, 0x3d, 0xf4, 0x22, 0xbe, 0xc0, 0x3c, 0x61, 0xfd, 0x6a, 0x6d,
- 0x80, 0xcf, 0x52, 0x6f, 0x85, 0xd5, 0x98, 0xb2, 0x6b, 0xd0, 0x7a, 0xff,
- 0x76, 0xae, 0xbd, 0xd8, 0x8e, 0x33, 0x0b, 0x5b, 0x57, 0xbd, 0x86, 0x3f,
- 0xaa, 0x71, 0xd1, 0x0f, 0x53, 0xfe, 0x3b, 0x18, 0x6b, 0xc1, 0x54, 0x69,
- 0xe6, 0x91, 0xe0, 0x3a, 0xb7, 0xf9, 0xef, 0xa4, 0x6f, 0xdc, 0xb2, 0x8a,
- 0x99, 0x24, 0xe4, 0xc4, 0x59, 0x3b, 0xe3, 0x2c, 0xc2, 0x38, 0x5b, 0xca,
- 0x38, 0x7b, 0xdc, 0x88, 0x27, 0xd6, 0x13, 0x77, 0xbd, 0x9c, 0x97, 0x58,
- 0x6b, 0x26, 0x5d, 0x8d, 0x72, 0x0d, 0xf7, 0x4a, 0xcc, 0x6c, 0x5d, 0x35,
- 0x7c, 0xb6, 0x12, 0xa2, 0x2b, 0x7c, 0xb6, 0x98, 0x18, 0x83, 0x99, 0xe9,
- 0xe2, 0x82, 0x3b, 0x3e, 0x78, 0xab, 0x3b, 0x3e, 0xf0, 0x9e, 0x7a, 0xd3,
- 0x7a, 0x9d, 0x71, 0xb6, 0x8d, 0x71, 0xb6, 0x9d, 0x71, 0xd6, 0x66, 0x5a,
- 0x78, 0x2e, 0xa9, 0x65, 0x9a, 0x5c, 0x31, 0xa3, 0xcd, 0x85, 0xa5, 0x95,
- 0x2c, 0x0d, 0x7e, 0xc4, 0x3b, 0xff, 0x88, 0xfc, 0x5f, 0x34, 0xe2, 0xdd,
- 0x09, 0x25, 0xb1, 0x15, 0xc5, 0x07, 0x94, 0xbb, 0xbc, 0x18, 0x5b, 0x7b,
- 0xa7, 0xcf, 0x17, 0x7d, 0xa3, 0x24, 0xbb, 0x1b, 0xcf, 0x1a, 0xcc, 0xa5,
- 0x8b, 0xb4, 0x68, 0xd6, 0xd5, 0x83, 0x23, 0xd4, 0xa3, 0x3f, 0xde, 0x83,
- 0xa3, 0xac, 0x87, 0xf7, 0xb2, 0x0e, 0xdf, 0x67, 0xc6, 0x5a, 0x36, 0xb3,
- 0xff, 0xb9, 0x14, 0xd1, 0xa2, 0x51, 0xd5, 0x83, 0x3e, 0xfa, 0x70, 0x1f,
- 0xeb, 0x46, 0x9b, 0xf9, 0x6b, 0xd5, 0x41, 0xac, 0xb0, 0xa7, 0x20, 0xef,
- 0x69, 0x89, 0x5e, 0x57, 0x3f, 0x7a, 0x67, 0x25, 0xb7, 0x21, 0x74, 0x53,
- 0xaa, 0x07, 0xc7, 0xcd, 0x32, 0xf4, 0x34, 0x77, 0xa9, 0xdb, 0x0b, 0x32,
- 0x7f, 0x63, 0x3c, 0x9a, 0x8c, 0x57, 0x9b, 0x5f, 0x85, 0x7c, 0xbc, 0x0b,
- 0x39, 0x89, 0x4f, 0x73, 0xbb, 0xba, 0x73, 0x5a, 0x62, 0xbc, 0x47, 0xf5,
- 0x48, 0x0c, 0x9b, 0x83, 0xea, 0x2e, 0x89, 0x69, 0x7b, 0x66, 0x2d, 0x71,
- 0x2f, 0x7b, 0x1a, 0xb7, 0x11, 0xc7, 0x81, 0x31, 0xe5, 0xfe, 0x5e, 0x84,
- 0x71, 0xd7, 0x56, 0xe6, 0xa2, 0x9f, 0xc6, 0x68, 0x3b, 0x17, 0xda, 0x8d,
- 0xdf, 0xb1, 0xb2, 0xa1, 0x5e, 0xc6, 0x54, 0x0f, 0x0e, 0x9b, 0x5f, 0xb6,
- 0x2e, 0xdb, 0xf8, 0xa4, 0x94, 0xd7, 0xd7, 0xe3, 0x9e, 0x89, 0x25, 0xf0,
- 0xe9, 0x52, 0xb7, 0x03, 0x48, 0xd4, 0xf8, 0x50, 0xa1, 0x4b, 0xbd, 0xd9,
- 0xd7, 0x3a, 0x77, 0x42, 0x49, 0xff, 0x51, 0x8c, 0xef, 0xf5, 0xb8, 0x9f,
- 0x79, 0x60, 0x77, 0xf2, 0x1e, 0xdc, 0x17, 0xaa, 0x40, 0x90, 0x7a, 0xda,
- 0x1f, 0x0a, 0x30, 0xbf, 0xfe, 0x7e, 0x91, 0xce, 0xb3, 0x65, 0xc5, 0xbe,
- 0xfa, 0x1a, 0xb6, 0xaa, 0x65, 0x8c, 0xad, 0x9b, 0x94, 0x39, 0x51, 0xa6,
- 0x35, 0x32, 0xa9, 0x23, 0xc8, 0x7e, 0x76, 0x7d, 0x52, 0x1b, 0x5c, 0xef,
- 0x8e, 0x49, 0xaf, 0x92, 0x0b, 0x12, 0xd7, 0xe5, 0xe3, 0xf1, 0xee, 0x26,
- 0xd1, 0xb1, 0x1e, 0xc1, 0x26, 0xea, 0x69, 0x4b, 0x3e, 0xcc, 0x18, 0x5a,
- 0x28, 0x13, 0x8c, 0x94, 0xce, 0x5f, 0xa7, 0x15, 0x21, 0xad, 0xc8, 0xa4,
- 0xe0, 0xb5, 0x0c, 0xf1, 0x9a, 0xce, 0x38, 0xb4, 0xac, 0x75, 0xc4, 0x69,
- 0x81, 0x53, 0x32, 0x6f, 0x8a, 0x1d, 0x21, 0xb6, 0x6d, 0x22, 0xee, 0xed,
- 0xa1, 0x57, 0x5b, 0xb7, 0xd4, 0xc7, 0x8d, 0x36, 0x85, 0x47, 0x66, 0x9a,
- 0xe1, 0x73, 0x93, 0xe6, 0x3b, 0xf9, 0x10, 0x2e, 0xe7, 0x23, 0x78, 0x9b,
- 0xb4, 0x2f, 0xd9, 0xb4, 0xeb, 0xf0, 0x8b, 0x62, 0xde, 0x4a, 0x32, 0x6f,
- 0x6d, 0x98, 0x50, 0xf4, 0xd7, 0x28, 0x86, 0x8c, 0xbf, 0xfe, 0xec, 0xd2,
- 0xcd, 0x3e, 0xea, 0x4d, 0x64, 0xf1, 0xf0, 0x7b, 0x14, 0xfb, 0xed, 0x3c,
- 0xfd, 0xda, 0x67, 0x53, 0x35, 0xb4, 0x15, 0x75, 0x5f, 0x5d, 0x7c, 0x6f,
- 0xe5, 0x54, 0xa1, 0x28, 0xaf, 0x0e, 0xd7, 0xa9, 0x04, 0xca, 0x4e, 0x5d,
- 0xe3, 0x55, 0x97, 0xf8, 0x60, 0x65, 0x7d, 0xe4, 0xfb, 0x5c, 0xff, 0x21,
- 0x62, 0x3e, 0x8b, 0xeb, 0x5f, 0xb5, 0xd7, 0x0d, 0x73, 0x5d, 0x75, 0x0d,
- 0x1f, 0x46, 0xae, 0xbd, 0x13, 0xa2, 0xec, 0x78, 0x38, 0x42, 0xdd, 0x5d,
- 0x59, 0x23, 0xcf, 0x05, 0x70, 0x7b, 0x7e, 0x55, 0xb9, 0xe4, 0x71, 0x3f,
- 0xfb, 0x01, 0xc7, 0x97, 0x88, 0xf7, 0xcc, 0xe7, 0x79, 0x4f, 0xf0, 0xd7,
- 0x7a, 0x62, 0x8d, 0xcf, 0xeb, 0x3d, 0x4c, 0x5b, 0x94, 0xd1, 0x78, 0x72,
- 0xef, 0x8b, 0xea, 0xe8, 0x9f, 0x61, 0x90, 0xbd, 0xd0, 0x43, 0x13, 0x59,
- 0xec, 0x9f, 0xf8, 0x63, 0x7b, 0x8f, 0x6e, 0xe5, 0x6a, 0xec, 0xe1, 0x9a,
- 0xfb, 0xaa, 0x19, 0x47, 0xff, 0x2d, 0x19, 0x17, 0x8c, 0xb4, 0xbd, 0x12,
- 0x52, 0x6b, 0xe3, 0x2d, 0xb7, 0x2a, 0x0b, 0x65, 0x49, 0x0c, 0xb4, 0x37,
- 0xc7, 0x13, 0x97, 0xf1, 0x88, 0x25, 0xf3, 0x6e, 0x77, 0xb1, 0xee, 0x12,
- 0x97, 0xaa, 0x76, 0xd6, 0xde, 0xb6, 0x22, 0x56, 0xda, 0x50, 0x78, 0xf3,
- 0x73, 0x33, 0x05, 0xe9, 0xc7, 0xa5, 0xde, 0xf8, 0x55, 0x1b, 0xd7, 0x39,
- 0xcc, 0x9c, 0xfd, 0xac, 0xf1, 0x62, 0x84, 0xd5, 0x18, 0x9e, 0x55, 0x0a,
- 0x07, 0x0c, 0x2f, 0xb2, 0x61, 0x0b, 0xdb, 0xf9, 0xbd, 0x97, 0xf8, 0xe9,
- 0x5d, 0xa3, 0x0a, 0x53, 0xa1, 0x10, 0x31, 0x23, 0x73, 0xb0, 0xeb, 0xff,
- 0x78, 0x65, 0x5f, 0x27, 0xea, 0x92, 0x3d, 0xf8, 0x7f, 0x6d, 0x5f, 0x66,
- 0x15, 0xf1, 0x8b, 0xc8, 0xee, 0x57, 0xcc, 0xa1, 0x09, 0x10, 0xd3, 0xec,
- 0x32, 0xe6, 0xa3, 0x2e, 0xa4, 0xaf, 0xba, 0xa0, 0x9d, 0x7e, 0x87, 0x7d,
- 0xde, 0x43, 0xf5, 0xda, 0xe9, 0x56, 0xb7, 0x8e, 0xc1, 0xe3, 0x3e, 0x3c,
- 0x78, 0xbc, 0x03, 0xd5, 0xf6, 0x7c, 0x68, 0x94, 0x3a, 0x75, 0xb1, 0xbf,
- 0x1a, 0xfe, 0xd4, 0xc3, 0x3e, 0xeb, 0xea, 0xea, 0x87, 0xd1, 0x62, 0x5f,
- 0x1f, 0xc1, 0x9e, 0x09, 0xbf, 0xda, 0x32, 0xe1, 0x41, 0xc7, 0x9d, 0x0f,
- 0xc3, 0xbb, 0xaa, 0x97, 0x7c, 0xc9, 0x75, 0xf9, 0xfd, 0x2e, 0xf6, 0x67,
- 0xc2, 0x5f, 0x19, 0xa2, 0x4b, 0xc8, 0xdb, 0x2a, 0x1d, 0x43, 0xc7, 0x3d,
- 0x6a, 0x87, 0xf9, 0x37, 0xd6, 0x55, 0x7b, 0xcf, 0x47, 0xae, 0x55, 0xc8,
- 0x59, 0x00, 0x3e, 0x23, 0x39, 0xa7, 0x0f, 0x13, 0x8c, 0xed, 0xbb, 0xec,
- 0xf7, 0x8f, 0x97, 0x39, 0x32, 0xa5, 0xd9, 0xb7, 0xb6, 0xd3, 0x7e, 0xf2,
- 0x4c, 0x6b, 0xf1, 0xda, 0x7a, 0x9f, 0x73, 0xde, 0x40, 0x7c, 0xa1, 0x0f,
- 0xcb, 0x68, 0x84, 0xfa, 0xb8, 0x5d, 0xa7, 0x50, 0x9f, 0x67, 0x42, 0x5d,
- 0xe2, 0xf0, 0xfb, 0x80, 0x39, 0xcf, 0x9e, 0x53, 0x67, 0xde, 0xa4, 0xee,
- 0x16, 0xcb, 0xfb, 0x55, 0xbe, 0xdf, 0x7e, 0x5f, 0xf2, 0x2d, 0xb1, 0x66,
- 0x50, 0x30, 0xe7, 0x17, 0xdd, 0xff, 0x5d, 0xc8, 0x3d, 0x8f, 0xfe, 0xa7,
- 0x8c, 0xe3, 0x78, 0x77, 0xa5, 0x4b, 0xfc, 0xe7, 0x4f, 0x71, 0xdf, 0xf4,
- 0x30, 0xef, 0x0b, 0xfd, 0x83, 0xec, 0x25, 0x3c, 0xaa, 0x93, 0xf9, 0x67,
- 0xef, 0x71, 0xd7, 0xed, 0x65, 0xf8, 0x4b, 0xab, 0x7c, 0xf1, 0x10, 0xea,
- 0x93, 0x23, 0x7c, 0x5e, 0xa1, 0x9d, 0xb8, 0xf1, 0x31, 0x63, 0x03, 0x3a,
- 0x6a, 0x24, 0x07, 0x3c, 0x6b, 0xf5, 0xf5, 0x88, 0x0e, 0x15, 0x36, 0xf2,
- 0xfa, 0x73, 0xb4, 0xef, 0x93, 0x86, 0x07, 0xf5, 0x8b, 0x64, 0xd6, 0xa7,
- 0x8d, 0xa7, 0xf1, 0x75, 0x9f, 0xb3, 0xf7, 0x95, 0xb5, 0xaa, 0x75, 0x7d,
- 0xe0, 0x0e, 0x57, 0xfd, 0xf8, 0x1b, 0xf4, 0xa7, 0xb6, 0x55, 0x37, 0xde,
- 0x2b, 0xe9, 0xc4, 0x40, 0x64, 0xd5, 0x33, 0x16, 0x6e, 0x1a, 0x46, 0x68,
- 0xd5, 0x8d, 0xf6, 0x2f, 0xf1, 0x7d, 0x90, 0x31, 0x88, 0x6c, 0x75, 0x4a,
- 0xe6, 0x3f, 0x71, 0xd2, 0x39, 0x88, 0x3f, 0x2c, 0x8c, 0xe0, 0xc0, 0x44,
- 0x11, 0x5b, 0xd3, 0xb7, 0xf5, 0x55, 0xd7, 0x65, 0x7b, 0x60, 0x22, 0xde,
- 0x5b, 0x55, 0x94, 0x6d, 0x1f, 0xfb, 0x8c, 0x4a, 0xe6, 0xd8, 0xfb, 0xa9,
- 0xd3, 0x01, 0x5b, 0xa7, 0x3d, 0x30, 0xf2, 0xd7, 0xe9, 0xf6, 0x93, 0xae,
- 0x3f, 0x25, 0x7a, 0x93, 0xfd, 0xb6, 0x83, 0xd8, 0x4b, 0xba, 0xbb, 0x6f,
- 0xa0, 0xdb, 0x67, 0x5c, 0xa7, 0xbb, 0x6b, 0x22, 0x7e, 0xda, 0x55, 0xa4,
- 0xfb, 0xed, 0xe9, 0x12, 0x8d, 0x2c, 0xb6, 0xad, 0xca, 0x22, 0xbf, 0x6e,
- 0x9f, 0xb5, 0xcf, 0xd6, 0xc7, 0x59, 0xfb, 0xfa, 0xc6, 0x7a, 0x89, 0x07,
- 0xfe, 0x9a, 0xd2, 0xed, 0xbd, 0x7d, 0x07, 0x7b, 0xdd, 0x18, 0x1f, 0xda,
- 0x9b, 0x5b, 0xdc, 0x69, 0xc6, 0x76, 0xd8, 0xb7, 0xf9, 0x73, 0x33, 0x8d,
- 0x0e, 0xf6, 0x61, 0x9b, 0xcc, 0x2e, 0x7f, 0xa7, 0xe9, 0x23, 0xee, 0xaa,
- 0x54, 0x1b, 0x27, 0x64, 0xb6, 0x21, 0xb1, 0x5c, 0xc4, 0xc2, 0x05, 0xe9,
- 0xf7, 0x76, 0xb2, 0x4f, 0x58, 0x46, 0xfb, 0xf6, 0xe2, 0x48, 0xa1, 0x57,
- 0xa5, 0xc3, 0x5c, 0xc7, 0x94, 0xba, 0x02, 0xd6, 0xbc, 0x6e, 0x54, 0xd2,
- 0x97, 0xc2, 0xa9, 0x81, 0xd4, 0xc9, 0x7a, 0x0b, 0xc4, 0x28, 0xbe, 0x45,
- 0xa9, 0x6c, 0x6a, 0x7b, 0xbd, 0x1b, 0xc7, 0x6c, 0xfc, 0xa5, 0x4d, 0xf1,
- 0x33, 0x2e, 0x31, 0x73, 0xc7, 0x84, 0xd4, 0x31, 0x42, 0x48, 0x7d, 0x08,
- 0xff, 0x90, 0x9c, 0x1f, 0xa8, 0x41, 0xfa, 0xde, 0x1a, 0x48, 0x5f, 0x71,
- 0x04, 0x3f, 0xd2, 0x23, 0xbe, 0x4c, 0xc1, 0xa3, 0xb6, 0x98, 0x33, 0xfe,
- 0xad, 0x66, 0x10, 0x01, 0xf6, 0x65, 0x5d, 0xee, 0x18, 0xfb, 0x0c, 0xd1,
- 0x63, 0x67, 0xeb, 0xb2, 0x7c, 0xc6, 0xdf, 0x6e, 0x3a, 0xb9, 0xf0, 0x96,
- 0x29, 0x9f, 0xbf, 0x63, 0x32, 0x16, 0x39, 0x62, 0x63, 0xb1, 0xae, 0xd6,
- 0x58, 0xde, 0xb2, 0x5e, 0x31, 0xe6, 0xaf, 0x96, 0x3b, 0x3d, 0x48, 0x6b,
- 0x22, 0xdf, 0x84, 0xbb, 0x89, 0x9f, 0xda, 0x26, 0x9b, 0x60, 0x4c, 0x02,
- 0x27, 0x8e, 0x47, 0xb0, 0x72, 0x42, 0x3b, 0x3d, 0xe8, 0xce, 0x60, 0x7c,
- 0xb6, 0x13, 0x13, 0x05, 0xff, 0x42, 0xd4, 0x45, 0x5c, 0x9d, 0x74, 0xe1,
- 0x76, 0x63, 0xb5, 0x9a, 0xb7, 0x63, 0x5a, 0xe1, 0x2e, 0x63, 0xbb, 0xea,
- 0xb5, 0x31, 0xc5, 0x0c, 0xb1, 0x88, 0xc2, 0x4d, 0xce, 0x5c, 0xbe, 0x35,
- 0x49, 0xcc, 0x7d, 0xfb, 0x84, 0xd4, 0x77, 0x0b, 0xaf, 0x26, 0xa9, 0x97,
- 0x64, 0x36, 0xe3, 0x65, 0x0f, 0xb4, 0x4f, 0x69, 0xdd, 0x86, 0x72, 0x30,
- 0xde, 0xad, 0x33, 0x0e, 0x2e, 0x5c, 0x36, 0xd3, 0xec, 0x97, 0x1c, 0xd4,
- 0x6e, 0x68, 0x11, 0x8f, 0x2b, 0x84, 0x01, 0x9b, 0x46, 0x6f, 0xab, 0x31,
- 0x53, 0x86, 0xa5, 0x7a, 0x0f, 0x4e, 0xdb, 0x32, 0xf4, 0xb7, 0xae, 0x27,
- 0xbe, 0x7e, 0xdc, 0xcc, 0xb0, 0x07, 0x96, 0xfd, 0xd0, 0x58, 0xa2, 0xc5,
- 0xdd, 0x46, 0x0c, 0x1b, 0x8b, 0x2e, 0xa8, 0xb4, 0xca, 0x7a, 0x1a, 0xd3,
- 0x33, 0x60, 0x45, 0xa9, 0x71, 0xea, 0x9b, 0xc8, 0x18, 0x27, 0xce, 0x6a,
- 0x3b, 0xee, 0x5f, 0x48, 0xc3, 0x99, 0xdf, 0x6c, 0x32, 0xfe, 0x37, 0x2e,
- 0x85, 0xb5, 0x23, 0x69, 0xf2, 0xdd, 0xc1, 0xbc, 0x3b, 0xdf, 0xe3, 0xe1,
- 0x7d, 0x99, 0xdb, 0x75, 0xb7, 0x8e, 0xe6, 0x30, 0xef, 0x4e, 0x49, 0x5f,
- 0x85, 0x60, 0x77, 0x01, 0x32, 0x43, 0x62, 0x6f, 0xf1, 0xa9, 0x55, 0xda,
- 0x3b, 0xea, 0x9a, 0x74, 0xf6, 0xc5, 0x72, 0xb3, 0x9e, 0xe0, 0x56, 0xb3,
- 0x19, 0xc7, 0x0a, 0x9e, 0x1b, 0x68, 0xc7, 0x8f, 0xdc, 0xe2, 0x72, 0x21,
- 0xbe, 0xea, 0x2e, 0x55, 0xdc, 0x5b, 0x62, 0x9e, 0xc8, 0xd8, 0x35, 0xb1,
- 0x8c, 0x72, 0x5e, 0x38, 0x29, 0x6b, 0x7c, 0xab, 0x75, 0xf4, 0xa4, 0xd4,
- 0xc8, 0xee, 0xd6, 0x88, 0xa9, 0x75, 0x4b, 0x1f, 0x58, 0x4d, 0x3d, 0x7d,
- 0x34, 0x26, 0x35, 0x78, 0x3f, 0x6b, 0xb0, 0xb6, 0xd0, 0xae, 0xa4, 0x8e,
- 0x69, 0x09, 0xbf, 0xdb, 0x85, 0x2b, 0x0d, 0x5a, 0xe6, 0x79, 0x68, 0xbd,
- 0xce, 0xbc, 0x70, 0x67, 0x6b, 0x63, 0x11, 0x0f, 0xdf, 0x3a, 0xd3, 0x27,
- 0xe7, 0x49, 0x6c, 0x1d, 0x37, 0xe5, 0x05, 0x1b, 0x5b, 0xd6, 0x4b, 0xc9,
- 0x2e, 0xe2, 0x06, 0xc1, 0xc6, 0x72, 0xfd, 0x81, 0xd6, 0x86, 0x29, 0x1f,
- 0x79, 0x53, 0x78, 0x8f, 0x75, 0xe9, 0x48, 0xa1, 0xc4, 0xa3, 0x83, 0x9b,
- 0x37, 0x13, 0x37, 0xbb, 0x53, 0x5a, 0xcb, 0x06, 0xe2, 0x66, 0x9d, 0x3d,
- 0x84, 0x07, 0x3d, 0x78, 0xcc, 0x74, 0xfa, 0x08, 0xc1, 0xce, 0xd6, 0x49,
- 0x2d, 0x2d, 0xb8, 0xf9, 0xea, 0x6a, 0x60, 0x07, 0x71, 0xf3, 0x42, 0xce,
- 0x83, 0x0c, 0x71, 0xf3, 0x47, 0x39, 0x1f, 0xee, 0x20, 0x6e, 0xbe, 0x42,
- 0x8c, 0x75, 0x3e, 0xf9, 0x4b, 0x7c, 0xbb, 0x38, 0x13, 0xdb, 0x95, 0xf0,
- 0xd1, 0xb7, 0x05, 0x3b, 0xff, 0xa6, 0x88, 0x9d, 0xff, 0xcb, 0x3f, 0xc3,
- 0xce, 0x77, 0x13, 0x13, 0x76, 0x4d, 0xc8, 0xfe, 0xd1, 0xae, 0xd6, 0xd7,
- 0x4f, 0xc9, 0x99, 0x95, 0x5b, 0xf1, 0xee, 0xc9, 0xe1, 0x7e, 0x62, 0x65,
- 0x8c, 0x24, 0x33, 0xc8, 0x4d, 0x62, 0x09, 0x71, 0xc1, 0x4b, 0x6e, 0xae,
- 0xbb, 0x32, 0xa9, 0x19, 0x6f, 0xa8, 0x78, 0x67, 0x06, 0x71, 0xf6, 0xca,
- 0xda, 0x02, 0x4d, 0x98, 0xf6, 0xa4, 0x88, 0x8d, 0x59, 0x03, 0x97, 0x12,
- 0x3b, 0x57, 0xcd, 0x01, 0xb5, 0x73, 0x0e, 0x76, 0x96, 0x79, 0x58, 0x55,
- 0x1c, 0x7f, 0x46, 0xec, 0xcc, 0xfe, 0x96, 0xa1, 0x36, 0xd7, 0xc4, 0x18,
- 0x55, 0x38, 0x1c, 0x0f, 0xa0, 0xeb, 0x38, 0x71, 0x8f, 0x3d, 0x0f, 0xb3,
- 0x86, 0x7e, 0x6a, 0x64, 0x70, 0x74, 0xd6, 0x99, 0x87, 0x6d, 0x22, 0x7e,
- 0xf3, 0xc4, 0xc3, 0x28, 0x9f, 0xf3, 0xe0, 0x19, 0xe2, 0xe7, 0x8d, 0xb4,
- 0xf3, 0x19, 0xe2, 0xe7, 0xbb, 0x6f, 0x98, 0x89, 0x4d, 0xcd, 0xe1, 0x15,
- 0x62, 0xf9, 0xba, 0x5a, 0xc4, 0x65, 0xde, 0x61, 0x5d, 0x59, 0x13, 0xc0,
- 0x39, 0x1b, 0x3f, 0xfb, 0x17, 0xb2, 0xca, 0x91, 0xad, 0x8c, 0xb6, 0x10,
- 0xbb, 0xba, 0x68, 0xd7, 0xb6, 0x93, 0x5a, 0xe7, 0x8b, 0xd4, 0x45, 0x63,
- 0xfc, 0xbc, 0x6d, 0x8f, 0xbe, 0xa4, 0xcc, 0x4e, 0x3a, 0x5b, 0xe5, 0x5c,
- 0x55, 0x05, 0xed, 0xbd, 0x65, 0x2c, 0x96, 0xfe, 0x00, 0x4e, 0x4c, 0x26,
- 0xf2, 0x65, 0xc5, 0x7a, 0x28, 0xf7, 0xfa, 0x79, 0x2f, 0x8d, 0xce, 0x35,
- 0x8e, 0x7f, 0x27, 0xf2, 0xc7, 0x88, 0x5d, 0x65, 0xcf, 0x34, 0x14, 0xdc,
- 0x64, 0x76, 0x62, 0xdc, 0x8c, 0xa2, 0xfc, 0x5c, 0x71, 0xef, 0xf5, 0x9c,
- 0x9c, 0xc5, 0xdb, 0xd9, 0x1a, 0xfa, 0x5e, 0x09, 0x13, 0xa6, 0x89, 0xef,
- 0xc2, 0xbe, 0xdb, 0x0b, 0x82, 0x17, 0xbb, 0x71, 0xd4, 0xd4, 0x22, 0x3f,
- 0x67, 0x4c, 0xdc, 0x2b, 0xfb, 0xee, 0x37, 0xcc, 0x9e, 0x1e, 0xe4, 0x3d,
- 0xf3, 0x73, 0xb3, 0xa7, 0xc1, 0x09, 0xfc, 0xc6, 0xdd, 0x5c, 0x0e, 0xd7,
- 0x4a, 0x2f, 0x31, 0xbd, 0x16, 0x19, 0xc1, 0x23, 0xc4, 0x1c, 0xbf, 0x56,
- 0x01, 0xdd, 0xd3, 0xdf, 0xe4, 0xd6, 0x22, 0x33, 0x2a, 0xc0, 0x77, 0x77,
- 0x32, 0xbf, 0xed, 0xa4, 0x6f, 0xc4, 0x16, 0x2a, 0x94, 0x1b, 0x97, 0xbe,
- 0x6c, 0xe3, 0x51, 0x7f, 0x37, 0xaf, 0x8d, 0x17, 0x4a, 0xb8, 0xa6, 0x47,
- 0x78, 0xc5, 0xa6, 0xe3, 0x4e, 0x0e, 0xd1, 0xf3, 0xfe, 0x85, 0x4b, 0x70,
- 0x64, 0xab, 0xa4, 0xac, 0xf7, 0x8f, 0x85, 0xac, 0xde, 0xc5, 0x12, 0xc3,
- 0x3a, 0xb6, 0x99, 0xe2, 0x5f, 0x7d, 0xe4, 0xb3, 0x07, 0x87, 0xcc, 0xa5,
- 0xec, 0xdd, 0x64, 0x0e, 0xda, 0x44, 0x6c, 0xdd, 0xcd, 0x1a, 0x6c, 0x59,
- 0x83, 0x46, 0xd6, 0x6a, 0x5a, 0xab, 0x1b, 0x79, 0x35, 0x5f, 0x13, 0x21,
- 0xbe, 0x59, 0xc5, 0xda, 0xdd, 0x56, 0x68, 0xc2, 0x1b, 0x67, 0x74, 0xfa,
- 0x66, 0x3b, 0xf1, 0x7b, 0x37, 0xee, 0xa1, 0x3c, 0xdf, 0x2e, 0x7c, 0x07,
- 0xe9, 0x6f, 0x78, 0x70, 0xe4, 0x78, 0x1a, 0xeb, 0x57, 0x0d, 0xe1, 0xd2,
- 0x37, 0x7d, 0xcc, 0x55, 0x01, 0x3c, 0x7e, 0x5c, 0xf2, 0x6b, 0x09, 0x6f,
- 0xdf, 0x88, 0x45, 0x7c, 0x88, 0xda, 0x38, 0xe4, 0x8b, 0xef, 0x39, 0x18,
- 0xc5, 0xcf, 0xfe, 0xb7, 0xf4, 0x3e, 0xf3, 0xd0, 0xaa, 0x7f, 0x86, 0x67,
- 0x88, 0x5b, 0x88, 0x05, 0x2a, 0x12, 0xf6, 0xb9, 0xb7, 0x12, 0xde, 0xf5,
- 0xd0, 0x07, 0x24, 0xa6, 0x97, 0x32, 0xd6, 0x2d, 0x62, 0xe7, 0x85, 0xe2,
- 0x5c, 0xf2, 0xed, 0x93, 0xda, 0xc5, 0x43, 0x88, 0x11, 0x43, 0xa3, 0x4f,
- 0xb0, 0x9b, 0x9b, 0x78, 0xf7, 0x4a, 0x3c, 0x6e, 0x9c, 0x23, 0xde, 0x1d,
- 0xa6, 0xad, 0x3d, 0xba, 0xf8, 0x66, 0x08, 0x65, 0x73, 0x11, 0xfa, 0xa4,
- 0xcc, 0x25, 0x5f, 0xf1, 0x3b, 0x73, 0x49, 0x99, 0x85, 0xcb, 0xb9, 0x10,
- 0x74, 0x94, 0xb1, 0x77, 0x2b, 0x57, 0x59, 0xe6, 0xe4, 0x29, 0xff, 0x0e,
- 0xe6, 0xf7, 0x8c, 0x19, 0x0e, 0xee, 0x28, 0x84, 0xf8, 0xa9, 0x0b, 0x66,
- 0x0a, 0xbf, 0xc7, 0xe7, 0x23, 0xfc, 0x8e, 0x62, 0x22, 0x5f, 0x5b, 0x21,
- 0xcd, 0xc0, 0x44, 0xde, 0xc9, 0x79, 0xd1, 0xfc, 0x5e, 0xbf, 0x60, 0xcd,
- 0xb6, 0xe3, 0xce, 0xdf, 0xfa, 0x0d, 0x7f, 0x7f, 0x1e, 0xf3, 0x7b, 0xc9,
- 0xf7, 0x99, 0x93, 0x3a, 0x3e, 0x3a, 0x69, 0x63, 0xfe, 0x79, 0x62, 0xfe,
- 0x01, 0xaf, 0x5b, 0xb0, 0xe6, 0xaf, 0xac, 0xf3, 0xf1, 0x78, 0xef, 0x34,
- 0xfd, 0xa0, 0x8b, 0x74, 0x5d, 0x7a, 0xd8, 0xe6, 0xd7, 0xe1, 0xd3, 0x99,
- 0xe5, 0x5e, 0x3e, 0x99, 0xc0, 0x3b, 0xd7, 0x67, 0xa7, 0x9f, 0x94, 0xd9,
- 0x33, 0x60, 0x3c, 0xf2, 0xee, 0x5a, 0xf8, 0x5a, 0xd8, 0x6f, 0x7a, 0xf9,
- 0x7c, 0xc4, 0x7e, 0x5e, 0x66, 0xb9, 0x9f, 0x7c, 0x56, 0xc2, 0xd3, 0x1f,
- 0x5d, 0x7f, 0xe7, 0x20, 0x3b, 0x35, 0xdf, 0x79, 0xc6, 0x96, 0xdb, 0x7e,
- 0x4e, 0xe6, 0xad, 0xfe, 0x05, 0xd8, 0xf1, 0xf5, 0xfb, 0x94, 0x49, 0xec,
- 0x7b, 0xc0, 0x72, 0xfc, 0x36, 0x1c, 0xdc, 0xc6, 0x78, 0xf8, 0x2e, 0xed,
- 0xb3, 0xed, 0x5c, 0x5d, 0xf0, 0x2e, 0xb3, 0xd3, 0x96, 0xf9, 0xae, 0x73,
- 0x52, 0x93, 0xe4, 0xfe, 0x1f, 0x54, 0x08, 0x1e, 0x7f, 0x9c, 0x35, 0x6b,
- 0xd8, 0x94, 0xd9, 0x3e, 0x94, 0x27, 0x75, 0x08, 0x9b, 0xc6, 0xa3, 0x78,
- 0xdb, 0xf0, 0x17, 0xcf, 0xb0, 0x48, 0x4c, 0x0e, 0x30, 0x26, 0xc3, 0x18,
- 0x31, 0x63, 0xd1, 0xb7, 0x89, 0x4f, 0xb3, 0x64, 0xf8, 0xe8, 0x84, 0x1b,
- 0x6f, 0x13, 0x33, 0x42, 0x39, 0x67, 0x40, 0x9d, 0x77, 0x4b, 0xbf, 0x57,
- 0x22, 0x5a, 0x13, 0x6b, 0xd9, 0x8b, 0x3a, 0xe4, 0x98, 0xf3, 0xfd, 0xfa,
- 0x8f, 0x71, 0xec, 0x84, 0x0b, 0xf7, 0xb1, 0xef, 0x4b, 0xdf, 0x69, 0xf0,
- 0xef, 0xc6, 0xfe, 0xf7, 0xf1, 0x0f, 0xd6, 0x94, 0x9c, 0xb3, 0x52, 0x72,
- 0x96, 0xe3, 0x13, 0xab, 0x56, 0xd7, 0xe7, 0x9f, 0x87, 0x3e, 0x78, 0x15,
- 0x8d, 0x03, 0x0b, 0xf8, 0xc0, 0x9a, 0xe7, 0xbd, 0xf7, 0x18, 0x3f, 0x2f,
- 0x1a, 0xb1, 0x88, 0x8b, 0xc2, 0xcc, 0x87, 0xdd, 0xb8, 0xd7, 0x90, 0x7d,
- 0x26, 0x6d, 0xe0, 0x69, 0x68, 0xfd, 0x17, 0x94, 0x9c, 0xcd, 0xb9, 0x64,
- 0x65, 0x6b, 0x64, 0x5d, 0x85, 0x95, 0xcb, 0x1b, 0x3b, 0xcb, 0xa0, 0xb5,
- 0x78, 0x95, 0x6e, 0xbc, 0xaf, 0xfe, 0xa7, 0x35, 0x1f, 0xfe, 0xc4, 0x7a,
- 0x47, 0x2f, 0xd1, 0xd5, 0xa2, 0x3e, 0x77, 0x89, 0xb7, 0x3a, 0x1c, 0x33,
- 0x65, 0x7f, 0xee, 0xc7, 0xb8, 0xef, 0x84, 0x07, 0xed, 0xc9, 0x5f, 0x5a,
- 0xd9, 0xb0, 0xd0, 0x0c, 0x56, 0xa2, 0x42, 0xe8, 0x3b, 0x33, 0xeb, 0x17,
- 0x0a, 0x50, 0x1d, 0xa6, 0xe0, 0x65, 0xf1, 0xd3, 0x71, 0x58, 0xa6, 0xcc,
- 0x11, 0x2d, 0xdc, 0x91, 0x1c, 0xc2, 0x7b, 0xc9, 0xf4, 0x1f, 0xf8, 0xa0,
- 0x5d, 0xbc, 0xec, 0xd6, 0xe6, 0x9b, 0xdc, 0x51, 0xe5, 0x6f, 0xd0, 0x07,
- 0x1a, 0xec, 0x7a, 0x93, 0x67, 0xef, 0x14, 0x60, 0x6e, 0x91, 0x1e, 0x73,
- 0x1c, 0x73, 0x63, 0x59, 0x78, 0x88, 0xed, 0x86, 0x9b, 0xb5, 0xcc, 0x53,
- 0x4a, 0x8b, 0xec, 0x53, 0x51, 0x75, 0x8f, 0x3e, 0x88, 0x67, 0x8c, 0x78,
- 0xba, 0x4d, 0xd5, 0xf9, 0x3a, 0x0b, 0x25, 0xda, 0xed, 0xc4, 0x2a, 0xda,
- 0xfc, 0x65, 0x77, 0x39, 0x6a, 0x57, 0xeb, 0x9d, 0xe5, 0x6e, 0x6d, 0xf0,
- 0x6b, 0x8c, 0xaf, 0xcd, 0x85, 0x79, 0xff, 0xfb, 0x71, 0x17, 0x56, 0xd8,
- 0xfb, 0x08, 0xb9, 0xe2, 0x8c, 0x74, 0x1c, 0x5b, 0xc6, 0xac, 0xf5, 0xaf,
- 0x26, 0xb5, 0xc8, 0x53, 0x2a, 0xbb, 0x23, 0x40, 0x4c, 0x73, 0x3f, 0xf4,
- 0xe8, 0x2c, 0xeb, 0x54, 0x7b, 0xc1, 0x85, 0x5b, 0x4e, 0x09, 0xcd, 0x1c,
- 0x69, 0x1e, 0x42, 0xf9, 0x09, 0x6b, 0xfd, 0x0e, 0x43, 0x1b, 0xbc, 0xec,
- 0xce, 0xfe, 0xd7, 0x5a, 0xea, 0xad, 0x43, 0xc9, 0x3e, 0xda, 0x10, 0x71,
- 0xc5, 0x90, 0x9c, 0x87, 0x4b, 0xfc, 0x39, 0x31, 0xc5, 0x1f, 0xd3, 0x57,
- 0xdd, 0xa9, 0x20, 0xf9, 0xd4, 0x12, 0xd3, 0x90, 0xf9, 0x79, 0x14, 0x97,
- 0x8d, 0xac, 0x7f, 0x53, 0x43, 0x82, 0xd8, 0x2c, 0xc2, 0x3a, 0x18, 0xc5,
- 0x51, 0x62, 0xbc, 0x43, 0x6c, 0x09, 0xe7, 0x43, 0x3a, 0xb1, 0x59, 0x37,
- 0x5c, 0x63, 0x01, 0x35, 0x93, 0x8b, 0x19, 0xed, 0xf8, 0xf7, 0x98, 0x8f,
- 0x88, 0x8b, 0x1c, 0x42, 0xe0, 0xc4, 0xdf, 0x59, 0x55, 0xba, 0xde, 0x32,
- 0xa6, 0xb8, 0xee, 0x13, 0x11, 0xea, 0x98, 0xef, 0xc9, 0xb9, 0x15, 0xb3,
- 0x0b, 0xf7, 0x8c, 0x85, 0xf9, 0x7e, 0x15, 0x56, 0x9e, 0x88, 0xe2, 0x4a,
- 0xf2, 0x66, 0xcc, 0xd7, 0x38, 0x18, 0xc8, 0xaf, 0xd3, 0x8f, 0xd8, 0x67,
- 0x65, 0x0b, 0xba, 0xbd, 0x77, 0x74, 0xc8, 0x94, 0xfe, 0xdc, 0xc3, 0xbf,
- 0x03, 0xfc, 0x88, 0x3e, 0xbf, 0x55, 0xc4, 0x3a, 0xfb, 0x5b, 0xa3, 0x33,
- 0x6f, 0x55, 0xd8, 0x7b, 0x9a, 0x88, 0xf2, 0xb9, 0x90, 0x3d, 0x17, 0x1c,
- 0x26, 0xcd, 0xb3, 0xe3, 0xd2, 0xb7, 0xb5, 0xad, 0xf3, 0x15, 0xf7, 0xdf,
- 0xdf, 0x32, 0x5c, 0x58, 0xcf, 0xde, 0x3e, 0xa2, 0x4b, 0xbd, 0x1c, 0xd6,
- 0x6a, 0xb1, 0x0e, 0xa7, 0x43, 0x6c, 0xc2, 0xf5, 0x7f, 0x87, 0x23, 0xa1,
- 0x04, 0x73, 0xbe, 0x8e, 0x77, 0x73, 0x5f, 0x66, 0xbf, 0x53, 0x27, 0x67,
- 0x77, 0x70, 0xcb, 0x09, 0x2f, 0xd7, 0x5c, 0x4f, 0x5c, 0xb3, 0x09, 0x3f,
- 0x0b, 0x39, 0xbd, 0xc6, 0x61, 0x5e, 0x1f, 0x9d, 0x0e, 0x10, 0x8b, 0xfa,
- 0xf8, 0xb9, 0x91, 0xb7, 0x2f, 0xe2, 0x49, 0x64, 0xf9, 0xd7, 0x78, 0xf2,
- 0x11, 0x0f, 0xe8, 0xb8, 0x9a, 0x7b, 0x09, 0x57, 0x48, 0x3b, 0x3b, 0xed,
- 0xd0, 0x3c, 0x5e, 0x10, 0xba, 0xb2, 0x5e, 0x6c, 0xb0, 0xd6, 0x2d, 0xf4,
- 0x03, 0x72, 0x8e, 0xf7, 0xdf, 0xb8, 0x06, 0x91, 0xdd, 0x09, 0xf6, 0xc7,
- 0x46, 0x03, 0xda, 0x43, 0xb4, 0x97, 0x29, 0x6b, 0x68, 0xec, 0x45, 0xe5,
- 0xdd, 0x08, 0x56, 0x8c, 0x59, 0x43, 0x91, 0x94, 0x5c, 0xb7, 0xac, 0xea,
- 0xb5, 0x7a, 0xe4, 0x0d, 0xe5, 0x61, 0xad, 0xf3, 0x50, 0x07, 0xa3, 0x38,
- 0x9b, 0x6b, 0xbc, 0xf8, 0x1e, 0xb1, 0x53, 0x94, 0xbd, 0xde, 0x25, 0xf7,
- 0x28, 0x66, 0x72, 0xff, 0xb1, 0x52, 0x66, 0x04, 0xa3, 0x85, 0x80, 0x9a,
- 0xce, 0xfd, 0x49, 0xa5, 0xe4, 0xa2, 0x11, 0xfa, 0x42, 0xd3, 0x98, 0xf0,
- 0x6a, 0x0d, 0x55, 0x91, 0xce, 0x51, 0xd2, 0x99, 0x5e, 0xa3, 0x67, 0x46,
- 0x94, 0xe8, 0x2c, 0x40, 0x5c, 0xf7, 0xaa, 0xcc, 0xcf, 0xa8, 0xb7, 0xa7,
- 0xf9, 0xbc, 0xe8, 0x2d, 0x8c, 0x9f, 0x15, 0xe9, 0x3c, 0x56, 0xb8, 0x88,
- 0xe9, 0xdc, 0x25, 0xfb, 0xf7, 0x91, 0x42, 0x82, 0xb5, 0xaf, 0x0f, 0x79,
- 0xe6, 0x93, 0xb1, 0x5c, 0x63, 0x66, 0x8c, 0x7c, 0x38, 0x67, 0xee, 0xfa,
- 0xf0, 0x64, 0xf1, 0x99, 0x61, 0xbe, 0x3b, 0x7c, 0xed, 0x77, 0xd1, 0x91,
- 0xb3, 0xaf, 0xef, 0xec, 0x2b, 0x94, 0xd3, 0x76, 0x4e, 0x1f, 0x7e, 0xd8,
- 0xf4, 0xca, 0x0c, 0x1c, 0x2f, 0x8d, 0xaf, 0xc7, 0x88, 0xf1, 0x97, 0xd8,
- 0x45, 0xb9, 0x47, 0xa9, 0xcf, 0x13, 0xa6, 0xbd, 0x7f, 0x2f, 0xe7, 0xba,
- 0x98, 0xab, 0xbb, 0x5a, 0xcf, 0x10, 0x8b, 0x1d, 0x63, 0xcc, 0xec, 0x49,
- 0x36, 0x76, 0xbf, 0x4c, 0xbf, 0x4b, 0x7f, 0x5d, 0xf6, 0xc8, 0x81, 0xb1,
- 0x89, 0x6f, 0x63, 0xaa, 0xa6, 0x71, 0xe1, 0x59, 0xe6, 0x84, 0xd3, 0xcc,
- 0x53, 0x1e, 0xe6, 0x84, 0xea, 0x09, 0x62, 0x48, 0xe6, 0xa9, 0x79, 0xe6,
- 0x29, 0x8f, 0xde, 0x78, 0x71, 0x06, 0xff, 0x9d, 0x7a, 0x11, 0xfe, 0x62,
- 0x89, 0x19, 0xc8, 0xb3, 0xce, 0xfc, 0x55, 0x9f, 0xe9, 0xc7, 0xa5, 0x9b,
- 0x9d, 0x19, 0x9a, 0x9b, 0x35, 0x7b, 0x77, 0xae, 0x31, 0x34, 0x22, 0xb4,
- 0x7b, 0xb4, 0x48, 0x96, 0xb6, 0x3a, 0x62, 0x63, 0xef, 0x6e, 0xf6, 0x0b,
- 0x72, 0x8e, 0xab, 0x0a, 0x1e, 0xfa, 0xfe, 0x88, 0x21, 0xe7, 0x1b, 0x22,
- 0xc1, 0xcd, 0xb4, 0xe1, 0x88, 0xd9, 0xd8, 0x12, 0x53, 0x3b, 0x70, 0xa9,
- 0x98, 0x63, 0x1d, 0x2c, 0xad, 0x65, 0x8e, 0xa2, 0xb1, 0xfb, 0x7e, 0x7c,
- 0x03, 0xe9, 0x9a, 0xc6, 0xde, 0x71, 0xc4, 0x8c, 0x7b, 0x21, 0xe7, 0x41,
- 0x1d, 0x5a, 0xf5, 0x79, 0x37, 0xf1, 0xc8, 0x27, 0xd6, 0x52, 0xfd, 0x31,
- 0x8c, 0x13, 0x33, 0x36, 0xac, 0xd2, 0x2f, 0x7e, 0xbf, 0x78, 0xcf, 0xd9,
- 0x2b, 0x12, 0x7f, 0xf1, 0x51, 0x07, 0xe5, 0xf0, 0x2c, 0xaa, 0xe3, 0x1a,
- 0xd4, 0x85, 0x7d, 0x56, 0xf8, 0x55, 0x1c, 0xa0, 0xbf, 0x8d, 0x17, 0x14,
- 0x8c, 0xfa, 0x57, 0x31, 0x20, 0xb5, 0x89, 0xef, 0xb4, 0xe5, 0x02, 0xc4,
- 0x29, 0x11, 0x94, 0xeb, 0xb1, 0xe8, 0x30, 0xe5, 0x6b, 0x63, 0x2e, 0x1f,
- 0x65, 0x0e, 0xc9, 0x86, 0x02, 0xf6, 0xf9, 0xd5, 0x72, 0x3d, 0x62, 0xff,
- 0xcf, 0x81, 0xf4, 0x41, 0x0d, 0x53, 0xb2, 0x4f, 0x7d, 0x08, 0xaf, 0x8e,
- 0xcf, 0xe3, 0x58, 0x32, 0x8d, 0xbd, 0x35, 0x21, 0x8c, 0x99, 0x8b, 0xed,
- 0xb9, 0x81, 0xf4, 0x5b, 0x5b, 0x26, 0x0e, 0xda, 0xb3, 0xc8, 0x8d, 0x49,
- 0x57, 0xbd, 0x9c, 0xe3, 0x98, 0x66, 0xdf, 0x35, 0x6e, 0x0c, 0xe1, 0x80,
- 0xf1, 0xc7, 0x30, 0x16, 0x49, 0xee, 0x1c, 0xc1, 0xf9, 0x29, 0xa9, 0x61,
- 0xfd, 0xad, 0xcb, 0xc6, 0x44, 0x3f, 0x2e, 0x62, 0x5e, 0x1f, 0x9a, 0x6c,
- 0x0c, 0x37, 0xd7, 0xba, 0x7c, 0xca, 0xc1, 0x72, 0x4d, 0x79, 0x39, 0x73,
- 0x5d, 0x85, 0x20, 0xf5, 0x75, 0x21, 0xe9, 0x65, 0xce, 0x11, 0x7d, 0xca,
- 0x19, 0x3f, 0x47, 0xce, 0x44, 0x5e, 0x61, 0xa4, 0xf9, 0xc6, 0xfd, 0x15,
- 0xf9, 0xff, 0x83, 0x6b, 0xe7, 0x0e, 0x8b, 0xb3, 0xf1, 0x3f, 0xb7, 0x2e,
- 0xdd, 0x24, 0x72, 0x27, 0x03, 0xcc, 0xe9, 0xd1, 0xa9, 0x6b, 0xfa, 0x15,
- 0x9d, 0x9e, 0x93, 0x9a, 0x61, 0xeb, 0xdc, 0x99, 0xb7, 0x69, 0x03, 0xef,
- 0xa8, 0x46, 0xd6, 0x13, 0xfa, 0x55, 0x0d, 0xfd, 0xad, 0x09, 0xbd, 0x4b,
- 0x53, 0x9e, 0x9e, 0xab, 0xe6, 0x7a, 0xb4, 0xac, 0x7e, 0xd7, 0xc2, 0xcd,
- 0x6d, 0x70, 0xeb, 0x72, 0x7d, 0xca, 0x4a, 0x87, 0xe4, 0x77, 0x33, 0x20,
- 0xb5, 0xfc, 0x05, 0x73, 0xde, 0x5a, 0xbe, 0xd8, 0xc1, 0x86, 0x7f, 0x97,
- 0x93, 0xbd, 0xaf, 0xac, 0xc5, 0x5e, 0xfb, 0xe2, 0xdb, 0xee, 0x83, 0xf8,
- 0xdb, 0xfc, 0x21, 0xbc, 0x39, 0xee, 0x21, 0xce, 0x14, 0x59, 0xd6, 0xa3,
- 0x7a, 0x75, 0x3c, 0xfd, 0x2e, 0xf3, 0xe2, 0xc5, 0xa9, 0x92, 0x5f, 0xcc,
- 0xb5, 0xae, 0x98, 0x52, 0xa4, 0x55, 0x85, 0x32, 0xca, 0xf9, 0x53, 0xc3,
- 0x8d, 0x68, 0x11, 0xdb, 0xba, 0xc9, 0xe7, 0xee, 0x9c, 0x83, 0x79, 0x63,
- 0xf9, 0xc3, 0x01, 0x67, 0xfe, 0x15, 0x60, 0x1e, 0x1d, 0xc5, 0x91, 0x5c,
- 0x63, 0xe2, 0x3d, 0x39, 0xa7, 0xc3, 0x5e, 0xec, 0x12, 0x46, 0x71, 0x22,
- 0x57, 0xca, 0xa1, 0x11, 0x39, 0xdf, 0x9a, 0x88, 0xba, 0x9c, 0x1c, 0x19,
- 0x75, 0x69, 0xd9, 0xa8, 0xeb, 0xe6, 0x80, 0x60, 0x83, 0xe1, 0x42, 0x2c,
- 0x52, 0x0e, 0x37, 0xf6, 0x18, 0x8e, 0x7f, 0xd4, 0xcf, 0x78, 0x11, 0x5d,
- 0x24, 0x75, 0x59, 0x6a, 0xb2, 0x87, 0x35, 0x79, 0x31, 0xd2, 0x8b, 0x3d,
- 0x78, 0x4d, 0x17, 0x7d, 0xec, 0x2f, 0xe9, 0xc3, 0x38, 0x87, 0xfd, 0xd6,
- 0x7c, 0xb7, 0xf8, 0x92, 0x17, 0x87, 0x9a, 0xa6, 0xad, 0xa9, 0xb0, 0xc8,
- 0xee, 0xc6, 0x69, 0xe6, 0x57, 0xdc, 0x1c, 0x8b, 0x9c, 0x66, 0xcd, 0x1e,
- 0xd1, 0x4b, 0x3e, 0x7e, 0x57, 0x91, 0x4f, 0x3d, 0x33, 0x8b, 0x3f, 0xe1,
- 0xef, 0xf5, 0x91, 0xbd, 0xca, 0x59, 0x6f, 0xf9, 0xcc, 0xdb, 0x81, 0xd2,
- 0xec, 0x54, 0x9e, 0x8d, 0xe6, 0x09, 0x3a, 0x2b, 0x84, 0x56, 0x80, 0xfe,
- 0x59, 0x8e, 0xde, 0xb0, 0x9c, 0xf3, 0x10, 0xbd, 0xc8, 0x9e, 0x22, 0xa8,
- 0x0f, 0x0b, 0x2f, 0x51, 0x1f, 0x87, 0xae, 0x9d, 0xa9, 0x72, 0xf2, 0x57,
- 0x05, 0xaf, 0x6f, 0x4e, 0xbe, 0xb8, 0xce, 0x8f, 0xdf, 0x58, 0x97, 0xc2,
- 0x11, 0xe6, 0x04, 0xb1, 0x69, 0xc6, 0xc6, 0x91, 0x6e, 0xe2, 0x93, 0xdd,
- 0xf6, 0xf9, 0x11, 0xc6, 0x81, 0x79, 0x4d, 0x8e, 0xf9, 0x3e, 0xe2, 0xec,
- 0xb9, 0x9c, 0x7d, 0x66, 0xaf, 0xf7, 0x0d, 0x15, 0x63, 0xae, 0xf9, 0x12,
- 0x7a, 0x6b, 0x85, 0x5e, 0x28, 0xb8, 0x6d, 0x32, 0x41, 0x1d, 0xd4, 0x09,
- 0x5d, 0xeb, 0x29, 0x76, 0x73, 0x87, 0xc6, 0x84, 0x3e, 0x30, 0x32, 0x16,
- 0xeb, 0xff, 0x29, 0xb0, 0xae, 0x0a, 0xda, 0xe0, 0x6c, 0xf1, 0xff, 0x38,
- 0x7e, 0xa1, 0x84, 0x96, 0xd0, 0xf1, 0xc0, 0x64, 0x8e, 0x3b, 0x3e, 0x57,
- 0x41, 0xdd, 0x69, 0xdd, 0x3f, 0x50, 0x15, 0x78, 0xec, 0x89, 0x04, 0x79,
- 0x5f, 0x14, 0xdc, 0x3c, 0xe9, 0x83, 0xff, 0x4c, 0x15, 0x6b, 0xae, 0x0f,
- 0x97, 0x9b, 0x69, 0xd7, 0x27, 0x4a, 0xbc, 0xdb, 0x7b, 0xa3, 0x78, 0x74,
- 0x22, 0x0a, 0x93, 0x3e, 0x3b, 0x67, 0xca, 0x3e, 0xb0, 0xcf, 0xce, 0x9f,
- 0x17, 0xd7, 0xd4, 0xd9, 0x7b, 0x54, 0xcf, 0x16, 0xf4, 0xc8, 0x59, 0x55,
- 0x85, 0x0f, 0x4e, 0xcc, 0xdf, 0x5c, 0x0e, 0xeb, 0x85, 0xa5, 0xa9, 0x78,
- 0x66, 0x17, 0x7d, 0x7e, 0xc5, 0xf2, 0x30, 0x7b, 0x19, 0xf6, 0x94, 0x6b,
- 0xa5, 0xff, 0x1d, 0x60, 0xff, 0x5b, 0xda, 0xd3, 0xd7, 0xfb, 0x1f, 0x52,
- 0xd9, 0x4d, 0x41, 0x58, 0x1f, 0x95, 0xa7, 0xac, 0x8f, 0xbd, 0xa9, 0x38,
- 0xdf, 0x97, 0x3d, 0x3d, 0xcb, 0x7a, 0xab, 0xd9, 0xb2, 0xf2, 0xcd, 0xb1,
- 0x4c, 0xc8, 0x1d, 0xc2, 0x99, 0x06, 0xd9, 0x07, 0x74, 0xe1, 0x83, 0xb8,
- 0x1e, 0xd9, 0x05, 0xd9, 0x7b, 0x67, 0x8e, 0x5f, 0x2c, 0xe7, 0x0e, 0xeb,
- 0x82, 0x9d, 0xe6, 0x22, 0x3c, 0x33, 0xbb, 0x16, 0xbd, 0x5e, 0xd8, 0xe7,
- 0x62, 0x2c, 0x03, 0x6f, 0x2c, 0x85, 0xd4, 0xed, 0x78, 0xcb, 0x43, 0x08,
- 0x63, 0xb6, 0x70, 0x08, 0x0f, 0x9e, 0x90, 0xfd, 0xc5, 0x07, 0x5a, 0x7d,
- 0x27, 0xac, 0xbf, 0x8b, 0xa4, 0xe6, 0x99, 0x17, 0x2d, 0xab, 0x62, 0x6d,
- 0x63, 0x84, 0xe5, 0x88, 0x18, 0xa3, 0x57, 0xb0, 0x7b, 0xff, 0x07, 0xa8,
- 0xc1, 0xd9, 0xe9, 0xf4, 0xcd, 0xec, 0x25, 0x3b, 0x9f, 0x54, 0x21, 0x3c,
- 0x4f, 0x19, 0x9f, 0x2e, 0x08, 0x4e, 0x79, 0xb0, 0x75, 0xcb, 0x89, 0x25,
- 0x78, 0x61, 0x36, 0x8c, 0xb3, 0xa6, 0x4e, 0x9c, 0x04, 0x55, 0x99, 0xb2,
- 0xaa, 0xab, 0xc9, 0x6b, 0xa5, 0xdb, 0x8d, 0x4d, 0x49, 0xe9, 0x0f, 0xf5,
- 0xfe, 0x80, 0xc2, 0x92, 0x72, 0xe8, 0x0b, 0xfb, 0x81, 0x01, 0x3f, 0xfb,
- 0xd5, 0x27, 0x55, 0x3c, 0xf3, 0xbe, 0x3b, 0x8c, 0xe7, 0x99, 0x7f, 0x7e,
- 0x50, 0x90, 0x33, 0x53, 0xcc, 0x31, 0xd3, 0x51, 0xda, 0xca, 0x07, 0x57,
- 0x7d, 0x15, 0x0e, 0x33, 0x5e, 0x5e, 0x32, 0xca, 0x98, 0xa3, 0xe4, 0x0c,
- 0x95, 0xe4, 0xf7, 0x9d, 0x72, 0x56, 0xc4, 0x7a, 0x56, 0x77, 0xfa, 0x7d,
- 0x63, 0xe6, 0xc6, 0x73, 0xc8, 0x21, 0xe6, 0xf5, 0xc6, 0xee, 0x88, 0x7a,
- 0xc5, 0x4a, 0x7f, 0x5d, 0x51, 0xce, 0xdd, 0x55, 0xa8, 0xb0, 0x65, 0xc5,
- 0xf0, 0x44, 0xa9, 0xa6, 0x54, 0x4b, 0x2f, 0xd7, 0x9d, 0x2d, 0xfa, 0x60,
- 0x25, 0x63, 0xfd, 0x28, 0x6b, 0x74, 0xf9, 0x09, 0xa9, 0x25, 0xec, 0x5f,
- 0xd4, 0x7a, 0x62, 0x61, 0xc1, 0x0d, 0x3e, 0xdc, 0x1f, 0xd2, 0x5a, 0xe4,
- 0x2c, 0xf6, 0xd3, 0x85, 0x0e, 0x8f, 0x9c, 0x89, 0x7a, 0xa6, 0x20, 0xb5,
- 0x5c, 0x72, 0x41, 0x69, 0xbd, 0x08, 0x6a, 0xc7, 0xc4, 0x46, 0xdd, 0xad,
- 0x1f, 0x8d, 0x05, 0xe4, 0xdc, 0xfc, 0x90, 0x8b, 0xbd, 0xb6, 0x6f, 0xcc,
- 0xb2, 0xee, 0x6e, 0xd6, 0xfb, 0xd7, 0xbb, 0x65, 0x3f, 0x39, 0xd6, 0x7b,
- 0x4e, 0x69, 0x2d, 0x47, 0xd4, 0x8d, 0x74, 0x9e, 0xab, 0x92, 0x18, 0xc9,
- 0x52, 0xce, 0x47, 0x6d, 0x99, 0xf6, 0x53, 0xa6, 0xd2, 0x99, 0xa1, 0x2a,
- 0x5c, 0x1e, 0x87, 0xce, 0xa8, 0xc5, 0x79, 0x83, 0xc9, 0x29, 0x14, 0x4f,
- 0xb7, 0x43, 0xfc, 0x5f, 0xeb, 0x15, 0x0c, 0x55, 0xc9, 0x9c, 0x3c, 0x3d,
- 0x2e, 0x35, 0x46, 0x09, 0x3e, 0xc9, 0x56, 0xa7, 0x06, 0x70, 0x65, 0x0d,
- 0xf0, 0xca, 0x98, 0xb3, 0xdf, 0x5e, 0x3c, 0xe3, 0x6d, 0x9f, 0x65, 0x78,
- 0xc8, 0x3e, 0xa3, 0x20, 0xf4, 0x0f, 0xe2, 0x4c, 0x4e, 0x30, 0xe5, 0x00,
- 0x31, 0x65, 0x6c, 0x90, 0x78, 0xb3, 0xa5, 0xe0, 0x9c, 0xb7, 0x32, 0x3e,
- 0xa2, 0xcf, 0x3f, 0x49, 0xac, 0x7a, 0x18, 0xce, 0x7e, 0x7b, 0x43, 0xf1,
- 0x0c, 0x42, 0x2c, 0xdf, 0xa9, 0xb6, 0x16, 0xec, 0x33, 0x5a, 0x8c, 0xb1,
- 0x76, 0xb5, 0x79, 0xb6, 0x43, 0x6d, 0x99, 0xed, 0x52, 0x3b, 0x0a, 0xd2,
- 0xb3, 0x3e, 0xd0, 0x7a, 0xff, 0x89, 0xed, 0x6a, 0xeb, 0x74, 0x8f, 0x22,
- 0xa6, 0x0d, 0xf9, 0x52, 0x19, 0xd5, 0x35, 0xeb, 0xcc, 0xcf, 0x3b, 0xd9,
- 0x77, 0x6d, 0x35, 0x4b, 0xfd, 0xbc, 0xfc, 0x1f, 0x57, 0x58, 0xfe, 0x67,
- 0xa2, 0x77, 0xa3, 0xb2, 0xac, 0x5b, 0x93, 0x7f, 0x2d, 0xf6, 0xb0, 0x9e,
- 0x4e, 0xb2, 0x36, 0x9a, 0x55, 0xe8, 0x63, 0xdf, 0x31, 0x6c, 0x2c, 0x2b,
- 0xee, 0x97, 0x89, 0x4c, 0x72, 0x4e, 0x42, 0xfc, 0x15, 0x59, 0xf6, 0x20,
- 0xf8, 0x7b, 0xf2, 0xbf, 0xb7, 0x28, 0x57, 0x97, 0x9c, 0x23, 0xf0, 0x5e,
- 0x3f, 0x47, 0x76, 0x6c, 0xec, 0xba, 0x5c, 0x1e, 0x5e, 0x1b, 0x25, 0x3e,
- 0xdd, 0xab, 0xb4, 0xc1, 0xa7, 0x1c, 0xb9, 0x2e, 0x5e, 0x66, 0x0c, 0x0f,
- 0xdb, 0x31, 0xec, 0xc8, 0xb5, 0xb2, 0x28, 0xd7, 0x8a, 0x7c, 0xa7, 0x7d,
- 0x3e, 0x8b, 0x74, 0x5a, 0xe7, 0xc6, 0xe4, 0x1c, 0x99, 0xcc, 0x2e, 0x45,
- 0x36, 0x91, 0xe3, 0x84, 0x55, 0xa1, 0x77, 0xa9, 0x6d, 0xf6, 0xb9, 0x32,
- 0x39, 0xd3, 0x25, 0xfb, 0xfb, 0x25, 0xb9, 0xa4, 0x8e, 0x2f, 0x0a, 0x76,
- 0x4c, 0xca, 0x39, 0x6b, 0xcb, 0xfa, 0x99, 0x51, 0x11, 0x14, 0x59, 0xce,
- 0x1a, 0x22, 0x8b, 0x9c, 0x17, 0x29, 0xc9, 0xf3, 0xb5, 0xa2, 0x3c, 0x62,
- 0xab, 0xeb, 0x76, 0x2a, 0xfd, 0xff, 0xdf, 0xdb, 0x39, 0xe7, 0x2c, 0x49,
- 0x49, 0x9e, 0x60, 0x4a, 0xf8, 0xcf, 0xb7, 0x8e, 0x8e, 0x0f, 0xe0, 0x15,
- 0xde, 0xff, 0x65, 0xae, 0x24, 0x97, 0x1b, 0x33, 0xd3, 0xa5, 0x33, 0x72,
- 0x6c, 0x29, 0xcd, 0x98, 0x31, 0x42, 0x3f, 0x72, 0xe4, 0x93, 0x33, 0x72,
- 0x8d, 0xf3, 0x97, 0xed, 0xb9, 0x57, 0x3c, 0xcd, 0x7e, 0x19, 0x67, 0x0b,
- 0xbf, 0x6d, 0xbf, 0xa6, 0x7c, 0x05, 0x7b, 0x64, 0xa1, 0x3d, 0x47, 0xda,
- 0x72, 0x96, 0x44, 0xe1, 0xa9, 0x69, 0x60, 0xda, 0xe4, 0xb2, 0xa9, 0x21,
- 0x3c, 0x6e, 0x58, 0xd6, 0x93, 0xcd, 0xba, 0x9c, 0x01, 0xba, 0x50, 0x6b,
- 0xcf, 0x85, 0x60, 0x54, 0xe9, 0xb2, 0x77, 0x27, 0xe7, 0x48, 0x7a, 0xa8,
- 0x03, 0x91, 0x5d, 0x7c, 0xa0, 0x64, 0x7b, 0x39, 0xdf, 0x96, 0xa5, 0x7e,
- 0x44, 0x37, 0xa5, 0x73, 0x6e, 0x32, 0x73, 0xb9, 0x51, 0x27, 0xb7, 0xd9,
- 0x3a, 0x79, 0xda, 0x10, 0x7f, 0x65, 0xf6, 0xa1, 0xaf, 0xce, 0x10, 0x3f,
- 0x8c, 0x18, 0x5e, 0x1b, 0xab, 0x1d, 0x26, 0x3e, 0x39, 0xc2, 0xd8, 0x79,
- 0xd4, 0xbc, 0x88, 0x8b, 0xf9, 0x97, 0xf0, 0xca, 0xb5, 0xff, 0x85, 0x13,
- 0x7f, 0xf1, 0xb5, 0x6c, 0xb1, 0xcf, 0x32, 0xfd, 0x75, 0xcb, 0xb2, 0xb8,
- 0xe4, 0xa1, 0x93, 0x4d, 0x72, 0xb6, 0xa9, 0x3c, 0xf5, 0xde, 0x3a, 0xd9,
- 0xdf, 0x2a, 0x4b, 0x0d, 0x7e, 0xf5, 0x82, 0x2e, 0xba, 0xf9, 0x64, 0xf5,
- 0x19, 0x5d, 0xe4, 0xd2, 0x8d, 0x51, 0xfb, 0x7f, 0x33, 0x43, 0x6b, 0x77,
- 0xeb, 0x12, 0x3b, 0xef, 0x34, 0xb7, 0xd9, 0x39, 0x61, 0x30, 0x75, 0xab,
- 0xad, 0x83, 0x83, 0xa9, 0x65, 0x8e, 0x2e, 0x52, 0x09, 0xfb, 0xfb, 0xe1,
- 0x94, 0xa3, 0x9b, 0x5c, 0xaa, 0xde, 0xfe, 0x1e, 0x4d, 0x39, 0x67, 0xa2,
- 0xb3, 0x29, 0xdd, 0xfe, 0x1e, 0x4f, 0xc5, 0xec, 0xef, 0x23, 0xa9, 0x5b,
- 0xae, 0xf3, 0xc5, 0x9f, 0xff, 0x07, 0xd8, 0xc4, 0xd3, 0xb4, 0xb4, 0x3a,
+ 0xad, 0x7b, 0x0f, 0x70, 0x54, 0xe7, 0x75, 0xef, 0xef, 0xee, 0x1f, 0x69,
+ 0x57, 0x5a, 0xad, 0x2e, 0x78, 0xc1, 0xab, 0x54, 0x29, 0x7b, 0xd9, 0xbb,
+ 0xd2, 0x1a, 0x09, 0xb8, 0x0b, 0xc2, 0x88, 0xe8, 0xd6, 0x6c, 0x85, 0x00,
+ 0x21, 0x64, 0x2c, 0x63, 0x25, 0x15, 0x7d, 0x9e, 0x5a, 0x0f, 0x64, 0x23,
+ 0xdb, 0xd8, 0x16, 0x35, 0x6d, 0xe5, 0xd4, 0xad, 0xd6, 0x92, 0xc0, 0xc2,
+ 0xac, 0xb8, 0x22, 0x0b, 0x11, 0xee, 0xf4, 0xbd, 0xc8, 0x96, 0xb0, 0xb0,
+ 0xb3, 0x62, 0xed, 0xa4, 0xaf, 0xd3, 0xcc, 0x34, 0xe3, 0x7d, 0xfe, 0x83,
+ 0x49, 0x1e, 0xb6, 0xd3, 0x4e, 0xe7, 0x3d, 0xa7, 0xf3, 0xde, 0x84, 0x17,
+ 0x63, 0x62, 0xa7, 0x89, 0xed, 0xe6, 0xa5, 0xf3, 0x44, 0xea, 0xf8, 0xbe,
+ 0xdf, 0xb9, 0x77, 0x17, 0x88, 0x9b, 0x4e, 0x67, 0x3a, 0x4f, 0x33, 0x9a,
+ 0xd5, 0xde, 0x3f, 0xdf, 0x77, 0xce, 0xf9, 0xce, 0xf9, 0x9d, 0xdf, 0x39,
+ 0xdf, 0xa7, 0x06, 0xa0, 0x0a, 0xa5, 0x9f, 0x1a, 0xfe, 0xb6, 0x0c, 0x0d,
+ 0x1f, 0x4a, 0xad, 0xb9, 0x75, 0x0d, 0xff, 0xbc, 0x15, 0x6a, 0x85, 0x4f,
+ 0x6e, 0xde, 0xaa, 0x00, 0xfd, 0x3f, 0xc6, 0xbf, 0xeb, 0xe7, 0xf3, 0xff,
+ 0xbe, 0xd7, 0x9c, 0x1f, 0x2f, 0xa0, 0x96, 0xe5, 0x92, 0x5f, 0x04, 0x3c,
+ 0xe6, 0xcc, 0x17, 0xda, 0x75, 0x04, 0xbc, 0x66, 0xaf, 0xb9, 0x4f, 0x07,
+ 0xd2, 0xf9, 0xa6, 0xd8, 0x16, 0xfc, 0xd2, 0xce, 0x44, 0x7c, 0x90, 0xeb,
+ 0x9f, 0x37, 0x3f, 0x19, 0xf9, 0xf6, 0x46, 0xed, 0xe3, 0x19, 0x2f, 0x02,
+ 0xaa, 0x79, 0x1a, 0x6a, 0x03, 0x02, 0xf5, 0x7c, 0xe7, 0xcf, 0x1b, 0xfd,
+ 0x5e, 0x84, 0xcb, 0x63, 0xb5, 0x62, 0xcc, 0x42, 0x26, 0x60, 0x0e, 0xa1,
+ 0x72, 0x03, 0xf0, 0x5e, 0x36, 0x61, 0x8c, 0x01, 0x53, 0x1e, 0x33, 0x11,
+ 0x7b, 0x05, 0x06, 0x0e, 0x17, 0x62, 0xe8, 0xe0, 0xef, 0x0e, 0xeb, 0x53,
+ 0x3b, 0xe6, 0x47, 0xc6, 0xcb, 0xe7, 0xf6, 0xb6, 0x00, 0x5b, 0xb3, 0x06,
+ 0x8e, 0x58, 0x08, 0xd4, 0x99, 0x8f, 0x63, 0x13, 0x3f, 0xc3, 0xe6, 0x30,
+ 0xde, 0x9a, 0x8c, 0xc7, 0x9e, 0x83, 0xd6, 0xa7, 0x7b, 0xb5, 0x61, 0xa0,
+ 0x69, 0x70, 0x40, 0xd1, 0xfa, 0xdf, 0x56, 0xb4, 0x9e, 0x49, 0x05, 0x01,
+ 0x85, 0xcf, 0x35, 0xe5, 0xe5, 0x73, 0x18, 0xab, 0xf2, 0x01, 0x5c, 0xf2,
+ 0xca, 0xfc, 0xbf, 0x45, 0x7b, 0x2b, 0xf0, 0xe9, 0xad, 0x18, 0xa7, 0x0c,
+ 0x7e, 0x53, 0xc1, 0xb3, 0x2d, 0x89, 0xe8, 0x28, 0xe4, 0x7e, 0x0c, 0x5b,
+ 0x0a, 0xf2, 0xa9, 0x51, 0x6b, 0xdb, 0x1e, 0x37, 0x6c, 0xfb, 0x8c, 0x51,
+ 0x89, 0x8c, 0xaa, 0x45, 0x01, 0x05, 0xa3, 0x86, 0x07, 0x69, 0xb5, 0x3d,
+ 0xe6, 0x83, 0x16, 0xbd, 0x17, 0xff, 0x4c, 0x9d, 0xd3, 0x49, 0x3f, 0xdc,
+ 0xe7, 0xfb, 0x51, 0x89, 0xa2, 0xea, 0x5a, 0xed, 0xd9, 0xac, 0x6d, 0x9f,
+ 0xd7, 0x7d, 0x38, 0x43, 0xfb, 0x8c, 0xe6, 0xff, 0xd9, 0x2e, 0xd2, 0x36,
+ 0xe3, 0x7a, 0x79, 0xfe, 0x00, 0x66, 0x54, 0xdb, 0x9e, 0xe5, 0xbd, 0x23,
+ 0xf9, 0xb2, 0x9d, 0x6d, 0xdb, 0xa3, 0xdb, 0xf6, 0x3e, 0xfd, 0x17, 0xf6,
+ 0xde, 0x5f, 0x79, 0xd6, 0xb6, 0x9f, 0x32, 0x6e, 0xc2, 0xd9, 0x5c, 0x87,
+ 0xd2, 0x35, 0xbf, 0x3c, 0xbc, 0x63, 0xda, 0xc6, 0x79, 0x03, 0xaa, 0xc7,
+ 0xdc, 0xa6, 0xec, 0x98, 0xef, 0x54, 0xb6, 0x16, 0x76, 0x2b, 0xdb, 0x66,
+ 0x7f, 0x57, 0xe9, 0x9c, 0xef, 0x57, 0xb6, 0x17, 0xa2, 0x98, 0xb3, 0x22,
+ 0x98, 0xb5, 0xfa, 0x94, 0x8e, 0xf9, 0x5e, 0xc5, 0xd5, 0x63, 0x58, 0x69,
+ 0x2f, 0x94, 0xc7, 0xba, 0x6e, 0xc7, 0x1d, 0x59, 0x13, 0x13, 0x56, 0x25,
+ 0xe7, 0x59, 0xb4, 0xbf, 0xdd, 0xb8, 0x48, 0x3d, 0x0d, 0x1c, 0x2d, 0x3c,
+ 0x85, 0xdb, 0xa7, 0x6d, 0x3b, 0x9f, 0x02, 0xf2, 0x05, 0xe0, 0xeb, 0x56,
+ 0xbc, 0x67, 0x50, 0xb1, 0xed, 0xed, 0x09, 0x7b, 0xc5, 0x15, 0xa3, 0x29,
+ 0xf9, 0x1a, 0xfe, 0xaf, 0x3d, 0x13, 0x41, 0x26, 0xc4, 0x31, 0x8e, 0x71,
+ 0xcd, 0x1e, 0x98, 0x44, 0xa0, 0xd2, 0x1c, 0xc7, 0x8f, 0xb2, 0x08, 0x54,
+ 0x98, 0x19, 0x9c, 0xcf, 0x8e, 0xaa, 0x01, 0xc4, 0xa3, 0x3b, 0x94, 0xcc,
+ 0xb0, 0x07, 0xda, 0xd0, 0xbb, 0xd0, 0x62, 0x5c, 0x8f, 0x0b, 0xaf, 0x2a,
+ 0x5a, 0xf1, 0x35, 0x68, 0xe9, 0x5f, 0x28, 0x5a, 0x67, 0x9d, 0x17, 0x69,
+ 0x4f, 0x22, 0x80, 0x6f, 0x37, 0xca, 0x9a, 0x8c, 0x63, 0x8d, 0xb3, 0x36,
+ 0x19, 0xdc, 0x72, 0x6d, 0x6d, 0x4c, 0x8c, 0x52, 0xae, 0x23, 0x94, 0xeb,
+ 0x75, 0x43, 0x8b, 0x3e, 0x0b, 0x7b, 0xc5, 0x80, 0x21, 0xf7, 0x4c, 0x8c,
+ 0x17, 0xec, 0x58, 0xd8, 0xbc, 0x44, 0x79, 0x91, 0xf9, 0x9c, 0x19, 0xc8,
+ 0xd4, 0x9a, 0xbf, 0xb4, 0xdf, 0xdc, 0x10, 0xc5, 0xcb, 0x85, 0x08, 0x5e,
+ 0x2a, 0xa8, 0x78, 0xb1, 0xd0, 0x01, 0xab, 0x80, 0xf0, 0xed, 0x85, 0x5f,
+ 0xe7, 0xc7, 0x36, 0x42, 0x7c, 0x9e, 0x72, 0x87, 0x77, 0x16, 0x7c, 0xfd,
+ 0x15, 0x26, 0x7a, 0xbe, 0x93, 0x1d, 0xb1, 0xab, 0x74, 0xf4, 0x2f, 0x31,
+ 0xf5, 0xf4, 0x2a, 0x25, 0xd4, 0x4a, 0x3f, 0xec, 0x79, 0x23, 0xdf, 0xea,
+ 0xd3, 0x8f, 0x07, 0xe1, 0xa7, 0xfd, 0xb7, 0x16, 0x6c, 0x7b, 0xcc, 0x38,
+ 0xb8, 0x76, 0x6f, 0xeb, 0x37, 0x8b, 0x3d, 0x7a, 0x37, 0x32, 0x85, 0x01,
+ 0x20, 0x6c, 0xf2, 0x93, 0xa1, 0xb8, 0xbb, 0xb9, 0x23, 0x76, 0xae, 0xdf,
+ 0xe7, 0xfa, 0x33, 0x65, 0xa0, 0xdd, 0x5f, 0xb2, 0x28, 0x83, 0xf5, 0x47,
+ 0x61, 0x54, 0xc5, 0xa8, 0xdf, 0xf7, 0x28, 0x67, 0x12, 0xdf, 0x28, 0xe8,
+ 0x94, 0xad, 0x99, 0x32, 0xc6, 0x28, 0x5f, 0x00, 0x7b, 0x73, 0xda, 0x54,
+ 0x06, 0xda, 0xc4, 0x0c, 0x56, 0x23, 0x1d, 0x51, 0xe9, 0x83, 0x7f, 0x06,
+ 0x77, 0x8c, 0x6e, 0x1c, 0xb7, 0xb0, 0x4e, 0x35, 0xb9, 0xbe, 0x29, 0x3c,
+ 0x5e, 0x81, 0x44, 0xff, 0xc7, 0x8a, 0x82, 0x37, 0x13, 0xdd, 0x98, 0xa4,
+ 0x3e, 0xdd, 0xf9, 0x20, 0x1e, 0xcc, 0x55, 0xe1, 0xfe, 0x9c, 0x8d, 0x07,
+ 0x52, 0x30, 0xab, 0xa8, 0x4f, 0x32, 0x95, 0x88, 0xbd, 0x0f, 0x1f, 0x3a,
+ 0xf2, 0xdd, 0x8c, 0xa5, 0x2d, 0x48, 0x57, 0x04, 0xb0, 0x25, 0x1f, 0x62,
+ 0x3c, 0xa6, 0x71, 0x7a, 0x3a, 0x00, 0xff, 0x7a, 0x0f, 0x66, 0x22, 0x15,
+ 0x48, 0x36, 0x78, 0xf8, 0x1b, 0x09, 0xb7, 0x4f, 0xd7, 0x87, 0xb7, 0x5a,
+ 0x3e, 0xec, 0xb7, 0x3c, 0x18, 0xc9, 0xd9, 0x76, 0x87, 0x61, 0xe3, 0xea,
+ 0x7a, 0x15, 0xdf, 0xa2, 0xfd, 0x0e, 0x5a, 0x51, 0x9c, 0x2d, 0x3c, 0x49,
+ 0x59, 0x22, 0xae, 0xbc, 0x16, 0x65, 0xb7, 0x28, 0xbb, 0x45, 0xb9, 0x2d,
+ 0x91, 0xf3, 0x55, 0xc6, 0x8c, 0x41, 0xbd, 0x82, 0x94, 0xa1, 0x1a, 0x83,
+ 0x94, 0x23, 0x9e, 0xb2, 0xe1, 0x49, 0x69, 0x99, 0xbd, 0x04, 0xaf, 0x15,
+ 0x0d, 0xb6, 0xfd, 0xf1, 0x7a, 0xd1, 0x85, 0x6b, 0xee, 0xe9, 0x96, 0x18,
+ 0xfd, 0xed, 0x1a, 0xc6, 0xd5, 0xf7, 0x69, 0xb7, 0xa7, 0x0b, 0x41, 0x0c,
+ 0xe7, 0x1c, 0xbf, 0x3d, 0x54, 0x41, 0xb9, 0x45, 0xae, 0x82, 0x9e, 0x60,
+ 0x8c, 0x26, 0xfa, 0x18, 0xa3, 0xd8, 0x49, 0x99, 0x1f, 0xb0, 0x22, 0xe1,
+ 0x8e, 0xe9, 0x44, 0xeb, 0x6e, 0xc5, 0x87, 0xed, 0xf9, 0xeb, 0x72, 0x52,
+ 0x5f, 0x89, 0x41, 0xea, 0xaa, 0x52, 0xbe, 0x08, 0xf6, 0x51, 0xce, 0x97,
+ 0x4a, 0x72, 0xce, 0x16, 0x64, 0xae, 0xcf, 0xca, 0x5a, 0x96, 0x13, 0x99,
+ 0xa5, 0x66, 0x44, 0x41, 0x55, 0x08, 0xbb, 0xf3, 0xef, 0x70, 0x2d, 0xea,
+ 0xf1, 0x4d, 0xae, 0xc1, 0xcb, 0x8c, 0x91, 0x6f, 0x5c, 0xf3, 0x17, 0x59,
+ 0x8f, 0x27, 0xb8, 0x0e, 0xda, 0xe9, 0x0c, 0x42, 0xe8, 0x2f, 0xa4, 0x71,
+ 0x78, 0x1a, 0xe9, 0x39, 0xe3, 0x18, 0xe3, 0x7d, 0x39, 0xbc, 0x7a, 0x65,
+ 0x5a, 0xd5, 0xab, 0xb0, 0x6f, 0x36, 0x82, 0xa1, 0x42, 0x3b, 0xac, 0x5c,
+ 0x04, 0x07, 0xe8, 0x9b, 0x1f, 0xa6, 0xd2, 0x0f, 0x84, 0x21, 0xb2, 0x47,
+ 0xf0, 0x20, 0xdf, 0x79, 0x6a, 0x3a, 0x82, 0x41, 0xda, 0x68, 0x47, 0x2a,
+ 0xd1, 0x1a, 0xe4, 0xb5, 0xfd, 0xbc, 0x76, 0x84, 0xf6, 0x7f, 0xd5, 0x98,
+ 0x44, 0x7f, 0x8f, 0x96, 0x04, 0x22, 0xb8, 0xcf, 0x82, 0x4a, 0x17, 0x7e,
+ 0x82, 0xf8, 0x96, 0x7c, 0x95, 0xdf, 0xef, 0x2d, 0x54, 0x51, 0xdf, 0x30,
+ 0xa2, 0xfa, 0x27, 0xb6, 0xbf, 0xc5, 0xb6, 0xbf, 0x66, 0x24, 0x2e, 0xfc,
+ 0xd0, 0xeb, 0xc3, 0x63, 0x05, 0x0f, 0x86, 0x67, 0xab, 0xf0, 0xfb, 0x39,
+ 0x1f, 0xee, 0x6c, 0xa8, 0xc2, 0xc1, 0xd9, 0x34, 0xc6, 0xa6, 0xab, 0x30,
+ 0x90, 0xc3, 0x8a, 0xfb, 0x8c, 0xb1, 0x25, 0x15, 0xd0, 0x16, 0x3b, 0x90,
+ 0xc4, 0x55, 0xae, 0xc3, 0x63, 0xb3, 0xa1, 0x70, 0xdf, 0xb4, 0x8a, 0xe1,
+ 0xf9, 0x20, 0x9f, 0xf7, 0xf0, 0xf9, 0x4a, 0x18, 0xeb, 0xe2, 0xc3, 0x2a,
+ 0x44, 0xc6, 0x6a, 0x3c, 0x3c, 0x1b, 0xc4, 0x43, 0x39, 0x15, 0x07, 0xa6,
+ 0x5b, 0x30, 0x65, 0xa5, 0x71, 0x94, 0xd8, 0xf1, 0xf5, 0x94, 0xd6, 0x73,
+ 0x40, 0xd1, 0xd2, 0x5b, 0x95, 0x34, 0x1a, 0x53, 0x7e, 0x5c, 0x22, 0x0e,
+ 0xf9, 0x53, 0x4d, 0xad, 0x2f, 0x12, 0x1b, 0x2a, 0xcc, 0x08, 0xbf, 0x6b,
+ 0x13, 0x8c, 0xd9, 0xb4, 0xdf, 0xb3, 0x1e, 0x58, 0x26, 0xf1, 0x1b, 0x09,
+ 0x77, 0x59, 0x6a, 0xb8, 0xab, 0x50, 0x1f, 0xde, 0x61, 0x45, 0xc3, 0x3b,
+ 0x18, 0x5f, 0x5b, 0xc5, 0x1f, 0xad, 0x00, 0x8e, 0xa5, 0x7e, 0x69, 0xf7,
+ 0x2f, 0x71, 0xf0, 0x2c, 0x7c, 0xfb, 0xb4, 0x96, 0x99, 0x81, 0x66, 0x30,
+ 0x1b, 0x60, 0x72, 0xde, 0xc7, 0xf5, 0x53, 0xb0, 0x44, 0x6f, 0x21, 0x8e,
+ 0xab, 0x78, 0x98, 0x98, 0xf2, 0xb7, 0xc4, 0x94, 0x81, 0xe3, 0x71, 0x75,
+ 0x0a, 0x41, 0xda, 0x1b, 0xd8, 0x7b, 0x2e, 0xc2, 0x35, 0xef, 0xc4, 0x93,
+ 0x94, 0x6b, 0xc7, 0x86, 0x08, 0xee, 0x2f, 0xa8, 0xe1, 0x4e, 0xae, 0xdf,
+ 0xfb, 0xf9, 0x68, 0x78, 0x0b, 0xd7, 0xf2, 0xdd, 0xbc, 0x16, 0x2b, 0xe2,
+ 0x9f, 0xc4, 0x9f, 0x92, 0xf0, 0x00, 0xf7, 0x1d, 0xf7, 0xa3, 0x18, 0x91,
+ 0xb9, 0x68, 0x73, 0xeb, 0x65, 0x3b, 0xa4, 0xeb, 0xa7, 0x0f, 0xd0, 0xd6,
+ 0x8f, 0x16, 0x42, 0x78, 0xc8, 0xd2, 0x92, 0xdf, 0x50, 0x42, 0xb4, 0x69,
+ 0x80, 0x76, 0x20, 0xc0, 0x2c, 0x97, 0xe7, 0x52, 0x88, 0x2d, 0x77, 0xb1,
+ 0xf6, 0xe0, 0xac, 0xf8, 0x09, 0xd7, 0xde, 0xa2, 0x0f, 0xd0, 0x7f, 0xbe,
+ 0x71, 0x2d, 0x56, 0x35, 0x35, 0xe3, 0x60, 0x77, 0x92, 0xfe, 0xe2, 0xda,
+ 0xe8, 0xc4, 0xb4, 0xd8, 0x41, 0x9b, 0x82, 0x27, 0x8d, 0xb5, 0xeb, 0xfe,
+ 0xd6, 0xbe, 0xb4, 0x4c, 0xec, 0xa1, 0x62, 0x84, 0x36, 0x3c, 0x6d, 0xd9,
+ 0xf6, 0xd5, 0xf5, 0x3f, 0xb5, 0x5b, 0x6f, 0x16, 0xbb, 0x88, 0xae, 0xdf,
+ 0x52, 0x24, 0x8f, 0x2c, 0xd1, 0xc3, 0xff, 0x1f, 0x7c, 0xe5, 0x0f, 0xed,
+ 0x7e, 0x47, 0x3f, 0xf1, 0x17, 0x1f, 0x7d, 0xf1, 0x49, 0x8e, 0xed, 0x41,
+ 0x3f, 0xc7, 0x7b, 0xc4, 0xb2, 0x3f, 0xaa, 0x33, 0x3f, 0xb5, 0x5b, 0x37,
+ 0xea, 0x43, 0x8b, 0xca, 0xff, 0xe0, 0xf5, 0x08, 0x1e, 0x2e, 0xb4, 0xd2,
+ 0x76, 0x1d, 0x78, 0xca, 0x12, 0x3c, 0xec, 0x64, 0xbc, 0x45, 0xe9, 0xcf,
+ 0xf5, 0xf4, 0x6f, 0x9f, 0xb2, 0xd5, 0xca, 0x63, 0xc7, 0x64, 0x06, 0xdb,
+ 0xe9, 0xef, 0x17, 0xb2, 0xf1, 0xd6, 0xe7, 0xa1, 0x65, 0xa8, 0x43, 0xb8,
+ 0x93, 0x36, 0xee, 0xb0, 0xb4, 0x4e, 0x59, 0xd3, 0x0e, 0xe2, 0xd2, 0x2b,
+ 0xd9, 0x68, 0xb8, 0xbd, 0x20, 0xf6, 0xae, 0x0f, 0x6f, 0x29, 0xdc, 0xca,
+ 0xb5, 0x57, 0xb0, 0x69, 0x75, 0x80, 0x38, 0x73, 0x07, 0xdc, 0x75, 0x75,
+ 0xd7, 0xee, 0xcd, 0x54, 0x53, 0xff, 0x4f, 0xd1, 0x85, 0xcc, 0x32, 0xf7,
+ 0xda, 0x30, 0xaf, 0xd5, 0xae, 0x47, 0xf8, 0x0e, 0xfa, 0xc1, 0x3d, 0xf4,
+ 0x83, 0xab, 0xeb, 0x7f, 0x69, 0xc7, 0x6e, 0x72, 0xfd, 0xa0, 0x7d, 0xda,
+ 0x17, 0xde, 0x46, 0x3b, 0x6d, 0x35, 0x14, 0xcc, 0x1a, 0x4f, 0xa1, 0xff,
+ 0x1a, 0x77, 0x48, 0xcf, 0x9c, 0x35, 0xd2, 0xc4, 0x91, 0x36, 0xf8, 0x96,
+ 0x60, 0xe6, 0x79, 0xe3, 0x30, 0x62, 0xae, 0xef, 0xe0, 0x40, 0x2e, 0x88,
+ 0xcc, 0x9d, 0x2a, 0xe6, 0x1a, 0x55, 0x3c, 0xc2, 0xb1, 0x3f, 0x4c, 0x35,
+ 0x0d, 0xbe, 0x45, 0x1b, 0xcc, 0x2c, 0x91, 0x6b, 0x69, 0xfc, 0x95, 0xf1,
+ 0x65, 0xe0, 0x26, 0x77, 0xee, 0x79, 0x89, 0xd1, 0xf9, 0x16, 0x1c, 0x29,
+ 0xf4, 0x29, 0x2e, 0x6e, 0x6a, 0x9d, 0x69, 0x7c, 0xcf, 0x16, 0x2c, 0x9d,
+ 0x27, 0x86, 0xb4, 0xd3, 0xa7, 0xc6, 0xe9, 0x47, 0xa3, 0xc4, 0x90, 0xed,
+ 0xf4, 0xa3, 0x27, 0xf3, 0xa2, 0x53, 0xc2, 0x30, 0xbc, 0x37, 0x33, 0x37,
+ 0xd3, 0x3e, 0x96, 0x93, 0xf3, 0x6b, 0x55, 0xfd, 0x30, 0xa6, 0x1c, 0xd9,
+ 0x86, 0x95, 0x3b, 0xc8, 0x31, 0x2e, 0xf9, 0x51, 0x1b, 0xd5, 0x1f, 0xc1,
+ 0x69, 0xe7, 0x5a, 0x84, 0xef, 0xa6, 0x3d, 0x1e, 0x1d, 0xaa, 0x6a, 0x76,
+ 0x30, 0xaf, 0x8a, 0xef, 0x77, 0x2a, 0x3b, 0x98, 0x6b, 0xd3, 0xcc, 0xb5,
+ 0x69, 0xe6, 0xda, 0x34, 0xe7, 0x4f, 0x33, 0xc7, 0xb6, 0x17, 0x86, 0x95,
+ 0x1e, 0xb1, 0xbb, 0xd8, 0xdf, 0x72, 0xf9, 0x03, 0xb1, 0x27, 0xbc, 0xbd,
+ 0xb0, 0xc6, 0xe3, 0x72, 0xba, 0x61, 0xa5, 0xc4, 0x61, 0x02, 0x55, 0x3a,
+ 0x73, 0x98, 0x35, 0xac, 0x74, 0x31, 0xcf, 0xf6, 0x39, 0x36, 0x8c, 0x0f,
+ 0x5d, 0x66, 0x7e, 0x7d, 0x93, 0xf9, 0x35, 0x9f, 0x62, 0x3c, 0xad, 0xbe,
+ 0x6a, 0xf7, 0x2f, 0x73, 0x73, 0xc1, 0x18, 0xe5, 0xfc, 0x1a, 0xd7, 0xaa,
+ 0xc8, 0x1c, 0xda, 0xe1, 0x55, 0x70, 0x9f, 0x8e, 0xda, 0x3a, 0x62, 0xe9,
+ 0x91, 0x02, 0xf1, 0xdf, 0x88, 0xb7, 0x7e, 0x40, 0x83, 0x1e, 0xd1, 0xfd,
+ 0xb8, 0x7a, 0x13, 0x49, 0x8e, 0xde, 0x8e, 0x63, 0xb9, 0x4a, 0x0c, 0xa6,
+ 0xd2, 0x4b, 0x03, 0xe4, 0x28, 0x9d, 0x2d, 0x78, 0x9c, 0x53, 0x2b, 0x51,
+ 0x33, 0x41, 0x7f, 0x41, 0xfa, 0x38, 0xf3, 0xc3, 0xa4, 0x75, 0x2b, 0xf2,
+ 0xcc, 0xa3, 0x73, 0x86, 0x0f, 0x6f, 0xe6, 0xd7, 0x10, 0xdf, 0x12, 0x46,
+ 0x48, 0xa9, 0x62, 0xdc, 0x9a, 0xc8, 0x5a, 0x82, 0x4b, 0xb6, 0x3d, 0x27,
+ 0x32, 0x24, 0x12, 0xe9, 0x51, 0x08, 0x56, 0xd9, 0x2b, 0xee, 0x4d, 0x55,
+ 0x60, 0x53, 0x22, 0x8c, 0x15, 0x7a, 0xbf, 0xd2, 0x59, 0x48, 0x18, 0xaf,
+ 0xe2, 0x77, 0x95, 0x7b, 0xe6, 0x4d, 0xc6, 0x74, 0x9f, 0xb2, 0x67, 0xbe,
+ 0x0a, 0x97, 0x22, 0x22, 0x23, 0x6a, 0xfd, 0xba, 0x07, 0xef, 0xdd, 0xa5,
+ 0x40, 0xd5, 0xd3, 0x38, 0xdf, 0xa2, 0xd2, 0x9f, 0x3a, 0xc9, 0x2d, 0x62,
+ 0xf0, 0x2e, 0x44, 0xc3, 0x3b, 0xb9, 0x06, 0xd5, 0x0b, 0xb2, 0x2e, 0x1d,
+ 0xb4, 0x55, 0x3d, 0xfd, 0xaf, 0x53, 0xe9, 0xa0, 0x1d, 0xbb, 0x66, 0xa1,
+ 0x56, 0x99, 0xbd, 0xca, 0xb6, 0x82, 0x46, 0x3b, 0x89, 0x4d, 0x86, 0xc9,
+ 0x91, 0xc4, 0x47, 0xca, 0x6b, 0x28, 0x7e, 0x7a, 0xe3, 0x3a, 0xf6, 0x79,
+ 0x24, 0xd6, 0x36, 0xad, 0x36, 0x19, 0x87, 0x1e, 0xca, 0x25, 0x32, 0x04,
+ 0x50, 0xdb, 0x68, 0xaf, 0xf8, 0x30, 0xb5, 0xc0, 0x7b, 0x26, 0x8e, 0x17,
+ 0xba, 0xb9, 0x2e, 0xcd, 0x25, 0xbf, 0x52, 0xe9, 0x87, 0x1d, 0x1c, 0x5f,
+ 0xfc, 0x3b, 0x0d, 0x77, 0x2d, 0x3b, 0xc9, 0x89, 0xfe, 0xb5, 0x35, 0x3c,
+ 0xc8, 0x31, 0x64, 0x1d, 0x2b, 0xca, 0x7e, 0x19, 0xbe, 0x67, 0x3a, 0x8d,
+ 0xf7, 0x9c, 0x1c, 0x5a, 0xf6, 0xe1, 0x61, 0xa5, 0x93, 0x6b, 0x09, 0xbf,
+ 0x3b, 0xfe, 0xae, 0x69, 0xf8, 0x6b, 0x4c, 0xc4, 0xbc, 0xe4, 0x6d, 0x17,
+ 0x53, 0x09, 0x75, 0x52, 0xe9, 0xe6, 0x58, 0x8c, 0x2d, 0x62, 0x7d, 0x35,
+ 0xfd, 0xa6, 0x83, 0xfa, 0x76, 0x51, 0xdf, 0x2e, 0x67, 0x4e, 0xf1, 0xbb,
+ 0x5f, 0x9d, 0x77, 0x4b, 0xe1, 0x1e, 0x47, 0xf7, 0x9d, 0x7c, 0x67, 0x0f,
+ 0x65, 0xdd, 0xc3, 0xe7, 0xb7, 0x58, 0xdf, 0xe7, 0x35, 0x91, 0x57, 0xe2,
+ 0xfa, 0xc6, 0x5c, 0x25, 0xb1, 0xfd, 0xdd, 0x12, 0x57, 0x40, 0xc6, 0x63,
+ 0x4a, 0xec, 0x0f, 0xa1, 0xa7, 0x05, 0x81, 0xa5, 0xe6, 0x50, 0xdb, 0xee,
+ 0x06, 0xe2, 0x14, 0x71, 0x32, 0x70, 0x9c, 0x1c, 0x99, 0xd8, 0x3b, 0xd7,
+ 0xaa, 0x60, 0xcc, 0xb8, 0x99, 0xf1, 0x67, 0x60, 0xa2, 0xa0, 0x75, 0xc6,
+ 0x78, 0xaf, 0x79, 0x52, 0xb8, 0xfb, 0x01, 0xb4, 0x93, 0xaf, 0x45, 0xcd,
+ 0x41, 0x44, 0xad, 0x78, 0x74, 0x42, 0xd1, 0x06, 0xb7, 0x40, 0xbb, 0x40,
+ 0xcc, 0x1f, 0x9e, 0x55, 0xb4, 0xa1, 0x3a, 0xaf, 0x96, 0x7e, 0xdb, 0xe1,
+ 0xcd, 0x07, 0xb0, 0xda, 0xe1, 0x66, 0x83, 0x48, 0x92, 0xa3, 0xee, 0xe4,
+ 0x98, 0xfb, 0x37, 0x29, 0xb8, 0x62, 0xfc, 0x94, 0xeb, 0xa4, 0xa5, 0x33,
+ 0x8a, 0x81, 0x2c, 0xe3, 0x3f, 0x7a, 0x5c, 0x38, 0xf8, 0x01, 0x72, 0x70,
+ 0x04, 0x42, 0x7c, 0x36, 0x3b, 0x19, 0x1f, 0x0e, 0x78, 0xb5, 0x24, 0xf9,
+ 0x77, 0x9a, 0x63, 0x1a, 0x05, 0xf2, 0x72, 0xce, 0x11, 0xbb, 0xaf, 0x34,
+ 0x66, 0xa2, 0x34, 0xa6, 0x9e, 0x07, 0xe3, 0x62, 0x02, 0xdb, 0x13, 0xcc,
+ 0x01, 0xc4, 0xb2, 0xa3, 0xc2, 0xf5, 0x39, 0x5e, 0xe5, 0x71, 0x83, 0xdf,
+ 0x87, 0x95, 0x3d, 0x12, 0x33, 0x95, 0x2e, 0x73, 0xab, 0xe5, 0x1c, 0x35,
+ 0xe6, 0x21, 0x2c, 0x38, 0x73, 0x0c, 0xc9, 0x1c, 0x43, 0x3f, 0x52, 0xb4,
+ 0xe4, 0x39, 0x45, 0x30, 0xb8, 0xa9, 0xef, 0x1c, 0x63, 0xe4, 0x88, 0xa2,
+ 0xb5, 0x1e, 0xa3, 0xfa, 0x41, 0x5d, 0xc6, 0x3f, 0x54, 0x9a, 0x67, 0x08,
+ 0x8d, 0x79, 0xc6, 0x5f, 0x21, 0xa0, 0x6c, 0xc9, 0xb5, 0x63, 0x6c, 0xb6,
+ 0x1d, 0xa3, 0x39, 0x05, 0xf7, 0x18, 0xcb, 0x70, 0xe9, 0x66, 0xa7, 0xfe,
+ 0xa8, 0x59, 0xa1, 0xd7, 0x61, 0x44, 0x45, 0xad, 0x47, 0xff, 0x3c, 0xf6,
+ 0x96, 0xb8, 0xfb, 0xf6, 0x13, 0x3d, 0xc4, 0x73, 0x1b, 0x1f, 0x30, 0x56,
+ 0xe2, 0x4b, 0x90, 0xf6, 0x9b, 0xad, 0xe4, 0xd9, 0x4b, 0xbd, 0x6e, 0x3c,
+ 0xff, 0x7d, 0xc0, 0x5d, 0x03, 0xb1, 0xff, 0x67, 0xef, 0xb5, 0xe3, 0xe9,
+ 0x5c, 0x05, 0x5a, 0xd7, 0xe3, 0xce, 0x28, 0x6a, 0x3c, 0xcc, 0x5d, 0xef,
+ 0xec, 0x56, 0x1e, 0xe6, 0x3d, 0xe7, 0xd9, 0xc0, 0x6f, 0x98, 0x1f, 0xb7,
+ 0xfd, 0x71, 0xa3, 0x5c, 0x97, 0x67, 0x6f, 0xbc, 0xae, 0x9a, 0xff, 0xf2,
+ 0xba, 0x82, 0x17, 0x08, 0x50, 0x5f, 0x67, 0xae, 0xc8, 0x67, 0x6d, 0x78,
+ 0x4d, 0x1f, 0x06, 0x27, 0x63, 0x38, 0xb0, 0x10, 0xc1, 0x42, 0x56, 0xeb,
+ 0xbf, 0xc4, 0xba, 0x60, 0x6f, 0x8b, 0x8e, 0x87, 0x16, 0xa2, 0x98, 0xcf,
+ 0xc2, 0x0e, 0x9a, 0x7a, 0x31, 0xa8, 0x24, 0xb1, 0x7f, 0xa1, 0x1e, 0xe7,
+ 0xb2, 0xfa, 0x85, 0x51, 0x25, 0x31, 0x5c, 0x47, 0x3e, 0xf1, 0xc8, 0x42,
+ 0x33, 0x1e, 0x5e, 0x08, 0xf0, 0x1d, 0x1b, 0x5d, 0xa9, 0x7a, 0x3e, 0xef,
+ 0xc1, 0xf3, 0x27, 0x6d, 0x5b, 0xf8, 0xd4, 0xe0, 0x02, 0x30, 0x3f, 0xc5,
+ 0x1c, 0x73, 0x86, 0xf9, 0xe6, 0x19, 0x60, 0xff, 0x33, 0x1e, 0xcc, 0x4e,
+ 0xd9, 0xd8, 0x6b, 0x8c, 0xd6, 0x79, 0xe8, 0xe4, 0xfd, 0xcc, 0x07, 0x7e,
+ 0xe6, 0xb6, 0x7b, 0x55, 0x17, 0xa7, 0x2f, 0x11, 0x87, 0x1e, 0x78, 0x26,
+ 0x89, 0x77, 0xb2, 0x19, 0x74, 0x91, 0x77, 0x0f, 0x53, 0x96, 0xb7, 0xb3,
+ 0xcc, 0x4f, 0x0b, 0x06, 0xde, 0xca, 0x06, 0x38, 0x4f, 0x33, 0x5e, 0xcb,
+ 0xca, 0x33, 0xf2, 0x6c, 0x08, 0x03, 0x94, 0xe5, 0xcd, 0x6c, 0x94, 0x73,
+ 0x46, 0xf0, 0x1d, 0x3e, 0x77, 0xff, 0x82, 0xce, 0x7c, 0x14, 0xe0, 0xbc,
+ 0x31, 0xbc, 0x91, 0x0d, 0x51, 0xd6, 0x08, 0x73, 0xd0, 0x00, 0xc6, 0xb2,
+ 0x4d, 0x17, 0xb6, 0x90, 0xb3, 0xb8, 0x39, 0x44, 0xae, 0x5d, 0xb6, 0xbb,
+ 0x9d, 0x98, 0x93, 0x79, 0xca, 0xf3, 0x0e, 0x60, 0x34, 0xfb, 0x9a, 0xb7,
+ 0x5c, 0x27, 0xbf, 0x30, 0xb5, 0xe8, 0x70, 0xba, 0xe7, 0x2d, 0xfe, 0x3d,
+ 0x0b, 0x9c, 0xb3, 0x32, 0x76, 0xad, 0x49, 0x0e, 0xcb, 0xdc, 0xf3, 0xc3,
+ 0x0d, 0xcd, 0x9c, 0x57, 0xef, 0x7f, 0x45, 0x91, 0x3a, 0xc6, 0x87, 0xd8,
+ 0x33, 0x62, 0x2f, 0xc6, 0xf1, 0x3c, 0xf0, 0x57, 0xe4, 0x95, 0x8d, 0x93,
+ 0x9a, 0xf8, 0x7d, 0x1f, 0xf9, 0x4a, 0x4f, 0x11, 0x0d, 0xc9, 0x87, 0x30,
+ 0x62, 0x57, 0x90, 0x77, 0xd7, 0x92, 0xaf, 0x2e, 0x34, 0x33, 0xff, 0x6c,
+ 0xb0, 0xed, 0xef, 0xb7, 0xc0, 0xf6, 0x98, 0xba, 0x51, 0xe7, 0x2d, 0x7e,
+ 0xbe, 0x06, 0xfa, 0x85, 0xb0, 0xa2, 0x17, 0x7f, 0x88, 0xc4, 0xd0, 0xab,
+ 0x10, 0xbb, 0x02, 0x6b, 0x16, 0x7c, 0x58, 0x4b, 0x7d, 0xb6, 0x4e, 0x72,
+ 0x6e, 0xf2, 0x8e, 0x04, 0x75, 0xba, 0x7d, 0x92, 0x5c, 0x4a, 0x0f, 0x61,
+ 0x35, 0x6d, 0x3c, 0x78, 0xca, 0xb6, 0x2b, 0x69, 0xe3, 0x46, 0xae, 0xcf,
+ 0x7d, 0x27, 0x6c, 0xbc, 0x62, 0xbc, 0x42, 0x9b, 0x2a, 0xe4, 0x83, 0x2d,
+ 0x7c, 0x27, 0xc2, 0xe7, 0x03, 0xd8, 0x3f, 0x29, 0x75, 0x50, 0x3d, 0x9f,
+ 0xb9, 0x88, 0x63, 0xd9, 0x24, 0x9a, 0x69, 0xbf, 0x18, 0xc7, 0x6c, 0xe2,
+ 0x3b, 0xb1, 0x05, 0x37, 0x97, 0xc4, 0x16, 0x7e, 0x1d, 0x0e, 0x00, 0xa7,
+ 0xa7, 0xb4, 0x89, 0x22, 0xb9, 0x74, 0x8d, 0x39, 0x02, 0xe6, 0x62, 0xbc,
+ 0x3d, 0xa3, 0xe0, 0xf8, 0x14, 0x6b, 0xb7, 0x0d, 0xb0, 0xab, 0xa8, 0xc7,
+ 0x5b, 0x33, 0xbf, 0x89, 0xe7, 0x4e, 0x52, 0xf7, 0x67, 0x23, 0xf8, 0x7a,
+ 0xd6, 0x87, 0x5b, 0x8e, 0x0b, 0x3f, 0xd3, 0x93, 0x07, 0x14, 0xa9, 0x75,
+ 0xa4, 0x06, 0x49, 0xc4, 0xfc, 0x8a, 0x07, 0x0d, 0xcf, 0xf9, 0xa0, 0x9f,
+ 0x8b, 0xc1, 0xdf, 0x10, 0x80, 0xde, 0xf0, 0xfb, 0xc4, 0x17, 0x0f, 0x2a,
+ 0x58, 0x97, 0x6e, 0xff, 0x4a, 0x92, 0xd7, 0x22, 0xbc, 0x86, 0xdf, 0xac,
+ 0x84, 0x77, 0xb9, 0x97, 0xf9, 0xb8, 0x42, 0x27, 0xb7, 0xf2, 0xd9, 0xb6,
+ 0x97, 0x78, 0xbf, 0xe7, 0xab, 0xb6, 0x1d, 0x5f, 0x2f, 0xcf, 0xab, 0x88,
+ 0x9f, 0xd3, 0xf9, 0x9c, 0x9b, 0x03, 0xaf, 0x73, 0x2b, 0x2f, 0x7d, 0x47,
+ 0xe2, 0xf3, 0x71, 0xb8, 0xf5, 0x90, 0xcb, 0xc1, 0x5f, 0x2a, 0x08, 0x4f,
+ 0x89, 0x39, 0x3a, 0x9c, 0x9d, 0x52, 0x88, 0x73, 0x26, 0x9f, 0xdd, 0x0c,
+ 0x6f, 0x4a, 0x9b, 0xc8, 0x70, 0xed, 0xf7, 0xaa, 0xad, 0x78, 0xc1, 0xf2,
+ 0xa3, 0x5a, 0x5f, 0x8e, 0x07, 0x7b, 0x54, 0xbc, 0x40, 0x8e, 0xcf, 0x75,
+ 0x4a, 0x16, 0x51, 0xc9, 0x5a, 0x8b, 0xe3, 0x79, 0xfe, 0x1a, 0xfa, 0x57,
+ 0x3c, 0xc4, 0x36, 0xaf, 0x83, 0x6d, 0x15, 0x0d, 0x40, 0x31, 0xef, 0xc3,
+ 0x79, 0xdd, 0xe5, 0x77, 0x2f, 0x39, 0x79, 0x58, 0x53, 0x8b, 0xd7, 0x78,
+ 0x9d, 0xd6, 0x9a, 0x56, 0x0e, 0x7b, 0x45, 0xce, 0x17, 0x0b, 0x3b, 0x7d,
+ 0xae, 0xff, 0x5c, 0xf4, 0x4a, 0xfd, 0x70, 0xfd, 0x7b, 0x15, 0x3c, 0xa6,
+ 0x16, 0x6d, 0xf7, 0x22, 0xe0, 0x33, 0x03, 0x6d, 0xe3, 0xfa, 0xe7, 0x6e,
+ 0x90, 0xbd, 0x19, 0x63, 0x85, 0xeb, 0x75, 0x73, 0x67, 0xd6, 0xf1, 0x9b,
+ 0x4e, 0xb1, 0xfd, 0x53, 0x86, 0x60, 0xeb, 0xb0, 0xd2, 0x41, 0xac, 0xca,
+ 0xf8, 0xdc, 0xba, 0xf8, 0x08, 0xeb, 0xe2, 0xd7, 0xb3, 0xd2, 0x1b, 0x39,
+ 0x84, 0x7d, 0x0e, 0xce, 0x0e, 0x09, 0xce, 0xc6, 0xce, 0x42, 0x1b, 0x1c,
+ 0x28, 0xe1, 0xec, 0x9c, 0x8b, 0xb3, 0xfd, 0x2e, 0xce, 0x1e, 0x2a, 0xe1,
+ 0xec, 0x10, 0x9a, 0xf3, 0x11, 0x72, 0xe0, 0x0e, 0xe6, 0xda, 0x6e, 0x72,
+ 0x0e, 0xc9, 0x91, 0x7d, 0xca, 0xce, 0xf9, 0x80, 0xb2, 0x2d, 0x17, 0xc0,
+ 0xeb, 0xe4, 0x53, 0x33, 0xbd, 0x50, 0x6f, 0xd9, 0x80, 0xe0, 0xce, 0x5c,
+ 0x0f, 0x2a, 0x75, 0xa9, 0x03, 0x2b, 0xb1, 0xdd, 0xc9, 0x55, 0x52, 0x2f,
+ 0x49, 0x2f, 0xa0, 0x97, 0x58, 0x07, 0x35, 0x68, 0xba, 0x75, 0xbf, 0xe0,
+ 0xde, 0xed, 0x7c, 0xf7, 0x2c, 0xfd, 0x10, 0x6e, 0x4e, 0x53, 0xee, 0x60,
+ 0x3d, 0xf0, 0x61, 0x4a, 0x41, 0xf1, 0xce, 0x00, 0x38, 0x16, 0xf5, 0x3d,
+ 0xd0, 0x36, 0x3e, 0xd5, 0xa3, 0x74, 0xcc, 0xce, 0x05, 0x99, 0xb7, 0x99,
+ 0x93, 0x66, 0x82, 0x6e, 0xae, 0xfe, 0xec, 0x58, 0xd2, 0x73, 0x49, 0xb6,
+ 0x6d, 0x22, 0xc7, 0x69, 0x5d, 0xff, 0x8f, 0x36, 0x7e, 0x47, 0xde, 0xff,
+ 0xcf, 0x25, 0xfb, 0xa5, 0x29, 0x4f, 0x24, 0xb0, 0xbd, 0xa0, 0x06, 0xd2,
+ 0x85, 0x0e, 0xbe, 0xdf, 0xc3, 0xb1, 0x7a, 0x83, 0x1d, 0xd6, 0xdd, 0xc1,
+ 0xad, 0x56, 0x77, 0x70, 0x9b, 0xc5, 0xd8, 0x2d, 0xf4, 0xd2, 0x8e, 0x3d,
+ 0xac, 0xe1, 0xef, 0x26, 0x7f, 0x90, 0x31, 0xfb, 0xc9, 0x65, 0x82, 0xd4,
+ 0x6d, 0x84, 0xba, 0x15, 0xa3, 0x7e, 0xa4, 0x35, 0x3f, 0x34, 0x75, 0xcc,
+ 0x59, 0xb7, 0x09, 0xa7, 0x8f, 0x54, 0x65, 0xae, 0x6e, 0xeb, 0x3a, 0x41,
+ 0x4c, 0x37, 0x1b, 0xda, 0x6e, 0x39, 0x85, 0x25, 0x7e, 0x53, 0xea, 0x5e,
+ 0xd6, 0xb2, 0x89, 0x84, 0xf1, 0x3e, 0x12, 0xd1, 0xd7, 0xf9, 0xec, 0x28,
+ 0x7d, 0x75, 0xcc, 0xe9, 0x1d, 0x70, 0x01, 0xf2, 0xcd, 0xe8, 0xb2, 0x02,
+ 0xc1, 0xdb, 0x59, 0x57, 0x85, 0x4d, 0xad, 0x75, 0x97, 0x57, 0x7a, 0x19,
+ 0xc5, 0xdf, 0x0e, 0xa1, 0x19, 0x9d, 0x85, 0x40, 0x70, 0xcb, 0xf4, 0xe7,
+ 0xf0, 0x0f, 0x27, 0x99, 0xbb, 0x20, 0x7e, 0x67, 0xdb, 0xf7, 0xb3, 0x26,
+ 0x39, 0x9a, 0xaf, 0xc7, 0x15, 0x67, 0x4d, 0x7d, 0x38, 0x92, 0x8f, 0xe1,
+ 0x32, 0xf1, 0xc9, 0xb7, 0x50, 0x87, 0x77, 0xa7, 0xbc, 0xd8, 0x67, 0xdc,
+ 0x56, 0xca, 0x09, 0x1e, 0xdc, 0x9b, 0x3c, 0x48, 0x1e, 0xe0, 0x41, 0x2d,
+ 0x39, 0xd8, 0x23, 0xce, 0x35, 0x2f, 0x6b, 0xb7, 0x2f, 0x62, 0xd8, 0xcd,
+ 0x19, 0x94, 0xb1, 0x9e, 0x32, 0xb6, 0x04, 0xb7, 0xe4, 0xb4, 0xe0, 0x1d,
+ 0x39, 0x04, 0xfc, 0xe6, 0xca, 0xb6, 0x33, 0x27, 0x6d, 0x0c, 0x18, 0xab,
+ 0xf0, 0xe1, 0xc9, 0xd1, 0x41, 0x1f, 0xfd, 0xe5, 0x27, 0xa9, 0x3e, 0x58,
+ 0xd3, 0x38, 0x4f, 0x26, 0x71, 0x31, 0x44, 0xfc, 0x6e, 0x24, 0x67, 0xa0,
+ 0x1f, 0x18, 0xf3, 0x8c, 0xc5, 0x6d, 0xf4, 0x0f, 0xfa, 0x43, 0xda, 0x6b,
+ 0x26, 0xfa, 0xc7, 0x48, 0x00, 0x6b, 0x28, 0x4f, 0x90, 0xf8, 0x1c, 0x5a,
+ 0x88, 0x05, 0xf7, 0x30, 0xa7, 0x44, 0x59, 0x9b, 0x05, 0x13, 0xb8, 0xad,
+ 0x0e, 0x89, 0xe4, 0x22, 0xf5, 0xf6, 0x2f, 0x34, 0x07, 0x77, 0x31, 0x47,
+ 0x5c, 0x49, 0xd8, 0x23, 0xaf, 0x18, 0x21, 0x84, 0x17, 0x0c, 0xda, 0xbb,
+ 0x0f, 0xa3, 0xf3, 0x2c, 0x97, 0x12, 0xac, 0xd7, 0x17, 0x5a, 0x83, 0xb7,
+ 0x33, 0x16, 0x6b, 0x88, 0x53, 0x4d, 0x0b, 0xe9, 0xa0, 0xd4, 0x6b, 0xcd,
+ 0x0b, 0x1b, 0x29, 0x9f, 0xac, 0x63, 0x73, 0xdb, 0x26, 0xfa, 0x41, 0x6c,
+ 0x01, 0xdb, 0x09, 0x65, 0xaf, 0x71, 0xcc, 0xbe, 0x28, 0x79, 0xe8, 0xfe,
+ 0x0d, 0x21, 0x62, 0x91, 0xd8, 0x92, 0x76, 0x2c, 0x94, 0x75, 0x92, 0xdc,
+ 0xdb, 0xd0, 0xb6, 0x70, 0x4a, 0x72, 0x6f, 0xb4, 0x2d, 0x7b, 0x4a, 0xc7,
+ 0x65, 0xe6, 0x8f, 0x35, 0x29, 0xcd, 0x38, 0xa7, 0xc4, 0xa3, 0x17, 0xa9,
+ 0x8b, 0x0f, 0x3f, 0xb3, 0xf7, 0xea, 0x89, 0xe2, 0x4a, 0xc6, 0x4f, 0x2d,
+ 0xf1, 0x2f, 0x4a, 0x5c, 0xaf, 0x5d, 0xa0, 0x61, 0x16, 0x7e, 0x46, 0xff,
+ 0x88, 0x22, 0x90, 0xd0, 0xf1, 0xde, 0xc9, 0x24, 0xed, 0x70, 0x6d, 0xcc,
+ 0x03, 0xa4, 0x50, 0x03, 0x4c, 0x77, 0x4f, 0x3c, 0x47, 0x1f, 0x1c, 0xe7,
+ 0xbc, 0x15, 0x0b, 0x22, 0xb3, 0x3c, 0x1f, 0xe1, 0xf3, 0xd7, 0xe7, 0xae,
+ 0xe5, 0xdc, 0x1f, 0x9d, 0x92, 0xfe, 0x52, 0xb4, 0xed, 0xfc, 0x49, 0x77,
+ 0xee, 0x44, 0x2a, 0x89, 0x9f, 0x9e, 0xd4, 0x86, 0xde, 0x53, 0xe2, 0xfd,
+ 0xe7, 0x15, 0x99, 0x1f, 0xf5, 0x35, 0xf8, 0xd0, 0x1e, 0x4d, 0x24, 0x86,
+ 0xf7, 0x72, 0xcc, 0xd6, 0x8d, 0xb4, 0xbf, 0x23, 0x07, 0x13, 0x3b, 0xb1,
+ 0xd4, 0x4f, 0x79, 0x5c, 0x59, 0xea, 0x39, 0xf6, 0xc9, 0x52, 0x9d, 0xc5,
+ 0x1a, 0xf3, 0xba, 0x3c, 0x11, 0xda, 0x21, 0xb0, 0xa7, 0x25, 0x84, 0x3a,
+ 0xe7, 0x39, 0x95, 0xcf, 0x89, 0x1d, 0x7e, 0xae, 0x78, 0xf4, 0xf7, 0x89,
+ 0x5b, 0x82, 0x1d, 0x11, 0x62, 0xd6, 0xdd, 0x52, 0x8f, 0x66, 0x32, 0xf4,
+ 0x77, 0x3f, 0xfd, 0x7d, 0xab, 0xf8, 0xb4, 0x45, 0x9f, 0xb6, 0xe8, 0xd3,
+ 0x96, 0x16, 0x1d, 0x42, 0x5c, 0x1d, 0xe0, 0xba, 0xa5, 0xa3, 0xe2, 0xeb,
+ 0xbd, 0xd8, 0xc7, 0xdf, 0xfb, 0x78, 0xff, 0x08, 0x6b, 0x54, 0x2c, 0x95,
+ 0x39, 0x0f, 0xa1, 0xc3, 0x7a, 0x02, 0x83, 0x39, 0xfc, 0x22, 0xd8, 0x52,
+ 0x89, 0xca, 0xd5, 0x52, 0x7f, 0x6b, 0xea, 0x51, 0x3c, 0xc1, 0x1a, 0xe8,
+ 0xe7, 0x4a, 0xb5, 0xee, 0xeb, 0x39, 0xa6, 0x68, 0x6a, 0x07, 0x6b, 0xd9,
+ 0xbd, 0x85, 0xbb, 0xb9, 0xbe, 0xf1, 0xc1, 0xd7, 0x15, 0xd6, 0x41, 0x75,
+ 0x9c, 0x9b, 0xb1, 0x74, 0x07, 0xe7, 0xb1, 0x44, 0x0e, 0x07, 0x5f, 0x7f,
+ 0x0f, 0x62, 0xdb, 0x6f, 0x37, 0x0e, 0x70, 0x7e, 0x57, 0x8e, 0x51, 0xd6,
+ 0x83, 0x03, 0x8c, 0xb1, 0x7d, 0x4e, 0x7c, 0xf5, 0x72, 0x8c, 0xeb, 0xb8,
+ 0xb5, 0x25, 0x2b, 0xf9, 0xd2, 0xc6, 0x93, 0x86, 0x8d, 0xe7, 0xf9, 0x7b,
+ 0x81, 0xd8, 0x35, 0x76, 0x03, 0x76, 0x79, 0xf8, 0xdc, 0x1e, 0x3e, 0xd7,
+ 0x4a, 0xdc, 0x9e, 0x9f, 0x95, 0xbe, 0xde, 0x21, 0xe9, 0xeb, 0x21, 0x6f,
+ 0x89, 0xed, 0x87, 0x70, 0x3e, 0x1b, 0x1f, 0xf6, 0x7a, 0xed, 0x11, 0xc6,
+ 0xd5, 0x85, 0x8f, 0xe8, 0xbb, 0x6f, 0x6e, 0xd0, 0x7a, 0x68, 0xc3, 0xe4,
+ 0xa4, 0xa2, 0x45, 0xbf, 0x8b, 0xe2, 0xf6, 0x00, 0x9a, 0x62, 0x6b, 0xbd,
+ 0x09, 0x95, 0x38, 0x57, 0x1c, 0xa0, 0xa6, 0xcf, 0x16, 0x5c, 0x6c, 0xdb,
+ 0x54, 0xc2, 0xb6, 0xd6, 0x7c, 0x15, 0xb1, 0x87, 0x39, 0x78, 0xd6, 0xce,
+ 0x84, 0x99, 0x9f, 0x0a, 0xb3, 0x32, 0xf6, 0x08, 0x9a, 0x52, 0x32, 0x96,
+ 0xde, 0x39, 0xa9, 0xe0, 0x4b, 0xd5, 0x48, 0x30, 0x37, 0xc1, 0xa8, 0xd4,
+ 0x33, 0x36, 0x73, 0x90, 0xea, 0x37, 0x25, 0x3f, 0x76, 0x13, 0x0f, 0x7b,
+ 0x89, 0x87, 0xc2, 0x99, 0xa5, 0xd7, 0xe9, 0xe2, 0xd1, 0xd6, 0x82, 0xac,
+ 0x8b, 0xac, 0x89, 0xac, 0xcd, 0x21, 0xdc, 0x6b, 0x49, 0xdd, 0x6e, 0x63,
+ 0xca, 0x48, 0xc4, 0x9e, 0x83, 0xac, 0xd3, 0x21, 0xda, 0xc2, 0x8f, 0x7d,
+ 0xc4, 0xbf, 0xbd, 0x2d, 0xb4, 0x55, 0xd8, 0x8f, 0xbd, 0x4e, 0x1f, 0xa0,
+ 0x6c, 0x3f, 0x3f, 0xd7, 0x50, 0x61, 0x4e, 0xfb, 0xaa, 0xdf, 0xb5, 0xa3,
+ 0xdb, 0x57, 0xf4, 0x9a, 0x32, 0x5e, 0xb9, 0xa7, 0xe8, 0xda, 0x6e, 0x7b,
+ 0x56, 0xc6, 0xb5, 0x71, 0xd6, 0x70, 0xb9, 0x69, 0xd9, 0x66, 0x82, 0xed,
+ 0x4b, 0x36, 0x02, 0x6b, 0x6f, 0xe0, 0xa7, 0x55, 0xbc, 0xd6, 0x75, 0x9d,
+ 0x9f, 0xf6, 0x09, 0x07, 0x26, 0x3f, 0xed, 0xdc, 0x49, 0x7e, 0xda, 0xa0,
+ 0x94, 0xb9, 0xa9, 0xf4, 0x14, 0xca, 0xfc, 0xb4, 0xb6, 0x84, 0xcd, 0x87,
+ 0xb0, 0x97, 0xdc, 0xa5, 0xae, 0x61, 0x04, 0x81, 0x75, 0x9e, 0x4f, 0x3d,
+ 0x18, 0x61, 0xed, 0x51, 0x01, 0x2c, 0xb3, 0xb1, 0x72, 0x7d, 0xc6, 0xae,
+ 0xd4, 0x1b, 0x62, 0x95, 0x1e, 0xe9, 0x19, 0x27, 0x32, 0x63, 0xc4, 0x12,
+ 0xcf, 0x3a, 0x2d, 0x93, 0x46, 0x40, 0x5d, 0xa2, 0xdf, 0x5d, 0xaa, 0x09,
+ 0xa2, 0x81, 0x1d, 0xe4, 0x36, 0x89, 0xd4, 0x2f, 0xed, 0x99, 0xc8, 0x08,
+ 0xa2, 0xeb, 0x8a, 0xc3, 0x51, 0xa4, 0x0f, 0x46, 0x1d, 0x5c, 0x99, 0x40,
+ 0x3e, 0x11, 0x0d, 0x74, 0x17, 0x32, 0xc1, 0xae, 0xc6, 0x18, 0x76, 0x4e,
+ 0x76, 0xb0, 0xe6, 0xd0, 0xb1, 0x6d, 0xb2, 0x93, 0xf5, 0x51, 0x8f, 0xd2,
+ 0x33, 0x2b, 0xf6, 0x11, 0xfb, 0x6a, 0x6a, 0xcc, 0x73, 0x63, 0x2f, 0xb3,
+ 0x5c, 0xcf, 0xbe, 0xef, 0xf8, 0xce, 0xb8, 0xa1, 0xd2, 0x2e, 0xff, 0xdb,
+ 0x8f, 0xb0, 0x8d, 0x33, 0x86, 0xf8, 0x1c, 0xbf, 0xb3, 0xb6, 0xda, 0xda,
+ 0x32, 0x65, 0xfb, 0x74, 0xe9, 0x49, 0x47, 0x9d, 0xf5, 0x92, 0x1a, 0xab,
+ 0x63, 0xb6, 0x97, 0x6b, 0x54, 0xee, 0x3f, 0xdf, 0xb8, 0x56, 0x9b, 0x83,
+ 0x5b, 0x89, 0x67, 0xac, 0xc7, 0x02, 0x01, 0x62, 0x64, 0xe0, 0x94, 0x8d,
+ 0x59, 0xe3, 0x1d, 0xfb, 0x49, 0xdd, 0xc7, 0xf5, 0xb8, 0x95, 0x78, 0x2b,
+ 0xfc, 0xc3, 0x0c, 0xee, 0x9a, 0xf6, 0x79, 0x58, 0x5b, 0xb5, 0x54, 0xc0,
+ 0xa9, 0xad, 0x9c, 0x3e, 0xe1, 0xb1, 0xfc, 0x6d, 0xc1, 0xae, 0x1c, 0xeb,
+ 0x04, 0xd6, 0xa9, 0x6e, 0x8d, 0x76, 0x6b, 0xf0, 0x9e, 0x9c, 0x57, 0xa9,
+ 0x33, 0xe1, 0x6d, 0xdd, 0x68, 0xe3, 0xe3, 0xf5, 0x89, 0xe1, 0xa8, 0x87,
+ 0xd8, 0xc8, 0xb1, 0xac, 0x7c, 0x4b, 0xb0, 0x8f, 0x58, 0x7c, 0x7b, 0x0e,
+ 0x69, 0xe9, 0xa9, 0x86, 0xd7, 0x8f, 0xf6, 0x87, 0x21, 0xfd, 0x2f, 0x7c,
+ 0x89, 0xd1, 0x18, 0xa1, 0xaf, 0x45, 0xdb, 0x95, 0xc4, 0xe2, 0x20, 0x12,
+ 0x17, 0x3e, 0xf6, 0xbe, 0x63, 0x3f, 0x9d, 0xdf, 0xc8, 0xe7, 0x3b, 0x89,
+ 0x93, 0x69, 0xe2, 0xe6, 0xe8, 0xb0, 0x1f, 0xf2, 0x8e, 0xd6, 0xf7, 0xb6,
+ 0x12, 0xa7, 0x8f, 0xe3, 0x77, 0xf8, 0xbc, 0xba, 0x8d, 0x18, 0x39, 0x6b,
+ 0x24, 0xd2, 0x5b, 0x90, 0xe9, 0xac, 0x85, 0x66, 0x34, 0x2a, 0xd2, 0xaf,
+ 0x12, 0xfb, 0x27, 0xf1, 0x3d, 0xce, 0xe9, 0xd3, 0xc5, 0x8e, 0x9b, 0x31,
+ 0x30, 0xab, 0xa9, 0xd7, 0xfd, 0x4c, 0x6c, 0x20, 0x76, 0xe9, 0xa8, 0x40,
+ 0xd5, 0x52, 0xea, 0xf6, 0x3d, 0x07, 0x4f, 0x82, 0xba, 0x8e, 0xff, 0x42,
+ 0x1e, 0xf4, 0x17, 0x05, 0xe9, 0x4b, 0x96, 0xb9, 0x9d, 0xf8, 0x44, 0x73,
+ 0xdb, 0x2d, 0x33, 0xc9, 0x52, 0x9f, 0x32, 0x10, 0xec, 0x9c, 0xb6, 0x71,
+ 0xd2, 0x08, 0x43, 0xea, 0xf3, 0xca, 0x54, 0x91, 0x19, 0xbf, 0x19, 0xdb,
+ 0x78, 0xbd, 0x63, 0xba, 0x5a, 0xe9, 0xc8, 0xd9, 0xf8, 0xa6, 0xa1, 0x65,
+ 0xda, 0xbd, 0x8c, 0x65, 0x43, 0x3b, 0x0b, 0x5c, 0x26, 0x27, 0x12, 0xdf,
+ 0xf2, 0x21, 0xa4, 0xbb, 0x63, 0x35, 0xcf, 0xdc, 0x46, 0xbe, 0x20, 0xb1,
+ 0xe5, 0x5d, 0x53, 0x85, 0x94, 0x32, 0xe3, 0x13, 0xbb, 0x75, 0x22, 0x5d,
+ 0xa8, 0x56, 0x76, 0xd3, 0x96, 0x77, 0xac, 0xab, 0xc0, 0x25, 0xc7, 0x96,
+ 0xb7, 0xd1, 0x96, 0x78, 0x6b, 0x05, 0xbc, 0xe7, 0xeb, 0xd0, 0xa9, 0xc0,
+ 0xa9, 0xbd, 0xaa, 0x99, 0x9f, 0xd3, 0xe4, 0xae, 0xe4, 0x7d, 0x6a, 0x2f,
+ 0xbe, 0x42, 0x9c, 0x79, 0x92, 0x3e, 0xfa, 0x33, 0xbd, 0x19, 0x55, 0x5f,
+ 0x6d, 0xe1, 0x3a, 0x6e, 0x0c, 0xee, 0xc8, 0xf5, 0xe1, 0xa9, 0x79, 0x1b,
+ 0xcf, 0x31, 0x3e, 0x1a, 0x53, 0x19, 0xb5, 0x92, 0xb5, 0x18, 0x73, 0xd9,
+ 0xe2, 0x09, 0xc7, 0xbf, 0x57, 0xb6, 0x6d, 0x9e, 0x8b, 0xc2, 0xfb, 0x15,
+ 0xf9, 0xbb, 0xbe, 0x2d, 0x36, 0x27, 0x9f, 0x51, 0x7e, 0xda, 0x18, 0x32,
+ 0xb4, 0xf4, 0xc7, 0xde, 0x2a, 0x54, 0x27, 0x6c, 0x7b, 0x28, 0x25, 0xd7,
+ 0xf5, 0xb6, 0xa4, 0x73, 0xbf, 0x81, 0x9f, 0xe5, 0x3e, 0xf2, 0xeb, 0xc2,
+ 0xf9, 0x62, 0x69, 0xea, 0xbc, 0x93, 0x79, 0xbd, 0x8f, 0x79, 0xbd, 0xce,
+ 0xd4, 0xd2, 0x7b, 0xbc, 0xd2, 0x3b, 0x29, 0x1e, 0xac, 0xe5, 0xf5, 0x5d,
+ 0xa5, 0xbc, 0x5e, 0x73, 0x4a, 0xfa, 0x70, 0xe4, 0x7a, 0x70, 0xf7, 0x2f,
+ 0xba, 0x99, 0xd7, 0xab, 0x26, 0x7d, 0xe8, 0x62, 0x4e, 0xf7, 0x93, 0x67,
+ 0x6f, 0xcd, 0xd7, 0x21, 0x78, 0xc2, 0x8b, 0x78, 0xea, 0xdb, 0x38, 0x48,
+ 0x1f, 0x3b, 0x98, 0xf4, 0x2a, 0xb1, 0xe5, 0x1e, 0xda, 0xe9, 0x9f, 0x70,
+ 0x40, 0xf5, 0xa2, 0x46, 0xff, 0x2e, 0x1e, 0xfa, 0x35, 0xb9, 0xbc, 0x2f,
+ 0x27, 0x31, 0xbd, 0xb2, 0xad, 0xeb, 0x94, 0x9b, 0xcb, 0x43, 0xa7, 0x46,
+ 0x17, 0x25, 0x97, 0xd7, 0xad, 0xef, 0xc3, 0xe9, 0x69, 0xfc, 0xe1, 0x0a,
+ 0x92, 0xc4, 0x3a, 0xce, 0xd9, 0x90, 0x4a, 0xb0, 0x6e, 0xd6, 0x06, 0xb7,
+ 0x29, 0x89, 0x89, 0x1a, 0xc6, 0xfe, 0x69, 0xe6, 0xf2, 0x80, 0x99, 0x50,
+ 0x93, 0x1e, 0x74, 0xfb, 0xb9, 0x1e, 0x1f, 0xb0, 0x86, 0xfe, 0x61, 0x3e,
+ 0xc6, 0x31, 0x2b, 0xe0, 0x63, 0x2e, 0xff, 0x40, 0xc7, 0xa7, 0x5e, 0xfa,
+ 0xde, 0x65, 0x6f, 0x00, 0x57, 0xf3, 0x6e, 0x2e, 0xaf, 0x6d, 0xb4, 0x47,
+ 0xae, 0xa4, 0x42, 0xf8, 0x30, 0x6f, 0xd0, 0x07, 0xfb, 0x70, 0x84, 0xb9,
+ 0xfc, 0x8a, 0xae, 0xe2, 0xa7, 0xf9, 0x56, 0xfa, 0x65, 0x04, 0x3f, 0x21,
+ 0xcf, 0x5d, 0xc7, 0x5c, 0x7e, 0x27, 0x7d, 0x2a, 0xc5, 0x5c, 0xde, 0xee,
+ 0xf0, 0x8c, 0xe6, 0xb6, 0x33, 0x53, 0x4e, 0x2e, 0x6f, 0x64, 0x89, 0x5f,
+ 0xef, 0x47, 0x62, 0x91, 0xf8, 0x60, 0xff, 0x6c, 0x63, 0x88, 0xcf, 0xd2,
+ 0x6e, 0x85, 0xf5, 0x98, 0x71, 0x72, 0xcf, 0xe6, 0xe0, 0x6e, 0xce, 0xbd,
+ 0xcc, 0x89, 0x33, 0x1b, 0x3b, 0xd7, 0xbd, 0x89, 0x3f, 0x58, 0xe2, 0xa1,
+ 0x1f, 0x9a, 0xc1, 0x3b, 0x18, 0x6b, 0x61, 0xfa, 0xd7, 0x4f, 0x53, 0x89,
+ 0xfe, 0x73, 0xac, 0x21, 0x7f, 0xc2, 0x38, 0xbb, 0x93, 0xbe, 0xb1, 0x72,
+ 0x5d, 0x80, 0xeb, 0xee, 0xc6, 0x59, 0x07, 0xe3, 0x2c, 0xca, 0x38, 0x5b,
+ 0xc1, 0x38, 0x7b, 0xda, 0x48, 0x24, 0x37, 0x93, 0x6f, 0xbd, 0x9e, 0x97,
+ 0x58, 0x6b, 0xe1, 0xb8, 0x1a, 0xf5, 0x1a, 0xed, 0x97, 0x98, 0xd9, 0xb9,
+ 0x6e, 0xf4, 0x6c, 0x35, 0xc4, 0x56, 0xf8, 0x74, 0x19, 0xb9, 0x05, 0x11,
+ 0xe9, 0xc2, 0xa2, 0x37, 0x31, 0xbc, 0xca, 0x9b, 0x18, 0x7a, 0x5f, 0x79,
+ 0xc7, 0x7e, 0x8b, 0x71, 0x76, 0x3b, 0xe3, 0x6c, 0x37, 0xe3, 0xac, 0xdd,
+ 0xb2, 0xf1, 0x52, 0x4a, 0xeb, 0x6b, 0xf6, 0xc4, 0x8d, 0x76, 0x0f, 0x56,
+ 0x54, 0x33, 0x25, 0x04, 0x91, 0xe8, 0xfc, 0x03, 0xca, 0x7f, 0xc1, 0x48,
+ 0xf4, 0x24, 0x15, 0x89, 0xad, 0x18, 0x7e, 0x4c, 0xbd, 0x2b, 0x4b, 0xb1,
+ 0xb5, 0x7f, 0xf6, 0xd5, 0x92, 0x6f, 0x94, 0x75, 0xf7, 0xe2, 0x45, 0x83,
+ 0x18, 0xba, 0x54, 0x8b, 0x65, 0x3c, 0xbd, 0x98, 0xa0, 0x1d, 0x83, 0x89,
+ 0x5e, 0x1c, 0x65, 0x1e, 0xbc, 0x9f, 0xf9, 0xf7, 0x01, 0x2b, 0xde, 0xba,
+ 0x83, 0x75, 0xce, 0xa5, 0xa8, 0x16, 0x8b, 0x29, 0xbd, 0x18, 0xa0, 0x0f,
+ 0x0f, 0x30, 0x5f, 0xb4, 0x5b, 0x3f, 0x57, 0xb6, 0x91, 0x23, 0xdc, 0x57,
+ 0x90, 0xf7, 0xb4, 0x64, 0xbf, 0x67, 0x10, 0xfd, 0xf3, 0x82, 0x6d, 0x50,
+ 0x6f, 0x32, 0x7b, 0x71, 0xdc, 0xaa, 0x40, 0x6f, 0x4b, 0xb7, 0xb2, 0xab,
+ 0x20, 0xbd, 0x33, 0xc6, 0xa3, 0xc5, 0x78, 0x75, 0xe4, 0x55, 0x88, 0xa5,
+ 0xdd, 0xc8, 0x4a, 0x7c, 0x5a, 0xbb, 0x95, 0x3b, 0x67, 0x25, 0xc6, 0x7b,
+ 0x95, 0x5e, 0x89, 0x61, 0x6b, 0x58, 0xb9, 0x4b, 0x62, 0xda, 0xe9, 0x33,
+ 0x4b, 0xdc, 0xcb, 0x3e, 0xc4, 0x6d, 0xe4, 0x6f, 0x60, 0x4c, 0x79, 0xbf,
+ 0x1a, 0x65, 0xdc, 0xb5, 0x57, 0x78, 0xe8, 0xa7, 0x71, 0xae, 0x9d, 0x07,
+ 0x1d, 0xc6, 0x6f, 0xda, 0x19, 0xb5, 0x9f, 0x31, 0xd5, 0x8b, 0x23, 0xd6,
+ 0x6f, 0xd8, 0x57, 0x1c, 0x5e, 0x52, 0xc6, 0xf3, 0xcd, 0xb8, 0x37, 0xb7,
+ 0x1c, 0x01, 0x5d, 0xf2, 0x75, 0x08, 0xc9, 0x25, 0x01, 0x54, 0xe9, 0x92,
+ 0x67, 0x9a, 0xdb, 0x16, 0x4e, 0x50, 0x86, 0x0d, 0xe5, 0xf8, 0xde, 0x8c,
+ 0x07, 0x89, 0x03, 0xfb, 0x52, 0xf7, 0xe2, 0x01, 0xb5, 0x0a, 0x61, 0xda,
+ 0xe9, 0x61, 0x35, 0x44, 0x7c, 0xfd, 0xbd, 0xd2, 0x38, 0xff, 0xa9, 0xa2,
+ 0x54, 0x33, 0x5f, 0xe3, 0x54, 0x75, 0x8c, 0xb1, 0x4d, 0xd3, 0x52, 0x9b,
+ 0x44, 0xdb, 0xa2, 0xd3, 0x3a, 0xc2, 0xac, 0x55, 0x37, 0xa7, 0xb4, 0xe1,
+ 0xcd, 0xde, 0xf8, 0xe0, 0xa2, 0x82, 0x6c, 0x98, 0x7c, 0x2e, 0x9f, 0x48,
+ 0xf4, 0x34, 0x8b, 0x8d, 0xf5, 0x28, 0xb6, 0xd3, 0x4e, 0x5d, 0xf9, 0x08,
+ 0x63, 0xe8, 0xbd, 0x0a, 0xe1, 0x46, 0xe9, 0xfc, 0xf5, 0xb1, 0xa2, 0x1c,
+ 0x2b, 0x3a, 0x2d, 0x3c, 0x2d, 0x4a, 0x9e, 0xa6, 0x33, 0x0e, 0x6d, 0x7b,
+ 0x13, 0xf9, 0x59, 0xe8, 0x94, 0xd4, 0x38, 0xf1, 0x09, 0x72, 0xda, 0x66,
+ 0xf2, 0xdd, 0x5e, 0x7a, 0xb5, 0xbd, 0xb2, 0x21, 0x61, 0xb4, 0x2b, 0x78,
+ 0x62, 0xae, 0x85, 0xf5, 0x11, 0xc7, 0xbc, 0x9c, 0x57, 0x71, 0x25, 0x1f,
+ 0xc5, 0xbb, 0x1c, 0xfb, 0x92, 0x33, 0x76, 0x3d, 0x7e, 0x54, 0xc2, 0xad,
+ 0x14, 0x71, 0x6b, 0x4b, 0x4e, 0xa1, 0xbf, 0xc6, 0x30, 0x62, 0xfc, 0xdd,
+ 0xa7, 0x97, 0x6e, 0x0e, 0xd0, 0x6e, 0xa2, 0x8b, 0x8f, 0x9f, 0xe3, 0x78,
+ 0xd8, 0xc1, 0xe9, 0x37, 0x3f, 0x9d, 0x59, 0xc2, 0xb5, 0xa2, 0xed, 0x6b,
+ 0x4b, 0xef, 0xad, 0x9d, 0xf9, 0xf3, 0x92, 0xbe, 0x3a, 0x3c, 0xa7, 0x92,
+ 0xa8, 0x38, 0x75, 0x4d, 0x56, 0x5d, 0xe2, 0x83, 0x19, 0xf5, 0x89, 0xaf,
+ 0x71, 0xfe, 0xc7, 0xc8, 0xf5, 0x6c, 0xce, 0x7f, 0xd5, 0x99, 0x37, 0xc2,
+ 0x79, 0x95, 0x6b, 0xbc, 0x30, 0x7a, 0xed, 0x1d, 0x95, 0xba, 0xe3, 0xf1,
+ 0x28, 0x6d, 0xf7, 0xe1, 0x06, 0x79, 0x2e, 0x84, 0x5d, 0xf9, 0x15, 0x95,
+ 0x82, 0xe3, 0x41, 0xd6, 0x01, 0xae, 0x2f, 0x91, 0xe7, 0x59, 0xcf, 0xf1,
+ 0x9e, 0xf0, 0xae, 0xcd, 0xe4, 0x18, 0x9f, 0xb5, 0x7b, 0x84, 0x6b, 0xf1,
+ 0x7f, 0xf8, 0x8e, 0xdc, 0xfb, 0x75, 0x79, 0xf4, 0x4f, 0x31, 0xcc, 0x1a,
+ 0xe8, 0xb1, 0x5c, 0x06, 0x0f, 0xe7, 0xbe, 0xec, 0xec, 0xab, 0xad, 0x5d,
+ 0x8f, 0xfb, 0x38, 0xe7, 0x81, 0x5a, 0xc6, 0xd1, 0x7f, 0x4b, 0x25, 0x84,
+ 0x1b, 0xed, 0xae, 0x86, 0xe4, 0xda, 0x44, 0xeb, 0x2a, 0xc5, 0x46, 0x45,
+ 0x0a, 0x43, 0x1d, 0x2d, 0x89, 0xe4, 0x15, 0x3c, 0x61, 0x4b, 0x5f, 0xd3,
+ 0x5b, 0xca, 0xbb, 0x52, 0xff, 0x49, 0x6f, 0xb5, 0xbd, 0xc4, 0x91, 0xb6,
+ 0x14, 0xde, 0xf9, 0x4c, 0xef, 0x40, 0xea, 0x6e, 0xc9, 0x37, 0x41, 0xa5,
+ 0x9d, 0xf3, 0x1c, 0x21, 0x66, 0xbf, 0x68, 0xbc, 0x12, 0x65, 0x36, 0x86,
+ 0x6f, 0x9d, 0x82, 0x83, 0x86, 0x1f, 0x99, 0x88, 0x8d, 0xdd, 0xfc, 0xdc,
+ 0x4f, 0xde, 0xf4, 0x9e, 0x51, 0x83, 0x19, 0x55, 0x25, 0x57, 0x24, 0x06,
+ 0x7b, 0xde, 0xf4, 0xcb, 0x5e, 0x4c, 0xcc, 0x23, 0xfb, 0xe6, 0xff, 0xd6,
+ 0x5e, 0xca, 0x3a, 0xf2, 0x16, 0xd1, 0x3d, 0xa8, 0x10, 0x43, 0x93, 0x20,
+ 0x97, 0xd9, 0x6b, 0x14, 0x63, 0x1e, 0xa4, 0xaf, 0x7a, 0xa0, 0x9d, 0xbe,
+ 0xcc, 0xfa, 0xee, 0xb1, 0x06, 0xed, 0x74, 0x9b, 0x57, 0xc7, 0xf0, 0xf1,
+ 0x00, 0x1e, 0x39, 0xbe, 0x0d, 0xb5, 0x4e, 0xef, 0x67, 0x9c, 0x36, 0xf5,
+ 0xb0, 0xae, 0x1a, 0xfd, 0xa5, 0x8f, 0xf5, 0xd5, 0xd5, 0xf5, 0x8f, 0xa3,
+ 0xd5, 0xb9, 0x3e, 0x86, 0xfb, 0x72, 0x41, 0xa5, 0x2b, 0xe7, 0xc3, 0xb6,
+ 0x3b, 0x1f, 0x87, 0x7f, 0x5d, 0x3f, 0xe5, 0x92, 0xeb, 0xf2, 0xf7, 0x5d,
+ 0xac, 0xcb, 0x44, 0xbe, 0x0a, 0xc4, 0x96, 0x53, 0xb6, 0x75, 0x3a, 0x46,
+ 0x8e, 0xfb, 0x94, 0x3d, 0xd6, 0x7f, 0xb7, 0xaf, 0x3a, 0xfb, 0x34, 0x72,
+ 0xad, 0x4a, 0xf6, 0xef, 0xf9, 0x8c, 0x60, 0xce, 0x00, 0x72, 0x8c, 0xed,
+ 0xbb, 0x9c, 0xf7, 0xff, 0xb8, 0xc2, 0xd5, 0x29, 0xcd, 0x7a, 0xb5, 0x83,
+ 0xeb, 0x27, 0xcf, 0x24, 0x4b, 0xd7, 0x9a, 0x03, 0xee, 0x19, 0x01, 0xf1,
+ 0x85, 0x01, 0xdc, 0xc2, 0x45, 0x68, 0x48, 0x88, 0x8f, 0x0d, 0xa0, 0x21,
+ 0x4f, 0x40, 0x5d, 0xee, 0xca, 0xfb, 0x90, 0x55, 0x64, 0xad, 0xa9, 0x13,
+ 0x37, 0x69, 0xbb, 0x65, 0xf2, 0xfe, 0x2f, 0x2a, 0x7f, 0xf5, 0x7d, 0xc1,
+ 0x5b, 0x72, 0xcc, 0xb0, 0x70, 0xcd, 0x5f, 0x77, 0xff, 0xb7, 0x20, 0xf7,
+ 0x7c, 0xfa, 0x9f, 0x30, 0x8e, 0x13, 0x3d, 0xd5, 0x1e, 0xf1, 0x9f, 0x3f,
+ 0xc1, 0x03, 0xb3, 0x8f, 0xf0, 0xbe, 0x8c, 0x7f, 0x88, 0x35, 0x84, 0x4f,
+ 0xe9, 0x24, 0xfe, 0xec, 0x3f, 0xee, 0xd9, 0x55, 0x81, 0xbf, 0xb4, 0x2b,
+ 0x97, 0x8d, 0xa0, 0x21, 0x35, 0xc6, 0xe7, 0x15, 0x74, 0x90, 0x2f, 0x3e,
+ 0x65, 0x6c, 0xc1, 0xb6, 0x25, 0x82, 0x01, 0x2f, 0xda, 0x03, 0xbd, 0x62,
+ 0x43, 0x05, 0x5b, 0x79, 0xfd, 0x25, 0xae, 0xef, 0xb3, 0x86, 0x0f, 0x0d,
+ 0x4b, 0xa5, 0x8f, 0xa7, 0x4d, 0xa5, 0xd1, 0x1e, 0x70, 0xf7, 0xab, 0x32,
+ 0x76, 0xad, 0xae, 0x0f, 0xdd, 0xe1, 0x69, 0x98, 0x7a, 0x9b, 0xfe, 0xd4,
+ 0xbe, 0xee, 0xc6, 0x7b, 0x65, 0x9b, 0x18, 0xe4, 0x90, 0x2f, 0xd8, 0xb8,
+ 0x69, 0x14, 0xea, 0xba, 0x1b, 0xd7, 0xbf, 0x2c, 0xf7, 0x21, 0xc6, 0x20,
+ 0x32, 0xb5, 0xa6, 0xf4, 0x79, 0x12, 0x1c, 0xe7, 0x10, 0x7e, 0xbf, 0x30,
+ 0x86, 0x83, 0xb9, 0x12, 0xa7, 0xa6, 0x6f, 0xeb, 0xeb, 0xae, 0xeb, 0xf6,
+ 0x50, 0x2e, 0xd1, 0x5f, 0x53, 0xd2, 0xed, 0x00, 0xeb, 0x8b, 0x6a, 0x62,
+ 0xec, 0x83, 0xb4, 0xe9, 0x90, 0x63, 0xd3, 0x5e, 0x18, 0xf9, 0xeb, 0xe3,
+ 0x0e, 0x72, 0xdc, 0xa0, 0x29, 0x76, 0x93, 0x3d, 0xb2, 0x43, 0xd8, 0xcf,
+ 0x71, 0xf7, 0xdd, 0x30, 0xee, 0x80, 0x71, 0x7d, 0xdc, 0xbd, 0xb9, 0xc4,
+ 0x69, 0x4f, 0x69, 0xdc, 0x47, 0x67, 0xcb, 0x63, 0x64, 0x70, 0xfb, 0xba,
+ 0x0c, 0xf2, 0x9b, 0x0e, 0xd8, 0x07, 0x1c, 0x7b, 0x9c, 0x72, 0xae, 0x6f,
+ 0x6d, 0x10, 0xee, 0xc5, 0x3f, 0x4d, 0xd9, 0x8f, 0x4f, 0x92, 0x7b, 0xe9,
+ 0xce, 0x9e, 0xf0, 0x37, 0x0a, 0xe5, 0xbe, 0x94, 0xf6, 0x4e, 0x97, 0x37,
+ 0xcd, 0xd8, 0x8e, 0x04, 0x76, 0x7c, 0xa6, 0x97, 0xb1, 0x8d, 0xf5, 0xd7,
+ 0x76, 0xab, 0x3b, 0xd8, 0x69, 0x05, 0xc8, 0xbb, 0xaa, 0x95, 0xad, 0x39,
+ 0xe9, 0x69, 0x48, 0x2c, 0x97, 0xb8, 0x70, 0x41, 0xea, 0xbc, 0xbb, 0x59,
+ 0x1f, 0x2c, 0x0f, 0x20, 0xdc, 0x8f, 0x89, 0xc2, 0xef, 0x2a, 0xe9, 0x88,
+ 0xec, 0x4d, 0x4b, 0x5e, 0x01, 0x73, 0x5e, 0x0f, 0xaa, 0xe9, 0x4b, 0x11,
+ 0xd3, 0x30, 0x4f, 0x36, 0xd8, 0x20, 0x47, 0x09, 0x2c, 0x35, 0xd3, 0xe6,
+ 0xee, 0x06, 0x2f, 0x8e, 0x39, 0xfc, 0x4b, 0x9b, 0xe1, 0xef, 0x94, 0xc4,
+ 0xcc, 0x1d, 0x39, 0xc9, 0x63, 0xa4, 0x90, 0xfa, 0x08, 0xfe, 0x31, 0x55,
+ 0x1c, 0x5a, 0x82, 0xf4, 0xfd, 0x4b, 0x20, 0xf5, 0xc4, 0x04, 0xfe, 0x4a,
+ 0x8f, 0x06, 0xfa, 0x0a, 0x3e, 0xa5, 0xcb, 0x9a, 0x0b, 0xee, 0xb4, 0xc2,
+ 0x08, 0xb1, 0x1e, 0xeb, 0xf6, 0xc6, 0x59, 0x5f, 0x88, 0x1d, 0x03, 0x6d,
+ 0xb7, 0xe4, 0xfb, 0x82, 0x1d, 0x96, 0x8b, 0x85, 0x2b, 0x67, 0x02, 0xc1,
+ 0x6d, 0xd3, 0xf1, 0xe8, 0x84, 0xc3, 0xc5, 0x42, 0x6d, 0xf1, 0xbc, 0x6d,
+ 0xbf, 0x61, 0x14, 0xaf, 0x56, 0x3a, 0xdf, 0x8d, 0xb6, 0x64, 0xbe, 0x19,
+ 0xf7, 0x90, 0x3f, 0xb5, 0x4f, 0x37, 0xc3, 0x98, 0x06, 0x4e, 0x1c, 0x8f,
+ 0x62, 0x6d, 0x4e, 0x3b, 0x3d, 0xec, 0xed, 0xc3, 0xd4, 0x7c, 0x27, 0x72,
+ 0x85, 0xe0, 0x62, 0xcc, 0x43, 0x5e, 0x9d, 0xf2, 0x60, 0x97, 0x71, 0x5c,
+ 0x29, 0x2e, 0x53, 0x70, 0x17, 0x11, 0xbc, 0xdf, 0xe1, 0x13, 0x73, 0xac,
+ 0x47, 0x15, 0xdc, 0xe4, 0xe0, 0x6e, 0x4b, 0xdb, 0x5a, 0xf2, 0xed, 0x3b,
+ 0xc9, 0x07, 0x77, 0x11, 0x57, 0x12, 0xeb, 0x6c, 0xbc, 0x99, 0xca, 0xf4,
+ 0xd7, 0x40, 0xeb, 0x39, 0xcc, 0x1a, 0xa8, 0x47, 0x71, 0xf9, 0x5d, 0xd3,
+ 0x9c, 0xcb, 0x09, 0x57, 0xcd, 0xb5, 0x90, 0x37, 0xb2, 0xae, 0x49, 0x69,
+ 0x31, 0x8f, 0x47, 0xc5, 0x94, 0x33, 0x46, 0xac, 0xcd, 0x98, 0xab, 0x60,
+ 0xbe, 0xeb, 0xc5, 0xd3, 0x8e, 0xfc, 0x49, 0xca, 0x77, 0x37, 0xbe, 0x66,
+ 0xf5, 0x05, 0xfb, 0x2c, 0xd9, 0xbf, 0x8c, 0x27, 0xaf, 0x7a, 0x4d, 0xf2,
+ 0xd7, 0x78, 0xac, 0xce, 0xfb, 0x05, 0x25, 0xe3, 0x6b, 0x6a, 0x9d, 0x83,
+ 0xa9, 0x5c, 0x2a, 0x71, 0x36, 0xd1, 0x2f, 0x41, 0x8e, 0xd5, 0x7e, 0x3c,
+ 0xb8, 0x98, 0x86, 0xdb, 0xb3, 0xd9, 0x66, 0xfc, 0x2f, 0x14, 0x23, 0xda,
+ 0x44, 0x9a, 0x18, 0xb0, 0x85, 0x98, 0xdb, 0xdf, 0xeb, 0xe3, 0x7d, 0xe9,
+ 0x79, 0xa9, 0x6d, 0xe3, 0x59, 0x14, 0x83, 0x66, 0x22, 0x73, 0x94, 0x9e,
+ 0xd3, 0x53, 0x90, 0xfd, 0x8d, 0x00, 0x1e, 0x60, 0xed, 0x94, 0x2e, 0xed,
+ 0xfd, 0x6c, 0x9d, 0x76, 0xf7, 0xb3, 0x0e, 0xcf, 0xfb, 0xc2, 0xdd, 0x56,
+ 0x0b, 0xf3, 0xbd, 0xef, 0x86, 0xb1, 0x13, 0x13, 0x2b, 0x3d, 0x1e, 0xac,
+ 0x5e, 0xb7, 0x47, 0x99, 0x59, 0x56, 0xce, 0xad, 0x51, 0x27, 0x1f, 0x56,
+ 0x50, 0xcf, 0xf3, 0x27, 0x65, 0x8e, 0xcf, 0xb5, 0x8d, 0x9f, 0x94, 0x5c,
+ 0xab, 0xb6, 0x6d, 0xb2, 0xb4, 0x3e, 0xa9, 0xfd, 0xa2, 0xb4, 0x53, 0x94,
+ 0xba, 0xad, 0x30, 0xd7, 0xb4, 0xd9, 0xd3, 0x5a, 0x74, 0x40, 0x49, 0x93,
+ 0xf7, 0x69, 0xc9, 0x5b, 0xbc, 0x1e, 0x3c, 0xa2, 0x6b, 0x83, 0xd2, 0x13,
+ 0x7c, 0x19, 0x2e, 0x07, 0x6e, 0x9a, 0x1b, 0x60, 0x5e, 0x73, 0x6d, 0xeb,
+ 0xf6, 0x07, 0xeb, 0xdb, 0x9a, 0x1d, 0x5e, 0x6c, 0xdb, 0x97, 0x53, 0xdd,
+ 0xe4, 0x0c, 0xc2, 0x8b, 0xe5, 0xfa, 0xea, 0xb6, 0xc6, 0x99, 0x00, 0x65,
+ 0x53, 0xf0, 0x3e, 0x73, 0xd2, 0x44, 0xa1, 0x2c, 0xa3, 0xcb, 0x99, 0x77,
+ 0x90, 0x33, 0x57, 0x99, 0x5a, 0x6b, 0x17, 0x39, 0xb3, 0x9e, 0x2a, 0xd6,
+ 0xf9, 0xd0, 0x8b, 0xa7, 0xac, 0x66, 0x39, 0xe3, 0xe4, 0xf0, 0xe6, 0x2b,
+ 0x27, 0xb5, 0xb4, 0x70, 0xe6, 0x1f, 0x18, 0xc0, 0x3d, 0xe4, 0xcc, 0x57,
+ 0xb3, 0x3e, 0xec, 0x21, 0x67, 0x5e, 0xcc, 0x06, 0xd0, 0x47, 0xce, 0xfc,
+ 0x11, 0xf9, 0xd5, 0xbb, 0xa9, 0x2b, 0x78, 0xb4, 0xd4, 0x07, 0xdb, 0x9b,
+ 0xf4, 0xd0, 0xaf, 0x85, 0x37, 0xff, 0xbc, 0xc4, 0x9b, 0xe7, 0xff, 0x05,
+ 0x6f, 0xde, 0x4a, 0x3e, 0xd8, 0x9d, 0x13, 0x4e, 0xb0, 0x92, 0x9c, 0xc0,
+ 0xc6, 0xcb, 0xa5, 0x1e, 0xd8, 0x0a, 0xe6, 0xb3, 0xa7, 0x53, 0x7d, 0xc8,
+ 0x4e, 0x63, 0x79, 0x8d, 0xd3, 0x77, 0x12, 0x99, 0x34, 0xe3, 0xb2, 0x92,
+ 0xe8, 0xec, 0x43, 0x82, 0xf5, 0xb1, 0x96, 0xbc, 0xe8, 0xf6, 0xc0, 0x16,
+ 0xdf, 0x85, 0xf4, 0x88, 0x7c, 0xa8, 0x59, 0x00, 0x56, 0xdc, 0xd0, 0x03,
+ 0xab, 0x49, 0xe0, 0x4f, 0xeb, 0x20, 0xfb, 0x9a, 0x0c, 0xb3, 0x85, 0x66,
+ 0xc6, 0xa7, 0x82, 0x23, 0x89, 0x10, 0xba, 0x8f, 0x93, 0xf3, 0x38, 0x3d,
+ 0x30, 0x7b, 0xe4, 0x3b, 0x46, 0x1f, 0x8e, 0xce, 0xbb, 0x3d, 0xb0, 0xed,
+ 0xe4, 0x6e, 0xbe, 0x44, 0x04, 0x95, 0x0b, 0x3e, 0xbc, 0x40, 0xee, 0xbc,
+ 0x95, 0xeb, 0x7c, 0xa6, 0xd4, 0x07, 0x5b, 0xc1, 0x18, 0xb1, 0x73, 0x2a,
+ 0x66, 0x16, 0xf0, 0x86, 0x17, 0xb8, 0xb8, 0xc2, 0xe9, 0xed, 0x4b, 0xff,
+ 0x3f, 0x84, 0x73, 0x0e, 0x77, 0x0e, 0x2e, 0x66, 0x14, 0x57, 0xb7, 0x0a,
+ 0xae, 0x89, 0xac, 0xab, 0x87, 0xeb, 0xda, 0x7e, 0x52, 0xeb, 0x7c, 0x85,
+ 0xb6, 0x68, 0x4a, 0xbc, 0xea, 0xac, 0xc7, 0x40, 0x4a, 0x6a, 0xd9, 0x40,
+ 0x5b, 0xc0, 0x39, 0x0f, 0xa5, 0xb6, 0xfd, 0x28, 0x1b, 0xef, 0xa9, 0x2c,
+ 0xc5, 0xe3, 0xaa, 0x7c, 0x05, 0xd2, 0x25, 0x1f, 0x09, 0xd0, 0xa7, 0x03,
+ 0x93, 0x69, 0x54, 0x6d, 0x70, 0xfd, 0x7b, 0x55, 0x7e, 0x9c, 0xbc, 0xb5,
+ 0x53, 0xea, 0xe8, 0xf0, 0x76, 0xab, 0x13, 0x53, 0x56, 0x0c, 0x95, 0xe7,
+ 0x4a, 0x7b, 0xa6, 0xe7, 0xe4, 0xec, 0x5c, 0x7d, 0x9b, 0xfa, 0xd5, 0x32,
+ 0x1f, 0x4c, 0x93, 0xe3, 0x44, 0x02, 0x77, 0x14, 0x84, 0x2b, 0xf6, 0xe0,
+ 0xa8, 0xa5, 0x45, 0xbf, 0x87, 0xf8, 0xd0, 0xfd, 0xb4, 0x51, 0xb1, 0xee,
+ 0x7a, 0xbf, 0x69, 0x40, 0xfa, 0x51, 0x9f, 0xe9, 0x37, 0x0d, 0xe7, 0xf0,
+ 0x8b, 0xba, 0x96, 0x4a, 0x78, 0xd6, 0xfa, 0xc9, 0xe7, 0xb5, 0xe8, 0xd3,
+ 0x78, 0x02, 0x23, 0xb9, 0x9f, 0x2b, 0x21, 0xdd, 0x37, 0xf8, 0x13, 0xaf,
+ 0x16, 0x9d, 0x53, 0x42, 0x7c, 0xf7, 0xee, 0x60, 0x97, 0x75, 0x37, 0x71,
+ 0x27, 0x9e, 0xec, 0x54, 0xbc, 0x98, 0x89, 0x3a, 0x5c, 0x34, 0xd8, 0xc3,
+ 0x6b, 0x53, 0x85, 0x32, 0xa7, 0x71, 0x6b, 0xfe, 0xed, 0xc7, 0x5d, 0xfc,
+ 0x88, 0xe7, 0x83, 0x8b, 0x97, 0xe0, 0xea, 0x56, 0x4d, 0x5d, 0x1f, 0x9c,
+ 0x54, 0xed, 0xfe, 0x65, 0x12, 0xc3, 0x3a, 0xf6, 0xd0, 0xf7, 0xee, 0x99,
+ 0x1e, 0xa0, 0x9c, 0xc2, 0xa5, 0x57, 0x10, 0xa7, 0xfa, 0x30, 0x4e, 0x9c,
+ 0xb1, 0x28, 0x5f, 0x8e, 0x35, 0xe4, 0xe2, 0xfa, 0x8c, 0x3d, 0xb9, 0x41,
+ 0x37, 0x56, 0x7b, 0x8b, 0x4b, 0xa2, 0xe4, 0x36, 0xeb, 0x98, 0xb7, 0xdb,
+ 0x0b, 0xcd, 0xb8, 0x7c, 0x46, 0x67, 0x7d, 0xdb, 0x41, 0xee, 0xde, 0x83,
+ 0x87, 0xa9, 0xcf, 0xa3, 0x85, 0xc7, 0x91, 0xfe, 0x92, 0x0f, 0x87, 0x8f,
+ 0xa7, 0xb1, 0x6a, 0x5d, 0x0a, 0xe9, 0x2f, 0x06, 0x88, 0x53, 0x21, 0x4c,
+ 0x30, 0x16, 0xa1, 0xb8, 0x7e, 0x2e, 0xe7, 0x7f, 0xfe, 0x82, 0x36, 0xfb,
+ 0x26, 0xed, 0xf7, 0x8d, 0x6b, 0x7b, 0x00, 0x65, 0xfe, 0x7d, 0x9d, 0xab,
+ 0x7a, 0xb9, 0x86, 0xfb, 0x9c, 0xd8, 0x8c, 0x32, 0x36, 0x75, 0x5c, 0x2d,
+ 0xf5, 0x12, 0x17, 0x4f, 0x6a, 0x8b, 0xf7, 0x22, 0x3e, 0x7c, 0xd9, 0x8b,
+ 0x81, 0x3a, 0xfa, 0x5d, 0x94, 0x5c, 0xf5, 0xc3, 0x44, 0xc2, 0x38, 0x47,
+ 0xae, 0x3a, 0xba, 0xc1, 0xe5, 0xaa, 0x9e, 0x05, 0x15, 0x15, 0x0b, 0xac,
+ 0x65, 0x9d, 0x5e, 0xe2, 0x37, 0x83, 0x6e, 0x2f, 0x51, 0xf8, 0x4d, 0xab,
+ 0x9c, 0x75, 0xba, 0x8d, 0xb5, 0x5c, 0xfa, 0x0a, 0x32, 0xe8, 0x2c, 0xcc,
+ 0x04, 0xef, 0x21, 0x36, 0xf7, 0x49, 0x6f, 0xa4, 0x10, 0x09, 0xdf, 0x43,
+ 0xde, 0xf5, 0x2d, 0xae, 0xaf, 0xec, 0xed, 0xf6, 0x15, 0x56, 0xf3, 0xbd,
+ 0x28, 0x3f, 0x05, 0x57, 0x45, 0xf6, 0x1b, 0xf5, 0xe8, 0xa9, 0x92, 0xbd,
+ 0x86, 0x97, 0xa9, 0x43, 0xff, 0xdc, 0x4a, 0x3c, 0x3a, 0xe7, 0xaf, 0x12,
+ 0xc2, 0xff, 0x68, 0xde, 0xc5, 0xb6, 0x58, 0xfe, 0xae, 0xa0, 0xf0, 0xc9,
+ 0xf6, 0xe3, 0xee, 0x77, 0xfd, 0x86, 0xef, 0x65, 0xfd, 0x56, 0x50, 0x3f,
+ 0x7b, 0x5a, 0xea, 0xa2, 0x68, 0xdb, 0x19, 0xea, 0xb7, 0x78, 0xd2, 0x89,
+ 0x2f, 0xd6, 0x98, 0xf1, 0xe1, 0x84, 0x57, 0xf4, 0xfa, 0x99, 0xe8, 0x45,
+ 0xae, 0xc2, 0x78, 0xe1, 0xb8, 0x1e, 0x3d, 0xe2, 0xe8, 0xe5, 0xea, 0xe3,
+ 0xf6, 0x69, 0xaf, 0x9c, 0x4c, 0xde, 0xd8, 0x17, 0xd5, 0xc9, 0x97, 0x3f,
+ 0x61, 0x6c, 0x3c, 0x71, 0x98, 0x9c, 0xf9, 0x2a, 0x6b, 0x4a, 0x3f, 0x9f,
+ 0xaf, 0x73, 0x9e, 0x97, 0x3e, 0xad, 0xe7, 0x1a, 0x67, 0x5e, 0xbc, 0xfe,
+ 0x4e, 0x89, 0x2f, 0x4b, 0x4f, 0x5a, 0x9e, 0x53, 0x1d, 0x3b, 0xed, 0x76,
+ 0x78, 0xa0, 0x70, 0x2b, 0x1b, 0x1d, 0xeb, 0xfe, 0xad, 0x35, 0x0b, 0x2e,
+ 0xce, 0x38, 0x6e, 0xd5, 0x55, 0x25, 0x7b, 0xe1, 0xab, 0xd6, 0x3d, 0x68,
+ 0xbb, 0xfe, 0x1c, 0x09, 0xef, 0x62, 0x9c, 0x7c, 0x85, 0xef, 0xec, 0x3a,
+ 0x57, 0x1f, 0xbe, 0xcb, 0x6a, 0x71, 0x6c, 0x74, 0xd7, 0xb9, 0x28, 0x46,
+ 0x2d, 0xe9, 0xeb, 0x43, 0xf1, 0x99, 0x87, 0xb1, 0x7d, 0x2a, 0x86, 0x77,
+ 0x8d, 0x60, 0xe9, 0xec, 0x89, 0xc4, 0xa4, 0xc1, 0x98, 0x8c, 0xd0, 0x77,
+ 0xe3, 0xb1, 0x77, 0xc9, 0x51, 0x33, 0x3e, 0xe0, 0x68, 0x8e, 0xb8, 0x46,
+ 0xde, 0x08, 0xc5, 0x3d, 0xbb, 0xe9, 0xbe, 0x5b, 0xfe, 0xbb, 0x1a, 0xb1,
+ 0x25, 0xf1, 0xd6, 0xfd, 0xa8, 0x47, 0x96, 0xd8, 0x1f, 0xd4, 0xff, 0x1a,
+ 0xc7, 0x4e, 0x78, 0x98, 0x1f, 0x08, 0x4e, 0x77, 0x1a, 0xfc, 0xde, 0x34,
+ 0xf8, 0x01, 0xfe, 0xd1, 0x9e, 0x91, 0xf3, 0x51, 0x8a, 0x9c, 0xc5, 0xf8,
+ 0xc4, 0xae, 0xd3, 0xf5, 0xe2, 0xb7, 0xa0, 0x0f, 0x5f, 0x45, 0xd3, 0xd0,
+ 0x22, 0x7e, 0x6c, 0x17, 0x79, 0xef, 0x7d, 0xc6, 0xd1, 0x2b, 0x46, 0x3c,
+ 0xea, 0xa1, 0xf0, 0xc5, 0x88, 0x17, 0xf7, 0x1b, 0xb2, 0xa7, 0xa4, 0x0d,
+ 0x3d, 0x0f, 0x6d, 0xf0, 0xbc, 0x22, 0x67, 0x6a, 0x2e, 0xd9, 0x99, 0x25,
+ 0x32, 0xaf, 0x82, 0xb5, 0xab, 0x9b, 0x3a, 0x2b, 0xa0, 0xb5, 0xfa, 0x15,
+ 0xdd, 0xf8, 0x40, 0xf9, 0x7b, 0xbb, 0x18, 0xf9, 0xc4, 0xbe, 0xac, 0x97,
+ 0xc7, 0xd5, 0x62, 0x01, 0x6f, 0x59, 0xb6, 0x7a, 0x1c, 0xb3, 0x64, 0x2f,
+ 0xee, 0xaf, 0xf1, 0xc0, 0x09, 0x1f, 0x3a, 0x52, 0x3f, 0xb1, 0x33, 0x11,
+ 0x19, 0xf3, 0x13, 0xda, 0x42, 0xc6, 0x77, 0xfb, 0xd5, 0x2f, 0x17, 0xa0,
+ 0x6c, 0xb3, 0x84, 0x33, 0x8b, 0x5f, 0x4c, 0xc1, 0xb6, 0xa4, 0x87, 0x68,
+ 0xe3, 0x8e, 0xd4, 0x08, 0xde, 0x4f, 0xa5, 0xff, 0x63, 0x00, 0xda, 0x85,
+ 0x2b, 0x5e, 0xad, 0xd8, 0xec, 0x8d, 0x29, 0xc1, 0x46, 0x7d, 0xa8, 0xd1,
+ 0xdd, 0x9f, 0x67, 0xfd, 0x14, 0x0a, 0xec, 0x2a, 0x48, 0x9d, 0x39, 0x85,
+ 0x85, 0xc9, 0x0c, 0x7c, 0xe4, 0x77, 0xa3, 0x2d, 0x5a, 0xdf, 0x73, 0x8a,
+ 0x16, 0x3d, 0xa0, 0xc4, 0x94, 0x7b, 0xf5, 0x61, 0xbc, 0x60, 0x24, 0xd2,
+ 0xed, 0x4a, 0x7d, 0xa0, 0xb3, 0x50, 0x1e, 0xbb, 0x83, 0xb8, 0xa1, 0x15,
+ 0xaf, 0x78, 0x2b, 0x51, 0xb7, 0x5e, 0xef, 0xac, 0xf4, 0x6a, 0xc3, 0x5f,
+ 0x60, 0x1d, 0xb0, 0xa3, 0x50, 0x0c, 0x7e, 0x90, 0xf0, 0x60, 0x8d, 0xb3,
+ 0x87, 0x90, 0x2d, 0xf5, 0x47, 0xa7, 0xd0, 0x35, 0x69, 0x6f, 0xbe, 0x98,
+ 0xd2, 0xa2, 0xcf, 0x29, 0x99, 0x3d, 0x21, 0xf2, 0x9a, 0x07, 0xa1, 0xc7,
+ 0xe6, 0x19, 0xc7, 0x1d, 0x05, 0x0f, 0x56, 0x3a, 0x7e, 0x9c, 0xe5, 0x98,
+ 0x87, 0x51, 0x79, 0xc2, 0xde, 0xbc, 0xc7, 0xd0, 0x86, 0xaf, 0x78, 0x33,
+ 0xff, 0xb5, 0x8e, 0x76, 0xdb, 0xa6, 0x68, 0xac, 0x4f, 0x47, 0x70, 0x91,
+ 0x3a, 0x7c, 0x3d, 0xa5, 0x25, 0xff, 0x4c, 0xd1, 0x7a, 0xbe, 0x4c, 0x5f,
+ 0xf6, 0x9a, 0x61, 0xca, 0xa9, 0x25, 0x67, 0x21, 0xbd, 0xf3, 0x18, 0xae,
+ 0x18, 0x99, 0xe0, 0xf6, 0xc6, 0x24, 0xf9, 0x59, 0x94, 0xf9, 0x30, 0x86,
+ 0xa3, 0xe4, 0x77, 0x87, 0x0b, 0x15, 0x28, 0xaa, 0x3a, 0xf9, 0x59, 0x0f,
+ 0x3c, 0x93, 0x21, 0x65, 0x2e, 0x1b, 0x37, 0x3a, 0xf0, 0x47, 0x28, 0x3a,
+ 0x38, 0x77, 0x18, 0xa1, 0x13, 0x3f, 0xb0, 0x6b, 0x74, 0xbd, 0x75, 0x52,
+ 0xe1, 0xbc, 0xcf, 0x44, 0x69, 0x63, 0xbe, 0x27, 0xe7, 0x4e, 0xac, 0x6e,
+ 0xdc, 0x3b, 0x19, 0xe1, 0xfb, 0x35, 0x58, 0x7b, 0x22, 0x86, 0x0f, 0x53,
+ 0x37, 0xa3, 0xe8, 0x70, 0x04, 0x85, 0x7e, 0x40, 0x3f, 0x62, 0xad, 0x95,
+ 0x21, 0x8f, 0x94, 0x7d, 0xa3, 0xc3, 0x96, 0xd4, 0xe8, 0x3e, 0x7e, 0x0f,
+ 0xf1, 0x57, 0xec, 0xf9, 0x39, 0x72, 0x1d, 0xf9, 0x5c, 0xd3, 0x16, 0x9b,
+ 0xfb, 0x5e, 0x95, 0xb3, 0x7f, 0x89, 0x18, 0x9f, 0x53, 0x9d, 0xde, 0xe0,
+ 0x28, 0xc7, 0x3c, 0x3b, 0x25, 0xb5, 0x5b, 0xfb, 0xa6, 0x40, 0x69, 0x7f,
+ 0xfd, 0x87, 0x86, 0x07, 0x9b, 0x59, 0xdf, 0x47, 0x75, 0x39, 0x9b, 0x39,
+ 0xaa, 0xd5, 0x61, 0x13, 0x4e, 0xab, 0x2c, 0xc4, 0xf5, 0xff, 0x80, 0x09,
+ 0x35, 0x49, 0xac, 0xd1, 0xf1, 0x5e, 0xf6, 0x37, 0x58, 0xf3, 0xd4, 0xcb,
+ 0xd9, 0x1b, 0xac, 0x3c, 0xe1, 0xe7, 0x9c, 0x9b, 0xc9, 0x75, 0xb6, 0xe3,
+ 0xbb, 0xaa, 0x5b, 0x6f, 0x10, 0x8f, 0x30, 0x3e, 0x1b, 0x22, 0x1f, 0x0d,
+ 0xf0, 0xf7, 0x46, 0xd9, 0x7e, 0x9d, 0x4c, 0xa2, 0xcb, 0xbf, 0x25, 0x53,
+ 0x80, 0x7c, 0x80, 0x78, 0x99, 0x7d, 0x0d, 0x1f, 0x72, 0xec, 0xcc, 0xac,
+ 0x3b, 0xe6, 0xf1, 0x82, 0x8c, 0x2b, 0xf3, 0xc5, 0x99, 0x37, 0x65, 0xfc,
+ 0x90, 0x9c, 0xbf, 0xfd, 0x77, 0xce, 0x41, 0x86, 0x77, 0x82, 0x35, 0xb2,
+ 0xd1, 0x88, 0x0e, 0x95, 0xeb, 0x65, 0xc9, 0x1c, 0x1a, 0xeb, 0x51, 0x79,
+ 0x37, 0x8a, 0x35, 0x93, 0xf6, 0x48, 0xd4, 0x94, 0xeb, 0xb6, 0x5d, 0xbb,
+ 0x51, 0x8f, 0xbe, 0xad, 0xf8, 0x98, 0xf3, 0x7c, 0xb4, 0xc1, 0x38, 0xce,
+ 0x66, 0x9b, 0x2e, 0xbc, 0x4f, 0x0e, 0x15, 0x63, 0xbd, 0x77, 0xc9, 0x3b,
+ 0x8e, 0xb9, 0xec, 0xb1, 0x6a, 0xe9, 0x13, 0x30, 0x0f, 0x2a, 0xb3, 0xd9,
+ 0xfb, 0xab, 0x05, 0xab, 0xc6, 0xe8, 0x0b, 0xcd, 0x93, 0x22, 0xab, 0x3d,
+ 0x52, 0xc3, 0x71, 0x8e, 0x72, 0x9c, 0xd9, 0x0d, 0x7a, 0xdf, 0x98, 0x22,
+ 0x36, 0x0b, 0xe1, 0x58, 0xe1, 0xa2, 0xf4, 0xd0, 0x68, 0xb7, 0x69, 0x3e,
+ 0x2f, 0x76, 0x8b, 0xe0, 0xbb, 0xa5, 0x71, 0x9e, 0x2a, 0x5c, 0xc0, 0x6c,
+ 0xf6, 0x2d, 0xe7, 0xef, 0x31, 0xd6, 0x0d, 0xe3, 0xac, 0x21, 0xf3, 0xc4,
+ 0x93, 0xc9, 0x6c, 0x53, 0xdf, 0x24, 0xe5, 0x70, 0xcf, 0xca, 0x0d, 0xe0,
+ 0xd9, 0xd2, 0x33, 0xa3, 0x7c, 0x77, 0xf4, 0xda, 0xdf, 0x62, 0x23, 0x77,
+ 0x0f, 0xdf, 0xdd, 0x53, 0xa8, 0xe4, 0xda, 0xb9, 0xb5, 0xf8, 0x11, 0xcb,
+ 0x2f, 0x7d, 0x70, 0xbc, 0x36, 0xb5, 0x19, 0x63, 0xc6, 0x5f, 0x62, 0x2f,
+ 0xf5, 0x1e, 0xa7, 0x3d, 0x4f, 0x58, 0xce, 0x5e, 0xbd, 0x9c, 0xcb, 0x22,
+ 0x96, 0x87, 0xda, 0xce, 0x90, 0x93, 0x1d, 0x63, 0xcc, 0xdc, 0x97, 0x6a,
+ 0xea, 0x79, 0x9d, 0x7e, 0x97, 0xfe, 0xa2, 0xec, 0x87, 0x03, 0x93, 0xb9,
+ 0x47, 0x31, 0xb3, 0xa4, 0x69, 0xf1, 0x45, 0x62, 0xc2, 0x69, 0xe2, 0x94,
+ 0x8f, 0x98, 0x50, 0x9b, 0xf3, 0x94, 0xf6, 0x77, 0x0d, 0x7e, 0x6f, 0xba,
+ 0x30, 0x87, 0xbf, 0xa1, 0x5d, 0x44, 0xbe, 0x78, 0x72, 0x0e, 0xf2, 0xac,
+ 0xdb, 0x83, 0xd5, 0xe7, 0x06, 0x71, 0xe9, 0x66, 0xb7, 0x8f, 0xe6, 0x65,
+ 0xee, 0xde, 0x97, 0x6d, 0x52, 0xc7, 0x64, 0xec, 0x5e, 0x2d, 0x9a, 0xe1,
+ 0x5a, 0x4d, 0x38, 0x1c, 0x5c, 0x65, 0x8e, 0x97, 0x73, 0x58, 0x35, 0xf0,
+ 0xd1, 0xf7, 0xc7, 0x0c, 0x39, 0xbf, 0x10, 0x0d, 0xef, 0xe0, 0x1a, 0x8e,
+ 0x59, 0x4d, 0xad, 0x71, 0x65, 0x0f, 0xca, 0xfc, 0xdb, 0xe5, 0xd4, 0x5a,
+ 0xdf, 0x51, 0x34, 0xf5, 0x3c, 0x88, 0x2f, 0x21, 0xbd, 0xa4, 0xa9, 0x7f,
+ 0x0a, 0x71, 0xe3, 0x7e, 0xc8, 0x39, 0x4e, 0x77, 0xac, 0x86, 0x3c, 0x33,
+ 0xc9, 0xd2, 0x4f, 0xec, 0x15, 0xfa, 0x53, 0x98, 0x22, 0x77, 0x6c, 0x5c,
+ 0xa7, 0x5f, 0xf8, 0x5a, 0xe9, 0x9e, 0xbb, 0x4f, 0x24, 0xfe, 0x12, 0xa0,
+ 0x0d, 0x2a, 0xe1, 0x5b, 0x5a, 0xcf, 0x39, 0x68, 0x0b, 0xe7, 0x8c, 0xef,
+ 0x45, 0x1c, 0xa4, 0xbf, 0x4d, 0x15, 0x14, 0x18, 0x0d, 0x17, 0x31, 0x24,
+ 0xb9, 0x8b, 0xef, 0xb4, 0x67, 0x43, 0xe4, 0xb2, 0x51, 0x54, 0xea, 0xf1,
+ 0xd8, 0x28, 0xf5, 0x6b, 0x27, 0x96, 0x8f, 0x13, 0x43, 0x32, 0x6a, 0xc8,
+ 0x39, 0x77, 0x5a, 0xa9, 0x47, 0x9d, 0xff, 0x15, 0x90, 0x5a, 0xa8, 0x71,
+ 0x46, 0xf6, 0xa8, 0x0f, 0xe3, 0xe2, 0x54, 0x11, 0xc7, 0x52, 0x69, 0xec,
+ 0x5f, 0xa2, 0x62, 0xd2, 0x5a, 0xe6, 0xf4, 0x0e, 0xa4, 0xe6, 0xea, 0xca,
+ 0x1d, 0x72, 0xfa, 0x91, 0x5b, 0x53, 0x9e, 0x06, 0x39, 0xa7, 0x31, 0xcb,
+ 0xda, 0x6b, 0xca, 0x18, 0xc1, 0x41, 0xe3, 0xcb, 0x30, 0x96, 0x0a, 0x76,
+ 0x8e, 0xe1, 0xd5, 0x19, 0xc9, 0x71, 0xc9, 0xb6, 0x5b, 0x26, 0xc5, 0x3e,
+ 0x1e, 0x72, 0xdf, 0x00, 0x9a, 0x1d, 0x2e, 0xf7, 0x50, 0xdb, 0xea, 0x19,
+ 0x97, 0xd3, 0x35, 0xe7, 0xe5, 0xac, 0x74, 0x0d, 0xc2, 0xb4, 0xd7, 0xf9,
+ 0x94, 0x9f, 0x98, 0x23, 0xf6, 0x94, 0x33, 0x7a, 0xae, 0x9e, 0xc9, 0xbc,
+ 0x82, 0xb1, 0x96, 0x1b, 0xf7, 0x58, 0xe4, 0xff, 0x06, 0xae, 0x9d, 0x1b,
+ 0x2c, 0xf5, 0xc7, 0xff, 0xcc, 0xbe, 0x74, 0x93, 0xe8, 0xbd, 0x22, 0x44,
+ 0x4c, 0x8f, 0xcd, 0x5c, 0xb3, 0xaf, 0xd8, 0xf4, 0x9c, 0xe4, 0x0c, 0xc7,
+ 0xe6, 0x6e, 0xcf, 0x4d, 0x1b, 0xba, 0xac, 0x34, 0x31, 0x9f, 0xd0, 0xaf,
+ 0x96, 0xd0, 0xdf, 0x9a, 0xd1, 0xbf, 0xc2, 0xf4, 0xf5, 0x5e, 0xb5, 0x36,
+ 0xa3, 0x75, 0xfd, 0x7b, 0x36, 0x6e, 0x6e, 0x87, 0x57, 0x97, 0xeb, 0x33,
+ 0x76, 0x5a, 0x95, 0xbf, 0xff, 0x24, 0x24, 0xb9, 0xfe, 0x65, 0xab, 0x68,
+ 0xaf, 0x5e, 0xe6, 0x72, 0xc4, 0x1f, 0x64, 0x65, 0xdf, 0x2b, 0x63, 0xb3,
+ 0xde, 0xbe, 0xf0, 0xae, 0xf7, 0x10, 0xbe, 0x9f, 0x3f, 0x8c, 0x77, 0xa6,
+ 0x7c, 0x08, 0xeb, 0xa2, 0xcb, 0x66, 0xd4, 0xae, 0x4f, 0xa4, 0xdf, 0x23,
+ 0x2e, 0x5e, 0x98, 0x29, 0xfb, 0xc5, 0x43, 0x6d, 0x6b, 0x66, 0x14, 0x8e,
+ 0x55, 0x83, 0x0a, 0xea, 0xf9, 0x1d, 0xc3, 0x8b, 0x58, 0x89, 0xe3, 0x7a,
+ 0x29, 0xa7, 0x9c, 0x7b, 0x10, 0xee, 0x1b, 0xcf, 0x1f, 0x0a, 0xb9, 0x3d,
+ 0xb0, 0x10, 0x71, 0x74, 0x1c, 0x13, 0xd9, 0xa6, 0xe4, 0xfb, 0x72, 0x0e,
+ 0x87, 0x35, 0xd9, 0x25, 0x8c, 0xe3, 0x44, 0xb6, 0x8c, 0xa1, 0x51, 0x39,
+ 0x97, 0x9a, 0x8c, 0x79, 0x5c, 0x8c, 0x8c, 0x79, 0xb4, 0x4c, 0xcc, 0xe3,
+ 0x0f, 0x09, 0x77, 0x18, 0x2d, 0xc4, 0xa3, 0x95, 0xf0, 0xe2, 0x3e, 0xc3,
+ 0xf5, 0x8f, 0x86, 0x39, 0x3f, 0x62, 0x4b, 0x25, 0x2f, 0x4b, 0x4e, 0xf6,
+ 0x31, 0x27, 0x2f, 0x23, 0xbf, 0xf6, 0xe1, 0x4d, 0x5d, 0xec, 0xb1, 0xa6,
+ 0x6c, 0x0f, 0xe3, 0x1c, 0x1e, 0xb6, 0x8b, 0x3d, 0xe2, 0x4b, 0x7e, 0x1c,
+ 0x6e, 0x9e, 0xb5, 0x67, 0x22, 0xa2, 0xbb, 0x17, 0xa7, 0x89, 0xaf, 0xb8,
+ 0x39, 0x1e, 0x3d, 0xcd, 0x9c, 0x3d, 0xa6, 0x97, 0x7d, 0xfc, 0xb7, 0x4b,
+ 0x72, 0xea, 0x7d, 0xf3, 0xb8, 0x9f, 0x7f, 0x37, 0x44, 0xf7, 0x2b, 0xee,
+ 0x7c, 0xab, 0xe7, 0xfe, 0x26, 0x54, 0xee, 0x9f, 0xca, 0xb3, 0xb1, 0xfc,
+ 0xe3, 0xfc, 0x2e, 0x63, 0x85, 0xe8, 0x9f, 0x95, 0xe8, 0x8f, 0xc8, 0xff,
+ 0x89, 0x88, 0x5d, 0x64, 0x3f, 0x11, 0xb4, 0x87, 0x8d, 0xd7, 0x68, 0x8f,
+ 0xc3, 0xd7, 0xce, 0x4c, 0xb9, 0xf8, 0x55, 0xc5, 0xeb, 0x3b, 0x52, 0xaf,
+ 0x6c, 0x0a, 0xe2, 0x17, 0xf6, 0xa5, 0x48, 0x94, 0x98, 0x50, 0xe6, 0xa1,
+ 0x62, 0x33, 0xc3, 0xb1, 0x99, 0x5b, 0x2b, 0x5e, 0xd3, 0xa3, 0x38, 0x40,
+ 0xbe, 0xbd, 0x90, 0x2d, 0x9f, 0x15, 0x89, 0x13, 0x6b, 0x3e, 0x8f, 0xfe,
+ 0x3a, 0x19, 0xaf, 0x9e, 0xfe, 0x95, 0xa4, 0x0d, 0xd4, 0xf0, 0xce, 0x69,
+ 0xa9, 0xb5, 0xc9, 0x8f, 0x27, 0xe3, 0xc6, 0x43, 0xe4, 0x91, 0x13, 0x93,
+ 0xb6, 0xfd, 0x96, 0x81, 0x3b, 0xc3, 0xcc, 0xef, 0x2f, 0x90, 0x4f, 0x90,
+ 0x6f, 0xc4, 0x2a, 0x95, 0xa6, 0xe8, 0x2a, 0xe6, 0xfa, 0x31, 0xd6, 0x0a,
+ 0x4f, 0x13, 0xe3, 0x4e, 0x2f, 0x54, 0xc1, 0x3a, 0x21, 0xfb, 0x82, 0x55,
+ 0x98, 0x7c, 0x26, 0x49, 0xd9, 0x97, 0x72, 0x9c, 0x00, 0xaa, 0xcf, 0xb4,
+ 0xa2, 0xea, 0x94, 0x82, 0x1d, 0x89, 0x56, 0x04, 0xcf, 0xd4, 0x30, 0xff,
+ 0x06, 0x70, 0xa5, 0x85, 0x6b, 0xfc, 0x4c, 0x59, 0x0f, 0x67, 0x8f, 0x14,
+ 0x4f, 0xe6, 0x62, 0xe4, 0xf1, 0x11, 0x2c, 0x58, 0xb2, 0x1f, 0x1c, 0x70,
+ 0xb0, 0xf4, 0xc2, 0x86, 0x7a, 0x67, 0xcf, 0xea, 0xc5, 0x82, 0x1e, 0x3d,
+ 0xab, 0xd4, 0xe0, 0xc7, 0x27, 0x8a, 0x37, 0x57, 0xc2, 0x7e, 0x79, 0x85,
+ 0x99, 0xe8, 0xdb, 0x4b, 0xff, 0x5f, 0xb3, 0x3a, 0xc2, 0xfa, 0xc6, 0xb6,
+ 0xaf, 0x6e, 0x94, 0x3a, 0xd8, 0x70, 0xea, 0x60, 0x77, 0x6f, 0x5f, 0x1f,
+ 0x7c, 0x4c, 0xc9, 0x6c, 0x0f, 0xc3, 0xfe, 0xa8, 0xd2, 0xb4, 0x3f, 0xf6,
+ 0x9b, 0x09, 0xbe, 0x2f, 0x7b, 0x7c, 0xb6, 0xfd, 0xc3, 0x16, 0xdb, 0xce,
+ 0xb7, 0xc4, 0xfb, 0x54, 0xaf, 0x8a, 0x33, 0x8d, 0xb2, 0x2f, 0xe8, 0xc1,
+ 0x8f, 0x13, 0x7a, 0x74, 0x2f, 0x64, 0x0f, 0x9e, 0x78, 0xbf, 0x4c, 0xce,
+ 0x18, 0xd6, 0x87, 0x3b, 0xad, 0xa5, 0x78, 0x61, 0x7e, 0x23, 0xfa, 0xfd,
+ 0x70, 0xce, 0xc5, 0xd8, 0x06, 0xde, 0x5e, 0x01, 0xc9, 0xe1, 0x89, 0xd6,
+ 0xc7, 0x10, 0xc1, 0x7c, 0xe1, 0x30, 0x1e, 0x39, 0x21, 0xf5, 0xd7, 0xea,
+ 0xb6, 0xc0, 0x09, 0xfb, 0x07, 0x51, 0xb3, 0x48, 0x8c, 0xb4, 0xed, 0xaa,
+ 0x8d, 0x4d, 0x51, 0xa6, 0x26, 0xf2, 0x8d, 0x18, 0x79, 0xb3, 0x3e, 0xf8,
+ 0x63, 0x2c, 0xc1, 0xd9, 0xd9, 0xf4, 0xcd, 0xe4, 0xf2, 0x9d, 0xcf, 0x2a,
+ 0xc2, 0xdb, 0x23, 0x78, 0xbe, 0x20, 0x9c, 0x65, 0x6d, 0x5b, 0xd7, 0x89,
+ 0xe5, 0x78, 0x79, 0x3e, 0x82, 0xb3, 0x96, 0x4e, 0xce, 0x04, 0xa5, 0xda,
+ 0xb4, 0x6b, 0x6b, 0x29, 0x6b, 0xb5, 0xd7, 0x8b, 0xed, 0x29, 0xa9, 0x19,
+ 0xf5, 0xc1, 0x90, 0x82, 0xe5, 0x95, 0xd0, 0x17, 0x1f, 0x06, 0x86, 0x82,
+ 0x66, 0xe2, 0xc2, 0xb3, 0x4a, 0xa2, 0xef, 0x03, 0x6f, 0x04, 0xdf, 0x22,
+ 0x16, 0x7d, 0xbd, 0x20, 0x67, 0xa5, 0x88, 0x37, 0xb3, 0x31, 0xae, 0x5b,
+ 0x00, 0x9e, 0x86, 0x1a, 0x1c, 0x61, 0xec, 0xbc, 0x66, 0x54, 0x10, 0xaf,
+ 0xe4, 0xec, 0x94, 0x60, 0x7d, 0xbd, 0x9c, 0x19, 0xb1, 0x5f, 0xd4, 0xdd,
+ 0x7a, 0xdf, 0x98, 0xbb, 0xf1, 0x4c, 0xb1, 0x4a, 0x8c, 0x6f, 0xea, 0x89,
+ 0x2a, 0x6f, 0xd8, 0xe9, 0x2f, 0x2a, 0xd4, 0xb3, 0xb7, 0x06, 0x55, 0x8e,
+ 0xae, 0x18, 0xcd, 0x95, 0xf3, 0x4b, 0xad, 0xd4, 0x77, 0x3d, 0x99, 0x92,
+ 0x3f, 0x56, 0x33, 0xee, 0x8f, 0x32, 0x5f, 0x57, 0x9e, 0x90, 0xbc, 0x42,
+ 0xfe, 0xad, 0x6c, 0x26, 0x2f, 0x16, 0x0e, 0x11, 0xc0, 0x83, 0xaa, 0xf8,
+ 0x86, 0x4a, 0xfd, 0x36, 0xf9, 0xe4, 0x2c, 0xd4, 0x0b, 0x05, 0xc9, 0xeb,
+ 0x82, 0x0b, 0xe5, 0xf9, 0xa2, 0xa8, 0x9b, 0x94, 0x35, 0x52, 0xdb, 0x3e,
+ 0x9a, 0x0c, 0xc9, 0xd9, 0xf7, 0x11, 0x0f, 0xeb, 0xef, 0x00, 0xfd, 0xeb,
+ 0x9e, 0x16, 0x7d, 0x70, 0xb3, 0x57, 0x63, 0x0d, 0x1e, 0x67, 0x2d, 0xa1,
+ 0xb5, 0x4e, 0x28, 0x37, 0x8e, 0xf3, 0x6c, 0x8d, 0xc4, 0x4b, 0x86, 0x7a,
+ 0x3e, 0xe9, 0xe8, 0xb4, 0x86, 0x3a, 0x09, 0x5e, 0x27, 0x89, 0xd7, 0x35,
+ 0xb8, 0x32, 0x05, 0x9d, 0x11, 0x8c, 0x57, 0x0d, 0x02, 0x95, 0x9a, 0x48,
+ 0x77, 0x40, 0x62, 0x41, 0xeb, 0x17, 0x3e, 0x55, 0x4d, 0x7c, 0x9e, 0x9d,
+ 0x92, 0x7c, 0xa3, 0x08, 0x57, 0xc9, 0xd4, 0x9a, 0x43, 0xf8, 0x70, 0x03,
+ 0xf0, 0xc6, 0xa4, 0xbb, 0xef, 0xde, 0x27, 0x67, 0x6f, 0x2b, 0xdd, 0x33,
+ 0x0d, 0x8f, 0x39, 0x67, 0x15, 0x64, 0xfc, 0x43, 0x38, 0x93, 0x15, 0x7e,
+ 0x39, 0x44, 0x7e, 0x19, 0x1f, 0x26, 0xf7, 0x6c, 0x2d, 0x40, 0x62, 0xb2,
+ 0xc9, 0xf8, 0x88, 0xbe, 0xff, 0x2c, 0x79, 0xeb, 0x11, 0xb8, 0xfb, 0xee,
+ 0x8d, 0xa5, 0xb3, 0x08, 0xf1, 0x7c, 0xa7, 0xb2, 0xd3, 0x39, 0xcf, 0x64,
+ 0x30, 0xde, 0x3a, 0x94, 0x1d, 0xf3, 0xdb, 0x94, 0xae, 0xf9, 0x6e, 0x65,
+ 0x4f, 0x41, 0xea, 0xd8, 0xd5, 0x6d, 0x0f, 0x9e, 0xd8, 0xad, 0xec, 0x9c,
+ 0xed, 0x55, 0xc8, 0x6f, 0xd5, 0x80, 0xd9, 0xa7, 0x74, 0xcf, 0xbb, 0xfd,
+ 0xf4, 0x4e, 0xd6, 0x70, 0x3b, 0x2d, 0xf1, 0x07, 0xb5, 0xad, 0x6b, 0x52,
+ 0xfe, 0x17, 0x2b, 0x22, 0xff, 0xf7, 0xd0, 0xbf, 0x55, 0xb1, 0xed, 0x55,
+ 0xa9, 0xd7, 0x65, 0x3d, 0xec, 0xe7, 0x53, 0xcc, 0x93, 0x56, 0x0d, 0x06,
+ 0x58, 0x83, 0x8c, 0x1a, 0xb7, 0x94, 0xf6, 0xcf, 0x44, 0x27, 0x39, 0x2f,
+ 0x21, 0xfe, 0x8a, 0x4c, 0x25, 0x65, 0xf8, 0x07, 0xca, 0xbf, 0xbf, 0xa4,
+ 0x57, 0xb7, 0x9c, 0x27, 0xf0, 0x23, 0x23, 0x3a, 0xe4, 0xa9, 0xef, 0xb1,
+ 0xc9, 0xeb, 0x7a, 0xf9, 0x78, 0x6d, 0x9c, 0x5c, 0x75, 0xbf, 0xa2, 0x0d,
+ 0x3f, 0xe7, 0xea, 0x75, 0xe1, 0x8a, 0xa2, 0x15, 0x47, 0x21, 0xb8, 0xe0,
+ 0xea, 0xb5, 0xb6, 0xa4, 0xd7, 0x9a, 0x7c, 0xa7, 0x73, 0x4e, 0xab, 0x86,
+ 0x7a, 0x2d, 0x4c, 0x76, 0x28, 0x9d, 0xf3, 0xd2, 0xcb, 0x14, 0xdd, 0x44,
+ 0x8f, 0x13, 0x76, 0x95, 0xde, 0xad, 0xdc, 0xee, 0x9c, 0x2b, 0x93, 0xb3,
+ 0x5d, 0xb2, 0xdf, 0x5f, 0xd6, 0x4b, 0x72, 0xfa, 0xd2, 0xf0, 0xb6, 0x69,
+ 0x35, 0xbc, 0x75, 0xda, 0xb6, 0xbf, 0x6b, 0xfc, 0xb3, 0xa3, 0xcb, 0x59,
+ 0x43, 0x74, 0x91, 0x73, 0x23, 0x65, 0x7d, 0xbe, 0x50, 0xd2, 0x47, 0xd6,
+ 0xea, 0xfa, 0x3a, 0x95, 0xff, 0x87, 0xef, 0xdd, 0xac, 0x7b, 0xa6, 0xa4,
+ 0xac, 0x4f, 0xd8, 0x2c, 0x9f, 0x2f, 0x1b, 0xc2, 0x1b, 0xbc, 0xff, 0x93,
+ 0x6c, 0x59, 0x2f, 0x2f, 0xe6, 0x66, 0xc5, 0xfe, 0x43, 0xf2, 0x3f, 0x7c,
+ 0xc4, 0x91, 0xb8, 0x31, 0x46, 0x3f, 0x72, 0xf5, 0xd3, 0x86, 0x57, 0x7a,
+ 0x9b, 0x8a, 0x57, 0xa0, 0xf5, 0x2f, 0x2a, 0x89, 0x34, 0x6b, 0x70, 0x9c,
+ 0x2d, 0xfc, 0xea, 0xfa, 0x35, 0xe7, 0xab, 0x94, 0x6d, 0x39, 0x19, 0xfb,
+ 0x21, 0x8e, 0x2d, 0x67, 0x4a, 0x14, 0x3c, 0x37, 0x0b, 0xcc, 0x5a, 0x9c,
+ 0xd6, 0x1c, 0xc1, 0xd3, 0x86, 0x6d, 0x3f, 0xdb, 0xa2, 0xcb, 0x59, 0xa0,
+ 0xf3, 0x6e, 0xaf, 0x08, 0x46, 0x8d, 0x2e, 0x7b, 0x79, 0x72, 0x9e, 0xa4,
+ 0x97, 0x36, 0x10, 0xdd, 0xc5, 0x07, 0xca, 0x6b, 0x2f, 0xe7, 0xdc, 0x32,
+ 0xb4, 0x8f, 0xd8, 0xa6, 0x7c, 0xde, 0x4d, 0xfa, 0x30, 0x37, 0xda, 0x64,
+ 0x6d, 0xd8, 0x59, 0x5f, 0x43, 0xfc, 0x95, 0xe8, 0x43, 0x5f, 0x9d, 0x23,
+ 0x97, 0x18, 0x33, 0xfc, 0x0e, 0x6f, 0x3b, 0x42, 0xae, 0x32, 0xc1, 0xd8,
+ 0x79, 0xd2, 0xba, 0x80, 0x0b, 0xf9, 0xd7, 0xf0, 0xc6, 0xb5, 0xff, 0x67,
+ 0x13, 0x7f, 0xb9, 0xb8, 0xb1, 0xcb, 0x39, 0xd3, 0x74, 0xba, 0xf5, 0x96,
+ 0x84, 0xe0, 0x50, 0x77, 0xb3, 0x9c, 0x71, 0xaa, 0x34, 0xf3, 0x9b, 0x64,
+ 0xbf, 0xab, 0xc2, 0x34, 0x6f, 0x3d, 0xaf, 0x8b, 0x6d, 0xfe, 0x62, 0xfd,
+ 0x19, 0x5d, 0xf4, 0xfa, 0x9f, 0x6b, 0xc7, 0x9d, 0xff, 0xaf, 0xfc, 0xbb,
+ 0x5b, 0xf7, 0xe9, 0x12, 0x3b, 0x67, 0x5b, 0xda, 0x1d, 0x4c, 0x68, 0x35,
+ 0x57, 0x39, 0x36, 0x68, 0x31, 0x6f, 0x71, 0x3e, 0x0d, 0x33, 0xe9, 0x7c,
+ 0x9a, 0xa6, 0x6b, 0x9b, 0x6e, 0xb3, 0xc1, 0xf9, 0xec, 0x30, 0xdd, 0xf3,
+ 0xcf, 0x69, 0x53, 0x77, 0x3e, 0x7b, 0xcc, 0xb8, 0xf3, 0xd9, 0x69, 0xae,
+ 0xbc, 0x2e, 0x17, 0x7f, 0xfe, 0x1f, 0x9b, 0x97, 0x53, 0xd9, 0x78, 0x3a,
0x00, 0x00, 0x00 };
static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
static struct fw_info bnx2_txp_fw_06 = {
- /* Firmware version: 4.4.2 */
+ /* Firmware version: 4.6.16 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x2,
+ .ver_minor = 0x6,
+ .ver_fix = 0x10,
.start_addr = 0x08000098,
.text_addr = 0x08000000,
- .text_len = 0x3ab0,
+ .text_len = 0x3a74,
.text_index = 0x0,
.gz_text = bnx2_TXP_b06FwText,
.gz_text_len = sizeof(bnx2_TXP_b06FwText),
@@ -4535,11 +4432,11 @@ static struct fw_info bnx2_txp_fw_06 = {
.data_index = 0x0,
.data = bnx2_TXP_b06FwData,
- .sbss_addr = 0x08003ae0,
+ .sbss_addr = 0x08003aa0,
.sbss_len = 0x68,
.sbss_index = 0x0,
- .bss_addr = 0x08003b48,
+ .bss_addr = 0x08003b08,
.bss_len = 0x14c,
.bss_index = 0x0,
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
index fe753b6bcb41..c54e4886b8bb 100644
--- a/drivers/net/bnx2_fw2.h
+++ b/drivers/net/bnx2_fw2.h
@@ -15,848 +15,847 @@
*/
static u8 bnx2_COM_b09FwText[] = {
- 0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x75, 0xe6, 0x79, 0x6f, 0xde, 0x90,
- 0x43, 0x8a, 0xa2, 0x1e, 0x99, 0x31, 0x33, 0x8e, 0xd8, 0x7a, 0x86, 0xf3,
- 0x48, 0xd1, 0x21, 0xe3, 0x3e, 0x33, 0x63, 0x99, 0x76, 0xa6, 0xd6, 0x64,
- 0x66, 0x28, 0x2b, 0x0e, 0x69, 0xd0, 0x8e, 0x82, 0x4d, 0x01, 0x03, 0xe5,
- 0x0e, 0xa9, 0x54, 0xd9, 0xf5, 0x22, 0xda, 0x34, 0x45, 0x8a, 0xa2, 0x88,
- 0x26, 0x24, 0xe5, 0x2a, 0xcd, 0x88, 0x1c, 0xcb, 0x34, 0x1b, 0x14, 0x5e,
- 0x64, 0x3c, 0xa4, 0x14, 0xb7, 0x1d, 0x89, 0x72, 0xe2, 0x2d, 0xbc, 0x58,
- 0x07, 0x66, 0xa9, 0x1f, 0x4e, 0x83, 0x14, 0xf0, 0x2e, 0xbc, 0x68, 0x60,
- 0xa4, 0x80, 0x20, 0xbb, 0x8d, 0xb3, 0xc8, 0x62, 0x83, 0xdd, 0x00, 0x71,
- 0x02, 0x27, 0x6f, 0xbf, 0xef, 0xde, 0xfb, 0xc8, 0xd1, 0x88, 0x76, 0xd2,
- 0xfc, 0xb5, 0x04, 0x06, 0xf7, 0xfd, 0xb8, 0x3f, 0xce, 0x3d, 0xf7, 0xdc,
- 0x73, 0xbe, 0x73, 0xee, 0x79, 0x7c, 0x40, 0xa4, 0x53, 0xcc, 0xdf, 0x5e,
- 0xfc, 0x32, 0xff, 0xe1, 0xb3, 0xb3, 0x63, 0x77, 0x65, 0xee, 0xc2, 0xe5,
- 0x87, 0xed, 0xf7, 0x3b, 0x0e, 0x9f, 0x47, 0xf0, 0x8b, 0xe3, 0x37, 0x66,
- 0xae, 0x77, 0xfb, 0x73, 0xf1, 0x3b, 0x68, 0x89, 0xcc, 0xfc, 0x4f, 0x11,
- 0xab, 0xe5, 0x5d, 0xec, 0x5d, 0xda, 0xbc, 0xd7, 0x9f, 0xfd, 0x1b, 0xb4,
- 0xf9, 0xd7, 0xfe, 0x45, 0x34, 0xd9, 0x6a, 0xde, 0xfc, 0x49, 0xcc, 0xce,
- 0xce, 0x4c, 0xe6, 0x3d, 0x89, 0x45, 0xb2, 0x47, 0xa7, 0x66, 0x3d, 0x91,
- 0x5c, 0x63, 0x24, 0x59, 0x90, 0x5f, 0x04, 0xe5, 0xb8, 0x23, 0x7c, 0xfe,
- 0x5b, 0xd9, 0x77, 0xbe, 0xf6, 0xad, 0x7b, 0x53, 0x3f, 0xae, 0x45, 0x24,
- 0xe6, 0x66, 0xdf, 0x16, 0x77, 0x48, 0x62, 0xfd, 0x68, 0xf3, 0xcc, 0x81,
- 0x57, 0x6d, 0xe9, 0x0e, 0xfb, 0x72, 0x67, 0x22, 0x59, 0x99, 0x3e, 0x56,
- 0x39, 0x19, 0xd8, 0x9e, 0x94, 0x9d, 0xac, 0x37, 0x5c, 0x97, 0xae, 0xf1,
- 0x73, 0x99, 0x7b, 0x05, 0xf7, 0xd3, 0xc7, 0x1a, 0x31, 0x99, 0x6f, 0x94,
- 0xbb, 0x6c, 0xcf, 0x43, 0x29, 0xb1, 0xb6, 0xec, 0x62, 0xec, 0x9a, 0xc7,
- 0xb1, 0xbf, 0x8a, 0xb1, 0xf7, 0x4b, 0xd4, 0x0b, 0x82, 0x73, 0x18, 0xfb,
- 0x70, 0xe3, 0x17, 0xc1, 0xb3, 0x8e, 0x1e, 0xd7, 0xce, 0x9e, 0x88, 0xb0,
- 0xb4, 0xb2, 0xb5, 0xc9, 0x81, 0x06, 0xef, 0x8b, 0xed, 0x9a, 0x4e, 0xbf,
- 0x13, 0x74, 0xc6, 0x9c, 0xec, 0x89, 0xce, 0x45, 0x94, 0xd1, 0x6c, 0x7c,
- 0xec, 0x9c, 0xaa, 0xb7, 0x6e, 0xea, 0x3d, 0x1e, 0xd5, 0xed, 0xde, 0x9a,
- 0x1c, 0x6a, 0xb0, 0xfc, 0xc9, 0xe4, 0xa0, 0x2a, 0xdf, 0x99, 0x4c, 0xab,
- 0x52, 0xa6, 0x06, 0x54, 0xe9, 0x4c, 0x79, 0xaa, 0x7c, 0xc6, 0x3c, 0x7f,
- 0x6e, 0x32, 0xa9, 0xca, 0x86, 0x29, 0x2f, 0x99, 0xf2, 0x05, 0x53, 0xbe,
- 0x68, 0xca, 0x97, 0x4c, 0xb9, 0x69, 0xca, 0x2b, 0x93, 0xba, 0x9f, 0x6f,
- 0x9b, 0xfb, 0xef, 0x9a, 0xf2, 0x55, 0x53, 0xbe, 0x66, 0xca, 0xef, 0x99,
- 0xf2, 0xfb, 0x86, 0xae, 0xeb, 0xa6, 0x7c, 0xd3, 0x94, 0x3f, 0x32, 0xef,
- 0x7f, 0x6c, 0xe8, 0x7d, 0x1b, 0x74, 0xfd, 0x49, 0xd4, 0xc8, 0x2a, 0xe6,
- 0x9d, 0x94, 0xd9, 0x8a, 0x23, 0xf3, 0xcb, 0x11, 0x29, 0xa8, 0x35, 0xfc,
- 0xca, 0x5e, 0xe9, 0x74, 0x64, 0x61, 0x23, 0x26, 0xd7, 0x95, 0x88, 0xbe,
- 0x15, 0x7c, 0xeb, 0x80, 0x94, 0xed, 0xac, 0x2b, 0x97, 0x36, 0xe2, 0xf2,
- 0xf2, 0x86, 0x58, 0xd3, 0x99, 0x0e, 0xb1, 0xcf, 0x7e, 0x40, 0x72, 0xae,
- 0x25, 0x11, 0xc5, 0xd3, 0xa4, 0xe4, 0x2b, 0x7d, 0xb8, 0x4f, 0x25, 0x44,
- 0xae, 0xee, 0xd5, 0xeb, 0x17, 0x93, 0xc8, 0x2a, 0xd7, 0xe4, 0xfe, 0xa9,
- 0x6b, 0x2b, 0x09, 0x71, 0x96, 0x46, 0x31, 0x46, 0x97, 0x44, 0x57, 0xa5,
- 0x3f, 0x22, 0x83, 0x89, 0x4f, 0xa3, 0x46, 0xb1, 0xe1, 0xc8, 0x44, 0xc3,
- 0x12, 0xc7, 0x8b, 0x41, 0x3e, 0xba, 0xf0, 0x73, 0xf1, 0x8b, 0xe3, 0x97,
- 0xc0, 0xef, 0x47, 0xe8, 0xa7, 0x5f, 0x0a, 0x0d, 0xf6, 0x89, 0x71, 0x97,
- 0x31, 0xfe, 0x72, 0xca, 0x9d, 0x11, 0xd2, 0x95, 0x90, 0x6f, 0x1d, 0x20,
- 0x5d, 0x2e, 0xe9, 0x01, 0x6d, 0x31, 0x2b, 0xbf, 0x22, 0x27, 0x0a, 0xbe,
- 0x24, 0x6d, 0xaf, 0x53, 0x4a, 0xae, 0x95, 0x9c, 0x1b, 0xee, 0x95, 0xf2,
- 0x51, 0xbc, 0x5f, 0x96, 0x9c, 0x8d, 0xfe, 0x4b, 0xae, 0xcc, 0xe8, 0x77,
- 0x7c, 0xf6, 0x36, 0xf6, 0x6a, 0xca, 0xa5, 0xd0, 0xbe, 0xbc, 0xfc, 0xb7,
- 0xb8, 0x66, 0x7f, 0x3f, 0x77, 0x34, 0xdd, 0x3f, 0xc5, 0x3d, 0x9f, 0x0f,
- 0x99, 0x79, 0xf0, 0x9a, 0x75, 0xc3, 0x71, 0xc3, 0xf9, 0x72, 0xfc, 0x61,
- 0xcc, 0x99, 0x34, 0x84, 0x73, 0x96, 0x72, 0x14, 0xb4, 0xd4, 0x57, 0xba,
- 0xac, 0xb5, 0x95, 0x51, 0x79, 0x62, 0xf9, 0x01, 0xc9, 0xfb, 0x41, 0x30,
- 0xeb, 0x4b, 0xdc, 0x96, 0x41, 0xb7, 0x80, 0x0a, 0x5b, 0x0d, 0xb1, 0xea,
- 0x15, 0x89, 0xb5, 0x83, 0x2f, 0x3f, 0x58, 0x61, 0xdf, 0x0e, 0x9e, 0xf5,
- 0xa1, 0x7e, 0xb7, 0xb5, 0xbe, 0x02, 0xfa, 0xb3, 0xe4, 0x4f, 0x10, 0x2c,
- 0xfa, 0x83, 0x89, 0x39, 0x8c, 0x79, 0xb9, 0x31, 0x38, 0x7e, 0x43, 0x5c,
- 0xf4, 0xd9, 0x8b, 0x3a, 0xe4, 0x15, 0xfb, 0x62, 0x9f, 0xec, 0xaf, 0x0b,
- 0x6d, 0xe3, 0x78, 0x47, 0xba, 0x82, 0x20, 0xef, 0xbb, 0xbc, 0x97, 0x4d,
- 0xf0, 0x6f, 0x93, 0xfc, 0xeb, 0xec, 0x97, 0x57, 0x1a, 0x1c, 0x63, 0x37,
- 0xda, 0x47, 0xfe, 0x3f, 0xa4, 0x3d, 0x81, 0xfe, 0xe3, 0x28, 0xf7, 0x58,
- 0xf5, 0x6a, 0x80, 0xf1, 0x13, 0xb8, 0xde, 0x6d, 0x1e, 0xd7, 0xd5, 0xda,
- 0x5f, 0xc2, 0xda, 0xbb, 0xd9, 0xb8, 0x3c, 0xbf, 0xd1, 0x8f, 0x79, 0x24,
- 0xe4, 0x1b, 0x90, 0xcd, 0x9e, 0x83, 0x7b, 0x24, 0x0d, 0xd9, 0xe4, 0x9a,
- 0x8f, 0xad, 0xce, 0x49, 0x29, 0x9e, 0x1a, 0xa6, 0x1e, 0xcd, 0x8f, 0xed,
- 0xc3, 0x7c, 0xb5, 0xb6, 0x1a, 0x58, 0xca, 0xed, 0xb7, 0xe5, 0x90, 0xd8,
- 0x59, 0x8c, 0x9b, 0x19, 0x01, 0x2d, 0x11, 0xbc, 0x8b, 0x8b, 0xb7, 0x9a,
- 0xc3, 0xb3, 0x54, 0xa2, 0x04, 0x1a, 0xe7, 0x41, 0x63, 0x49, 0xca, 0x62,
- 0x5f, 0x7c, 0xce, 0x0a, 0xf7, 0x8a, 0xe6, 0xdd, 0xb0, 0xe9, 0x67, 0x5b,
- 0xce, 0x2d, 0x7b, 0xb5, 0xcb, 0x8a, 0xac, 0x8e, 0xca, 0xa9, 0x5d, 0x78,
- 0x56, 0x07, 0xcf, 0xec, 0xa5, 0x70, 0x1f, 0x38, 0xb8, 0xef, 0x43, 0xdd,
- 0x6e, 0xcb, 0x59, 0xbd, 0x95, 0x5f, 0x6b, 0x8d, 0x41, 0x7f, 0x0b, 0xfc,
- 0xb2, 0x57, 0x7b, 0x51, 0xe7, 0x56, 0x7e, 0xd5, 0xc1, 0x2f, 0x7b, 0x55,
- 0xf3, 0xaa, 0x0e, 0x5e, 0xd9, 0x4b, 0x71, 0x94, 0x7b, 0x2c, 0xfb, 0xac,
- 0xe6, 0x55, 0xdd, 0xec, 0x99, 0xf3, 0x4a, 0x5f, 0xe5, 0x40, 0xab, 0x25,
- 0x5a, 0x67, 0xe5, 0x84, 0xba, 0x29, 0x92, 0x2d, 0x62, 0xaf, 0xdb, 0xe0,
- 0x85, 0x23, 0xc5, 0x31, 0x4b, 0x66, 0xd5, 0xbb, 0xa2, 0xa4, 0x1b, 0x1f,
- 0x00, 0x23, 0x47, 0x86, 0x61, 0x29, 0xca, 0x6d, 0xd9, 0x17, 0xed, 0xad,
- 0x4a, 0x4c, 0x0a, 0x4e, 0x52, 0xbc, 0x25, 0xa5, 0xc7, 0x9b, 0xfa, 0x99,
- 0x41, 0x3f, 0xdf, 0x01, 0x3f, 0x2c, 0xe8, 0x56, 0xbe, 0x7b, 0x4c, 0xed,
- 0xfb, 0xf4, 0xaa, 0x23, 0x83, 0x4b, 0xac, 0x53, 0xb6, 0xaf, 0x34, 0xde,
- 0x09, 0x74, 0xbf, 0x8f, 0x71, 0x4c, 0xd7, 0xce, 0x2e, 0xda, 0x97, 0xd7,
- 0x4f, 0xdb, 0x57, 0x1b, 0xe8, 0xb7, 0xc1, 0xb5, 0xc0, 0x5a, 0x2d, 0x63,
- 0xad, 0x96, 0xb1, 0x6e, 0x66, 0x4f, 0xd7, 0xd4, 0xde, 0x4a, 0x9a, 0x75,
- 0x25, 0x0d, 0x5c, 0xdb, 0x04, 0xd6, 0x94, 0x6b, 0x2b, 0xd6, 0xab, 0x99,
- 0x3d, 0x12, 0x39, 0x1b, 0x51, 0x6b, 0xda, 0xb3, 0xfa, 0x91, 0xed, 0x35,
- 0x1d, 0x68, 0x5a, 0x53, 0xfb, 0x5d, 0xd6, 0xd4, 0xd9, 0x65, 0x4d, 0xb7,
- 0x1a, 0x3f, 0x31, 0x6b, 0xfa, 0x73, 0x31, 0xb2, 0xff, 0x9e, 0xfc, 0x1a,
- 0x00, 0xbf, 0xbc, 0x5f, 0x83, 0x5f, 0xce, 0xae, 0xfc, 0xea, 0xb3, 0x5b,
- 0xf9, 0x15, 0x01, 0xbf, 0xa2, 0xbf, 0x36, 0xbf, 0xc0, 0x87, 0x5d, 0x79,
- 0x15, 0x83, 0xde, 0x2b, 0x4b, 0x3e, 0x23, 0x92, 0xaf, 0x6a, 0x5d, 0x5d,
- 0x56, 0x3a, 0x9b, 0xba, 0x2a, 0xd4, 0xd9, 0xd4, 0xd7, 0x6a, 0x9f, 0x58,
- 0x85, 0x4a, 0x12, 0xba, 0xd4, 0x41, 0xf9, 0x1c, 0xca, 0x3d, 0xd6, 0x74,
- 0xb5, 0x1f, 0x76, 0x36, 0x10, 0x77, 0x2c, 0xb4, 0x97, 0xe5, 0x84, 0x8b,
- 0xb5, 0x71, 0xef, 0x8a, 0x8a, 0xf4, 0xa5, 0xc0, 0xa7, 0x14, 0xde, 0xa7,
- 0x12, 0x39, 0xc9, 0xda, 0x21, 0xae, 0xc9, 0x57, 0x3a, 0xde, 0xce, 0xa9,
- 0x2b, 0x3e, 0x67, 0xbb, 0x0c, 0x9e, 0x45, 0x65, 0x06, 0x76, 0xa0, 0xe8,
- 0x71, 0x3c, 0xf6, 0x9f, 0x9c, 0xe1, 0xb8, 0x85, 0x46, 0xa8, 0xb3, 0x25,
- 0x07, 0x1b, 0x8e, 0x77, 0xdc, 0xb7, 0xe3, 0x56, 0x41, 0xd9, 0xa0, 0x8c,
- 0x78, 0x8d, 0x66, 0xfb, 0xb2, 0x4d, 0x27, 0xf6, 0x73, 0x0e, 0x72, 0x4d,
- 0xda, 0x92, 0xd8, 0x7b, 0xc7, 0x22, 0xe1, 0xfa, 0x38, 0xd9, 0x71, 0x81,
- 0x5d, 0x96, 0xf9, 0x0a, 0xfb, 0xfb, 0x63, 0x2b, 0x72, 0x31, 0xec, 0x9f,
- 0x7c, 0x64, 0xdf, 0xba, 0xbf, 0xf9, 0xc6, 0x5b, 0x46, 0x37, 0x28, 0x5b,
- 0x85, 0xfe, 0xca, 0x4d, 0xfd, 0x95, 0xad, 0xc8, 0x92, 0xec, 0x53, 0xf6,
- 0xe0, 0x28, 0xf9, 0x77, 0x1a, 0xef, 0xae, 0x4b, 0x84, 0x32, 0xa3, 0xf6,
- 0x18, 0xf7, 0xfb, 0x97, 0x38, 0xdf, 0x26, 0xde, 0x4e, 0xc3, 0xc6, 0x71,
- 0x7f, 0x61, 0x8d, 0xe3, 0x7c, 0x7e, 0xc8, 0xd0, 0xe4, 0x48, 0x4e, 0xdd,
- 0x7f, 0x63, 0x4f, 0xa8, 0x3f, 0xb1, 0x9f, 0x41, 0xdb, 0x8b, 0x6a, 0x8e,
- 0x76, 0x36, 0x0b, 0xde, 0x34, 0xd3, 0xc8, 0x79, 0x67, 0xb1, 0xc6, 0xa1,
- 0x0e, 0x0b, 0xd7, 0x8a, 0xb8, 0xc6, 0xb1, 0x16, 0x2a, 0x5d, 0xb0, 0x8f,
- 0x31, 0x63, 0x83, 0xd9, 0x7e, 0x11, 0xed, 0xf9, 0x9c, 0x6d, 0xbb, 0x60,
- 0x8f, 0xd9, 0x7e, 0xd1, 0xb4, 0xdf, 0xb1, 0xcb, 0xdc, 0x2b, 0xb4, 0xc9,
- 0x57, 0x32, 0xc0, 0x42, 0x2b, 0xb6, 0x14, 0x7c, 0xe0, 0x1c, 0xbf, 0xdf,
- 0xec, 0x0b, 0x2d, 0x9b, 0x1f, 0x75, 0x2c, 0x69, 0xf7, 0x76, 0x93, 0xcd,
- 0x7f, 0xb0, 0xb5, 0xad, 0xdb, 0x91, 0xcd, 0x05, 0xe8, 0xa8, 0x53, 0x90,
- 0x95, 0xc5, 0xed, 0x7a, 0x94, 0x4b, 0x25, 0xa3, 0x90, 0xcd, 0xd4, 0x38,
- 0xa7, 0x79, 0xa5, 0xd1, 0x2c, 0xa3, 0x61, 0x1f, 0x31, 0x25, 0x07, 0x7a,
- 0x9c, 0xc5, 0xa6, 0x71, 0x16, 0x9b, 0xc6, 0x59, 0x32, 0xd8, 0x8e, 0xfd,
- 0x68, 0xbb, 0x7a, 0xfd, 0x26, 0x7b, 0xce, 0x35, 0xfb, 0x24, 0xf6, 0xa4,
- 0x96, 0x05, 0x60, 0x35, 0xbd, 0x06, 0x15, 0x57, 0xe6, 0x37, 0x2e, 0x84,
- 0x7b, 0xb5, 0xdc, 0x8e, 0xe7, 0x3f, 0xc4, 0xf3, 0xe1, 0x33, 0x2e, 0xec,
- 0x14, 0xb1, 0xda, 0x4b, 0x72, 0xae, 0x42, 0x19, 0x79, 0x11, 0x74, 0xa7,
- 0xfd, 0x36, 0x8b, 0x7c, 0x4d, 0x0d, 0x9f, 0x97, 0x54, 0x72, 0x5e, 0x46,
- 0x7c, 0x96, 0x4f, 0x88, 0xc2, 0x58, 0xa2, 0x31, 0xd0, 0x8b, 0x90, 0x3f,
- 0x91, 0x1f, 0x57, 0xda, 0xc5, 0x1e, 0xfb, 0x61, 0x40, 0x3b, 0x78, 0x7a,
- 0xa3, 0xb5, 0x1f, 0x91, 0xa1, 0x33, 0xaa, 0x1f, 0xf4, 0x91, 0xf6, 0xbf,
- 0xad, 0xfa, 0x0b, 0xfb, 0xc2, 0x3c, 0xc7, 0x5a, 0xfb, 0x73, 0xe4, 0xba,
- 0x6b, 0xa3, 0xbf, 0xb4, 0x99, 0x23, 0xaf, 0x21, 0x23, 0xae, 0x83, 0xf2,
- 0x61, 0x3b, 0x94, 0x19, 0x7b, 0xec, 0x3b, 0x41, 0x6e, 0x9a, 0x73, 0x2b,
- 0x99, 0x67, 0xff, 0xc3, 0xc8, 0x9b, 0x54, 0xed, 0x2c, 0x78, 0x96, 0x19,
- 0xc4, 0x78, 0xbc, 0x4f, 0x02, 0x1f, 0x49, 0x99, 0xf8, 0xac, 0x54, 0xf9,
- 0x65, 0x90, 0x73, 0x34, 0xa6, 0xd2, 0x6b, 0xcf, 0xf7, 0x96, 0x14, 0x50,
- 0x77, 0xc1, 0xe8, 0x83, 0x62, 0xe3, 0xba, 0xe2, 0xdf, 0xf3, 0x6a, 0x1f,
- 0xa5, 0x4e, 0x97, 0xa9, 0x37, 0x36, 0xdc, 0x08, 0xf7, 0xf8, 0x25, 0xff,
- 0xa5, 0x60, 0x61, 0x39, 0x95, 0x4c, 0xda, 0x83, 0x52, 0xaa, 0x0e, 0x96,
- 0x6d, 0x94, 0x27, 0x6a, 0x09, 0x39, 0x51, 0x61, 0x3f, 0xfb, 0x51, 0x07,
- 0x8a, 0xc8, 0xc6, 0x26, 0xef, 0xa3, 0xae, 0xe1, 0x98, 0x6f, 0x5b, 0x7a,
- 0x4c, 0xcc, 0xc1, 0xdb, 0xb4, 0xfe, 0x63, 0xe3, 0x8a, 0x55, 0xaa, 0x71,
- 0xfd, 0xf1, 0xbc, 0xd1, 0xac, 0x8f, 0x42, 0x5d, 0xb4, 0x83, 0xc5, 0x22,
- 0xd9, 0x45, 0xab, 0xb4, 0x22, 0x76, 0xde, 0x8f, 0x12, 0x0f, 0x26, 0x45,
- 0xee, 0x75, 0xf5, 0x3c, 0x3f, 0x19, 0xa1, 0x1e, 0x74, 0xbc, 0xd3, 0xe8,
- 0xbb, 0x53, 0x72, 0x0e, 0xd7, 0x9f, 0xd7, 0x12, 0x44, 0xb2, 0x1e, 0x6d,
- 0xa5, 0x13, 0xc9, 0x3a, 0xd8, 0x63, 0xac, 0xf3, 0x52, 0xc0, 0xbd, 0x90,
- 0xaf, 0x6a, 0x19, 0x29, 0xef, 0x60, 0x2f, 0xd0, 0x9b, 0x83, 0x8e, 0x11,
- 0x1b, 0x7b, 0xcc, 0x8d, 0x64, 0xf9, 0x7c, 0x1c, 0xd7, 0x9b, 0xa8, 0x4f,
- 0x1d, 0x0b, 0x4c, 0x5a, 0x53, 0xbc, 0xc3, 0x58, 0x39, 0xab, 0x58, 0x09,
- 0x79, 0xf2, 0x52, 0xf0, 0xe4, 0x72, 0x88, 0x11, 0x94, 0x6c, 0xc9, 0xc0,
- 0xd9, 0xa4, 0xd9, 0xd7, 0x5d, 0xdc, 0x73, 0xe4, 0x3f, 0x9e, 0xf9, 0xe6,
- 0x59, 0x7b, 0xd3, 0xb3, 0x70, 0xff, 0x7f, 0x09, 0xb4, 0xf5, 0x2b, 0xfe,
- 0xd8, 0xd9, 0x23, 0x56, 0x5e, 0xe1, 0x93, 0x20, 0x28, 0x78, 0x51, 0x29,
- 0x8d, 0xfe, 0x09, 0xe6, 0xca, 0x77, 0x65, 0x30, 0x9c, 0x76, 0x63, 0x78,
- 0x72, 0xd6, 0x4b, 0x29, 0xfb, 0x9f, 0xc7, 0xfe, 0xd3, 0x3a, 0x53, 0xca,
- 0x3d, 0xa0, 0xdd, 0x5b, 0xe2, 0x9a, 0xbc, 0x14, 0x9c, 0x05, 0x16, 0x9e,
- 0x5e, 0x2a, 0x5a, 0x03, 0xd8, 0x12, 0x76, 0x9f, 0x05, 0x3e, 0x77, 0x49,
- 0xfe, 0x22, 0xd7, 0x82, 0x75, 0xf8, 0xbc, 0x4d, 0xa6, 0xe3, 0xad, 0xb6,
- 0xf2, 0xdc, 0x3e, 0xe9, 0x24, 0xbf, 0x51, 0x77, 0xe9, 0xff, 0x46, 0xb4,
- 0x5e, 0x76, 0x65, 0x60, 0x95, 0x7c, 0x2f, 0x5a, 0xb3, 0x15, 0xea, 0xb1,
- 0x0e, 0xd8, 0x47, 0x3e, 0x67, 0x9f, 0x78, 0x77, 0xbe, 0xb5, 0x8f, 0xdf,
- 0x8b, 0xe8, 0x3e, 0xd8, 0x2e, 0xec, 0xa3, 0x99, 0x1f, 0x7b, 0x94, 0x9e,
- 0xeb, 0xcd, 0xf6, 0xb6, 0xf4, 0x9b, 0x68, 0xea, 0x17, 0xef, 0xce, 0x7f,
- 0x37, 0x42, 0x5c, 0xf6, 0xf2, 0x32, 0xf8, 0xac, 0xe6, 0xc4, 0x77, 0x6c,
- 0x53, 0xb4, 0x0a, 0x4b, 0x41, 0x30, 0xed, 0xdb, 0x12, 0xe9, 0x0b, 0xeb,
- 0xea, 0x79, 0x15, 0x31, 0xaf, 0x3c, 0xe6, 0x65, 0xf7, 0xb5, 0xd2, 0xf4,
- 0xfb, 0x86, 0xa6, 0xde, 0x26, 0x9a, 0xe2, 0xef, 0x31, 0xaf, 0xf8, 0x2e,
- 0xf3, 0x7a, 0xa9, 0x57, 0xf7, 0x11, 0x6f, 0xea, 0xa3, 0xaf, 0xa5, 0x0f,
- 0xe8, 0xfd, 0x38, 0xdb, 0xf7, 0xed, 0xd2, 0xfe, 0x87, 0x1d, 0xba, 0x3d,
- 0xdb, 0xb4, 0x41, 0xb7, 0xf7, 0x1b, 0xbd, 0x78, 0xa2, 0x49, 0x97, 0x9d,
- 0x80, 0x2e, 0x6b, 0x6e, 0xd3, 0x2c, 0xff, 0xa1, 0x8f, 0x44, 0xff, 0x28,
- 0xc4, 0x8a, 0x1f, 0x50, 0x18, 0x64, 0x07, 0x63, 0xc7, 0x80, 0x47, 0xba,
- 0x60, 0xff, 0xbb, 0xe9, 0x07, 0x19, 0x4c, 0x48, 0xbf, 0x88, 0x38, 0x50,
- 0x3c, 0xa0, 0x28, 0xe8, 0x96, 0xc1, 0xc4, 0x31, 0x11, 0xe5, 0x07, 0x11,
- 0x5f, 0xd3, 0x27, 0xe2, 0x38, 0xf4, 0x89, 0xb8, 0xee, 0xbc, 0x2f, 0x6c,
- 0xfb, 0x48, 0xfd, 0xd8, 0xf7, 0xc4, 0xc7, 0xdc, 0x33, 0xa1, 0xad, 0x69,
- 0xd6, 0xa7, 0xbb, 0xd1, 0xd4, 0xdf, 0x42, 0x13, 0x74, 0x12, 0x7c, 0xb3,
- 0x05, 0xc8, 0x23, 0x30, 0x29, 0x74, 0xe0, 0xfd, 0x53, 0xe7, 0x56, 0x44,
- 0x4a, 0x0d, 0xda, 0xc7, 0x51, 0x81, 0x5f, 0x05, 0xba, 0xd8, 0xb7, 0xb2,
- 0x91, 0xd0, 0x4d, 0xdd, 0x39, 0x3b, 0x3b, 0x08, 0x3f, 0xdc, 0x91, 0x39,
- 0x43, 0xdb, 0x8c, 0xf2, 0xe1, 0xba, 0x50, 0x26, 0x94, 0x5c, 0xcd, 0x80,
- 0x3e, 0x5e, 0xcf, 0x18, 0xec, 0x7e, 0xac, 0xd1, 0x4a, 0xdb, 0xf7, 0x40,
- 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x02, 0xb0, 0xfb, 0x37, 0xd5, 0xbe, 0x0c,
- 0x75, 0x17, 0x65, 0x29, 0x55, 0x2d, 0xcb, 0x66, 0xb0, 0xb2, 0xcc, 0x7d,
- 0x4b, 0x1b, 0xde, 0x25, 0x65, 0xac, 0xd7, 0xc0, 0x52, 0x2a, 0x99, 0xb3,
- 0xc5, 0x7a, 0xdf, 0x41, 0xca, 0xd3, 0xe3, 0x32, 0x70, 0x51, 0x2c, 0x67,
- 0x09, 0x7b, 0xbd, 0x3b, 0xc4, 0x57, 0x9c, 0xdf, 0x6f, 0x63, 0x7e, 0xe8,
- 0x7b, 0x39, 0x9c, 0x5f, 0x97, 0x94, 0x56, 0x39, 0xbf, 0xed, 0xb9, 0xc5,
- 0x19, 0x11, 0xf9, 0x1c, 0xf4, 0x35, 0xe6, 0x08, 0x1a, 0xc7, 0x81, 0x73,
- 0xef, 0x30, 0x73, 0xea, 0xc2, 0x9c, 0x60, 0xa3, 0x97, 0xd8, 0x1e, 0x74,
- 0x81, 0xe6, 0x12, 0xea, 0xcd, 0x2f, 0x71, 0xcd, 0x41, 0x2b, 0xd6, 0xbd,
- 0xd4, 0xe0, 0xda, 0x73, 0x6e, 0xda, 0xae, 0x3b, 0x1e, 0xe7, 0xc7, 0x79,
- 0x0e, 0x63, 0x5e, 0xac, 0xc3, 0x76, 0xad, 0x32, 0x32, 0xfc, 0x1e, 0xeb,
- 0xf1, 0xdb, 0x2d, 0xeb, 0x21, 0x66, 0x3d, 0x62, 0xd2, 0xb6, 0xaa, 0xfc,
- 0x65, 0x45, 0x03, 0x7d, 0x08, 0x07, 0xf4, 0x2f, 0xae, 0xc8, 0x68, 0x54,
- 0x48, 0x7b, 0x82, 0xcf, 0x32, 0x6d, 0x32, 0xe8, 0x5f, 0x81, 0x5c, 0x95,
- 0x20, 0x0b, 0xf4, 0x07, 0x5e, 0x5e, 0xd6, 0x6b, 0x51, 0x6a, 0x74, 0xc2,
- 0x47, 0xe7, 0xf8, 0xe4, 0x37, 0xe7, 0xe6, 0xaa, 0x75, 0x68, 0x5e, 0x97,
- 0x4f, 0xdf, 0xb2, 0x2e, 0xd4, 0xbb, 0xd4, 0x03, 0xc4, 0x3d, 0xd4, 0x05,
- 0x61, 0x4c, 0xa0, 0xe6, 0xea, 0xfd, 0x14, 0xda, 0x9f, 0xeb, 0xdb, 0xf8,
- 0x52, 0xaf, 0x59, 0xc2, 0xc4, 0x05, 0xba, 0xc4, 0x5e, 0xbd, 0x83, 0x7a,
- 0x1f, 0xf6, 0x27, 0x9c, 0xdf, 0xef, 0xe0, 0x3e, 0x71, 0xd3, 0x7a, 0xd8,
- 0x98, 0x93, 0xa3, 0xe6, 0xa8, 0xd6, 0x62, 0x5b, 0xe6, 0xe6, 0x1a, 0x7a,
- 0x5e, 0xce, 0xd2, 0x1e, 0xb3, 0x1e, 0x31, 0x3c, 0xe3, 0xbc, 0x42, 0x9b,
- 0xc3, 0x79, 0x91, 0x5e, 0xd7, 0xc8, 0x1c, 0xe7, 0xc3, 0xfd, 0xd7, 0x2c,
- 0x6b, 0x2f, 0x05, 0xd5, 0xe5, 0xa8, 0x9a, 0x7b, 0xde, 0xef, 0x26, 0x46,
- 0xa3, 0x8e, 0x34, 0xfa, 0x89, 0xcf, 0x69, 0x07, 0xf1, 0x2e, 0x43, 0x19,
- 0xc2, 0x7d, 0x9d, 0xf7, 0xcd, 0x36, 0xed, 0x79, 0x47, 0xeb, 0x01, 0xc6,
- 0x9f, 0xde, 0xdb, 0xd6, 0x45, 0xb3, 0x62, 0xad, 0x57, 0xe8, 0x33, 0x07,
- 0xc0, 0x5d, 0x77, 0x40, 0xaf, 0x1c, 0x92, 0x92, 0x0b, 0x7b, 0x3d, 0x7c,
- 0x3b, 0xe6, 0x3c, 0x2e, 0x2a, 0xde, 0x30, 0xbc, 0x17, 0xd7, 0x7b, 0x94,
- 0xef, 0x52, 0x1a, 0xfe, 0x90, 0xe4, 0xa6, 0x69, 0xd3, 0x7e, 0x5f, 0x66,
- 0x60, 0x5b, 0x4b, 0xc3, 0x77, 0x82, 0x3e, 0xde, 0x43, 0x27, 0x7a, 0x43,
- 0x8c, 0x51, 0xe0, 0xef, 0x71, 0x13, 0x9b, 0x39, 0x80, 0xfb, 0x3d, 0xa8,
- 0xf3, 0x49, 0x53, 0xa7, 0x1b, 0x75, 0x06, 0x5b, 0xea, 0x70, 0xbc, 0xfb,
- 0x50, 0x07, 0xf6, 0x14, 0x56, 0xd2, 0xf6, 0x0e, 0xe2, 0x37, 0x81, 0x67,
- 0xf7, 0xe2, 0xd9, 0x3d, 0x78, 0x76, 0x0f, 0xee, 0x7f, 0xd7, 0xc4, 0x3c,
- 0xc2, 0x36, 0xdd, 0xb8, 0xff, 0x12, 0xde, 0x43, 0xc7, 0xb9, 0xdf, 0xc6,
- 0xfb, 0xfb, 0xf0, 0x1b, 0x6b, 0xa9, 0xe3, 0xb6, 0xdc, 0x9f, 0x76, 0x74,
- 0x8c, 0x84, 0xcf, 0x82, 0xc8, 0xce, 0xf5, 0x7f, 0x35, 0xcf, 0xbd, 0xa6,
- 0xf7, 0x1f, 0x37, 0xd7, 0xad, 0xb2, 0x94, 0x86, 0x2c, 0xf1, 0xfd, 0x57,
- 0xf6, 0xe9, 0xb5, 0xb8, 0x43, 0xc7, 0x1f, 0x6e, 0xc2, 0x1b, 0x4a, 0xfc,
- 0x71, 0xbd, 0x09, 0x9c, 0x41, 0xec, 0xd1, 0x8c, 0x3b, 0x48, 0x8b, 0xab,
- 0xe4, 0xf5, 0xe5, 0xe5, 0xd7, 0xba, 0xf5, 0x18, 0x62, 0xd5, 0x21, 0x73,
- 0x13, 0x2a, 0x16, 0xf1, 0x33, 0xf3, 0xcc, 0xdb, 0xb7, 0xf3, 0x6e, 0xaf,
- 0x4c, 0x54, 0xff, 0x68, 0xdf, 0x0e, 0x6d, 0x93, 0x4d, 0xd7, 0x3b, 0x98,
- 0x02, 0xfe, 0x84, 0xbd, 0x83, 0x77, 0x72, 0xf6, 0x5c, 0xa3, 0x68, 0xeb,
- 0x71, 0x59, 0x07, 0xef, 0x1a, 0x9b, 0x3d, 0x8e, 0x92, 0xfd, 0x9c, 0x4d,
- 0x5f, 0xa3, 0xbc, 0xc6, 0xeb, 0xdb, 0x51, 0x36, 0xb7, 0xed, 0x87, 0x1e,
- 0xcf, 0xd9, 0x9a, 0xee, 0xd6, 0xf6, 0xe1, 0xbe, 0xf1, 0x65, 0xa1, 0x0a,
- 0x99, 0xf3, 0x52, 0xc3, 0x65, 0xac, 0xdd, 0xac, 0x9f, 0x9a, 0xa6, 0x4c,
- 0xc2, 0x9f, 0xfd, 0x94, 0xc8, 0xa4, 0xcc, 0x57, 0x1f, 0x06, 0xfe, 0x0e,
- 0xe4, 0x21, 0xe0, 0x8a, 0x7f, 0x0f, 0x5c, 0x52, 0x83, 0xac, 0xd7, 0x1a,
- 0x1e, 0x7e, 0xfd, 0xf2, 0x57, 0x95, 0x84, 0x3c, 0x07, 0x7f, 0x02, 0xb2,
- 0x06, 0x3d, 0x9c, 0x76, 0x1f, 0x12, 0xe9, 0xb1, 0xe5, 0xf2, 0xbd, 0xb6,
- 0x8c, 0x24, 0x07, 0xac, 0x74, 0x02, 0x3f, 0xb7, 0x0d, 0xbf, 0x22, 0x7c,
- 0xb8, 0xb5, 0x06, 0x63, 0x01, 0x71, 0xf9, 0xeb, 0xf5, 0x24, 0x7e, 0x7d,
- 0xf2, 0x37, 0xeb, 0x1c, 0x7f, 0xc0, 0x94, 0x6a, 0x1f, 0xc3, 0xe7, 0x28,
- 0xcb, 0x62, 0x26, 0x21, 0x0b, 0x95, 0xe0, 0xa4, 0xf6, 0x99, 0x3d, 0xf8,
- 0xc8, 0xdc, 0xb3, 0x2f, 0x60, 0xcf, 0xe2, 0xb9, 0xc2, 0x9e, 0xa1, 0xdd,
- 0x7b, 0x01, 0x76, 0x2f, 0x5c, 0x23, 0xce, 0xb3, 0x75, 0x7d, 0xd8, 0x2f,
- 0xd7, 0x88, 0x7a, 0x9d, 0xba, 0x3c, 0x06, 0xfc, 0x10, 0xea, 0x76, 0xea,
- 0x08, 0x6f, 0xdb, 0x0f, 0x7d, 0xe4, 0x60, 0x17, 0xb0, 0x86, 0xc4, 0xe2,
- 0xd9, 0x9f, 0xca, 0xca, 0x59, 0xee, 0x1b, 0xda, 0xe3, 0xbb, 0x21, 0x6f,
- 0xa9, 0xaf, 0x96, 0x89, 0x99, 0xbd, 0x0c, 0xf8, 0x51, 0x96, 0xe9, 0x83,
- 0xab, 0xbd, 0x5a, 0x4e, 0x26, 0xc5, 0x39, 0xfb, 0x85, 0xa8, 0x74, 0x9f,
- 0x94, 0x45, 0x1f, 0x7e, 0xa9, 0x5d, 0x0e, 0x22, 0x9e, 0x97, 0x28, 0x28,
- 0xbf, 0x69, 0x05, 0x74, 0xc6, 0x64, 0xe2, 0x2c, 0xeb, 0x9c, 0x84, 0x8c,
- 0xb5, 0x81, 0xe6, 0x76, 0x39, 0x15, 0x4f, 0x95, 0x0b, 0xf0, 0xf7, 0x6d,
- 0xaf, 0x47, 0x06, 0xea, 0x2c, 0x89, 0x41, 0xfe, 0x37, 0xe4, 0x87, 0xd7,
- 0xf0, 0x03, 0x57, 0xf9, 0x7c, 0x00, 0x25, 0x9f, 0x7b, 0xd0, 0x2f, 0xe4,
- 0x07, 0x70, 0xc3, 0xc5, 0xb2, 0x9c, 0xca, 0x4c, 0x4a, 0xbd, 0x2a, 0xd6,
- 0x42, 0x06, 0x7b, 0xa0, 0x96, 0x95, 0x3a, 0x78, 0x51, 0x6a, 0x1c, 0x87,
- 0xdf, 0xf9, 0x26, 0xca, 0x39, 0x94, 0xd7, 0x51, 0x3e, 0x8e, 0xf2, 0x2d,
- 0x94, 0xa4, 0xfd, 0xb8, 0xd4, 0x6b, 0x7b, 0xda, 0xa4, 0x93, 0x7d, 0x6c,
- 0x18, 0x9a, 0xe1, 0x3b, 0x1e, 0x3c, 0x0e, 0x2c, 0x1a, 0x3e, 0x3f, 0x2e,
- 0x52, 0xff, 0x0c, 0x7e, 0x0f, 0xaa, 0x7b, 0xfa, 0x96, 0x0b, 0x99, 0x71,
- 0xe0, 0x7a, 0xb1, 0x4e, 0x65, 0x1e, 0x37, 0xfd, 0x7c, 0x06, 0xe3, 0x5d,
- 0xc5, 0xd8, 0x31, 0xc8, 0x48, 0x20, 0x8f, 0xf8, 0x27, 0xe5, 0x73, 0xfe,
- 0x7e, 0x19, 0xeb, 0x8d, 0x95, 0x63, 0x59, 0xce, 0x9f, 0x7a, 0x6a, 0xb7,
- 0xf9, 0x87, 0xf3, 0xe6, 0x9c, 0xa1, 0x5b, 0x97, 0xf6, 0x6a, 0xdc, 0x6d,
- 0x7f, 0x39, 0xaa, 0x69, 0xb1, 0x64, 0x60, 0x88, 0xfd, 0x65, 0x25, 0x72,
- 0x76, 0xc8, 0xcd, 0xd8, 0x23, 0xf0, 0x52, 0xd2, 0xf8, 0x9d, 0x84, 0xfc,
- 0x79, 0xa7, 0x07, 0xec, 0xdb, 0x40, 0x13, 0xde, 0xd5, 0x39, 0x0e, 0xec,
- 0xe9, 0x3d, 0xaf, 0x62, 0x6e, 0x65, 0x69, 0xbf, 0x27, 0x2b, 0x37, 0x1a,
- 0xbc, 0x86, 0x3d, 0xba, 0x30, 0x29, 0xff, 0x5c, 0xbd, 0x2a, 0x4f, 0x54,
- 0x27, 0xe5, 0x0d, 0x94, 0x8b, 0xd5, 0x32, 0xf8, 0xc8, 0x58, 0x3c, 0xfb,
- 0x08, 0xb0, 0x2e, 0x83, 0xf0, 0x8d, 0x3e, 0x98, 0x98, 0xc3, 0xfa, 0xcd,
- 0xb8, 0x81, 0x9c, 0xf3, 0xcb, 0x72, 0x6e, 0x1c, 0x6d, 0x6a, 0x1d, 0x12,
- 0x7d, 0x96, 0xf3, 0xed, 0x96, 0x02, 0x2c, 0x7a, 0x31, 0x43, 0x9d, 0xd9,
- 0x29, 0x85, 0x5a, 0xab, 0xdc, 0x51, 0xde, 0xde, 0xb6, 0xea, 0xdb, 0x3a,
- 0x60, 0xd3, 0xfa, 0x66, 0x83, 0x36, 0x78, 0x37, 0x7b, 0xaa, 0xe5, 0xae,
- 0x5e, 0xa3, 0x4d, 0xdd, 0x91, 0xbd, 0x3a, 0xfc, 0xb9, 0x7a, 0xf5, 0xba,
- 0x91, 0x3f, 0x25, 0xb7, 0x58, 0x17, 0x62, 0xf1, 0x9f, 0x08, 0xb0, 0x1f,
- 0x78, 0x14, 0xc6, 0x09, 0xb5, 0x7f, 0x54, 0x03, 0xad, 0x85, 0x38, 0x71,
- 0x06, 0xac, 0x5b, 0xed, 0x0b, 0x8a, 0x57, 0xde, 0xd9, 0x7e, 0xa9, 0x2e,
- 0x93, 0xbf, 0x29, 0xd7, 0xb6, 0x95, 0x4f, 0x02, 0xbe, 0x7a, 0x58, 0x9f,
- 0xf0, 0x7d, 0x0a, 0x7e, 0xd2, 0x49, 0x71, 0xc7, 0x3a, 0x31, 0x27, 0x5e,
- 0x8b, 0x4c, 0x5f, 0x6c, 0xc5, 0x91, 0xa1, 0x9d, 0x68, 0x83, 0x3f, 0x1e,
- 0xc5, 0x5a, 0x76, 0xc1, 0x9f, 0x86, 0x9f, 0x0a, 0x39, 0xfa, 0x33, 0x60,
- 0xaf, 0xd3, 0xca, 0xb7, 0xe6, 0x9e, 0xea, 0x9e, 0x1a, 0x58, 0x67, 0xb9,
- 0x77, 0x2a, 0x5d, 0x63, 0x19, 0x9f, 0xd2, 0xbe, 0x64, 0x62, 0x4a, 0xc7,
- 0xed, 0x93, 0x53, 0x07, 0x54, 0xe9, 0x4d, 0x0d, 0xab, 0x72, 0x78, 0x6a,
- 0x27, 0x66, 0x42, 0x9e, 0x8a, 0x95, 0xcf, 0x64, 0xa4, 0x58, 0x21, 0x8d,
- 0xe2, 0x1c, 0x83, 0x3c, 0xcd, 0x01, 0xcb, 0xe4, 0x2b, 0xbe, 0x9c, 0xda,
- 0xc8, 0x82, 0x66, 0xe8, 0x99, 0xac, 0x8f, 0x52, 0xcc, 0x5f, 0xd8, 0xb6,
- 0x8d, 0x31, 0x32, 0xae, 0x99, 0xf1, 0x33, 0x7d, 0xfa, 0x99, 0xcd, 0x7f,
- 0xec, 0x0f, 0xb2, 0x49, 0xfb, 0xf9, 0x0b, 0xf8, 0xc6, 0xe2, 0x94, 0x32,
- 0x6c, 0xeb, 0xc3, 0x07, 0x17, 0xd9, 0x5a, 0x91, 0x58, 0x2c, 0xfb, 0x1d,
- 0x89, 0x3d, 0x1d, 0x04, 0x3f, 0xf0, 0x53, 0x47, 0xca, 0x02, 0x5e, 0x59,
- 0x78, 0xbe, 0xce, 0x77, 0xd4, 0x4d, 0x23, 0xee, 0x0d, 0xc8, 0x5c, 0xee,
- 0xa8, 0xc8, 0x2b, 0x78, 0x56, 0x5f, 0xe1, 0x1a, 0x7c, 0x17, 0x6b, 0x60,
- 0xd6, 0x44, 0x3d, 0x63, 0x3d, 0xf8, 0x58, 0x71, 0xce, 0x63, 0xc4, 0x6d,
- 0x47, 0xfb, 0xda, 0x3a, 0xdb, 0xa4, 0xc6, 0x79, 0xe4, 0xf5, 0xca, 0xba,
- 0x9e, 0xdf, 0xe1, 0xcc, 0xb0, 0x5c, 0xae, 0xa8, 0x3e, 0x20, 0xeb, 0xbf,
- 0x44, 0x9b, 0x4d, 0xc8, 0x2d, 0x63, 0x53, 0x59, 0x99, 0x07, 0x4e, 0x9b,
- 0xaf, 0xa4, 0x21, 0x3b, 0x8e, 0xcc, 0x24, 0x48, 0xb6, 0x27, 0x5b, 0x95,
- 0x37, 0xdb, 0x88, 0x85, 0xf3, 0x1e, 0xaf, 0xc7, 0x51, 0x67, 0x5a, 0x88,
- 0xb7, 0xf2, 0x19, 0xce, 0xa9, 0x99, 0x17, 0xfa, 0xaf, 0x84, 0xb5, 0x30,
- 0x73, 0x54, 0x7f, 0x7a, 0x1c, 0xb4, 0x37, 0xe3, 0x14, 0x01, 0x53, 0xe0,
- 0x6b, 0x4a, 0xfa, 0x82, 0xe3, 0xe4, 0x2b, 0x8e, 0x0c, 0x5c, 0xc0, 0xb6,
- 0xca, 0x1a, 0x5e, 0x34, 0x42, 0x59, 0x0b, 0x31, 0x10, 0x65, 0x8b, 0x3c,
- 0x48, 0x95, 0x37, 0xc1, 0xec, 0xde, 0xec, 0x35, 0x79, 0x74, 0x55, 0xcf,
- 0xd9, 0x3e, 0x2f, 0x3c, 0x0b, 0x91, 0x1b, 0x2b, 0x29, 0xff, 0x3a, 0xf4,
- 0x7d, 0x21, 0xee, 0x43, 0x56, 0xfe, 0x4b, 0x1b, 0xf6, 0xf4, 0x78, 0xce,
- 0xde, 0xdf, 0xae, 0x6d, 0xac, 0x83, 0x3d, 0x01, 0xac, 0x59, 0xc9, 0xa1,
- 0x4d, 0xbb, 0xfc, 0x5b, 0x07, 0xd7, 0xc4, 0x9e, 0x78, 0x66, 0xec, 0x22,
- 0xae, 0x75, 0x7f, 0xf3, 0x98, 0x87, 0x8e, 0x03, 0x5b, 0xf2, 0x28, 0x2c,
- 0x88, 0xa0, 0xff, 0x01, 0x33, 0xd6, 0xc0, 0xf9, 0x50, 0x36, 0x40, 0xf7,
- 0x6a, 0x16, 0xf8, 0xdd, 0x31, 0x7e, 0x2b, 0x75, 0x8c, 0xec, 0xe2, 0xf7,
- 0x34, 0xc7, 0x5e, 0x63, 0x2a, 0x4e, 0x47, 0x2c, 0x47, 0xd9, 0x3a, 0x62,
- 0x64, 0xeb, 0x33, 0x90, 0xad, 0xe3, 0x4a, 0xb6, 0x02, 0xf9, 0x81, 0xef,
- 0xcb, 0x97, 0x77, 0x95, 0xaf, 0xd6, 0xbf, 0x2e, 0xd0, 0xcb, 0x5f, 0x9f,
- 0x2c, 0xfc, 0x05, 0xc6, 0xbd, 0xe0, 0xe2, 0x3a, 0x95, 0x9b, 0x11, 0xf2,
- 0x31, 0x81, 0xeb, 0x18, 0xca, 0x7e, 0x55, 0x67, 0xe0, 0x02, 0xec, 0x1a,
- 0xe4, 0x8d, 0xfc, 0x9d, 0x87, 0x8d, 0x1b, 0xb8, 0x10, 0x85, 0x2d, 0xe4,
- 0x9e, 0x95, 0x5e, 0x1b, 0xba, 0x81, 0xf5, 0xeb, 0xd8, 0x3b, 0x03, 0x17,
- 0xba, 0x50, 0x26, 0x55, 0x5f, 0xf5, 0x8a, 0xa7, 0xda, 0xd7, 0x2b, 0xc3,
- 0xaa, 0x5d, 0xbd, 0x32, 0x8a, 0x12, 0xfa, 0x3d, 0xe3, 0xcb, 0xd0, 0x85,
- 0x8c, 0x24, 0x2f, 0x58, 0x52, 0x9a, 0x0e, 0x82, 0x18, 0x68, 0x1f, 0xbe,
- 0xd0, 0x23, 0xd7, 0xa7, 0x39, 0x37, 0xea, 0x62, 0xb1, 0x16, 0x33, 0xd3,
- 0xd8, 0x9b, 0xe4, 0x1f, 0xb0, 0xfe, 0x85, 0x22, 0x6c, 0x6e, 0x51, 0x4e,
- 0xad, 0x90, 0x3f, 0x8c, 0xb5, 0x6f, 0x25, 0x22, 0x92, 0x82, 0x2e, 0x3b,
- 0x2a, 0x73, 0xd5, 0x76, 0xe8, 0x32, 0xc7, 0xad, 0xcb, 0x13, 0x58, 0xa3,
- 0x41, 0xca, 0x03, 0xf8, 0x92, 0x45, 0xdf, 0x45, 0x29, 0xa0, 0x4d, 0x71,
- 0x65, 0xa7, 0x7e, 0x49, 0xda, 0xb1, 0xa7, 0x8e, 0xca, 0xb1, 0x2a, 0xfb,
- 0x71, 0xdc, 0x79, 0x39, 0x00, 0x19, 0xf2, 0xdc, 0x09, 0xf4, 0x03, 0x1b,
- 0xd9, 0xf4, 0xc7, 0xfd, 0x97, 0x7b, 0x0f, 0x99, 0x0c, 0xf7, 0x5d, 0xac,
- 0xdc, 0x96, 0x9d, 0xb6, 0xb6, 0x32, 0xe2, 0xcc, 0x66, 0x1e, 0xb2, 0x5e,
- 0xc9, 0x64, 0xac, 0x2b, 0x99, 0x9c, 0x75, 0x35, 0x53, 0xb4, 0xae, 0xc1,
- 0x36, 0xd5, 0x37, 0xde, 0x81, 0xfc, 0x00, 0x4f, 0x10, 0x7b, 0x6f, 0xaf,
- 0x61, 0xdc, 0xf8, 0x39, 0x6f, 0xc9, 0xb9, 0x0a, 0xed, 0x74, 0x70, 0x68,
- 0xd6, 0x2f, 0xdf, 0x0e, 0xfa, 0x40, 0x07, 0xe3, 0x11, 0x3b, 0xb6, 0x23,
- 0x9a, 0x1d, 0x06, 0x4e, 0xa0, 0xed, 0xe8, 0xa2, 0xed, 0xf0, 0x0b, 0xb2,
- 0x57, 0xb6, 0xaa, 0x3a, 0x2e, 0x97, 0x07, 0x6e, 0xda, 0xaa, 0xc5, 0xe5,
- 0xcb, 0xcb, 0xa1, 0x2c, 0x71, 0xbe, 0xf3, 0xef, 0xeb, 0x90, 0x88, 0x1c,
- 0x51, 0xf6, 0xba, 0x5b, 0x2e, 0xaf, 0x03, 0xd3, 0x02, 0x81, 0xd8, 0x77,
- 0x32, 0xce, 0x63, 0xab, 0xf8, 0x85, 0xf4, 0xf0, 0x3c, 0xf0, 0x1f, 0xc0,
- 0x2b, 0x9e, 0xd9, 0x61, 0x9e, 0x3d, 0x9c, 0x51, 0x78, 0x3f, 0x8a, 0x3d,
- 0xc9, 0x6b, 0x4b, 0x0a, 0xc0, 0xed, 0x5b, 0x15, 0x96, 0x09, 0x94, 0x26,
- 0x56, 0x0f, 0x5d, 0x10, 0xc9, 0xfe, 0xa3, 0x7a, 0xdf, 0xee, 0x89, 0x35,
- 0x0b, 0x3b, 0x5c, 0x5a, 0xa1, 0x4c, 0xa3, 0x5c, 0xd7, 0x63, 0x17, 0x7c,
- 0x60, 0xe6, 0xd1, 0x0e, 0xda, 0x37, 0xe0, 0x27, 0xec, 0x7b, 0x85, 0xed,
- 0x33, 0xd8, 0x73, 0x3f, 0x68, 0xa7, 0x6d, 0x3f, 0xec, 0x8f, 0xcb, 0xb5,
- 0x0a, 0xaf, 0xf9, 0x3e, 0xe5, 0x8b, 0x8a, 0x1b, 0xc7, 0xa6, 0x16, 0x3d,
- 0xdf, 0xec, 0x31, 0x15, 0xd3, 0xb1, 0x3e, 0x06, 0xcc, 0x38, 0x70, 0xa6,
- 0x4d, 0xd2, 0x4f, 0xdb, 0x7d, 0xfa, 0x7c, 0xe5, 0x90, 0x14, 0xfd, 0x03,
- 0x98, 0xc3, 0x3e, 0x99, 0x87, 0x2f, 0xb6, 0xb0, 0x31, 0x2c, 0xf3, 0xc3,
- 0xf0, 0xb9, 0xdd, 0xbb, 0x89, 0xd5, 0xf0, 0xeb, 0xc0, 0xf3, 0x41, 0x94,
- 0xed, 0x28, 0x6f, 0x97, 0xf9, 0xa7, 0xba, 0x63, 0xba, 0xbf, 0x68, 0xcb,
- 0xfd, 0xb3, 0x1c, 0x3b, 0x99, 0xb4, 0x7e, 0x15, 0x2e, 0x6c, 0xc6, 0x84,
- 0xa4, 0x23, 0x2a, 0xde, 0x93, 0x5d, 0x32, 0x78, 0xc6, 0x95, 0xa1, 0x33,
- 0x09, 0x39, 0x70, 0xa6, 0x5f, 0x86, 0xcf, 0x24, 0xe5, 0xce, 0x33, 0x21,
- 0xfe, 0xea, 0x9e, 0x4a, 0x1b, 0x5b, 0xe1, 0xfd, 0x9a, 0xb6, 0xe2, 0xce,
- 0x86, 0xc6, 0xa8, 0xf3, 0x6b, 0xc4, 0x74, 0xaf, 0x62, 0xef, 0x6e, 0xaa,
- 0xf3, 0xca, 0x4b, 0x1b, 0x41, 0x70, 0xc9, 0x6f, 0x77, 0xa7, 0x85, 0xfc,
- 0xce, 0x00, 0x9f, 0xf9, 0xd0, 0x61, 0xa3, 0xd0, 0x61, 0xe3, 0xca, 0x36,
- 0xd6, 0xbf, 0x2e, 0xd6, 0xb1, 0xcc, 0x03, 0xb2, 0x06, 0xd9, 0x7e, 0xd0,
- 0x4f, 0x7d, 0x75, 0x53, 0xf1, 0x47, 0x62, 0x3d, 0xd0, 0x67, 0x77, 0xaf,
- 0xb6, 0xcb, 0x1b, 0xf1, 0x20, 0x38, 0x0b, 0x1d, 0x50, 0xaf, 0x68, 0xf9,
- 0xcd, 0x7b, 0xd4, 0x05, 0x0f, 0x61, 0xfe, 0xa3, 0x78, 0x96, 0x33, 0xba,
- 0xbd, 0x43, 0x6e, 0xc4, 0x13, 0xb2, 0x7e, 0x60, 0xbc, 0xa5, 0x5e, 0x06,
- 0xf7, 0xc0, 0x3d, 0x8d, 0xdf, 0x23, 0xbf, 0xf0, 0xdc, 0x95, 0x73, 0xf0,
- 0x99, 0xcf, 0x1f, 0x48, 0x8d, 0x27, 0x6d, 0xea, 0xc3, 0xa4, 0xd4, 0xbe,
- 0x9e, 0x90, 0xb5, 0x65, 0x6d, 0x97, 0x66, 0xbd, 0x71, 0x29, 0x00, 0xfb,
- 0xae, 0x2d, 0x67, 0x51, 0xb2, 0x7e, 0xa8, 0x73, 0xb4, 0x5c, 0x16, 0x33,
- 0x79, 0xec, 0x63, 0xee, 0x0f, 0x6d, 0x77, 0x6c, 0xbb, 0x1d, 0x72, 0xc4,
- 0x3d, 0xf1, 0x30, 0x9e, 0xe7, 0xb1, 0xaf, 0x69, 0xc7, 0xd3, 0x90, 0xaf,
- 0xcf, 0xc6, 0x28, 0x1f, 0x05, 0x9f, 0xf8, 0x9a, 0x6d, 0x52, 0x89, 0x34,
- 0x9e, 0x4f, 0x4b, 0x5a, 0x9d, 0x0b, 0xcd, 0xfa, 0x61, 0x7f, 0x59, 0xa3,
- 0x17, 0x22, 0x8c, 0x81, 0xe1, 0xef, 0x64, 0x8c, 0xf2, 0x18, 0xf1, 0xc2,
- 0xe7, 0x23, 0xb0, 0x3d, 0x51, 0x35, 0xc6, 0xfc, 0x32, 0x9f, 0xa5, 0x5d,
- 0xb6, 0x2f, 0xf8, 0xbc, 0x17, 0xf9, 0x44, 0x83, 0xf1, 0x9a, 0x98, 0x3c,
- 0xda, 0xe8, 0x02, 0xbd, 0x6d, 0xbf, 0xc2, 0xf6, 0xec, 0xec, 0x73, 0x3b,
- 0xbb, 0x95, 0x70, 0x95, 0x6e, 0xa1, 0x1e, 0xa1, 0x0e, 0x69, 0x17, 0x67,
- 0x8c, 0xfb, 0x0c, 0x6b, 0xb2, 0x8c, 0x35, 0x5a, 0xc6, 0x1a, 0x2d, 0x63,
- 0x8d, 0x96, 0xb1, 0x7e, 0xcb, 0xd4, 0x2d, 0x83, 0xd8, 0xcf, 0x39, 0x73,
- 0x86, 0x40, 0xfd, 0xf2, 0x1c, 0xd6, 0x76, 0x5a, 0xfe, 0x76, 0x63, 0x52,
- 0xfe, 0xf3, 0xc6, 0x11, 0xe0, 0xee, 0x22, 0xd6, 0x35, 0x87, 0x75, 0xcd,
- 0x62, 0x5d, 0x8f, 0x62, 0x5d, 0xc7, 0x55, 0xcc, 0xb3, 0x5a, 0x49, 0x5d,
- 0x2a, 0x2b, 0x8c, 0xff, 0x16, 0xe4, 0x61, 0x4c, 0x9c, 0xd5, 0x7e, 0xe8,
- 0x8b, 0x72, 0x10, 0xf7, 0x82, 0x43, 0xc0, 0xd6, 0x18, 0xbb, 0x9c, 0x72,
- 0x94, 0xee, 0xf3, 0xdc, 0xcf, 0x63, 0xaf, 0xbc, 0x2f, 0x9b, 0xaa, 0x52,
- 0x75, 0x9d, 0xab, 0x0e, 0x4b, 0xe9, 0x22, 0xea, 0x9f, 0xed, 0x02, 0xad,
- 0xc4, 0x7c, 0xa9, 0xd3, 0x25, 0xd9, 0x84, 0xbe, 0xcb, 0x81, 0xc6, 0x0f,
- 0xc9, 0x7c, 0x3c, 0xf5, 0x9c, 0xc8, 0xb8, 0xdc, 0x03, 0x3f, 0x9d, 0xf1,
- 0xcc, 0x9c, 0x8a, 0xb1, 0xe1, 0xfa, 0x62, 0x16, 0xfe, 0x36, 0x6d, 0xec,
- 0x3e, 0xe3, 0x87, 0x6b, 0x1c, 0x5b, 0x13, 0x8e, 0xcb, 0xf1, 0xfe, 0x58,
- 0xe6, 0x80, 0x15, 0xe1, 0xeb, 0x03, 0x8b, 0x78, 0x09, 0x8c, 0x19, 0x9b,
- 0xbd, 0xe8, 0xc6, 0xe6, 0x2e, 0xb2, 0x9f, 0x98, 0x44, 0x96, 0xa8, 0xb3,
- 0xd8, 0x0f, 0x74, 0x3b, 0xfa, 0x4e, 0xab, 0x33, 0xb3, 0x11, 0xb4, 0xfb,
- 0x5d, 0xe0, 0x4c, 0xcd, 0xc7, 0xfc, 0x59, 0x6d, 0xf7, 0xf2, 0xf5, 0x66,
- 0xac, 0x07, 0xdd, 0x02, 0xbb, 0x98, 0xab, 0x6b, 0xdc, 0x56, 0x54, 0xb8,
- 0x4e, 0x63, 0xba, 0xa3, 0x72, 0xa8, 0x43, 0x3a, 0x3d, 0x35, 0x9f, 0xc8,
- 0xd9, 0x4d, 0xe2, 0x58, 0x8c, 0xc1, 0x36, 0xd1, 0x26, 0xba, 0x33, 0xb0,
- 0xa7, 0xb7, 0x77, 0x50, 0x66, 0x3e, 0x09, 0xdc, 0x38, 0xb0, 0xa4, 0xcf,
- 0x98, 0x06, 0x2e, 0xfa, 0x98, 0x8f, 0xf4, 0x31, 0xb2, 0x69, 0x63, 0x0e,
- 0x1f, 0x55, 0x76, 0x79, 0x0c, 0xb6, 0xd8, 0x85, 0xac, 0x53, 0xe7, 0xf4,
- 0x61, 0xff, 0xf0, 0x9e, 0xba, 0x87, 0x7a, 0x8c, 0x32, 0x13, 0x07, 0x6e,
- 0x82, 0xfe, 0xe9, 0xee, 0x97, 0xda, 0x06, 0xdf, 0xf5, 0x2b, 0x1d, 0xed,
- 0x60, 0x0d, 0x16, 0x2b, 0xc1, 0xa1, 0xbc, 0x5f, 0x86, 0x16, 0x25, 0xcf,
- 0xc9, 0x0f, 0xf2, 0x7d, 0x14, 0xb4, 0x91, 0xc7, 0xdd, 0x65, 0x7d, 0x6e,
- 0xb9, 0x57, 0x4a, 0x55, 0xea, 0x69, 0x94, 0xb5, 0xbd, 0xf0, 0x9d, 0x5c,
- 0x85, 0x65, 0x73, 0xd3, 0x9c, 0x7b, 0xac, 0xec, 0x42, 0x6e, 0xdd, 0x83,
- 0x93, 0x2a, 0xa6, 0x72, 0x79, 0x29, 0xe5, 0xd7, 0x6c, 0x8c, 0x09, 0x9d,
- 0x69, 0x9f, 0x1f, 0x93, 0xb9, 0x95, 0x6e, 0x19, 0x5c, 0xe5, 0xf9, 0xf2,
- 0x50, 0x4c, 0xba, 0x83, 0xe0, 0x9c, 0x9f, 0x57, 0xb1, 0xc7, 0x81, 0x55,
- 0x60, 0x82, 0xa3, 0x9a, 0x77, 0x9c, 0x2f, 0x74, 0xc4, 0xbf, 0x82, 0x8f,
- 0xef, 0x8e, 0x8f, 0x8b, 0xbb, 0xe0, 0xe3, 0x57, 0x2f, 0x42, 0xfe, 0x96,
- 0x21, 0x9b, 0xcb, 0x90, 0xcd, 0x65, 0xc8, 0xe6, 0x32, 0x64, 0x73, 0x19,
- 0xb2, 0x89, 0xfd, 0xf3, 0xfc, 0xf2, 0xb8, 0xc1, 0x1f, 0x9f, 0x82, 0x2c,
- 0x7f, 0xdb, 0xe0, 0x8f, 0x51, 0xc8, 0x70, 0x12, 0xb2, 0xeb, 0x43, 0x6e,
- 0x87, 0x21, 0xcb, 0x1e, 0x64, 0xb9, 0x1f, 0x72, 0x9c, 0x50, 0xfe, 0xe3,
- 0x04, 0xb0, 0xe8, 0x83, 0xf0, 0x41, 0xce, 0x57, 0xfb, 0x65, 0x51, 0xd1,
- 0x12, 0xc8, 0x96, 0xbf, 0x49, 0x1e, 0x62, 0x5f, 0xd0, 0x3f, 0x77, 0xe5,
- 0xfc, 0x5a, 0x48, 0xdb, 0xab, 0xf2, 0xcd, 0xca, 0x6b, 0xf2, 0x42, 0x85,
- 0x34, 0xe6, 0x64, 0x11, 0xef, 0xd6, 0x9e, 0xa2, 0x1f, 0xa9, 0xe8, 0x83,
- 0xcc, 0x9d, 0x94, 0xff, 0x03, 0x5e, 0xae, 0x6f, 0x7c, 0x58, 0x3e, 0xe7,
- 0x52, 0x86, 0xe3, 0xd0, 0x35, 0xb8, 0x3f, 0x40, 0xbd, 0x04, 0x3f, 0xb4,
- 0x92, 0x2a, 0x97, 0xa0, 0x27, 0xaa, 0xf6, 0x08, 0x30, 0x58, 0x39, 0xe8,
- 0xa1, 0x0e, 0xab, 0x7a, 0xee, 0x80, 0x4d, 0xde, 0xec, 0x87, 0xbc, 0xa4,
- 0xbe, 0x0a, 0xe1, 0xc5, 0x33, 0xda, 0x73, 0x94, 0x35, 0xe8, 0xcf, 0xa7,
- 0xc8, 0x47, 0xfa, 0xb5, 0xb8, 0x56, 0xba, 0xf7, 0x27, 0x2a, 0x7e, 0x5c,
- 0x9a, 0x86, 0x2f, 0xbf, 0x46, 0x3e, 0x41, 0x56, 0x9e, 0x22, 0x1f, 0x49,
- 0x9f, 0xe6, 0xe3, 0x23, 0x12, 0xf2, 0x90, 0xef, 0x5a, 0x79, 0x08, 0x27,
- 0xaa, 0x33, 0x8e, 0xb9, 0x7f, 0x2d, 0x66, 0x62, 0xc8, 0xc6, 0x26, 0xbf,
- 0x2a, 0xd3, 0x0d, 0xce, 0xc7, 0x92, 0xdb, 0xbc, 0xab, 0xf0, 0xa9, 0x38,
- 0xf6, 0xab, 0xc1, 0xa3, 0x71, 0xce, 0x81, 0xeb, 0xba, 0x47, 0xea, 0x7d,
- 0xbe, 0x89, 0xaf, 0xfc, 0x2a, 0x5b, 0xc4, 0x7a, 0xe0, 0x3b, 0xf4, 0xcb,
- 0x0b, 0xcb, 0xe0, 0x37, 0xfc, 0xae, 0x6f, 0xc0, 0xef, 0x62, 0x9c, 0x53,
- 0xaf, 0xcf, 0xb8, 0x89, 0xd9, 0xb6, 0xc6, 0x6a, 0x93, 0x58, 0x23, 0xfa,
- 0xed, 0xa9, 0xf2, 0x75, 0xe8, 0xc1, 0xe7, 0x7d, 0xc6, 0xf8, 0x02, 0xf9,
- 0xef, 0x7e, 0xb3, 0xa6, 0x53, 0xf1, 0x6d, 0x79, 0x04, 0xba, 0xf1, 0x51,
- 0xe8, 0xc6, 0x4f, 0xdc, 0x92, 0xe7, 0x43, 0x79, 0xbb, 0x7f, 0x6a, 0x76,
- 0x65, 0xb0, 0x1c, 0xb1, 0xfb, 0x31, 0xa7, 0xe6, 0xb6, 0x8c, 0xf1, 0x25,
- 0x4d, 0x2c, 0xb6, 0x19, 0xb3, 0x86, 0xf1, 0x56, 0xca, 0x74, 0x20, 0xd7,
- 0xfc, 0x72, 0x57, 0x44, 0x9d, 0x3f, 0x7b, 0xb4, 0x13, 0xbb, 0xfc, 0xbd,
- 0xd8, 0xa1, 0xed, 0xf3, 0x5b, 0x46, 0xc6, 0x76, 0x72, 0x99, 0x26, 0x32,
- 0xe1, 0x99, 0x73, 0x37, 0x6c, 0x1e, 0xf7, 0x6d, 0x2a, 0x99, 0xc3, 0xde,
- 0x9e, 0xdf, 0xa0, 0x5d, 0x20, 0x9e, 0x6c, 0x63, 0x4c, 0x6f, 0xa6, 0x3d,
- 0xcb, 0xd8, 0x41, 0x37, 0xfc, 0x97, 0xd7, 0xe5, 0xdc, 0xca, 0x3f, 0x75,
- 0xe8, 0xfd, 0xa4, 0x73, 0xcf, 0xec, 0x8b, 0xad, 0x71, 0x54, 0xbd, 0x46,
- 0x85, 0x4c, 0x37, 0x30, 0x0c, 0xfd, 0xa5, 0x6b, 0xca, 0x5f, 0x3a, 0xec,
- 0x3b, 0xb2, 0x19, 0x67, 0x9f, 0xaf, 0xcb, 0xb1, 0x95, 0xe1, 0x4e, 0xc6,
- 0x2b, 0x17, 0x97, 0x0f, 0xc8, 0x96, 0xd2, 0x65, 0x0f, 0xa3, 0x6e, 0x16,
- 0x7b, 0x36, 0x08, 0x26, 0xfc, 0xb4, 0x7b, 0x5e, 0x46, 0x12, 0xe7, 0xc1,
- 0xd3, 0x3f, 0x43, 0x1b, 0xf8, 0xd4, 0x41, 0x11, 0xcf, 0xae, 0xc2, 0x6f,
- 0xbf, 0x21, 0xbc, 0x1e, 0x71, 0x4f, 0x43, 0x18, 0x72, 0x6e, 0xda, 0x7d,
- 0x4b, 0x42, 0xdb, 0x45, 0x3b, 0xc5, 0x33, 0xeb, 0x3e, 0x29, 0xac, 0x6b,
- 0x5a, 0xe7, 0x41, 0xeb, 0xa9, 0x15, 0x8e, 0xc1, 0x79, 0x91, 0xde, 0x7f,
- 0xe2, 0x19, 0x07, 0xe6, 0xf2, 0x41, 0x60, 0x59, 0xe2, 0x28, 0x1d, 0x8b,
- 0x28, 0xa0, 0x8d, 0xc2, 0x5a, 0x3e, 0xcf, 0x2b, 0xc9, 0xc7, 0x2f, 0xc2,
- 0x6f, 0x88, 0x43, 0x8e, 0xf1, 0x7c, 0xbd, 0x39, 0xe6, 0xcb, 0xfa, 0xfa,
- 0x1c, 0xed, 0x92, 0xf2, 0x11, 0xf2, 0xc0, 0x85, 0x93, 0xa8, 0xcb, 0x78,
- 0x67, 0x10, 0x1c, 0xf7, 0xe1, 0xc7, 0x3f, 0x45, 0xd9, 0xbb, 0x53, 0x4a,
- 0xca, 0xe7, 0x20, 0x86, 0x65, 0xfe, 0xc6, 0x96, 0x1b, 0xc3, 0xfe, 0x9c,
- 0x86, 0x6d, 0xcb, 0xc3, 0xb6, 0x45, 0xee, 0x3e, 0x02, 0x3c, 0xab, 0xce,
- 0xd9, 0x60, 0x3f, 0x39, 0xee, 0xc3, 0xd6, 0xdf, 0x67, 0x46, 0x81, 0x6f,
- 0x1f, 0x00, 0xbe, 0x65, 0x1e, 0x59, 0x1e, 0x18, 0x97, 0xf8, 0xd6, 0x95,
- 0xbf, 0xda, 0xc8, 0x43, 0xb7, 0x4d, 0x74, 0x52, 0x17, 0x1f, 0xd9, 0xb6,
- 0xd3, 0x45, 0x63, 0xc7, 0xf7, 0x49, 0x41, 0x9d, 0xbb, 0x15, 0x95, 0xbd,
- 0x9f, 0x5f, 0x27, 0xae, 0x87, 0xed, 0x5f, 0x87, 0xef, 0x57, 0xa1, 0x8f,
- 0x96, 0xc3, 0xfd, 0x03, 0xb8, 0x7f, 0x08, 0xe5, 0x11, 0x94, 0xda, 0xf7,
- 0xb9, 0xb4, 0x1c, 0xe9, 0xd4, 0x31, 0xde, 0x44, 0x93, 0xff, 0x43, 0x39,
- 0x8c, 0x4f, 0xcd, 0x56, 0xc3, 0x38, 0xfd, 0x21, 0x39, 0xee, 0xeb, 0xb3,
- 0xf5, 0x09, 0xf8, 0xeb, 0x9d, 0xc0, 0x60, 0x0f, 0x3d, 0x0d, 0x9b, 0x71,
- 0xdf, 0x21, 0xb1, 0xef, 0xb3, 0x64, 0x76, 0x14, 0x74, 0x8f, 0x0e, 0x42,
- 0x3f, 0xf7, 0xc3, 0xdf, 0x56, 0x7e, 0xb0, 0xc1, 0x9c, 0xd4, 0xfb, 0x71,
- 0xf9, 0xf3, 0x8d, 0x10, 0x7b, 0xb6, 0x01, 0xa7, 0x32, 0x56, 0x98, 0x54,
- 0xb8, 0xd9, 0xbe, 0x8d, 0xeb, 0xdf, 0x25, 0xf9, 0xdb, 0xc8, 0x53, 0x3e,
- 0x03, 0xa6, 0x51, 0xd7, 0x71, 0x49, 0x9f, 0xe1, 0xba, 0xb5, 0x9b, 0x18,
- 0x2f, 0x6d, 0x06, 0xcb, 0xbf, 0xec, 0xdc, 0xc6, 0x96, 0x8c, 0x01, 0x59,
- 0xe3, 0x9d, 0x3b, 0x79, 0x69, 0xa1, 0xdc, 0x87, 0xf9, 0x04, 0x94, 0xff,
- 0x4b, 0xa0, 0x9f, 0xf6, 0x9e, 0xb6, 0xc1, 0xb5, 0xa2, 0x07, 0x89, 0x05,
- 0x22, 0xd2, 0xe6, 0x71, 0x9f, 0xd2, 0x4e, 0x1d, 0xc1, 0x9c, 0x88, 0x0d,
- 0x3e, 0xdf, 0x2d, 0xdd, 0xc4, 0x07, 0x49, 0x3c, 0xbb, 0x8e, 0x7a, 0xbc,
- 0x67, 0x3d, 0xf8, 0x52, 0xcb, 0x62, 0x45, 0x0e, 0xce, 0x41, 0xae, 0x3d,
- 0x5c, 0x1f, 0x47, 0x39, 0x8c, 0xf2, 0x71, 0x94, 0xd4, 0x4f, 0x57, 0x65,
- 0x56, 0xc7, 0x7f, 0x14, 0x0e, 0xa1, 0xed, 0x9c, 0xf6, 0xa9, 0x53, 0x4f,
- 0x8a, 0x3d, 0xf6, 0x41, 0x3c, 0xa3, 0x1f, 0x8f, 0x91, 0xee, 0xff, 0x82,
- 0x89, 0x3f, 0x6d, 0xc7, 0xac, 0x8c, 0x4e, 0x5e, 0x51, 0x31, 0xfc, 0xf5,
- 0xa7, 0xe8, 0x23, 0xff, 0x54, 0x1e, 0xbd, 0x29, 0xb6, 0xb7, 0x1d, 0xcb,
- 0x1a, 0x2f, 0x28, 0x5d, 0x4c, 0x7e, 0x40, 0x0f, 0xbb, 0x19, 0xf9, 0xfa,
- 0x46, 0x0f, 0xf4, 0x5b, 0x5c, 0xde, 0x58, 0x09, 0x80, 0xd5, 0xb9, 0x37,
- 0x47, 0x60, 0x33, 0x5d, 0x83, 0x03, 0xe2, 0xf2, 0x2f, 0x90, 0xf3, 0x7f,
- 0xae, 0x24, 0xe4, 0xcd, 0x4a, 0x10, 0x5c, 0xf3, 0xd3, 0xfe, 0x61, 0x91,
- 0xbb, 0xdb, 0x74, 0x0e, 0x00, 0x6a, 0xe8, 0x73, 0xfb, 0x79, 0x75, 0x76,
- 0x8f, 0x7a, 0xd0, 0x3b, 0x6f, 0x36, 0x7e, 0x01, 0xbe, 0xea, 0x3e, 0x5b,
- 0xdb, 0x6e, 0xe9, 0xb6, 0x3c, 0xfb, 0x4f, 0x6c, 0x4a, 0xda, 0xe4, 0x10,
- 0xa4, 0xd1, 0x36, 0x3d, 0xbc, 0xb6, 0xdd, 0x9e, 0x6d, 0x33, 0xca, 0x5e,
- 0x94, 0xd6, 0x7b, 0xa5, 0xfe, 0x17, 0xdc, 0x2b, 0xf0, 0x63, 0xd5, 0x99,
- 0x11, 0x4b, 0x9e, 0x55, 0xb0, 0x4e, 0xd2, 0xbc, 0x1f, 0x30, 0xef, 0x3d,
- 0x85, 0x5f, 0x9d, 0xed, 0x18, 0x20, 0x7c, 0xdb, 0xe5, 0xd4, 0x69, 0x65,
- 0x47, 0x18, 0xb7, 0x5d, 0xa6, 0x7f, 0x4f, 0x5d, 0x3e, 0x69, 0xec, 0x09,
- 0x7c, 0x8f, 0xda, 0x71, 0x99, 0x51, 0xd7, 0x9f, 0x90, 0x47, 0x5c, 0xf2,
- 0xee, 0xa4, 0xf8, 0x63, 0x1a, 0x4b, 0x89, 0x89, 0x09, 0x76, 0x78, 0x27,
- 0xe1, 0x9b, 0x29, 0x7b, 0xec, 0x7e, 0x4c, 0xc8, 0xe3, 0x36, 0xda, 0x8f,
- 0x9c, 0x6d, 0x01, 0x83, 0x3d, 0x99, 0x91, 0xe7, 0x36, 0x50, 0x17, 0xeb,
- 0xf5, 0x31, 0xc1, 0xfd, 0xb3, 0xb8, 0x67, 0x1c, 0xed, 0xe9, 0xb8, 0x44,
- 0x9e, 0xee, 0x97, 0xf6, 0x33, 0xc4, 0x29, 0xe4, 0x69, 0x42, 0xda, 0xce,
- 0x10, 0x2f, 0x33, 0xb6, 0x9c, 0x1a, 0xbf, 0x21, 0x8c, 0xe5, 0xa4, 0xfc,
- 0x2b, 0xf8, 0x6d, 0x61, 0xde, 0xed, 0xf0, 0xc3, 0xdb, 0x2e, 0xe8, 0x76,
- 0xf6, 0xb9, 0x3e, 0x00, 0xc3, 0x98, 0xd8, 0xf0, 0x59, 0xec, 0x0b, 0x2c,
- 0xbb, 0x50, 0xf2, 0x1d, 0x48, 0x3a, 0x37, 0x60, 0xde, 0x41, 0x37, 0x5e,
- 0xe0, 0xf8, 0xb0, 0x8f, 0xbe, 0xce, 0x17, 0x1d, 0x18, 0xf2, 0xe5, 0xd2,
- 0x1a, 0x65, 0x93, 0x71, 0x74, 0x62, 0x97, 0x57, 0xc5, 0x5e, 0xca, 0x48,
- 0xe4, 0x4c, 0x06, 0x72, 0xe8, 0xc3, 0xee, 0x12, 0xf3, 0xd1, 0xd6, 0xe1,
- 0x39, 0xf0, 0x56, 0xfd, 0x29, 0xce, 0xe9, 0xaa, 0xd8, 0xf5, 0x5f, 0x65,
- 0xc3, 0xc2, 0x7d, 0xc1, 0x31, 0x4e, 0xc2, 0xfe, 0x46, 0xe5, 0x73, 0x71,
- 0xca, 0x8a, 0x96, 0xbd, 0xb4, 0x3d, 0xa4, 0x64, 0xb5, 0x48, 0xbb, 0xfc,
- 0xd4, 0xed, 0x7b, 0xe0, 0xa7, 0x9d, 0x2e, 0x6f, 0xcb, 0x18, 0xf3, 0x42,
- 0x03, 0xa9, 0x02, 0xef, 0xcc, 0x7b, 0x96, 0x2c, 0x78, 0x27, 0x15, 0x1e,
- 0x7c, 0x14, 0xed, 0x4f, 0x98, 0xf6, 0x0b, 0x32, 0x64, 0x64, 0x5d, 0xc5,
- 0x11, 0xa0, 0xc7, 0xb8, 0x66, 0xbc, 0xff, 0x2d, 0xf1, 0x7b, 0xb9, 0x9e,
- 0x27, 0x65, 0x60, 0x4c, 0xe3, 0x90, 0x92, 0x4d, 0x1c, 0xf2, 0xae, 0x71,
- 0x5a, 0x95, 0xcb, 0x57, 0xa8, 0xd0, 0xce, 0xec, 0x85, 0xfc, 0xc2, 0x27,
- 0xda, 0x08, 0x63, 0xb5, 0x6a, 0x5f, 0x25, 0x06, 0x6c, 0x4b, 0xbc, 0xa1,
- 0xa1, 0xe1, 0x12, 0xf0, 0xc9, 0x3c, 0x7c, 0x5e, 0xd2, 0xb1, 0x00, 0x3b,
- 0xb7, 0xe6, 0xff, 0x4b, 0x70, 0x22, 0x9e, 0x3a, 0x3d, 0xf3, 0xae, 0xf1,
- 0xfb, 0x30, 0x6e, 0xdf, 0x7c, 0x9e, 0xb2, 0x69, 0xfd, 0x61, 0xe3, 0x88,
- 0xd2, 0x91, 0x37, 0xe3, 0xae, 0x30, 0x7e, 0x3f, 0x7d, 0x53, 0x1c, 0xb5,
- 0xd4, 0x08, 0x73, 0xf0, 0x42, 0x3d, 0x7f, 0x1a, 0xba, 0x3a, 0x22, 0x37,
- 0x80, 0x41, 0x27, 0xc0, 0xbb, 0x73, 0x6b, 0x65, 0xeb, 0x4a, 0x45, 0xd4,
- 0x7d, 0xc1, 0x67, 0x4e, 0xde, 0x47, 0xc0, 0x3b, 0xd8, 0x98, 0x0d, 0xc7,
- 0x9c, 0x29, 0x39, 0x78, 0x66, 0x2b, 0x9f, 0xb9, 0xa4, 0x74, 0xf3, 0xe1,
- 0x2e, 0x9e, 0xb9, 0x5c, 0x5a, 0xfe, 0x28, 0xee, 0x79, 0xf6, 0x71, 0xa4,
- 0xe5, 0xf9, 0x66, 0x4f, 0x54, 0x63, 0x37, 0xf0, 0x5d, 0xf3, 0xcd, 0x01,
- 0xbf, 0x8b, 0x8c, 0xe7, 0x35, 0x88, 0x83, 0x3b, 0x0d, 0x0e, 0x26, 0xce,
- 0xc2, 0x7a, 0x6d, 0x30, 0x0e, 0x43, 0xac, 0x15, 0x57, 0x7e, 0xa1, 0xc2,
- 0x5e, 0xfe, 0x31, 0x93, 0x7f, 0x71, 0xab, 0x5c, 0xcd, 0x56, 0x42, 0x3c,
- 0xd7, 0x2c, 0x57, 0xee, 0x6f, 0x20, 0x57, 0x13, 0x5d, 0x3a, 0xdf, 0x81,
- 0x36, 0xcd, 0x92, 0x37, 0xaa, 0x7b, 0x64, 0xab, 0xfa, 0x20, 0x70, 0xb4,
- 0xca, 0xfb, 0x90, 0x2d, 0xac, 0xc5, 0x83, 0x95, 0x49, 0x99, 0xa8, 0xc6,
- 0xe4, 0x5a, 0xd5, 0x7e, 0xa0, 0x5d, 0x18, 0x07, 0x27, 0x36, 0xf9, 0x1b,
- 0xa5, 0xdf, 0x7e, 0xe0, 0xef, 0xb4, 0xe7, 0xb9, 0xca, 0x0d, 0xb4, 0x9f,
- 0xad, 0xde, 0x2b, 0x25, 0xd5, 0xbe, 0x7e, 0xcb, 0x18, 0x51, 0x33, 0x46,
- 0xbd, 0x7a, 0x97, 0x89, 0xdf, 0x95, 0xe5, 0x12, 0xb0, 0xaf, 0x7d, 0x96,
- 0xf3, 0xbd, 0xc3, 0xe4, 0x77, 0xc5, 0x9a, 0xfc, 0x91, 0xa8, 0xf1, 0x47,
- 0x7e, 0x06, 0x3d, 0xfe, 0x94, 0x44, 0xbd, 0xb0, 0x2f, 0xe6, 0x6a, 0x27,
- 0x4c, 0x6e, 0xc7, 0x5e, 0xf4, 0x75, 0x10, 0xef, 0xee, 0xc3, 0xef, 0x49,
- 0xd4, 0xa3, 0xbd, 0xe2, 0xd9, 0x28, 0x31, 0x02, 0xcf, 0xeb, 0x7a, 0x51,
- 0xaf, 0x03, 0x58, 0x72, 0xbf, 0x79, 0x16, 0xf6, 0x11, 0xd6, 0x0d, 0xef,
- 0x9b, 0xcf, 0x53, 0x59, 0x2f, 0xd9, 0x74, 0x9e, 0x0a, 0x45, 0xa5, 0xda,
- 0x86, 0xb6, 0x36, 0xb4, 0x51, 0xc9, 0x26, 0x1b, 0xf5, 0x56, 0x53, 0x9e,
- 0xa7, 0xc6, 0x61, 0x57, 0x33, 0x9c, 0x6b, 0x5f, 0x53, 0x0e, 0x4a, 0xaa,
- 0x4c, 0xfb, 0xc8, 0x78, 0xdf, 0x7a, 0x25, 0xb4, 0x1f, 0xb9, 0x1e, 0x9e,
- 0x5b, 0x2c, 0xfa, 0x2a, 0x16, 0x97, 0x8c, 0x64, 0x69, 0x7f, 0xfc, 0xd8,
- 0x16, 0x70, 0x65, 0x5d, 0x9d, 0xeb, 0x47, 0xf0, 0x83, 0x5d, 0x76, 0x2c,
- 0x71, 0x3d, 0x3e, 0x2b, 0x1b, 0xbd, 0x03, 0x5d, 0x6e, 0xab, 0x3a, 0xc9,
- 0xbc, 0xdf, 0x67, 0xee, 0x13, 0xb2, 0x56, 0xf9, 0x50, 0xbf, 0x9d, 0xfd,
- 0x5f, 0xb7, 0xe7, 0x33, 0x3d, 0x3c, 0x7f, 0xc2, 0x33, 0xe2, 0xf5, 0xd7,
- 0x54, 0x4e, 0xa3, 0xc6, 0x46, 0x0e, 0xcf, 0x2f, 0x81, 0x73, 0x7e, 0x04,
- 0x9e, 0x84, 0xb8, 0xfb, 0x75, 0x99, 0x50, 0x98, 0xaa, 0x0d, 0xb6, 0xd2,
- 0x60, 0xaa, 0xee, 0x14, 0x30, 0x15, 0xdb, 0xb7, 0xe2, 0x40, 0xbd, 0x97,
- 0x22, 0x59, 0x1d, 0x57, 0x6d, 0x89, 0x15, 0x5b, 0x8f, 0x64, 0xc4, 0x3a,
- 0x81, 0x1f, 0x65, 0xd4, 0x5e, 0x7a, 0x4d, 0xbc, 0xa5, 0x54, 0x95, 0xf9,
- 0xb1, 0x0b, 0x1b, 0x3c, 0xc7, 0x03, 0x16, 0x4b, 0x50, 0x96, 0xf9, 0x6e,
- 0x1a, 0x63, 0xbc, 0x06, 0xff, 0x73, 0x0f, 0xf8, 0x6d, 0x1b, 0x1e, 0xf9,
- 0x26, 0x46, 0x11, 0x63, 0x2c, 0x18, 0x7b, 0x71, 0x5e, 0x61, 0x89, 0x52,
- 0x7c, 0x11, 0xe5, 0x0f, 0x0d, 0x76, 0x78, 0xbd, 0x2b, 0x3c, 0xb7, 0x2f,
- 0xc5, 0xbf, 0x84, 0xe7, 0xaf, 0xc3, 0x1f, 0x8c, 0x4a, 0x9b, 0x5a, 0xb3,
- 0x10, 0x3b, 0xff, 0x3d, 0xea, 0x90, 0xfe, 0x3b, 0x4d, 0x7e, 0x0d, 0xf3,
- 0x06, 0xd8, 0x1f, 0xec, 0x96, 0xca, 0xe1, 0xca, 0xa1, 0x64, 0x3b, 0xb6,
- 0x79, 0x05, 0x75, 0x73, 0x98, 0x37, 0x9f, 0x4b, 0x5f, 0x44, 0x9a, 0x9f,
- 0x7f, 0x14, 0xcf, 0x29, 0x87, 0xef, 0x37, 0x72, 0x18, 0xbe, 0xcb, 0x1b,
- 0x3e, 0xdd, 0x8e, 0x31, 0xc8, 0xab, 0x66, 0xba, 0x38, 0x9f, 0x70, 0xcd,
- 0xdb, 0x4c, 0xae, 0x01, 0x9f, 0xbd, 0xdf, 0x3c, 0x73, 0xcc, 0x1c, 0x3f,
- 0xde, 0x65, 0xb0, 0x04, 0x76, 0x7b, 0xb8, 0x1f, 0x49, 0x67, 0xac, 0x09,
- 0xb3, 0xfe, 0x61, 0xef, 0x4e, 0x1e, 0x26, 0x65, 0xce, 0x53, 0xb1, 0x23,
- 0xe6, 0x8f, 0xe5, 0x6c, 0x9d, 0xb3, 0xf1, 0x8d, 0x9b, 0xe2, 0xdd, 0x4a,
- 0xd7, 0xf2, 0x0c, 0xa4, 0x6a, 0x67, 0xdb, 0x7f, 0xed, 0xbc, 0xbb, 0x48,
- 0x36, 0x6c, 0x07, 0x9c, 0xa6, 0xda, 0x24, 0x65, 0xae, 0xf1, 0x6e, 0x39,
- 0x7a, 0xca, 0xbf, 0x30, 0x79, 0x10, 0xfb, 0x55, 0x1e, 0x04, 0xf5, 0xe2,
- 0x5a, 0x35, 0x02, 0x5e, 0xf7, 0x31, 0x37, 0x0a, 0x7e, 0x4c, 0x0c, 0x73,
- 0x45, 0x5f, 0xf1, 0xf7, 0xab, 0x5c, 0xa9, 0x88, 0x17, 0xe6, 0xf5, 0x72,
- 0x1f, 0xde, 0xa1, 0xde, 0x7f, 0x7d, 0xa5, 0x9d, 0xf9, 0xaa, 0x28, 0xb9,
- 0x47, 0x7f, 0x09, 0xfd, 0x18, 0x95, 0x42, 0xd5, 0x03, 0xfe, 0x89, 0x52,
- 0x2e, 0xf1, 0x7c, 0x3f, 0xfc, 0x61, 0xc1, 0x3e, 0x69, 0x83, 0x6f, 0xa2,
- 0x7c, 0x1d, 0xcc, 0x68, 0x87, 0x0e, 0x62, 0x70, 0x9d, 0x1f, 0x1a, 0x40,
- 0x87, 0xcf, 0xcb, 0xda, 0xf8, 0xa2, 0xd4, 0xc7, 0x9b, 0x31, 0x2c, 0x30,
- 0xaa, 0x5b, 0x0e, 0xea, 0x9e, 0x8a, 0x65, 0x1a, 0xdd, 0x72, 0xc2, 0xe0,
- 0x4e, 0xae, 0x83, 0x2d, 0x85, 0xd1, 0x05, 0x25, 0x5f, 0x75, 0xb5, 0x1e,
- 0x8e, 0x75, 0x59, 0xe5, 0xf9, 0x72, 0x0c, 0xe6, 0xfa, 0x46, 0x0c, 0x0e,
- 0x3b, 0x65, 0xd6, 0xd5, 0xd9, 0x1b, 0xe6, 0xcc, 0x47, 0xb3, 0x87, 0x99,
- 0xdb, 0x01, 0x6c, 0x3d, 0x3d, 0x35, 0x5b, 0xa1, 0x2d, 0x0c, 0x82, 0xba,
- 0xbf, 0x89, 0x1e, 0x7f, 0xac, 0x30, 0xe4, 0x96, 0x68, 0xdd, 0xbe, 0xa0,
- 0x72, 0x66, 0x27, 0xa7, 0xf2, 0x2a, 0x5e, 0xd8, 0x7c, 0x76, 0xf3, 0x5e,
- 0xe7, 0x36, 0x31, 0xf8, 0xfe, 0x1d, 0x66, 0xfd, 0x63, 0x4e, 0xa9, 0xd2,
- 0xe5, 0xcc, 0xaa, 0xb3, 0xb5, 0xac, 0xf9, 0x16, 0x27, 0x37, 0x95, 0x6e,
- 0x7c, 0x76, 0x2f, 0xb1, 0x3e, 0xcf, 0x31, 0x0a, 0x15, 0x9e, 0xe3, 0xe8,
- 0xf7, 0x69, 0xf3, 0x7e, 0xa0, 0xa1, 0xde, 0xa9, 0x78, 0x23, 0x63, 0x8c,
- 0xed, 0x28, 0x6f, 0x54, 0xa8, 0x6b, 0xd0, 0x7f, 0x5c, 0xcf, 0x21, 0x92,
- 0x2d, 0xc2, 0x3f, 0x25, 0x7d, 0x47, 0xa6, 0xf2, 0x2b, 0xcc, 0xdb, 0x7a,
- 0x68, 0xea, 0x1a, 0xfc, 0xa5, 0x73, 0x9e, 0xce, 0x2b, 0x5f, 0x67, 0x1c,
- 0x8c, 0xed, 0x54, 0x9f, 0x45, 0x13, 0xab, 0x3d, 0x3c, 0x35, 0xb8, 0x1e,
- 0x91, 0x27, 0x4c, 0x1f, 0xbc, 0x4f, 0x6e, 0xfb, 0x52, 0x4a, 0xff, 0xc1,
- 0x3f, 0x18, 0x85, 0x7f, 0xd0, 0x09, 0x5d, 0x4f, 0x3f, 0x83, 0xf8, 0xbb,
- 0x13, 0x7b, 0x85, 0xe3, 0xdc, 0xa5, 0xc6, 0x89, 0x60, 0x9c, 0x59, 0xf8,
- 0x38, 0x8c, 0x47, 0xe6, 0x3d, 0x07, 0x58, 0x02, 0xb6, 0xde, 0x63, 0xbc,
- 0xdc, 0xc6, 0x9c, 0x87, 0xa1, 0x27, 0x98, 0xa3, 0x32, 0x11, 0xe6, 0x0d,
- 0xa1, 0x9d, 0x6f, 0xda, 0x1d, 0x44, 0x3b, 0xfa, 0x07, 0x6c, 0x2b, 0xb7,
- 0xd9, 0x32, 0xa8, 0xb0, 0x81, 0xf6, 0x6b, 0x48, 0x43, 0x0d, 0x73, 0xa5,
- 0x5d, 0xc5, 0x9e, 0x53, 0xf3, 0x3a, 0xa8, 0xda, 0x59, 0xd9, 0x31, 0xd0,
- 0x4e, 0xfc, 0x87, 0xbe, 0x97, 0x75, 0xbc, 0xb3, 0xa0, 0xe4, 0x08, 0x72,
- 0x32, 0x1e, 0xe6, 0xbd, 0xe8, 0x76, 0x61, 0xfd, 0x81, 0xf5, 0x86, 0x19,
- 0xff, 0xe7, 0x41, 0xee, 0x68, 0xa7, 0xf2, 0xad, 0x5f, 0xbe, 0x29, 0x07,
- 0x8d, 0x6d, 0xc2, 0x3a, 0x91, 0x30, 0x2f, 0xb9, 0x89, 0xe6, 0xac, 0x59,
- 0x73, 0xb6, 0x63, 0x6c, 0x58, 0xe5, 0xe2, 0xf3, 0x99, 0x33, 0x97, 0x61,
- 0x1f, 0xcd, 0x67, 0x4d, 0xa3, 0xc0, 0x19, 0xda, 0x86, 0x94, 0x37, 0x3c,
- 0xd8, 0xeb, 0x36, 0xac, 0x1d, 0x6d, 0xc2, 0xa0, 0xf1, 0x2d, 0xde, 0x2b,
- 0xce, 0xca, 0x73, 0xcc, 0x51, 0xf8, 0xf5, 0x61, 0x7b, 0xae, 0x63, 0x6e,
- 0xea, 0x5a, 0xc5, 0x93, 0x53, 0xcb, 0x3a, 0x3f, 0x4c, 0xf3, 0x81, 0x3a,
- 0x9b, 0x6b, 0x9b, 0x94, 0x59, 0x8f, 0xb1, 0x9c, 0xa4, 0xbc, 0xe2, 0x35,
- 0xe7, 0x39, 0xa1, 0xfe, 0xc6, 0xa8, 0xc9, 0xc7, 0x3e, 0x88, 0xf9, 0x13,
- 0x37, 0x6a, 0x59, 0x3a, 0x00, 0x3b, 0xf4, 0x77, 0x0e, 0x70, 0x21, 0xf6,
- 0xd3, 0x75, 0xa7, 0x79, 0x7e, 0xdb, 0xf9, 0xdf, 0x4a, 0x2e, 0x1d, 0xc8,
- 0xc8, 0xe2, 0x36, 0xdf, 0xe1, 0xb7, 0xdf, 0x35, 0x04, 0x7d, 0x6f, 0x49,
- 0x71, 0xd4, 0x4b, 0x2c, 0xf0, 0x5c, 0xc3, 0x1d, 0x01, 0xca, 0xa7, 0x1f,
- 0x9d, 0x04, 0xbd, 0xbc, 0x1e, 0x04, 0x3e, 0x62, 0x4e, 0x22, 0xee, 0x99,
- 0x13, 0x18, 0xf7, 0x40, 0xaf, 0xab, 0xce, 0x2b, 0xb4, 0xce, 0xfe, 0xfe,
- 0x5e, 0xe6, 0xc0, 0xf5, 0x78, 0xe1, 0xda, 0xab, 0xef, 0xda, 0xd0, 0x77,
- 0xc4, 0xbc, 0x9f, 0xd8, 0xe6, 0xbf, 0xf4, 0xb1, 0xdc, 0xce, 0x35, 0x33,
- 0xb1, 0x17, 0xd6, 0x1f, 0x57, 0xb4, 0xcc, 0x42, 0x57, 0xcf, 0xa9, 0xf9,
- 0xdc, 0x0f, 0x59, 0x88, 0xc8, 0xfc, 0xb6, 0xfc, 0xde, 0x0f, 0xf9, 0xdd,
- 0xc3, 0x14, 0xcf, 0x5d, 0x64, 0x2d, 0x94, 0x31, 0xca, 0x17, 0x65, 0xeb,
- 0xe3, 0xdd, 0xdc, 0x73, 0xe5, 0xed, 0x75, 0x77, 0x94, 0xcd, 0x4d, 0xda,
- 0xe1, 0xba, 0xf3, 0x7a, 0xb7, 0xdc, 0xaa, 0x70, 0x7f, 0x64, 0x7e, 0x83,
- 0xb5, 0xf5, 0xcd, 0xda, 0x66, 0x9a, 0xbe, 0x83, 0x08, 0xfb, 0x63, 0x0c,
- 0x94, 0x36, 0x88, 0xe7, 0x50, 0xed, 0x52, 0x56, 0x32, 0x68, 0x29, 0x6c,
- 0x9d, 0x73, 0xf3, 0x49, 0xc6, 0xbc, 0x8f, 0xc9, 0xbf, 0x03, 0xcd, 0xb9,
- 0xe1, 0xa8, 0xe8, 0xb6, 0x33, 0xe0, 0xf7, 0xa6, 0x0b, 0x7f, 0x90, 0x67,
- 0xd6, 0x15, 0x47, 0xce, 0xa9, 0x73, 0x57, 0xec, 0xd1, 0x4e, 0x47, 0x16,
- 0xbd, 0xed, 0x73, 0x78, 0xa9, 0xa1, 0xce, 0x1a, 0xde, 0x3d, 0xb1, 0x4d,
- 0x1b, 0xfd, 0x09, 0xf8, 0x52, 0xde, 0xcf, 0x83, 0x52, 0xfc, 0xa6, 0xba,
- 0x46, 0xaf, 0x33, 0x4e, 0xc3, 0xf3, 0x01, 0x57, 0x0a, 0xf0, 0x0b, 0x0b,
- 0xf0, 0x09, 0x0b, 0x4a, 0x2f, 0x30, 0x6e, 0xc3, 0x18, 0x5b, 0x19, 0x3e,
- 0x48, 0x39, 0x68, 0xf7, 0x4e, 0xaa, 0x18, 0xe2, 0xa5, 0x8d, 0x54, 0xb9,
- 0x2c, 0x5e, 0xf2, 0xc1, 0xed, 0x7c, 0xba, 0xee, 0x72, 0x2c, 0xdb, 0x1c,
- 0x87, 0x4b, 0xaa, 0x5c, 0xb4, 0x0e, 0x60, 0xe4, 0xe3, 0xd0, 0xd5, 0xcf,
- 0xfb, 0x8c, 0xbf, 0xdd, 0x49, 0x7e, 0x7f, 0x95, 0x93, 0xb4, 0x87, 0x46,
- 0xc5, 0xbb, 0xe0, 0x0d, 0x3f, 0x28, 0xf4, 0x3f, 0x52, 0xc9, 0x23, 0xe4,
- 0xdb, 0xf6, 0x37, 0x0d, 0xa1, 0x7d, 0x1d, 0x95, 0xc1, 0x0b, 0xaf, 0xab,
- 0x33, 0x8e, 0x4f, 0xf8, 0xad, 0xb2, 0xa1, 0xe2, 0x77, 0xa3, 0x3d, 0x32,
- 0x08, 0xdf, 0x57, 0x60, 0xa1, 0xf8, 0x8d, 0x83, 0x05, 0xdf, 0x43, 0xdd,
- 0xcb, 0x74, 0x23, 0x69, 0xf2, 0x54, 0x69, 0x5f, 0x19, 0xdf, 0xd3, 0x79,
- 0x7a, 0xcc, 0x4d, 0x65, 0xfe, 0x64, 0x51, 0xe5, 0xeb, 0x31, 0xd6, 0xc7,
- 0x58, 0x1e, 0xe3, 0x7d, 0x8c, 0xdb, 0xe9, 0x5c, 0xbd, 0x89, 0xc6, 0x6e,
- 0xb1, 0xbd, 0x30, 0x5f, 0x52, 0xdb, 0xad, 0xad, 0xcc, 0x3e, 0xd8, 0x3a,
- 0x57, 0xc5, 0x4e, 0x4a, 0x6e, 0x8f, 0x1c, 0x1b, 0x6e, 0x07, 0xcf, 0x7b,
- 0x55, 0x3e, 0x9d, 0xed, 0xdd, 0x0f, 0x1c, 0xcb, 0xf8, 0x1c, 0xb1, 0x69,
- 0xc8, 0xe7, 0x7b, 0xf0, 0xec, 0x1d, 0xf0, 0x9e, 0xcf, 0x80, 0x5b, 0x95,
- 0x1d, 0xfa, 0xbc, 0x6c, 0x55, 0x98, 0x03, 0x5f, 0xdb, 0x97, 0x57, 0xeb,
- 0x41, 0xdf, 0x3c, 0xd4, 0x4d, 0x61, 0xfe, 0x28, 0x7d, 0x2a, 0xd7, 0x9c,
- 0x93, 0xd3, 0x37, 0xef, 0x85, 0xbf, 0x4e, 0xfd, 0x63, 0xa9, 0xb1, 0xae,
- 0x47, 0x3e, 0x20, 0xe5, 0xda, 0x6e, 0x67, 0xfe, 0x41, 0xf0, 0x0d, 0x5f,
- 0xe5, 0xac, 0xc2, 0x9f, 0xd4, 0x6b, 0xac, 0xbf, 0x8f, 0x74, 0x76, 0xf2,
- 0xcb, 0xe3, 0xda, 0x67, 0xcc, 0xf5, 0x02, 0xb3, 0x78, 0xa7, 0xbb, 0x77,
- 0xb0, 0xf3, 0x2f, 0x0d, 0xae, 0x25, 0x6e, 0xee, 0x55, 0xd8, 0xc0, 0xae,
- 0x87, 0x72, 0xc2, 0x7c, 0x1f, 0x62, 0xea, 0x03, 0x92, 0xab, 0x41, 0x6f,
- 0xf6, 0xf1, 0xfe, 0x47, 0xa6, 0x2d, 0xaf, 0x03, 0x39, 0x3c, 0xd6, 0x7a,
- 0x96, 0x3f, 0xae, 0x71, 0x7d, 0x67, 0x78, 0x9e, 0x1f, 0xe6, 0xbc, 0xdf,
- 0x94, 0x5b, 0x0b, 0x79, 0x0a, 0x69, 0xd0, 0x63, 0x4d, 0x80, 0xde, 0x7a,
- 0x35, 0x21, 0xbd, 0x1e, 0xf3, 0x84, 0x22, 0x32, 0xd6, 0x9b, 0x82, 0x13,
- 0xaf, 0xe9, 0xa9, 0xd7, 0x60, 0xf3, 0xab, 0x21, 0x9d, 0x1a, 0xe3, 0xd7,
- 0x6b, 0x7c, 0x9f, 0xc4, 0x58, 0xed, 0x32, 0xd6, 0x47, 0x3e, 0xb7, 0xd2,
- 0x91, 0x34, 0xf9, 0xdc, 0xad, 0xcf, 0xef, 0x6b, 0xa2, 0xef, 0xd6, 0xef,
- 0x4a, 0xf3, 0x8c, 0x8b, 0xad, 0xd0, 0x3f, 0x21, 0x8d, 0xbd, 0xd0, 0x73,
- 0x98, 0xa3, 0x1f, 0xfa, 0x1a, 0x21, 0x5f, 0x42, 0x1f, 0x25, 0xaa, 0xe4,
- 0x62, 0x36, 0xc3, 0xb9, 0x44, 0x8d, 0xcf, 0x42, 0xba, 0x14, 0x6d, 0x11,
- 0x9e, 0x25, 0x46, 0xbd, 0xcf, 0xec, 0xd3, 0xeb, 0xff, 0xa4, 0x99, 0xaf,
- 0x6b, 0xea, 0xb0, 0xaf, 0xfd, 0x68, 0xff, 0xb5, 0x00, 0x63, 0x31, 0x08,
- 0x87, 0xfd, 0x1f, 0x62, 0xf7, 0xfd, 0xba, 0xaf, 0xce, 0x10, 0xbf, 0x87,
- 0xdf, 0xa1, 0x91, 0x4e, 0xee, 0xaf, 0x90, 0x87, 0xec, 0xa3, 0xd7, 0xc4,
- 0x5c, 0x49, 0x43, 0x47, 0x0b, 0x0d, 0x29, 0xff, 0x66, 0x1d, 0x77, 0x4f,
- 0xd3, 0xdc, 0x29, 0x6b, 0xdd, 0xb2, 0x50, 0xed, 0x94, 0xf9, 0xaa, 0xf2,
- 0x75, 0x86, 0x45, 0x88, 0xed, 0xb8, 0x2f, 0x55, 0x2e, 0xb3, 0xc9, 0x99,
- 0x0c, 0xf7, 0x67, 0x37, 0xea, 0xd1, 0x86, 0xa0, 0xac, 0x69, 0xfd, 0x54,
- 0x93, 0x5b, 0xbf, 0xd3, 0x98, 0x6b, 0xb4, 0xe6, 0xe3, 0x5d, 0x6f, 0xca,
- 0xc7, 0x6b, 0xce, 0x7f, 0x2a, 0xcb, 0x23, 0x07, 0x3b, 0x64, 0xe0, 0x6c,
- 0xa7, 0x91, 0xd1, 0xfb, 0xcd, 0x38, 0x18, 0x6f, 0x69, 0x5c, 0x06, 0x96,
- 0xbe, 0x28, 0xa5, 0x69, 0x95, 0xff, 0xde, 0xf4, 0xfd, 0xc3, 0xa0, 0xf9,
- 0xfe, 0x29, 0x67, 0x31, 0x17, 0xa6, 0xb0, 0x84, 0xf5, 0x3a, 0x98, 0x1a,
- 0x4e, 0xda, 0xfc, 0x46, 0xf7, 0x31, 0x19, 0x58, 0x1d, 0x97, 0xf4, 0x12,
- 0x31, 0x03, 0xb3, 0x01, 0x52, 0x2a, 0x2e, 0x9a, 0xbe, 0xa8, 0xfb, 0xf3,
- 0x96, 0xf8, 0x3e, 0x0d, 0xbc, 0xca, 0xf7, 0x85, 0x44, 0x44, 0x65, 0x0c,
- 0x7c, 0x10, 0xf2, 0xd4, 0x66, 0xf0, 0x80, 0x23, 0xf9, 0x25, 0xb6, 0x27,
- 0xf6, 0xf8, 0x47, 0xac, 0x59, 0x21, 0x69, 0x0b, 0xdb, 0xa8, 0xfe, 0x70,
- 0x1d, 0xc6, 0xd3, 0xc9, 0xeb, 0x51, 0x59, 0x6f, 0x78, 0xd8, 0x13, 0xfa,
- 0x9b, 0x89, 0x52, 0x2d, 0xcc, 0x27, 0x7d, 0xc4, 0xc4, 0x00, 0x34, 0x8d,
- 0xc5, 0x4a, 0xab, 0xec, 0x3d, 0x63, 0xbe, 0x9d, 0xe8, 0x50, 0x67, 0x68,
- 0x4d, 0xfa, 0xcf, 0xd4, 0xbf, 0xdd, 0x65, 0xde, 0x80, 0x08, 0xdf, 0x37,
- 0xf9, 0x24, 0xf1, 0xb8, 0xda, 0x07, 0x03, 0xf5, 0xb0, 0xde, 0xa8, 0xab,
- 0x7d, 0x60, 0xf2, 0x29, 0x6b, 0x68, 0x1e, 0x83, 0xcf, 0xc3, 0x67, 0x07,
- 0xd0, 0x96, 0xeb, 0x84, 0xb2, 0x7e, 0x40, 0xe5, 0x39, 0x46, 0xb2, 0x47,
- 0xcc, 0x59, 0x5a, 0x9f, 0x1a, 0xcb, 0xcd, 0xb2, 0xff, 0x50, 0x37, 0x74,
- 0x34, 0x8d, 0xdf, 0x4a, 0x2f, 0x7d, 0xf8, 0x9f, 0x19, 0x79, 0xe1, 0x7b,
- 0xde, 0xb7, 0xd6, 0xf9, 0xa3, 0x7d, 0xe1, 0x7b, 0x67, 0xfb, 0x1b, 0x0c,
- 0xf2, 0x92, 0x67, 0x80, 0x28, 0x2f, 0x32, 0x97, 0x9d, 0xd7, 0x28, 0xcd,
- 0xb7, 0x25, 0xce, 0x12, 0x7f, 0xad, 0xfd, 0x38, 0xe8, 0x3b, 0xdc, 0xb3,
- 0xbb, 0xe5, 0x06, 0x51, 0x17, 0x9f, 0xb6, 0xb6, 0x2a, 0x8c, 0x5d, 0x94,
- 0xe5, 0x58, 0xa6, 0x5b, 0x66, 0xab, 0x36, 0xbf, 0x4d, 0x65, 0x2c, 0x96,
- 0x67, 0x95, 0x32, 0xa7, 0x74, 0xdc, 0x90, 0xe8, 0xef, 0x76, 0x3b, 0xa4,
- 0xe8, 0x52, 0x9e, 0x87, 0x64, 0xbd, 0x36, 0xdd, 0x94, 0x03, 0xdc, 0x66,
- 0xe4, 0xec, 0xef, 0xa2, 0xd2, 0xc9, 0x38, 0x52, 0xb8, 0xa7, 0x87, 0xa4,
- 0x58, 0x6b, 0x3e, 0x67, 0x60, 0x9e, 0x11, 0xe5, 0xb6, 0xbf, 0x69, 0xef,
- 0x31, 0x57, 0x0f, 0xb8, 0x2a, 0x4e, 0x9f, 0x95, 0xf5, 0xf6, 0x1a, 0x7b,
- 0xfb, 0x15, 0xac, 0xc7, 0xfb, 0x2d, 0xf1, 0x48, 0x1b, 0x6c, 0x84, 0xc9,
- 0x35, 0x3e, 0x1c, 0x2f, 0xc3, 0x3f, 0x1b, 0x32, 0xe3, 0xde, 0x81, 0x7b,
- 0xd6, 0xdd, 0x67, 0xde, 0xef, 0x37, 0xf7, 0x9d, 0xe6, 0x3e, 0x82, 0x7b,
- 0xe6, 0x8d, 0xb3, 0x4f, 0x96, 0xfc, 0x9e, 0x88, 0xdf, 0xeb, 0x64, 0x25,
- 0x7a, 0x11, 0xe8, 0xa9, 0xd1, 0x29, 0x9f, 0xae, 0x29, 0xfe, 0x5a, 0xde,
- 0x12, 0x01, 0xc1, 0x7e, 0x73, 0x7d, 0xeb, 0x1e, 0xfc, 0xdc, 0x4d, 0xdf,
- 0x4a, 0x55, 0x8c, 0xac, 0x34, 0xd3, 0x9b, 0x03, 0xad, 0xef, 0x96, 0x83,
- 0x45, 0x1b, 0xa5, 0xfd, 0xc6, 0x62, 0x45, 0xe7, 0x1a, 0x1d, 0x83, 0xdf,
- 0x78, 0xb8, 0xfa, 0xa8, 0xab, 0xf3, 0x62, 0xc2, 0x5c, 0xca, 0x4e, 0xcc,
- 0x6b, 0xc8, 0x9c, 0x5b, 0xb3, 0x2d, 0x73, 0x3a, 0xc3, 0xf3, 0x99, 0x66,
- 0xac, 0x4a, 0x5b, 0x44, 0x3b, 0xc3, 0xef, 0x9a, 0x7c, 0xd4, 0x5d, 0xa4,
- 0xae, 0x69, 0xca, 0xcd, 0xff, 0x52, 0x4b, 0x6e, 0x3e, 0xbf, 0xfb, 0x16,
- 0xf9, 0x6f, 0x0d, 0xc6, 0x95, 0x3a, 0x24, 0x72, 0x36, 0xcc, 0xc1, 0xe2,
- 0x1a, 0x13, 0x87, 0xf1, 0x7b, 0xef, 0xa9, 0x5d, 0x62, 0x4e, 0xa1, 0x9c,
- 0x7f, 0xc7, 0x65, 0x7e, 0xab, 0x9b, 0x0d, 0xe3, 0x54, 0xcc, 0xeb, 0x21,
- 0xe6, 0x3a, 0x60, 0x62, 0x0a, 0x7c, 0x57, 0x96, 0x9e, 0x83, 0x53, 0xdc,
- 0x1b, 0xbf, 0x1d, 0xd9, 0xce, 0xfd, 0x57, 0xe3, 0xc4, 0x35, 0x86, 0xe4,
- 0x77, 0xe3, 0x3e, 0xf6, 0xd5, 0x9e, 0xcd, 0xf0, 0x9b, 0x8c, 0xcb, 0x8d,
- 0x8c, 0xfa, 0xf6, 0x83, 0x67, 0x1e, 0x5b, 0x0d, 0xee, 0x3b, 0x7e, 0x23,
- 0x9e, 0x55, 0x39, 0x01, 0x5b, 0xe6, 0x9b, 0xe7, 0xab, 0x0d, 0xfd, 0x1d,
- 0xcb, 0xe2, 0xb2, 0xca, 0xcb, 0x07, 0x56, 0x4b, 0xe2, 0x3d, 0x73, 0xe8,
- 0xfa, 0x55, 0x2e, 0xc1, 0x7c, 0xe3, 0x53, 0x28, 0x3f, 0x2f, 0x6b, 0x15,
- 0x1d, 0x7f, 0x9d, 0x6f, 0x30, 0xa7, 0xc0, 0x55, 0x67, 0x44, 0x03, 0x4b,
- 0x45, 0x8c, 0x17, 0x7e, 0xb3, 0x1d, 0xc7, 0x33, 0xd2, 0x57, 0x36, 0x7b,
- 0x34, 0xcc, 0x05, 0xe9, 0xea, 0xa1, 0x4d, 0x28, 0x37, 0xba, 0x54, 0x1e,
- 0x82, 0xc6, 0x23, 0xc4, 0x7a, 0x31, 0xd4, 0xe5, 0x5c, 0x3b, 0x69, 0xaf,
- 0x02, 0xea, 0xa4, 0x34, 0xc6, 0xa9, 0xab, 0xdc, 0x44, 0xf2, 0xd9, 0x73,
- 0x4b, 0xf4, 0xd7, 0x94, 0x8e, 0x4f, 0x0d, 0xcf, 0x48, 0xc1, 0x8d, 0xc2,
- 0x17, 0x9b, 0x57, 0x7e, 0xce, 0xfd, 0xc0, 0xd0, 0x5d, 0x9b, 0x91, 0x2c,
- 0xe7, 0xc6, 0xb1, 0xe9, 0x87, 0xe8, 0xf9, 0xe8, 0x33, 0x02, 0xb1, 0xe6,
- 0xd5, 0xf7, 0x8f, 0x7c, 0xce, 0x78, 0x6f, 0xf8, 0xcd, 0x90, 0xfe, 0x26,
- 0x64, 0xa6, 0x71, 0x44, 0x4e, 0x55, 0xf6, 0xf2, 0x5b, 0x09, 0x7f, 0x0b,
- 0x7c, 0x3b, 0xd6, 0xe8, 0x52, 0xdf, 0xa5, 0xcc, 0x34, 0x98, 0x3f, 0x17,
- 0xda, 0x1e, 0xae, 0x55, 0xdc, 0x7c, 0x37, 0x91, 0x30, 0xdf, 0x4d, 0xf0,
- 0xdb, 0x8f, 0x1f, 0xed, 0x0d, 0xf7, 0xfb, 0xad, 0x38, 0x9c, 0x32, 0xf8,
- 0xa7, 0xf0, 0x0d, 0xc3, 0x3c, 0x4c, 0xe6, 0x8b, 0x06, 0xc1, 0x31, 0x9f,
- 0xf1, 0xdb, 0xe9, 0xc3, 0x6b, 0x98, 0xe3, 0x95, 0x1a, 0x78, 0x78, 0x94,
- 0xcf, 0x98, 0x37, 0xd6, 0x2e, 0xf9, 0xd1, 0x76, 0xea, 0xf2, 0xce, 0x35,
- 0x6f, 0xaf, 0x5c, 0xae, 0xc6, 0x55, 0x0e, 0x5c, 0x09, 0x38, 0xbf, 0x2e,
- 0x1f, 0xeb, 0xe1, 0xd9, 0xdd, 0x84, 0x6a, 0x1f, 0xee, 0x77, 0x1d, 0x37,
- 0x98, 0x58, 0xd7, 0xfa, 0xe4, 0x78, 0x06, 0xb8, 0xe5, 0x82, 0x58, 0x7f,
- 0x90, 0xe9, 0x87, 0xef, 0xcd, 0xb1, 0xd2, 0x68, 0x07, 0xd9, 0x49, 0x70,
- 0xaf, 0xbf, 0x13, 0xd4, 0x41, 0xef, 0x8d, 0x06, 0xf1, 0x3a, 0x30, 0xd4,
- 0x34, 0xdb, 0x64, 0xc5, 0x3e, 0xc3, 0x3a, 0xbd, 0x90, 0xbf, 0x28, 0xe6,
- 0xe3, 0xc0, 0x17, 0xd8, 0x27, 0x75, 0x97, 0xef, 0x1c, 0x7d, 0xa6, 0x12,
- 0x0f, 0xfd, 0x94, 0xef, 0x81, 0x7f, 0x49, 0xa5, 0x93, 0xc2, 0xf3, 0x4e,
- 0xe6, 0xb3, 0xce, 0x56, 0x27, 0xb1, 0x87, 0x1c, 0x83, 0xcd, 0x1c, 0xf4,
- 0xf1, 0xe1, 0x1e, 0x8d, 0x15, 0x78, 0x1e, 0xaa, 0xb1, 0x88, 0xb6, 0x31,
- 0x3c, 0xdf, 0x71, 0xe0, 0x0b, 0x84, 0xfb, 0xf2, 0x99, 0x7d, 0x37, 0x7f,
- 0x0b, 0x43, 0x1c, 0x93, 0x4e, 0x9c, 0xe7, 0x79, 0xdc, 0xc6, 0xc3, 0x32,
- 0x03, 0x9a, 0x4f, 0x9b, 0x79, 0x3e, 0x98, 0xf1, 0xe4, 0x7a, 0x8d, 0xe7,
- 0x95, 0x07, 0x50, 0x32, 0xd7, 0x91, 0x34, 0x8f, 0x98, 0x7c, 0xce, 0x2c,
- 0xe6, 0xfa, 0x98, 0xbc, 0x01, 0x7c, 0xfd, 0x66, 0x25, 0xed, 0x4f, 0xa8,
- 0x3c, 0xa4, 0x54, 0xe2, 0xb2, 0x8c, 0x24, 0xe9, 0x03, 0x96, 0xdd, 0x54,
- 0xe2, 0x3a, 0xe4, 0xe1, 0x46, 0xe5, 0x99, 0x1e, 0xfe, 0xaf, 0x8a, 0x3a,
- 0xec, 0xe1, 0x0d, 0x95, 0x83, 0x94, 0x62, 0xcc, 0x04, 0xf7, 0xfd, 0x26,
- 0x0f, 0x8a, 0xe3, 0xf0, 0x5d, 0xbf, 0xbc, 0x51, 0xd9, 0xb6, 0xbf, 0x1c,
- 0xc7, 0x7c, 0x03, 0xcf, 0xb1, 0x2e, 0xf4, 0x50, 0x0f, 0x71, 0x3c, 0xdd,
- 0x47, 0x58, 0x87, 0x7c, 0x0d, 0xe3, 0x9a, 0xea, 0x5b, 0xcb, 0xa4, 0x58,
- 0x96, 0xb4, 0x79, 0x9c, 0xfb, 0x54, 0x8f, 0xc6, 0x40, 0x6c, 0x97, 0x76,
- 0x0f, 0xab, 0xfe, 0x78, 0xb6, 0xc7, 0xf3, 0xaf, 0xb0, 0x1f, 0xe6, 0x43,
- 0x31, 0xe7, 0x8a, 0xba, 0xaf, 0x99, 0x06, 0x6d, 0xff, 0xdf, 0x50, 0xb1,
- 0xf4, 0x71, 0xd4, 0xa7, 0x8d, 0x86, 0xbc, 0xd4, 0x12, 0xdb, 0xdf, 0x7c,
- 0x68, 0x5e, 0xf2, 0xfa, 0x99, 0xed, 0x6f, 0x32, 0xec, 0xbb, 0x5d, 0xf3,
- 0x3e, 0xc4, 0xa5, 0xfd, 0xd8, 0xaf, 0x8f, 0x49, 0x7d, 0x25, 0x9d, 0xf8,
- 0xb4, 0x84, 0xfd, 0x06, 0x87, 0x78, 0xde, 0x51, 0xcc, 0x8c, 0xb8, 0x0b,
- 0x8a, 0x9e, 0x54, 0x82, 0x39, 0xc8, 0x97, 0x31, 0x5e, 0xbd, 0xd1, 0x1a,
- 0x7b, 0x48, 0xe5, 0x36, 0x25, 0xed, 0xeb, 0xb5, 0x19, 0x92, 0x4d, 0xac,
- 0xcd, 0x9f, 0x9b, 0xb5, 0xf9, 0x18, 0xfa, 0xf6, 0xce, 0x8c, 0x4a, 0xfa,
- 0x4c, 0x3a, 0x79, 0x5a, 0x78, 0x96, 0xb8, 0x8f, 0x31, 0x2c, 0xeb, 0xc1,
- 0x4c, 0x12, 0xf3, 0x4d, 0x61, 0xbe, 0x28, 0x1b, 0xbc, 0x1e, 0x81, 0x6f,
- 0xbe, 0x87, 0x7b, 0xfb, 0x10, 0x75, 0x26, 0x79, 0x51, 0x54, 0xef, 0x80,
- 0x4f, 0x9e, 0x26, 0x4d, 0x00, 0xca, 0x9d, 0x29, 0x15, 0x07, 0xbc, 0xde,
- 0xe0, 0xf9, 0xa2, 0xa6, 0xaf, 0x00, 0xfa, 0xe6, 0x34, 0x7d, 0xc9, 0x99,
- 0x6d, 0xec, 0x9a, 0x4a, 0x9c, 0x12, 0xe2, 0x25, 0xe2, 0x17, 0xe2, 0xfa,
- 0x47, 0x7a, 0xc3, 0x6f, 0x5a, 0xf2, 0x77, 0xe7, 0xb6, 0xe7, 0xde, 0x86,
- 0xba, 0x57, 0x32, 0x2a, 0xbf, 0xd9, 0x3d, 0x22, 0x1f, 0x91, 0xdc, 0xa7,
- 0x52, 0xc9, 0x9c, 0xe5, 0x19, 0x0c, 0x88, 0xb2, 0xc6, 0x6b, 0xea, 0x5c,
- 0xcf, 0x60, 0x0b, 0xae, 0x4d, 0x06, 0x63, 0x29, 0xde, 0xc2, 0x67, 0xea,
- 0x87, 0xcc, 0x53, 0xd6, 0x7e, 0x07, 0x7b, 0x48, 0xff, 0x9f, 0x8e, 0xcb,
- 0xe0, 0xe3, 0x3c, 0xf8, 0x78, 0xfc, 0x16, 0x0c, 0x16, 0xdd, 0xc6, 0x60,
- 0x5b, 0x6a, 0xbc, 0x7b, 0x41, 0x53, 0xc1, 0x25, 0xfe, 0x9a, 0xdf, 0x96,
- 0x15, 0xd2, 0x34, 0xca, 0xff, 0xb5, 0x23, 0x57, 0x33, 0x5c, 0x0f, 0x60,
- 0x30, 0xf4, 0xb7, 0xb6, 0x23, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e,
- 0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x1a, 0x68, 0xd9, 0x52,
- 0x72, 0xa0, 0x65, 0x60, 0xab, 0xd6, 0xf9, 0x1e, 0x32, 0xc0, 0x79, 0x52,
- 0xfe, 0x42, 0xd9, 0xdb, 0xc9, 0xa7, 0xe8, 0x00, 0x4f, 0x3e, 0x78, 0x4f,
- 0x56, 0xf2, 0x67, 0x78, 0x16, 0x26, 0xd6, 0xc8, 0x3d, 0x94, 0x49, 0xe2,
- 0x04, 0x60, 0xc8, 0x04, 0x79, 0xac, 0xf1, 0xe0, 0xcc, 0xb3, 0x7b, 0xf1,
- 0x7b, 0xb3, 0x87, 0x39, 0x33, 0xf9, 0x73, 0xd4, 0x57, 0x62, 0xdd, 0x79,
- 0x8f, 0xf6, 0x0f, 0x6f, 0xc4, 0xc1, 0x73, 0xbc, 0x1f, 0x78, 0xb2, 0x0d,
- 0xfa, 0xca, 0x31, 0xf3, 0xe6, 0x3d, 0xf9, 0x8a, 0xf2, 0xd9, 0x29, 0xa3,
- 0x03, 0xa8, 0x47, 0xc4, 0xec, 0x8b, 0xb2, 0xcc, 0x31, 0x46, 0x9f, 0xe9,
- 0x94, 0x09, 0xe8, 0xb5, 0x23, 0x95, 0x71, 0xf9, 0x72, 0xa5, 0x4b, 0xe1,
- 0x86, 0xbf, 0xf6, 0xd3, 0x89, 0x61, 0x2b, 0x90, 0x07, 0x81, 0x7f, 0x66,
- 0xfa, 0xdb, 0xe4, 0xcd, 0x51, 0x9d, 0xfb, 0x7b, 0x83, 0xc9, 0x8d, 0x2e,
- 0xf3, 0x55, 0x39, 0x1f, 0xe8, 0x7d, 0x0b, 0xbe, 0x80, 0xd5, 0x2e, 0x33,
- 0xf1, 0x2e, 0xf9, 0xb8, 0x8f, 0xf2, 0x36, 0x5f, 0x7d, 0x63, 0x9c, 0x8b,
- 0x37, 0xeb, 0x91, 0x37, 0xcd, 0xd8, 0x5f, 0x34, 0xe5, 0xbf, 0xe9, 0x6d,
- 0xa2, 0xc5, 0x9a, 0xcb, 0x44, 0xd4, 0xfc, 0xe6, 0x6b, 0xd4, 0x6f, 0x6c,
- 0x03, 0x7d, 0xd2, 0xe0, 0x39, 0x51, 0x59, 0xd6, 0xa0, 0x5f, 0x4a, 0x55,
- 0xb1, 0xce, 0x65, 0x80, 0xa8, 0x3d, 0x8d, 0x3f, 0x4b, 0x90, 0xaf, 0xd9,
- 0xaa, 0x8a, 0x59, 0xaa, 0xbc, 0xed, 0x59, 0x60, 0x5d, 0xf8, 0xc4, 0xc0,
- 0x10, 0x26, 0x7f, 0xa5, 0x93, 0xf1, 0x90, 0x66, 0x1d, 0x16, 0xfe, 0x2f,
- 0x9d, 0xff, 0xd4, 0x2b, 0xdd, 0x65, 0xac, 0x4b, 0x88, 0xb9, 0xc1, 0x53,
- 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x73, 0xbe, 0x78,
- 0x88, 0x39, 0xb8, 0x67, 0x69, 0x2f, 0xa4, 0x1c, 0x03, 0xa6, 0xed, 0x38,
- 0x03, 0xdb, 0x5d, 0xcd, 0x42, 0x56, 0xc6, 0x55, 0xde, 0xe7, 0x3c, 0xb0,
- 0xdb, 0x1f, 0xf8, 0x7f, 0x2a, 0xf6, 0xd3, 0x07, 0x64, 0xad, 0xda, 0x01,
- 0x7e, 0xd0, 0x2e, 0x44, 0x95, 0x7f, 0x7d, 0xe3, 0x28, 0xed, 0x1d, 0x6d,
- 0x89, 0x5e, 0x8b, 0xad, 0xda, 0xf7, 0x7a, 0xf5, 0xb7, 0x33, 0x7b, 0x65,
- 0xb3, 0x16, 0xda, 0x42, 0xf8, 0x87, 0xd5, 0xa8, 0xb1, 0xcb, 0x9d, 0xd0,
- 0xdd, 0xdf, 0x8f, 0xd6, 0x95, 0xaf, 0xce, 0xf9, 0xd3, 0x06, 0x45, 0x99,
- 0x17, 0xd7, 0x59, 0xf7, 0x38, 0xf7, 0x66, 0x1b, 0xa4, 0x71, 0x87, 0x7b,
- 0x90, 0xe3, 0x31, 0x87, 0x82, 0x73, 0x8c, 0x4b, 0xf4, 0xfc, 0x63, 0x62,
- 0xc3, 0x6f, 0x89, 0x2c, 0x11, 0xeb, 0xdd, 0xec, 0xbb, 0x44, 0x2e, 0xba,
- 0xe6, 0x5b, 0xec, 0x41, 0x8d, 0x65, 0x32, 0x28, 0xeb, 0xe1, 0xf7, 0xd9,
- 0xfc, 0x35, 0xdb, 0xcd, 0xd0, 0xb7, 0xd8, 0xd5, 0x96, 0xe2, 0xef, 0xff,
- 0x01, 0x37, 0x64, 0x26, 0x2b, 0x1c, 0x4c, 0x00, 0x00, 0x00 };
+ 0xcd, 0x7c, 0x7b, 0x6c, 0x5c, 0xd7, 0x99, 0xdf, 0x77, 0xef, 0xcc, 0x90,
+ 0x43, 0x6a, 0x44, 0x5d, 0x32, 0x13, 0x66, 0x1c, 0x33, 0xcd, 0x3c, 0x2e,
+ 0x29, 0xda, 0x64, 0x92, 0x31, 0x77, 0xa4, 0xd0, 0xc9, 0xad, 0x3d, 0x99,
+ 0x19, 0xc9, 0x4c, 0xa8, 0x0d, 0xe8, 0x44, 0x2e, 0x52, 0x54, 0x28, 0xd8,
+ 0x21, 0xe5, 0x28, 0x8b, 0xec, 0xae, 0xf2, 0x28, 0x9a, 0x2e, 0xd2, 0xd5,
+ 0x64, 0x48, 0x29, 0xca, 0x62, 0xc4, 0x19, 0xd3, 0x34, 0x93, 0xa2, 0x01,
+ 0x32, 0x19, 0x92, 0x72, 0x76, 0x31, 0x12, 0x15, 0xdb, 0xcd, 0x1a, 0x41,
+ 0xe2, 0xb0, 0xd4, 0x23, 0xde, 0x20, 0x2d, 0xb4, 0x1b, 0x17, 0x4d, 0xd3,
+ 0x45, 0x21, 0xc8, 0x4e, 0x6c, 0x6c, 0xb3, 0x6d, 0x50, 0x2c, 0x10, 0x77,
+ 0x91, 0x64, 0xfa, 0xfb, 0x9d, 0x73, 0xee, 0x70, 0x44, 0x31, 0x4e, 0xba,
+ 0x7f, 0x95, 0xc0, 0xe0, 0xdc, 0x7b, 0x9e, 0xdf, 0xf9, 0xce, 0xf7, 0x3e,
+ 0xdf, 0xe5, 0x43, 0x22, 0xbd, 0x62, 0xfe, 0xf6, 0xe3, 0x97, 0xf9, 0xfd,
+ 0x3f, 0x9c, 0x7b, 0xe0, 0x9d, 0x87, 0xdf, 0x89, 0xc7, 0x43, 0xf6, 0x81,
+ 0xae, 0x20, 0xeb, 0x03, 0xf8, 0x45, 0xf1, 0x9b, 0x30, 0xcf, 0x7b, 0xfd,
+ 0x39, 0xf8, 0x1d, 0xb6, 0x44, 0x66, 0xff, 0x46, 0xc4, 0xda, 0xd5, 0x16,
+ 0xfe, 0x35, 0x63, 0xde, 0xe8, 0xcf, 0xfe, 0x2d, 0xfb, 0x39, 0xff, 0x80,
+ 0xb9, 0xfd, 0xbf, 0x80, 0x19, 0xbe, 0xdf, 0xfc, 0x24, 0x6c, 0x7b, 0xb7,
+ 0x3e, 0x90, 0x73, 0x25, 0x1c, 0xf0, 0x7e, 0x38, 0x3d, 0xe7, 0x8a, 0x64,
+ 0x9b, 0x63, 0xf1, 0xbc, 0xfc, 0xb2, 0x55, 0x8a, 0x06, 0x85, 0xf5, 0x6f,
+ 0xf3, 0x7e, 0xf1, 0x95, 0x6f, 0xbf, 0x3b, 0xf1, 0xb3, 0x7a, 0x40, 0xc2,
+ 0x8e, 0xf7, 0xba, 0x38, 0x23, 0x12, 0x1e, 0xc2, 0x98, 0x2f, 0x1f, 0x9c,
+ 0xb5, 0xa5, 0xcf, 0x9f, 0xeb, 0xb5, 0xd6, 0xb7, 0x0f, 0x4a, 0xc9, 0xf6,
+ 0x1c, 0xb9, 0xb2, 0x19, 0x95, 0xef, 0x6c, 0x8a, 0x35, 0x93, 0xe9, 0x11,
+ 0x7b, 0xf9, 0xad, 0x92, 0x75, 0x2c, 0x09, 0xb8, 0x5c, 0x27, 0x2e, 0xb9,
+ 0xca, 0x20, 0xde, 0x13, 0x31, 0x91, 0x7f, 0xbe, 0x5f, 0x8f, 0x0d, 0x4b,
+ 0x60, 0x55, 0xc2, 0x5d, 0xde, 0x0b, 0xd3, 0x37, 0x56, 0x62, 0x12, 0x5c,
+ 0x1a, 0x97, 0x72, 0x35, 0x22, 0xa1, 0x55, 0x19, 0x0a, 0xc8, 0x70, 0xec,
+ 0x71, 0xf4, 0x28, 0x34, 0x83, 0x72, 0xa4, 0x69, 0x49, 0xd0, 0x0d, 0x03,
+ 0xb6, 0x08, 0x7e, 0x0e, 0x7e, 0x51, 0xfc, 0x62, 0xf8, 0x9d, 0xc5, 0x3c,
+ 0x43, 0x92, 0x6f, 0x72, 0x4e, 0xac, 0x5b, 0xc5, 0xfa, 0xd5, 0x84, 0x33,
+ 0x8b, 0x79, 0x6f, 0x05, 0x62, 0xf2, 0xed, 0x83, 0x84, 0xcb, 0x21, 0x3c,
+ 0x80, 0x2d, 0x6c, 0xe5, 0x56, 0xe4, 0x74, 0x3e, 0x2d, 0x71, 0xdb, 0xed,
+ 0x95, 0xa2, 0x63, 0xc5, 0xe7, 0x47, 0x07, 0xa4, 0x74, 0x1c, 0xed, 0x55,
+ 0xc9, 0xda, 0x98, 0xbf, 0xe8, 0xc8, 0xac, 0x6e, 0x63, 0xdd, 0x17, 0x41,
+ 0x27, 0x09, 0x87, 0x08, 0xfb, 0x4e, 0xf5, 0x31, 0x3c, 0x73, 0xbe, 0x78,
+ 0x50, 0xc3, 0xbd, 0x8a, 0x77, 0xd6, 0xff, 0x41, 0x44, 0xbf, 0xf3, 0x99,
+ 0x7d, 0xfd, 0x75, 0xfd, 0xfd, 0x72, 0xfd, 0x51, 0xec, 0x99, 0x30, 0xf8,
+ 0x7b, 0x96, 0x52, 0x08, 0xb0, 0x34, 0x56, 0x22, 0xd6, 0xda, 0xca, 0xb8,
+ 0x9c, 0xab, 0x3e, 0x24, 0xb9, 0x74, 0xab, 0x35, 0x97, 0x96, 0xa8, 0x2d,
+ 0xc3, 0x4e, 0x1e, 0x1d, 0xb6, 0x9b, 0x62, 0x35, 0x2a, 0x12, 0xee, 0x06,
+ 0x5e, 0x5e, 0x5d, 0xe1, 0xdc, 0x41, 0xd4, 0x0d, 0xa2, 0x7f, 0x9f, 0xb5,
+ 0xbe, 0x02, 0xf8, 0x3d, 0xe2, 0xa7, 0xd5, 0x5a, 0x4c, 0x0f, 0xc7, 0xe6,
+ 0xb1, 0xe6, 0xd5, 0xe6, 0xf0, 0xe4, 0x6d, 0x71, 0x30, 0xe7, 0x00, 0xfa,
+ 0x10, 0x57, 0x9c, 0x8b, 0x73, 0x72, 0xbe, 0x08, 0xc6, 0x46, 0xd1, 0x46,
+ 0xb8, 0x5a, 0xad, 0x5c, 0xda, 0xe1, 0xbb, 0x6c, 0x01, 0x7f, 0x5b, 0xc4,
+ 0x5f, 0xef, 0x90, 0x7c, 0xb7, 0xc9, 0x35, 0xda, 0xb0, 0x97, 0xba, 0xbc,
+ 0xe7, 0xed, 0xed, 0x0a, 0xcf, 0x2d, 0x2c, 0xef, 0x0b, 0x26, 0x46, 0x4b,
+ 0x8a, 0x4e, 0x66, 0xb1, 0x1f, 0x4b, 0xd1, 0x84, 0x85, 0xe7, 0x64, 0x93,
+ 0xfd, 0x89, 0xeb, 0xb8, 0x2c, 0xe0, 0x5c, 0xcb, 0x2b, 0x25, 0xfb, 0x6a,
+ 0xf3, 0x17, 0xad, 0x9c, 0xbb, 0x68, 0x6f, 0xaf, 0xb3, 0xff, 0x09, 0xf4,
+ 0x0f, 0xca, 0x62, 0xa5, 0x4f, 0x08, 0x93, 0x1e, 0x77, 0x02, 0xe3, 0xc4,
+ 0xb1, 0xbd, 0x73, 0xf6, 0xd5, 0xf5, 0xf3, 0xf6, 0x35, 0x75, 0x6e, 0x58,
+ 0xab, 0x3d, 0x57, 0x27, 0xde, 0xc6, 0xfe, 0x3f, 0xc4, 0x5b, 0x0c, 0xf3,
+ 0x47, 0x51, 0xee, 0xb3, 0x1a, 0xb5, 0x16, 0xd6, 0x8f, 0xe1, 0x79, 0x2f,
+ 0x1c, 0xde, 0x52, 0x74, 0x77, 0x05, 0x74, 0xe7, 0x78, 0x31, 0x79, 0x66,
+ 0x73, 0x08, 0xfb, 0x88, 0xca, 0xd7, 0xc1, 0x17, 0x03, 0x87, 0xf7, 0x49,
+ 0x1e, 0x7c, 0x41, 0x7a, 0x7b, 0x74, 0xf5, 0x9f, 0x49, 0x31, 0x9a, 0x18,
+ 0xa5, 0xfc, 0x48, 0x4e, 0x80, 0x9e, 0x0d, 0x6b, 0xe7, 0x96, 0xb2, 0x29,
+ 0x5b, 0x1e, 0x16, 0xdb, 0xc3, 0xba, 0x99, 0x31, 0xa7, 0x20, 0x41, 0xb4,
+ 0x65, 0x25, 0xe0, 0x45, 0x25, 0xb7, 0xfa, 0x5e, 0x0b, 0x74, 0x19, 0x5f,
+ 0xc0, 0xa0, 0xc0, 0x92, 0x58, 0xb6, 0xdb, 0x25, 0xc5, 0xe3, 0xac, 0x0f,
+ 0x83, 0xc6, 0xc1, 0xb3, 0x2b, 0x07, 0x00, 0x97, 0x0c, 0xdb, 0xc2, 0xba,
+ 0x61, 0xa7, 0x2c, 0x25, 0xb1, 0x2f, 0xff, 0xa1, 0x65, 0x64, 0x9e, 0xc1,
+ 0xef, 0xa8, 0x59, 0xab, 0xcd, 0x87, 0x96, 0xbd, 0x1a, 0xb1, 0x02, 0xab,
+ 0xe3, 0x72, 0x76, 0x0f, 0xbc, 0x36, 0x80, 0x57, 0x7b, 0xc9, 0xe7, 0xd3,
+ 0x20, 0xde, 0x07, 0xd1, 0xb7, 0xcf, 0x0a, 0xae, 0xde, 0x8d, 0xd3, 0xb5,
+ 0xe6, 0x70, 0x7a, 0x1b, 0x38, 0xb5, 0x57, 0x07, 0xd0, 0xe7, 0x6e, 0x9c,
+ 0x36, 0x80, 0x53, 0x7b, 0x55, 0xe3, 0xb3, 0x01, 0x7c, 0xda, 0x4b, 0x51,
+ 0x94, 0xfb, 0x2c, 0x7b, 0x59, 0xe3, 0xb3, 0x61, 0x78, 0xfa, 0x62, 0x93,
+ 0xb0, 0x66, 0x3b, 0x68, 0x2e, 0x4b, 0xda, 0x81, 0x9c, 0x2a, 0xc8, 0x5c,
+ 0xc5, 0x06, 0xbe, 0x82, 0xe2, 0x4e, 0x58, 0x32, 0xa7, 0xda, 0x0a, 0x92,
+ 0x02, 0x0d, 0x95, 0x9c, 0xb1, 0x51, 0x5b, 0x12, 0xf1, 0xac, 0x0d, 0x7c,
+ 0x57, 0x81, 0xf7, 0x2a, 0x70, 0xae, 0x64, 0xc2, 0x8b, 0xe0, 0xd7, 0x38,
+ 0xce, 0x65, 0x77, 0x7d, 0xc2, 0xa9, 0x2b, 0x9e, 0x8d, 0x9b, 0x33, 0x23,
+ 0xed, 0xf3, 0x9c, 0x62, 0x38, 0x2f, 0x75, 0x7e, 0xd6, 0x5f, 0x66, 0xf6,
+ 0x49, 0x6a, 0x39, 0xa0, 0xce, 0x2b, 0xbd, 0xfa, 0xae, 0xf6, 0x79, 0xd9,
+ 0x13, 0x94, 0x65, 0x3c, 0x23, 0x91, 0xd4, 0x12, 0xcf, 0x29, 0x9b, 0x0a,
+ 0x08, 0xcf, 0x2a, 0x24, 0xd9, 0x19, 0x9e, 0x4b, 0x54, 0x92, 0xab, 0x3c,
+ 0xb3, 0x0d, 0x73, 0x5e, 0xfa, 0x9c, 0x92, 0x7b, 0x9c, 0x53, 0xd2, 0x9c,
+ 0xd3, 0x76, 0xf3, 0x8a, 0x39, 0xa7, 0x7f, 0x2b, 0x86, 0xe6, 0xdf, 0x10,
+ 0x07, 0x36, 0x70, 0x10, 0xbc, 0x03, 0x07, 0xdd, 0x6d, 0x1c, 0xc4, 0x6d,
+ 0xec, 0xe1, 0xae, 0xfd, 0x77, 0xd6, 0x75, 0xee, 0x5d, 0x4a, 0x41, 0x4f,
+ 0xac, 0x85, 0x0a, 0xe1, 0x0e, 0x48, 0x71, 0x86, 0x30, 0x52, 0xae, 0x6b,
+ 0x58, 0xf3, 0x2b, 0x94, 0x6d, 0x07, 0x04, 0x34, 0xf1, 0xb6, 0x80, 0x1a,
+ 0x53, 0x92, 0x85, 0x26, 0xdb, 0x4a, 0x92, 0xcb, 0x80, 0x5e, 0x6b, 0xac,
+ 0x03, 0x83, 0x6e, 0x6a, 0x3e, 0xde, 0xd1, 0x07, 0xd1, 0x36, 0x1e, 0xf3,
+ 0x95, 0x38, 0xe4, 0x74, 0x10, 0xe5, 0xd7, 0x50, 0xee, 0xb3, 0x66, 0x6a,
+ 0x7f, 0x65, 0x49, 0x5f, 0x4b, 0x9c, 0x09, 0xee, 0x31, 0x36, 0x9d, 0x73,
+ 0x4b, 0x31, 0x47, 0xde, 0x26, 0xce, 0x3b, 0x43, 0x22, 0x83, 0x09, 0xa7,
+ 0x28, 0xff, 0x05, 0xed, 0x89, 0x58, 0x56, 0xfe, 0xb7, 0x4f, 0xbb, 0xc0,
+ 0x43, 0xcf, 0xeb, 0x59, 0xf5, 0xc4, 0x7a, 0x8e, 0xcb, 0xa0, 0x2e, 0x24,
+ 0xb3, 0xd0, 0x31, 0x05, 0x97, 0xeb, 0x71, 0xfe, 0xf8, 0x2c, 0xd7, 0xcd,
+ 0x37, 0x7d, 0x7d, 0x20, 0xd9, 0x80, 0xc7, 0x36, 0xf2, 0xe5, 0xa4, 0x95,
+ 0x6f, 0x12, 0x57, 0x19, 0x71, 0x9b, 0x1a, 0x66, 0x0d, 0x6b, 0x1b, 0x4e,
+ 0xf0, 0x6b, 0x16, 0x34, 0x49, 0xd8, 0xe2, 0xe0, 0x9b, 0x73, 0x01, 0xff,
+ 0x1c, 0x82, 0xde, 0xa4, 0x2c, 0x42, 0x3f, 0x96, 0x2b, 0x9c, 0xef, 0x33,
+ 0x56, 0xe0, 0xb2, 0x3f, 0x3f, 0xcf, 0x86, 0x73, 0xeb, 0xf9, 0xca, 0xcd,
+ 0xd7, 0x0c, 0xef, 0x2b, 0x3d, 0x88, 0xf9, 0x4a, 0x1d, 0xf3, 0x95, 0xc8,
+ 0xb3, 0x07, 0x94, 0xae, 0x39, 0x4e, 0xfc, 0x9d, 0x47, 0xdb, 0x2d, 0xd0,
+ 0x08, 0xf9, 0x81, 0xfc, 0x41, 0x5e, 0x7d, 0xb7, 0x8d, 0xfd, 0x76, 0xe0,
+ 0x76, 0x06, 0x72, 0x98, 0xbc, 0x11, 0x96, 0x7c, 0x94, 0xf5, 0x8f, 0x1b,
+ 0x98, 0x20, 0x13, 0xd4, 0xfb, 0xf1, 0x1e, 0x5f, 0x3e, 0x82, 0x16, 0x01,
+ 0xdb, 0xf3, 0x6a, 0x8f, 0xb6, 0xe7, 0x01, 0x37, 0x9d, 0x30, 0x72, 0xdf,
+ 0x9e, 0x91, 0xdb, 0x3e, 0xbc, 0x3c, 0x2b, 0xca, 0x55, 0xb1, 0xd6, 0x33,
+ 0x61, 0xc8, 0x70, 0x5b, 0xf2, 0x69, 0xd0, 0x66, 0x3a, 0x60, 0xe4, 0xc3,
+ 0x8b, 0xc6, 0x56, 0xd2, 0x38, 0x0e, 0x2a, 0x3d, 0xbe, 0x88, 0x79, 0x4f,
+ 0x00, 0x46, 0xce, 0x19, 0xb4, 0xd6, 0x2a, 0x11, 0xe8, 0x6c, 0xc0, 0xe6,
+ 0x24, 0xe2, 0x80, 0x09, 0xef, 0x7e, 0x9f, 0x88, 0x2c, 0x6c, 0xfa, 0xeb,
+ 0x2e, 0xb6, 0xf5, 0x45, 0x49, 0xe1, 0xdb, 0x99, 0x0d, 0xec, 0xd0, 0xc6,
+ 0xcc, 0xc9, 0xca, 0x99, 0x96, 0xed, 0x92, 0x06, 0xdd, 0xd1, 0x86, 0x44,
+ 0x26, 0x37, 0x32, 0xef, 0x06, 0xbf, 0xa1, 0x1e, 0x63, 0xca, 0xcd, 0x52,
+ 0xc4, 0x76, 0x5d, 0x94, 0x94, 0x3f, 0x27, 0xba, 0x6f, 0xb8, 0x3e, 0xbd,
+ 0x0c, 0x49, 0xc8, 0x6d, 0xb5, 0x36, 0x70, 0x26, 0x47, 0x9b, 0xbf, 0x6c,
+ 0x7d, 0x35, 0xa8, 0xed, 0x15, 0xdb, 0xfb, 0xa9, 0xa5, 0xd7, 0x8c, 0x4f,
+ 0x27, 0x15, 0x1e, 0x62, 0x5d, 0xfa, 0xdd, 0x35, 0xef, 0xd7, 0x22, 0x46,
+ 0x87, 0x99, 0xf7, 0xf9, 0xa0, 0xb6, 0x7f, 0xc2, 0x3d, 0xe4, 0xa3, 0xa0,
+ 0xe7, 0xf4, 0xe0, 0x9c, 0xc3, 0x21, 0x6f, 0x6a, 0x7c, 0x43, 0xf5, 0x2b,
+ 0x99, 0x7e, 0xd1, 0x6e, 0x3d, 0xee, 0xd4, 0xf4, 0x88, 0xa2, 0xa1, 0x4f,
+ 0x4f, 0x0f, 0xab, 0xf2, 0xb3, 0xd3, 0x29, 0x55, 0x2e, 0x4e, 0xbb, 0xaa,
+ 0x3c, 0xaf, 0xfa, 0x5b, 0xde, 0x90, 0xa9, 0x1f, 0x9d, 0x8e, 0xab, 0x72,
+ 0xdc, 0x94, 0x69, 0x53, 0x66, 0x4c, 0x39, 0x69, 0x4a, 0xcf, 0x94, 0x59,
+ 0x53, 0x16, 0xcc, 0x7c, 0x53, 0xe6, 0xfd, 0x98, 0x29, 0x67, 0x4c, 0x79,
+ 0xdc, 0x94, 0x1f, 0x31, 0xe5, 0x09, 0x03, 0xd7, 0xbc, 0x29, 0x3f, 0x6e,
+ 0xea, 0x4f, 0x1b, 0x38, 0x3f, 0x03, 0x78, 0x1e, 0x09, 0xed, 0xd0, 0xca,
+ 0x69, 0x4d, 0x5f, 0x15, 0x47, 0xca, 0x9b, 0xdc, 0x7f, 0x1c, 0x32, 0x25,
+ 0x88, 0xb3, 0x04, 0xbf, 0x3b, 0xa4, 0x09, 0x17, 0x72, 0x38, 0x88, 0x33,
+ 0xe4, 0xf3, 0x69, 0xf9, 0x53, 0xf4, 0x1d, 0xbd, 0xe0, 0xc8, 0x62, 0x95,
+ 0xfa, 0xf5, 0x5b, 0xf2, 0x6a, 0x85, 0xe7, 0xf1, 0xbc, 0xdc, 0xa8, 0xa4,
+ 0xe2, 0x41, 0x8b, 0x74, 0x94, 0x98, 0x7c, 0x45, 0x12, 0x90, 0xfd, 0x63,
+ 0x71, 0x96, 0xd7, 0xa8, 0x54, 0xd0, 0xef, 0xa0, 0x5a, 0xfb, 0x79, 0x01,
+ 0x4c, 0x72, 0xa5, 0xd2, 0x0d, 0x99, 0xf5, 0x4a, 0x8b, 0x7a, 0xfd, 0xfc,
+ 0xa6, 0xc8, 0xc8, 0x05, 0xe2, 0xf9, 0x5b, 0xb2, 0x51, 0x21, 0xde, 0x9f,
+ 0x87, 0xad, 0x90, 0x4a, 0xbf, 0x28, 0x89, 0xd1, 0x8b, 0xc2, 0xf9, 0xc6,
+ 0xd2, 0x28, 0xe3, 0x65, 0xfc, 0xce, 0x41, 0xde, 0x76, 0x4f, 0xe8, 0xf9,
+ 0x86, 0xcd, 0x7c, 0x2e, 0xec, 0xc2, 0x5b, 0x0e, 0x65, 0xe0, 0x7f, 0xb5,
+ 0xf4, 0x9e, 0xb4, 0x3c, 0xcc, 0x3a, 0x41, 0x96, 0xb6, 0xcf, 0x23, 0xf6,
+ 0xc4, 0xf5, 0x16, 0xe4, 0x31, 0xf9, 0xdf, 0xd4, 0x6d, 0x1b, 0xfe, 0x92,
+ 0x9a, 0xed, 0x81, 0x3e, 0x33, 0xc3, 0x58, 0x83, 0xef, 0x71, 0xd8, 0x9a,
+ 0x52, 0x22, 0x1e, 0x8a, 0x95, 0x5f, 0xb5, 0xb2, 0x41, 0x6d, 0x9f, 0x6a,
+ 0x19, 0xc1, 0x76, 0x4b, 0xf2, 0xe8, 0xbb, 0x60, 0x64, 0x66, 0xa1, 0x79,
+ 0x4b, 0xc9, 0x8d, 0xaf, 0x2b, 0x1a, 0x4e, 0x9c, 0x2f, 0x09, 0x75, 0x86,
+ 0x1d, 0xa0, 0x4c, 0xbb, 0x92, 0xae, 0xb7, 0x16, 0xaa, 0x94, 0xc1, 0xc3,
+ 0x52, 0xac, 0x0d, 0x97, 0x6c, 0x94, 0xa7, 0xeb, 0x31, 0x39, 0x5d, 0xe1,
+ 0x3c, 0xfb, 0xd1, 0xc7, 0x45, 0x1d, 0x18, 0x6b, 0x90, 0xf2, 0x98, 0x6b,
+ 0xbe, 0x6e, 0xe9, 0x35, 0xb1, 0x07, 0x77, 0xcb, 0xfa, 0x44, 0xf3, 0x9a,
+ 0x55, 0xac, 0xd3, 0x4e, 0x42, 0x7d, 0xb3, 0x53, 0x66, 0xfb, 0xf2, 0xfa,
+ 0x79, 0xac, 0x5d, 0xc0, 0x7a, 0x59, 0x25, 0xb3, 0xba, 0x21, 0xf7, 0x7e,
+ 0x52, 0xf9, 0x72, 0xab, 0x5c, 0x1d, 0x95, 0x8b, 0x9b, 0x71, 0x39, 0x52,
+ 0x19, 0x97, 0x8d, 0x4d, 0x4f, 0x0a, 0x95, 0xb4, 0xac, 0xa3, 0x4f, 0xbe,
+ 0x92, 0x91, 0xb5, 0xcd, 0x63, 0xea, 0xac, 0x2f, 0x42, 0x2e, 0x6d, 0xa0,
+ 0x4f, 0x63, 0x73, 0x12, 0x3f, 0xdf, 0x1e, 0x88, 0xa1, 0xdf, 0x10, 0xfa,
+ 0x88, 0xf5, 0xb3, 0xca, 0x3d, 0xc0, 0x21, 0xe6, 0xae, 0xfa, 0xb6, 0xc1,
+ 0xb8, 0x2c, 0x54, 0x79, 0x4e, 0x2f, 0x4c, 0x6f, 0xac, 0xc4, 0xb2, 0xd4,
+ 0x77, 0xa7, 0x9b, 0xc3, 0xe0, 0x53, 0xe8, 0xef, 0x2a, 0x65, 0x42, 0x50,
+ 0x8a, 0x90, 0xb5, 0x0d, 0xc0, 0x46, 0x58, 0x1b, 0xb0, 0xdf, 0x8b, 0xcd,
+ 0x21, 0x94, 0x0e, 0x4a, 0xac, 0x03, 0xd8, 0x8b, 0x4d, 0x17, 0x65, 0x0c,
+ 0xa5, 0xd6, 0xed, 0x27, 0x9b, 0x9c, 0x3f, 0xab, 0x74, 0x90, 0xc6, 0xf1,
+ 0xd4, 0x1d, 0xb6, 0x7a, 0xc0, 0x5b, 0xb4, 0x8a, 0x2b, 0x62, 0xe7, 0xd2,
+ 0x21, 0xfa, 0x0b, 0x90, 0x2b, 0x37, 0x0f, 0x68, 0x58, 0x3e, 0x1b, 0xa0,
+ 0xdc, 0x09, 0xba, 0xe7, 0x81, 0xaf, 0x5e, 0xc9, 0x06, 0x69, 0x73, 0xf1,
+ 0x59, 0x5a, 0x01, 0xcf, 0xa5, 0xad, 0x12, 0x0c, 0x50, 0x5f, 0x45, 0xd9,
+ 0xa7, 0xde, 0xa2, 0x5c, 0xca, 0xd5, 0xb4, 0x6d, 0x5e, 0x6a, 0xdb, 0xe6,
+ 0xeb, 0xa8, 0xb7, 0x20, 0x3b, 0xe0, 0x9b, 0xd4, 0x79, 0x1e, 0x03, 0x98,
+ 0x33, 0x6b, 0x15, 0x2a, 0xfe, 0x79, 0xd6, 0x5b, 0x4f, 0x54, 0x69, 0xaf,
+ 0xd1, 0x6e, 0x53, 0xf2, 0x49, 0x92, 0xcb, 0x71, 0x23, 0x83, 0x23, 0x8a,
+ 0x37, 0x88, 0x83, 0xe4, 0x72, 0xda, 0xd4, 0x75, 0x77, 0xd4, 0xf9, 0xb2,
+ 0xfa, 0x73, 0x80, 0x61, 0x48, 0x9d, 0xad, 0xed, 0x4d, 0x59, 0x39, 0x65,
+ 0x2b, 0xb6, 0x5a, 0x79, 0x37, 0x24, 0xc5, 0xf1, 0x3f, 0xc2, 0x9e, 0xd8,
+ 0x56, 0x72, 0x40, 0x5a, 0xe0, 0xbb, 0xca, 0x07, 0xe6, 0xdc, 0x84, 0xb2,
+ 0xb3, 0x72, 0x15, 0xf8, 0x38, 0x5a, 0xd5, 0x95, 0xfa, 0xa1, 0x87, 0xdc,
+ 0x25, 0xd2, 0x53, 0xbd, 0xb5, 0x0c, 0x9c, 0xce, 0x2c, 0x15, 0xac, 0xe4,
+ 0x12, 0xe8, 0x63, 0x10, 0xb6, 0x87, 0x1b, 0x91, 0xdc, 0x65, 0xd2, 0x11,
+ 0xfb, 0xb0, 0xbe, 0x4b, 0x66, 0xa2, 0xbb, 0x6d, 0x9b, 0x87, 0x0e, 0x68,
+ 0x9d, 0x8f, 0xbe, 0x4b, 0x70, 0xe6, 0x7a, 0xb5, 0x9f, 0x92, 0x5c, 0xa5,
+ 0x9c, 0x2d, 0x40, 0xd7, 0x53, 0xe7, 0xf4, 0xc0, 0x9e, 0x61, 0x3d, 0xe7,
+ 0x44, 0xdb, 0xc5, 0xac, 0x05, 0xfd, 0x66, 0x97, 0x95, 0x8d, 0x3e, 0x89,
+ 0xf2, 0xde, 0x20, 0x6d, 0x5b, 0xea, 0x90, 0xe4, 0xaa, 0x3f, 0x47, 0x27,
+ 0x3e, 0xf6, 0x29, 0x9d, 0x34, 0xe0, 0x0d, 0xa8, 0x79, 0x61, 0x97, 0x58,
+ 0x73, 0x6a, 0xde, 0x58, 0xc7, 0xbc, 0x68, 0xbb, 0xf8, 0xb7, 0x01, 0x3d,
+ 0x0f, 0xf0, 0xac, 0xf6, 0xc4, 0x36, 0x8e, 0x29, 0x58, 0x79, 0xd8, 0x4e,
+ 0x33, 0x69, 0x5b, 0x02, 0x83, 0x7e, 0x5f, 0xbd, 0xaf, 0x02, 0xf6, 0x95,
+ 0xc3, 0xbe, 0xec, 0xc1, 0xdd, 0xfb, 0x2a, 0x05, 0xf4, 0xbe, 0x06, 0x3a,
+ 0x60, 0x8a, 0xee, 0x5a, 0xbf, 0x73, 0x5f, 0x68, 0xbb, 0xb8, 0x7b, 0x8e,
+ 0xc7, 0x06, 0xf4, 0x1c, 0xd1, 0x8e, 0x39, 0x06, 0x77, 0xcd, 0x01, 0x7a,
+ 0x8e, 0x72, 0xfc, 0xe0, 0x1e, 0xe3, 0x5f, 0xef, 0xd5, 0xe3, 0x39, 0xa6,
+ 0x0b, 0x7a, 0x58, 0x9d, 0x75, 0x58, 0xc9, 0xd4, 0xb6, 0xad, 0x76, 0x1a,
+ 0x3a, 0xaf, 0x73, 0xcc, 0x9d, 0x76, 0xa6, 0xad, 0xec, 0xcc, 0x3b, 0xe8,
+ 0xcc, 0x7a, 0x14, 0x3e, 0x73, 0x6a, 0x19, 0xbe, 0x73, 0xe5, 0xed, 0x58,
+ 0xf7, 0xcf, 0xe0, 0x87, 0x42, 0x16, 0x8d, 0xd2, 0x2f, 0x98, 0x14, 0xe5,
+ 0x97, 0x8e, 0xc2, 0xff, 0x75, 0xf6, 0x29, 0x5b, 0xb4, 0x38, 0x3a, 0xee,
+ 0xfb, 0x0b, 0xd6, 0x2c, 0xe4, 0x46, 0x71, 0x14, 0x36, 0x7d, 0x14, 0xf8,
+ 0x72, 0x47, 0x30, 0x8e, 0xf0, 0xbc, 0x3b, 0x44, 0x9f, 0xf5, 0x99, 0xea,
+ 0x2c, 0xde, 0xf7, 0xa1, 0xfd, 0xe7, 0x06, 0xce, 0x3e, 0xf4, 0xf9, 0x57,
+ 0xa8, 0x63, 0x1b, 0xfb, 0x70, 0x8a, 0x1f, 0xe0, 0xfd, 0x41, 0xf4, 0x01,
+ 0x4f, 0x81, 0x53, 0x6c, 0xf7, 0x30, 0x7e, 0x2f, 0xa3, 0xee, 0xdd, 0xa8,
+ 0xbb, 0x8e, 0xba, 0x43, 0x78, 0xff, 0xe1, 0xae, 0x79, 0xdf, 0x81, 0xf7,
+ 0xcf, 0xa1, 0x1d, 0xfb, 0x77, 0x5e, 0x44, 0xfb, 0x83, 0xf8, 0xfd, 0xc5,
+ 0xae, 0x3e, 0x8d, 0x5d, 0xef, 0xbe, 0xbc, 0x79, 0xc9, 0xf0, 0xc0, 0x8e,
+ 0x6f, 0x07, 0xfe, 0xb1, 0xa8, 0x8f, 0x0a, 0x15, 0xca, 0x9b, 0xb0, 0x3c,
+ 0xb2, 0xe2, 0xcb, 0x1c, 0x91, 0x79, 0xc8, 0xfa, 0x42, 0x45, 0xbc, 0x6e,
+ 0x19, 0x9e, 0xfc, 0x31, 0x64, 0xfa, 0x3c, 0xf0, 0x5a, 0x80, 0x7d, 0x71,
+ 0x74, 0x25, 0x8c, 0xe7, 0x21, 0xc8, 0x3b, 0xc9, 0x74, 0x09, 0x79, 0x3e,
+ 0x02, 0xd9, 0xd2, 0x0b, 0x9e, 0x57, 0x3e, 0x88, 0x3c, 0x0e, 0xb9, 0x34,
+ 0x8b, 0xbe, 0xb3, 0xe8, 0xf3, 0xd1, 0xe6, 0xff, 0x31, 0xb4, 0xec, 0xc3,
+ 0xf0, 0xec, 0x2e, 0x18, 0xc2, 0xe2, 0xae, 0x92, 0x1f, 0x5f, 0x98, 0x9e,
+ 0x5b, 0x89, 0xc8, 0xf0, 0xaa, 0x9d, 0xa4, 0xb3, 0x3f, 0xb2, 0xca, 0x98,
+ 0x84, 0x8c, 0x04, 0x85, 0xb2, 0x5f, 0xc6, 0x43, 0xb0, 0xd1, 0x02, 0xde,
+ 0x30, 0x74, 0x94, 0x7a, 0x97, 0x2c, 0x60, 0xcb, 0x36, 0x77, 0x62, 0x13,
+ 0x47, 0xda, 0xb1, 0x89, 0x21, 0xe8, 0x88, 0xd7, 0x83, 0x5a, 0x5e, 0x45,
+ 0x40, 0x27, 0x6f, 0x01, 0xfe, 0x29, 0x5b, 0x42, 0xe0, 0x1f, 0x07, 0xbc,
+ 0xf3, 0x26, 0xda, 0x6f, 0xd4, 0x5b, 0xa0, 0x77, 0xc8, 0x38, 0x9b, 0xf5,
+ 0x2c, 0xd1, 0x96, 0x21, 0x0f, 0xe0, 0xbd, 0xd1, 0xc9, 0x6b, 0xe7, 0xb4,
+ 0x8d, 0x75, 0x97, 0x6f, 0xf3, 0xa0, 0xa3, 0x69, 0x91, 0xf6, 0xfa, 0xe1,
+ 0xd0, 0x9d, 0x7b, 0xfc, 0xa3, 0x5d, 0x7b, 0x0c, 0x4a, 0x72, 0x89, 0xf8,
+ 0x8d, 0xa8, 0xbd, 0xfa, 0xf8, 0x2d, 0x2a, 0x5b, 0x7e, 0x1c, 0x3e, 0x89,
+ 0x40, 0x9a, 0x2b, 0x5b, 0x14, 0x3a, 0xb1, 0x0f, 0xb2, 0x9e, 0x72, 0x9e,
+ 0xf8, 0x0e, 0x03, 0x87, 0x11, 0xfc, 0x1c, 0xfc, 0x76, 0x70, 0x7a, 0xb2,
+ 0xbd, 0x3f, 0x7f, 0x0f, 0xeb, 0x90, 0x55, 0x2c, 0x09, 0x3f, 0xf0, 0x71,
+ 0x91, 0xcf, 0x90, 0xaf, 0x7d, 0x94, 0xb7, 0x3e, 0x4c, 0x8f, 0xed, 0x82,
+ 0x89, 0xb8, 0x21, 0x4c, 0xf5, 0x16, 0x6c, 0x8b, 0x28, 0xa3, 0x60, 0xa7,
+ 0x9b, 0xd4, 0x29, 0x5c, 0x73, 0x92, 0xf6, 0xb6, 0x81, 0x93, 0x7a, 0xc5,
+ 0x93, 0x73, 0x95, 0xb7, 0x1b, 0xb8, 0x78, 0xbe, 0xb0, 0xf9, 0x96, 0xb8,
+ 0x7e, 0x54, 0xe9, 0x1e, 0x0d, 0xd3, 0x6e, 0xfc, 0xd0, 0x3f, 0x27, 0x7e,
+ 0xa8, 0x0f, 0x88, 0x4b, 0xda, 0xd4, 0xc4, 0xe7, 0xef, 0x00, 0x9f, 0xec,
+ 0xeb, 0x1a, 0xdd, 0xf2, 0x2e, 0x03, 0xd7, 0xdd, 0xfa, 0xf8, 0xf4, 0x1d,
+ 0xfa, 0xd8, 0xc7, 0xf1, 0x5e, 0x67, 0xf1, 0xfb, 0x7d, 0xbe, 0xcc, 0x1d,
+ 0x5e, 0xdd, 0xab, 0x7d, 0xd9, 0xb4, 0xb3, 0xad, 0xb3, 0xfe, 0xdb, 0x7d,
+ 0xfe, 0x19, 0x0e, 0x2f, 0xef, 0x6e, 0xeb, 0x3b, 0xb0, 0x33, 0x66, 0xf7,
+ 0x7c, 0x3f, 0xee, 0xdb, 0xdb, 0xaf, 0xdd, 0xf1, 0xeb, 0xe0, 0xab, 0xd8,
+ 0x3b, 0x7b, 0xc9, 0xda, 0xf3, 0xcd, 0x82, 0xad, 0xf7, 0xc2, 0x3e, 0x68,
+ 0x6b, 0x6e, 0xf5, 0x07, 0x95, 0x6e, 0xcc, 0xda, 0xf4, 0x63, 0x4a, 0x6b,
+ 0x7c, 0xbe, 0x07, 0x65, 0xe7, 0xd8, 0x21, 0xf0, 0x40, 0x16, 0x7d, 0x39,
+ 0xc7, 0xee, 0xf1, 0xbe, 0x8d, 0x94, 0x96, 0x85, 0x5a, 0x08, 0xed, 0x89,
+ 0x6c, 0x49, 0x1e, 0x86, 0xaf, 0x98, 0x98, 0xa2, 0xdf, 0x00, 0x7f, 0x79,
+ 0x46, 0xe4, 0x98, 0x94, 0x6b, 0x1f, 0x94, 0x85, 0x95, 0x96, 0xbc, 0x1f,
+ 0x7a, 0xf0, 0xf7, 0xa0, 0x47, 0xe5, 0x12, 0x84, 0xd7, 0x25, 0x1c, 0xc6,
+ 0xa5, 0xa8, 0xd8, 0x4f, 0xc1, 0x96, 0xbf, 0x10, 0x93, 0xe0, 0x05, 0xd2,
+ 0x5e, 0xca, 0x79, 0xbf, 0x48, 0xbf, 0x2d, 0x57, 0xe1, 0x08, 0x25, 0x26,
+ 0xb3, 0x92, 0x82, 0xfd, 0x37, 0xe6, 0x34, 0x50, 0x96, 0x25, 0x35, 0xfa,
+ 0xb4, 0xa0, 0xef, 0x25, 0xf4, 0xc5, 0xb8, 0x9e, 0x8d, 0x38, 0x7e, 0x83,
+ 0xd2, 0xbb, 0x41, 0x18, 0x92, 0xa6, 0x24, 0x2c, 0x3f, 0x6c, 0xd1, 0xd7,
+ 0x7d, 0x66, 0x33, 0x0c, 0xdd, 0x14, 0x97, 0xe7, 0x20, 0x67, 0x9f, 0x55,
+ 0xf1, 0x17, 0xb7, 0xed, 0x8f, 0x3e, 0x7a, 0x18, 0x74, 0xb7, 0x2c, 0xe1,
+ 0xa8, 0xf7, 0x73, 0x59, 0x59, 0x6e, 0xc1, 0xef, 0xa1, 0xac, 0x7f, 0x00,
+ 0xf2, 0x2a, 0xf1, 0xa5, 0x12, 0x6d, 0x49, 0x37, 0x03, 0xd8, 0x4b, 0x32,
+ 0x73, 0xf8, 0x5d, 0x03, 0x9a, 0x3e, 0x8e, 0x49, 0x70, 0xb9, 0x00, 0xfb,
+ 0xf9, 0x8c, 0x2c, 0xa6, 0xe1, 0x9f, 0xda, 0xa5, 0x56, 0xc0, 0x75, 0x63,
+ 0xd0, 0xdb, 0xd0, 0xa7, 0x2b, 0xf4, 0x87, 0xe5, 0xc8, 0x32, 0xfb, 0x9c,
+ 0x01, 0x6d, 0x75, 0x01, 0x77, 0xdd, 0x72, 0x36, 0x9a, 0x28, 0xe5, 0xc1,
+ 0x4f, 0xb6, 0xdb, 0x0f, 0x5e, 0x66, 0x49, 0xfd, 0xf6, 0x34, 0xe8, 0x87,
+ 0xcf, 0x38, 0xce, 0x55, 0xd6, 0x27, 0x51, 0xb2, 0xde, 0x15, 0x7b, 0x29,
+ 0x8c, 0xb9, 0xa0, 0x93, 0x2e, 0x97, 0xe4, 0x6c, 0xe6, 0x98, 0x34, 0x6a,
+ 0xf0, 0xc9, 0x33, 0xb0, 0xa3, 0xea, 0x9e, 0x34, 0x2a, 0xb4, 0x9f, 0x4e,
+ 0x81, 0x1f, 0x5e, 0x41, 0x39, 0x8f, 0xf2, 0x16, 0xca, 0x8f, 0xa3, 0x7c,
+ 0x0d, 0x25, 0x61, 0x3f, 0x25, 0x8d, 0xfa, 0x55, 0xcc, 0xcd, 0x39, 0xa6,
+ 0x0c, 0xcc, 0xf0, 0x21, 0x0f, 0x9f, 0x82, 0x9d, 0xe3, 0xd7, 0x9f, 0x12,
+ 0x69, 0x7c, 0x0c, 0xbf, 0x96, 0x7a, 0xa7, 0x8f, 0xb9, 0x90, 0x99, 0x84,
+ 0xbd, 0x2b, 0xd6, 0xd9, 0xcc, 0xc7, 0xcd, 0x3c, 0x1f, 0xc3, 0x7a, 0xd7,
+ 0xb1, 0x76, 0x18, 0xe7, 0xd9, 0x92, 0x47, 0xd3, 0x67, 0xe4, 0x93, 0xe9,
+ 0x7b, 0x65, 0x62, 0x20, 0x5c, 0x0a, 0x7b, 0xdc, 0x3f, 0xed, 0xda, 0xbd,
+ 0xf6, 0xef, 0xef, 0x9b, 0x7b, 0x8e, 0x60, 0x2f, 0xfb, 0xb5, 0xed, 0x66,
+ 0xff, 0x13, 0xe3, 0x73, 0x58, 0x92, 0x1c, 0xe1, 0x7c, 0x9e, 0x04, 0x96,
+ 0x47, 0x9c, 0x8c, 0x3d, 0x06, 0xeb, 0x3d, 0x85, 0xdf, 0x19, 0xd0, 0x8a,
+ 0x7b, 0x3e, 0x69, 0xff, 0x47, 0xc0, 0x84, 0xb6, 0x06, 0xd7, 0x11, 0x2b,
+ 0x78, 0xe8, 0x26, 0xf6, 0x56, 0x92, 0xee, 0x43, 0x9e, 0xdc, 0x6e, 0xf2,
+ 0x19, 0x92, 0xf2, 0xd2, 0x31, 0xf9, 0x71, 0xed, 0xba, 0x9c, 0xab, 0x1d,
+ 0x93, 0x97, 0x51, 0x2e, 0xd6, 0x4a, 0xc0, 0x23, 0x7d, 0x46, 0xce, 0xd1,
+ 0xc2, 0xb9, 0x50, 0x2e, 0xdf, 0x1f, 0x9b, 0xc7, 0xf9, 0xcd, 0x3a, 0x2d,
+ 0xd9, 0x48, 0x97, 0x64, 0x63, 0x12, 0x63, 0xea, 0x3d, 0x12, 0xfa, 0x2a,
+ 0xf7, 0xdb, 0x27, 0xf9, 0x5a, 0x49, 0x0a, 0x19, 0xfa, 0x34, 0xbd, 0x92,
+ 0x87, 0x4d, 0x0e, 0x3b, 0xe8, 0x8c, 0x8e, 0xb3, 0xb9, 0xb1, 0x22, 0x6c,
+ 0xf8, 0x85, 0xe6, 0xeb, 0x56, 0xa3, 0x6d, 0xff, 0x6f, 0x59, 0xcf, 0xc2,
+ 0x76, 0xfd, 0x0e, 0xe4, 0xc6, 0x73, 0xb0, 0x09, 0x9f, 0xbd, 0x83, 0xc7,
+ 0x48, 0x23, 0xd7, 0xac, 0x46, 0x7d, 0x94, 0x7c, 0x66, 0xf8, 0x01, 0x63,
+ 0xe1, 0xe7, 0x34, 0x6a, 0xb7, 0x0c, 0xfd, 0x29, 0x5b, 0x00, 0xe7, 0x42,
+ 0xbd, 0xf2, 0x77, 0xf0, 0xaf, 0x28, 0x77, 0x7c, 0xbd, 0xaf, 0xfd, 0x86,
+ 0x3a, 0x60, 0xcd, 0x47, 0x13, 0x80, 0x4a, 0xa4, 0x5e, 0x2f, 0x28, 0x5c,
+ 0xb9, 0xcb, 0x43, 0x52, 0xab, 0x12, 0xbf, 0x09, 0xc7, 0xb6, 0x95, 0x5d,
+ 0x0b, 0xbc, 0xba, 0x38, 0x1f, 0xbf, 0x3d, 0x01, 0xff, 0xe1, 0x8c, 0x38,
+ 0x13, 0xbd, 0xd8, 0x13, 0x9f, 0x45, 0x66, 0x2e, 0xff, 0x3a, 0x19, 0xd0,
+ 0x05, 0xbf, 0x3e, 0x84, 0xb3, 0x8c, 0xc8, 0x59, 0xd8, 0xff, 0xe7, 0x40,
+ 0x47, 0x9f, 0xaf, 0x0c, 0xc9, 0xf9, 0x4a, 0x1c, 0xfe, 0x16, 0xed, 0x94,
+ 0xe5, 0xe9, 0xe4, 0x3a, 0xcb, 0x27, 0xa6, 0x53, 0x75, 0x96, 0x5f, 0x32,
+ 0xfe, 0xe2, 0x97, 0x8d, 0x1f, 0xb9, 0x3e, 0xad, 0x7d, 0xb8, 0xaf, 0x4d,
+ 0x8f, 0xaa, 0xb2, 0x39, 0xbd, 0x13, 0x3b, 0x09, 0x1b, 0xbd, 0x9d, 0xa1,
+ 0x7e, 0x06, 0x8c, 0x12, 0x3c, 0x09, 0x7a, 0x9a, 0x87, 0xdc, 0xce, 0xc1,
+ 0xf7, 0x38, 0x0b, 0x1f, 0xa4, 0xd8, 0x84, 0x4c, 0xf0, 0xd2, 0x28, 0xc5,
+ 0xfc, 0xf9, 0x63, 0xbb, 0x18, 0xdf, 0xe4, 0x99, 0x19, 0xff, 0x2b, 0x4d,
+ 0xff, 0xab, 0xf3, 0x8f, 0xf3, 0x81, 0x36, 0xa9, 0x2b, 0x7f, 0x09, 0x9f,
+ 0x51, 0x82, 0xc5, 0x0c, 0xc7, 0xa6, 0xe9, 0xaf, 0xca, 0x36, 0xec, 0x83,
+ 0xb0, 0xf7, 0x3d, 0x09, 0x3f, 0xd5, 0x6a, 0xbd, 0x0a, 0x59, 0x53, 0x82,
+ 0xcf, 0x68, 0x5b, 0xa8, 0x5f, 0x67, 0x1b, 0xe5, 0xc8, 0x98, 0x73, 0x1b,
+ 0x34, 0x97, 0x3d, 0x2e, 0xf2, 0x5d, 0xd4, 0x35, 0x56, 0x78, 0x06, 0xdf,
+ 0xc7, 0x19, 0x98, 0x33, 0x51, 0x75, 0xec, 0x07, 0xfb, 0x3d, 0xca, 0x7d,
+ 0x8c, 0x39, 0xdd, 0x18, 0x5f, 0x5f, 0xe7, 0x98, 0xc4, 0x24, 0xaf, 0x74,
+ 0xbe, 0xbb, 0xae, 0xf7, 0x77, 0x34, 0x33, 0x2a, 0x57, 0x2b, 0x6a, 0x0e,
+ 0xd0, 0xfa, 0xaf, 0x30, 0x66, 0x0b, 0x74, 0xcb, 0x18, 0x95, 0x27, 0x65,
+ 0xe8, 0xa4, 0x72, 0x25, 0x05, 0xda, 0x09, 0xca, 0x6c, 0x8c, 0x60, 0xbb,
+ 0xb2, 0x5d, 0xf9, 0x72, 0x97, 0x8e, 0x8f, 0xf0, 0x19, 0x3a, 0xac, 0x39,
+ 0x23, 0xbc, 0x1b, 0x81, 0x7d, 0x83, 0x3d, 0x75, 0xe2, 0x42, 0xff, 0x15,
+ 0x71, 0x16, 0x66, 0x8f, 0xea, 0x4f, 0xaf, 0x83, 0xf1, 0x66, 0x9d, 0x02,
+ 0x14, 0x77, 0x1e, 0xeb, 0xa7, 0x2e, 0x05, 0x83, 0x8c, 0xa9, 0x27, 0x2f,
+ 0x81, 0xad, 0x3c, 0x83, 0x8b, 0xa6, 0x4f, 0x6b, 0xbe, 0x2f, 0x4a, 0xda,
+ 0x22, 0x0e, 0x12, 0xa5, 0x2d, 0x20, 0x7b, 0xc0, 0xbb, 0x21, 0x1f, 0x5a,
+ 0xd5, 0x7b, 0xb6, 0x2f, 0x0a, 0xef, 0x5b, 0xe4, 0xf6, 0x4a, 0x22, 0x7d,
+ 0x0b, 0xb2, 0x39, 0x1f, 0x4d, 0x83, 0x56, 0x3e, 0xd1, 0x05, 0x9e, 0x9e,
+ 0xcc, 0xda, 0x3f, 0xe8, 0xd2, 0xb6, 0x20, 0x7c, 0x7e, 0xc6, 0x01, 0x2a,
+ 0x59, 0x8c, 0xe9, 0x96, 0x7f, 0x11, 0xc4, 0x73, 0x93, 0xef, 0xb0, 0x73,
+ 0x82, 0x1a, 0xbe, 0xb2, 0xc1, 0x21, 0xfc, 0x04, 0xd1, 0xb1, 0x5c, 0x4b,
+ 0x3e, 0x04, 0x29, 0x2f, 0x98, 0x3f, 0x69, 0xd6, 0x4a, 0x5e, 0x0c, 0xb7,
+ 0x6d, 0xba, 0xd4, 0xaa, 0x07, 0xdb, 0x22, 0x68, 0x7c, 0x22, 0xca, 0x18,
+ 0xd9, 0xc3, 0xa6, 0xee, 0xb4, 0x8f, 0xc3, 0x2a, 0x5e, 0xc7, 0x7b, 0x24,
+ 0xd2, 0xd6, 0x94, 0xa1, 0xad, 0x8f, 0x81, 0xb6, 0x4e, 0x29, 0xda, 0x6a,
+ 0xc9, 0xab, 0xe9, 0xb4, 0x7c, 0x61, 0x4f, 0xfa, 0xda, 0xfd, 0x17, 0x01,
+ 0xbc, 0xfc, 0x0d, 0xca, 0xc2, 0x17, 0xb1, 0x2e, 0xf4, 0x4e, 0xb9, 0x92,
+ 0xc8, 0xce, 0xd2, 0x16, 0x82, 0x1e, 0x29, 0xc3, 0xe7, 0x4a, 0x5e, 0x1a,
+ 0x52, 0x7d, 0x92, 0xd0, 0x29, 0x0d, 0xd0, 0x1b, 0xf1, 0x5b, 0xae, 0x40,
+ 0x0e, 0x5f, 0x0a, 0x41, 0x6f, 0x91, 0x67, 0x65, 0xc0, 0x86, 0x6c, 0x60,
+ 0xff, 0x06, 0x78, 0x27, 0x79, 0x29, 0x82, 0x32, 0xae, 0xe6, 0x6a, 0x54,
+ 0x5c, 0x35, 0xbe, 0x51, 0x19, 0x55, 0xe3, 0x1a, 0xb0, 0x5f, 0x93, 0x97,
+ 0x20, 0xdf, 0x33, 0x69, 0x19, 0xb9, 0x94, 0x91, 0xf8, 0x25, 0x4b, 0x8a,
+ 0x33, 0xad, 0x56, 0x18, 0xb0, 0x8f, 0x5e, 0xea, 0x97, 0x5b, 0x2a, 0xb6,
+ 0x1a, 0x56, 0xf1, 0xd6, 0xc5, 0xcc, 0x0c, 0x78, 0x93, 0xf8, 0xf3, 0x30,
+ 0xa6, 0x00, 0xfd, 0x58, 0x90, 0xb3, 0x2b, 0xc4, 0x0f, 0xe3, 0xe5, 0xdb,
+ 0xb1, 0x80, 0x24, 0x20, 0xcb, 0x8e, 0xcb, 0x7c, 0xad, 0x1b, 0xb2, 0x2c,
+ 0x08, 0x1d, 0xf8, 0x50, 0xb7, 0xf4, 0x0e, 0x93, 0x1e, 0x80, 0x17, 0x0f,
+ 0x73, 0x17, 0x24, 0x8f, 0x31, 0x85, 0x95, 0x9d, 0xfe, 0x45, 0xe9, 0x06,
+ 0x4f, 0x1d, 0x97, 0x93, 0x35, 0xce, 0x13, 0x74, 0xca, 0x72, 0x10, 0x34,
+ 0xe4, 0x3a, 0x47, 0x30, 0x0f, 0xf4, 0x76, 0xc7, 0x1f, 0xf9, 0x2f, 0xfb,
+ 0x06, 0x34, 0xe9, 0xf3, 0x5d, 0xb8, 0xd4, 0xe5, 0xcd, 0x58, 0xdb, 0x19,
+ 0x09, 0xce, 0x65, 0x3e, 0x60, 0x7d, 0x37, 0x93, 0xb1, 0xae, 0x65, 0xb2,
+ 0xd6, 0xf5, 0x4c, 0xc1, 0xba, 0x01, 0xdd, 0xd4, 0xd8, 0x7c, 0x0e, 0xf4,
+ 0x03, 0xdd, 0xcf, 0x98, 0x79, 0xfb, 0x0c, 0xa3, 0x26, 0x66, 0xf0, 0x9a,
+ 0x6c, 0x54, 0x68, 0x3b, 0xb4, 0x1e, 0x9e, 0x4b, 0x97, 0xee, 0x01, 0x7c,
+ 0x80, 0x83, 0xbe, 0xee, 0x8e, 0xee, 0x08, 0x79, 0xa3, 0xb2, 0xa6, 0x74,
+ 0x47, 0x84, 0xba, 0x23, 0x9d, 0x97, 0xfd, 0xb2, 0x5d, 0x03, 0xff, 0x89,
+ 0xb2, 0x83, 0x65, 0xbb, 0x1e, 0x95, 0x2f, 0x54, 0x7d, 0x5a, 0xe2, 0x7e,
+ 0xcb, 0x6f, 0xea, 0x91, 0x80, 0x4c, 0x29, 0x7d, 0xdd, 0x27, 0x57, 0xd7,
+ 0xe1, 0x0f, 0xc1, 0x5a, 0xb0, 0xef, 0x63, 0xac, 0xc0, 0x56, 0xbe, 0xb1,
+ 0xf4, 0xf3, 0xee, 0xea, 0x2c, 0x70, 0xc5, 0xfb, 0x25, 0xec, 0xb3, 0x9f,
+ 0x3b, 0xf2, 0xdf, 0xc7, 0xc1, 0x93, 0x7c, 0xb6, 0x24, 0x0f, 0xbb, 0x91,
+ 0xf7, 0x5c, 0x79, 0xd8, 0x3d, 0xdb, 0x95, 0x31, 0xc0, 0x15, 0x80, 0x4d,
+ 0x1e, 0x06, 0x1c, 0x55, 0xd5, 0xde, 0xed, 0x8a, 0x35, 0x07, 0x3d, 0x5c,
+ 0x54, 0xf7, 0x57, 0x28, 0xd7, 0xf5, 0xda, 0x79, 0xf8, 0xab, 0xc5, 0xf1,
+ 0x1e, 0xea, 0xb7, 0xd1, 0x12, 0xf9, 0x5e, 0xd9, 0xf1, 0x19, 0xf0, 0xdc,
+ 0x57, 0xba, 0xa9, 0xdb, 0x8f, 0xa6, 0x27, 0xe5, 0x46, 0x85, 0xcf, 0x6c,
+ 0x4f, 0xa4, 0x45, 0xc5, 0x8f, 0x2b, 0xd3, 0x8b, 0xee, 0x6b, 0x86, 0xc7,
+ 0x6a, 0xa0, 0xf1, 0x53, 0xf2, 0x8d, 0xcd, 0x79, 0xf9, 0xf7, 0x9b, 0xb3,
+ 0xb0, 0x4f, 0x4e, 0xc0, 0x3e, 0xf9, 0x08, 0x78, 0xf8, 0x38, 0x78, 0xf8,
+ 0xe3, 0xa0, 0xfb, 0x19, 0x15, 0x77, 0xa8, 0x55, 0x12, 0x57, 0x4a, 0x2a,
+ 0xce, 0xfd, 0x1a, 0x68, 0x7e, 0x42, 0x82, 0xab, 0x43, 0xc0, 0x6b, 0xa9,
+ 0x15, 0x75, 0x5b, 0x0f, 0xc3, 0x06, 0xc1, 0x59, 0x97, 0x12, 0x41, 0x45,
+ 0x23, 0xae, 0xf3, 0x69, 0xe0, 0xf2, 0x4d, 0x5e, 0xa2, 0xc6, 0x23, 0xde,
+ 0xa8, 0x8d, 0x4a, 0xf1, 0x32, 0xfa, 0x2f, 0x47, 0x80, 0x37, 0xea, 0xc6,
+ 0xc4, 0xf9, 0xa2, 0x6c, 0x81, 0x2e, 0xb2, 0xc0, 0xcf, 0x3b, 0xa4, 0x1c,
+ 0x4d, 0x7c, 0x4d, 0x64, 0x52, 0x0e, 0x2d, 0x81, 0xa6, 0x97, 0x6c, 0xec,
+ 0x99, 0xb8, 0xc4, 0xf3, 0x65, 0x4f, 0xec, 0x65, 0xca, 0xa2, 0x03, 0xc6,
+ 0x37, 0xd1, 0xfa, 0xbe, 0x2e, 0x5c, 0x97, 0xeb, 0x7d, 0x46, 0xe6, 0xa1,
+ 0x53, 0x61, 0x7f, 0x43, 0x66, 0xbb, 0x31, 0xac, 0x19, 0x9e, 0xbb, 0xec,
+ 0x84, 0xe7, 0x2f, 0x73, 0x9e, 0xb0, 0x04, 0x96, 0x78, 0xb6, 0x9c, 0x07,
+ 0x3c, 0x80, 0xb9, 0x53, 0x4b, 0xc4, 0xdb, 0x18, 0xc6, 0xfd, 0x63, 0xe8,
+ 0x63, 0x4d, 0x57, 0xb9, 0x65, 0x2d, 0x1f, 0x72, 0x8d, 0x4e, 0x9d, 0x88,
+ 0x33, 0x80, 0xfc, 0xc8, 0x36, 0xb4, 0x7e, 0x2b, 0x28, 0xfd, 0xa7, 0x75,
+ 0xdf, 0x71, 0x81, 0x51, 0xd7, 0xeb, 0xaa, 0xfd, 0x04, 0x96, 0xb7, 0xa8,
+ 0xef, 0xb1, 0x06, 0xc7, 0x84, 0x3a, 0xe0, 0xce, 0x40, 0xee, 0xdc, 0x1b,
+ 0x26, 0xee, 0x1f, 0x83, 0x7e, 0x4d, 0x2e, 0xe9, 0x98, 0x7c, 0xf2, 0x72,
+ 0x1a, 0xfb, 0x91, 0x41, 0x46, 0x17, 0x6c, 0xec, 0xe1, 0x7d, 0x4a, 0x7e,
+ 0x4d, 0x40, 0x66, 0x39, 0xb2, 0x7e, 0x90, 0x67, 0x33, 0x28, 0x8d, 0xa7,
+ 0xf9, 0xce, 0x33, 0xe2, 0x79, 0x93, 0x17, 0xa3, 0xd0, 0x2f, 0x38, 0xa7,
+ 0xbe, 0x21, 0xa9, 0x6f, 0xb2, 0x6d, 0x48, 0xd1, 0x72, 0x10, 0x67, 0xb0,
+ 0x58, 0x69, 0x3d, 0x9c, 0x4b, 0x97, 0x40, 0x6d, 0xc4, 0x39, 0xf1, 0x41,
+ 0xbc, 0x8f, 0x03, 0x36, 0xe2, 0xb8, 0x8f, 0xba, 0x18, 0x75, 0xfb, 0xa5,
+ 0x58, 0x23, 0x3d, 0xa3, 0xac, 0xef, 0x37, 0xbe, 0xde, 0x67, 0x78, 0x27,
+ 0x84, 0xbd, 0x6b, 0x3a, 0x2e, 0x80, 0xa6, 0xca, 0xf0, 0xbb, 0xae, 0x2e,
+ 0x49, 0xf8, 0x4d, 0x90, 0xcf, 0x9f, 0xa2, 0x0c, 0x05, 0x7d, 0x95, 0xd7,
+ 0x27, 0x40, 0x6b, 0x7d, 0x90, 0x97, 0xad, 0xd6, 0x71, 0xd8, 0xc9, 0xa7,
+ 0xd3, 0xc4, 0xd1, 0x4d, 0xe0, 0xa8, 0x3b, 0x76, 0x1a, 0xe7, 0xb5, 0xf6,
+ 0xf4, 0x43, 0x4a, 0x5e, 0xc0, 0xd6, 0x51, 0x7a, 0x4b, 0xc7, 0x38, 0xd2,
+ 0xb4, 0x8d, 0x14, 0x0f, 0xe7, 0x5c, 0xca, 0xc3, 0x3c, 0xf0, 0x30, 0xae,
+ 0xe4, 0xb7, 0x96, 0x2d, 0x3d, 0x52, 0x3c, 0x9e, 0xc5, 0x7e, 0x27, 0x77,
+ 0xf5, 0xcb, 0xe0, 0x1d, 0xb6, 0x5f, 0xf3, 0x43, 0x61, 0xc6, 0x43, 0x03,
+ 0xde, 0xa4, 0x6c, 0x1c, 0x9c, 0x92, 0x8b, 0x07, 0x13, 0x93, 0xb3, 0x36,
+ 0x75, 0xc2, 0x94, 0xd4, 0x9f, 0xce, 0xca, 0x5a, 0x55, 0xeb, 0xe6, 0x39,
+ 0x77, 0x52, 0xf2, 0xcd, 0x02, 0xde, 0x3d, 0x94, 0xec, 0xef, 0xcb, 0x5d,
+ 0x7f, 0x4f, 0x39, 0xee, 0x09, 0x32, 0x42, 0xeb, 0x5e, 0xdb, 0xee, 0xc6,
+ 0xf9, 0x50, 0x2e, 0x7c, 0x10, 0xf5, 0x39, 0xc8, 0x36, 0x9e, 0x67, 0x0a,
+ 0x67, 0x77, 0x4a, 0x9d, 0x53, 0x3e, 0x4d, 0x7f, 0x80, 0x63, 0x12, 0xb1,
+ 0x39, 0xd4, 0xcf, 0x08, 0x75, 0x28, 0xf7, 0xe6, 0xcf, 0xe7, 0x19, 0xf8,
+ 0x03, 0x8c, 0x31, 0xe1, 0xef, 0x33, 0x61, 0xf2, 0x64, 0xc0, 0xf5, 0xeb,
+ 0xc7, 0xa0, 0x7f, 0x43, 0x6a, 0x8d, 0x72, 0x95, 0x75, 0x29, 0x87, 0xe3,
+ 0xf3, 0x69, 0xbe, 0x8b, 0x3c, 0x66, 0xfc, 0xf2, 0xe3, 0xf0, 0x5b, 0xf3,
+ 0xcd, 0xae, 0xdf, 0xa0, 0x7f, 0x77, 0x64, 0x9d, 0x96, 0xcb, 0xdb, 0x31,
+ 0xc7, 0xc8, 0xde, 0x93, 0x35, 0xc6, 0xac, 0x2d, 0xe9, 0x82, 0x2c, 0x3d,
+ 0x2a, 0xc3, 0x46, 0x8e, 0x72, 0x3f, 0x7d, 0x4a, 0xd7, 0xe5, 0x67, 0x62,
+ 0x72, 0x6e, 0xed, 0xff, 0x85, 0xae, 0x7f, 0xbd, 0x5d, 0x57, 0xd8, 0xc3,
+ 0xae, 0xbb, 0x79, 0x19, 0xf2, 0xa0, 0x0a, 0x59, 0x51, 0x85, 0xac, 0xa8,
+ 0x42, 0x56, 0x54, 0x21, 0x2b, 0xaa, 0x90, 0x15, 0x55, 0xc8, 0x8a, 0xea,
+ 0x8c, 0xd1, 0x9b, 0xa7, 0x21, 0x73, 0xe9, 0xf3, 0xd0, 0xcf, 0xe9, 0xb4,
+ 0x05, 0xe2, 0x90, 0x25, 0xf4, 0x67, 0x12, 0xa5, 0x5b, 0xc0, 0xcd, 0xd7,
+ 0xd3, 0xf4, 0xb9, 0x5b, 0xf2, 0x57, 0xe9, 0xce, 0xdd, 0xab, 0xf8, 0x86,
+ 0x3c, 0x0a, 0x7c, 0x7d, 0x08, 0xf8, 0xfa, 0xf0, 0x5d, 0x39, 0x16, 0x7e,
+ 0x4c, 0x64, 0xb8, 0x14, 0x80, 0xff, 0x39, 0x73, 0x07, 0xee, 0xe8, 0x7b,
+ 0x63, 0x8d, 0xbb, 0x6c, 0x63, 0xfa, 0xdc, 0xa3, 0xea, 0xde, 0x7c, 0x03,
+ 0x76, 0xf9, 0x8d, 0x74, 0x29, 0x12, 0x50, 0xf7, 0x73, 0x2e, 0x69, 0x67,
+ 0x8f, 0xbf, 0x6f, 0x84, 0xb5, 0x5c, 0xd4, 0x67, 0x9f, 0xcf, 0xf4, 0x81,
+ 0x0f, 0x68, 0xdf, 0xdd, 0x50, 0xf6, 0xdd, 0xd1, 0x74, 0x50, 0xb6, 0xa2,
+ 0xd4, 0xa9, 0x3f, 0x92, 0x93, 0x2b, 0x91, 0x1e, 0xfa, 0xdf, 0x8b, 0xd5,
+ 0x83, 0xb2, 0xad, 0x64, 0xca, 0x07, 0xd1, 0xd7, 0x93, 0x79, 0xd0, 0xc4,
+ 0x11, 0xf8, 0x8e, 0x17, 0x65, 0x2c, 0x76, 0x11, 0x7b, 0xfd, 0x3c, 0xc6,
+ 0xc0, 0x07, 0x68, 0x15, 0x50, 0x77, 0x1d, 0x7e, 0xc6, 0x6d, 0xe1, 0xf3,
+ 0x98, 0x73, 0x1e, 0x88, 0xce, 0x3a, 0x29, 0xe7, 0x35, 0xf1, 0xe9, 0x8c,
+ 0x34, 0xc5, 0xbb, 0xb6, 0x41, 0xc9, 0xaf, 0xd3, 0x2f, 0xeb, 0x03, 0x1f,
+ 0xfe, 0x08, 0x7a, 0x98, 0x6b, 0x50, 0x2e, 0x70, 0x0f, 0xff, 0x0d, 0xf0,
+ 0xc5, 0x67, 0xbb, 0xbd, 0xfb, 0xa1, 0x7b, 0x29, 0xf7, 0xb5, 0xef, 0x94,
+ 0xc7, 0x18, 0xa5, 0x1b, 0xd2, 0xbc, 0x77, 0xe0, 0xfe, 0xfe, 0x18, 0x76,
+ 0x4e, 0x14, 0x74, 0x80, 0xfa, 0x75, 0xdf, 0xce, 0xf5, 0xed, 0x19, 0x1d,
+ 0xeb, 0xbb, 0xa2, 0x6c, 0x9a, 0x1c, 0xf4, 0xd8, 0x31, 0xf4, 0x65, 0xac,
+ 0xbd, 0xd5, 0x3a, 0x95, 0x86, 0xdf, 0xf1, 0x24, 0x65, 0xd9, 0x7d, 0xe0,
+ 0x69, 0xda, 0x45, 0xd4, 0xb9, 0x62, 0xdd, 0xcc, 0x6c, 0x3b, 0x61, 0xe8,
+ 0xcb, 0x19, 0xd0, 0x5c, 0x0e, 0x74, 0x18, 0x78, 0x60, 0x0a, 0xfa, 0x57,
+ 0xc5, 0x9c, 0x41, 0xeb, 0x5c, 0xf7, 0x83, 0xd6, 0x5f, 0x64, 0xc6, 0xa1,
+ 0x8f, 0x1f, 0x82, 0x3e, 0xe6, 0x7d, 0x74, 0x0e, 0x3a, 0x99, 0xfa, 0xd8,
+ 0x91, 0x3f, 0xdd, 0xcc, 0x41, 0x76, 0xdd, 0xd7, 0x43, 0x5e, 0x9b, 0x6a,
+ 0xf3, 0x54, 0xc1, 0xf0, 0xdc, 0x01, 0x13, 0xfb, 0x28, 0x28, 0xde, 0x2c,
+ 0xaf, 0xd3, 0x0e, 0x01, 0x9f, 0xae, 0x53, 0x46, 0xd0, 0xa6, 0xa4, 0xec,
+ 0x80, 0xac, 0x59, 0xff, 0x00, 0xca, 0x29, 0x94, 0xda, 0x56, 0xbb, 0x52,
+ 0x7d, 0x35, 0xec, 0xdf, 0x23, 0xef, 0xd8, 0x6b, 0x75, 0xec, 0xef, 0x18,
+ 0x73, 0x1b, 0x4a, 0xfd, 0xde, 0x47, 0xb0, 0xc7, 0xe3, 0xa0, 0xc1, 0x19,
+ 0xd0, 0xe0, 0x14, 0xf6, 0x7a, 0xde, 0x1a, 0x39, 0x1c, 0x80, 0x3e, 0x3f,
+ 0x23, 0x85, 0x34, 0x64, 0xee, 0x5a, 0xc9, 0x9a, 0x58, 0x12, 0xf5, 0x9e,
+ 0x4f, 0xf3, 0x4e, 0xfd, 0xbd, 0x2a, 0x3e, 0xb8, 0xbc, 0x19, 0x34, 0x71,
+ 0xc4, 0x20, 0xea, 0xa8, 0xc3, 0x21, 0xb3, 0x1c, 0xcc, 0x55, 0xfd, 0x59,
+ 0xaf, 0xf4, 0x62, 0xbe, 0xea, 0x34, 0xde, 0x19, 0x5b, 0x38, 0x66, 0xdd,
+ 0x59, 0xcf, 0xd8, 0x45, 0xc2, 0xc9, 0xc1, 0x17, 0x0d, 0xba, 0x8c, 0x5f,
+ 0xb8, 0x38, 0x9f, 0xac, 0xe4, 0x47, 0x60, 0x93, 0x29, 0x99, 0xdc, 0x6b,
+ 0x64, 0x32, 0xe4, 0x5d, 0xcd, 0x93, 0xb5, 0x4d, 0xda, 0x4e, 0x9e, 0xf2,
+ 0xa7, 0x29, 0xc7, 0x8a, 0x35, 0xd8, 0x3f, 0xe9, 0xdf, 0xb3, 0xb2, 0x6a,
+ 0xce, 0xb0, 0xca, 0xd5, 0x28, 0xad, 0x89, 0xe5, 0x1c, 0xbe, 0x09, 0xff,
+ 0x35, 0x03, 0x1e, 0xf6, 0x20, 0x37, 0x1d, 0xc8, 0x45, 0xea, 0xb5, 0xaf,
+ 0x76, 0x4b, 0x1f, 0xea, 0x2f, 0xc3, 0xe6, 0x79, 0x92, 0x7c, 0x7b, 0x5d,
+ 0xec, 0xc6, 0x1b, 0xc5, 0x47, 0x18, 0x1b, 0x19, 0x32, 0x77, 0xb3, 0xff,
+ 0x0b, 0xf0, 0xea, 0x35, 0x42, 0xb0, 0xeb, 0xaf, 0xd6, 0xf6, 0xc1, 0x47,
+ 0x3c, 0x66, 0xe5, 0xa3, 0xac, 0x2b, 0xc9, 0x7a, 0x86, 0x76, 0x28, 0x63,
+ 0x24, 0x61, 0xd4, 0xef, 0xf6, 0x49, 0xa9, 0xff, 0x9f, 0x53, 0x77, 0x34,
+ 0x0b, 0x4a, 0xee, 0xfa, 0xf1, 0xe5, 0xe7, 0x24, 0xd9, 0xf4, 0xe3, 0x54,
+ 0x5c, 0x7f, 0xcb, 0x2a, 0x36, 0xff, 0x1c, 0xeb, 0x10, 0x06, 0xee, 0x45,
+ 0xaf, 0x63, 0x2f, 0x4f, 0x98, 0x75, 0x1c, 0x2b, 0x74, 0x38, 0x86, 0xfd,
+ 0xec, 0xef, 0x93, 0xbe, 0x00, 0xe4, 0xd9, 0x28, 0x9e, 0x6f, 0xa1, 0x6e,
+ 0xe7, 0xbd, 0x51, 0x15, 0x2b, 0x70, 0x18, 0xde, 0x33, 0xf4, 0x77, 0x03,
+ 0x32, 0xc7, 0x86, 0xfe, 0x6c, 0x54, 0x3f, 0x8e, 0x12, 0xe3, 0x9e, 0xbc,
+ 0x2e, 0x73, 0xda, 0xdf, 0x86, 0x4d, 0x39, 0xac, 0x74, 0xf0, 0x4c, 0x9a,
+ 0xb1, 0x90, 0x33, 0x90, 0x8f, 0xf7, 0xa3, 0x8e, 0x7e, 0x53, 0x49, 0x9c,
+ 0xf7, 0x14, 0x8c, 0xbf, 0xaf, 0xcf, 0x25, 0xa0, 0xf4, 0xf5, 0x0a, 0xce,
+ 0x83, 0x73, 0x50, 0xdf, 0xfd, 0x5c, 0x3e, 0xd5, 0x11, 0x47, 0xc9, 0xd9,
+ 0xed, 0xb8, 0x41, 0x36, 0x0f, 0x1d, 0xbd, 0x56, 0x25, 0x0f, 0x66, 0x70,
+ 0xde, 0x59, 0xf9, 0xda, 0xe6, 0x3d, 0xc0, 0x75, 0x54, 0x02, 0x4f, 0xb5,
+ 0x40, 0x3f, 0xd4, 0x0d, 0x63, 0x90, 0xc9, 0x8e, 0xb1, 0x25, 0xa2, 0x12,
+ 0x7c, 0x6a, 0x48, 0xba, 0x2f, 0xc4, 0xa4, 0xeb, 0x02, 0xf3, 0x4f, 0x52,
+ 0x71, 0xd8, 0xc5, 0xb4, 0x87, 0x78, 0x0f, 0xc9, 0xfb, 0xc3, 0xb8, 0xbe,
+ 0x8f, 0xe4, 0x5d, 0x24, 0xfa, 0xc1, 0x76, 0xef, 0xba, 0xe4, 0x00, 0x3f,
+ 0x7a, 0xce, 0xdd, 0x63, 0xcb, 0x7a, 0x2c, 0xef, 0x31, 0x63, 0x25, 0x49,
+ 0x99, 0x7b, 0xcc, 0x14, 0xc6, 0xa6, 0x26, 0x5f, 0x6e, 0x8f, 0xe7, 0x58,
+ 0xea, 0xc4, 0x28, 0xf8, 0xfb, 0xad, 0xd2, 0xf8, 0x22, 0xf9, 0xdc, 0xbf,
+ 0xeb, 0x1a, 0x32, 0x77, 0x5f, 0xec, 0x13, 0x37, 0xed, 0x49, 0xd3, 0xee,
+ 0x2a, 0x3d, 0x19, 0x6c, 0xc7, 0x5b, 0x78, 0x2f, 0x96, 0x38, 0xcf, 0xe4,
+ 0x11, 0x7d, 0x47, 0x46, 0x5f, 0x0a, 0xbe, 0xc5, 0x93, 0xb0, 0x31, 0xeb,
+ 0x2c, 0x7b, 0xa4, 0x5c, 0x3f, 0x25, 0xb3, 0xea, 0xf9, 0x43, 0xf2, 0xa8,
+ 0x43, 0xdc, 0x9d, 0x91, 0xf4, 0x84, 0xb6, 0xc7, 0xc4, 0xd6, 0xb8, 0xed,
+ 0x76, 0xcf, 0xc8, 0xd1, 0xb4, 0xd2, 0x21, 0xce, 0x23, 0xc0, 0x71, 0xb1,
+ 0xd9, 0x45, 0x7a, 0x07, 0xec, 0x1e, 0x78, 0x2c, 0x2b, 0x17, 0x37, 0xd1,
+ 0x17, 0x67, 0xf5, 0x08, 0xdf, 0xeb, 0xc0, 0x27, 0x63, 0x16, 0x4f, 0x11,
+ 0x9f, 0xdc, 0x3b, 0x75, 0x28, 0x71, 0x4a, 0x1c, 0x50, 0x2f, 0x33, 0xe6,
+ 0x96, 0x98, 0xbc, 0x2d, 0xf4, 0x9b, 0x89, 0x33, 0xce, 0xe3, 0xef, 0x5b,
+ 0x8f, 0xb3, 0x37, 0x06, 0x85, 0xe6, 0x98, 0x7d, 0xc1, 0x11, 0xfb, 0x12,
+ 0xcb, 0x08, 0x4a, 0xb6, 0x01, 0xa4, 0x8d, 0xa4, 0x69, 0x73, 0x51, 0x07,
+ 0x3b, 0xf2, 0x09, 0xf2, 0x96, 0xce, 0xff, 0x4b, 0x8e, 0x4c, 0xca, 0x95,
+ 0xb5, 0xbb, 0xf9, 0x2b, 0x70, 0x41, 0xdb, 0x25, 0x77, 0xf2, 0xd7, 0xe4,
+ 0x3f, 0x80, 0xbf, 0xb8, 0xc6, 0x19, 0x95, 0xbb, 0xf0, 0xa9, 0x68, 0x22,
+ 0x9e, 0xd5, 0xfe, 0x85, 0x93, 0xb2, 0x47, 0xe2, 0xb4, 0x47, 0x1b, 0x4f,
+ 0x8e, 0xe3, 0xdc, 0x5b, 0xf2, 0x44, 0xda, 0xa7, 0x2f, 0xe6, 0xf8, 0xb5,
+ 0xa4, 0x06, 0xfd, 0x5c, 0x76, 0x2d, 0x59, 0x70, 0xcf, 0x28, 0x7b, 0xf2,
+ 0xc3, 0xd1, 0x96, 0x9c, 0x4e, 0xeb, 0xb1, 0x0b, 0x32, 0x62, 0x68, 0x5c,
+ 0xf9, 0x6b, 0x90, 0xbf, 0x3c, 0x2f, 0xbe, 0xdf, 0x23, 0xe9, 0x81, 0x33,
+ 0x92, 0x9c, 0xd8, 0x22, 0xbe, 0x70, 0x0e, 0x94, 0x3b, 0xbf, 0x36, 0x16,
+ 0xa6, 0x72, 0x9e, 0xf2, 0x15, 0xc2, 0xb4, 0x0f, 0x74, 0x9b, 0x85, 0xbf,
+ 0xb4, 0x13, 0x0f, 0x4b, 0x8d, 0x94, 0x5a, 0x21, 0xac, 0x5d, 0x84, 0x3f,
+ 0xf1, 0xe1, 0xa8, 0x1b, 0x1f, 0xb6, 0x47, 0x62, 0x67, 0xa5, 0xa6, 0x60,
+ 0xfd, 0x44, 0x5a, 0xd3, 0xcb, 0x62, 0x66, 0xaf, 0x18, 0x55, 0x67, 0x8c,
+ 0x9a, 0x73, 0x6d, 0x59, 0x9f, 0x6c, 0xea, 0x78, 0xd4, 0x4e, 0x9c, 0x7a,
+ 0x47, 0xe6, 0x04, 0x8d, 0x2c, 0x28, 0xd7, 0xde, 0x25, 0xbe, 0xcc, 0xa9,
+ 0x65, 0x70, 0x56, 0xcb, 0x3c, 0xa3, 0xb8, 0xb9, 0x47, 0x0a, 0x77, 0xd8,
+ 0xca, 0x21, 0xe6, 0xfd, 0xc5, 0xb3, 0xf6, 0x32, 0x64, 0xc3, 0x93, 0x12,
+ 0x72, 0xfd, 0xb9, 0x98, 0xd3, 0x19, 0x33, 0xf7, 0x11, 0xfb, 0x19, 0xb7,
+ 0x42, 0x9f, 0x07, 0xd1, 0x7e, 0x3f, 0xfa, 0x51, 0x57, 0xf2, 0x1e, 0x80,
+ 0x7a, 0x93, 0xb1, 0xf6, 0x01, 0xf4, 0xeb, 0x91, 0x7c, 0x7d, 0xbf, 0xa9,
+ 0xf3, 0xe7, 0x38, 0xdc, 0xd1, 0xdf, 0xaf, 0xd3, 0xf7, 0x07, 0x59, 0x1b,
+ 0x32, 0x7e, 0x99, 0x7d, 0xe3, 0xed, 0x3b, 0x10, 0xbb, 0xf1, 0xa0, 0xa3,
+ 0xc7, 0xb3, 0x1f, 0x65, 0x3e, 0x74, 0x4b, 0x15, 0xfa, 0xa6, 0x3a, 0xc5,
+ 0xbb, 0x40, 0x63, 0x57, 0xcc, 0x9a, 0x7c, 0x16, 0xda, 0x17, 0xaf, 0x19,
+ 0x7d, 0xbb, 0x93, 0x8b, 0x7a, 0x24, 0xe3, 0xe7, 0xf5, 0x30, 0x17, 0x91,
+ 0xeb, 0xf2, 0x3c, 0x40, 0x53, 0x9b, 0xda, 0x96, 0xb6, 0x33, 0x5d, 0xbc,
+ 0x6b, 0x83, 0x7e, 0xd7, 0xfa, 0xbf, 0x01, 0xfd, 0xbf, 0xb1, 0x02, 0x9d,
+ 0xdf, 0x47, 0xdd, 0xaf, 0xf3, 0x4f, 0xec, 0x76, 0xbe, 0x8f, 0x7f, 0x8f,
+ 0xbc, 0xa5, 0xee, 0xf1, 0x7a, 0x3c, 0xca, 0xf4, 0x8c, 0xfc, 0x39, 0x6c,
+ 0xad, 0x67, 0x36, 0x27, 0xb1, 0x5e, 0x1a, 0x7e, 0xdd, 0x38, 0xfc, 0xba,
+ 0x51, 0xf8, 0x75, 0x2e, 0x74, 0xe1, 0x90, 0xca, 0x27, 0xa3, 0xde, 0x9f,
+ 0x38, 0x24, 0xd6, 0xd7, 0x32, 0x62, 0x1d, 0xbc, 0x00, 0x1b, 0x61, 0xe9,
+ 0x25, 0xd0, 0x7f, 0xe2, 0x79, 0x11, 0xf2, 0x04, 0xf9, 0xef, 0x31, 0xc9,
+ 0xc6, 0x86, 0xe4, 0xf3, 0x9b, 0x6c, 0x23, 0x3d, 0x65, 0xe5, 0x15, 0xf7,
+ 0x25, 0xc5, 0x67, 0x17, 0x6b, 0xd7, 0x25, 0xf4, 0x84, 0x96, 0xb5, 0x3f,
+ 0x80, 0x3d, 0xd5, 0x48, 0x6b, 0xda, 0xbb, 0x2d, 0xa4, 0x3d, 0xe8, 0xa7,
+ 0x35, 0xca, 0xd8, 0x9b, 0x12, 0xbd, 0xf0, 0x92, 0xbc, 0xf9, 0x82, 0xab,
+ 0xe2, 0x12, 0x6b, 0x4f, 0x2a, 0xdd, 0x07, 0xb9, 0x16, 0x95, 0xf5, 0xcd,
+ 0xdf, 0x91, 0x4f, 0x39, 0x89, 0x2b, 0x94, 0x99, 0x94, 0x5d, 0x5a, 0xa7,
+ 0x41, 0xc6, 0x56, 0x12, 0xa5, 0x32, 0x6c, 0xef, 0x2b, 0xf6, 0x98, 0x64,
+ 0x83, 0xa5, 0x56, 0x3f, 0xfd, 0x82, 0x9a, 0xeb, 0x24, 0x6d, 0x9e, 0xef,
+ 0xbd, 0xb0, 0xad, 0x13, 0x75, 0x25, 0xa3, 0xa8, 0x27, 0x33, 0xd4, 0x9b,
+ 0xd4, 0x7d, 0xd4, 0x3f, 0x8c, 0x97, 0xe3, 0x79, 0x8d, 0xba, 0xe9, 0xef,
+ 0xd4, 0x9d, 0x67, 0x71, 0xc6, 0x91, 0xfa, 0x1a, 0xe5, 0x13, 0xf4, 0xfc,
+ 0x93, 0xb4, 0x73, 0x45, 0xd1, 0x3f, 0xed, 0xdc, 0x47, 0xc5, 0xb7, 0x71,
+ 0xd9, 0xb6, 0xdb, 0xc6, 0xfd, 0x83, 0x7d, 0xd2, 0x1b, 0x05, 0x7e, 0xc8,
+ 0xff, 0x3b, 0x36, 0x60, 0x2e, 0x73, 0x13, 0xb6, 0x26, 0xf7, 0x61, 0xc9,
+ 0xa0, 0x7b, 0x1d, 0x74, 0xc4, 0xb5, 0x6f, 0xb6, 0x3e, 0x1c, 0xe5, 0x1e,
+ 0x2c, 0x65, 0x23, 0x6c, 0x0f, 0xfe, 0xa6, 0x3b, 0x0a, 0xca, 0x88, 0x7d,
+ 0xb0, 0xcd, 0x6d, 0x43, 0xb3, 0x9f, 0x34, 0xbe, 0x04, 0xf8, 0x79, 0x95,
+ 0x7b, 0x28, 0xf3, 0x4e, 0x04, 0x36, 0xd7, 0x22, 0x63, 0x52, 0x6a, 0xdd,
+ 0xf7, 0x67, 0x22, 0x92, 0xbc, 0xd0, 0x25, 0xa9, 0xa7, 0xec, 0x41, 0x9d,
+ 0xb7, 0xf8, 0x30, 0x74, 0xcf, 0x41, 0xb4, 0x1f, 0x90, 0xb2, 0x13, 0x85,
+ 0x3f, 0x33, 0x2a, 0xe5, 0xd1, 0x30, 0x78, 0xe6, 0x01, 0xde, 0x75, 0x28,
+ 0x38, 0xca, 0xce, 0x30, 0xca, 0x6e, 0x94, 0xf7, 0x48, 0xf9, 0xc9, 0x4b,
+ 0xfb, 0xb4, 0x2d, 0xbb, 0xfb, 0xfd, 0x9f, 0x76, 0xab, 0xd8, 0xb9, 0xf5,
+ 0x8e, 0x88, 0xb9, 0x47, 0xff, 0x2d, 0x60, 0xf7, 0xfb, 0x12, 0x9e, 0x90,
+ 0xb8, 0x4f, 0x44, 0x64, 0x18, 0xb2, 0x77, 0x04, 0x7a, 0xeb, 0xe0, 0x85,
+ 0x21, 0x19, 0xbd, 0x10, 0x97, 0xfb, 0x2e, 0xf8, 0xf6, 0xc0, 0xf2, 0x74,
+ 0xca, 0xc4, 0x71, 0xdd, 0xdf, 0x32, 0x8e, 0x7b, 0x9f, 0x9a, 0x1f, 0x30,
+ 0xae, 0x41, 0x1e, 0x46, 0x3f, 0xa7, 0xec, 0x06, 0x8d, 0xfb, 0x1f, 0xc9,
+ 0x91, 0x95, 0x90, 0x1c, 0x55, 0xbc, 0xe8, 0xdb, 0xf0, 0xff, 0x13, 0xfb,
+ 0x48, 0x80, 0x47, 0x4e, 0x18, 0xbf, 0xb3, 0x17, 0x78, 0x25, 0x0e, 0xa1,
+ 0xeb, 0xe0, 0x8b, 0x32, 0x3f, 0xb5, 0x98, 0xee, 0x1c, 0xcf, 0xb1, 0x3f,
+ 0xc5, 0x98, 0x2c, 0x6c, 0x0b, 0xb6, 0xcb, 0x60, 0x40, 0xf6, 0x6a, 0x7f,
+ 0x1f, 0xda, 0x29, 0x73, 0x8e, 0x42, 0xe6, 0xec, 0x6e, 0xcf, 0xa1, 0x8d,
+ 0xeb, 0xdf, 0x83, 0x75, 0xc9, 0x8f, 0x5c, 0xd7, 0xc7, 0x09, 0xcf, 0x75,
+ 0x10, 0xfe, 0x07, 0xcf, 0xb5, 0x4b, 0x0a, 0x0e, 0x73, 0x37, 0x59, 0xf7,
+ 0x16, 0x73, 0xd6, 0x13, 0xe6, 0xac, 0x05, 0xb6, 0x31, 0xed, 0x2d, 0x9d,
+ 0xaf, 0x50, 0x88, 0x26, 0x4a, 0x22, 0x71, 0x15, 0xbf, 0x5b, 0xaf, 0xf8,
+ 0xf6, 0x49, 0xb6, 0x9f, 0xf7, 0x10, 0x8b, 0x69, 0x15, 0x5b, 0x8b, 0x07,
+ 0x3c, 0xda, 0x37, 0xe9, 0x30, 0xf3, 0x92, 0x1b, 0x2b, 0xbc, 0x93, 0x0c,
+ 0xe0, 0x07, 0x3c, 0x07, 0x2d, 0x71, 0x5c, 0xd6, 0x95, 0xb4, 0x6e, 0x9b,
+ 0x01, 0xff, 0xda, 0xaa, 0x4f, 0x3c, 0x97, 0x1e, 0x34, 0xef, 0x31, 0x59,
+ 0xab, 0xbc, 0x63, 0xc8, 0xf6, 0xfe, 0xf6, 0x9e, 0x5c, 0xa6, 0x9f, 0xf7,
+ 0x49, 0xa8, 0x23, 0x9f, 0xbc, 0xa4, 0x72, 0x15, 0xb5, 0xef, 0x10, 0xe4,
+ 0x3d, 0x24, 0xf6, 0xf9, 0x53, 0xd0, 0xf5, 0xee, 0x3d, 0x77, 0x99, 0x3d,
+ 0x73, 0xbf, 0xc4, 0x37, 0xc7, 0xfb, 0x7a, 0x8e, 0x38, 0x0f, 0x77, 0xf8,
+ 0x1b, 0x91, 0x81, 0x9d, 0xfb, 0x73, 0xca, 0x42, 0xca, 0xbf, 0x49, 0x95,
+ 0xef, 0x72, 0xcb, 0x86, 0x1c, 0xaa, 0x42, 0x2e, 0x55, 0x21, 0x8b, 0xaa,
+ 0x90, 0x45, 0xb0, 0x41, 0x9e, 0x85, 0x5c, 0x7d, 0x06, 0xbe, 0xda, 0xd7,
+ 0xab, 0xbe, 0xfd, 0x9e, 0x85, 0x1c, 0x53, 0x36, 0x1d, 0xed, 0x9f, 0x9a,
+ 0xed, 0x75, 0xff, 0xd6, 0xf9, 0x50, 0x01, 0xcf, 0x1f, 0xd7, 0x2d, 0x45,
+ 0x35, 0x26, 0x2e, 0xf3, 0xcd, 0xbd, 0xfa, 0x72, 0x7f, 0xa1, 0x8e, 0xfd,
+ 0x9a, 0xbb, 0x7e, 0x15, 0x8b, 0xa0, 0x0c, 0xfe, 0x4d, 0x3c, 0xd0, 0x99,
+ 0xa7, 0xc9, 0x33, 0x56, 0x39, 0x42, 0x38, 0x53, 0xe2, 0x9d, 0x76, 0x61,
+ 0x59, 0x16, 0x26, 0x17, 0xa5, 0x3c, 0x69, 0xc9, 0xdc, 0x38, 0xce, 0x68,
+ 0x7c, 0x18, 0x3a, 0x32, 0x0d, 0x5d, 0xbb, 0x80, 0x79, 0xc8, 0x7f, 0x0f,
+ 0xe2, 0x5c, 0x1c, 0x73, 0x27, 0xfe, 0xa5, 0xe9, 0x5c, 0x4d, 0xac, 0x6b,
+ 0x2a, 0x47, 0x7c, 0x79, 0xfa, 0xd5, 0x95, 0x87, 0x61, 0x3f, 0x4d, 0xc8,
+ 0xd5, 0xc9, 0x87, 0x65, 0xfb, 0x8e, 0xf1, 0x38, 0x07, 0xc8, 0xe1, 0xcf,
+ 0x6f, 0xf2, 0x1e, 0xb4, 0x4b, 0x66, 0xa3, 0x8c, 0x81, 0xc1, 0xc6, 0x71,
+ 0xfb, 0x65, 0x5b, 0xf9, 0xa1, 0x07, 0xe4, 0xb6, 0xa2, 0x2d, 0xd6, 0x85,
+ 0x50, 0xa7, 0xed, 0xd1, 0xb5, 0x8a, 0x6f, 0x5b, 0x28, 0x1c, 0x99, 0x98,
+ 0x1f, 0xf5, 0x0d, 0xe3, 0x49, 0x8c, 0x2f, 0xad, 0x45, 0x76, 0x64, 0x01,
+ 0x4b, 0xff, 0x5c, 0x3b, 0xfd, 0xe3, 0xbf, 0x8e, 0xe8, 0x6f, 0x0b, 0xba,
+ 0xa4, 0x1c, 0x2d, 0xb5, 0xca, 0x6e, 0xd0, 0xba, 0xda, 0xce, 0x69, 0xf5,
+ 0xdb, 0x48, 0xcb, 0x36, 0x60, 0x25, 0x1d, 0x24, 0x55, 0xee, 0xce, 0x77,
+ 0xaa, 0x03, 0xfb, 0xf4, 0x37, 0x0a, 0x01, 0x8c, 0xe3, 0xfb, 0x89, 0x88,
+ 0x7e, 0xf7, 0xef, 0xdd, 0xdf, 0x86, 0xbe, 0x31, 0x25, 0xaf, 0xd6, 0x6a,
+ 0x01, 0xf0, 0xf0, 0x20, 0x9e, 0x5f, 0x44, 0x9f, 0x30, 0xce, 0x86, 0xb1,
+ 0xa4, 0xb7, 0xa8, 0xfc, 0x9b, 0x80, 0xeb, 0xe7, 0xf5, 0x52, 0x77, 0xff,
+ 0x67, 0xd5, 0xfe, 0xf4, 0x4a, 0x37, 0xf3, 0x55, 0x51, 0x52, 0xaf, 0xff,
+ 0x0a, 0xbe, 0x56, 0x48, 0xf2, 0x35, 0x17, 0xb6, 0x78, 0x88, 0xf4, 0x8b,
+ 0xfa, 0x7b, 0xa1, 0xa3, 0x04, 0xfc, 0xd4, 0x05, 0xbd, 0xa9, 0x70, 0x0d,
+ 0x4a, 0xa2, 0x4f, 0xef, 0xe7, 0x99, 0x6a, 0x38, 0x42, 0xde, 0xf7, 0x98,
+ 0x6f, 0x10, 0x0e, 0x78, 0x2f, 0x4d, 0xcf, 0x55, 0x68, 0x2b, 0xb5, 0x5a,
+ 0xd0, 0x65, 0xd8, 0xc9, 0xcf, 0x94, 0x5f, 0xb1, 0x2d, 0xda, 0x57, 0x5b,
+ 0x50, 0xf9, 0x96, 0x37, 0xa7, 0x35, 0x8d, 0x74, 0xde, 0x9f, 0xbc, 0xd1,
+ 0xdd, 0x49, 0x58, 0xb6, 0xd3, 0x3d, 0x86, 0x2f, 0xc2, 0xc1, 0x62, 0x25,
+ 0x12, 0x9c, 0x53, 0xf7, 0x5b, 0x5b, 0x26, 0x1f, 0xf3, 0xda, 0x74, 0xaa,
+ 0x19, 0x56, 0xb9, 0x00, 0xbc, 0x4b, 0xc8, 0x57, 0x78, 0x97, 0xa2, 0xdb,
+ 0x53, 0xa6, 0x3d, 0xd9, 0x54, 0x6d, 0x2a, 0xde, 0xc5, 0x18, 0x57, 0x37,
+ 0xca, 0xdb, 0x15, 0xca, 0x07, 0xcc, 0xaf, 0x65, 0x09, 0x60, 0x7f, 0x71,
+ 0x7a, 0x6e, 0x85, 0xf0, 0x7d, 0x7f, 0x3a, 0xb7, 0xc2, 0x1c, 0xc8, 0xff,
+ 0x34, 0x7d, 0x63, 0xc5, 0x92, 0x0d, 0x37, 0xa1, 0xe2, 0x57, 0xeb, 0x8c,
+ 0xb1, 0x72, 0x9c, 0x9a, 0xf3, 0x45, 0x23, 0x93, 0xbf, 0x37, 0x3d, 0xbc,
+ 0x1e, 0x90, 0x73, 0x66, 0x0e, 0xbe, 0xc7, 0xd7, 0xef, 0xa0, 0x6b, 0xd0,
+ 0xca, 0x15, 0xd0, 0x4a, 0x2f, 0x6c, 0x09, 0xd2, 0x37, 0x7d, 0xb2, 0x5e,
+ 0xc8, 0x01, 0xae, 0xf3, 0x8c, 0x5a, 0x27, 0x80, 0x75, 0xe6, 0x54, 0xce,
+ 0x78, 0x80, 0x79, 0xb7, 0xb0, 0x35, 0x61, 0x13, 0xba, 0x8c, 0x59, 0xdb,
+ 0xd8, 0xf3, 0x28, 0xf4, 0x12, 0xf3, 0x3f, 0xfe, 0x7b, 0x64, 0x27, 0x6f,
+ 0xfc, 0x39, 0x33, 0xee, 0x9b, 0x18, 0xc7, 0x33, 0x51, 0xf9, 0xe6, 0x6f,
+ 0xb6, 0x65, 0x58, 0xd9, 0x90, 0x3a, 0x07, 0x89, 0x30, 0xd4, 0xb1, 0x57,
+ 0xea, 0xe2, 0x2e, 0xc9, 0xab, 0x7d, 0x7d, 0x53, 0x8d, 0xb3, 0xbc, 0x6f,
+ 0x00, 0x76, 0xda, 0x25, 0x98, 0xbb, 0xaa, 0xe3, 0x6d, 0x79, 0xc5, 0xd3,
+ 0xe0, 0x91, 0x49, 0x3f, 0x57, 0x4f, 0x8f, 0xf3, 0xfb, 0x27, 0xd7, 0x8f,
+ 0x98, 0x9c, 0x8e, 0xbf, 0x6f, 0x65, 0x8f, 0xf7, 0x2a, 0x1b, 0x6c, 0xe7,
+ 0x9b, 0x08, 0x7f, 0x8c, 0xdf, 0xc7, 0xcf, 0x31, 0x7e, 0x74, 0xff, 0x0e,
+ 0xcc, 0x5b, 0xe6, 0xcc, 0x39, 0x8e, 0xb1, 0x49, 0x95, 0xaf, 0xcb, 0xba,
+ 0xe0, 0x7c, 0x86, 0x73, 0x74, 0xde, 0xf7, 0x8c, 0x83, 0x47, 0xb5, 0xcd,
+ 0x57, 0x82, 0x9d, 0x55, 0x06, 0xbf, 0x04, 0x3c, 0xca, 0xf1, 0x61, 0x13,
+ 0x57, 0x7b, 0xa3, 0x38, 0x1f, 0xef, 0x12, 0xc7, 0x21, 0x7b, 0xfc, 0xf1,
+ 0x3c, 0xc7, 0x6b, 0xd3, 0x37, 0x2a, 0xae, 0x9c, 0xad, 0xea, 0x7c, 0x47,
+ 0x8d, 0x07, 0xc6, 0x6e, 0x78, 0xb6, 0x71, 0x99, 0x73, 0xa9, 0x67, 0xe3,
+ 0xf2, 0x5d, 0xd7, 0x8f, 0xad, 0xf1, 0x7e, 0x0a, 0xfd, 0x61, 0xeb, 0x2d,
+ 0x6c, 0x72, 0xff, 0xdf, 0xc4, 0xfe, 0xe9, 0x53, 0x68, 0x5a, 0x3a, 0x08,
+ 0xb9, 0xf5, 0x1f, 0x82, 0xf0, 0x19, 0xa0, 0xbb, 0x6f, 0x05, 0x3b, 0xf7,
+ 0xe7, 0xeb, 0x6b, 0x4d, 0x97, 0x41, 0xd0, 0xc8, 0x62, 0x1b, 0xef, 0x96,
+ 0x04, 0xde, 0x39, 0x02, 0x1d, 0x64, 0x49, 0x61, 0xdc, 0x8d, 0x2d, 0xf0,
+ 0x6e, 0xc1, 0x19, 0x73, 0x1c, 0x95, 0xc7, 0x16, 0x07, 0xbc, 0x7c, 0xe6,
+ 0xb7, 0x02, 0xcc, 0x39, 0x8b, 0xab, 0x5c, 0xdd, 0x6c, 0xd4, 0x05, 0xbc,
+ 0x8e, 0xb2, 0x4f, 0xb4, 0x5e, 0xfe, 0x97, 0xfb, 0x29, 0x6b, 0xfa, 0x5d,
+ 0xff, 0xec, 0x39, 0xf7, 0x8b, 0x98, 0x3b, 0x60, 0xda, 0x7d, 0x1a, 0x09,
+ 0x30, 0xe5, 0x4d, 0x76, 0xbe, 0x01, 0xf1, 0xe3, 0x7c, 0xec, 0xff, 0x2d,
+ 0x05, 0xcb, 0x1c, 0xf4, 0xd0, 0xbc, 0xda, 0xcf, 0x0b, 0xa0, 0x05, 0xca,
+ 0x15, 0x9f, 0x7e, 0x5f, 0x00, 0xfd, 0xee, 0x63, 0x0a, 0xdf, 0x1e, 0xb4,
+ 0xe6, 0xd3, 0x18, 0xe9, 0x8b, 0xb4, 0xf5, 0x8a, 0xe2, 0xb9, 0x52, 0xfb,
+ 0xdc, 0x29, 0xb3, 0x12, 0x4e, 0xdc, 0xf6, 0xcf, 0x9d, 0xcf, 0x7b, 0xe5,
+ 0xb8, 0xfa, 0xfc, 0x91, 0xf9, 0x07, 0x9c, 0x6d, 0xda, 0x9c, 0x6d, 0xa6,
+ 0xe3, 0x9b, 0x04, 0x7f, 0x3e, 0xfa, 0xfb, 0xd4, 0xaf, 0xbc, 0x0b, 0xe2,
+ 0xf7, 0x12, 0xca, 0x44, 0x90, 0x72, 0x9a, 0x7c, 0x94, 0x8b, 0xf3, 0x3e,
+ 0xe5, 0xa4, 0x04, 0xfa, 0x60, 0xb7, 0x8c, 0x86, 0xc4, 0xff, 0x2e, 0xa9,
+ 0x4b, 0xb6, 0x9c, 0x56, 0xeb, 0x06, 0xef, 0x8d, 0x2b, 0x41, 0xd9, 0x50,
+ 0x77, 0x9f, 0xe0, 0xd1, 0xde, 0xa0, 0x2c, 0xba, 0x6d, 0x3d, 0x27, 0x75,
+ 0xf4, 0x59, 0x43, 0xdb, 0xb9, 0x36, 0x6c, 0xd4, 0x07, 0xb0, 0x21, 0xdd,
+ 0xbf, 0x6f, 0x15, 0xa3, 0x77, 0xf4, 0x35, 0x32, 0x96, 0xb1, 0x47, 0xc6,
+ 0xa7, 0x1d, 0xc9, 0xaf, 0x0f, 0xe0, 0x07, 0x19, 0xaf, 0xe4, 0x02, 0x63,
+ 0x91, 0x8c, 0xe7, 0x96, 0xe0, 0x9f, 0x6a, 0x3f, 0x9f, 0xf6, 0xf6, 0x95,
+ 0xcd, 0x44, 0xa9, 0x24, 0x6e, 0xfc, 0x91, 0xf6, 0x77, 0x3c, 0x7d, 0xa5,
+ 0xb0, 0xd7, 0x19, 0xf3, 0x8d, 0xab, 0xfc, 0xd9, 0x1e, 0x2f, 0x11, 0x3b,
+ 0x05, 0xdf, 0xf5, 0xeb, 0x69, 0xc6, 0x7a, 0xef, 0x23, 0xbe, 0xbf, 0xc4,
+ 0x4d, 0xda, 0x23, 0xe3, 0xe2, 0x5e, 0x72, 0x47, 0x1f, 0x11, 0xfa, 0xa7,
+ 0x89, 0xf8, 0x14, 0xf1, 0xd6, 0xfe, 0xbe, 0x20, 0x68, 0xec, 0xa5, 0x71,
+ 0x19, 0xbe, 0xf4, 0x23, 0x15, 0x63, 0xff, 0x70, 0x7a, 0x37, 0x6d, 0xa8,
+ 0x58, 0xf1, 0x78, 0xbf, 0x0c, 0x8f, 0xae, 0x89, 0x40, 0x5b, 0xf0, 0x7b,
+ 0x03, 0x0b, 0x3e, 0xaa, 0x7a, 0x87, 0xbd, 0x1e, 0x57, 0xdf, 0x5c, 0x65,
+ 0x55, 0xde, 0x23, 0x63, 0xc9, 0x3c, 0xd3, 0x88, 0xca, 0x85, 0x7b, 0x16,
+ 0x67, 0x5b, 0x68, 0xf2, 0x7c, 0x19, 0x57, 0x66, 0xdc, 0x98, 0xb1, 0x65,
+ 0xc6, 0x88, 0xf5, 0xf7, 0x53, 0x47, 0x9a, 0x7b, 0xc5, 0x91, 0x89, 0x8b,
+ 0x51, 0xf3, 0x4d, 0x9a, 0x58, 0xdb, 0xd0, 0xbb, 0xf9, 0x9a, 0xa3, 0xee,
+ 0xfd, 0x8a, 0x4e, 0xbf, 0x9c, 0x1c, 0xed, 0x06, 0xce, 0x07, 0x54, 0x3e,
+ 0xa4, 0xed, 0xbe, 0x07, 0x7e, 0x25, 0xfd, 0x38, 0xea, 0x5b, 0x1f, 0xcf,
+ 0x87, 0x50, 0xf7, 0x0b, 0xe0, 0x9e, 0x75, 0xf0, 0x39, 0x95, 0xee, 0xfd,
+ 0xb4, 0x6c, 0x57, 0x98, 0x9f, 0x5d, 0x3f, 0x90, 0x53, 0xe7, 0xc1, 0x98,
+ 0x8d, 0x2f, 0x9b, 0xfc, 0x5c, 0x35, 0xfa, 0xcc, 0x8e, 0xb9, 0xab, 0x66,
+ 0xcc, 0x66, 0x40, 0x8a, 0xeb, 0x94, 0x3f, 0x96, 0x5a, 0xeb, 0x56, 0xe0,
+ 0xad, 0x52, 0xaa, 0xef, 0x75, 0xef, 0xde, 0x6a, 0x3d, 0x93, 0x56, 0xbe,
+ 0xec, 0xf9, 0x92, 0x39, 0x63, 0xfd, 0x1d, 0x64, 0x70, 0x27, 0x7f, 0x38,
+ 0xaa, 0xe3, 0x09, 0xd9, 0x81, 0x5e, 0xfa, 0x0f, 0x7d, 0x1a, 0xbf, 0xf4,
+ 0x7b, 0x7f, 0x65, 0x6c, 0x51, 0xfa, 0xbc, 0x03, 0x4a, 0x4f, 0xdb, 0x0d,
+ 0x9f, 0x4e, 0x98, 0x73, 0x43, 0x7f, 0xf8, 0xa0, 0x64, 0xeb, 0x90, 0x9b,
+ 0x83, 0x7c, 0x3f, 0x6b, 0xc6, 0xf2, 0xb9, 0x25, 0x47, 0x27, 0x76, 0xdf,
+ 0xa7, 0x4f, 0x6a, 0x3f, 0xbb, 0xd7, 0xbf, 0x53, 0xf7, 0x73, 0x4d, 0x7d,
+ 0x78, 0x15, 0x9c, 0xa0, 0x27, 0x1f, 0x06, 0xbd, 0xd6, 0x11, 0xc0, 0xcb,
+ 0x18, 0xe4, 0x80, 0xcb, 0x5c, 0x9d, 0x80, 0x4c, 0x0c, 0x24, 0x98, 0xc3,
+ 0xa7, 0xe0, 0x69, 0xd4, 0x43, 0x68, 0xf3, 0xe1, 0xd4, 0xfe, 0x79, 0xa3,
+ 0xce, 0xf6, 0x38, 0xd6, 0xea, 0x96, 0x89, 0x41, 0xe2, 0x79, 0x37, 0x1c,
+ 0x03, 0x81, 0xbd, 0x73, 0xd4, 0x1e, 0xec, 0x80, 0xef, 0xee, 0xef, 0x47,
+ 0x73, 0xf0, 0xc3, 0x72, 0x2b, 0x8c, 0x15, 0x10, 0xc6, 0x01, 0xc8, 0x39,
+ 0xec, 0x31, 0xed, 0xe7, 0x0e, 0xfb, 0x78, 0xf1, 0x63, 0x0c, 0x21, 0x45,
+ 0x17, 0x73, 0x19, 0xee, 0x25, 0x64, 0x62, 0x0e, 0x84, 0x2b, 0x61, 0xf2,
+ 0x0f, 0x09, 0x9f, 0x7d, 0x40, 0x9f, 0xff, 0xfd, 0x66, 0xbf, 0x7e, 0xce,
+ 0x22, 0xe7, 0xba, 0x17, 0xe3, 0xbf, 0xd2, 0xc2, 0x5a, 0x34, 0xe8, 0xc0,
+ 0xff, 0xbe, 0xaf, 0x7f, 0xaf, 0x9e, 0xab, 0xd7, 0xff, 0xa6, 0x2f, 0x66,
+ 0xbe, 0xe3, 0x23, 0x9c, 0xe4, 0x2f, 0x1f, 0x87, 0x9c, 0x63, 0xc0, 0xdc,
+ 0x23, 0x10, 0x86, 0x9e, 0x5d, 0x30, 0x24, 0xd2, 0x77, 0xca, 0xb8, 0x43,
+ 0x1d, 0x7b, 0x27, 0xad, 0xf5, 0xc9, 0x42, 0xad, 0x57, 0xca, 0x35, 0xe6,
+ 0x53, 0xf3, 0xfb, 0x32, 0xda, 0x59, 0xe4, 0x4b, 0x95, 0x37, 0x69, 0xf2,
+ 0x15, 0x7d, 0xfe, 0xec, 0x43, 0x3f, 0xea, 0x10, 0x94, 0x75, 0x2d, 0x9f,
+ 0xea, 0x72, 0x77, 0xce, 0xe2, 0x7c, 0x3b, 0x67, 0x51, 0xe7, 0x25, 0x15,
+ 0xdb, 0x79, 0x22, 0xcc, 0x89, 0xeb, 0xcc, 0x41, 0x2a, 0xc9, 0xa3, 0x87,
+ 0x7b, 0x24, 0xb9, 0xdc, 0x6b, 0x68, 0xf4, 0x3d, 0x66, 0x1d, 0xac, 0xb7,
+ 0x34, 0x29, 0xc9, 0xa5, 0x3f, 0x86, 0x6f, 0xaf, 0xf2, 0x22, 0x3b, 0xf2,
+ 0xdb, 0x87, 0xcd, 0xb7, 0x48, 0x59, 0x8b, 0xf9, 0x28, 0xf9, 0x25, 0x9c,
+ 0xd7, 0xe1, 0xc4, 0x68, 0xdc, 0xe6, 0xb7, 0xb8, 0x27, 0x24, 0xb9, 0x3a,
+ 0xa9, 0xbf, 0x89, 0x4b, 0xf3, 0x46, 0x3e, 0xa1, 0xec, 0xe9, 0xd4, 0x65,
+ 0x3d, 0x9f, 0xbb, 0xc4, 0xf6, 0x14, 0x6c, 0x47, 0xb6, 0xe7, 0x63, 0x01,
+ 0x75, 0x6b, 0x7f, 0x3f, 0xe8, 0xa9, 0xcb, 0xd8, 0x03, 0xcc, 0xe9, 0xe4,
+ 0x78, 0xda, 0x1e, 0xa7, 0x71, 0x66, 0xf9, 0xb8, 0x2d, 0x1c, 0xa3, 0xe6,
+ 0xc3, 0xb3, 0x7f, 0x47, 0x44, 0x5c, 0x8f, 0xcb, 0x7a, 0xd3, 0x05, 0x4f,
+ 0xe8, 0x9c, 0xf8, 0x62, 0xdd, 0xcf, 0xe5, 0x7c, 0xb4, 0x9d, 0xcb, 0x49,
+ 0x18, 0x0b, 0x95, 0xdd, 0xb4, 0x77, 0xc8, 0xe4, 0x54, 0xf6, 0xa8, 0xfb,
+ 0xd9, 0x0e, 0xf9, 0x67, 0xfa, 0x3f, 0x73, 0x80, 0x77, 0xf7, 0x22, 0x6c,
+ 0x1f, 0x34, 0xed, 0xb0, 0x8f, 0xa2, 0x51, 0xc5, 0x07, 0xc9, 0x86, 0xdf,
+ 0xef, 0xfa, 0x01, 0x9d, 0x0b, 0x4a, 0x3c, 0x79, 0x06, 0xe6, 0x09, 0xf8,
+ 0xb1, 0xac, 0x3b, 0x88, 0xb1, 0x3c, 0x27, 0x94, 0x8d, 0x83, 0x2a, 0xd7,
+ 0x30, 0xe0, 0x4d, 0x99, 0x7b, 0xc1, 0x41, 0xb5, 0x96, 0xe3, 0x71, 0x7e,
+ 0x5f, 0x36, 0xf4, 0x74, 0xac, 0xbf, 0x1b, 0x5e, 0xc6, 0xe0, 0xfc, 0xdc,
+ 0x51, 0xb6, 0xf3, 0x7d, 0x77, 0x1f, 0x3f, 0x4f, 0x34, 0x6b, 0x05, 0xdb,
+ 0x39, 0xf6, 0xc4, 0x25, 0xef, 0x96, 0x51, 0x5e, 0xf6, 0x00, 0x23, 0x9f,
+ 0x51, 0x9a, 0x6f, 0x07, 0x82, 0x4b, 0xfc, 0xed, 0x9e, 0x27, 0x88, 0xb9,
+ 0x7d, 0x9e, 0xdd, 0x3b, 0xa7, 0xb4, 0xcb, 0x3b, 0x6f, 0x6d, 0x57, 0x98,
+ 0x27, 0x51, 0x92, 0x93, 0x99, 0x3e, 0x99, 0xab, 0xd9, 0xfc, 0xc6, 0x93,
+ 0x31, 0x7a, 0xde, 0x83, 0xcb, 0xbc, 0x92, 0x71, 0x23, 0xc6, 0xe7, 0xee,
+ 0x81, 0x6f, 0x4e, 0x7a, 0x1e, 0x91, 0xf5, 0xfa, 0x4c, 0x47, 0xfe, 0x6d,
+ 0x97, 0xa1, 0xb3, 0x7f, 0x1d, 0x92, 0xde, 0x12, 0x7c, 0x32, 0x9f, 0xa7,
+ 0x47, 0xa4, 0x50, 0xef, 0xbc, 0x3b, 0x63, 0xae, 0x4f, 0xe7, 0x37, 0xb4,
+ 0x4a, 0x0f, 0xd6, 0x4a, 0xb4, 0xab, 0xa2, 0x8c, 0x4b, 0xb0, 0xdf, 0x7e,
+ 0xa3, 0x6f, 0xe1, 0x08, 0xf5, 0xbe, 0xc5, 0x12, 0x97, 0xb0, 0x41, 0x47,
+ 0xa8, 0x75, 0x52, 0x72, 0x34, 0x5a, 0x82, 0x8f, 0x3a, 0x62, 0xd6, 0x7d,
+ 0x3b, 0xde, 0xd9, 0xf7, 0x80, 0x69, 0xbf, 0xd7, 0xbc, 0xf7, 0x9a, 0xf7,
+ 0x00, 0xde, 0xeb, 0xad, 0x5a, 0x95, 0x73, 0xb2, 0xe4, 0xf7, 0x22, 0xbc,
+ 0xdb, 0xf2, 0x24, 0x74, 0x59, 0xa0, 0xa7, 0x7a, 0xe5, 0xf1, 0xba, 0xc2,
+ 0xaf, 0xe5, 0x2e, 0xd1, 0x20, 0xd8, 0x6f, 0x9e, 0xef, 0xe6, 0xc1, 0x4f,
+ 0xde, 0x91, 0x37, 0x3c, 0xec, 0x98, 0xdc, 0xec, 0x0e, 0x78, 0xb3, 0x80,
+ 0xf5, 0xd7, 0xe5, 0x41, 0x51, 0x47, 0x69, 0x5f, 0xb9, 0x50, 0xd1, 0xf9,
+ 0x3e, 0x27, 0x2b, 0x80, 0xb5, 0xf6, 0x3f, 0x0e, 0xe8, 0xdc, 0x14, 0x3f,
+ 0x9f, 0x91, 0xf9, 0xee, 0x23, 0x26, 0x27, 0x82, 0x63, 0x99, 0x57, 0xe9,
+ 0xdf, 0x39, 0x76, 0xda, 0xaa, 0xd4, 0x45, 0xd4, 0x33, 0xfc, 0x6e, 0x25,
+ 0x8d, 0xbe, 0x8b, 0x94, 0x35, 0xd0, 0x53, 0xbe, 0x2d, 0xf1, 0x39, 0xe5,
+ 0x1f, 0x76, 0x7e, 0xf7, 0x73, 0x0e, 0xb0, 0xfe, 0x65, 0x93, 0x71, 0xe1,
+ 0x1e, 0x09, 0x2c, 0xfb, 0x79, 0x50, 0x3c, 0x63, 0xda, 0x61, 0xfc, 0xb6,
+ 0xfa, 0x77, 0x77, 0xc5, 0x8c, 0x7d, 0x5b, 0x81, 0x74, 0x3e, 0xe7, 0x30,
+ 0xc7, 0xd4, 0xf1, 0xfc, 0x38, 0x33, 0x73, 0x6b, 0x68, 0x73, 0x1d, 0x14,
+ 0x5b, 0xc5, 0x8d, 0xd8, 0x56, 0x92, 0xfe, 0xc3, 0xbf, 0x4b, 0xde, 0xf8,
+ 0x47, 0xfc, 0x16, 0x46, 0xe7, 0x79, 0xab, 0x75, 0xa2, 0xda, 0x86, 0xe4,
+ 0x37, 0xda, 0x69, 0xf0, 0xd5, 0xbe, 0x2d, 0x9d, 0xf3, 0x1d, 0xc1, 0x7b,
+ 0x06, 0x74, 0x0c, 0x99, 0x2a, 0xfc, 0x1e, 0x9b, 0x7c, 0xc7, 0xef, 0xb1,
+ 0x3d, 0x95, 0x6f, 0xb2, 0x6d, 0xbe, 0x2f, 0xba, 0xde, 0x0c, 0x8a, 0xbd,
+ 0x34, 0xce, 0x6f, 0xd5, 0xf8, 0x6d, 0x23, 0x6c, 0xb5, 0x38, 0xda, 0x99,
+ 0xc7, 0x36, 0xa4, 0xf2, 0x54, 0xca, 0xcd, 0x8f, 0xa0, 0xfc, 0x34, 0xfc,
+ 0x75, 0x1d, 0x9f, 0x2f, 0x37, 0x99, 0xaf, 0xe2, 0xa8, 0x7b, 0xcf, 0xe4,
+ 0x52, 0x01, 0xeb, 0xf9, 0xdf, 0x3e, 0x47, 0x51, 0x47, 0xf8, 0x4a, 0x86,
+ 0x47, 0xfd, 0x5c, 0x84, 0x0d, 0x87, 0x3a, 0xa1, 0xd4, 0x8c, 0xa8, 0x1c,
+ 0x17, 0x6d, 0x8f, 0xd0, 0xd6, 0x0b, 0xa3, 0x2f, 0xf7, 0xda, 0x4b, 0x7d,
+ 0xd5, 0xa2, 0x4c, 0x4a, 0x61, 0x9d, 0x86, 0xca, 0x0f, 0x24, 0x9e, 0x5d,
+ 0xa7, 0x48, 0x7f, 0x4d, 0xc9, 0xf8, 0xc4, 0xe8, 0xac, 0xe4, 0x9d, 0x10,
+ 0x7c, 0xb1, 0xb2, 0xf2, 0x73, 0x5e, 0x80, 0x0d, 0x1d, 0xd9, 0x0a, 0x78,
+ 0xdc, 0x1b, 0xd7, 0xa6, 0x1f, 0xa2, 0xf7, 0xa3, 0xef, 0x8e, 0xc4, 0x2a,
+ 0xab, 0xef, 0xf5, 0x58, 0xcf, 0x7b, 0x01, 0xff, 0x7b, 0x6c, 0xe6, 0xef,
+ 0xc3, 0x4f, 0x68, 0x4e, 0xc9, 0xd9, 0xca, 0x7e, 0xe6, 0xc6, 0xa7, 0xb7,
+ 0x81, 0xb7, 0x93, 0xed, 0x7c, 0x7d, 0xe6, 0xb0, 0xf9, 0xba, 0x87, 0x67,
+ 0xc5, 0x5c, 0x79, 0xd2, 0x19, 0xf3, 0xe5, 0x69, 0x87, 0x0d, 0xc9, 0xe3,
+ 0x4d, 0x3f, 0x47, 0x7e, 0x2f, 0x3b, 0x9c, 0x34, 0xf8, 0x59, 0xf8, 0x86,
+ 0x7e, 0x2e, 0x24, 0x73, 0x36, 0x5b, 0xad, 0x93, 0x69, 0xde, 0xc7, 0xce,
+ 0x1c, 0x5d, 0xc3, 0x1e, 0xaf, 0xd5, 0x81, 0xc3, 0xe3, 0xac, 0x63, 0xee,
+ 0x56, 0xb7, 0xe4, 0xc6, 0x55, 0xbc, 0xaf, 0x77, 0xcd, 0xdd, 0x2f, 0x57,
+ 0x6b, 0x51, 0x95, 0x87, 0x56, 0x84, 0x9d, 0xdf, 0x90, 0xdb, 0x0e, 0xef,
+ 0xa3, 0x8f, 0xa8, 0xf1, 0x3e, 0xbf, 0x73, 0x9d, 0xa8, 0x1c, 0x59, 0xd7,
+ 0xf2, 0xe4, 0x54, 0x06, 0x76, 0xcb, 0x25, 0xb1, 0x3e, 0x9a, 0x19, 0x82,
+ 0xef, 0xcd, 0xb5, 0x52, 0x18, 0x07, 0xda, 0x89, 0x91, 0xd7, 0x7f, 0xd1,
+ 0x6a, 0x00, 0xde, 0xdb, 0x4d, 0xda, 0xeb, 0xb0, 0xa1, 0x66, 0x38, 0xc6,
+ 0x13, 0xfb, 0x02, 0xfb, 0x0c, 0x80, 0xfe, 0x42, 0xfa, 0x7b, 0xb4, 0xca,
+ 0x01, 0x69, 0x38, 0x6c, 0xe3, 0x73, 0x4c, 0x1a, 0x51, 0xdf, 0x4f, 0xf9,
+ 0x21, 0xf0, 0x17, 0x57, 0x32, 0xc9, 0xbf, 0xc3, 0x67, 0x4e, 0xe9, 0x5c,
+ 0xed, 0x18, 0x78, 0x28, 0x68, 0x6c, 0xb3, 0x20, 0xe6, 0xf8, 0xbe, 0xa3,
+ 0x6d, 0x05, 0xde, 0xf1, 0x6b, 0x5b, 0x44, 0xeb, 0x18, 0xde, 0xfb, 0x05,
+ 0xe1, 0x0b, 0xf8, 0x7c, 0x79, 0xc8, 0xd8, 0x14, 0x9d, 0xbe, 0x7c, 0x2a,
+ 0x76, 0x91, 0xff, 0x0f, 0x62, 0xf3, 0x83, 0x32, 0x0b, 0x98, 0xcf, 0x9b,
+ 0x7d, 0x3e, 0x92, 0x71, 0xe5, 0x56, 0x9d, 0x77, 0xf0, 0x07, 0x51, 0x32,
+ 0xdf, 0x90, 0x30, 0x8f, 0x99, 0x9c, 0x4a, 0x0f, 0x7b, 0x3d, 0x21, 0x2f,
+ 0xc3, 0xbe, 0x7e, 0xa5, 0x92, 0x4a, 0x1f, 0x51, 0x71, 0xe7, 0x44, 0xec,
+ 0xaa, 0x8c, 0xc5, 0xe9, 0x03, 0x96, 0x9c, 0x44, 0xec, 0x16, 0xe8, 0xe1,
+ 0x76, 0xe5, 0x50, 0x3f, 0xff, 0x27, 0x45, 0x03, 0xfa, 0xf0, 0xb6, 0xca,
+ 0x81, 0x49, 0x30, 0x66, 0x82, 0xf7, 0x21, 0x93, 0x87, 0xc3, 0x75, 0xd8,
+ 0x36, 0x24, 0x2f, 0x57, 0xda, 0xfa, 0x97, 0xeb, 0xe8, 0xdc, 0x36, 0xa5,
+ 0x5f, 0x8f, 0xf6, 0x53, 0x0e, 0x71, 0x3d, 0x3d, 0x87, 0xdf, 0x87, 0x78,
+ 0xf5, 0x63, 0x91, 0x8e, 0xfe, 0xbe, 0xc1, 0x62, 0xde, 0x0b, 0xf7, 0xfe,
+ 0x13, 0x47, 0xdb, 0x40, 0x1c, 0x97, 0x72, 0x8e, 0xaa, 0xf9, 0x78, 0xdf,
+ 0x3b, 0x24, 0x3f, 0x6e, 0xfa, 0xf3, 0x30, 0x1f, 0x87, 0x39, 0x3f, 0x94,
+ 0x7d, 0x9d, 0x30, 0x68, 0xfd, 0xff, 0xb2, 0x8a, 0xeb, 0x4d, 0xa2, 0x3f,
+ 0x75, 0x34, 0xe8, 0xa5, 0x1e, 0xd3, 0xff, 0xdf, 0xa1, 0x2d, 0xe3, 0xf8,
+ 0x4c, 0x7c, 0x72, 0x1d, 0xd8, 0xf8, 0x0f, 0x38, 0xa6, 0xdd, 0xb7, 0x4b,
+ 0x87, 0xc0, 0xaf, 0x27, 0xa4, 0xb1, 0x92, 0x8a, 0x3d, 0x2e, 0xfe, 0xbc,
+ 0xad, 0x87, 0x79, 0x2f, 0x56, 0xc8, 0x8c, 0x39, 0x0b, 0x0a, 0x1e, 0xde,
+ 0xdd, 0x26, 0x9c, 0xab, 0x58, 0xaf, 0xd1, 0xdc, 0x1d, 0x7b, 0x48, 0x64,
+ 0xb7, 0x24, 0x95, 0xd6, 0x67, 0x33, 0x22, 0x5b, 0x38, 0x9b, 0x3f, 0x31,
+ 0x67, 0xf3, 0x7e, 0xcc, 0xed, 0x5e, 0x18, 0x97, 0xd4, 0x85, 0x54, 0xfc,
+ 0xbc, 0xf0, 0x8e, 0xf9, 0x00, 0xef, 0x98, 0xad, 0x47, 0x32, 0x71, 0xec,
+ 0x37, 0x81, 0xfd, 0xa2, 0x6c, 0xf2, 0x99, 0xdf, 0xf7, 0xef, 0x23, 0x6f,
+ 0x3f, 0x4c, 0x99, 0x49, 0x5c, 0x14, 0x54, 0x1b, 0xec, 0x93, 0xa7, 0x08,
+ 0xd3, 0xbf, 0xe3, 0xf9, 0xa8, 0x58, 0xe8, 0xad, 0x26, 0xbf, 0x5b, 0xd5,
+ 0xf0, 0xe5, 0x01, 0xdf, 0xbc, 0x86, 0x2f, 0x3e, 0xdb, 0xb6, 0x5d, 0x13,
+ 0xb1, 0xb3, 0x42, 0x7b, 0x89, 0xf6, 0x0b, 0xed, 0xfa, 0xbf, 0xe9, 0xd7,
+ 0xb1, 0x3d, 0xf8, 0xb1, 0x0f, 0x64, 0xdb, 0x7b, 0xef, 0x42, 0xdf, 0x6b,
+ 0x19, 0x95, 0x63, 0xec, 0x4c, 0xc9, 0x7b, 0x25, 0xfb, 0x91, 0x44, 0x3c,
+ 0x6b, 0xb9, 0xc6, 0x06, 0x44, 0x59, 0xe7, 0x33, 0x65, 0xae, 0x6b, 0x6c,
+ 0x0b, 0x9e, 0x4d, 0x06, 0x6b, 0x29, 0xdc, 0xc2, 0x67, 0x1a, 0x02, 0xcd,
+ 0x93, 0xd6, 0xde, 0x05, 0x1e, 0xd2, 0xff, 0x13, 0xe3, 0x2a, 0xf0, 0x58,
+ 0x06, 0x1e, 0x4f, 0xdd, 0x65, 0x83, 0x85, 0xda, 0x36, 0xd8, 0xb6, 0x5a,
+ 0xef, 0x26, 0x60, 0xca, 0x3b, 0xb4, 0xbf, 0xca, 0x6d, 0x5a, 0x21, 0x4c,
+ 0xe3, 0xfc, 0x2e, 0x5b, 0xae, 0x67, 0x78, 0x1e, 0xb0, 0xc1, 0x30, 0xdf,
+ 0xda, 0x0e, 0x2d, 0x61, 0xff, 0x8a, 0x7e, 0x41, 0xbb, 0x09, 0x27, 0x68,
+ 0xf1, 0x2c, 0x38, 0x9f, 0x58, 0x37, 0x00, 0xcb, 0xb6, 0xa2, 0x03, 0x4d,
+ 0x03, 0xdb, 0xf5, 0xde, 0x37, 0xa0, 0x01, 0xee, 0x93, 0xf4, 0xe7, 0xd3,
+ 0x5e, 0xfb, 0xbb, 0x75, 0xf8, 0xb7, 0x25, 0xb9, 0xff, 0x90, 0x27, 0xb9,
+ 0x0b, 0x2d, 0x59, 0x48, 0x8b, 0x35, 0x76, 0x88, 0x34, 0x49, 0x3b, 0x01,
+ 0x36, 0x64, 0x8c, 0x38, 0xd6, 0xf6, 0xe0, 0xec, 0x57, 0xf7, 0xe3, 0xf7,
+ 0x6f, 0xfa, 0x79, 0xbf, 0x94, 0xdb, 0xa0, 0xbc, 0x12, 0xeb, 0xbe, 0x43,
+ 0xda, 0x3f, 0xbc, 0x1d, 0x05, 0xce, 0xd1, 0x9e, 0x7c, 0xa2, 0xcb, 0xc4,
+ 0x51, 0xb5, 0x5e, 0x4e, 0x3e, 0x41, 0xbc, 0xa2, 0xfc, 0xea, 0x4f, 0x1c,
+ 0x3f, 0x27, 0x49, 0xc7, 0x04, 0xc9, 0x17, 0x25, 0x99, 0xcf, 0x30, 0x27,
+ 0xb4, 0x57, 0x8e, 0x40, 0xae, 0x4d, 0x55, 0x26, 0xe5, 0x0b, 0x95, 0x88,
+ 0xb2, 0x1b, 0xfe, 0x2c, 0x9d, 0x8a, 0x8d, 0x5a, 0x2d, 0x79, 0x04, 0xf6,
+ 0xcf, 0xec, 0x50, 0x97, 0xbc, 0x32, 0xae, 0xf3, 0x6f, 0x6f, 0x33, 0xb9,
+ 0xce, 0x61, 0xce, 0x28, 0xf7, 0x03, 0xb9, 0x6f, 0xc1, 0x17, 0xb0, 0xba,
+ 0x65, 0x36, 0x1a, 0x91, 0xe9, 0x34, 0xca, 0x37, 0xa7, 0xd5, 0x37, 0xa4,
+ 0xd9, 0x68, 0xa7, 0x1c, 0x21, 0xcc, 0x2c, 0xdf, 0x62, 0xca, 0x9f, 0xf5,
+ 0x77, 0xc0, 0x62, 0xcd, 0x67, 0x02, 0x6a, 0x7f, 0xe5, 0x3a, 0xe5, 0x1b,
+ 0xc7, 0x40, 0x9e, 0x34, 0x79, 0x0f, 0x59, 0x92, 0x35, 0xc8, 0x97, 0x62,
+ 0x4d, 0xac, 0x8d, 0x0c, 0x2c, 0x6a, 0x57, 0xdb, 0x9f, 0x45, 0xd0, 0xd7,
+ 0x5c, 0x8d, 0xf2, 0x6f, 0x4a, 0xe5, 0x4e, 0xcf, 0xc1, 0xd6, 0x85, 0x4f,
+ 0x3c, 0xdb, 0xed, 0x99, 0x7b, 0xce, 0x5e, 0xc6, 0x43, 0x3a, 0x65, 0x98,
+ 0xff, 0x3f, 0x73, 0x0e, 0x0f, 0x48, 0x5f, 0x09, 0xe7, 0xe2, 0xdb, 0xdc,
+ 0xc0, 0x29, 0xd6, 0xcc, 0xa9, 0x73, 0xf2, 0xcf, 0x84, 0xb2, 0xa7, 0x33,
+ 0x67, 0xdb, 0xb7, 0x39, 0xc8, 0xb3, 0xd4, 0x17, 0x52, 0x0a, 0xc3, 0xa6,
+ 0xed, 0xb9, 0x00, 0xdd, 0x5d, 0xf3, 0x40, 0x2b, 0x93, 0xd0, 0x87, 0x93,
+ 0x52, 0x86, 0xed, 0xf6, 0xd1, 0xf4, 0x67, 0xc5, 0x7e, 0xea, 0xa0, 0xac,
+ 0xd5, 0x7a, 0x80, 0x0f, 0xea, 0x85, 0x90, 0xf2, 0xaf, 0x6f, 0x1f, 0xa7,
+ 0xbe, 0xa3, 0x2e, 0xd1, 0x67, 0xb1, 0x5d, 0xff, 0xc4, 0x80, 0xfe, 0x7e,
+ 0x65, 0xbf, 0x6c, 0xd5, 0x7d, 0x5d, 0x08, 0xff, 0xb0, 0x16, 0x32, 0x7a,
+ 0xb9, 0x17, 0xb2, 0xfb, 0xaf, 0x43, 0x0d, 0xe5, 0xab, 0x73, 0xff, 0xd4,
+ 0x41, 0xea, 0xff, 0x70, 0xf4, 0x36, 0x5c, 0xee, 0xbd, 0x53, 0x07, 0x69,
+ 0xbb, 0xc3, 0x39, 0xcc, 0xf5, 0x78, 0x1f, 0xc7, 0x3d, 0x46, 0x25, 0x74,
+ 0xf1, 0x84, 0xd8, 0xf0, 0x5b, 0x02, 0x4b, 0xb4, 0xf5, 0xee, 0xf4, 0x5d,
+ 0x02, 0x97, 0x6d, 0xf3, 0xad, 0xed, 0xb0, 0xb6, 0x65, 0x32, 0x28, 0x1b,
+ 0xfe, 0xf7, 0xb7, 0xfc, 0xdd, 0xe1, 0xdb, 0x1d, 0x78, 0x03, 0x5d, 0x8a,
+ 0xbf, 0xff, 0x0b, 0xc4, 0xbf, 0x6d, 0x24, 0x80, 0x4a, 0x00, 0x00, 0x00 };
static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e20, 0x08000e78,
- 0x08000ebc, 0x08000f50, 0x08000f94, 0x80080100, 0x80080080, 0x80080000,
+ 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000ea4, 0x08000efc,
+ 0x08000f40, 0x08000fd4, 0x08001018, 0x80080100, 0x80080080, 0x80080000,
0x00000000 };
static struct fw_info bnx2_com_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
.start_addr = 0x080000f8,
.text_addr = 0x08000000,
- .text_len = 0x4c18,
+ .text_len = 0x4a7c,
.text_index = 0x0,
.gz_text = bnx2_COM_b09FwText,
.gz_text_len = sizeof(bnx2_COM_b09FwText),
@@ -866,1210 +865,1189 @@ static struct fw_info bnx2_com_fw_09 = {
.data_index = 0x0,
.data = bnx2_COM_b09FwData,
- .sbss_addr = 0x08004c60,
+ .sbss_addr = 0x08004ae0,
.sbss_len = 0x38,
.sbss_index = 0x0,
- .bss_addr = 0x08004c98,
- .bss_len = 0xbc,
+ .bss_addr = 0x08004b18,
+ .bss_len = 0xc0,
.bss_index = 0x0,
- .rodata_addr = 0x08004c18,
+ .rodata_addr = 0x08004a7c,
.rodata_len = 0x30,
.rodata_index = 0x0,
.rodata = bnx2_COM_b09FwRodata,
};
static u8 bnx2_CP_b09FwText[] = {
- 0xad, 0xbc, 0x0b, 0x74, 0x1c, 0xd5, 0x95, 0x2e, 0xfc, 0x55, 0x75, 0xb7,
- 0xd4, 0x92, 0xda, 0x52, 0x4b, 0x6e, 0xcb, 0x6d, 0xd0, 0xe0, 0x6a, 0xab,
- 0xda, 0x6a, 0x2c, 0x01, 0xd5, 0xb2, 0x0c, 0x4d, 0xa6, 0xc0, 0x1d, 0x5b,
- 0x80, 0x0c, 0x26, 0x11, 0xc6, 0xb9, 0x23, 0xe6, 0x7a, 0xfe, 0xf4, 0x18,
- 0x03, 0x86, 0x90, 0x5c, 0x33, 0x93, 0x9b, 0x71, 0xb8, 0x9e, 0xeb, 0x8a,
- 0xe4, 0x87, 0xc0, 0xa5, 0xee, 0x96, 0x90, 0x1f, 0xac, 0x35, 0xeb, 0xa7,
- 0x2d, 0xcb, 0x92, 0x21, 0xad, 0x16, 0x49, 0x98, 0x19, 0xe7, 0xe6, 0x81,
- 0xc6, 0xd8, 0x60, 0x93, 0xf0, 0xc8, 0x6b, 0xfd, 0x4c, 0xfe, 0xb9, 0x7f,
- 0x3c, 0xb6, 0x79, 0x83, 0xe3, 0x3c, 0x47, 0x9e, 0xc1, 0xa9, 0xff, 0xdb,
- 0xd5, 0xdd, 0xb6, 0xec, 0x40, 0x1e, 0xeb, 0x8e, 0xd6, 0xaa, 0xa5, 0xee,
- 0xaa, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0x4e,
- 0xb5, 0x06, 0x54, 0xa3, 0xf4, 0x37, 0x8b, 0xd7, 0xd5, 0x1d, 0x1b, 0xee,
- 0x5e, 0xdc, 0x7e, 0x75, 0x87, 0x7c, 0xf7, 0xce, 0xf5, 0x7a, 0xf1, 0x61,
- 0x7f, 0x26, 0x12, 0x97, 0xde, 0xd2, 0x3e, 0xb4, 0xe0, 0x47, 0xfc, 0x25,
- 0x10, 0x91, 0x7f, 0xad, 0xa5, 0xaf, 0x1e, 0x20, 0x58, 0x6e, 0x5f, 0x2e,
- 0xf8, 0x55, 0xb3, 0xf3, 0xbf, 0x2e, 0xd3, 0xe1, 0xf7, 0x98, 0x9f, 0xff,
- 0x8b, 0xbb, 0x75, 0x20, 0x99, 0x6f, 0xd5, 0x96, 0xe3, 0x9c, 0x63, 0x85,
- 0xbc, 0x90, 0xfb, 0x7f, 0x62, 0x7e, 0xf0, 0xc4, 0xb7, 0xae, 0x8b, 0x9c,
- 0xc9, 0x79, 0xe0, 0x0f, 0x9a, 0x16, 0x82, 0x0b, 0xe1, 0x6f, 0x62, 0x9d,
- 0xbf, 0x6b, 0xd9, 0xa6, 0xa2, 0xb6, 0x2c, 0x2b, 0x12, 0xce, 0x21, 0x12,
- 0xb4, 0x10, 0x89, 0x59, 0x40, 0xca, 0x6b, 0x22, 0x55, 0x69, 0xfa, 0x51,
- 0xa1, 0x57, 0x20, 0x15, 0xdc, 0xa8, 0x6d, 0xe1, 0x18, 0x97, 0xd9, 0x7e,
- 0xed, 0x44, 0x1e, 0xb8, 0xdb, 0xf6, 0xe3, 0xb8, 0x27, 0xa0, 0x9d, 0xcc,
- 0xef, 0xab, 0x2b, 0xea, 0x23, 0x09, 0x8f, 0x8e, 0x94, 0x6a, 0xca, 0x7d,
- 0x68, 0xcb, 0xf3, 0x48, 0xf9, 0xcc, 0xcf, 0x6b, 0xe3, 0x36, 0xd0, 0x9b,
- 0x69, 0x36, 0x4e, 0xa0, 0x35, 0x7c, 0x18, 0x95, 0x48, 0x85, 0x22, 0x31,
- 0xe0, 0x83, 0x73, 0x8f, 0x66, 0x14, 0xf8, 0xf4, 0xd9, 0xe8, 0xdc, 0x0b,
- 0x3c, 0x92, 0x89, 0x24, 0x75, 0x05, 0xe8, 0x9f, 0x94, 0xba, 0x91, 0x60,
- 0x8e, 0xcf, 0xb7, 0x64, 0x80, 0xad, 0x99, 0xd9, 0xd8, 0x96, 0x75, 0xf0,
- 0x9c, 0xd1, 0x1c, 0xdc, 0xc7, 0x16, 0x7a, 0xdd, 0xe7, 0xb3, 0x61, 0xe5,
- 0xe4, 0xf9, 0x5b, 0xce, 0xb7, 0x5a, 0x82, 0x78, 0x7a, 0x32, 0x84, 0x67,
- 0x27, 0xeb, 0xf1, 0x48, 0xb6, 0x1e, 0xdb, 0xb3, 0x31, 0xa8, 0xba, 0x83,
- 0x58, 0x3c, 0x86, 0x8a, 0xeb, 0x1d, 0x9c, 0x34, 0xda, 0xb0, 0x95, 0x82,
- 0x5f, 0x6d, 0x6b, 0xc4, 0xda, 0x60, 0x13, 0xb6, 0xe8, 0xd7, 0xa1, 0x38,
- 0xd6, 0x0f, 0xce, 0x65, 0x32, 0xd2, 0x3f, 0xaf, 0xaa, 0xea, 0x37, 0xe2,
- 0xf4, 0x4e, 0x13, 0xef, 0xef, 0xc4, 0x9a, 0x5a, 0x38, 0x4e, 0x3e, 0x1e,
- 0xed, 0x7e, 0x50, 0x09, 0x6a, 0x4f, 0xe5, 0xd9, 0xa1, 0x55, 0x5e, 0xca,
- 0x83, 0x36, 0x92, 0x9f, 0x39, 0x15, 0x6c, 0x2f, 0xc3, 0x76, 0x33, 0xd2,
- 0x97, 0x30, 0xbe, 0xd5, 0xf2, 0xdf, 0x68, 0x0f, 0xc5, 0x31, 0x6d, 0xcd,
- 0xbc, 0xc6, 0x3e, 0x69, 0xec, 0x4f, 0x13, 0xbe, 0x36, 0x19, 0xc6, 0x57,
- 0xd9, 0xb7, 0xaf, 0x4c, 0x4a, 0x1f, 0x23, 0x7b, 0x2c, 0xd4, 0x63, 0x34,
- 0xdb, 0x84, 0xa7, 0xf5, 0x36, 0x7c, 0x85, 0x7d, 0xec, 0x33, 0x62, 0x58,
- 0x9b, 0xb8, 0x8b, 0xfd, 0x51, 0xb0, 0xaa, 0xed, 0x2f, 0x4b, 0xfd, 0x8a,
- 0x68, 0x50, 0x55, 0x24, 0x1b, 0x22, 0x31, 0x4d, 0x15, 0x99, 0x17, 0xfa,
- 0x3b, 0x90, 0x81, 0xe5, 0x37, 0xa5, 0xcf, 0x37, 0x22, 0xcf, 0xfe, 0x7e,
- 0x79, 0x67, 0xd4, 0x58, 0xaf, 0x62, 0x65, 0x80, 0x7d, 0x7e, 0x20, 0x1e,
- 0x4d, 0x2c, 0x62, 0x9f, 0xc7, 0xf3, 0x2a, 0xc7, 0x13, 0xd2, 0xc6, 0xd8,
- 0xf7, 0xe4, 0x2a, 0x95, 0x7d, 0x67, 0x5f, 0x32, 0xec, 0x4b, 0x86, 0x7d,
- 0xc9, 0xb0, 0x2f, 0x6e, 0xbf, 0x63, 0xec, 0x73, 0x71, 0x8e, 0x46, 0xf2,
- 0xc7, 0xd9, 0xdf, 0x99, 0xfd, 0x6c, 0x62, 0xdf, 0x91, 0xaa, 0xe7, 0xbc,
- 0x35, 0xa7, 0x65, 0xde, 0x1c, 0xe7, 0x55, 0xc3, 0x71, 0x7e, 0x6e, 0x04,
- 0xa8, 0xbf, 0x0c, 0xed, 0xa0, 0xdc, 0x9f, 0xf9, 0x56, 0x85, 0x89, 0x4e,
- 0x9a, 0xa0, 0x73, 0xa4, 0x23, 0x9a, 0x68, 0x50, 0x54, 0x78, 0xf5, 0xa0,
- 0xd6, 0x52, 0x88, 0x18, 0xd4, 0x8f, 0x16, 0x2d, 0x40, 0xd3, 0x0b, 0x94,
- 0x75, 0x51, 0xbb, 0x91, 0xe0, 0x14, 0xa4, 0x5d, 0x8d, 0xed, 0x1f, 0x2f,
- 0xcd, 0x9d, 0xc8, 0x0f, 0xb3, 0x4d, 0x69, 0x5f, 0x64, 0x3b, 0xce, 0xcf,
- 0x0c, 0xe8, 0x41, 0x44, 0xad, 0x41, 0xda, 0x9f, 0xc7, 0x0c, 0x6a, 0x1b,
- 0xf2, 0x7c, 0x7e, 0x5e, 0x46, 0x71, 0x3e, 0xd6, 0xe6, 0xb5, 0xd2, 0x18,
- 0x22, 0xec, 0x82, 0xd8, 0x41, 0x38, 0x15, 0x30, 0x83, 0xd2, 0xf7, 0xee,
- 0x3d, 0x03, 0x9b, 0x9d, 0x79, 0xba, 0xe8, 0x4a, 0xdf, 0x38, 0xcf, 0x13,
- 0x48, 0x9c, 0x5e, 0xf2, 0x90, 0x35, 0xab, 0x23, 0x8e, 0x6a, 0x1d, 0x81,
- 0x2a, 0x1d, 0xdd, 0xe9, 0x89, 0x6a, 0xab, 0xc6, 0xfc, 0xe6, 0x9d, 0x03,
- 0x13, 0x7e, 0x54, 0x4f, 0xe8, 0xa8, 0x9a, 0x78, 0xdc, 0x8b, 0x5a, 0x03,
- 0x3b, 0x26, 0xff, 0xcc, 0x5b, 0x1c, 0xdb, 0xcd, 0xa5, 0x31, 0xba, 0xb6,
- 0xef, 0x7f, 0xdd, 0x3e, 0xe3, 0x54, 0xe8, 0x55, 0x7f, 0xe6, 0x31, 0x75,
- 0x6d, 0x0c, 0x38, 0xb3, 0xb6, 0x63, 0x39, 0x7a, 0x83, 0x0a, 0xe6, 0xeb,
- 0x7f, 0x32, 0x0b, 0xb5, 0x26, 0xac, 0xc9, 0xc6, 0x54, 0x85, 0x19, 0x4a,
- 0x71, 0x6e, 0xf0, 0x82, 0x9d, 0x83, 0x6f, 0xc0, 0x71, 0xa4, 0xec, 0x49,
- 0xdc, 0x79, 0xa7, 0x6a, 0x1e, 0xba, 0xc6, 0x87, 0x4e, 0x96, 0xc7, 0xa6,
- 0xa3, 0x1d, 0x3f, 0x57, 0xd4, 0x9d, 0xdd, 0xb0, 0xc6, 0x3d, 0x48, 0x06,
- 0x53, 0xfc, 0x7f, 0xc5, 0x15, 0x2b, 0x13, 0xdd, 0xb0, 0xc7, 0xa7, 0x79,
- 0xdf, 0xcb, 0x7b, 0x26, 0xd2, 0x99, 0x2b, 0xae, 0xb8, 0x3d, 0x91, 0xc2,
- 0xc0, 0xb8, 0x7c, 0xf6, 0x62, 0xaa, 0x3e, 0x85, 0xed, 0xbb, 0x35, 0xd4,
- 0xe9, 0xdd, 0xc8, 0x8c, 0xcb, 0x67, 0xc7, 0x39, 0x65, 0x7c, 0x09, 0x7b,
- 0xda, 0xe8, 0xff, 0x73, 0xbb, 0xb1, 0x6d, 0xb7, 0x85, 0x4a, 0xdd, 0xa2,
- 0xee, 0x15, 0xef, 0x3f, 0xb7, 0x29, 0xd0, 0xee, 0x84, 0xb7, 0x42, 0x17,
- 0xbd, 0x25, 0xbc, 0xf7, 0xd8, 0x66, 0x70, 0xbe, 0xee, 0x38, 0x23, 0xc6,
- 0x22, 0x7c, 0xba, 0x7b, 0x2d, 0xac, 0x7d, 0x01, 0x58, 0xab, 0xe5, 0x7f,
- 0x37, 0x75, 0xb8, 0x16, 0xbd, 0xfb, 0xd6, 0xa2, 0xff, 0x31, 0x3a, 0x6e,
- 0x7d, 0xd0, 0x9d, 0xa7, 0x6f, 0xb5, 0x48, 0x9f, 0xa4, 0x7f, 0x3d, 0xbc,
- 0x44, 0xb7, 0x5f, 0xe0, 0x7f, 0x29, 0x33, 0xed, 0x60, 0xce, 0x85, 0x32,
- 0xdb, 0x59, 0x66, 0xdb, 0x45, 0x65, 0x4c, 0x3c, 0x31, 0x29, 0xba, 0x10,
- 0x95, 0xfd, 0x3e, 0x5d, 0x7c, 0xdb, 0xe9, 0x0d, 0x89, 0x2e, 0xac, 0x1e,
- 0x1f, 0x22, 0xdd, 0xf7, 0x2a, 0x5e, 0xac, 0x18, 0x00, 0xeb, 0xd0, 0x09,
- 0xaa, 0x23, 0xc9, 0x85, 0x8a, 0x89, 0xea, 0x01, 0x05, 0x2b, 0xe2, 0x55,
- 0xd0, 0xea, 0x45, 0xde, 0x8f, 0x1c, 0x2b, 0x28, 0xfd, 0x3d, 0x8a, 0x1a,
- 0xde, 0x5f, 0x17, 0xff, 0x01, 0xf1, 0x4c, 0xfa, 0x14, 0x67, 0xf9, 0x3b,
- 0x78, 0xff, 0x95, 0x19, 0xdf, 0xa5, 0x9c, 0xe3, 0xf4, 0x19, 0x06, 0xfa,
- 0x33, 0x6d, 0xd8, 0x9e, 0x49, 0x46, 0xa8, 0x25, 0xcb, 0x67, 0xf2, 0xbe,
- 0x19, 0xed, 0xea, 0x85, 0xb4, 0x03, 0xa5, 0xda, 0x84, 0x37, 0xdf, 0x71,
- 0xdc, 0xff, 0x92, 0xad, 0xf7, 0x3c, 0xa5, 0xf8, 0x68, 0xec, 0xd2, 0xce,
- 0x71, 0xff, 0x2b, 0xb6, 0x82, 0x37, 0xf5, 0xe8, 0x86, 0x77, 0x94, 0xe3,
- 0xfe, 0x97, 0xf3, 0x41, 0xcc, 0x1b, 0x88, 0xf4, 0x58, 0x4a, 0x02, 0x5f,
- 0xcf, 0x87, 0x10, 0x1e, 0x30, 0x71, 0x30, 0x6f, 0xe0, 0xc9, 0x8b, 0x70,
- 0xe0, 0x43, 0xff, 0x2c, 0x0f, 0xc7, 0xbe, 0xce, 0xd6, 0xd0, 0x6b, 0x9c,
- 0x73, 0x92, 0x41, 0xa4, 0xea, 0xcc, 0xe3, 0xfe, 0xf7, 0x07, 0xa0, 0xd4,
- 0x9a, 0x7a, 0xb8, 0xa0, 0xfc, 0xab, 0x93, 0x0a, 0x49, 0x31, 0xf6, 0xcf,
- 0xc5, 0xb2, 0x24, 0xed, 0xce, 0x20, 0xce, 0x9d, 0x71, 0x6a, 0x68, 0xb3,
- 0x15, 0xe6, 0x65, 0x18, 0x1f, 0xd6, 0xf1, 0xa4, 0xed, 0x38, 0xef, 0x19,
- 0x53, 0x89, 0x00, 0xf4, 0xee, 0x77, 0x11, 0x49, 0x2e, 0xa2, 0x5e, 0x8e,
- 0xe6, 0x75, 0x8c, 0xda, 0x26, 0x9e, 0xb3, 0x9b, 0x83, 0x7d, 0x58, 0x8c,
- 0x64, 0xb8, 0x18, 0x43, 0x26, 0xd8, 0xef, 0x91, 0x68, 0x37, 0xea, 0xcc,
- 0x04, 0x0e, 0xb1, 0xdf, 0xa7, 0x97, 0x88, 0x1c, 0x03, 0x2f, 0xff, 0x01,
- 0x7d, 0x25, 0xbe, 0xe3, 0x71, 0xf6, 0x35, 0xb1, 0xf8, 0x9c, 0x83, 0xd9,
- 0x7e, 0x9c, 0x30, 0xe6, 0xd2, 0x0e, 0x61, 0x55, 0x99, 0x7e, 0x6f, 0xbf,
- 0x1d, 0xc4, 0x81, 0x7c, 0xc0, 0xdb, 0x67, 0x87, 0xb0, 0x8f, 0xfe, 0x36,
- 0x8f, 0xa6, 0x1e, 0xa6, 0xdc, 0x79, 0xc4, 0xb5, 0xc2, 0x70, 0x13, 0x26,
- 0x87, 0x23, 0xc6, 0x2b, 0x4a, 0x18, 0x63, 0xa3, 0x97, 0x61, 0x62, 0x58,
- 0xc1, 0x78, 0x94, 0x7d, 0xe7, 0xe7, 0x2f, 0x0f, 0x5f, 0x81, 0xfc, 0xb0,
- 0x07, 0x3b, 0x5c, 0xbd, 0xba, 0x38, 0x53, 0xfa, 0x7f, 0x19, 0x72, 0xa3,
- 0xf0, 0x2e, 0x1a, 0x08, 0xe2, 0xa9, 0xbc, 0xd7, 0xab, 0x0f, 0x84, 0x30,
- 0x9a, 0xff, 0x36, 0xe7, 0x4d, 0x64, 0x6b, 0x18, 0xb1, 0xc7, 0xdc, 0x39,
- 0xac, 0x33, 0x29, 0xac, 0x18, 0x5f, 0x19, 0xcb, 0x34, 0xc6, 0x99, 0x04,
- 0x71, 0x48, 0x7c, 0xdc, 0x4f, 0x0c, 0x12, 0x1f, 0x7f, 0x4d, 0x41, 0x6d,
- 0x02, 0x7d, 0x93, 0xe5, 0xe7, 0x0a, 0xed, 0xdf, 0x8b, 0x75, 0x41, 0x03,
- 0x76, 0x46, 0xec, 0xb4, 0x8c, 0xcb, 0xf2, 0x59, 0xe6, 0xbf, 0x1a, 0xd6,
- 0xfe, 0x6a, 0xec, 0xa0, 0x8f, 0x3d, 0xba, 0x53, 0xee, 0x3b, 0xce, 0x7d,
- 0xf1, 0x3a, 0xda, 0x18, 0x6e, 0xaa, 0x42, 0xd4, 0x78, 0xcb, 0xed, 0x9b,
- 0x85, 0xb1, 0xbc, 0xc4, 0x50, 0x8d, 0xf1, 0xed, 0x28, 0xdb, 0xea, 0x60,
- 0x3b, 0x06, 0xbe, 0x3d, 0xd9, 0x86, 0x7f, 0x9c, 0x8c, 0xe1, 0x1f, 0x26,
- 0x75, 0xfc, 0xfd, 0xa4, 0x86, 0x67, 0x2e, 0xc2, 0xf5, 0x3b, 0xa9, 0x2b,
- 0xc1, 0x30, 0x03, 0x5b, 0x32, 0x15, 0xd8, 0x36, 0x5c, 0x8d, 0xbe, 0xe1,
- 0xe6, 0xd8, 0x73, 0xc4, 0xe3, 0x7f, 0x30, 0x6e, 0xc7, 0x54, 0x43, 0x87,
- 0xeb, 0x33, 0x8f, 0xf0, 0xfe, 0xa3, 0xc3, 0xcd, 0x9c, 0x43, 0xc7, 0x51,
- 0xe3, 0xad, 0x89, 0x43, 0xc4, 0xf7, 0xe3, 0xa1, 0x88, 0x36, 0xa5, 0x46,
- 0xb4, 0x24, 0x7c, 0xb0, 0xdb, 0x54, 0x58, 0x73, 0x22, 0x39, 0x7a, 0x31,
- 0x42, 0xfa, 0x7d, 0x1c, 0x5b, 0x44, 0xb3, 0x54, 0x83, 0xf6, 0xcb, 0x98,
- 0xa1, 0x76, 0x10, 0x5f, 0xaa, 0xf1, 0xfe, 0x70, 0xa4, 0xdf, 0x52, 0xef,
- 0x80, 0xd5, 0xe0, 0x38, 0x5f, 0x8d, 0x63, 0xc3, 0x5c, 0x13, 0xc9, 0x39,
- 0x8c, 0x05, 0x57, 0x98, 0x49, 0x30, 0x8e, 0xe1, 0xf4, 0x80, 0x1e, 0xfe,
- 0x7f, 0x94, 0x3b, 0xf1, 0xdf, 0xbb, 0x23, 0x9a, 0xa6, 0xb6, 0x5a, 0xfb,
- 0x54, 0x92, 0x8d, 0x46, 0x68, 0x61, 0xf3, 0x56, 0x6c, 0x74, 0x79, 0x82,
- 0x82, 0xa0, 0xde, 0x81, 0xbe, 0x0c, 0x2b, 0x85, 0x9a, 0x7b, 0x06, 0xd5,
- 0xe6, 0x69, 0x43, 0x8d, 0x1c, 0xed, 0x56, 0x89, 0xb7, 0x8b, 0x4f, 0x3b,
- 0x5a, 0xa3, 0xe3, 0xb4, 0x2f, 0x96, 0x36, 0x35, 0x34, 0x70, 0x9e, 0xeb,
- 0x39, 0xcf, 0xed, 0x85, 0x6a, 0xbc, 0x33, 0x0c, 0x6b, 0xae, 0x19, 0xe9,
- 0x7a, 0x40, 0xad, 0xc6, 0xdb, 0xa3, 0xd5, 0x38, 0x39, 0xec, 0xc5, 0x5b,
- 0xc3, 0x8e, 0x73, 0x8f, 0x51, 0x87, 0x8a, 0x38, 0xe6, 0x54, 0x20, 0x7a,
- 0x66, 0x04, 0x16, 0x7e, 0xc3, 0xb2, 0xbf, 0x1c, 0x0e, 0xe3, 0x57, 0xc3,
- 0x1f, 0xc3, 0x33, 0x0d, 0xc9, 0x63, 0xb3, 0x19, 0x23, 0xa7, 0x69, 0x3f,
- 0xa7, 0xed, 0x48, 0xcf, 0x3c, 0x4f, 0x64, 0x23, 0x79, 0xcb, 0xfa, 0x2f,
- 0x2a, 0x91, 0xd4, 0x2b, 0x4a, 0x44, 0x1b, 0x50, 0x42, 0x78, 0x97, 0x76,
- 0x7a, 0x2a, 0xdf, 0x9c, 0xf8, 0x01, 0xdb, 0xff, 0xb5, 0xf1, 0x0f, 0xce,
- 0x54, 0xa3, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xd3, 0x77, 0xff, 0x91, 0x31,
- 0xea, 0x1f, 0x32, 0xd4, 0x39, 0xfb, 0xf3, 0xcc, 0x6f, 0xc5, 0x2f, 0x99,
- 0xaf, 0x04, 0xe7, 0xf1, 0x72, 0xfc, 0x4f, 0x77, 0x6c, 0xc7, 0x9c, 0xbf,
- 0x09, 0xc9, 0xf8, 0x3a, 0x1b, 0x8b, 0x18, 0x24, 0xe3, 0x3c, 0xea, 0xa4,
- 0x82, 0x32, 0x46, 0x19, 0xab, 0xab, 0x4b, 0x6d, 0x83, 0xf2, 0x90, 0x8a,
- 0x6a, 0xc7, 0x79, 0xcc, 0x28, 0x3d, 0x0f, 0x95, 0xc7, 0xfa, 0x31, 0xde,
- 0x97, 0xf1, 0xbe, 0xe3, 0x11, 0xdd, 0x6b, 0xea, 0xd5, 0xfc, 0x1e, 0xb1,
- 0x92, 0xb8, 0x33, 0xc0, 0xef, 0xb1, 0xe4, 0xf9, 0xef, 0xde, 0xba, 0x8b,
- 0x9f, 0xd3, 0x4e, 0xdd, 0xf6, 0xee, 0xe4, 0x77, 0x19, 0xcb, 0xab, 0xb4,
- 0x9b, 0x0f, 0xb3, 0x13, 0xb1, 0x91, 0x18, 0xed, 0xe9, 0x94, 0xc4, 0x15,
- 0x2b, 0x64, 0xfa, 0x2d, 0xd5, 0x84, 0x46, 0x9c, 0xf0, 0x2b, 0xe6, 0x06,
- 0x68, 0x79, 0x0b, 0x9f, 0xea, 0xf0, 0xe0, 0xaf, 0x3a, 0x14, 0xcc, 0xd6,
- 0x37, 0x20, 0x7b, 0xad, 0xe5, 0xd4, 0xeb, 0x7b, 0x55, 0xf1, 0x81, 0x8a,
- 0x34, 0x2c, 0xfa, 0x1d, 0x12, 0xe4, 0x4a, 0x75, 0x7f, 0xaa, 0xe0, 0x44,
- 0x3c, 0x4a, 0x9b, 0xdb, 0x82, 0x6d, 0x9c, 0xf3, 0x59, 0x69, 0xf8, 0x03,
- 0xa6, 0x09, 0x7b, 0x00, 0xfe, 0x2a, 0xfa, 0xfe, 0x95, 0x03, 0xcd, 0x1b,
- 0xc6, 0x94, 0x48, 0x22, 0xad, 0x44, 0xba, 0xa9, 0x6f, 0xe3, 0xb4, 0x8b,
- 0x1b, 0x11, 0xad, 0x42, 0x91, 0x76, 0x4c, 0xb4, 0xe4, 0xb7, 0x60, 0x60,
- 0x52, 0x3e, 0x27, 0xa0, 0xe7, 0x7f, 0x5c, 0xea, 0x3b, 0xfc, 0x3e, 0xf6,
- 0x61, 0xbf, 0xfd, 0xba, 0x93, 0x0b, 0x46, 0xb4, 0x9c, 0xfb, 0x7d, 0x3d,
- 0xbf, 0xc3, 0x5f, 0x61, 0x3e, 0x88, 0xe7, 0xed, 0x37, 0xe7, 0x94, 0xcb,
- 0x15, 0xfb, 0x7a, 0x69, 0x7f, 0xfe, 0xb7, 0x93, 0x0c, 0xb9, 0xfd, 0xf1,
- 0xd7, 0xb0, 0x8d, 0xcf, 0x0c, 0xb0, 0x8d, 0x4c, 0xb9, 0x3f, 0x40, 0x20,
- 0x2d, 0x71, 0x38, 0xa2, 0x2d, 0x50, 0x9a, 0x8d, 0x01, 0x25, 0x12, 0xbb,
- 0x57, 0x69, 0x4d, 0x8c, 0x91, 0x5f, 0x6e, 0x47, 0xb1, 0x4f, 0xd1, 0x7c,
- 0xb1, 0x3f, 0x0b, 0xf2, 0x50, 0x3c, 0x03, 0x08, 0xcc, 0xd7, 0x17, 0x62,
- 0xb3, 0x3b, 0xa7, 0x50, 0xc2, 0x03, 0x1a, 0x6a, 0xc9, 0x5f, 0xc2, 0x13,
- 0xc0, 0xe4, 0x10, 0xb9, 0x5c, 0xbc, 0x19, 0x9f, 0x63, 0x2c, 0x98, 0xc7,
- 0x32, 0x5f, 0x0c, 0x9e, 0xc7, 0x2f, 0xa5, 0xdf, 0x26, 0xc0, 0xcc, 0x29,
- 0xf2, 0xb2, 0xd4, 0x7f, 0x41, 0x52, 0xee, 0x3d, 0x6e, 0x43, 0xc9, 0xd8,
- 0x91, 0x3d, 0x80, 0x3e, 0x15, 0xf7, 0x24, 0xef, 0x0f, 0x63, 0x33, 0x4e,
- 0xc7, 0xa3, 0xa9, 0x82, 0x12, 0x35, 0x86, 0x14, 0xc3, 0xbf, 0x8d, 0xed,
- 0xed, 0x60, 0x99, 0xed, 0xbc, 0x1e, 0x88, 0xea, 0x5d, 0x77, 0x28, 0xc9,
- 0x2b, 0xab, 0x58, 0xe6, 0xa4, 0x11, 0x25, 0xcf, 0x8c, 0x4e, 0xaf, 0x82,
- 0xe1, 0x7f, 0x22, 0x2f, 0xb2, 0x12, 0xca, 0x96, 0xc2, 0xe3, 0x6a, 0x11,
- 0x8f, 0x7e, 0x5d, 0xd2, 0xd9, 0x49, 0xf9, 0xee, 0xb6, 0xed, 0x1d, 0x68,
- 0xaa, 0xf9, 0xed, 0x7b, 0xda, 0x9c, 0x8b, 0xef, 0xb5, 0x06, 0x47, 0xe9,
- 0x7f, 0x1e, 0xbd, 0x8a, 0x73, 0x27, 0xfc, 0x28, 0x19, 0xf3, 0x41, 0xee,
- 0x79, 0x90, 0xf3, 0x26, 0xc3, 0x1e, 0x7c, 0xe0, 0x24, 0x57, 0xcb, 0xbd,
- 0x6a, 0xa4, 0xba, 0x5b, 0xc3, 0x5e, 0xb4, 0x26, 0xb6, 0x12, 0x0b, 0x8e,
- 0xaf, 0x5e, 0xc6, 0x67, 0x51, 0xe3, 0x39, 0x34, 0x6b, 0x5b, 0x21, 0x9f,
- 0xcf, 0xd2, 0x66, 0x97, 0x49, 0x5d, 0x96, 0x29, 0x72, 0x1f, 0xc1, 0x9a,
- 0x2d, 0x86, 0x83, 0xe7, 0x0d, 0x58, 0x95, 0xe6, 0x41, 0xe5, 0x84, 0xfd,
- 0x1b, 0x27, 0xe9, 0xc5, 0x4a, 0xfa, 0xa5, 0x41, 0xda, 0xab, 0xf9, 0xcd,
- 0xa8, 0x76, 0x94, 0x99, 0x82, 0xc7, 0xb4, 0x94, 0xe3, 0xf9, 0x2d, 0xca,
- 0xeb, 0xf9, 0x7e, 0xe5, 0x54, 0x5e, 0xea, 0x1e, 0x54, 0x4e, 0xe6, 0x25,
- 0x1e, 0x36, 0x69, 0x47, 0xc8, 0x6f, 0xc8, 0xa9, 0xd4, 0x3e, 0x03, 0xca,
- 0x36, 0xa3, 0x96, 0x3c, 0x5f, 0x8f, 0x8d, 0xb0, 0xbf, 0xfb, 0x3b, 0x60,
- 0x6c, 0x37, 0x7c, 0x38, 0x1e, 0x44, 0xa0, 0xcf, 0xf0, 0xca, 0x77, 0xe6,
- 0x03, 0x52, 0xb7, 0x49, 0xdb, 0x9a, 0x3f, 0x47, 0xff, 0x2a, 0x7e, 0xdf,
- 0xdf, 0x51, 0xbe, 0xf7, 0x0b, 0x67, 0x6a, 0xb5, 0xca, 0xef, 0x7f, 0xea,
- 0xe1, 0x50, 0x58, 0x77, 0x26, 0x3f, 0x17, 0x2e, 0xa5, 0x92, 0x3f, 0xd6,
- 0xc3, 0x0a, 0x46, 0xac, 0x1c, 0x73, 0x85, 0xbe, 0x4c, 0x3b, 0xfd, 0x2d,
- 0xcc, 0x58, 0x99, 0x24, 0xbe, 0x93, 0xf7, 0xb2, 0xcd, 0x0a, 0x3d, 0x80,
- 0x9b, 0xec, 0x66, 0x4f, 0x51, 0x7f, 0x2a, 0x31, 0xcc, 0xc3, 0x98, 0x2e,
- 0x1c, 0xef, 0x52, 0xce, 0xdd, 0xa4, 0xbd, 0xc5, 0x7e, 0x57, 0xe9, 0x7a,
- 0xac, 0x4a, 0x69, 0xd2, 0x5e, 0xcf, 0x27, 0xe9, 0xe3, 0x3d, 0x6c, 0x37,
- 0x80, 0xd7, 0xed, 0x5a, 0xe6, 0x20, 0x91, 0xa4, 0x45, 0x81, 0x37, 0x77,
- 0x84, 0x41, 0xce, 0x37, 0xe3, 0xaf, 0x1b, 0x8c, 0xff, 0x12, 0xa3, 0xd5,
- 0x5b, 0x96, 0x24, 0xb0, 0x3e, 0x0f, 0xef, 0xba, 0x0e, 0x13, 0xf7, 0x30,
- 0xb6, 0xdf, 0xc7, 0x78, 0xf9, 0x20, 0x63, 0xe1, 0x8e, 0x38, 0xc7, 0x56,
- 0xef, 0x38, 0x95, 0xfa, 0x66, 0xc9, 0x67, 0x30, 0xc0, 0x58, 0x7c, 0x37,
- 0xe3, 0xcb, 0x16, 0x7e, 0x7e, 0x29, 0xff, 0x1f, 0xce, 0x7d, 0xcc, 0xa7,
- 0x9e, 0xbf, 0x48, 0x26, 0xd4, 0x51, 0xbd, 0x35, 0xb6, 0x95, 0xb1, 0x98,
- 0x72, 0xad, 0x5a, 0xd3, 0x71, 0xae, 0x8c, 0x46, 0x92, 0x3e, 0xc5, 0xc0,
- 0x73, 0x13, 0xc7, 0x1d, 0x6d, 0x8e, 0xe4, 0x52, 0xe5, 0x38, 0x28, 0x63,
- 0x95, 0x1c, 0x41, 0xf0, 0x41, 0xf2, 0x84, 0x99, 0x18, 0xa1, 0xe2, 0xe6,
- 0x61, 0xc9, 0x13, 0xc2, 0x58, 0x65, 0x7f, 0x09, 0xcf, 0xb5, 0x79, 0xd1,
- 0xc5, 0x1c, 0xeb, 0x16, 0x3b, 0x80, 0x3b, 0x88, 0xa5, 0x2b, 0x6c, 0xe6,
- 0x4e, 0xc1, 0x10, 0x6e, 0xb5, 0xbd, 0x38, 0xdc, 0xc6, 0x1c, 0x28, 0x54,
- 0x89, 0x77, 0x0d, 0x0f, 0x8e, 0x18, 0x41, 0xe4, 0x5c, 0x7f, 0xd8, 0x41,
- 0x0c, 0xa4, 0x1e, 0x55, 0xc9, 0x1d, 0x44, 0x87, 0x1e, 0xea, 0x53, 0x45,
- 0xea, 0xbc, 0x0e, 0x3f, 0x2c, 0x17, 0x90, 0x7e, 0x49, 0x3e, 0xf0, 0x33,
- 0x27, 0x35, 0x47, 0xea, 0xc3, 0x0a, 0x98, 0x32, 0x0e, 0xe1, 0xb7, 0x06,
- 0xfa, 0x26, 0x3a, 0xc8, 0xed, 0x66, 0x0e, 0xf5, 0x0c, 0xb9, 0x75, 0x1d,
- 0x5e, 0xd3, 0x85, 0x5b, 0xbf, 0x8a, 0x20, 0x7d, 0xb7, 0x7f, 0x22, 0xba,
- 0xe1, 0x8c, 0xe2, 0xc1, 0x4b, 0x7a, 0x2d, 0x79, 0x9f, 0x89, 0xed, 0x13,
- 0xf0, 0x6e, 0x5d, 0x62, 0x20, 0x3d, 0xd1, 0x9b, 0x98, 0xc5, 0xb4, 0xd7,
- 0xbb, 0xa4, 0xc8, 0x89, 0x3e, 0x43, 0xdd, 0xae, 0x8d, 0xbb, 0x9c, 0xa8,
- 0xc8, 0x07, 0x82, 0x8e, 0x73, 0x52, 0x17, 0x3d, 0x03, 0x07, 0x4a, 0x3a,
- 0xde, 0xcf, 0xcf, 0xfd, 0x25, 0x1d, 0x6f, 0xa1, 0x3c, 0xfa, 0x1f, 0xb6,
- 0x5d, 0xc4, 0x63, 0x34, 0x54, 0x9a, 0xc2, 0x6f, 0x88, 0xc3, 0xc4, 0x93,
- 0x24, 0x75, 0xfc, 0x42, 0x7e, 0xbd, 0xe0, 0x36, 0xa7, 0xbb, 0xdd, 0xc5,
- 0xef, 0xa4, 0x7a, 0x80, 0x76, 0x20, 0x7a, 0x78, 0xad, 0x94, 0xdb, 0x38,
- 0xce, 0x90, 0x21, 0x3a, 0x2e, 0xe7, 0x65, 0xa2, 0xeb, 0x36, 0xc9, 0xb1,
- 0xfa, 0x81, 0xdf, 0xb0, 0xac, 0x87, 0xb8, 0x6b, 0xe2, 0x6b, 0xdd, 0x62,
- 0x3b, 0xb3, 0xdc, 0x58, 0x79, 0xd5, 0x42, 0xc7, 0xf9, 0x4a, 0x5c, 0xc3,
- 0x7b, 0x7a, 0x6b, 0xa2, 0x5d, 0x8d, 0xb0, 0xaf, 0x49, 0xd8, 0x93, 0x1d,
- 0x9c, 0xbb, 0x2b, 0x90, 0x0c, 0x89, 0xad, 0x61, 0x43, 0x45, 0x11, 0xc3,
- 0x71, 0xca, 0xd6, 0x63, 0xdb, 0x38, 0x67, 0xfb, 0x42, 0x5d, 0xe4, 0x71,
- 0x6a, 0x27, 0xd3, 0x7f, 0xf2, 0x27, 0xdd, 0x7a, 0x04, 0xef, 0x38, 0xb9,
- 0x90, 0xc3, 0x38, 0x29, 0xb9, 0xd1, 0x7c, 0x1c, 0x0e, 0x7a, 0xf0, 0x62,
- 0xac, 0x11, 0xc9, 0x7a, 0x05, 0x35, 0xfa, 0x9b, 0xce, 0x77, 0x42, 0xd2,
- 0x0e, 0x73, 0x3c, 0xf5, 0x56, 0x8f, 0xe4, 0x80, 0x5e, 0x5d, 0xe4, 0x76,
- 0x31, 0xc7, 0xbd, 0xb4, 0xfd, 0x7f, 0x75, 0x8e, 0x87, 0xa4, 0xfd, 0x48,
- 0x50, 0x53, 0x7f, 0xd7, 0x1c, 0x7e, 0xdf, 0xf9, 0x81, 0x2b, 0x33, 0xe3,
- 0xea, 0x01, 0xaa, 0xc8, 0x23, 0x54, 0x54, 0x8b, 0xcc, 0x72, 0x3b, 0xe2,
- 0x67, 0x73, 0x79, 0x4f, 0x9e, 0x89, 0x8d, 0x6c, 0x61, 0xbb, 0xcf, 0x39,
- 0x68, 0x94, 0xef, 0xd3, 0x1e, 0x29, 0x6b, 0x4d, 0x1e, 0x5a, 0xe1, 0xc5,
- 0x52, 0xb4, 0xc4, 0x97, 0x2d, 0x97, 0xb1, 0xa8, 0x66, 0x52, 0xf3, 0xc3,
- 0x6a, 0xf4, 0x10, 0x8b, 0xdf, 0x68, 0x6b, 0xc3, 0x72, 0xe6, 0x8c, 0xef,
- 0x10, 0x5c, 0x7a, 0x75, 0x0f, 0xa6, 0x38, 0xbe, 0x27, 0x0d, 0x59, 0x2f,
- 0x70, 0x70, 0x4b, 0xdc, 0x4a, 0xd1, 0x63, 0xad, 0x59, 0xb4, 0x9d, 0x6a,
- 0x5d, 0xe2, 0x7c, 0x2d, 0x6a, 0x4c, 0x6f, 0xec, 0x1d, 0x44, 0x8c, 0x1d,
- 0xe4, 0x39, 0x5a, 0x7d, 0x4b, 0xc2, 0x47, 0xed, 0xbe, 0x6c, 0x47, 0x13,
- 0x47, 0x94, 0xa2, 0x3f, 0xbc, 0xc0, 0xb9, 0x7d, 0xcd, 0xd6, 0x37, 0x56,
- 0x7a, 0x8a, 0xdf, 0x5f, 0x71, 0xf3, 0xd1, 0xb2, 0x3f, 0x84, 0x4b, 0xb8,
- 0xe1, 0xf7, 0x9f, 0xb2, 0x71, 0x86, 0x54, 0x88, 0x79, 0x29, 0xce, 0xf4,
- 0x19, 0x53, 0x8a, 0x4f, 0xaf, 0x25, 0xae, 0x0a, 0x96, 0x56, 0x90, 0x13,
- 0x4a, 0xec, 0xf7, 0xfb, 0xdf, 0x61, 0x19, 0x72, 0xba, 0xe3, 0xb1, 0xeb,
- 0x5b, 0x13, 0x7e, 0x24, 0xad, 0x4a, 0xfa, 0xe5, 0x2c, 0x33, 0xe4, 0xbf,
- 0xaa, 0x60, 0x35, 0x06, 0x68, 0xd7, 0x35, 0xcc, 0x57, 0x5b, 0xd2, 0x13,
- 0x8c, 0xe1, 0x6d, 0x78, 0x70, 0x82, 0x23, 0x6b, 0x18, 0x6c, 0x54, 0x4d,
- 0x59, 0x83, 0x08, 0xc2, 0xd7, 0xf0, 0xe0, 0x0d, 0xaa, 0x79, 0x1c, 0x3d,
- 0x1d, 0xfe, 0xce, 0x44, 0x01, 0xfe, 0x7a, 0x73, 0x13, 0xe2, 0x69, 0xc9,
- 0x3b, 0x05, 0x23, 0x93, 0x5b, 0x89, 0x5a, 0x8d, 0x75, 0xd7, 0x96, 0xf5,
- 0x0d, 0xb5, 0xd6, 0x94, 0xfc, 0x53, 0xeb, 0x7c, 0xc5, 0xc5, 0xd2, 0x20,
- 0xf3, 0x85, 0x1f, 0x87, 0xff, 0xcf, 0xea, 0x27, 0x38, 0x27, 0xd2, 0x17,
- 0xf9, 0x2f, 0x79, 0x3f, 0xbc, 0x2a, 0xb1, 0xb0, 0x77, 0xdc, 0xcb, 0xfc,
- 0x4a, 0xe6, 0x4c, 0xe2, 0xf1, 0x6b, 0xff, 0xf5, 0x79, 0xfa, 0x8b, 0x8f,
- 0xba, 0x7f, 0x44, 0xb7, 0x08, 0xf3, 0x8e, 0xa3, 0xc7, 0x23, 0xe1, 0x0a,
- 0x45, 0xc3, 0xf6, 0xb6, 0x7f, 0xa7, 0x8d, 0x80, 0x38, 0x06, 0x12, 0xeb,
- 0x5a, 0x6c, 0x19, 0xaf, 0x98, 0x51, 0xaf, 0x67, 0x4d, 0xb9, 0xde, 0x80,
- 0x6e, 0xa5, 0xa4, 0xde, 0x68, 0x3c, 0xd2, 0xb3, 0x8d, 0xf5, 0x1e, 0x65,
- 0xbd, 0x24, 0x63, 0xe7, 0x3d, 0x13, 0x41, 0x37, 0x9f, 0xb3, 0xc6, 0xab,
- 0x67, 0xb6, 0x77, 0xbe, 0xde, 0xe3, 0xba, 0x35, 0xe5, 0xb6, 0xb7, 0x38,
- 0xb2, 0xb1, 0xc2, 0xe3, 0x45, 0x9a, 0xf5, 0xa6, 0x58, 0xef, 0xf5, 0x09,
- 0x59, 0x8f, 0xc0, 0x0d, 0xe3, 0x76, 0xe6, 0xb8, 0x47, 0xd7, 0x83, 0x27,
- 0x91, 0x24, 0xe6, 0xba, 0x73, 0x79, 0xc3, 0x58, 0x7e, 0x33, 0xb6, 0xeb,
- 0x87, 0xe2, 0x95, 0xac, 0x77, 0x44, 0x3f, 0x14, 0xf6, 0xd1, 0xaf, 0xd6,
- 0x51, 0x5e, 0x2f, 0xf3, 0x1a, 0x95, 0xfe, 0xb2, 0x65, 0x5c, 0x62, 0xbf,
- 0x41, 0x5e, 0x12, 0xa2, 0xcd, 0xc9, 0x98, 0xa5, 0x5d, 0x99, 0x53, 0x19,
- 0x5f, 0x24, 0x36, 0xee, 0x8e, 0x4f, 0x99, 0x7b, 0x40, 0x72, 0xdd, 0x7a,
- 0x0b, 0x7d, 0x6d, 0x12, 0xff, 0x14, 0x62, 0x6f, 0x03, 0xf3, 0x4f, 0x69,
- 0x23, 0x84, 0x6d, 0xf4, 0xed, 0xfd, 0x86, 0xe3, 0x3c, 0x6f, 0xcc, 0xc7,
- 0x01, 0x23, 0x92, 0x12, 0x3b, 0x7c, 0xd3, 0x58, 0x76, 0xa5, 0xe4, 0x96,
- 0xc0, 0x9f, 0x60, 0x8a, 0xb6, 0x51, 0xa5, 0x8b, 0xbf, 0x29, 0x08, 0x47,
- 0xbd, 0x5a, 0x8d, 0xe2, 0xc0, 0xbf, 0x78, 0xe1, 0xc6, 0x85, 0x1c, 0x7b,
- 0xed, 0xf5, 0x0a, 0xde, 0xbf, 0x4a, 0xc1, 0xa1, 0xab, 0xa2, 0xe1, 0x11,
- 0x65, 0x16, 0xb1, 0x35, 0xda, 0xdd, 0xa9, 0x58, 0x47, 0x59, 0x37, 0xd9,
- 0xe6, 0x89, 0x84, 0xa1, 0xd4, 0xd1, 0xef, 0x5b, 0x34, 0x09, 0xfd, 0xde,
- 0x81, 0x68, 0xf8, 0x51, 0xfe, 0xf7, 0x4c, 0x28, 0x98, 0xd0, 0x23, 0x49,
- 0xb8, 0xf2, 0xd9, 0x36, 0xd3, 0xce, 0xab, 0xa3, 0x8e, 0x73, 0x2c, 0xde,
- 0x1a, 0x3c, 0x86, 0x37, 0x89, 0x6d, 0xd2, 0x4e, 0x19, 0xeb, 0xc1, 0x5c,
- 0x56, 0x4f, 0x76, 0x2a, 0x8e, 0x57, 0xf8, 0xc3, 0xfa, 0xbc, 0xc4, 0xc3,
- 0x72, 0x7f, 0xcb, 0x71, 0xd1, 0x71, 0xde, 0x34, 0x8a, 0xb2, 0x82, 0x1d,
- 0x91, 0x14, 0x30, 0x1f, 0x93, 0x7a, 0xa4, 0x6b, 0x8a, 0x3a, 0x08, 0xd3,
- 0xdf, 0xe6, 0xe9, 0x8d, 0x38, 0xee, 0x8b, 0x04, 0x8f, 0x2b, 0xcb, 0xcf,
- 0xaa, 0x58, 0xb4, 0xfe, 0x09, 0xa5, 0x75, 0x43, 0x15, 0xf4, 0x64, 0x41,
- 0x99, 0x2b, 0x3a, 0x09, 0x07, 0xc8, 0xa5, 0xd6, 0xc1, 0x8d, 0xd1, 0xb8,
- 0xcd, 0xf6, 0x26, 0xa7, 0xd1, 0x4c, 0xdb, 0xd7, 0x7b, 0xee, 0x23, 0x0f,
- 0x04, 0x3e, 0xce, 0x24, 0x41, 0xfa, 0xda, 0x88, 0xd4, 0xa7, 0x1c, 0xe7,
- 0x7e, 0xf6, 0x75, 0x07, 0xfb, 0xfa, 0x60, 0xfc, 0x3d, 0xe7, 0x5f, 0x5d,
- 0x99, 0x37, 0x62, 0x44, 0xbf, 0x54, 0xee, 0xbb, 0xcc, 0xf5, 0x45, 0xae,
- 0x0f, 0x37, 0xcf, 0x61, 0xbe, 0xd2, 0x21, 0xb8, 0x71, 0xd2, 0x4b, 0xdc,
- 0xa0, 0x3c, 0xc6, 0x10, 0xf5, 0xd2, 0x38, 0xec, 0x01, 0xe3, 0x5b, 0x38,
- 0xa5, 0xa8, 0x24, 0x42, 0x41, 0xf8, 0x75, 0x07, 0x0f, 0x90, 0x33, 0x24,
- 0xe7, 0xd4, 0xe1, 0x73, 0x86, 0x1f, 0xb3, 0xa2, 0xea, 0x65, 0x1e, 0xce,
- 0xc9, 0x81, 0xb8, 0x7c, 0xf7, 0x61, 0x6a, 0x8e, 0x07, 0x9b, 0xc9, 0x25,
- 0x82, 0x51, 0x75, 0x9e, 0xdc, 0xf7, 0xb7, 0xcb, 0x77, 0xf6, 0x7f, 0xae,
- 0x82, 0xfb, 0x69, 0x15, 0x6a, 0xb4, 0x37, 0x2c, 0xf7, 0xbb, 0x0c, 0xf9,
- 0xae, 0xa0, 0x39, 0xee, 0xe5, 0xbc, 0x38, 0xf0, 0x48, 0x7a, 0x1f, 0xe5,
- 0xfd, 0xb8, 0x7c, 0x4e, 0xde, 0xcf, 0x71, 0x27, 0xf7, 0x29, 0x82, 0x33,
- 0x3f, 0x72, 0x5e, 0x64, 0x1c, 0x09, 0xf2, 0xf9, 0xe7, 0xd8, 0xf6, 0xd1,
- 0xf8, 0xf3, 0xce, 0x3c, 0xe2, 0xeb, 0xb1, 0x84, 0x86, 0xf9, 0x57, 0x35,
- 0xe1, 0xf8, 0x9d, 0x32, 0x66, 0x05, 0xb3, 0xf4, 0x2f, 0xf8, 0x24, 0xcf,
- 0xac, 0xd5, 0xe7, 0xe2, 0xe6, 0x3b, 0x8a, 0xf7, 0xaa, 0xa2, 0xb2, 0x4e,
- 0xa8, 0xa1, 0xea, 0xaa, 0x06, 0x68, 0xa5, 0x7b, 0xcb, 0xa3, 0xde, 0xee,
- 0x59, 0x8a, 0x1e, 0xbc, 0x4d, 0x91, 0xe7, 0xbf, 0x24, 0xb7, 0x75, 0x9c,
- 0x07, 0x38, 0x5f, 0x2d, 0xf1, 0x00, 0x4e, 0xb3, 0x9d, 0x5e, 0xea, 0x6f,
- 0xe5, 0xf9, 0xf9, 0x2a, 0xd7, 0xff, 0xb9, 0xa3, 0x7d, 0x4a, 0xea, 0x8a,
- 0x8c, 0x85, 0x5d, 0x37, 0x2b, 0x1c, 0x50, 0xb5, 0xe8, 0xd9, 0xd5, 0x19,
- 0xcb, 0xf6, 0xba, 0xdf, 0x83, 0x1d, 0xaf, 0x9d, 0x5f, 0xf3, 0x3a, 0xe3,
- 0xc6, 0xa3, 0x65, 0xd7, 0x07, 0x71, 0xdc, 0xa9, 0x6f, 0xb7, 0x82, 0x95,
- 0x90, 0xb8, 0xd4, 0x1c, 0xfb, 0x0a, 0xe5, 0xfe, 0xc0, 0x28, 0xc6, 0xac,
- 0xfd, 0x46, 0x24, 0x6b, 0xd1, 0x1f, 0x52, 0xcc, 0x13, 0x3b, 0x25, 0x76,
- 0x4f, 0xd6, 0xfa, 0x50, 0x3b, 0x1f, 0x95, 0xed, 0x91, 0xfe, 0x05, 0xcc,
- 0x9b, 0x3c, 0x1d, 0x12, 0xeb, 0x64, 0x7e, 0xdc, 0x32, 0x6c, 0xab, 0x0a,
- 0xcb, 0xd9, 0xc7, 0x78, 0xfb, 0xef, 0x8b, 0x13, 0x22, 0x47, 0xac, 0x33,
- 0xd2, 0x9f, 0xc4, 0xef, 0x2b, 0x0b, 0x46, 0x65, 0x59, 0x4f, 0xf2, 0xdf,
- 0x90, 0xca, 0xab, 0xe4, 0x19, 0x15, 0xc1, 0xde, 0x8e, 0x46, 0x5e, 0xf2,
- 0xdc, 0x7b, 0xc3, 0xda, 0xfc, 0xf9, 0x75, 0x3c, 0x64, 0x8d, 0x0a, 0xa8,
- 0x57, 0x0b, 0x66, 0x13, 0x7d, 0x83, 0x32, 0x3e, 0x8b, 0x56, 0x2e, 0x39,
- 0x7a, 0xe7, 0x5d, 0x77, 0xd3, 0x9f, 0x9f, 0x63, 0x8b, 0xa3, 0xe4, 0x33,
- 0x96, 0xeb, 0x19, 0xe2, 0xeb, 0x33, 0xd7, 0xf5, 0x24, 0x86, 0x94, 0xd7,
- 0x06, 0x1b, 0x30, 0xb8, 0xfb, 0x0e, 0x68, 0x8d, 0x45, 0x1c, 0x52, 0xcd,
- 0xc5, 0x58, 0x96, 0x7d, 0xdb, 0x57, 0xe4, 0xe0, 0xb5, 0x18, 0xd8, 0x1d,
- 0x47, 0x6e, 0x8e, 0x3c, 0x93, 0x7b, 0x7e, 0x08, 0x4e, 0x6e, 0xdf, 0x7d,
- 0x99, 0xe4, 0xd4, 0x61, 0x91, 0x9b, 0xa2, 0xef, 0xa8, 0xfa, 0xdb, 0x8e,
- 0x15, 0x14, 0xf9, 0x87, 0xae, 0xf4, 0x52, 0x87, 0x37, 0xa1, 0xb5, 0x67,
- 0x0c, 0xa7, 0xc8, 0xeb, 0xdc, 0x35, 0x54, 0xad, 0xd2, 0x9c, 0xba, 0xdf,
- 0x87, 0x68, 0x6a, 0x9c, 0x38, 0x10, 0x98, 0xf0, 0x93, 0x9f, 0xcc, 0x77,
- 0xd7, 0x8e, 0x96, 0x91, 0x7f, 0xa4, 0xc8, 0x6d, 0x3f, 0xee, 0xf5, 0xe2,
- 0x6e, 0x62, 0xc6, 0x7e, 0xbd, 0x75, 0xc3, 0x18, 0x7e, 0x45, 0xac, 0x93,
- 0xf2, 0x3f, 0x60, 0x7b, 0x22, 0xd3, 0xcb, 0xf6, 0xe0, 0xf7, 0x12, 0x8f,
- 0xc9, 0x09, 0xbd, 0x3e, 0x3d, 0xed, 0x93, 0xf8, 0x2d, 0xdc, 0x75, 0xc7,
- 0x6e, 0x05, 0x9d, 0x94, 0xf3, 0x28, 0x6d, 0xe6, 0xfe, 0x28, 0xbc, 0x5d,
- 0x57, 0x91, 0xa3, 0x90, 0xf3, 0x61, 0x4e, 0x00, 0x8f, 0x8c, 0x23, 0x91,
- 0xd7, 0xa7, 0xe6, 0x05, 0xf0, 0x26, 0xe5, 0x08, 0xae, 0x57, 0x94, 0xe4,
- 0xf4, 0xac, 0xb9, 0x58, 0x4e, 0x2d, 0x1e, 0x2f, 0xc9, 0xd9, 0x43, 0x39,
- 0xd7, 0xb4, 0xc0, 0x5b, 0x7b, 0x8d, 0xcc, 0x55, 0x1b, 0xfd, 0xa7, 0x16,
- 0x19, 0x17, 0xdb, 0xc9, 0xe9, 0x3e, 0x06, 0x45, 0x5f, 0x28, 0xfc, 0xff,
- 0x1b, 0x6e, 0xbd, 0x9b, 0xda, 0xa6, 0xa6, 0xeb, 0x09, 0x9e, 0x67, 0x5a,
- 0xa6, 0xe8, 0xa8, 0x65, 0xdd, 0x34, 0x62, 0xeb, 0xee, 0xea, 0x72, 0x7f,
- 0xd9, 0x4e, 0xb9, 0x8d, 0x06, 0xde, 0x0b, 0xe1, 0x11, 0xe6, 0x71, 0x37,
- 0xb1, 0x9d, 0x03, 0x86, 0x70, 0xb1, 0x56, 0xa3, 0x4a, 0x91, 0xbc, 0x36,
- 0xcc, 0xb8, 0xde, 0x80, 0x3e, 0x37, 0x16, 0x84, 0x59, 0x7f, 0x77, 0x5d,
- 0x91, 0x4f, 0xc0, 0x77, 0x2b, 0xcb, 0x76, 0xc6, 0x8b, 0xed, 0xf9, 0x74,
- 0xc9, 0x15, 0xdb, 0xb1, 0x7f, 0xf8, 0xfc, 0xf3, 0xc8, 0x4d, 0xfa, 0xcc,
- 0xf9, 0x9a, 0x8a, 0x10, 0x4b, 0x2b, 0x50, 0x5d, 0x21, 0x58, 0x7f, 0xd1,
- 0xd8, 0xb7, 0x8c, 0xff, 0x29, 0xef, 0x57, 0x63, 0xeb, 0xb8, 0x83, 0x2d,
- 0x6e, 0x9e, 0x50, 0x81, 0xde, 0x36, 0xc1, 0x43, 0xb1, 0xa5, 0x39, 0x92,
- 0x27, 0x25, 0x72, 0x90, 0x18, 0x27, 0xf6, 0xb3, 0xc6, 0xb5, 0x1f, 0x8f,
- 0x32, 0xd3, 0x7e, 0x36, 0xe3, 0xbb, 0xfa, 0xa1, 0x3b, 0x2a, 0x71, 0xe8,
- 0x2e, 0x59, 0xff, 0xde, 0x10, 0xc7, 0xe1, 0x5b, 0xe8, 0x9b, 0xaf, 0x13,
- 0x5b, 0xb6, 0xb4, 0x30, 0x86, 0xb8, 0x98, 0xa5, 0xa0, 0x92, 0xb1, 0x7d,
- 0xdb, 0x6e, 0xe6, 0xc0, 0x6a, 0x90, 0x6d, 0x5e, 0x8a, 0x5d, 0xd2, 0x7f,
- 0x83, 0xb9, 0xee, 0xa1, 0x2f, 0x56, 0x22, 0x20, 0x39, 0xc7, 0x4f, 0x4e,
- 0x51, 0xc6, 0x4d, 0x46, 0x59, 0x57, 0xa2, 0xa7, 0xb2, 0x9c, 0x06, 0xa4,
- 0x77, 0x97, 0xeb, 0x2b, 0x78, 0x29, 0x1a, 0x2e, 0xad, 0x3f, 0x37, 0x60,
- 0x60, 0xfc, 0xd0, 0x31, 0x72, 0x0d, 0x27, 0xd1, 0x72, 0x68, 0x63, 0x98,
- 0x7d, 0x39, 0x13, 0x2f, 0xcf, 0xa9, 0xf8, 0xe6, 0x4c, 0x19, 0x62, 0xbb,
- 0x50, 0x6a, 0x17, 0x62, 0x4b, 0x2d, 0x6d, 0x34, 0x1f, 0x45, 0xaa, 0xc6,
- 0xac, 0x85, 0x3d, 0x4e, 0xdf, 0x9a, 0xa8, 0x80, 0xf7, 0x5a, 0x89, 0x7d,
- 0xc2, 0x77, 0xbc, 0x37, 0x9c, 0xb0, 0x2b, 0xf0, 0x69, 0xe3, 0x9c, 0x23,
- 0xb8, 0x78, 0x4c, 0xc7, 0xe5, 0x15, 0xc4, 0xc4, 0x85, 0xf1, 0x68, 0x72,
- 0x1d, 0xf3, 0xc2, 0x23, 0x6d, 0xde, 0x1b, 0xde, 0xca, 0xff, 0x9a, 0xdc,
- 0xf2, 0xd2, 0xf1, 0x88, 0x3e, 0x70, 0x74, 0x45, 0x54, 0xda, 0x94, 0xf6,
- 0xca, 0x36, 0x2a, 0xed, 0x3b, 0x4e, 0x34, 0x1e, 0x70, 0xe7, 0xbc, 0x3c,
- 0x86, 0x37, 0xf4, 0xf2, 0x18, 0x02, 0x8c, 0xa7, 0x49, 0x72, 0x57, 0xe1,
- 0xd5, 0x7e, 0xe6, 0x91, 0x5e, 0xf2, 0xf1, 0x6e, 0x08, 0xdf, 0x3b, 0x4a,
- 0x7e, 0xf2, 0xa4, 0x0d, 0xbc, 0x93, 0x75, 0xb0, 0x2c, 0x3e, 0x8b, 0xf8,
- 0xd2, 0x4f, 0xd9, 0xb2, 0xa6, 0x76, 0x50, 0x19, 0x67, 0xae, 0x79, 0xdc,
- 0x5b, 0x95, 0x54, 0x99, 0x5b, 0x1e, 0xc8, 0x47, 0xc3, 0x87, 0x98, 0x67,
- 0xfa, 0x99, 0xeb, 0x72, 0x06, 0x94, 0x27, 0x99, 0x67, 0xee, 0x2b, 0xe5,
- 0x99, 0x07, 0xf2, 0x01, 0xe4, 0xb3, 0xc4, 0xc6, 0x38, 0xf3, 0x5b, 0x37,
- 0x4f, 0x0f, 0x60, 0x32, 0xab, 0x32, 0x1f, 0x7f, 0xdf, 0x99, 0xaa, 0x77,
- 0xf7, 0x0b, 0xf0, 0x75, 0xbb, 0x01, 0x07, 0x87, 0x9b, 0x70, 0x36, 0x3f,
- 0x45, 0xbb, 0xb8, 0x0c, 0xd3, 0xa3, 0xb5, 0x98, 0x18, 0x7e, 0x95, 0x9f,
- 0xdb, 0xf0, 0xfe, 0xa8, 0x9b, 0xe3, 0x12, 0x0f, 0xa5, 0x7f, 0x07, 0x95,
- 0x43, 0x6e, 0x8e, 0x6b, 0x25, 0x99, 0xdb, 0x26, 0xfa, 0x4b, 0xb9, 0xed,
- 0x14, 0x73, 0xdb, 0x23, 0x6c, 0xf3, 0x85, 0x52, 0x9b, 0xcf, 0xb9, 0xff,
- 0xa5, 0x2f, 0x52, 0x77, 0x66, 0xbd, 0x44, 0x52, 0xd6, 0xa6, 0xc7, 0xed,
- 0x68, 0xac, 0x5c, 0xf7, 0x05, 0xd6, 0x3b, 0x72, 0xbe, 0xde, 0x6a, 0x0c,
- 0x64, 0xd6, 0x90, 0xe7, 0xcb, 0xda, 0xca, 0x7b, 0x6b, 0x6c, 0xea, 0xf2,
- 0xcb, 0xd1, 0xa9, 0xee, 0x59, 0xa8, 0xc3, 0xfa, 0xb8, 0x70, 0xa2, 0xb7,
- 0xc8, 0x89, 0x22, 0x89, 0x95, 0x8c, 0x0f, 0x9e, 0x68, 0x84, 0x58, 0x0f,
- 0x44, 0x27, 0x98, 0x03, 0xe4, 0xeb, 0x70, 0x37, 0x73, 0x31, 0xb5, 0x7e,
- 0x75, 0x69, 0x0f, 0xab, 0x94, 0xe3, 0x78, 0xd6, 0xa0, 0x6f, 0x52, 0xe4,
- 0xad, 0x26, 0xbf, 0xae, 0xc1, 0x2d, 0xc5, 0x75, 0x0b, 0xbf, 0x9f, 0xb2,
- 0xfd, 0xd1, 0xa9, 0x18, 0x5d, 0xc6, 0x38, 0xc0, 0x1b, 0xcf, 0xd9, 0x0a,
- 0x96, 0xe9, 0x3e, 0xac, 0x0b, 0xd6, 0x61, 0x99, 0xf1, 0xef, 0xce, 0x2d,
- 0xab, 0xe5, 0xd9, 0x79, 0x1e, 0xe1, 0xaf, 0x64, 0xbb, 0x6f, 0x92, 0x53,
- 0x8f, 0xf3, 0xcb, 0x54, 0xbe, 0x78, 0xdf, 0xca, 0x53, 0x36, 0xe5, 0x6e,
- 0xa3, 0xdc, 0x7b, 0x83, 0x6e, 0xbe, 0x5b, 0x2a, 0x37, 0x15, 0xf3, 0x10,
- 0xd7, 0xa5, 0x6c, 0x27, 0xe5, 0xde, 0x4d, 0xb9, 0xfd, 0x41, 0xe9, 0xdf,
- 0xbf, 0x3b, 0xf7, 0xae, 0x96, 0x67, 0xe5, 0x7d, 0x13, 0x29, 0xff, 0x9e,
- 0xc8, 0x35, 0xc6, 0x4b, 0x6d, 0x1d, 0xb2, 0x91, 0x95, 0xdc, 0x6f, 0x6d,
- 0x47, 0x54, 0xeb, 0x75, 0xd7, 0xb2, 0x35, 0xac, 0xcb, 0x6b, 0xb8, 0x87,
- 0xba, 0xcb, 0x79, 0xcb, 0x63, 0x72, 0xfb, 0x64, 0x09, 0x77, 0x5e, 0xce,
- 0x72, 0x7d, 0x25, 0xdc, 0xee, 0xcc, 0x8b, 0x0d, 0xcd, 0xdc, 0x4f, 0x6a,
- 0x2a, 0xf9, 0xb3, 0x17, 0x4f, 0xdb, 0x1f, 0x9c, 0x1b, 0xcc, 0x48, 0x3c,
- 0x93, 0xf5, 0x10, 0x0d, 0xd9, 0xfc, 0xe5, 0x68, 0x1e, 0x0a, 0x62, 0xad,
- 0x31, 0x9b, 0xbe, 0xfe, 0xa5, 0xf3, 0x36, 0x75, 0x80, 0xed, 0xc0, 0xe7,
- 0x8a, 0x57, 0x9e, 0xce, 0xb7, 0x06, 0x1b, 0x70, 0xe9, 0x1e, 0xd2, 0xfc,
- 0x64, 0x8d, 0x19, 0xed, 0xfe, 0x0e, 0xe7, 0xae, 0xca, 0xe5, 0xd0, 0x5b,
- 0x94, 0x1c, 0xe7, 0xef, 0xa9, 0xd2, 0xfc, 0x3d, 0x99, 0xbf, 0xae, 0xb2,
- 0x88, 0x45, 0x97, 0xa3, 0x65, 0x48, 0xfe, 0x07, 0xf1, 0x46, 0xc7, 0xc7,
- 0x79, 0xef, 0x72, 0x2c, 0x1c, 0xf9, 0x54, 0x25, 0xb9, 0xb5, 0x51, 0xcc,
- 0xc1, 0x2f, 0xcd, 0x33, 0x22, 0xfd, 0x16, 0x16, 0xb0, 0x5c, 0x13, 0x75,
- 0x26, 0x18, 0x28, 0xfd, 0x7a, 0xe4, 0x7c, 0xbf, 0xbe, 0xcc, 0x7e, 0xa5,
- 0x7c, 0xb2, 0xd6, 0x2a, 0xfd, 0x52, 0x92, 0xb5, 0x66, 0x13, 0xde, 0x1f,
- 0x40, 0x30, 0x68, 0x46, 0x53, 0x2f, 0xd3, 0xde, 0x27, 0xd8, 0xd7, 0x7a,
- 0xf4, 0x2b, 0x79, 0x77, 0xaf, 0xea, 0x20, 0xcb, 0xcc, 0x8c, 0xa3, 0xd2,
- 0x4f, 0xaf, 0xe4, 0x59, 0x3e, 0xd9, 0x67, 0xf2, 0xe9, 0x22, 0xff, 0x6d,
- 0x72, 0xc5, 0x3e, 0xca, 0x4f, 0x72, 0xfe, 0xfc, 0x6c, 0x03, 0x56, 0xb5,
- 0xd9, 0xed, 0x72, 0x55, 0x2f, 0xfd, 0x6e, 0x19, 0x6d, 0xea, 0xc9, 0x9c,
- 0x82, 0x51, 0x2a, 0xfd, 0x68, 0x56, 0xd6, 0x89, 0xc3, 0x38, 0x90, 0xf3,
- 0xe1, 0x85, 0xec, 0x3c, 0x8c, 0xe7, 0x2a, 0xf0, 0x5c, 0xf6, 0x32, 0xec,
- 0xcb, 0x11, 0xfd, 0xb2, 0x97, 0x63, 0x24, 0xe7, 0xc7, 0x4f, 0xb2, 0xd4,
- 0x53, 0xae, 0x0a, 0xff, 0x9c, 0xfd, 0x13, 0x7c, 0x3d, 0x57, 0x8d, 0xd7,
- 0xb2, 0x57, 0xe0, 0x60, 0xae, 0x06, 0xaf, 0x64, 0xc9, 0x27, 0x73, 0x01,
- 0xbc, 0x9c, 0xd5, 0x50, 0xc8, 0xcd, 0xc2, 0x4b, 0xd9, 0x08, 0x26, 0x72,
- 0xb5, 0xf8, 0x6e, 0x76, 0x01, 0xf2, 0xb9, 0x3a, 0x7c, 0x27, 0xdb, 0x8c,
- 0x2f, 0xe7, 0x82, 0x78, 0x31, 0xab, 0xe3, 0xa9, 0x5c, 0x3d, 0x8e, 0x65,
- 0xa3, 0x6c, 0x37, 0x84, 0xa3, 0xc3, 0x31, 0x1c, 0x18, 0x6d, 0xc4, 0x0b,
- 0xc3, 0x8b, 0x30, 0x3e, 0x1a, 0xc6, 0x73, 0xc3, 0x6d, 0xd8, 0x37, 0xfa,
- 0x6f, 0x15, 0xa2, 0x9f, 0x23, 0xf6, 0xff, 0x38, 0xaf, 0xc7, 0x6d, 0x1f,
- 0x31, 0xdf, 0xaf, 0xda, 0xa2, 0x37, 0xbf, 0x55, 0xcf, 0x39, 0x7a, 0x3a,
- 0xef, 0xce, 0x3b, 0xf4, 0x21, 0x77, 0x7f, 0x06, 0x7d, 0xc6, 0x65, 0xcc,
- 0xd9, 0xfa, 0x25, 0x7e, 0xd0, 0x16, 0x0e, 0x2a, 0xdb, 0x5d, 0x1c, 0xa9,
- 0x4d, 0xce, 0xa2, 0x2e, 0x39, 0xec, 0x60, 0x0d, 0x7d, 0x32, 0x4b, 0x7f,
- 0xb6, 0x38, 0xaf, 0x76, 0xfe, 0xa0, 0xb2, 0x83, 0x39, 0xe2, 0x95, 0x43,
- 0x96, 0x53, 0xed, 0xe2, 0x69, 0x34, 0xb9, 0x88, 0x3e, 0x17, 0x1b, 0x11,
- 0x7d, 0xde, 0x59, 0x21, 0xfa, 0xac, 0xd0, 0x3f, 0xcc, 0x4e, 0xca, 0x7a,
- 0x0f, 0x94, 0xec, 0xe1, 0xfb, 0x95, 0xc5, 0xbc, 0xaa, 0x3c, 0xef, 0x8e,
- 0x33, 0x68, 0x94, 0xe7, 0x9e, 0xfc, 0xaf, 0x41, 0xd6, 0xa4, 0xc0, 0x58,
- 0x50, 0x8f, 0x5c, 0x48, 0xf2, 0xf5, 0x99, 0x98, 0x81, 0x64, 0xa5, 0x19,
- 0xd5, 0x5a, 0xd4, 0x99, 0x7c, 0x45, 0xb0, 0x43, 0xe4, 0x5b, 0x2e, 0xee,
- 0x1c, 0x3e, 0x8f, 0x1f, 0x67, 0x2b, 0x85, 0xa7, 0xec, 0xb7, 0xa5, 0x6f,
- 0x50, 0x2b, 0xa4, 0xcf, 0x28, 0xde, 0x43, 0xa1, 0xac, 0xaf, 0x99, 0x76,
- 0xa7, 0x52, 0xb7, 0x62, 0x7b, 0x5e, 0xfa, 0xc2, 0x72, 0x89, 0x7b, 0xec,
- 0x47, 0x13, 0x5e, 0xb0, 0x8b, 0x7b, 0x33, 0xe3, 0x79, 0xd1, 0xb7, 0x86,
- 0xad, 0xe4, 0x5e, 0x87, 0x87, 0x15, 0xea, 0xee, 0x2f, 0x51, 0xdc, 0x3f,
- 0xf2, 0xd2, 0x57, 0xd7, 0xb2, 0x3c, 0x63, 0x7c, 0x61, 0xda, 0xdd, 0x1b,
- 0xae, 0x73, 0xf3, 0xee, 0x30, 0x0a, 0x03, 0x1f, 0x9c, 0xdb, 0x96, 0xf9,
- 0xe5, 0xb9, 0x3d, 0x99, 0x68, 0x4a, 0xf6, 0x67, 0xf2, 0x13, 0x3e, 0xe4,
- 0xf6, 0x06, 0xf0, 0xd4, 0x84, 0x1f, 0x35, 0x69, 0xc9, 0xf3, 0x83, 0x78,
- 0x6a, 0xff, 0xa1, 0x15, 0x35, 0x68, 0xe0, 0xff, 0x10, 0xaf, 0x46, 0x5e,
- 0x01, 0x1c, 0x1b, 0xf5, 0xe3, 0x2d, 0x5b, 0x7c, 0x58, 0xfc, 0xa3, 0x8d,
- 0xd8, 0x1f, 0x60, 0xbc, 0x55, 0x19, 0x47, 0x9a, 0x70, 0x38, 0x1f, 0xc4,
- 0xf2, 0x6c, 0x3d, 0x9e, 0xcb, 0x25, 0xf1, 0x44, 0xa6, 0x1e, 0x67, 0x1f,
- 0xf3, 0x63, 0xde, 0x3e, 0xf1, 0x87, 0x06, 0x9c, 0x1e, 0xfc, 0x04, 0x0a,
- 0x7b, 0x93, 0xb0, 0x33, 0xb3, 0xb1, 0x63, 0xb0, 0x01, 0xdf, 0x61, 0x99,
- 0x7e, 0xea, 0xa9, 0x7a, 0xa7, 0x89, 0x17, 0x69, 0x43, 0x55, 0x3b, 0x6f,
- 0xa4, 0xec, 0x30, 0x7c, 0x03, 0x21, 0x1c, 0xc9, 0x7b, 0x85, 0xd7, 0x71,
- 0x1e, 0x7f, 0x5a, 0x9c, 0x17, 0x08, 0x6f, 0xbd, 0x98, 0x07, 0x1e, 0x3f,
- 0xcf, 0x03, 0x81, 0x5c, 0x5e, 0xd6, 0x18, 0xdb, 0x3a, 0xfb, 0xec, 0x89,
- 0xff, 0xcf, 0x6f, 0xfe, 0xf4, 0xdb, 0x15, 0x4b, 0x0c, 0x62, 0x9d, 0x8c,
- 0x7f, 0xed, 0x83, 0xd5, 0xe6, 0x86, 0x2f, 0xae, 0x58, 0x52, 0x89, 0xfb,
- 0xdd, 0xf9, 0xea, 0x81, 0xbd, 0xbb, 0x9b, 0xf1, 0xb5, 0xb5, 0x67, 0x40,
- 0xb9, 0x02, 0xa9, 0xfa, 0x21, 0xde, 0x53, 0x4b, 0x3e, 0x07, 0x55, 0x6c,
- 0xad, 0x8e, 0xfa, 0x54, 0x0b, 0x1a, 0x4e, 0xd0, 0xc8, 0x6a, 0xd3, 0x11,
- 0x4c, 0xd5, 0xcb, 0x38, 0x63, 0xcc, 0xb3, 0x3c, 0xb2, 0x77, 0x8d, 0x4f,
- 0x33, 0xc6, 0x9d, 0x5d, 0xac, 0x20, 0xf1, 0x67, 0xe2, 0x83, 0xb7, 0x96,
- 0xf6, 0x80, 0x65, 0x3f, 0x4c, 0xe6, 0xad, 0xac, 0xff, 0xbd, 0xb2, 0xee,
- 0xc9, 0x3f, 0xc1, 0x0a, 0x2f, 0x0e, 0xdb, 0x39, 0xe6, 0x08, 0x32, 0x07,
- 0x32, 0xa6, 0xed, 0xac, 0x27, 0xe3, 0x92, 0xe7, 0xad, 0x89, 0xfa, 0x8f,
- 0x1c, 0x97, 0x8c, 0x67, 0xad, 0x1f, 0xd5, 0x32, 0x86, 0xb2, 0x2e, 0xfa,
- 0x58, 0xf7, 0x51, 0xde, 0x93, 0x7a, 0x8e, 0xb3, 0xfd, 0xa2, 0x98, 0x55,
- 0x91, 0xac, 0x66, 0xdf, 0x9f, 0xb4, 0xa3, 0xc9, 0x77, 0x88, 0x8b, 0xc7,
- 0xa8, 0xc3, 0x51, 0x5b, 0xec, 0x6f, 0x0b, 0xed, 0xae, 0x5f, 0x39, 0x7a,
- 0xde, 0xf6, 0x80, 0x83, 0xb6, 0xcc, 0xaf, 0xf0, 0x29, 0x19, 0xaf, 0x86,
- 0xe9, 0x89, 0xa0, 0xcb, 0xc7, 0xdf, 0xb6, 0xc5, 0x26, 0x62, 0xcc, 0xcf,
- 0xa6, 0xcf, 0xf5, 0x66, 0x0c, 0x1c, 0xe3, 0xdc, 0x9e, 0xb6, 0xab, 0x88,
- 0x37, 0x1d, 0x90, 0xbd, 0xce, 0xf7, 0xed, 0x04, 0x5e, 0x22, 0x66, 0xbd,
- 0x47, 0x5b, 0xfb, 0x2e, 0x31, 0xec, 0x5d, 0x5b, 0xc7, 0x77, 0x68, 0x7b,
- 0xef, 0xd8, 0x31, 0xbc, 0x98, 0xaf, 0xc7, 0x51, 0xe2, 0xd0, 0x49, 0x7e,
- 0x5e, 0x9e, 0xf7, 0xc1, 0x0a, 0xc9, 0xbe, 0xda, 0x1e, 0x3f, 0x6a, 0x7b,
- 0xd9, 0xe7, 0x48, 0x97, 0x1c, 0x44, 0x79, 0x96, 0xe3, 0xd3, 0x94, 0x32,
- 0x0f, 0x29, 0xe7, 0x04, 0x49, 0x64, 0x33, 0x33, 0xb1, 0x21, 0xd2, 0x9f,
- 0xa3, 0xdd, 0xfa, 0xd2, 0xe5, 0x38, 0xc0, 0xd8, 0x59, 0x10, 0xdb, 0xf6,
- 0xc0, 0x33, 0x24, 0xf6, 0x7f, 0x0d, 0x75, 0x3d, 0x7d, 0x4e, 0xf6, 0xd2,
- 0x54, 0x7d, 0x8a, 0xfe, 0x5e, 0x85, 0xde, 0xdc, 0xe5, 0xa8, 0x19, 0x5a,
- 0x8a, 0xfb, 0xe3, 0xe2, 0xf7, 0x7e, 0xf4, 0xe7, 0x3c, 0xa8, 0x1c, 0x22,
- 0x77, 0x61, 0xd9, 0xa9, 0x50, 0x31, 0x1e, 0xa9, 0x69, 0xc3, 0xf5, 0x83,
- 0x05, 0x85, 0x0f, 0xce, 0xd9, 0x99, 0x43, 0xf3, 0x54, 0x4c, 0x9f, 0x4b,
- 0x67, 0x02, 0xe8, 0xa3, 0x4d, 0xab, 0x69, 0x05, 0x75, 0x7a, 0x88, 0xf9,
- 0x5f, 0x1b, 0x7a, 0xa9, 0x8b, 0xf9, 0xe9, 0x26, 0x3c, 0x31, 0xd1, 0x88,
- 0x79, 0xbb, 0x4c, 0x3c, 0x4e, 0xdb, 0x0f, 0xef, 0xba, 0x11, 0x7b, 0x58,
- 0xee, 0x15, 0x3e, 0x7b, 0x65, 0x7f, 0x03, 0xaf, 0x10, 0xaf, 0x46, 0x5e,
- 0xf5, 0x18, 0xd8, 0xab, 0x97, 0xce, 0x61, 0x78, 0xd0, 0x30, 0x24, 0xf8,
- 0xa2, 0xe2, 0x8e, 0x76, 0x05, 0xc6, 0xd5, 0x6c, 0x73, 0xe1, 0x87, 0x61,
- 0x4d, 0xc3, 0x1f, 0xd0, 0xef, 0x1f, 0x38, 0x53, 0xe7, 0xed, 0xc7, 0x0f,
- 0x6f, 0xfa, 0xfb, 0xae, 0xfd, 0x2c, 0x28, 0x48, 0x3b, 0xef, 0x12, 0x33,
- 0xc4, 0x86, 0x7e, 0x17, 0x9e, 0x95, 0xf5, 0xfe, 0xdb, 0x67, 0x2b, 0x70,
- 0xde, 0xbe, 0x2e, 0x5a, 0x77, 0x47, 0x9e, 0x36, 0xb1, 0xc3, 0x3d, 0x3b,
- 0x22, 0xb9, 0x4e, 0xa4, 0x2b, 0x47, 0xfd, 0xf4, 0x33, 0x87, 0xb9, 0x87,
- 0x38, 0xb1, 0x3d, 0x13, 0xb1, 0x2c, 0xb6, 0xe5, 0x23, 0x36, 0x3c, 0x30,
- 0xe8, 0x97, 0xf5, 0x6e, 0xcd, 0xa7, 0xcf, 0xc3, 0x3b, 0x39, 0xb1, 0xf9,
- 0x2a, 0x1c, 0xce, 0x86, 0x71, 0xca, 0xfd, 0x5c, 0xcd, 0x58, 0xe3, 0xa0,
- 0xd3, 0x98, 0x85, 0xbe, 0x60, 0x15, 0x06, 0x62, 0x37, 0x22, 0x77, 0x07,
- 0x73, 0x6c, 0xfa, 0x58, 0xad, 0xee, 0x47, 0x3a, 0x28, 0xf9, 0x8b, 0x07,
- 0x99, 0xd8, 0xed, 0x38, 0x5e, 0xef, 0xc5, 0x3c, 0x59, 0x6f, 0xe1, 0xb3,
- 0x3d, 0x41, 0x28, 0xf4, 0xbd, 0xa4, 0x8f, 0xb8, 0x34, 0x6b, 0x00, 0x4e,
- 0xad, 0xa9, 0xcb, 0x1e, 0x4c, 0xcf, 0x56, 0xe2, 0x52, 0xcd, 0x44, 0x0d,
- 0xe3, 0x4e, 0x0b, 0xaa, 0xf7, 0xca, 0x5e, 0x40, 0x00, 0xeb, 0x86, 0xaf,
- 0x95, 0xbd, 0x81, 0x98, 0xa6, 0x04, 0x70, 0xef, 0xb0, 0xc4, 0x8f, 0x35,
- 0xa8, 0xd8, 0x5f, 0x8b, 0x2f, 0x66, 0xbd, 0xc4, 0x78, 0xe2, 0x0d, 0xcb,
- 0xed, 0xc9, 0xd4, 0xa1, 0xee, 0xb1, 0x67, 0x9d, 0x30, 0x75, 0x5c, 0xb7,
- 0x57, 0xb0, 0x88, 0xb6, 0x9b, 0xf9, 0x3c, 0x0a, 0x76, 0x33, 0xe5, 0xf6,
- 0x70, 0x7c, 0x21, 0xbc, 0x4b, 0xec, 0xaa, 0x99, 0x08, 0xe3, 0x9d, 0xdd,
- 0x92, 0xab, 0x24, 0xe1, 0x9d, 0xb8, 0x0c, 0x6f, 0xf2, 0xf3, 0x09, 0xa3,
- 0x13, 0xea, 0x44, 0x13, 0x4e, 0x66, 0xba, 0xe0, 0x99, 0xa8, 0x2d, 0x62,
- 0xd8, 0x5e, 0x3f, 0xea, 0x06, 0xf5, 0xd8, 0x34, 0xe7, 0xc8, 0xb7, 0x97,
- 0x04, 0xa7, 0x51, 0xda, 0x3f, 0x6f, 0xdb, 0xc6, 0x85, 0x7d, 0x87, 0xf2,
- 0xd9, 0x15, 0xb1, 0xef, 0xef, 0x3a, 0x4f, 0x04, 0xd9, 0xbf, 0x8e, 0x08,
- 0xfa, 0x62, 0xc7, 0x64, 0x3f, 0x9f, 0xe3, 0x4b, 0x72, 0xee, 0x9f, 0x77,
- 0xe4, 0x5c, 0x88, 0xcf, 0x94, 0x33, 0x19, 0xcf, 0x39, 0xdb, 0x57, 0xcb,
- 0xfd, 0xdb, 0xab, 0x50, 0xcd, 0xc4, 0xc9, 0x14, 0x99, 0x3b, 0x64, 0x6e,
- 0x19, 0x75, 0x3e, 0x4c, 0xe6, 0x3f, 0x3a, 0x8f, 0x9f, 0x2f, 0x8f, 0xa0,
- 0xcf, 0x5d, 0x13, 0xbf, 0xe0, 0xcb, 0x35, 0x9c, 0xbb, 0xf5, 0x25, 0x5f,
- 0x7e, 0xc7, 0x96, 0xf9, 0x93, 0xf3, 0x4b, 0x01, 0x72, 0x30, 0x03, 0xd5,
- 0x9c, 0xbb, 0xf7, 0x6d, 0x28, 0xb7, 0x76, 0x74, 0x63, 0xd6, 0x44, 0x80,
- 0xbe, 0x1e, 0x59, 0x6f, 0xc1, 0x66, 0x5b, 0x1d, 0xa8, 0x62, 0x9d, 0x93,
- 0xb6, 0x87, 0x7e, 0x9e, 0xe0, 0x98, 0x83, 0x70, 0x5c, 0x5e, 0xbf, 0x1a,
- 0xf3, 0xa9, 0xa7, 0xb3, 0xb6, 0x89, 0x79, 0xd4, 0xd3, 0xb4, 0xed, 0x25,
- 0x4e, 0x34, 0x11, 0x0f, 0x34, 0xd4, 0x12, 0x1b, 0x2b, 0x06, 0x1d, 0x1c,
- 0x32, 0xea, 0xc8, 0xf5, 0xc5, 0x4e, 0x3b, 0x10, 0x1e, 0x30, 0x30, 0x6f,
- 0xa0, 0x79, 0xe3, 0x3c, 0x8f, 0x07, 0xc7, 0x7d, 0xc5, 0xd8, 0x93, 0x9b,
- 0x23, 0xfa, 0x91, 0x31, 0xb9, 0xb9, 0xfc, 0x87, 0x60, 0xc0, 0x6a, 0x80,
- 0xb2, 0x0a, 0xc4, 0x8c, 0xcf, 0xb1, 0xad, 0x37, 0xec, 0x57, 0x71, 0xf3,
- 0x84, 0xe0, 0xcb, 0x0f, 0xb1, 0x92, 0xfd, 0x78, 0x97, 0xb8, 0x76, 0x5f,
- 0xf4, 0x1b, 0x1c, 0x6b, 0x13, 0x6e, 0x99, 0x98, 0x3e, 0xd7, 0xe7, 0x8e,
- 0xb3, 0x9c, 0xff, 0xf9, 0x71, 0x5f, 0xb6, 0x7c, 0x06, 0x2d, 0x49, 0x9f,
- 0x91, 0x38, 0xe1, 0x87, 0xf8, 0x4d, 0xb7, 0xbd, 0x0d, 0xc5, 0x78, 0x2e,
- 0x57, 0x59, 0x8f, 0x3b, 0xbd, 0x92, 0x97, 0x17, 0x7d, 0x43, 0xfa, 0xf3,
- 0xbb, 0xca, 0x14, 0x7d, 0x43, 0xfc, 0xe2, 0xcb, 0xae, 0x7e, 0x85, 0x77,
- 0x69, 0xb8, 0x6d, 0xe2, 0x97, 0xc4, 0xc7, 0x48, 0x32, 0x47, 0xcc, 0x7e,
- 0x9d, 0xfa, 0xdd, 0x4e, 0xfd, 0x32, 0x07, 0x60, 0xbc, 0x4a, 0x50, 0x9f,
- 0x3e, 0x72, 0x15, 0x2f, 0x31, 0xd3, 0xa4, 0x2e, 0x41, 0x0c, 0x64, 0xee,
- 0x1e, 0x2c, 0x8e, 0x37, 0x77, 0x7e, 0xfe, 0xd8, 0x96, 0x92, 0xc0, 0x09,
- 0xfb, 0x87, 0x55, 0x72, 0x26, 0xe8, 0xa4, 0xed, 0x3e, 0x97, 0x35, 0xcd,
- 0x19, 0x65, 0x2e, 0xb4, 0xbd, 0xcf, 0x16, 0xfe, 0x5c, 0x49, 0xbb, 0xd6,
- 0x28, 0xaf, 0xa6, 0x84, 0xa9, 0x52, 0x57, 0xf6, 0x60, 0xa5, 0xfd, 0x6e,
- 0xe1, 0x20, 0x78, 0x83, 0x3e, 0x77, 0xc4, 0xa8, 0xc0, 0xa8, 0x3b, 0x17,
- 0x62, 0x8f, 0xc5, 0x76, 0x2f, 0xd8, 0x4d, 0xba, 0xae, 0x74, 0x1e, 0xab,
- 0xba, 0xc8, 0xc9, 0x2e, 0x6d, 0xa3, 0xe2, 0x3f, 0xb1, 0x8d, 0x44, 0xa9,
- 0x8d, 0x8f, 0x3a, 0xe3, 0x06, 0x3c, 0x65, 0x4b, 0xec, 0x97, 0xfd, 0x0f,
- 0x0d, 0x8b, 0x26, 0x04, 0x5f, 0xe8, 0xbb, 0x03, 0xd3, 0x2e, 0xf7, 0xcf,
- 0x41, 0xf6, 0xb6, 0x42, 0xf0, 0x45, 0x35, 0x9c, 0xd2, 0x63, 0x58, 0x58,
- 0x90, 0xfd, 0xa9, 0x7d, 0x75, 0xc2, 0xe1, 0xce, 0xe8, 0xc2, 0x3b, 0x64,
- 0xbe, 0xca, 0xf7, 0xfc, 0xd8, 0xaf, 0x17, 0xfb, 0x9a, 0x54, 0x8b, 0xdc,
- 0xd1, 0x43, 0xee, 0xd8, 0x6b, 0xf8, 0x69, 0x97, 0xad, 0xc1, 0xd9, 0xbf,
- 0x73, 0x2f, 0xab, 0xdc, 0xdf, 0xdf, 0x57, 0xee, 0xc2, 0x7a, 0x5c, 0xf6,
- 0xa2, 0xfd, 0x21, 0x19, 0xd3, 0x5c, 0xa0, 0x41, 0xe2, 0x55, 0x91, 0xa3,
- 0x6e, 0x3d, 0x9f, 0xff, 0x58, 0xca, 0x60, 0xfe, 0x31, 0xd4, 0xeb, 0x0b,
- 0x50, 0xdf, 0x50, 0xc3, 0xb8, 0x1c, 0xed, 0xa2, 0x7b, 0x4b, 0x2c, 0xb3,
- 0x82, 0xa6, 0xe4, 0xbf, 0xc2, 0x5b, 0xa5, 0xcd, 0x7e, 0xa5, 0xaa, 0x20,
- 0xed, 0x1e, 0x54, 0xfc, 0x85, 0x0f, 0x6b, 0x5b, 0xce, 0xfb, 0x4d, 0x9f,
- 0x1b, 0xca, 0x74, 0xbb, 0x7b, 0x8c, 0xcb, 0x86, 0x1c, 0xdc, 0x69, 0x34,
- 0xe1, 0xee, 0x06, 0x69, 0xa3, 0x98, 0xc3, 0x68, 0xea, 0x34, 0x39, 0xdc,
- 0x6f, 0x1c, 0x55, 0x97, 0xcf, 0x3e, 0x78, 0x1e, 0xd3, 0xa7, 0xd7, 0x42,
- 0xc5, 0xd9, 0xeb, 0x24, 0x9f, 0xf1, 0x91, 0x7f, 0x6d, 0xaa, 0x2e, 0xee,
- 0x2f, 0x8b, 0x1d, 0x4b, 0x3f, 0xfc, 0xf4, 0xb3, 0x0b, 0xfd, 0xd8, 0xf6,
- 0x07, 0xf5, 0xc3, 0x8f, 0x9b, 0x86, 0x92, 0x18, 0x35, 0x4e, 0x38, 0x56,
- 0x68, 0x66, 0xdb, 0x3e, 0xac, 0x1c, 0xfa, 0x8d, 0x33, 0xcb, 0x6d, 0x5b,
- 0x27, 0xa7, 0x52, 0xf1, 0xc0, 0x12, 0x1f, 0x6e, 0x1d, 0x89, 0x62, 0xc5,
- 0x90, 0x8a, 0xd8, 0x12, 0xe9, 0x43, 0x14, 0x5d, 0x23, 0xbb, 0xbd, 0xc5,
- 0xf2, 0xc0, 0x2d, 0x1c, 0xc3, 0x1b, 0x46, 0x0d, 0x7e, 0x40, 0x0c, 0xac,
- 0x75, 0xb9, 0xfd, 0x46, 0x25, 0x23, 0xdc, 0xde, 0xa7, 0x62, 0xb6, 0x8e,
- 0x60, 0x83, 0x99, 0xa4, 0xee, 0x3a, 0x95, 0xc7, 0x72, 0x1b, 0x95, 0xa1,
- 0x7c, 0xb9, 0xef, 0x01, 0x7c, 0xa2, 0x10, 0xc4, 0x27, 0xc6, 0x1a, 0x78,
- 0x85, 0x78, 0x35, 0xf2, 0x7a, 0xf1, 0xfc, 0xb8, 0xca, 0x67, 0x3c, 0x9f,
- 0x65, 0x4e, 0xb1, 0xcd, 0xf5, 0x4b, 0x89, 0x0b, 0x9a, 0x9c, 0xd5, 0xc1,
- 0x5b, 0x59, 0xc9, 0x27, 0xb6, 0xd1, 0x86, 0x65, 0x4d, 0xb8, 0x92, 0x39,
- 0x45, 0x24, 0x36, 0x85, 0xbf, 0xaa, 0x2e, 0xce, 0x7d, 0xd1, 0x86, 0x71,
- 0xde, 0x86, 0x7d, 0x78, 0x3b, 0xab, 0xa2, 0x25, 0xfe, 0x6f, 0xce, 0xf1,
- 0xa0, 0xe0, 0xc9, 0xa5, 0xcf, 0xcb, 0x9c, 0x65, 0xfa, 0x5c, 0x36, 0xd3,
- 0x34, 0x63, 0x5f, 0x56, 0x41, 0xc5, 0x90, 0xf0, 0xf3, 0xeb, 0x5c, 0xbe,
- 0xf7, 0x7d, 0xc3, 0x07, 0xef, 0xd0, 0xa1, 0x2b, 0xe5, 0x68, 0x93, 0x6f,
- 0x8c, 0x71, 0xab, 0x83, 0xf3, 0x32, 0xf2, 0xf1, 0x92, 0xce, 0xca, 0xba,
- 0x50, 0xdc, 0x35, 0x49, 0xd5, 0x8d, 0xe9, 0x41, 0xa8, 0x63, 0xc2, 0x43,
- 0xc9, 0x0d, 0xc6, 0x24, 0x1f, 0x08, 0xf1, 0xbf, 0xe4, 0x06, 0x8d, 0xfc,
- 0xcf, 0xc4, 0xa2, 0x51, 0xe2, 0x78, 0x0f, 0xfa, 0x19, 0x9f, 0x2a, 0xa3,
- 0x3d, 0xd8, 0x3e, 0xfe, 0x61, 0x31, 0xbf, 0x98, 0x63, 0x3d, 0x7b, 0xde,
- 0xcf, 0xdc, 0x39, 0x62, 0x9f, 0xa6, 0xcf, 0x89, 0xcf, 0xc8, 0x5c, 0xed,
- 0xcb, 0x4a, 0x1f, 0x1c, 0x6c, 0x30, 0x6e, 0x64, 0xdb, 0x3e, 0xa8, 0x0d,
- 0x33, 0xb9, 0xe7, 0x79, 0x3e, 0x4d, 0xdd, 0x6d, 0x54, 0x46, 0x39, 0x27,
- 0x96, 0xb7, 0x52, 0xd6, 0x87, 0x82, 0x15, 0x9c, 0x93, 0xaf, 0xe4, 0x45,
- 0x46, 0xa7, 0x32, 0x9e, 0x9b, 0x59, 0x67, 0xa3, 0x32, 0x96, 0xff, 0x55,
- 0xb5, 0xac, 0x99, 0x5f, 0xd0, 0x4d, 0xb9, 0x0f, 0x62, 0x63, 0x1a, 0xea,
- 0xd3, 0xa2, 0x67, 0x19, 0xb3, 0x06, 0x2f, 0x79, 0x5c, 0x7d, 0xe1, 0x43,
- 0xdb, 0x6c, 0xac, 0x72, 0xcf, 0x62, 0xc6, 0x18, 0x8b, 0x02, 0x56, 0x25,
- 0x39, 0x1f, 0x6d, 0x34, 0xe5, 0x33, 0xbb, 0x3a, 0xf7, 0xd9, 0x0b, 0x83,
- 0x87, 0x4b, 0x6b, 0x11, 0x6b, 0x21, 0xbc, 0x54, 0x71, 0x71, 0xd6, 0xa3,
- 0x47, 0xb1, 0x9c, 0xb9, 0xee, 0x4d, 0xb9, 0x62, 0x7f, 0xc7, 0xd8, 0xdf,
- 0x29, 0xd7, 0xf7, 0x92, 0xca, 0x68, 0x5e, 0x75, 0xfb, 0xed, 0x35, 0xa5,
- 0xbf, 0x52, 0x97, 0xe3, 0xc9, 0xbf, 0x56, 0xca, 0xa9, 0x92, 0x18, 0xcc,
- 0xcc, 0xf4, 0x61, 0xe9, 0x73, 0x2d, 0xda, 0x86, 0x3e, 0xa0, 0x9f, 0xc9,
- 0xbc, 0x0a, 0xfe, 0xcc, 0xc3, 0xca, 0x91, 0x59, 0x68, 0x1d, 0x0a, 0xe3,
- 0xb6, 0x91, 0x06, 0x2c, 0xda, 0xb5, 0x06, 0xd5, 0x63, 0x41, 0x5c, 0xb9,
- 0x4b, 0xd6, 0xf8, 0x57, 0xa3, 0xb2, 0x70, 0x5b, 0x8d, 0xe4, 0xb8, 0x7a,
- 0x3a, 0xc1, 0xf9, 0x4b, 0xa0, 0x22, 0x1d, 0x49, 0x24, 0x21, 0x6b, 0xa4,
- 0x26, 0x2a, 0x0a, 0x26, 0xf9, 0xa4, 0xb3, 0x79, 0xbe, 0xe9, 0x73, 0xcf,
- 0x9b, 0x2d, 0x2b, 0xd0, 0xe6, 0x39, 0x6e, 0x1f, 0x2f, 0x4f, 0xda, 0x71,
- 0xce, 0x5e, 0x87, 0xcd, 0x35, 0x66, 0x13, 0x3c, 0x85, 0xcb, 0x91, 0x1c,
- 0x69, 0xc3, 0xbc, 0x42, 0x03, 0x3a, 0x47, 0x42, 0x88, 0xa5, 0xc5, 0xc7,
- 0x23, 0x5a, 0x4a, 0xed, 0x80, 0xbf, 0xc0, 0x78, 0x9a, 0xfe, 0x8d, 0xf3,
- 0x16, 0xed, 0xa0, 0x87, 0xfa, 0xba, 0x26, 0xdd, 0x85, 0xba, 0x42, 0x00,
- 0x57, 0x0f, 0x7d, 0x02, 0xb5, 0x23, 0x7e, 0xcc, 0x1a, 0xd2, 0x90, 0x5f,
- 0xe2, 0x47, 0x60, 0x24, 0x8c, 0xea, 0xb4, 0xde, 0x75, 0x9b, 0x82, 0xe4,
- 0xc2, 0x25, 0x61, 0xb6, 0x4d, 0x7b, 0xa3, 0x7f, 0x8d, 0x90, 0x7f, 0x2d,
- 0xef, 0x06, 0x36, 0xa7, 0x05, 0x1b, 0x45, 0x27, 0x9f, 0x72, 0xcf, 0x9f,
- 0xac, 0x4b, 0x7f, 0x18, 0xce, 0x95, 0xed, 0x5b, 0xfc, 0xdc, 0x72, 0xcf,
- 0xc4, 0x32, 0x07, 0x52, 0xa6, 0x5b, 0xf4, 0xec, 0x3c, 0xde, 0xfb, 0x39,
- 0xe3, 0xf3, 0x43, 0xe9, 0x80, 0x55, 0x6b, 0x6e, 0xc6, 0x55, 0xed, 0x11,
- 0xab, 0xa0, 0xbc, 0xca, 0xf1, 0xff, 0x90, 0x41, 0xbb, 0x89, 0xfd, 0xfc,
- 0x63, 0xe5, 0x5f, 0xba, 0xce, 0xb6, 0xe4, 0xa2, 0xf5, 0xb9, 0x23, 0xcc,
- 0xe7, 0xa7, 0x2e, 0x5a, 0x9f, 0x13, 0xbc, 0x2f, 0x9f, 0x83, 0x90, 0xb9,
- 0xd2, 0x66, 0xd8, 0xb7, 0xac, 0x17, 0x09, 0x36, 0xca, 0x7c, 0x95, 0xd7,
- 0x8b, 0x7c, 0x58, 0x3e, 0x24, 0xb9, 0x92, 0xca, 0x3c, 0xa1, 0x05, 0xc9,
- 0xd0, 0xa3, 0x9c, 0x03, 0x77, 0x4d, 0x89, 0xf7, 0x06, 0xf8, 0x59, 0xd6,
- 0x7b, 0x34, 0xe2, 0x8f, 0x56, 0xca, 0x0b, 0xaa, 0x70, 0xeb, 0x50, 0x83,
- 0xbb, 0x1f, 0xb5, 0x22, 0x7e, 0x39, 0x62, 0xf5, 0x5f, 0x62, 0x99, 0x0b,
- 0x6b, 0x43, 0x57, 0x31, 0xdf, 0xa8, 0x71, 0xcf, 0x4a, 0x2c, 0xa3, 0xbe,
- 0x2f, 0x47, 0xdb, 0x48, 0x11, 0xcf, 0x6e, 0x1b, 0x29, 0xe2, 0x56, 0x5a,
- 0x6c, 0xce, 0x57, 0xb4, 0xb9, 0x2c, 0x6d, 0x2e, 0xa8, 0x77, 0x2a, 0xd9,
- 0xdc, 0x47, 0xc5, 0x13, 0x04, 0xeb, 0xcc, 0xf2, 0x99, 0x6a, 0x62, 0x5e,
- 0xfe, 0x48, 0xcd, 0x1f, 0x16, 0x7f, 0x2e, 0xd5, 0xd9, 0xb5, 0x7f, 0xa4,
- 0xce, 0xca, 0x31, 0xeb, 0x82, 0xce, 0x06, 0x2f, 0xd1, 0xd9, 0x02, 0xea,
- 0xa0, 0x41, 0x2f, 0xea, 0x6d, 0xb9, 0x71, 0x19, 0x52, 0xae, 0xde, 0xaa,
- 0x64, 0x6d, 0x8c, 0xf7, 0x04, 0xaf, 0xe7, 0xe0, 0xfb, 0xc1, 0x2f, 0xb9,
- 0xf7, 0x16, 0x51, 0x27, 0x45, 0x7d, 0x05, 0xa9, 0xaf, 0x0b, 0xb1, 0x00,
- 0xea, 0x07, 0xcc, 0xa7, 0x8a, 0xb1, 0x40, 0x74, 0xf7, 0xda, 0xa0, 0x86,
- 0xba, 0xeb, 0x2e, 0xc7, 0x2b, 0x7b, 0xab, 0xd0, 0x3e, 0xe2, 0xa3, 0x7f,
- 0x49, 0x7c, 0x28, 0xc6, 0xa4, 0xd6, 0x11, 0x77, 0x3f, 0x8a, 0xf8, 0xda,
- 0x10, 0xf8, 0xc3, 0x63, 0xb0, 0x8c, 0x47, 0xce, 0xe5, 0xc9, 0xb9, 0x39,
- 0x19, 0x97, 0x3e, 0xc3, 0x16, 0x1c, 0xe7, 0x19, 0xce, 0x77, 0xaa, 0x21,
- 0x92, 0x95, 0xf5, 0xa6, 0x2c, 0x39, 0x99, 0x27, 0x2d, 0x3a, 0x13, 0xbe,
- 0xad, 0xde, 0xe8, 0x81, 0xda, 0xe6, 0xc1, 0x66, 0x9c, 0x32, 0xf4, 0xfe,
- 0x7b, 0xf1, 0x27, 0xe8, 0x0d, 0x39, 0xd8, 0x6f, 0xac, 0x64, 0x3e, 0x51,
- 0x8d, 0xf5, 0x6d, 0x34, 0xcf, 0x3b, 0x3a, 0x88, 0x09, 0x56, 0x8f, 0x07,
- 0xb2, 0x9e, 0xbb, 0xf1, 0x2e, 0x3b, 0x1a, 0xe9, 0x7e, 0x50, 0x01, 0x56,
- 0x0c, 0xf8, 0xa1, 0x29, 0x2e, 0xdf, 0x89, 0x0d, 0xa9, 0xb2, 0xb6, 0xfc,
- 0x2f, 0x15, 0xc5, 0xb3, 0x10, 0x2a, 0xb4, 0x46, 0x69, 0x67, 0x25, 0xac,
- 0xc9, 0x0e, 0x17, 0x4f, 0x6a, 0x16, 0x2a, 0xb8, 0x75, 0x61, 0xc4, 0x4a,
- 0x29, 0x8e, 0xb3, 0x2a, 0xee, 0x75, 0x9f, 0xef, 0x98, 0x6c, 0x4d, 0xdd,
- 0xa9, 0xfe, 0x8b, 0x63, 0xb9, 0xeb, 0xd9, 0x91, 0x60, 0x52, 0x65, 0x9f,
- 0x3f, 0xf2, 0xac, 0xa2, 0x8c, 0x93, 0x5c, 0x9c, 0xbc, 0xfb, 0xc9, 0xd2,
- 0xfa, 0xaf, 0xcf, 0x5c, 0xff, 0x17, 0xfb, 0x75, 0xc9, 0xf7, 0xbe, 0xe4,
- 0x9e, 0xfb, 0xc8, 0x66, 0x64, 0xfd, 0xf0, 0xe1, 0x00, 0xaa, 0x57, 0xa2,
- 0x77, 0xf2, 0x3a, 0x4c, 0xb4, 0xfd, 0xab, 0x93, 0x2b, 0xf6, 0x5d, 0xcc,
- 0xd0, 0x3f, 0xcf, 0xcc, 0xdd, 0x75, 0x7d, 0x4b, 0x84, 0x1c, 0x5c, 0xce,
- 0x7a, 0x92, 0x0b, 0x2b, 0x45, 0x1e, 0x3e, 0x5f, 0xbf, 0x09, 0xcf, 0x5e,
- 0x24, 0x53, 0xd6, 0x12, 0xca, 0x32, 0x77, 0x51, 0x9e, 0xc8, 0x65, 0x3c,
- 0xd0, 0xff, 0xcd, 0x19, 0x09, 0xcd, 0x2c, 0x17, 0xab, 0x2a, 0xc6, 0x2a,
- 0x29, 0x57, 0x6e, 0xb7, 0x82, 0xf5, 0xde, 0x77, 0x46, 0x2f, 0x2a, 0xf7,
- 0xd3, 0x52, 0xb9, 0x67, 0x02, 0x72, 0x66, 0x24, 0x9b, 0x11, 0xce, 0x7a,
- 0xca, 0x19, 0xbb, 0xa8, 0x4c, 0x4b, 0xf5, 0xc5, 0x65, 0x9a, 0x89, 0xd1,
- 0xff, 0xaf, 0x33, 0x7e, 0x51, 0x99, 0xe4, 0x25, 0x65, 0x16, 0x10, 0x13,
- 0xbf, 0xef, 0xec, 0xbb, 0xa8, 0x4c, 0xed, 0x25, 0x65, 0x16, 0xd3, 0x1e,
- 0x9f, 0x71, 0x0e, 0x5c, 0x54, 0x66, 0xcc, 0x7f, 0x71, 0x19, 0xd9, 0xe3,
- 0x58, 0xff, 0x17, 0x5b, 0xf4, 0x75, 0x25, 0x9f, 0xbb, 0x70, 0xbf, 0x58,
- 0xfe, 0xf1, 0x4b, 0xfa, 0x1f, 0xb1, 0x64, 0xbe, 0x7d, 0xed, 0xe5, 0xf9,
- 0x7e, 0xb8, 0x74, 0xff, 0x7b, 0x35, 0x17, 0x97, 0xbb, 0x22, 0x70, 0x69,
- 0x3b, 0x45, 0x79, 0x47, 0x2f, 0x69, 0xff, 0xe6, 0xca, 0x8b, 0xbf, 0xbf,
- 0x5d, 0x51, 0xfc, 0x5e, 0xd6, 0xe9, 0xa1, 0x4b, 0x9e, 0xff, 0x7d, 0xc5,
- 0xc5, 0xdf, 0x37, 0x54, 0x7e, 0x78, 0x3b, 0xb5, 0x97, 0xb4, 0xa3, 0xf4,
- 0xca, 0xbb, 0x38, 0x1e, 0x53, 0xad, 0xed, 0xed, 0x58, 0x7f, 0x43, 0x2a,
- 0xbf, 0x89, 0xf6, 0x29, 0xb6, 0xf5, 0xe0, 0x0d, 0x6b, 0xf3, 0x6f, 0xcd,
- 0xe0, 0xb1, 0xcb, 0xc2, 0x41, 0x7c, 0x1c, 0x6b, 0xdd, 0xbd, 0x34, 0x95,
- 0x38, 0x69, 0xb9, 0xb6, 0x40, 0x8e, 0xe9, 0x57, 0xcc, 0x14, 0x0c, 0xf7,
- 0xbc, 0xe5, 0x3a, 0x34, 0xe7, 0xdd, 0x3d, 0xbb, 0x58, 0x0a, 0xcf, 0xaa,
- 0x5d, 0xba, 0x55, 0x3a, 0x47, 0x67, 0x5d, 0x1f, 0x44, 0x72, 0x66, 0x7e,
- 0xaa, 0x8d, 0x23, 0x12, 0xde, 0x86, 0x75, 0xee, 0x59, 0x6b, 0xc5, 0xec,
- 0x29, 0x9d, 0xd7, 0x5c, 0x03, 0x3d, 0x5f, 0xe6, 0x4d, 0xb2, 0x9e, 0x2b,
- 0xe7, 0x19, 0x1c, 0xfa, 0xa0, 0xc4, 0xf9, 0x83, 0x8a, 0x3a, 0xe0, 0xae,
- 0x99, 0xae, 0xf6, 0x20, 0x9a, 0xe8, 0x54, 0x90, 0xaa, 0x32, 0xa3, 0xda,
- 0xdb, 0x25, 0x4c, 0xf3, 0x4d, 0x6c, 0x51, 0x2a, 0x26, 0xfa, 0x15, 0xef,
- 0x44, 0x11, 0xd3, 0x3c, 0x13, 0xb2, 0xb6, 0xd0, 0xc0, 0x32, 0x41, 0xb4,
- 0x2c, 0xf1, 0xe2, 0x3b, 0x76, 0xad, 0xfb, 0x1e, 0xc7, 0xd6, 0x25, 0x15,
- 0x78, 0x20, 0xae, 0xa0, 0xeb, 0xaa, 0xc3, 0x78, 0x2b, 0x2f, 0xeb, 0x6c,
- 0x56, 0x7c, 0x94, 0x6d, 0x1e, 0xb2, 0x65, 0xbd, 0x74, 0x4b, 0x7c, 0xc4,
- 0x6d, 0xff, 0xf3, 0xe8, 0x73, 0xf7, 0xad, 0xba, 0x9d, 0xed, 0x99, 0x1e,
- 0x67, 0x1b, 0x73, 0x8d, 0x82, 0xdd, 0x90, 0xaa, 0x63, 0xfd, 0xb7, 0x96,
- 0xac, 0xc7, 0x69, 0x96, 0x99, 0xb0, 0x1f, 0xc4, 0xfb, 0xf9, 0x20, 0xf2,
- 0xf6, 0x4a, 0x7c, 0x37, 0x1f, 0x60, 0xce, 0xd7, 0x85, 0xef, 0xe4, 0x57,
- 0xe3, 0xc5, 0x61, 0xf7, 0x7d, 0x29, 0x2c, 0xb3, 0x15, 0xac, 0x88, 0xae,
- 0xc6, 0xb1, 0xd1, 0xd5, 0x38, 0x3c, 0x2c, 0xef, 0x0e, 0xcc, 0x25, 0x8f,
- 0x2c, 0xda, 0x9b, 0x4a, 0x8c, 0x59, 0x66, 0xaf, 0xc2, 0xa1, 0xd1, 0x30,
- 0x73, 0x29, 0x03, 0x27, 0xf3, 0x21, 0x8c, 0xd8, 0x6d, 0x38, 0x91, 0x0f,
- 0xe3, 0xeb, 0x76, 0x02, 0x67, 0xf9, 0xfd, 0xa0, 0x2d, 0x9c, 0xa5, 0x03,
- 0xd3, 0xf9, 0x6f, 0x32, 0xcf, 0x99, 0x87, 0x23, 0xdd, 0xcf, 0x30, 0x1c,
- 0x1d, 0xe4, 0xd5, 0x85, 0x13, 0xa3, 0x5d, 0x38, 0x35, 0x7c, 0x2b, 0x4e,
- 0x8d, 0xfe, 0x18, 0x6f, 0x0d, 0x4b, 0x7f, 0xe5, 0xfc, 0xb7, 0xc8, 0xd5,
- 0x29, 0x77, 0x35, 0xa6, 0x46, 0xff, 0x18, 0xd9, 0xef, 0x3a, 0x47, 0x56,
- 0x8b, 0xdc, 0x67, 0x7e, 0x87, 0x6c, 0xd1, 0xa5, 0x60, 0xbf, 0x1f, 0xc7,
- 0x6c, 0x3f, 0x8e, 0xda, 0x53, 0x57, 0x56, 0x61, 0xea, 0x7a, 0x22, 0x1d,
- 0xb6, 0xe7, 0x2b, 0xf1, 0x5c, 0x56, 0xd6, 0xd8, 0x3e, 0x86, 0x64, 0x70,
- 0x23, 0xb6, 0x4e, 0x56, 0xe2, 0x3b, 0x59, 0x3f, 0x75, 0x7c, 0x3d, 0x92,
- 0xf5, 0xab, 0xa9, 0xbf, 0x00, 0x5e, 0xb2, 0x43, 0x78, 0xd9, 0x6e, 0x4d,
- 0x15, 0x94, 0x76, 0x58, 0x2e, 0xfe, 0x07, 0xa8, 0xef, 0x0d, 0x6e, 0x9f,
- 0xbe, 0x63, 0x77, 0x3b, 0x5b, 0xa9, 0xe3, 0xfe, 0xcc, 0xe7, 0xdd, 0xb3,
- 0xdb, 0x2f, 0xda, 0xd3, 0x8e, 0xbc, 0x93, 0xf1, 0x14, 0x75, 0x7a, 0xcc,
- 0x4e, 0x91, 0xdb, 0x35, 0x71, 0x8e, 0xa6, 0x30, 0x4a, 0xbb, 0x3c, 0x99,
- 0xd5, 0x8f, 0xae, 0xc5, 0x26, 0x9c, 0xcd, 0x55, 0xe2, 0x35, 0xb6, 0x51,
- 0xb7, 0xd8, 0x8b, 0xe3, 0xae, 0xbc, 0x4d, 0x78, 0x3f, 0xab, 0x30, 0xde,
- 0x6e, 0xc2, 0x7b, 0x7c, 0xf6, 0x0a, 0x3f, 0x9f, 0x8e, 0xb3, 0x87, 0xa5,
- 0x67, 0xa7, 0xc8, 0xcf, 0x65, 0xcd, 0xa8, 0xb7, 0x63, 0x13, 0x4e, 0xe4,
- 0xde, 0x23, 0xa7, 0x75, 0xf0, 0x45, 0x63, 0x36, 0x12, 0xb3, 0xc9, 0x9b,
- 0xf4, 0x4a, 0x1c, 0xe3, 0xf3, 0x85, 0xc4, 0xdf, 0xe2, 0xfa, 0xd9, 0x26,
- 0xbc, 0xcb, 0xf1, 0x3c, 0x40, 0x59, 0xef, 0xe4, 0xfe, 0x96, 0x72, 0x97,
- 0x22, 0x1f, 0xff, 0x5b, 0xca, 0xfd, 0x31, 0xc6, 0x4b, 0xfa, 0x38, 0x61,
- 0xc8, 0xb8, 0xbe, 0x31, 0x0b, 0xd5, 0x21, 0x8e, 0xe3, 0x9b, 0xfc, 0xbf,
- 0x01, 0xc7, 0xf3, 0xff, 0x9b, 0xff, 0xbf, 0x8b, 0x03, 0x79, 0x59, 0xaf,
- 0x9e, 0x19, 0x4b, 0xc5, 0x7f, 0xca, 0x1c, 0x64, 0x0e, 0x32, 0x83, 0xb5,
- 0xa9, 0xd9, 0xb4, 0xa3, 0xbf, 0xbe, 0xb6, 0x0e, 0xef, 0xc6, 0x2d, 0xec,
- 0xd8, 0xe7, 0x45, 0x86, 0xb8, 0xbb, 0x63, 0xa0, 0x01, 0x4f, 0xec, 0x0c,
- 0xe2, 0xf1, 0x9d, 0x97, 0x61, 0xcb, 0xce, 0x2b, 0xb0, 0x67, 0x67, 0x13,
- 0xd2, 0x3b, 0x1d, 0xe7, 0xfd, 0xc5, 0x8e, 0xb3, 0x88, 0xd7, 0x23, 0xf4,
- 0x05, 0x3f, 0xff, 0xbf, 0x10, 0x17, 0x3f, 0xd1, 0x71, 0x95, 0xeb, 0x2f,
- 0x9d, 0xb8, 0xd2, 0xfd, 0x9f, 0xc4, 0xa2, 0xfc, 0xc6, 0xf8, 0xfa, 0xc2,
- 0xa6, 0xf8, 0x7d, 0x85, 0x39, 0xd8, 0x3a, 0xd8, 0x88, 0xc1, 0x9d, 0x0d,
- 0xa9, 0x06, 0xb6, 0xb3, 0xea, 0x5a, 0xe1, 0x76, 0x8e, 0x63, 0xb4, 0xf7,
- 0xc7, 0xd7, 0x16, 0x9e, 0x41, 0x77, 0x21, 0x84, 0xbe, 0xc1, 0x30, 0xdb,
- 0x92, 0xbd, 0x5c, 0xef, 0xd1, 0x7b, 0xe1, 0x38, 0xd3, 0x8b, 0x0f, 0xe2,
- 0xae, 0xc2, 0x37, 0xc9, 0x1b, 0x43, 0x48, 0x0f, 0xae, 0x47, 0x66, 0xb2,
- 0x22, 0xe5, 0x37, 0x1d, 0xbc, 0x14, 0x9f, 0xc2, 0xed, 0x94, 0xf7, 0xe8,
- 0x60, 0x2d, 0xfb, 0x54, 0x9d, 0xaa, 0x34, 0x25, 0x86, 0x3f, 0xc8, 0x18,
- 0x25, 0xfc, 0xe2, 0x28, 0x56, 0x30, 0xbf, 0xaa, 0x5f, 0xa2, 0xcf, 0x42,
- 0x6d, 0xd0, 0x7b, 0xa6, 0x43, 0xec, 0x2f, 0x45, 0xfb, 0x93, 0x7d, 0xf5,
- 0x75, 0xb8, 0xdb, 0x3d, 0xe7, 0xdd, 0x83, 0xe7, 0x6d, 0xc1, 0x9d, 0x35,
- 0xd8, 0x6f, 0xaf, 0x63, 0xce, 0x25, 0xf1, 0x7a, 0x25, 0x9a, 0x0b, 0x7f,
- 0x17, 0xbf, 0xa7, 0xb0, 0x9a, 0x7c, 0xf6, 0x5f, 0x70, 0x53, 0x21, 0xc7,
- 0x7e, 0x8d, 0xc6, 0xef, 0x2e, 0xec, 0x89, 0xdf, 0x5b, 0xe8, 0xc2, 0x02,
- 0x37, 0xa7, 0x64, 0xfe, 0x55, 0x90, 0x38, 0x77, 0x9c, 0x5c, 0xf8, 0x14,
- 0x96, 0x17, 0x5e, 0xc3, 0xcd, 0x05, 0xc1, 0x0d, 0x89, 0x7f, 0x2f, 0x7a,
- 0x51, 0x2d, 0x71, 0xef, 0x0b, 0xd8, 0xba, 0x3b, 0x85, 0xbe, 0xdd, 0x65,
- 0x8c, 0x6a, 0x0d, 0xee, 0x13, 0x7c, 0x99, 0xf4, 0x95, 0x62, 0xd4, 0xa7,
- 0x68, 0x8f, 0x2a, 0x63, 0xa3, 0xac, 0xd3, 0xaf, 0xa3, 0x2f, 0x6f, 0x24,
- 0x66, 0xca, 0x7a, 0xfc, 0x27, 0x4b, 0xf7, 0x25, 0xd6, 0xcb, 0x5a, 0xbc,
- 0x86, 0x43, 0x79, 0x77, 0x4f, 0x5b, 0xf3, 0xeb, 0xb7, 0xf3, 0x99, 0xd4,
- 0xff, 0x02, 0xd2, 0xbb, 0x57, 0x3b, 0x8f, 0x66, 0x8a, 0xfb, 0x66, 0x47,
- 0xa2, 0x6c, 0x6b, 0x9c, 0xb1, 0x7d, 0x2f, 0xfc, 0xb3, 0x38, 0xb6, 0x89,
- 0x01, 0x58, 0x1e, 0xbd, 0xdb, 0xd9, 0x92, 0xc1, 0xbd, 0xb3, 0x10, 0xc6,
- 0xca, 0x89, 0x0a, 0x24, 0xf7, 0x57, 0xe3, 0xb6, 0x9d, 0x3d, 0xb4, 0x65,
- 0x8b, 0xf6, 0xab, 0x1b, 0x77, 0x2b, 0xd5, 0xb8, 0x99, 0xf7, 0x3e, 0x3d,
- 0x28, 0x6b, 0x58, 0xd1, 0xa3, 0x27, 0x3c, 0xd5, 0xb8, 0x6b, 0xaf, 0x1f,
- 0xb9, 0xdc, 0x4a, 0x24, 0xf7, 0x1e, 0x81, 0x95, 0xa3, 0x4d, 0xee, 0x22,
- 0xce, 0x30, 0xcd, 0x51, 0xcd, 0x1f, 0x63, 0xcf, 0xa8, 0x8a, 0xba, 0x5d,
- 0xb2, 0xfe, 0xa8, 0xe8, 0xa7, 0xa3, 0x05, 0xa4, 0x47, 0xbd, 0x98, 0x95,
- 0xee, 0xc4, 0x04, 0xb1, 0x26, 0x90, 0x4e, 0x22, 0x9f, 0xef, 0x46, 0x8e,
- 0x58, 0x92, 0x1b, 0x0d, 0xa0, 0x26, 0x6d, 0x20, 0xa0, 0xc7, 0xb0, 0x83,
- 0xfe, 0x52, 0x91, 0xd6, 0xb1, 0x2d, 0x7f, 0x23, 0xac, 0xd1, 0x4f, 0x60,
- 0xfb, 0x68, 0x37, 0x2f, 0x13, 0x7d, 0xa3, 0x9f, 0xc7, 0xb2, 0x89, 0xa3,
- 0xe8, 0xcf, 0xa7, 0x68, 0x8f, 0xef, 0x61, 0x7b, 0xee, 0x30, 0x9e, 0xc8,
- 0x6e, 0xc6, 0xd9, 0xc5, 0x87, 0xf1, 0x38, 0x3f, 0x67, 0xb3, 0xfa, 0xc6,
- 0xb0, 0x7a, 0x18, 0x99, 0xdc, 0x26, 0x7c, 0x62, 0x50, 0xc1, 0x4b, 0xb4,
- 0xf5, 0xdb, 0xf7, 0xd2, 0x16, 0x1f, 0xdb, 0x80, 0xae, 0x89, 0xef, 0xc2,
- 0xce, 0x3f, 0x8f, 0x1d, 0xb9, 0x07, 0xd1, 0x9f, 0x59, 0xcf, 0xfc, 0xff,
- 0x19, 0xca, 0x39, 0x48, 0x3f, 0xdf, 0xc8, 0x31, 0x3e, 0xcc, 0xeb, 0xc2,
- 0x1a, 0xe3, 0x85, 0x35, 0x39, 0xfa, 0x7d, 0x46, 0x72, 0xcf, 0x75, 0xc4,
- 0x89, 0x27, 0x6b, 0x65, 0x5d, 0xb2, 0x4a, 0x9f, 0xb9, 0x56, 0x2f, 0xb6,
- 0x1f, 0x76, 0x73, 0xed, 0xaa, 0xb4, 0xe4, 0x75, 0x53, 0x91, 0x2a, 0x72,
- 0x0c, 0x7f, 0x5a, 0x74, 0xd8, 0xe3, 0xf4, 0x66, 0x04, 0x4b, 0x64, 0x3e,
- 0x34, 0xbc, 0x90, 0xff, 0x31, 0xb6, 0x0e, 0xcf, 0xc6, 0xf2, 0x6c, 0x1b,
- 0x39, 0xa5, 0xe3, 0x7c, 0x85, 0xbe, 0x66, 0x93, 0xeb, 0xec, 0x18, 0x4c,
- 0x12, 0x53, 0x66, 0x23, 0x39, 0xa7, 0xc8, 0x4f, 0xc2, 0x69, 0x69, 0xcb,
- 0x57, 0xda, 0xab, 0x9b, 0xba, 0x32, 0xcc, 0x7b, 0x75, 0x69, 0x99, 0xb7,
- 0x88, 0xa1, 0xb9, 0xfb, 0x69, 0x8e, 0xf3, 0x52, 0xb4, 0xcc, 0x95, 0xa6,
- 0xae, 0xac, 0xc3, 0x6c, 0x59, 0x77, 0x4d, 0xc8, 0x39, 0xdf, 0x6f, 0xb5,
- 0x2c, 0xa7, 0xaf, 0x7e, 0x01, 0x03, 0xe3, 0xe5, 0x77, 0x23, 0xff, 0xb3,
- 0xe4, 0xdd, 0xf5, 0x9f, 0x2c, 0xaf, 0xbc, 0x07, 0x2a, 0xe7, 0x8c, 0xcb,
- 0xef, 0x50, 0x8a, 0x2e, 0xaf, 0x90, 0xfd, 0x03, 0xab, 0xb8, 0x4f, 0x0a,
- 0x1c, 0xb1, 0x2b, 0x18, 0x87, 0xd5, 0xa5, 0x64, 0x63, 0x21, 0x1f, 0x2a,
- 0x19, 0x2f, 0x1b, 0xd1, 0x47, 0xbe, 0x7a, 0x93, 0x51, 0x81, 0x03, 0x6d,
- 0x49, 0x39, 0xcf, 0xd7, 0xe3, 0x73, 0x79, 0xea, 0xa6, 0x3f, 0xff, 0x6d,
- 0x9e, 0xba, 0x09, 0xe9, 0x8c, 0x9c, 0x63, 0xeb, 0xc6, 0x4b, 0xf5, 0xf2,
- 0x5e, 0xe7, 0x26, 0xf7, 0x9c, 0x70, 0xd5, 0x42, 0x62, 0x46, 0x5c, 0xc3,
- 0x51, 0xbd, 0x55, 0x6b, 0x50, 0x23, 0x06, 0x94, 0xd7, 0x1d, 0x2b, 0x94,
- 0x44, 0xff, 0xa4, 0x9c, 0xd5, 0xfb, 0xa8, 0x3d, 0x84, 0xb5, 0xd8, 0xfe,
- 0x58, 0x07, 0x8e, 0xaf, 0x96, 0xb5, 0xbc, 0x9f, 0x95, 0xde, 0xdb, 0x93,
- 0x3e, 0x46, 0xea, 0xe4, 0x0c, 0xaa, 0xc8, 0xde, 0x9e, 0x51, 0x19, 0x7b,
- 0xe2, 0x78, 0x3d, 0xe8, 0x8e, 0x37, 0x56, 0x3e, 0x97, 0x59, 0xa9, 0x2f,
- 0x2f, 0x95, 0x5f, 0x50, 0x27, 0xbc, 0x64, 0x5b, 0x66, 0x13, 0xb9, 0xb6,
- 0xf4, 0xe7, 0xd7, 0xce, 0xda, 0x50, 0x03, 0xcb, 0x8e, 0x95, 0x9e, 0x8b,
- 0xad, 0x45, 0x8c, 0x24, 0xe4, 0x9e, 0xd4, 0x11, 0x9d, 0xcd, 0xac, 0xe3,
- 0x41, 0xbd, 0x7e, 0x25, 0x1e, 0xa2, 0x8f, 0xcf, 0xd7, 0x5f, 0x76, 0x36,
- 0xcb, 0x39, 0xcd, 0x85, 0xc1, 0x19, 0x6d, 0x2d, 0x75, 0xfb, 0x52, 0xc9,
- 0xbe, 0x0c, 0x66, 0xe4, 0xbd, 0x81, 0xb3, 0xce, 0xc2, 0x46, 0x79, 0x7e,
- 0x5b, 0x6d, 0x51, 0x7e, 0xb3, 0x7b, 0x0e, 0x7b, 0x4f, 0xa6, 0xdc, 0x6f,
- 0x39, 0xe3, 0x1e, 0x2a, 0xb7, 0x15, 0xbb, 0x30, 0x1e, 0xe9, 0xdb, 0xd7,
- 0x6a, 0x2f, 0xee, 0xf3, 0x9d, 0xb3, 0xca, 0xef, 0x17, 0xcc, 0x73, 0xeb,
- 0x94, 0xdb, 0x94, 0x3e, 0x6e, 0xc2, 0xe3, 0x93, 0x97, 0x8e, 0xf1, 0xee,
- 0x19, 0x63, 0x92, 0x3a, 0x32, 0xae, 0x60, 0xc9, 0x0e, 0x36, 0xb2, 0x8c,
- 0xd4, 0x91, 0x75, 0x82, 0xa0, 0x9b, 0x3f, 0xd4, 0xed, 0x16, 0x79, 0x22,
- 0xc3, 0x71, 0xde, 0x70, 0x63, 0xf2, 0x02, 0xb7, 0xcc, 0xe0, 0xe4, 0x6a,
- 0xfa, 0x91, 0xb3, 0x99, 0xf8, 0xec, 0xbc, 0xd1, 0x11, 0xc6, 0x56, 0x5b,
- 0x74, 0xad, 0x87, 0xc7, 0x88, 0x4d, 0x7d, 0x2e, 0x9f, 0xf1, 0xa1, 0x37,
- 0x57, 0x3e, 0xeb, 0x52, 0x29, 0x7b, 0x21, 0x61, 0xd1, 0x79, 0xaf, 0x41,
- 0x1e, 0x17, 0x5c, 0xa6, 0x79, 0xc9, 0xc5, 0xee, 0xc1, 0x7f, 0xc8, 0xfc,
- 0xc6, 0x7c, 0xa5, 0x75, 0x93, 0x14, 0xed, 0xa8, 0x18, 0x0f, 0x41, 0xfe,
- 0x40, 0x1e, 0x56, 0x3a, 0x43, 0xdf, 0x9b, 0xff, 0x0f, 0x67, 0xca, 0x3d,
- 0x43, 0x7f, 0xe1, 0x2c, 0x4a, 0x2e, 0xe8, 0x38, 0xfb, 0xf8, 0xec, 0xc2,
- 0x79, 0x7a, 0x72, 0x06, 0x5d, 0xce, 0xdd, 0xff, 0x3b, 0xe7, 0x6e, 0x66,
- 0xd9, 0xa9, 0xfa, 0xe2, 0xfb, 0x25, 0x49, 0x75, 0x99, 0x5e, 0xc6, 0x6d,
- 0xd9, 0x27, 0x12, 0xdc, 0x3e, 0x58, 0x57, 0x5c, 0x3f, 0x8e, 0x74, 0x75,
- 0x43, 0xf6, 0xe4, 0xcb, 0x38, 0xa3, 0x1b, 0x8b, 0x94, 0xcd, 0x68, 0x89,
- 0x57, 0xcb, 0xf9, 0xba, 0x88, 0xd7, 0x8c, 0x04, 0xdf, 0x42, 0x34, 0x76,
- 0xd8, 0x3d, 0x43, 0x22, 0xd8, 0xa3, 0xe3, 0x9e, 0xbc, 0x4e, 0x9b, 0x95,
- 0xf7, 0xd2, 0xe5, 0x73, 0xf1, 0xdd, 0xc7, 0x64, 0x5e, 0xb0, 0xba, 0x87,
- 0x58, 0x6d, 0xfd, 0xa5, 0xcf, 0x95, 0x17, 0xe9, 0x19, 0x55, 0x22, 0x5d,
- 0x0f, 0x2a, 0x65, 0x79, 0x81, 0x0f, 0x91, 0x17, 0x63, 0x7d, 0xad, 0xf4,
- 0x2e, 0xb8, 0x4e, 0x19, 0x97, 0x9e, 0x0d, 0x9a, 0x93, 0x92, 0x3c, 0xfa,
- 0x40, 0x89, 0x73, 0x1e, 0xfe, 0xad, 0x3c, 0xfa, 0x43, 0xdb, 0x4c, 0xb2,
- 0xcd, 0xae, 0x6a, 0x25, 0x19, 0x97, 0xf7, 0x80, 0x2a, 0xe3, 0xd1, 0xd8,
- 0x0b, 0x74, 0x72, 0xaf, 0x19, 0x0d, 0x8f, 0xba, 0x67, 0x5d, 0x0c, 0xff,
- 0xf2, 0x7c, 0xd1, 0x7f, 0xac, 0xc9, 0xdf, 0xad, 0x93, 0x1a, 0x5d, 0xef,
- 0x6e, 0x55, 0x92, 0xd7, 0x57, 0x53, 0x4e, 0x2c, 0x0e, 0xad, 0xc2, 0x2c,
- 0xeb, 0x28, 0x1a, 0x7b, 0x8b, 0xf3, 0x79, 0xa8, 0x23, 0x1a, 0x1e, 0x71,
- 0x73, 0x74, 0xd1, 0x8b, 0xe1, 0x2f, 0xce, 0xbd, 0x2e, 0x7c, 0xde, 0xf2,
- 0x31, 0x36, 0x8f, 0xdb, 0x7e, 0x8e, 0xa5, 0x35, 0xb8, 0x1d, 0xf5, 0xb4,
- 0x71, 0x24, 0xfb, 0xda, 0x18, 0x1f, 0x6c, 0x24, 0x3d, 0x57, 0xd5, 0x21,
- 0x45, 0x82, 0xee, 0xd1, 0x53, 0xe4, 0x5c, 0xad, 0xb1, 0x47, 0x68, 0xbf,
- 0xb9, 0x50, 0x24, 0x6c, 0x21, 0x85, 0xe7, 0xec, 0x65, 0x7f, 0xee, 0x81,
- 0x65, 0xd4, 0x70, 0xa2, 0xab, 0xcd, 0xa9, 0x3f, 0xbf, 0x35, 0x1a, 0xd1,
- 0x5e, 0x2c, 0x9d, 0xd5, 0xe9, 0xb5, 0x7f, 0xe1, 0xee, 0x51, 0x79, 0xf4,
- 0xdf, 0x55, 0x46, 0xda, 0xf6, 0x63, 0x2c, 0x9b, 0xc5, 0x96, 0xc7, 0xd8,
- 0x47, 0xdd, 0xc1, 0x32, 0x63, 0x33, 0x96, 0x1b, 0x01, 0xac, 0x0b, 0xb6,
- 0x24, 0xe4, 0x2c, 0xd2, 0x48, 0xae, 0xb8, 0x36, 0x52, 0x5c, 0x0b, 0xef,
- 0xc7, 0xa3, 0x19, 0x37, 0x3e, 0x07, 0xfd, 0x66, 0x52, 0x79, 0x34, 0xdf,
- 0xa9, 0x3c, 0x52, 0x5a, 0x8f, 0xeb, 0xcf, 0xdf, 0x10, 0x44, 0xb5, 0x85,
- 0x13, 0x86, 0xbc, 0x47, 0x29, 0x72, 0x2d, 0x8c, 0x76, 0xfc, 0x21, 0xef,
- 0x53, 0x8a, 0x4e, 0x37, 0xa2, 0x6f, 0xf8, 0x61, 0xf4, 0x0e, 0xbf, 0xe4,
- 0x9e, 0x65, 0xf5, 0xe9, 0x7e, 0xeb, 0x0a, 0x33, 0x72, 0xd0, 0xc2, 0xbc,
- 0x7a, 0x59, 0x13, 0x6e, 0x34, 0x8f, 0xe2, 0xd1, 0xa0, 0xbc, 0x27, 0xd8,
- 0x4f, 0x9e, 0x22, 0xef, 0x9c, 0xad, 0xc1, 0x67, 0x06, 0x64, 0x0e, 0x6b,
- 0xad, 0x4a, 0x33, 0x92, 0x5c, 0xe7, 0xce, 0x61, 0x1b, 0x8e, 0x15, 0x1e,
- 0xc6, 0x1b, 0xbb, 0x36, 0x43, 0x8d, 0x47, 0xc2, 0xb7, 0xc0, 0xd9, 0x7c,
- 0xc4, 0x48, 0x5a, 0x3e, 0x44, 0x0e, 0x78, 0x54, 0xe0, 0xd9, 0x5d, 0x92,
- 0x4f, 0xf7, 0xe0, 0x7a, 0x72, 0x80, 0x3a, 0xdd, 0x59, 0xfa, 0xab, 0xc5,
- 0x91, 0x7e, 0xdd, 0x63, 0xfd, 0xd3, 0x1c, 0x44, 0xb2, 0x09, 0x55, 0xef,
- 0xf9, 0xa4, 0x0a, 0x25, 0x60, 0xca, 0x6f, 0x00, 0x6c, 0xc6, 0x27, 0xda,
- 0x03, 0xd6, 0x2c, 0x33, 0x92, 0x7d, 0x49, 0x89, 0xc4, 0x2c, 0xf5, 0x1b,
- 0x9c, 0xe7, 0x18, 0x5e, 0x24, 0xc7, 0xe9, 0x62, 0x6c, 0x5f, 0x21, 0x31,
- 0xdd, 0xc5, 0xbe, 0xe6, 0x44, 0x95, 0x12, 0xc4, 0x2d, 0x05, 0xe0, 0x50,
- 0x6e, 0x0d, 0x4e, 0xee, 0x32, 0xd0, 0xc9, 0x67, 0x83, 0x19, 0x02, 0x16,
- 0x31, 0x60, 0x83, 0x61, 0xb5, 0xaa, 0xe4, 0x16, 0x3e, 0x15, 0xcb, 0xe6,
- 0x9b, 0xd1, 0xa9, 0xa5, 0x1e, 0x2f, 0x12, 0x05, 0x2f, 0xee, 0x60, 0x99,
- 0xed, 0x8c, 0x0b, 0x9f, 0x4c, 0xfb, 0xc9, 0x6f, 0x9b, 0xf0, 0x33, 0xf2,
- 0xec, 0x9f, 0x92, 0x4f, 0x1f, 0x27, 0x5f, 0x38, 0x9e, 0xaf, 0x46, 0xf7,
- 0x90, 0x4f, 0xce, 0x1f, 0x4d, 0xf9, 0x38, 0x17, 0xb5, 0xed, 0x21, 0x9c,
- 0x1e, 0xf5, 0xe3, 0xf6, 0x5d, 0x91, 0x3d, 0xc7, 0xd5, 0x46, 0xbc, 0x3f,
- 0x5a, 0x8d, 0x95, 0x43, 0x7e, 0xf6, 0xcd, 0xc1, 0x0e, 0xe2, 0xff, 0xbb,
- 0x7c, 0xd6, 0xb9, 0x0b, 0x4a, 0x7e, 0xc9, 0x02, 0xe6, 0x04, 0x3a, 0xeb,
- 0xd7, 0xe0, 0xd6, 0x21, 0xe1, 0x81, 0x2a, 0xde, 0x1e, 0x55, 0xf0, 0x56,
- 0xce, 0xc0, 0x32, 0xb6, 0xd7, 0x97, 0x79, 0xd6, 0xf1, 0xd3, 0xcf, 0xd7,
- 0xe6, 0x0d, 0xdc, 0x9b, 0xd3, 0x19, 0x53, 0x7e, 0xe2, 0x78, 0xf4, 0x76,
- 0xfc, 0x64, 0xa7, 0x7e, 0xf4, 0x75, 0x4f, 0x74, 0x6a, 0x89, 0xa7, 0x1d,
- 0xaf, 0xed, 0x6f, 0xc7, 0xf7, 0x06, 0x97, 0xe2, 0x9a, 0xf6, 0x24, 0xce,
- 0x2c, 0x69, 0xc7, 0xab, 0x7b, 0x75, 0x3c, 0x92, 0xe9, 0x80, 0x36, 0x31,
- 0x45, 0xfe, 0x9b, 0x40, 0xeb, 0x84, 0x09, 0x7d, 0xd0, 0xd9, 0x5c, 0x63,
- 0x6e, 0xc6, 0xa3, 0x86, 0x89, 0x45, 0x7b, 0x45, 0x0f, 0x8e, 0xb3, 0x6e,
- 0x89, 0x89, 0x17, 0xb2, 0x3a, 0xfd, 0xd4, 0xa4, 0x1e, 0x74, 0x3c, 0x9e,
- 0x31, 0x11, 0x7d, 0x4c, 0x9f, 0xde, 0xc7, 0xef, 0x4b, 0xf7, 0x75, 0xa0,
- 0x87, 0xed, 0xdb, 0xc4, 0xeb, 0x3d, 0x13, 0x6d, 0x1c, 0xb3, 0xc1, 0xf1,
- 0x37, 0x5b, 0x3f, 0x53, 0x3a, 0x91, 0x9d, 0xe8, 0x22, 0x9f, 0xdd, 0x4c,
- 0x1e, 0xdb, 0xe5, 0xee, 0xb9, 0x6f, 0xcd, 0x18, 0xb8, 0x35, 0xdd, 0x85,
- 0x27, 0x6d, 0x39, 0x3b, 0xaf, 0x27, 0xae, 0x55, 0xe4, 0x1d, 0xdd, 0x2e,
- 0x8c, 0x51, 0x27, 0xcb, 0x86, 0x56, 0xba, 0xe7, 0x9d, 0x96, 0xef, 0xd2,
- 0xf1, 0x44, 0xe6, 0x13, 0x38, 0x39, 0x6e, 0xa0, 0x3b, 0x2d, 0xfa, 0x96,
- 0xf3, 0x9b, 0x29, 0x1c, 0x61, 0x6c, 0xf9, 0xd9, 0x50, 0xf2, 0x9f, 0x38,
- 0xcd, 0xc7, 0x54, 0xc8, 0x7a, 0x89, 0x8a, 0xab, 0xdb, 0xe5, 0x0c, 0xae,
- 0x87, 0xa8, 0x16, 0xb1, 0xea, 0x54, 0x4b, 0xe3, 0x7d, 0xcb, 0xab, 0x6e,
- 0xc2, 0x67, 0x87, 0xbc, 0xcc, 0x19, 0x54, 0xe6, 0x3a, 0xd6, 0x06, 0xda,
- 0x86, 0x55, 0xab, 0x16, 0xe7, 0xcd, 0xdd, 0x63, 0xd0, 0x3d, 0xd8, 0x61,
- 0x34, 0x77, 0xd7, 0xb0, 0xde, 0x8a, 0x78, 0x24, 0x59, 0xa5, 0x76, 0x30,
- 0x0f, 0x7d, 0x18, 0xeb, 0x76, 0x3d, 0x8c, 0xb5, 0xbc, 0x36, 0xec, 0x72,
- 0x36, 0xdf, 0x6c, 0x28, 0x78, 0x4e, 0x77, 0x36, 0x6f, 0x36, 0x74, 0xce,
- 0xad, 0xcc, 0xeb, 0xc3, 0xd8, 0x38, 0xf6, 0x30, 0x1e, 0xa2, 0x7d, 0x35,
- 0xd0, 0x8f, 0x57, 0xa5, 0x9d, 0xcd, 0xd7, 0xb4, 0xc7, 0xf0, 0x73, 0x37,
- 0xbf, 0x11, 0x7b, 0x3d, 0xe3, 0xe6, 0xdc, 0x39, 0xd5, 0xb5, 0xdd, 0xa0,
- 0x7c, 0xb6, 0xd4, 0x25, 0xc1, 0x72, 0x6c, 0xf9, 0x05, 0xe5, 0xfe, 0x72,
- 0x57, 0x1d, 0x1e, 0x6b, 0x90, 0xf8, 0xe1, 0xb7, 0xaa, 0x4c, 0x28, 0xfa,
- 0x12, 0xe6, 0x71, 0x8f, 0x1d, 0xc1, 0x76, 0xf2, 0xc2, 0x50, 0x5c, 0x72,
- 0xec, 0x56, 0x63, 0x8b, 0x7a, 0x23, 0xb1, 0x5d, 0xc1, 0xa3, 0x0b, 0xb3,
- 0x18, 0xa0, 0xaf, 0xee, 0x58, 0x18, 0x49, 0x0d, 0xc0, 0x74, 0x76, 0xcc,
- 0xe9, 0xff, 0x23, 0xde, 0xa1, 0x2d, 0xef, 0x4b, 0xca, 0x7b, 0xb4, 0x0f,
- 0x63, 0xf3, 0x2e, 0x99, 0xff, 0x87, 0xf1, 0x45, 0xf6, 0x7f, 0xe3, 0xd0,
- 0xc3, 0xf8, 0x1c, 0x6d, 0xa7, 0x7e, 0xf1, 0xa1, 0x2f, 0xd6, 0xa3, 0x25,
- 0x5b, 0x87, 0xa9, 0xfb, 0x1b, 0xe4, 0xbc, 0x2d, 0x31, 0x71, 0x40, 0x79,
- 0x18, 0xf7, 0x8c, 0xd4, 0xd2, 0x17, 0xdd, 0x31, 0x10, 0x8b, 0xcb, 0xf1,
- 0x2a, 0x8c, 0x75, 0xf9, 0xa6, 0x12, 0xae, 0x87, 0xb0, 0xd6, 0x3e, 0xe0,
- 0xfa, 0x7e, 0x85, 0xb9, 0x9a, 0x7e, 0xdf, 0x4d, 0xbf, 0x5f, 0x49, 0xbf,
- 0xef, 0xa2, 0xdf, 0x77, 0xd2, 0xef, 0x93, 0xf4, 0x7b, 0x93, 0x7e, 0x9f,
- 0xa0, 0xdf, 0x77, 0xd0, 0xef, 0x0d, 0xd9, 0x3b, 0x54, 0x8e, 0x76, 0x1c,
- 0x81, 0x6f, 0xd0, 0x4f, 0x1b, 0x2a, 0xbe, 0xd3, 0xb8, 0x9f, 0xf8, 0x73,
- 0xc2, 0x58, 0x14, 0xbe, 0x89, 0xaa, 0x1a, 0x25, 0x46, 0xe4, 0xc6, 0xff,
- 0xce, 0x7d, 0xff, 0x2d, 0x47, 0xdc, 0x7f, 0x91, 0xfa, 0x58, 0x11, 0x6f,
- 0x36, 0x9e, 0x64, 0x0c, 0xfb, 0xa1, 0xde, 0xda, 0x1f, 0x62, 0x99, 0xaf,
- 0x65, 0x5a, 0xb3, 0xb3, 0xa1, 0x5b, 0xed, 0xea, 0x56, 0x60, 0x55, 0x88,
- 0x63, 0x96, 0x73, 0xdd, 0xab, 0xf0, 0xc5, 0xe1, 0x6e, 0xfc, 0xcf, 0xe1,
- 0x20, 0x75, 0xd1, 0x3c, 0x75, 0xa3, 0x07, 0xdf, 0x0c, 0xc3, 0x13, 0x9a,
- 0x0b, 0x7c, 0xd0, 0x88, 0x45, 0x07, 0xe4, 0x5d, 0xec, 0x5c, 0xa3, 0xa7,
- 0x6d, 0x3e, 0xc4, 0x46, 0x40, 0xa4, 0xf6, 0x30, 0xd3, 0x5c, 0xe4, 0xbe,
- 0xaf, 0x99, 0x5c, 0x2d, 0x98, 0x5e, 0x85, 0xad, 0x31, 0x17, 0x67, 0x9f,
- 0x96, 0xf3, 0xe9, 0x8d, 0xc4, 0xa3, 0x80, 0xd9, 0x85, 0x6d, 0x03, 0xd6,
- 0x5d, 0x8d, 0x58, 0x89, 0xfe, 0x81, 0xa2, 0x0e, 0xee, 0x8f, 0x13, 0xf2,
- 0xcc, 0xa8, 0xb6, 0x48, 0x81, 0x77, 0x43, 0x47, 0x02, 0xf7, 0xe6, 0x6d,
- 0x64, 0x39, 0xc6, 0xf5, 0xf4, 0xb3, 0x75, 0xbf, 0xff, 0x3d, 0x7c, 0x7c,
- 0xce, 0xd6, 0x68, 0xff, 0xe7, 0x9c, 0x5c, 0xfd, 0xa2, 0x6c, 0x23, 0xf4,
- 0x8d, 0x77, 0xa8, 0xd7, 0x32, 0x67, 0x8e, 0x1c, 0xe4, 0x23, 0x6b, 0x8e,
- 0x7b, 0x8e, 0xce, 0x8f, 0x05, 0x43, 0x50, 0x46, 0xd3, 0xf2, 0xce, 0xda,
- 0x66, 0xfc, 0x5f, 0xc6, 0x37, 0x5c, 0x5b, 0x9a, 0xf2, 0xc8, 0x99, 0x16,
- 0xb9, 0xef, 0x2c, 0x3d, 0xbb, 0x38, 0x12, 0xd3, 0x3c, 0x3f, 0xa8, 0x93,
- 0xfd, 0x8b, 0xaf, 0x33, 0xce, 0x86, 0x87, 0x96, 0x42, 0x5d, 0xec, 0xc7,
- 0x9d, 0x6d, 0xb3, 0x90, 0x5a, 0x25, 0x3c, 0xd4, 0xdd, 0x5f, 0xa1, 0x3e,
- 0xff, 0x02, 0xf7, 0x19, 0x5f, 0xc1, 0xf1, 0x90, 0x8d, 0x21, 0xe2, 0xd7,
- 0x3a, 0xe3, 0x76, 0xc5, 0xe2, 0x67, 0xe6, 0x44, 0x58, 0x6f, 0x30, 0xd7,
- 0xfa, 0x54, 0x03, 0x1a, 0x76, 0x49, 0x79, 0x91, 0x7b, 0xc6, 0x95, 0xb7,
- 0x3f, 0x23, 0x9f, 0x8b, 0x36, 0x3b, 0xe5, 0xf9, 0x24, 0xd0, 0x20, 0xe7,
- 0x84, 0x15, 0xbc, 0xbd, 0xd0, 0xc6, 0x63, 0x19, 0x7c, 0xb3, 0x0a, 0xcd,
- 0xb9, 0x41, 0xd5, 0xf3, 0xcd, 0xb9, 0x58, 0x64, 0xfc, 0x5a, 0x95, 0xf9,
- 0x48, 0xe2, 0xbe, 0x85, 0x72, 0x1e, 0x4d, 0x3f, 0xf3, 0x3d, 0xfa, 0xd6,
- 0x71, 0xd8, 0xd8, 0x3e, 0xf9, 0x92, 0x33, 0x35, 0x37, 0x84, 0xa7, 0x26,
- 0xa5, 0x6e, 0x37, 0x4e, 0x70, 0x4e, 0xbe, 0xec, 0xee, 0xe7, 0x45, 0x92,
- 0x27, 0x54, 0x79, 0xe7, 0xb0, 0x1b, 0x6f, 0x8d, 0x1a, 0xd8, 0xc7, 0x1c,
- 0xea, 0x57, 0xc3, 0xab, 0xf0, 0xeb, 0xe1, 0x66, 0xed, 0x6f, 0x14, 0x39,
- 0x03, 0xff, 0x71, 0xfc, 0xa8, 0x21, 0x88, 0x83, 0xb4, 0xa1, 0x69, 0xbb,
- 0x0b, 0x6f, 0xdb, 0x56, 0x64, 0x2e, 0x22, 0x7b, 0xbc, 0x9e, 0xc8, 0x01,
- 0x79, 0xcf, 0x79, 0x9d, 0x1a, 0x39, 0xb8, 0x44, 0x89, 0x58, 0x6f, 0xa8,
- 0x2b, 0xf1, 0x8b, 0x7c, 0x17, 0xce, 0xe4, 0x67, 0xda, 0xc2, 0x66, 0x07,
- 0x8d, 0x62, 0x07, 0x62, 0x0f, 0xb4, 0x45, 0xe6, 0x8a, 0xdf, 0x26, 0x8f,
- 0xee, 0xfd, 0x18, 0xed, 0x31, 0x43, 0x7b, 0xcc, 0xd0, 0x1e, 0x89, 0x49,
- 0xcf, 0x10, 0xab, 0xbe, 0x96, 0xa1, 0x3d, 0xd2, 0x7f, 0xbe, 0x42, 0xff,
- 0x29, 0x72, 0xe5, 0x1e, 0x77, 0x4d, 0xff, 0x15, 0xc6, 0x44, 0xfb, 0x31,
- 0x79, 0x7f, 0xb8, 0x79, 0x7d, 0x01, 0x91, 0x9e, 0x01, 0x65, 0x5d, 0xbd,
- 0xbc, 0xcf, 0xf1, 0xf9, 0xa8, 0xf8, 0x80, 0xbc, 0x7b, 0x46, 0xbf, 0x1a,
- 0x3f, 0x55, 0x27, 0xef, 0xb2, 0xee, 0xdf, 0xfd, 0x51, 0x3a, 0xfb, 0x7b,
- 0xf6, 0x43, 0xf4, 0xf5, 0xc7, 0x8e, 0x5d, 0x74, 0xf9, 0x4f, 0xce, 0x8f,
- 0x1a, 0x65, 0xfc, 0xab, 0xf1, 0xf3, 0xe1, 0x4e, 0x9c, 0x65, 0xfc, 0xfd,
- 0x74, 0xfb, 0x94, 0x45, 0x9b, 0xdd, 0x68, 0x78, 0x4c, 0x4c, 0xe6, 0x3b,
- 0x71, 0xda, 0x36, 0x91, 0xb7, 0x9b, 0xd7, 0x7f, 0x57, 0x79, 0x53, 0xcd,
- 0xcd, 0x2b, 0xf2, 0xf9, 0xdf, 0x90, 0x5f, 0x1e, 0x6a, 0x91, 0xf7, 0x5d,
- 0x13, 0x18, 0xc9, 0x8b, 0x9d, 0x06, 0x71, 0xd3, 0x12, 0x43, 0xde, 0x11,
- 0xfb, 0xbd, 0x7f, 0xf7, 0xd9, 0xb2, 0x97, 0x72, 0xce, 0x99, 0x0a, 0xfa,
- 0xad, 0x20, 0x7d, 0xd8, 0xb3, 0x4b, 0x7e, 0x07, 0x40, 0xfc, 0x59, 0xc1,
- 0x67, 0x8c, 0x29, 0xad, 0x06, 0x91, 0xa7, 0x77, 0x33, 0x81, 0x7a, 0x2d,
- 0x2d, 0x67, 0x88, 0x3b, 0xf1, 0x26, 0xcb, 0x57, 0xd1, 0x2f, 0x5e, 0xcb,
- 0x7b, 0xbd, 0x3f, 0x4a, 0xcb, 0x7b, 0xec, 0x2b, 0xf1, 0xa3, 0xfc, 0xcb,
- 0xea, 0x2f, 0x82, 0x06, 0xde, 0x2e, 0xac, 0xc2, 0xfc, 0x5d, 0xb2, 0xbe,
- 0x90, 0xc4, 0x7e, 0x3b, 0x72, 0xf4, 0x59, 0xac, 0xc2, 0xbc, 0xb1, 0xd5,
- 0xcc, 0xa3, 0x15, 0xbc, 0x17, 0x5d, 0x8d, 0x00, 0x3f, 0xd7, 0xee, 0x72,
- 0x9c, 0xc3, 0xf1, 0x3a, 0x67, 0xfb, 0x6a, 0x99, 0x3b, 0xc1, 0x93, 0x65,
- 0xf5, 0xa8, 0x5d, 0x0d, 0x8c, 0x09, 0x57, 0xd1, 0x71, 0xeb, 0xc0, 0x2a,
- 0x5c, 0xb1, 0xab, 0x39, 0x76, 0x2b, 0x9a, 0xb3, 0x47, 0x3c, 0xab, 0xd0,
- 0x30, 0x76, 0x2f, 0xe7, 0x40, 0xca, 0x6a, 0xb4, 0x3f, 0x0b, 0x95, 0xe4,
- 0x84, 0x9d, 0xe9, 0x9f, 0x3a, 0xf3, 0x4d, 0x77, 0x1f, 0x0e, 0xeb, 0x0a,
- 0x3a, 0xe3, 0x5d, 0x35, 0x52, 0x23, 0x4f, 0x38, 0x75, 0xa6, 0x17, 0x6b,
- 0x0b, 0x6d, 0xb8, 0x69, 0xc8, 0x71, 0x4e, 0x2f, 0x49, 0x22, 0x60, 0x06,
- 0x88, 0x61, 0x01, 0x3c, 0x94, 0xae, 0xe1, 0x7f, 0x07, 0x15, 0x8c, 0xc9,
- 0x2d, 0xaa, 0xbe, 0x7e, 0x9e, 0x47, 0xef, 0x29, 0x28, 0x12, 0xf7, 0x03,
- 0x78, 0x80, 0xf1, 0x79, 0x45, 0x3a, 0x8c, 0x54, 0xc1, 0x71, 0x5e, 0xed,
- 0x08, 0xe1, 0x7e, 0xd6, 0xef, 0x4a, 0xf7, 0xa3, 0x97, 0x76, 0x91, 0x1a,
- 0xd3, 0xb5, 0x20, 0xe3, 0xfd, 0xba, 0x82, 0x9f, 0x31, 0xac, 0x01, 0xb7,
- 0xec, 0xd2, 0xf0, 0x50, 0x21, 0xc0, 0xf8, 0xe6, 0x2c, 0x3d, 0x69, 0x58,
- 0x57, 0x7a, 0xa0, 0x63, 0x63, 0x21, 0x84, 0x95, 0xe9, 0xc8, 0xb4, 0xbc,
- 0x47, 0x7d, 0xd6, 0x88, 0xe1, 0xc1, 0x42, 0x18, 0xb7, 0xa5, 0x0f, 0x3d,
- 0x34, 0x1f, 0xd6, 0xff, 0x98, 0x87, 0x36, 0x7c, 0xa6, 0xd0, 0x44, 0xf9,
- 0x91, 0xf5, 0xaf, 0x28, 0x4d, 0xf8, 0xec, 0x98, 0x41, 0xf9, 0x2a, 0x6e,
- 0xa5, 0x9c, 0x9b, 0xd3, 0x57, 0xe0, 0x81, 0xb1, 0x0e, 0xdc, 0x5b, 0x58,
- 0x8c, 0xe5, 0x8c, 0x4f, 0x1b, 0x98, 0x1b, 0xe2, 0xbf, 0x00, 0xb7, 0x0d,
- 0x89, 0xee, 0xa1, 0xbc, 0xda, 0x31, 0xc5, 0x7c, 0xdc, 0x00, 0x0d, 0x91,
- 0xf7, 0x74, 0x72, 0x30, 0x03, 0xb7, 0xed, 0x5d, 0xec, 0xee, 0xc9, 0x37,
- 0xc7, 0x2b, 0x91, 0xea, 0x56, 0xd0, 0x39, 0x24, 0x71, 0x56, 0xb8, 0x8d,
- 0xc1, 0xb8, 0x1a, 0x65, 0x1b, 0x06, 0xe3, 0x6a, 0xf1, 0x7e, 0x6f, 0x46,
- 0xd6, 0x2e, 0x7e, 0x42, 0xbe, 0x14, 0x47, 0xa7, 0x1b, 0xa3, 0xfd, 0xe4,
- 0xd7, 0x16, 0xbc, 0x8c, 0xdd, 0x71, 0xda, 0xf8, 0xd2, 0x76, 0x89, 0xd5,
- 0x3a, 0x06, 0xe8, 0x0f, 0x93, 0x83, 0xfa, 0x86, 0x69, 0xc5, 0x44, 0x61,
- 0xaf, 0xc4, 0xc4, 0x10, 0x1e, 0x4c, 0x9b, 0x38, 0x29, 0xe7, 0xf8, 0xaf,
- 0x4a, 0xae, 0xa8, 0x81, 0x6e, 0x3c, 0x80, 0xa8, 0x75, 0x8c, 0xb1, 0xfd,
- 0x4c, 0xae, 0x01, 0x37, 0xed, 0x92, 0x32, 0xed, 0x78, 0x7d, 0xd4, 0x8b,
- 0x9b, 0xd2, 0x9b, 0xf0, 0x44, 0xd6, 0x83, 0x11, 0xa3, 0xb9, 0x5f, 0x65,
- 0xfc, 0xbc, 0xbe, 0x3d, 0x12, 0xfc, 0x3a, 0xb9, 0xea, 0xf4, 0x62, 0x46,
- 0xe5, 0xb9, 0x1d, 0xe8, 0x64, 0xbf, 0x3a, 0x75, 0xf1, 0x49, 0x0b, 0xf7,
- 0x76, 0x6c, 0xc2, 0xb1, 0xac, 0x6e, 0x3d, 0x29, 0xeb, 0x0c, 0xed, 0x7c,
- 0x3e, 0xc7, 0x8b, 0x3e, 0x5d, 0x38, 0xad, 0x4e, 0xdf, 0x22, 0xeb, 0xd4,
- 0x3b, 0x70, 0x92, 0xf6, 0xda, 0x9f, 0x5b, 0xca, 0xd8, 0x2f, 0x31, 0xdf,
- 0x6f, 0x85, 0x59, 0xaf, 0xee, 0x3a, 0x05, 0x27, 0xf6, 0x09, 0xc7, 0x5a,
- 0x8a, 0xbb, 0xa8, 0xa7, 0xce, 0xb4, 0x8a, 0xeb, 0xc7, 0xd6, 0xe0, 0xf4,
- 0xce, 0x22, 0xe7, 0x7a, 0x35, 0x6e, 0x7d, 0x86, 0x9c, 0xab, 0x67, 0x16,
- 0x39, 0x17, 0xb9, 0x5c, 0xec, 0x41, 0xc5, 0x8b, 0x68, 0x21, 0x41, 0x5e,
- 0x21, 0xfc, 0x22, 0x8c, 0xa7, 0xf2, 0x1d, 0xb8, 0x25, 0xdd, 0x84, 0x71,
- 0xf2, 0xad, 0x1c, 0xf1, 0x22, 0x97, 0x67, 0x5c, 0x19, 0x6d, 0xe4, 0xa5,
- 0xf1, 0x5a, 0xc0, 0x4b, 0x77, 0xef, 0xad, 0xa5, 0x2d, 0x27, 0xbb, 0x25,
- 0x4f, 0x23, 0xff, 0xcd, 0x4b, 0xac, 0x56, 0x98, 0xb7, 0xfe, 0xaf, 0x7a,
- 0xc9, 0x4d, 0x83, 0xba, 0x82, 0xaf, 0x65, 0x35, 0xfc, 0x55, 0xfb, 0x76,
- 0x25, 0xd9, 0xe0, 0xbe, 0x83, 0x4a, 0xdf, 0xb6, 0x70, 0x92, 0x63, 0xba,
- 0x37, 0x2b, 0x76, 0x49, 0x19, 0xcc, 0xd1, 0x8f, 0x19, 0xf5, 0xd0, 0xea,
- 0x35, 0x39, 0xd7, 0xc4, 0xd8, 0xc1, 0xf8, 0x6b, 0xa7, 0xc8, 0xa3, 0x5a,
- 0xbb, 0x5b, 0x55, 0x8f, 0xbc, 0x9f, 0x67, 0x68, 0xaa, 0xf8, 0x58, 0x0a,
- 0x15, 0x69, 0xbf, 0x55, 0x27, 0xf5, 0x97, 0x6c, 0x60, 0x3c, 0x68, 0x5d,
- 0xff, 0xb2, 0xf0, 0xfb, 0x39, 0x11, 0x6d, 0x0a, 0x1b, 0xb0, 0xce, 0xd6,
- 0x19, 0x03, 0xd7, 0x38, 0xbd, 0x9c, 0x87, 0x51, 0x7b, 0x03, 0xee, 0xb2,
- 0x5b, 0xa7, 0x1e, 0xa7, 0x6d, 0xe1, 0xce, 0x0d, 0xe8, 0xe4, 0xb3, 0x91,
- 0x4c, 0xf3, 0x74, 0x2f, 0x75, 0x7d, 0x7c, 0x76, 0xcc, 0x5d, 0xf7, 0x97,
- 0x33, 0xe4, 0xa3, 0xe4, 0xd7, 0x5f, 0xcd, 0xb4, 0x26, 0x87, 0xd4, 0x1e,
- 0x05, 0x73, 0x24, 0x97, 0x4c, 0x90, 0x53, 0x05, 0xf0, 0x99, 0xb4, 0x45,
- 0x1f, 0x00, 0x6d, 0xae, 0x83, 0x79, 0xc5, 0x13, 0x4e, 0xbd, 0x19, 0x35,
- 0x44, 0x3f, 0xeb, 0x0b, 0x4b, 0xf1, 0x14, 0x63, 0x6f, 0xf3, 0xb5, 0x7a,
- 0xf0, 0x39, 0x68, 0xf0, 0x99, 0x3f, 0x75, 0x1a, 0xcc, 0x1a, 0x3c, 0x30,
- 0x12, 0x4d, 0xdc, 0xc4, 0x38, 0xdb, 0x79, 0xad, 0x7e, 0xf4, 0x14, 0x63,
- 0xe0, 0x7c, 0xd3, 0x96, 0xf3, 0x26, 0xe4, 0x3b, 0x01, 0xd7, 0xce, 0x4f,
- 0xdb, 0xe2, 0x27, 0x3a, 0x71, 0x33, 0x84, 0xcf, 0xd1, 0xce, 0xdf, 0xb7,
- 0x63, 0x98, 0x24, 0xdf, 0xf8, 0x2c, 0xfd, 0xe3, 0x8c, 0x1d, 0x49, 0x5d,
- 0xa3, 0xea, 0xd8, 0x40, 0xff, 0x78, 0xd7, 0x4e, 0xd0, 0x77, 0x3e, 0xc6,
- 0xab, 0x8d, 0xfe, 0x10, 0x63, 0x1d, 0x8d, 0x7e, 0x10, 0x72, 0xcf, 0x95,
- 0x8e, 0x65, 0x9a, 0xbb, 0x1f, 0x42, 0x73, 0xec, 0x66, 0xa5, 0x8e, 0x79,
- 0x6a, 0x10, 0xf7, 0x14, 0x6e, 0xc0, 0x89, 0x6c, 0x64, 0x9a, 0x39, 0xf9,
- 0xc6, 0xa5, 0x0a, 0xee, 0x20, 0x67, 0x5b, 0x5f, 0xad, 0xb4, 0x4e, 0x3d,
- 0xa5, 0x44, 0x68, 0x93, 0x8c, 0x97, 0xf4, 0xcf, 0xcf, 0xb2, 0xcc, 0x99,
- 0x6c, 0x35, 0x36, 0x8c, 0xd8, 0xe8, 0xcf, 0x54, 0xa0, 0x6a, 0xa7, 0x1f,
- 0xf7, 0x8f, 0xe9, 0xc8, 0x64, 0x64, 0x1d, 0xd9, 0x6f, 0xd5, 0x12, 0x37,
- 0x46, 0x89, 0x0d, 0x2f, 0x2d, 0x01, 0xa6, 0xf7, 0xae, 0xc1, 0x81, 0x9d,
- 0x3a, 0xe3, 0x5d, 0xd1, 0x3e, 0x82, 0x71, 0x97, 0x93, 0xa7, 0x84, 0x93,
- 0x57, 0x99, 0x12, 0xfb, 0xa2, 0x3d, 0x8f, 0x50, 0x07, 0xb7, 0x15, 0xc4,
- 0xee, 0x12, 0x9c, 0xa3, 0x30, 0x06, 0x69, 0x23, 0xfb, 0xec, 0x26, 0xe6,
- 0xe6, 0x01, 0x58, 0xb4, 0x11, 0x4b, 0xde, 0x53, 0xa5, 0x8d, 0x58, 0xb4,
- 0x11, 0x8b, 0x36, 0x62, 0xd1, 0x46, 0xac, 0xfc, 0x52, 0xe6, 0x4c, 0x3a,
- 0xc6, 0xd9, 0xe6, 0xb6, 0x51, 0x72, 0xf7, 0xa0, 0xd8, 0x4a, 0x0c, 0x5f,
- 0xcf, 0xf4, 0x2b, 0xda, 0x9d, 0x37, 0x60, 0x24, 0x7b, 0x23, 0x2f, 0x05,
- 0xb7, 0xd2, 0x56, 0x1e, 0xcd, 0x89, 0xed, 0xe9, 0xee, 0xef, 0xd3, 0x3c,
- 0x9b, 0xdf, 0x33, 0x1b, 0xd5, 0xe2, 0x03, 0x8c, 0x45, 0xee, 0x7d, 0x39,
- 0x73, 0xec, 0xc7, 0x68, 0xfe, 0x82, 0x5f, 0x7c, 0x4f, 0xce, 0xab, 0xb4,
- 0xcb, 0x6f, 0xc5, 0x74, 0x30, 0x0f, 0x90, 0x73, 0xee, 0x32, 0x4e, 0x19,
- 0x57, 0x71, 0x4c, 0x55, 0x83, 0x9b, 0xf0, 0xf5, 0x41, 0x9d, 0xb1, 0xca,
- 0xc0, 0x93, 0x39, 0x89, 0xe5, 0xe2, 0xdf, 0x32, 0x0f, 0xe2, 0xeb, 0x1e,
- 0xd4, 0xb4, 0x7b, 0x11, 0x70, 0xfd, 0xbc, 0x39, 0xbc, 0x43, 0xb1, 0xe9,
- 0x3b, 0xba, 0x9c, 0x03, 0x9d, 0x0a, 0xeb, 0x0d, 0x38, 0xbd, 0xbb, 0x1d,
- 0xff, 0x6d, 0xa7, 0x87, 0x3c, 0xc0, 0x59, 0xfa, 0x52, 0x5c, 0x4f, 0x4e,
- 0x2b, 0xd1, 0xd8, 0x2c, 0xa5, 0x1d, 0xf7, 0x90, 0xfb, 0x6f, 0x18, 0x8c,
- 0x74, 0x33, 0x66, 0x1b, 0xb7, 0x28, 0x4b, 0x51, 0xc5, 0x1c, 0xa0, 0x8d,
- 0x39, 0xc0, 0x83, 0xc4, 0x80, 0xaf, 0x66, 0xbc, 0x68, 0x59, 0x2c, 0xbf,
- 0x4d, 0xa6, 0xbb, 0x6b, 0x3b, 0x2f, 0x90, 0xa3, 0xce, 0x37, 0x3b, 0xe4,
- 0x2c, 0x8e, 0x72, 0xf6, 0xba, 0x29, 0x24, 0x28, 0x7f, 0xcc, 0xcd, 0x2f,
- 0x12, 0x38, 0x98, 0x27, 0x6e, 0x70, 0xdc, 0xaf, 0xb4, 0xfd, 0x84, 0xf9,
- 0xb0, 0x70, 0x7b, 0x13, 0x13, 0x39, 0x97, 0xff, 0x47, 0xea, 0x88, 0x19,
- 0xd9, 0x41, 0xbd, 0xcb, 0xaf, 0x9a, 0x78, 0x64, 0xaf, 0xf8, 0xb0, 0x89,
- 0xf6, 0x21, 0x3d, 0x7c, 0x9b, 0x1a, 0x0d, 0xae, 0xe3, 0xb3, 0x05, 0x9c,
- 0xcf, 0xc7, 0x33, 0x32, 0x8f, 0x1a, 0x5a, 0x18, 0x9b, 0xdf, 0x9c, 0xd0,
- 0xb1, 0x88, 0x71, 0xfa, 0x9d, 0x89, 0x18, 0x96, 0x32, 0x66, 0x3b, 0xcc,
- 0x1f, 0x12, 0x19, 0xf1, 0x45, 0xf2, 0x81, 0x09, 0x8d, 0x71, 0x56, 0xd6,
- 0x87, 0x9e, 0xc0, 0xd8, 0x6a, 0x0d, 0xfb, 0xdc, 0xf3, 0x7c, 0x7e, 0xab,
- 0x81, 0x58, 0xd9, 0x39, 0xe0, 0xc7, 0xa7, 0x87, 0x36, 0xe3, 0xf5, 0xc5,
- 0xc2, 0x95, 0xd6, 0x38, 0xa2, 0x9f, 0xc7, 0x29, 0x73, 0x8c, 0xbc, 0x78,
- 0x94, 0x79, 0xd7, 0xc2, 0x7d, 0x6b, 0xf0, 0xc9, 0x5d, 0x17, 0xf2, 0xb4,
- 0x33, 0x71, 0xeb, 0x6e, 0xda, 0xc4, 0xfa, 0x00, 0x6d, 0xa2, 0x96, 0x36,
- 0x61, 0x67, 0xa2, 0xc9, 0x02, 0x6d, 0x22, 0x46, 0xdc, 0xc8, 0x0e, 0x48,
- 0x39, 0xf7, 0x9d, 0x99, 0xbb, 0xe4, 0xdd, 0x65, 0x83, 0xbe, 0xb3, 0x75,
- 0xc0, 0xd9, 0xec, 0x65, 0xbc, 0x79, 0xa4, 0xa3, 0x89, 0xd8, 0x72, 0x23,
- 0xf6, 0x0c, 0x36, 0xa1, 0x85, 0x31, 0x63, 0x61, 0x1a, 0x77, 0x84, 0xa1,
- 0xce, 0x0f, 0x23, 0xb2, 0xe1, 0x1d, 0x44, 0xa7, 0xef, 0x56, 0x5a, 0x8f,
- 0xbe, 0xa8, 0x44, 0x36, 0xfe, 0x84, 0x36, 0x7c, 0x56, 0x91, 0xb6, 0x9b,
- 0x70, 0x35, 0xfd, 0xe4, 0x2a, 0xfa, 0x84, 0xc6, 0x5c, 0x52, 0x63, 0xdd,
- 0xfe, 0x41, 0x1f, 0xe6, 0x33, 0xd7, 0x93, 0xb3, 0xca, 0xb1, 0x31, 0x2f,
- 0xb2, 0x3b, 0xf5, 0xa9, 0x47, 0xd0, 0x08, 0x63, 0xec, 0x46, 0x6c, 0x1d,
- 0xd4, 0x10, 0xe5, 0xbd, 0xbe, 0x9d, 0x0b, 0xd0, 0x4c, 0xfb, 0xd6, 0xe8,
- 0xa7, 0xbd, 0x83, 0x2a, 0x16, 0x8c, 0xdd, 0x80, 0x1d, 0x83, 0x0a, 0xee,
- 0x8b, 0x2a, 0x68, 0x19, 0x91, 0x1c, 0x2c, 0x86, 0xa7, 0x32, 0xc2, 0x15,
- 0xa1, 0xb4, 0x5c, 0x4b, 0x8e, 0x4c, 0xee, 0xf9, 0x93, 0x9c, 0xcc, 0xb9,
- 0xe8, 0x53, 0x7e, 0x53, 0xa6, 0x1d, 0x9f, 0xdb, 0xd9, 0x80, 0xab, 0x76,
- 0xeb, 0xd6, 0x69, 0xc5, 0x59, 0x7a, 0x80, 0x7c, 0xde, 0xaf, 0x16, 0xe7,
- 0xfc, 0xc1, 0xc1, 0x67, 0x19, 0x2f, 0x7e, 0xe2, 0x04, 0xf5, 0xa5, 0xe8,
- 0x8b, 0x27, 0xb1, 0xb6, 0xa3, 0x1d, 0x6b, 0xf7, 0x8a, 0xbe, 0x1c, 0xe6,
- 0x87, 0xcc, 0xfd, 0x26, 0xa7, 0xf0, 0x0e, 0xfd, 0x77, 0x11, 0x39, 0xed,
- 0x52, 0xc6, 0x89, 0x37, 0x16, 0x9b, 0xd4, 0x9f, 0xee, 0x9e, 0xf5, 0x9b,
- 0x67, 0x9a, 0xa8, 0x1d, 0xd4, 0x19, 0x67, 0x4c, 0xcc, 0xda, 0x2b, 0xed,
- 0x99, 0xb8, 0x67, 0x50, 0x4f, 0x3d, 0xcd, 0xb9, 0x14, 0xbb, 0x11, 0xcc,
- 0xae, 0x61, 0xec, 0x3f, 0x39, 0x29, 0x38, 0xd5, 0x89, 0x13, 0xcc, 0x03,
- 0xde, 0x7c, 0x2c, 0xda, 0xfd, 0x33, 0xe6, 0x74, 0xef, 0x50, 0x46, 0x96,
- 0xfd, 0x1b, 0xe0, 0xbc, 0x56, 0xa4, 0xf5, 0x8d, 0xff, 0x8c, 0x28, 0xfd,
- 0xbb, 0x0b, 0xb5, 0xd4, 0xc9, 0x81, 0xc1, 0x95, 0xf0, 0xd3, 0x16, 0x1e,
- 0xc9, 0x88, 0xdd, 0x10, 0xbf, 0x77, 0x7e, 0x02, 0x5b, 0xf7, 0x17, 0xf3,
- 0xbc, 0x7b, 0x06, 0x36, 0xd1, 0xc6, 0x85, 0xb3, 0xc7, 0x68, 0xef, 0x98,
- 0xe7, 0x43, 0xb2, 0x9e, 0x18, 0x91, 0x58, 0x4e, 0xcc, 0x7c, 0xd4, 0x20,
- 0xae, 0xd6, 0x47, 0xc2, 0x2d, 0xaa, 0x95, 0x60, 0x5e, 0x17, 0xbe, 0x0f,
- 0xd2, 0xbe, 0x85, 0x75, 0x4b, 0x36, 0x61, 0x4f, 0xd6, 0x8b, 0xaa, 0xc5,
- 0x1e, 0xe2, 0xb1, 0x60, 0x94, 0x15, 0x94, 0xe7, 0x6b, 0x21, 0x7e, 0x22,
- 0xf3, 0xeb, 0xc1, 0x99, 0x78, 0xf3, 0x86, 0xac, 0xfc, 0x96, 0x05, 0x73,
- 0xbe, 0xcf, 0xa2, 0x83, 0x73, 0x2f, 0xfe, 0x98, 0xc0, 0x3d, 0x63, 0xc2,
- 0xd5, 0xc8, 0xe7, 0x6c, 0x3f, 0xfe, 0x3a, 0x2b, 0x9c, 0x6e, 0x33, 0xee,
- 0x69, 0x2f, 0xe7, 0x6e, 0x62, 0x77, 0xad, 0xd3, 0x1e, 0x34, 0x93, 0x93,
- 0xe9, 0xb9, 0xac, 0x1a, 0xb1, 0x52, 0x88, 0xf4, 0xa7, 0x20, 0x71, 0xa2,
- 0xd5, 0xe2, 0x0c, 0x53, 0x36, 0xb9, 0xa5, 0xed, 0x41, 0x1d, 0x7d, 0x5c,
- 0x7e, 0x44, 0xae, 0x9d, 0xf6, 0xf3, 0xac, 0x5d, 0x0d, 0xcd, 0xb5, 0x75,
- 0x2f, 0x96, 0x16, 0x2c, 0xe2, 0xed, 0x52, 0xb4, 0x3d, 0x16, 0xc0, 0x35,
- 0xe4, 0x26, 0x57, 0xa7, 0x9f, 0x70, 0x66, 0x11, 0x7b, 0xdb, 0x46, 0xa2,
- 0xc1, 0x23, 0xe4, 0x81, 0x07, 0x96, 0xfc, 0xd4, 0xf1, 0x98, 0xae, 0x5f,
- 0x68, 0xf4, 0x00, 0xe7, 0x33, 0x1d, 0xfa, 0xd4, 0x0e, 0x04, 0x90, 0x20,
- 0x7e, 0x5e, 0x99, 0x69, 0x40, 0xfb, 0xee, 0x7e, 0xce, 0x7f, 0x10, 0x57,
- 0xf2, 0xfb, 0x62, 0xc6, 0x37, 0x8d, 0xd8, 0xaa, 0xc9, 0xe7, 0x82, 0xd8,
- 0x4b, 0x98, 0x7e, 0xe4, 0x2c, 0xbd, 0xb3, 0xdd, 0xba, 0x63, 0x36, 0xf5,
- 0xd5, 0x42, 0x5c, 0x5e, 0x9a, 0x89, 0x6c, 0xbc, 0x59, 0x51, 0xb0, 0xb2,
- 0xdd, 0x60, 0xdb, 0x01, 0xc4, 0x32, 0xb2, 0x36, 0x70, 0xe8, 0xa1, 0x3a,
- 0x58, 0xad, 0x01, 0xda, 0xe9, 0x11, 0x45, 0xd6, 0x35, 0x44, 0x6f, 0x4d,
- 0xb8, 0x8a, 0x7c, 0x44, 0x23, 0x66, 0xc7, 0x0a, 0xa2, 0x43, 0x60, 0x6d,
- 0x6e, 0x0d, 0xf6, 0x0c, 0x8b, 0x7f, 0x0a, 0x76, 0x3a, 0x4e, 0xe5, 0xe2,
- 0xa8, 0xf1, 0x36, 0x75, 0xf8, 0xc6, 0x84, 0x60, 0x90, 0x82, 0x79, 0xb4,
- 0x63, 0x55, 0x97, 0x58, 0x2b, 0xb8, 0x15, 0xa6, 0xdf, 0x76, 0xe0, 0xd3,
- 0x8c, 0x6d, 0xd5, 0x9c, 0x83, 0x55, 0x4b, 0x9a, 0xe8, 0xbf, 0xc4, 0xc9,
- 0x89, 0x20, 0xaf, 0x10, 0x8e, 0xef, 0x6f, 0xe4, 0xa5, 0xf1, 0x5a, 0xc0,
- 0x4b, 0xe7, 0x3d, 0x15, 0x67, 0xf6, 0x93, 0x33, 0xed, 0x15, 0x0e, 0x22,
- 0x3e, 0xe8, 0xc7, 0xd3, 0x13, 0x20, 0x8f, 0x31, 0xc8, 0x43, 0x04, 0xff,
- 0x64, 0x9e, 0x98, 0xc7, 0x0c, 0xc6, 0x11, 0x1d, 0x29, 0x72, 0x8e, 0x93,
- 0xc3, 0x7a, 0xcf, 0x5a, 0x44, 0xb5, 0xbf, 0x26, 0x7e, 0x9d, 0x1a, 0x6d,
- 0xc7, 0x74, 0x96, 0xb8, 0xb5, 0xb8, 0x1d, 0x6f, 0xe7, 0x36, 0xd1, 0xff,
- 0x55, 0x9c, 0x25, 0x66, 0x69, 0x73, 0x05, 0xd7, 0x05, 0x43, 0xfd, 0xb4,
- 0xd7, 0x0e, 0x59, 0x03, 0x55, 0xe2, 0xc4, 0xac, 0x6b, 0xd2, 0xcf, 0x3a,
- 0xb5, 0x3a, 0x73, 0x2a, 0x35, 0x81, 0x0c, 0x31, 0xcb, 0xce, 0xca, 0x7c,
- 0x6d, 0xc6, 0x56, 0xe2, 0xd5, 0xd6, 0x9c, 0xd8, 0x37, 0x6d, 0x7a, 0x50,
- 0x0f, 0x16, 0x68, 0xdb, 0xea, 0x5e, 0x91, 0x61, 0xa2, 0x8f, 0xb1, 0xfd,
- 0x33, 0x1d, 0x26, 0x76, 0xe4, 0x24, 0x0e, 0x0a, 0x07, 0xd3, 0x98, 0x97,
- 0x24, 0xd1, 0x43, 0x9c, 0x7a, 0xdb, 0xee, 0xc4, 0x0a, 0xe2, 0xd4, 0x2f,
- 0x98, 0xa7, 0xdc, 0x49, 0x9c, 0x7a, 0xc3, 0x2e, 0xe2, 0xd4, 0xcd, 0x13,
- 0x62, 0x0b, 0x45, 0x5e, 0x7e, 0xc2, 0x6e, 0x6b, 0x90, 0xdf, 0x39, 0xab,
- 0x36, 0x7f, 0x57, 0x5c, 0x58, 0x85, 0x97, 0x86, 0xcb, 0x7b, 0xc5, 0x91,
- 0xe4, 0xed, 0xe4, 0xcc, 0x47, 0x47, 0xcb, 0x9c, 0xf7, 0xb8, 0x9b, 0x5b,
- 0xcf, 0x32, 0xcb, 0xfb, 0x96, 0xe5, 0xfd, 0x06, 0x0b, 0x5f, 0x5d, 0x22,
- 0x3c, 0x53, 0xd6, 0x81, 0x2a, 0xc8, 0x27, 0xbb, 0x31, 0xbe, 0xf3, 0x3d,
- 0x3c, 0x32, 0xa8, 0xde, 0x5c, 0xc3, 0xd8, 0x7a, 0x8b, 0xb2, 0x19, 0x9e,
- 0xb8, 0xbc, 0x47, 0x2a, 0x6b, 0xe5, 0xcc, 0x5d, 0x26, 0xb3, 0xe8, 0xdb,
- 0x57, 0x83, 0x43, 0x41, 0xc7, 0x79, 0xda, 0x98, 0x27, 0x3f, 0x13, 0x20,
- 0xb8, 0x19, 0xa8, 0xa0, 0x2f, 0xdc, 0xfc, 0x5b, 0xbf, 0xdd, 0x58, 0xde,
- 0x3b, 0xd8, 0x88, 0xbb, 0x76, 0x3d, 0x8c, 0x9e, 0x5d, 0x7f, 0x8b, 0x4f,
- 0x0e, 0x2d, 0xec, 0x9f, 0xe7, 0x71, 0x9c, 0xab, 0xdb, 0xa7, 0x70, 0x2a,
- 0xce, 0xd8, 0x18, 0x52, 0xf0, 0xbd, 0xab, 0x16, 0x8a, 0x1c, 0xfe, 0xbd,
- 0xef, 0x68, 0xae, 0xbc, 0x5b, 0x4b, 0x3e, 0x92, 0x98, 0xc3, 0xf1, 0x53,
- 0xf6, 0x8a, 0xfa, 0xd2, 0xbb, 0xc2, 0x7f, 0x40, 0x5b, 0x3f, 0x16, 0x19,
- 0xfc, 0x2b, 0xcb, 0x78, 0xcd, 0x49, 0xae, 0x96, 0x7a, 0x15, 0xa5, 0x36,
- 0xfe, 0x96, 0x9c, 0x90, 0xbc, 0xd0, 0xe0, 0xff, 0x91, 0xeb, 0x44, 0x3e,
- 0x9f, 0x95, 0xe5, 0xbf, 0xe4, 0x24, 0xbb, 0xe5, 0xbb, 0x94, 0x59, 0xc7,
- 0x67, 0x52, 0xae, 0xfc, 0xec, 0xf9, 0x92, 0x9c, 0x4a, 0x68, 0x0d, 0x45,
- 0x39, 0x9f, 0xa6, 0x9c, 0x33, 0x8b, 0x93, 0x50, 0xaf, 0x9d, 0x29, 0xab,
- 0xdc, 0xee, 0xff, 0x3a, 0x2f, 0xab, 0x58, 0xee, 0x6f, 0xe6, 0xc8, 0xbe,
- 0x80, 0x7a, 0xed, 0xcc, 0x75, 0xf2, 0x0a, 0xfa, 0x6f, 0x34, 0xb8, 0xd5,
- 0x5d, 0x9f, 0x36, 0xb0, 0xf6, 0xe2, 0x1c, 0x4b, 0xb0, 0x03, 0xe3, 0x76,
- 0xb0, 0x94, 0x53, 0xc9, 0x2d, 0x13, 0x5f, 0x66, 0xce, 0xf6, 0x94, 0x1d,
- 0xe9, 0x5a, 0xa7, 0xb4, 0x26, 0x17, 0x31, 0xce, 0xa0, 0x5e, 0xd6, 0xb0,
- 0x13, 0xee, 0xef, 0xf9, 0xe5, 0xa3, 0x09, 0xe4, 0x69, 0x8f, 0xaf, 0xd8,
- 0x91, 0x0d, 0xa7, 0xdc, 0xfd, 0x3b, 0x13, 0x2f, 0xe7, 0x5f, 0x2d, 0xed,
- 0x33, 0x95, 0x7f, 0x4f, 0x6c, 0xe6, 0x1a, 0xaa, 0xcc, 0xbf, 0x9c, 0xb1,
- 0x6e, 0x90, 0xb5, 0x0a, 0xcb, 0xa2, 0x9f, 0xf7, 0x66, 0xac, 0xb0, 0x8a,
- 0xeb, 0x90, 0x0a, 0xc9, 0xbe, 0xc4, 0xd6, 0xd2, 0x6f, 0x52, 0xb1, 0xde,
- 0xef, 0x58, 0x13, 0x02, 0x8c, 0xd2, 0x39, 0xb6, 0x18, 0xac, 0xc9, 0x2b,
- 0xc8, 0xc5, 0x64, 0xbd, 0x01, 0xd6, 0x6c, 0x53, 0x43, 0x48, 0x3f, 0xcc,
- 0x71, 0xfb, 0x30, 0x87, 0xf9, 0x54, 0x7c, 0x61, 0x6b, 0x77, 0xbb, 0x3a,
- 0x57, 0x70, 0x36, 0x98, 0x54, 0x63, 0x12, 0x07, 0x50, 0x99, 0x96, 0xb3,
- 0x26, 0x56, 0x97, 0x9f, 0x98, 0xba, 0x98, 0xd8, 0x52, 0x11, 0x85, 0xf7,
- 0xbe, 0xbc, 0x17, 0xc1, 0x85, 0xbf, 0x70, 0x7e, 0x18, 0x8a, 0x61, 0xdb,
- 0x64, 0xb9, 0x0f, 0x06, 0xfe, 0x7b, 0xe1, 0xd2, 0x8c, 0xb3, 0x2c, 0xf3,
- 0x3d, 0x27, 0x39, 0x47, 0xda, 0x2e, 0xca, 0xfd, 0xe8, 0xbe, 0x4a, 0x1f,
- 0xa5, 0xaf, 0xcd, 0x1a, 0x51, 0x15, 0x5b, 0x8d, 0x89, 0x39, 0xf2, 0x9b,
- 0x3f, 0xf7, 0xb8, 0x67, 0xd3, 0x65, 0x0e, 0xe4, 0xfd, 0xf1, 0x04, 0xee,
- 0x93, 0xf7, 0x30, 0x19, 0xb3, 0xee, 0xcd, 0xbb, 0xef, 0x77, 0x42, 0x7e,
- 0x17, 0xf1, 0xde, 0x7c, 0x51, 0x7f, 0x0f, 0xe5, 0x03, 0xe4, 0xdd, 0x01,
- 0xcb, 0x6b, 0x6e, 0x80, 0x4f, 0x97, 0x33, 0x67, 0x65, 0x5d, 0xfe, 0xdf,
- 0x73, 0x24, 0x97, 0xff, 0x2a, 0xfd, 0xc9, 0xbb, 0x50, 0x3e, 0x5b, 0xf2,
- 0xae, 0xa2, 0x52, 0xfc, 0x7c, 0xc6, 0x7d, 0xef, 0x5d, 0x35, 0xd7, 0xd1,
- 0x2f, 0x67, 0xbb, 0xef, 0xeb, 0x89, 0x7e, 0x42, 0xa6, 0xe5, 0xcc, 0xd6,
- 0x03, 0xb4, 0x91, 0xde, 0x39, 0xa5, 0x77, 0x0f, 0xba, 0xee, 0x20, 0x8e,
- 0x2c, 0x22, 0xb7, 0x5a, 0xac, 0x44, 0xb4, 0x55, 0x4a, 0x37, 0xeb, 0x51,
- 0x4f, 0x05, 0x91, 0xa1, 0xb8, 0xbf, 0xbd, 0xeb, 0xa3, 0x8c, 0xfd, 0x76,
- 0xab, 0xe6, 0x53, 0x7f, 0x5e, 0x3a, 0x7b, 0x2d, 0x7b, 0xf1, 0x29, 0x3c,
- 0x6f, 0xcf, 0xc1, 0xd4, 0x6f, 0xc9, 0x3d, 0xbf, 0x66, 0xfd, 0x4f, 0x41,
- 0x62, 0x88, 0x4f, 0x8f, 0x6c, 0x8c, 0x7b, 0x22, 0xeb, 0xa7, 0xe9, 0xd3,
- 0x85, 0xb8, 0x9e, 0xfa, 0x1a, 0xdb, 0xf8, 0x3e, 0xb9, 0x85, 0x3d, 0x43,
- 0x7e, 0x51, 0x56, 0x6b, 0x4f, 0x85, 0x7a, 0xc6, 0x29, 0xbe, 0x77, 0x2d,
- 0xbf, 0xfb, 0xbb, 0x06, 0xc1, 0xb4, 0xe5, 0x84, 0x28, 0x73, 0xbe, 0x19,
- 0xd9, 0x53, 0xaf, 0xea, 0xd9, 0xcf, 0xab, 0x9b, 0xb1, 0x56, 0x8e, 0x7c,
- 0x98, 0x11, 0xed, 0xd3, 0xb4, 0x8f, 0x76, 0x57, 0x46, 0x32, 0x56, 0x81,
- 0x8f, 0x3a, 0xd3, 0xc6, 0xf1, 0x41, 0xd6, 0x28, 0x59, 0xce, 0xdd, 0xe3,
- 0x97, 0xf7, 0x77, 0x98, 0x63, 0xdb, 0xf2, 0xbb, 0xa6, 0x6e, 0x33, 0xa5,
- 0x7d, 0x24, 0xe6, 0xc8, 0x8c, 0x97, 0xf7, 0xc8, 0x6f, 0xc8, 0x55, 0x07,
- 0x70, 0xaf, 0x2d, 0xeb, 0x0e, 0xff, 0x3f, 0x45, 0x18, 0xff, 0x64, 0x3c,
- 0x59, 0x00, 0x00, 0x00 };
+ 0xa5, 0xbc, 0x0d, 0x74, 0x1c, 0xe5, 0x95, 0x26, 0xfc, 0x54, 0x75, 0xb7,
+ 0xd4, 0x92, 0x5a, 0x52, 0x49, 0x6e, 0x8b, 0x36, 0x68, 0x70, 0xb5, 0x55,
+ 0x2d, 0x0b, 0x4b, 0x40, 0xb5, 0x24, 0x3b, 0xed, 0x6c, 0x83, 0x3b, 0xb6,
+ 0x6c, 0x64, 0x63, 0x40, 0x36, 0x06, 0xc4, 0xb7, 0xfe, 0x3e, 0x7a, 0xfc,
+ 0x03, 0x86, 0x38, 0x19, 0x91, 0xcd, 0xce, 0x0a, 0xd6, 0x59, 0x55, 0xe4,
+ 0x3f, 0xd9, 0x6e, 0x75, 0x4b, 0x42, 0xfe, 0xe1, 0xec, 0x9c, 0xa5, 0x2d,
+ 0xcb, 0x96, 0x21, 0xad, 0x16, 0x24, 0x6c, 0xc6, 0x39, 0x27, 0x09, 0x1a,
+ 0x63, 0x83, 0x0d, 0x18, 0xc8, 0x24, 0xf9, 0x86, 0xc9, 0xd9, 0x5d, 0x34,
+ 0xc6, 0xfc, 0x19, 0x70, 0x1c, 0x92, 0xc9, 0x9a, 0x19, 0x4c, 0xed, 0x73,
+ 0xab, 0xd5, 0xb6, 0xec, 0x30, 0xc9, 0xcc, 0x59, 0x9d, 0xd3, 0xa7, 0xab,
+ 0xab, 0xde, 0x9f, 0xfb, 0xde, 0xf7, 0xde, 0xe7, 0x3e, 0xf7, 0x7d, 0xdf,
+ 0x92, 0x0e, 0x14, 0x63, 0xf2, 0xaf, 0x94, 0x9f, 0x9b, 0x9a, 0x3b, 0xd6,
+ 0xce, 0x0d, 0xdf, 0x34, 0x4f, 0x7e, 0xbb, 0xcb, 0x0b, 0xdc, 0xf8, 0xb2,
+ 0xbf, 0x28, 0x22, 0x57, 0xdf, 0xd2, 0xbf, 0xb4, 0xe0, 0xbf, 0xf0, 0x17,
+ 0x41, 0x50, 0xe1, 0x57, 0xfd, 0xe4, 0x4f, 0x17, 0xa0, 0xe5, 0xfb, 0x97,
+ 0x0f, 0xbc, 0x6a, 0xd4, 0xb8, 0x77, 0xa1, 0x01, 0xaf, 0x2b, 0xba, 0xaa,
+ 0x7d, 0xad, 0x01, 0xc4, 0x32, 0xf5, 0xfa, 0x22, 0x5c, 0xb4, 0x2d, 0xbf,
+ 0x1b, 0x72, 0xff, 0xcf, 0xa2, 0x9f, 0x3f, 0xf5, 0x93, 0xaf, 0x04, 0xcf,
+ 0xa7, 0x5d, 0xf0, 0x6a, 0x51, 0x0b, 0x5a, 0x2d, 0xbc, 0xd5, 0xac, 0xf3,
+ 0x57, 0xb3, 0xb7, 0xa9, 0x28, 0xcb, 0xb7, 0x15, 0x0c, 0xa4, 0x11, 0xd4,
+ 0x2c, 0x04, 0xeb, 0x2c, 0x20, 0xee, 0x8e, 0x22, 0x5e, 0x18, 0xf5, 0xa2,
+ 0xc0, 0x28, 0x40, 0x5c, 0xeb, 0xd4, 0xb7, 0x34, 0x03, 0x0b, 0x13, 0x5e,
+ 0xfd, 0x74, 0x06, 0x58, 0x9b, 0xf0, 0x62, 0xc2, 0xe5, 0xd3, 0xdf, 0xc9,
+ 0x44, 0xca, 0x72, 0xfa, 0x88, 0xc1, 0x65, 0x20, 0xae, 0x46, 0xe5, 0x3e,
+ 0xf4, 0x45, 0x19, 0xa9, 0x0b, 0x6c, 0x4b, 0x7d, 0x5b, 0x7f, 0x37, 0x11,
+ 0xd4, 0xb6, 0xa1, 0x3e, 0x30, 0x84, 0x42, 0xc4, 0xfd, 0xc1, 0x3a, 0xe0,
+ 0xf3, 0x8b, 0x3b, 0x53, 0x0a, 0x3c, 0xc6, 0x34, 0xb4, 0xec, 0x07, 0x76,
+ 0xa4, 0x82, 0x31, 0x83, 0xc3, 0xeb, 0x19, 0x93, 0xba, 0x41, 0x2d, 0xcd,
+ 0xe7, 0x5b, 0x52, 0xc0, 0xd6, 0xd4, 0x34, 0x6c, 0xeb, 0xb3, 0xf1, 0xa2,
+ 0x59, 0xa3, 0x1d, 0x60, 0x0f, 0xdd, 0xce, 0xf3, 0x69, 0xb0, 0xd2, 0xf2,
+ 0xfc, 0x03, 0xfb, 0x27, 0xb3, 0x35, 0x3c, 0x3b, 0xe6, 0xc7, 0x0b, 0x63,
+ 0x15, 0xd8, 0xd1, 0x57, 0x81, 0xed, 0x7d, 0x75, 0x50, 0x0d, 0x1b, 0x75,
+ 0xe1, 0x3a, 0x14, 0xcc, 0xb7, 0xf1, 0x8e, 0xd9, 0x80, 0xad, 0x6c, 0xf8,
+ 0xcd, 0x86, 0x2a, 0xac, 0xd1, 0xaa, 0xb1, 0xc5, 0xf8, 0x0a, 0x72, 0x63,
+ 0xfd, 0xfc, 0x62, 0x2a, 0x85, 0xb8, 0x27, 0xea, 0x56, 0x55, 0xe3, 0x56,
+ 0x9c, 0xdb, 0x1d, 0xc5, 0x27, 0xbb, 0xb1, 0xba, 0x0c, 0xb6, 0x9d, 0x09,
+ 0x87, 0xda, 0x36, 0x2a, 0x9a, 0xfe, 0x4c, 0x86, 0x02, 0xad, 0x74, 0xb3,
+ 0x3d, 0xe8, 0x43, 0x99, 0xa9, 0x53, 0xc1, 0xfe, 0x52, 0xec, 0x37, 0x25,
+ 0xb2, 0x04, 0xf0, 0x93, 0xd9, 0x7f, 0x41, 0x7b, 0xc8, 0x8d, 0x69, 0x6b,
+ 0xea, 0x2d, 0xca, 0xa4, 0x53, 0x9e, 0x6a, 0xfc, 0x60, 0x2c, 0x80, 0xef,
+ 0x53, 0xb6, 0xe7, 0xc6, 0x44, 0xc6, 0xe0, 0x3e, 0x0b, 0x15, 0x18, 0xee,
+ 0xab, 0xc6, 0xb3, 0x46, 0x03, 0x9e, 0xa3, 0x8c, 0x9b, 0xcd, 0x3a, 0xac,
+ 0x89, 0xdc, 0x4f, 0x79, 0x14, 0xac, 0x6c, 0xf8, 0xf3, 0x49, 0xb9, 0x82,
+ 0x3a, 0x54, 0x15, 0xb1, 0xca, 0x60, 0x9d, 0xae, 0x4a, 0x9b, 0x97, 0xe5,
+ 0xed, 0x4d, 0xc1, 0xf2, 0x46, 0x45, 0xe6, 0x5b, 0x91, 0xa1, 0xbc, 0xdf,
+ 0xdb, 0x1d, 0x32, 0x37, 0xa8, 0x58, 0xee, 0xa3, 0xcc, 0x8f, 0x84, 0x43,
+ 0x91, 0x39, 0x94, 0x79, 0x24, 0xa3, 0x72, 0x3c, 0x7e, 0xfd, 0x10, 0x65,
+ 0x8f, 0xad, 0x54, 0x29, 0x3b, 0x65, 0x49, 0x51, 0x96, 0x14, 0x65, 0x49,
+ 0x51, 0x16, 0x47, 0xee, 0x3a, 0xca, 0x9c, 0x9b, 0xa3, 0xa1, 0xcc, 0x04,
+ 0xe5, 0x9d, 0x2a, 0x67, 0x35, 0x65, 0x47, 0xbc, 0x22, 0xfa, 0x6d, 0xbd,
+ 0x26, 0x49, 0x7d, 0xa7, 0x6c, 0xfb, 0x4d, 0xd3, 0xb6, 0x3f, 0x35, 0x7d,
+ 0xd4, 0x5f, 0x8a, 0x76, 0x90, 0x97, 0x67, 0xa6, 0x55, 0x10, 0x45, 0x0b,
+ 0x4d, 0xd0, 0x3e, 0xde, 0x1c, 0x8a, 0x54, 0x2a, 0x2a, 0xdc, 0x86, 0xa6,
+ 0xcf, 0xce, 0x06, 0x4d, 0xea, 0x47, 0x0f, 0x65, 0xa1, 0x1b, 0x59, 0xb6,
+ 0x75, 0x45, 0xbf, 0x41, 0x6d, 0x1c, 0xd2, 0xaf, 0xce, 0xfe, 0x27, 0x26,
+ 0xe7, 0x4e, 0xda, 0x0f, 0xb0, 0x4f, 0xe9, 0x5f, 0xda, 0xb6, 0xed, 0xdf,
+ 0x98, 0x30, 0x34, 0x84, 0xac, 0x7e, 0xda, 0x9f, 0x2b, 0xaa, 0xe9, 0x1d,
+ 0x19, 0x3e, 0xbf, 0xd4, 0x46, 0x6e, 0x3e, 0xd6, 0x64, 0xf4, 0xc9, 0x31,
+ 0x04, 0x29, 0x82, 0xd8, 0x41, 0x20, 0xee, 0x8b, 0x6a, 0x22, 0x7b, 0xdb,
+ 0xbe, 0xde, 0x2e, 0x7b, 0x86, 0x21, 0xba, 0x32, 0x3a, 0x67, 0xb8, 0x7c,
+ 0x91, 0x73, 0x73, 0x1f, 0xb5, 0x4a, 0x9b, 0xc3, 0x28, 0x36, 0xe0, 0x2b,
+ 0x32, 0xd0, 0x96, 0x1c, 0x2d, 0xb6, 0x4a, 0xa2, 0x3f, 0xbe, 0xbb, 0x77,
+ 0xd4, 0x8b, 0xe2, 0x51, 0x03, 0x45, 0xa3, 0x4f, 0xbb, 0x51, 0xd6, 0x80,
+ 0x5d, 0x63, 0x0f, 0xb9, 0x73, 0x63, 0x5b, 0x32, 0x39, 0x46, 0xc7, 0xf6,
+ 0xbd, 0xef, 0x26, 0xce, 0xdb, 0x05, 0x46, 0xd1, 0x7d, 0xae, 0xa8, 0xa1,
+ 0x1f, 0x02, 0xce, 0xaf, 0x69, 0x5e, 0x84, 0x6e, 0x4d, 0xc1, 0x4c, 0xe3,
+ 0x95, 0x12, 0x94, 0x45, 0x60, 0x8d, 0x55, 0xc5, 0x0b, 0xa2, 0xfe, 0x38,
+ 0xe7, 0x06, 0x2f, 0x27, 0xd2, 0xf0, 0xf4, 0xda, 0xb6, 0x94, 0x7d, 0x07,
+ 0x77, 0xdf, 0xad, 0x46, 0x8f, 0xde, 0xec, 0x41, 0x0b, 0xcb, 0x63, 0xd3,
+ 0x89, 0xe6, 0x4f, 0x15, 0x75, 0x77, 0x1b, 0xac, 0x11, 0x17, 0x62, 0x5a,
+ 0x9c, 0xdf, 0xd7, 0x5f, 0xbf, 0x3c, 0xd2, 0x86, 0xc4, 0xc8, 0x05, 0xde,
+ 0x77, 0xf3, 0x5e, 0x04, 0xc9, 0xd4, 0xf5, 0xd7, 0xdf, 0x11, 0x89, 0xa3,
+ 0x77, 0x44, 0xae, 0xdd, 0x18, 0xaf, 0x88, 0x63, 0xfb, 0x5e, 0x1d, 0xe5,
+ 0x46, 0x1b, 0x52, 0x23, 0x72, 0x6d, 0xdb, 0x67, 0xcc, 0xef, 0x62, 0x5f,
+ 0x03, 0xfd, 0xff, 0x9a, 0x36, 0x6c, 0xdb, 0x6b, 0xa1, 0xd0, 0xb0, 0xa8,
+ 0x7b, 0xc5, 0xfd, 0xf7, 0x0d, 0x0a, 0xf4, 0xbb, 0xe1, 0x2e, 0x30, 0x44,
+ 0x6f, 0x11, 0xf7, 0xfa, 0x44, 0x54, 0x9b, 0x69, 0xd8, 0xf6, 0x90, 0x39,
+ 0x07, 0x0f, 0xb4, 0xad, 0x81, 0x75, 0xc0, 0x07, 0x6b, 0x95, 0x7c, 0xb7,
+ 0x51, 0x87, 0x6b, 0xd0, 0x7d, 0x60, 0x0d, 0x7a, 0x9e, 0xa0, 0xe3, 0x56,
+ 0x68, 0xce, 0x3c, 0xfd, 0x64, 0xb6, 0xc8, 0x24, 0xf2, 0xb5, 0xf3, 0x23,
+ 0xba, 0xfd, 0x4b, 0x7e, 0x4b, 0x99, 0x0b, 0x36, 0xa6, 0x5f, 0x2e, 0xb3,
+ 0x9d, 0x65, 0xb6, 0x5d, 0x51, 0x26, 0x82, 0xa7, 0xc6, 0x44, 0x17, 0xa2,
+ 0xb2, 0x3f, 0xa5, 0x8b, 0x9f, 0xda, 0xdd, 0x7e, 0xd1, 0x85, 0xd5, 0xee,
+ 0x41, 0xb0, 0xed, 0x41, 0xc5, 0x8d, 0xa5, 0xbd, 0x60, 0x1d, 0x3a, 0x41,
+ 0x71, 0x30, 0x56, 0xab, 0x44, 0x51, 0xdc, 0xab, 0x60, 0x69, 0xb8, 0x08,
+ 0x7a, 0x85, 0xb4, 0xf7, 0x4b, 0xdb, 0xd2, 0x44, 0xde, 0x13, 0x28, 0xe1,
+ 0xfd, 0x75, 0xe1, 0x9f, 0x13, 0xcf, 0x44, 0xa6, 0x30, 0xcb, 0xaf, 0xe0,
+ 0xfd, 0x37, 0xa6, 0xfc, 0x96, 0x72, 0xb6, 0xbd, 0x99, 0x3e, 0xdf, 0x43,
+ 0x1b, 0xdf, 0x9e, 0x8a, 0x05, 0xa9, 0x25, 0xcb, 0x13, 0xe5, 0xfd, 0x68,
+ 0xa8, 0xb5, 0x1b, 0xd2, 0x0f, 0x94, 0xe2, 0x28, 0xdc, 0x99, 0xe6, 0x09,
+ 0xef, 0xa9, 0x84, 0xd1, 0xfe, 0x8c, 0xe2, 0xa1, 0xb1, 0x4b, 0x3f, 0x13,
+ 0xde, 0x37, 0x12, 0x0a, 0xde, 0x37, 0x42, 0x1d, 0x67, 0x95, 0x09, 0xef,
+ 0xeb, 0x19, 0x0d, 0x33, 0x7a, 0x83, 0xed, 0x96, 0x12, 0xc1, 0x8f, 0x32,
+ 0x7e, 0x04, 0x7a, 0xa3, 0x38, 0x92, 0x31, 0xf1, 0xf4, 0x15, 0x38, 0xf0,
+ 0xa5, 0x7f, 0x96, 0x8b, 0x63, 0x5f, 0x97, 0xd0, 0xd1, 0x6d, 0x5e, 0xb4,
+ 0x63, 0x1a, 0xe2, 0xe5, 0xd1, 0x09, 0xef, 0x27, 0xbd, 0x50, 0xca, 0xa2,
+ 0x46, 0x20, 0xab, 0xfc, 0x83, 0x1d, 0xf7, 0x4b, 0x31, 0xca, 0xe7, 0x60,
+ 0x59, 0x94, 0x76, 0x47, 0x8c, 0x4a, 0x9d, 0xb7, 0x4b, 0x68, 0xb3, 0x05,
+ 0xd1, 0x6b, 0x31, 0x32, 0x68, 0xe0, 0xe9, 0x84, 0x6d, 0x7f, 0x6c, 0x8e,
+ 0x47, 0x7c, 0x30, 0xda, 0x3e, 0x42, 0x30, 0x36, 0x87, 0x7a, 0x39, 0x91,
+ 0x31, 0x30, 0x9c, 0x88, 0xe2, 0xc5, 0x44, 0x8d, 0xb6, 0x19, 0x4d, 0x88,
+ 0x05, 0x72, 0x31, 0x64, 0x94, 0x72, 0x0f, 0x85, 0xda, 0x50, 0x1e, 0x8d,
+ 0xe0, 0x28, 0xe5, 0x3e, 0x37, 0x57, 0xda, 0x31, 0xf1, 0xfa, 0xbf, 0x42,
+ 0x56, 0xe2, 0x3b, 0x9e, 0xa4, 0xac, 0x91, 0xa6, 0x8b, 0x36, 0xa6, 0x79,
+ 0x71, 0xda, 0xbc, 0x86, 0x76, 0x08, 0xab, 0x28, 0xea, 0x75, 0xf7, 0x24,
+ 0x34, 0x1c, 0xce, 0xf8, 0xdc, 0x9b, 0x13, 0x7e, 0x1c, 0xa0, 0xbf, 0xcd,
+ 0x88, 0xc2, 0x0a, 0xb0, 0xdd, 0x19, 0xc4, 0xb5, 0xec, 0x60, 0x35, 0xc6,
+ 0x06, 0x83, 0xe6, 0x1b, 0x4a, 0x00, 0x87, 0x86, 0xaf, 0xc5, 0xe8, 0xa0,
+ 0x82, 0x91, 0x10, 0x65, 0xe7, 0xf5, 0xf7, 0x06, 0xaf, 0x47, 0x66, 0xd0,
+ 0x85, 0x5d, 0x8e, 0x5e, 0x1d, 0x9c, 0x99, 0xfc, 0xbe, 0x16, 0xe9, 0x61,
+ 0xb8, 0xe7, 0xf4, 0x6a, 0x78, 0x26, 0xe3, 0x76, 0x1b, 0xbd, 0x7e, 0x0c,
+ 0x67, 0x7e, 0xca, 0x79, 0x93, 0xb6, 0x75, 0x0c, 0x25, 0x0e, 0x39, 0x73,
+ 0x58, 0x1e, 0x65, 0x63, 0xb9, 0xf8, 0xca, 0x58, 0xa6, 0x33, 0xce, 0x34,
+ 0x13, 0x87, 0xc4, 0xc7, 0xbd, 0xc4, 0x20, 0xf1, 0xf1, 0xb7, 0x14, 0x94,
+ 0x35, 0x63, 0xf3, 0x58, 0xfe, 0xb9, 0x42, 0xfb, 0x77, 0x63, 0x9d, 0xd6,
+ 0x80, 0x44, 0x4a, 0xec, 0x34, 0x8f, 0xcb, 0x72, 0x2d, 0xf3, 0x5f, 0x0c,
+ 0xeb, 0x60, 0x31, 0x76, 0xd1, 0xc7, 0x76, 0xee, 0x96, 0xfb, 0xb6, 0xfd,
+ 0x50, 0xb8, 0x9c, 0x36, 0x86, 0xc5, 0x45, 0x08, 0x99, 0x1f, 0x38, 0xb2,
+ 0x59, 0x38, 0x94, 0x91, 0x18, 0xaa, 0x33, 0xbe, 0x9d, 0x60, 0x5f, 0xcd,
+ 0xec, 0xc7, 0xc4, 0x4f, 0x39, 0x37, 0x7f, 0x3d, 0x56, 0x87, 0x1f, 0x8e,
+ 0x19, 0xf8, 0xef, 0x63, 0x3a, 0x9e, 0xbf, 0x02, 0xd7, 0xef, 0xa6, 0xae,
+ 0x04, 0xc3, 0x1a, 0xb0, 0x25, 0x55, 0x80, 0x6d, 0x83, 0xc5, 0xd8, 0x3c,
+ 0x58, 0x53, 0xf7, 0x22, 0xf1, 0xf8, 0x87, 0xe6, 0x1d, 0x18, 0xaf, 0x6c,
+ 0x76, 0x7c, 0x66, 0x07, 0xef, 0xef, 0x1c, 0xac, 0xe1, 0x1c, 0xda, 0xb6,
+ 0x1a, 0xae, 0x8f, 0x1c, 0x25, 0xbe, 0x4f, 0xf8, 0x83, 0xfa, 0xb8, 0x1a,
+ 0xd4, 0x63, 0xf0, 0x20, 0xd1, 0xa0, 0xc2, 0x9a, 0x1e, 0x4c, 0xd3, 0x8b,
+ 0xe1, 0x37, 0x1e, 0xe2, 0xd8, 0x82, 0xba, 0xa5, 0x36, 0xd0, 0x7e, 0x19,
+ 0x33, 0x54, 0x93, 0xf8, 0x52, 0x8c, 0x4f, 0x06, 0x83, 0x3d, 0x96, 0xba,
+ 0x02, 0x56, 0xa5, 0x6d, 0x7f, 0x3f, 0x8c, 0x8e, 0x6b, 0xa2, 0x88, 0x4d,
+ 0x67, 0x2c, 0xb8, 0x3e, 0x1a, 0x05, 0xe3, 0x18, 0xce, 0xf5, 0x1a, 0x81,
+ 0xbf, 0x53, 0xee, 0xc6, 0x7f, 0x6c, 0x0b, 0xea, 0xba, 0x5a, 0x6f, 0x1d,
+ 0x50, 0x49, 0x36, 0xaa, 0xa0, 0x07, 0xa2, 0xcb, 0xd0, 0xe9, 0xf0, 0x04,
+ 0x05, 0x9a, 0x61, 0x62, 0x73, 0x8a, 0x95, 0xfc, 0x35, 0xed, 0xfd, 0x6a,
+ 0xcd, 0x05, 0x53, 0x0d, 0x9e, 0x68, 0x53, 0x89, 0xb7, 0x4d, 0xe7, 0x6c,
+ 0xbd, 0xca, 0xb6, 0x1b, 0x9b, 0xa4, 0x4f, 0x1d, 0x95, 0x9c, 0xe7, 0x0a,
+ 0xce, 0x73, 0x63, 0xb6, 0x18, 0x67, 0x07, 0x61, 0x5d, 0x13, 0x0d, 0xb6,
+ 0x3e, 0xa2, 0x16, 0xe3, 0xc3, 0xe1, 0x62, 0xbc, 0x33, 0xe8, 0xc6, 0x07,
+ 0x83, 0xb6, 0xbd, 0xde, 0x2c, 0x47, 0x41, 0x18, 0xd3, 0x0b, 0x10, 0x3a,
+ 0x3f, 0x04, 0x0b, 0x5f, 0xb0, 0xec, 0xef, 0x06, 0x03, 0xf8, 0xc7, 0xc1,
+ 0xaf, 0xe2, 0xf9, 0xca, 0xd8, 0xc9, 0x69, 0x8c, 0x91, 0x17, 0x68, 0x3f,
+ 0xe7, 0x12, 0xc1, 0xf6, 0x19, 0xae, 0x60, 0x27, 0x79, 0xcb, 0x86, 0xc7,
+ 0x94, 0x60, 0xfc, 0x0d, 0x25, 0xa8, 0xf7, 0x2a, 0x7e, 0x7c, 0x44, 0x3b,
+ 0x3d, 0x93, 0xa9, 0x89, 0xfc, 0x9c, 0xfd, 0xff, 0xde, 0xfc, 0xa1, 0x3d,
+ 0x5e, 0x25, 0x3a, 0x14, 0x7d, 0x51, 0xe7, 0x29, 0xea, 0x9c, 0xfe, 0xfb,
+ 0xc3, 0x14, 0x75, 0x4e, 0x79, 0x9e, 0xff, 0x83, 0xf8, 0x25, 0xf3, 0x15,
+ 0xe1, 0x3c, 0x5e, 0x87, 0xff, 0xe2, 0x8c, 0xed, 0xa4, 0xfd, 0x9f, 0xfc,
+ 0x32, 0xbe, 0xcf, 0xfd, 0x39, 0x0c, 0x92, 0x71, 0x9e, 0xb0, 0xe3, 0x9a,
+ 0x8c, 0x51, 0xc6, 0xea, 0xe8, 0x52, 0xef, 0x50, 0x1e, 0x55, 0x51, 0x6c,
+ 0xdb, 0x4f, 0x98, 0x93, 0xcf, 0xfd, 0xf9, 0xb1, 0x7e, 0x95, 0xf7, 0x65,
+ 0xbc, 0x67, 0x5d, 0xa2, 0x7b, 0x5d, 0xbd, 0x89, 0xbf, 0x83, 0x56, 0x0c,
+ 0xa7, 0x0b, 0xf9, 0xbb, 0x2e, 0x76, 0xe9, 0xf7, 0x93, 0xa5, 0x57, 0x3e,
+ 0xa7, 0x9d, 0x3a, 0xfd, 0xdd, 0xcd, 0xdf, 0x32, 0x96, 0x37, 0x69, 0x37,
+ 0x5f, 0x66, 0x27, 0x62, 0x23, 0x75, 0xb4, 0xa7, 0x33, 0x12, 0x57, 0x2c,
+ 0x7f, 0xd4, 0x6b, 0xa9, 0x51, 0xe8, 0x74, 0x7d, 0xaf, 0x12, 0xed, 0x80,
+ 0x9e, 0xb1, 0x70, 0x4f, 0xb3, 0x0b, 0xdf, 0x6a, 0x56, 0x30, 0xcd, 0xe8,
+ 0x40, 0xdf, 0x3c, 0xcb, 0xae, 0x30, 0xf6, 0xab, 0xe2, 0x03, 0x05, 0x49,
+ 0x58, 0xf4, 0x3b, 0x44, 0xc8, 0x95, 0xca, 0xff, 0x9d, 0x82, 0xd3, 0xe1,
+ 0x10, 0x6d, 0x6e, 0x0b, 0x39, 0x15, 0x50, 0x98, 0x84, 0xb7, 0x94, 0xf3,
+ 0x3f, 0xda, 0x0b, 0x6f, 0x31, 0x7d, 0x7f, 0x59, 0x6f, 0x4d, 0xc7, 0x7b,
+ 0xc4, 0x8a, 0xac, 0x12, 0x6c, 0xa7, 0xbe, 0xcd, 0x32, 0x25, 0xd8, 0x7a,
+ 0x3b, 0xf5, 0x5d, 0xab, 0x48, 0x3f, 0x51, 0xd4, 0x65, 0xb6, 0x10, 0x73,
+ 0xe4, 0x3a, 0x02, 0x23, 0xf3, 0xab, 0x49, 0xd9, 0xe1, 0xf5, 0x50, 0x86,
+ 0x83, 0x89, 0x77, 0xed, 0xb4, 0x16, 0xd4, 0xd3, 0xce, 0xef, 0x0d, 0xfc,
+ 0x0d, 0x6f, 0x41, 0x74, 0x23, 0x5e, 0x4a, 0x3c, 0xe5, 0xcf, 0x97, 0xcb,
+ 0xc9, 0x7a, 0xb5, 0x3c, 0xff, 0xd3, 0x8e, 0xf9, 0x73, 0xf2, 0xf8, 0x92,
+ 0x5b, 0x40, 0x8e, 0xe2, 0x2d, 0x64, 0x5f, 0xef, 0x3b, 0xf5, 0x23, 0xac,
+ 0x5f, 0xd3, 0xde, 0xab, 0x04, 0xeb, 0x3e, 0x42, 0xbd, 0xfe, 0x3d, 0x04,
+ 0x5b, 0x8f, 0x92, 0x5b, 0x1a, 0x93, 0xf2, 0x84, 0x32, 0x0e, 0x9f, 0x71,
+ 0xe4, 0x99, 0x95, 0x81, 0xe2, 0xea, 0x85, 0x6f, 0xa6, 0x51, 0x8b, 0x2e,
+ 0x67, 0x4e, 0xa1, 0x04, 0x7a, 0x75, 0x94, 0x91, 0xbf, 0x04, 0x46, 0x81,
+ 0xb1, 0x01, 0x72, 0xb9, 0x70, 0x0d, 0xbe, 0xc9, 0x58, 0x30, 0x83, 0x65,
+ 0x1e, 0xd3, 0x2e, 0xe1, 0x97, 0xd2, 0x93, 0x20, 0xc0, 0x4c, 0xcf, 0xf1,
+ 0xb2, 0xf8, 0xbd, 0x88, 0xc9, 0xbd, 0x27, 0x13, 0x50, 0x52, 0x89, 0xe0,
+ 0x3e, 0xc0, 0x18, 0x0f, 0xbb, 0x62, 0x0f, 0x07, 0xd0, 0x85, 0x73, 0xe1,
+ 0x50, 0x3c, 0xab, 0x84, 0xda, 0x07, 0x14, 0xd3, 0xbb, 0x8b, 0xfd, 0x6d,
+ 0x67, 0x99, 0x1d, 0xfc, 0x9c, 0x35, 0x0c, 0x73, 0x85, 0x12, 0xbb, 0xa1,
+ 0x80, 0x65, 0x6a, 0xc2, 0x21, 0xf2, 0xcc, 0xd0, 0x85, 0x95, 0x30, 0xbd,
+ 0x4f, 0x65, 0xa4, 0xad, 0x88, 0xb2, 0x25, 0xfb, 0xa4, 0x9a, 0xc3, 0xa3,
+ 0xdf, 0x4f, 0xea, 0xec, 0x1d, 0xf9, 0xed, 0xf4, 0xed, 0xee, 0xfd, 0xaf,
+ 0x85, 0x7f, 0x78, 0xef, 0xaf, 0xa7, 0x5d, 0x79, 0xaf, 0x5e, 0x1b, 0xa6,
+ 0xff, 0xb9, 0x8c, 0x22, 0xce, 0x9d, 0xf0, 0xa3, 0x58, 0x9d, 0x07, 0x72,
+ 0xcf, 0x85, 0xb4, 0x3b, 0x16, 0x70, 0xe1, 0x73, 0x3b, 0xb6, 0x4a, 0xee,
+ 0x15, 0x23, 0xde, 0x56, 0x1f, 0x70, 0xa3, 0x3e, 0xb2, 0x95, 0x58, 0x30,
+ 0xb1, 0x6a, 0x21, 0x9f, 0x85, 0xcc, 0x17, 0x51, 0xa3, 0x6f, 0x85, 0x5c,
+ 0x7f, 0x46, 0x9b, 0x5d, 0x28, 0x75, 0x59, 0x26, 0xc7, 0x7d, 0x04, 0x6b,
+ 0xb6, 0x98, 0x36, 0x5e, 0x22, 0x4c, 0x14, 0x46, 0x8f, 0x28, 0xa7, 0x13,
+ 0x5f, 0xd8, 0x31, 0x37, 0x96, 0xd3, 0x2f, 0x4d, 0xea, 0x59, 0xf7, 0x46,
+ 0x43, 0xfa, 0x09, 0x66, 0x0a, 0xae, 0xa8, 0xa5, 0x4c, 0x64, 0xb6, 0x28,
+ 0xef, 0x66, 0x7a, 0x94, 0x33, 0x19, 0xa9, 0x7b, 0x44, 0x79, 0x27, 0x23,
+ 0xf1, 0xb0, 0x5a, 0x3f, 0x4e, 0x7e, 0x43, 0x4e, 0xa5, 0x6e, 0x36, 0xa1,
+ 0x6c, 0x33, 0xcb, 0xc8, 0xf3, 0x8d, 0xba, 0x21, 0xca, 0x7b, 0xb0, 0x19,
+ 0xe6, 0x76, 0xd3, 0x83, 0x09, 0x0d, 0xbe, 0xcd, 0xa6, 0x5b, 0x7e, 0x33,
+ 0x1f, 0x90, 0xba, 0xd5, 0xfa, 0xd6, 0xcc, 0x45, 0xfa, 0x57, 0xee, 0xf7,
+ 0xc1, 0xe6, 0xfc, 0xbd, 0xdf, 0xda, 0xe3, 0xab, 0x54, 0xfe, 0xfe, 0x77,
+ 0x2e, 0x0e, 0x85, 0x75, 0xa7, 0xf2, 0x73, 0xe1, 0x52, 0x2a, 0xf9, 0x63,
+ 0x05, 0x2c, 0x2d, 0x68, 0xa5, 0x99, 0x0e, 0x6d, 0x4e, 0x35, 0xd2, 0xdf,
+ 0x02, 0x8c, 0x95, 0x51, 0xe2, 0x3b, 0x79, 0x2f, 0xfb, 0x2c, 0x30, 0x7c,
+ 0x58, 0x9c, 0xa8, 0x71, 0xe5, 0xf4, 0xa7, 0x12, 0xc3, 0x5c, 0x8c, 0xe9,
+ 0xc2, 0xf1, 0xae, 0xe6, 0xdc, 0xd5, 0xfa, 0x07, 0x94, 0xbb, 0xc8, 0x30,
+ 0xea, 0x8a, 0x94, 0x6a, 0xfd, 0xdd, 0x4c, 0x94, 0x3e, 0xde, 0xce, 0x7e,
+ 0x7d, 0x78, 0x37, 0x51, 0xc6, 0x1c, 0x24, 0x18, 0xb3, 0xd8, 0xe0, 0x92,
+ 0xe6, 0x00, 0xc8, 0xf9, 0xa6, 0xfc, 0xb5, 0x81, 0xf1, 0x5f, 0x62, 0xb4,
+ 0x7a, 0xdb, 0xdc, 0x08, 0x36, 0x64, 0xe0, 0x5e, 0xd7, 0x1c, 0xc5, 0x7a,
+ 0xc6, 0xf6, 0x87, 0x18, 0x2f, 0x37, 0x32, 0x16, 0xee, 0x0a, 0x73, 0x6c,
+ 0x15, 0xb6, 0x5d, 0x68, 0x74, 0x49, 0x3e, 0x83, 0x5e, 0xc6, 0xe2, 0xb5,
+ 0x8c, 0x2f, 0x5b, 0x78, 0x7d, 0x2a, 0xf3, 0xcf, 0xf6, 0x43, 0xcc, 0xa7,
+ 0x5e, 0xba, 0xa2, 0x4d, 0xa8, 0xc3, 0x46, 0x7d, 0xdd, 0x56, 0xc6, 0x62,
+ 0xb6, 0x6b, 0x95, 0x45, 0x6d, 0xfb, 0x86, 0x50, 0x30, 0xe6, 0x51, 0x4c,
+ 0xbc, 0x38, 0x3a, 0x61, 0xeb, 0xd3, 0x25, 0x97, 0xca, 0xc7, 0x41, 0x19,
+ 0xab, 0xe4, 0x08, 0x82, 0x0f, 0x92, 0x27, 0x4c, 0xc5, 0x08, 0x15, 0x4b,
+ 0x06, 0x25, 0x4f, 0x08, 0x60, 0x65, 0xe2, 0xbb, 0x78, 0xb1, 0xc1, 0x8d,
+ 0x56, 0xe6, 0x58, 0xb7, 0x25, 0x7c, 0x58, 0x41, 0x2c, 0x5d, 0x9a, 0x60,
+ 0xee, 0xa4, 0xf9, 0xb1, 0x2c, 0xe1, 0xc6, 0xb1, 0x06, 0xe6, 0x40, 0xfe,
+ 0x42, 0x7c, 0x64, 0xba, 0x70, 0xdc, 0xd4, 0x90, 0x76, 0xfc, 0x61, 0x17,
+ 0x31, 0x90, 0x7a, 0x54, 0x25, 0x77, 0x10, 0x1d, 0xba, 0xa8, 0x4f, 0x15,
+ 0xf1, 0x4b, 0x3a, 0xfc, 0xb2, 0x5c, 0x40, 0xe4, 0x92, 0x7c, 0xe0, 0x37,
+ 0x76, 0x7c, 0xba, 0xd4, 0x87, 0xe5, 0x8b, 0xca, 0x38, 0x84, 0xdf, 0x12,
+ 0x27, 0x47, 0x4d, 0x72, 0xbb, 0xa9, 0x43, 0x3d, 0x4f, 0x6e, 0x5d, 0x8e,
+ 0xb7, 0x0c, 0xe1, 0xd6, 0x6f, 0x42, 0xa3, 0xef, 0xf6, 0x8c, 0x86, 0x3a,
+ 0xce, 0x2b, 0x2e, 0x9c, 0x32, 0xca, 0xc8, 0xfb, 0x38, 0x0f, 0xa3, 0x70,
+ 0x6f, 0x9d, 0x6b, 0x22, 0x39, 0xda, 0x1d, 0x29, 0xe5, 0x78, 0xdd, 0x73,
+ 0x73, 0x9c, 0xe8, 0xeb, 0xd4, 0xed, 0x9a, 0xb0, 0xc3, 0x89, 0x72, 0x7c,
+ 0x40, 0xb3, 0xed, 0x77, 0x0c, 0xd1, 0x33, 0x70, 0x78, 0x52, 0xc7, 0x07,
+ 0x79, 0xdd, 0x33, 0xa9, 0xe3, 0x2d, 0x6c, 0x8f, 0xfe, 0x87, 0x6d, 0x57,
+ 0xf0, 0x18, 0x1d, 0xcc, 0x29, 0xc9, 0x6f, 0x88, 0xc3, 0xc4, 0x95, 0x18,
+ 0x75, 0xfc, 0x72, 0x66, 0x83, 0xe0, 0x36, 0xa7, 0xbb, 0xd1, 0xc1, 0xef,
+ 0x98, 0x7a, 0x98, 0x76, 0x20, 0x7a, 0x78, 0x6b, 0x32, 0xb7, 0xb1, 0xed,
+ 0x01, 0x53, 0x74, 0x9c, 0xcf, 0xcb, 0x44, 0xd7, 0x37, 0x4a, 0x8e, 0xd5,
+ 0x03, 0x7c, 0xc1, 0xb2, 0x2e, 0xe2, 0xee, 0x42, 0xfc, 0xa0, 0x4d, 0x6c,
+ 0xa7, 0xd4, 0x89, 0x95, 0xf3, 0x6b, 0x6d, 0x3b, 0xdc, 0xa4, 0xe3, 0x82,
+ 0x51, 0x1f, 0x69, 0x54, 0x67, 0x51, 0xd6, 0x28, 0xf6, 0x91, 0x0f, 0x74,
+ 0xa7, 0x66, 0x22, 0xe6, 0x17, 0x5b, 0x43, 0x47, 0x41, 0x0e, 0xc3, 0x71,
+ 0x26, 0x61, 0xd4, 0x6d, 0xc3, 0x0c, 0x1c, 0xf0, 0xb7, 0x90, 0xc7, 0xa9,
+ 0x2d, 0x4c, 0xff, 0xc9, 0x9f, 0x0c, 0x6b, 0x07, 0xce, 0xda, 0x69, 0xbf,
+ 0xcd, 0x38, 0x49, 0x18, 0xa0, 0x2e, 0x5f, 0xd1, 0x5c, 0x78, 0xb5, 0xee,
+ 0x9a, 0x49, 0xbe, 0x29, 0x9c, 0xe5, 0x3d, 0xfb, 0x98, 0x5f, 0xfa, 0x62,
+ 0x9e, 0xa7, 0x2e, 0x73, 0x49, 0x1e, 0xe8, 0x36, 0xa4, 0x6d, 0xe6, 0x0b,
+ 0x63, 0x57, 0xcb, 0x30, 0x61, 0x4f, 0xf8, 0x45, 0x86, 0xa0, 0xa6, 0xab,
+ 0x7f, 0x6c, 0x1e, 0xaf, 0xc3, 0xcf, 0x35, 0x37, 0x7c, 0xe4, 0xc5, 0xaf,
+ 0xf9, 0x73, 0x6d, 0xf4, 0x9a, 0xe3, 0x33, 0x4a, 0x1d, 0xac, 0x3c, 0xa2,
+ 0x24, 0x89, 0x0f, 0xe3, 0x1e, 0x68, 0xe5, 0x51, 0xb7, 0xae, 0x11, 0x13,
+ 0x36, 0x13, 0x13, 0x2c, 0x62, 0x42, 0x5f, 0xe6, 0x88, 0x92, 0xca, 0x7c,
+ 0x46, 0x5d, 0x48, 0x1d, 0xb1, 0x9d, 0x2d, 0x94, 0xe5, 0x27, 0x36, 0xaa,
+ 0x44, 0x9e, 0x0b, 0xbc, 0xdf, 0x42, 0x1e, 0x92, 0x97, 0x53, 0x7c, 0x95,
+ 0x10, 0x54, 0x2c, 0xcf, 0x52, 0xb9, 0xdf, 0xaa, 0x5c, 0xcf, 0x70, 0x4b,
+ 0xb9, 0xee, 0xb1, 0xa3, 0x4b, 0xdd, 0x58, 0x80, 0xd9, 0xe1, 0x85, 0x8b,
+ 0x44, 0x17, 0x6a, 0x34, 0xa6, 0x7b, 0x61, 0x55, 0xb9, 0x88, 0xe5, 0xef,
+ 0x35, 0x34, 0x60, 0x11, 0x73, 0xce, 0xb3, 0x04, 0xa7, 0x6e, 0xc3, 0x85,
+ 0x71, 0xea, 0xe7, 0x69, 0x53, 0xd6, 0x1b, 0x6c, 0xdc, 0x16, 0xb6, 0xe2,
+ 0xf4, 0x78, 0xab, 0x94, 0xb6, 0x57, 0x6c, 0x08, 0x4f, 0x28, 0x43, 0x49,
+ 0xd4, 0x5d, 0x77, 0x16, 0x41, 0x73, 0x17, 0x79, 0x92, 0x5e, 0x31, 0x3b,
+ 0xe2, 0xa1, 0xe6, 0x5e, 0x4f, 0x84, 0x22, 0xc7, 0x95, 0x9c, 0x3f, 0xbd,
+ 0x4c, 0xdb, 0x78, 0x2b, 0x61, 0x74, 0x16, 0xba, 0x72, 0xbf, 0xdf, 0x70,
+ 0xf2, 0xd9, 0xbc, 0x3f, 0x05, 0x26, 0x71, 0xc7, 0xeb, 0x3d, 0x93, 0xc0,
+ 0x79, 0xb5, 0x59, 0xf2, 0x5a, 0x9c, 0xdf, 0x6c, 0x8e, 0x2b, 0x1e, 0xa3,
+ 0x8c, 0xfa, 0x10, 0x2c, 0x2e, 0x20, 0xa7, 0x14, 0xee, 0xe0, 0xf5, 0x9e,
+ 0x65, 0x19, 0x72, 0xc2, 0x89, 0xba, 0xf9, 0xf5, 0x11, 0x2f, 0x62, 0x56,
+ 0x21, 0xfd, 0xba, 0x34, 0xea, 0xf7, 0xde, 0x98, 0xb5, 0xaa, 0x7c, 0xf4,
+ 0x8b, 0x12, 0xe6, 0xbb, 0xb3, 0x93, 0x0b, 0xcb, 0x24, 0x57, 0xdc, 0x38,
+ 0xca, 0x91, 0x55, 0xf6, 0x57, 0xa9, 0x51, 0x59, 0xc3, 0xd0, 0xe0, 0xa9,
+ 0xdc, 0x78, 0x8b, 0x1a, 0x9d, 0x40, 0x7b, 0xb3, 0xb7, 0x25, 0x92, 0x85,
+ 0xb7, 0x22, 0xba, 0x09, 0xe1, 0xa4, 0xe4, 0xad, 0x82, 0xb1, 0xb1, 0xad,
+ 0x44, 0xbd, 0xaa, 0xf2, 0x79, 0xf9, 0xb9, 0x82, 0x5a, 0x16, 0x95, 0xfc,
+ 0x55, 0x6f, 0x79, 0xc3, 0xc1, 0x62, 0x8d, 0xf9, 0xc6, 0xaf, 0x02, 0xff,
+ 0x77, 0xf5, 0x5b, 0xdd, 0x32, 0x77, 0x1e, 0x43, 0xbe, 0x65, 0xdd, 0x00,
+ 0x6e, 0x95, 0x58, 0xda, 0x3d, 0xe2, 0x66, 0x7e, 0x26, 0xf3, 0x25, 0xf1,
+ 0xf8, 0xc8, 0xbd, 0x2f, 0xd1, 0xdf, 0x3c, 0xd4, 0xfd, 0x0e, 0xc3, 0x62,
+ 0x98, 0xb0, 0x6d, 0x23, 0x1c, 0x0c, 0x14, 0x28, 0x3a, 0xb6, 0x37, 0xfc,
+ 0x13, 0xed, 0x0b, 0xc4, 0x41, 0x90, 0x98, 0x97, 0x61, 0xcb, 0x48, 0xc1,
+ 0x94, 0x7a, 0x91, 0xfb, 0xf2, 0xf5, 0x7a, 0x0d, 0x2b, 0x2e, 0xf5, 0x86,
+ 0xc3, 0xc1, 0xf6, 0x6d, 0xac, 0xb7, 0x93, 0xf5, 0x62, 0x8c, 0xbd, 0xeb,
+ 0x47, 0x35, 0x27, 0x1f, 0xb4, 0x46, 0x8a, 0xa7, 0xf6, 0x77, 0xa9, 0xde,
+ 0x93, 0x86, 0x35, 0xee, 0xf4, 0xd7, 0x14, 0xec, 0x2c, 0x70, 0xb9, 0x91,
+ 0x64, 0xbd, 0x71, 0xd6, 0x7b, 0x77, 0x54, 0xd6, 0x33, 0x70, 0xcb, 0x48,
+ 0x22, 0x35, 0xe1, 0x32, 0x0c, 0xed, 0x1d, 0xc4, 0x88, 0xd9, 0xce, 0x5c,
+ 0xde, 0x72, 0x28, 0xd3, 0x85, 0xed, 0xc6, 0xd1, 0x70, 0x21, 0xeb, 0x1d,
+ 0x37, 0x8e, 0x06, 0x3c, 0xf4, 0x99, 0x75, 0x6c, 0xaf, 0x9b, 0x79, 0x91,
+ 0x4a, 0x8c, 0xdc, 0x32, 0x22, 0xdc, 0xc1, 0xc4, 0x6c, 0xe6, 0x67, 0x8e,
+ 0x6d, 0xca, 0xda, 0x09, 0x64, 0x4e, 0x65, 0x7c, 0xc1, 0xba, 0x11, 0x67,
+ 0x7c, 0xca, 0x35, 0x87, 0x25, 0x57, 0xae, 0xb0, 0xb0, 0xb9, 0x41, 0xe2,
+ 0xa7, 0x42, 0xec, 0x0e, 0xd6, 0x8d, 0x33, 0x9e, 0x6c, 0x1b, 0xfb, 0x33,
+ 0x8c, 0x6b, 0x95, 0xcc, 0x65, 0x6d, 0xfb, 0x15, 0x63, 0x61, 0x05, 0x43,
+ 0xbc, 0xd7, 0x4b, 0x99, 0xbd, 0xa1, 0x62, 0x89, 0xd3, 0x4e, 0x5b, 0x31,
+ 0x08, 0x3e, 0x29, 0x48, 0x1a, 0xd6, 0x06, 0x91, 0xff, 0x58, 0x38, 0x18,
+ 0x3f, 0xac, 0xd4, 0xb7, 0x6f, 0xc3, 0x3f, 0x11, 0x2f, 0x41, 0xac, 0x9b,
+ 0x89, 0x21, 0x93, 0xd6, 0xd2, 0x66, 0x31, 0x42, 0x4a, 0x8c, 0x77, 0x9f,
+ 0x58, 0xc4, 0x08, 0xe7, 0x46, 0xb0, 0xb3, 0x95, 0xe5, 0x23, 0xb9, 0x75,
+ 0x16, 0x5c, 0x18, 0x0d, 0x32, 0x0e, 0x8b, 0x2e, 0x80, 0xad, 0x99, 0x7c,
+ 0x2c, 0xb0, 0xed, 0x83, 0xa6, 0x6d, 0xbf, 0x64, 0xce, 0xc4, 0x61, 0x33,
+ 0x18, 0x17, 0x1f, 0x78, 0xdf, 0x5c, 0x78, 0x83, 0xe4, 0xc5, 0x80, 0xc8,
+ 0xa6, 0x30, 0x76, 0x29, 0x28, 0xe1, 0x27, 0x10, 0x72, 0xeb, 0x25, 0x8a,
+ 0x0d, 0x6f, 0x53, 0x6d, 0x67, 0x2d, 0xf5, 0x5e, 0x36, 0x5f, 0xc1, 0x27,
+ 0x37, 0x2a, 0x38, 0x7a, 0x63, 0x28, 0x30, 0xa4, 0x94, 0x32, 0x2e, 0x84,
+ 0xda, 0x5a, 0x14, 0xeb, 0x04, 0xeb, 0xc6, 0x1a, 0x5c, 0xc1, 0x00, 0x94,
+ 0x72, 0x62, 0xd6, 0x6c, 0x5d, 0x68, 0x8b, 0xbb, 0x37, 0x14, 0xd8, 0xc9,
+ 0x6f, 0xd7, 0xa8, 0x82, 0x51, 0x23, 0x18, 0x83, 0xd3, 0x3e, 0xfb, 0x66,
+ 0xca, 0x7c, 0x53, 0xc8, 0xb6, 0x4f, 0x86, 0xeb, 0xb5, 0x93, 0x78, 0x9f,
+ 0xb8, 0x2c, 0xfd, 0xe4, 0x65, 0x03, 0xf3, 0x70, 0x23, 0xd6, 0xa2, 0xdc,
+ 0x24, 0xb4, 0x84, 0x71, 0x52, 0x62, 0x79, 0x5e, 0xde, 0x7c, 0x4c, 0xb7,
+ 0xed, 0xf7, 0xcd, 0x5c, 0x5b, 0x5a, 0x73, 0x30, 0x0e, 0xcc, 0xc4, 0x98,
+ 0x11, 0x6c, 0x1d, 0xa7, 0x1e, 0x02, 0xf4, 0xf5, 0x19, 0x46, 0x15, 0x26,
+ 0x3c, 0x41, 0x6d, 0x42, 0x59, 0xf4, 0x99, 0x8a, 0x39, 0x1b, 0x9e, 0x52,
+ 0xea, 0x3b, 0x8a, 0x60, 0x90, 0x9f, 0x5e, 0x23, 0xf3, 0x11, 0xf0, 0x91,
+ 0x0b, 0xae, 0x83, 0xc3, 0x2f, 0x70, 0x7b, 0xc2, 0x1d, 0xbb, 0x80, 0x1a,
+ 0xfa, 0x9d, 0xd1, 0xfe, 0x90, 0x12, 0x64, 0xf2, 0xf2, 0x35, 0x26, 0x38,
+ 0x22, 0x6b, 0x15, 0xe2, 0xf7, 0xd8, 0xf6, 0xc3, 0x94, 0x75, 0x17, 0x65,
+ 0xdd, 0x18, 0xfe, 0xd8, 0xfe, 0x07, 0xa7, 0xcd, 0x5b, 0x31, 0x64, 0x5c,
+ 0xdd, 0xee, 0x47, 0x36, 0xa6, 0x4b, 0xbb, 0x1e, 0x2c, 0x99, 0xce, 0x5c,
+ 0xab, 0x59, 0xf0, 0xaa, 0xd2, 0x43, 0x7c, 0x62, 0x7b, 0x8c, 0x7f, 0xea,
+ 0xd5, 0x1c, 0xc2, 0x05, 0xc6, 0xe6, 0x40, 0x5c, 0x51, 0xab, 0x4b, 0xa0,
+ 0xc1, 0x6b, 0xd8, 0x78, 0x84, 0x7c, 0x27, 0x36, 0xbd, 0x1c, 0xdf, 0xe4,
+ 0x9c, 0x96, 0x86, 0xd4, 0x6b, 0x5d, 0x9c, 0x93, 0xc3, 0x61, 0xf9, 0xed,
+ 0xc1, 0xf8, 0x74, 0x17, 0xba, 0x38, 0xcb, 0x5a, 0x48, 0x9d, 0x21, 0xf7,
+ 0xbd, 0x8d, 0xf2, 0x9b, 0xf2, 0x5f, 0xa3, 0xe0, 0x61, 0x5a, 0xa4, 0x1a,
+ 0xea, 0x0e, 0xc8, 0xfd, 0x56, 0x53, 0x7e, 0x2b, 0xe4, 0x92, 0x6e, 0xce,
+ 0x8b, 0x0d, 0x97, 0x2c, 0x4d, 0x84, 0x78, 0x3f, 0x2c, 0xd7, 0xb1, 0x87,
+ 0x39, 0xee, 0xd8, 0x01, 0x45, 0x30, 0xee, 0x97, 0xf6, 0x2b, 0x8c, 0x81,
+ 0x1a, 0x9f, 0x7f, 0x93, 0x7d, 0x9f, 0x08, 0xbf, 0x64, 0xcf, 0xa8, 0x50,
+ 0x70, 0x32, 0xa2, 0x63, 0xe6, 0x8d, 0xd5, 0x98, 0xb8, 0x5b, 0xc6, 0xac,
+ 0xa0, 0xd4, 0x38, 0xe8, 0x91, 0x1c, 0xb9, 0xcc, 0xb8, 0x06, 0x4b, 0x56,
+ 0xe4, 0xee, 0x15, 0x85, 0x64, 0x8d, 0x53, 0x47, 0xd1, 0x8d, 0x95, 0xd0,
+ 0x27, 0xef, 0x2d, 0x0a, 0xb9, 0xdb, 0x4a, 0x15, 0x43, 0xbb, 0x5d, 0x91,
+ 0xe7, 0xbf, 0x23, 0x2f, 0xb7, 0xed, 0x47, 0x38, 0x5f, 0xb3, 0xc3, 0x3e,
+ 0x9c, 0x63, 0x3f, 0xdd, 0xd4, 0xdf, 0xf2, 0x4b, 0xf3, 0x95, 0xaf, 0xff,
+ 0xa9, 0xad, 0xdf, 0x23, 0x75, 0xa5, 0x8d, 0xda, 0xd6, 0x25, 0xca, 0x03,
+ 0x1e, 0xc9, 0x91, 0x36, 0x86, 0x1d, 0x9d, 0xb1, 0xec, 0x73, 0xce, 0x6f,
+ 0xad, 0xf9, 0xad, 0x4b, 0xeb, 0x75, 0xe7, 0x9d, 0x58, 0xba, 0x70, 0xbe,
+ 0x86, 0x09, 0xbb, 0xa2, 0xd1, 0xd2, 0x0a, 0x21, 0x31, 0xb5, 0xa6, 0xee,
+ 0x39, 0xb6, 0xfb, 0x73, 0x33, 0x17, 0x6f, 0x0f, 0x9a, 0xc1, 0x3e, 0x8b,
+ 0xfe, 0x13, 0x67, 0x8e, 0xdb, 0x22, 0xbc, 0x63, 0xec, 0x16, 0xce, 0xc3,
+ 0x4c, 0x14, 0x36, 0x06, 0x7b, 0x66, 0x31, 0xe7, 0x73, 0x35, 0x4b, 0x9c,
+ 0x96, 0xf9, 0x71, 0xca, 0xb0, 0xaf, 0x22, 0x2c, 0xa2, 0x8c, 0xe1, 0xc6,
+ 0x3f, 0x15, 0xdf, 0xa4, 0x1d, 0xb1, 0xce, 0x60, 0x4f, 0x0c, 0x7f, 0xaa,
+ 0x2c, 0xc8, 0x28, 0x64, 0x2d, 0xcc, 0x7b, 0x4b, 0x3c, 0xa3, 0x92, 0x23,
+ 0x15, 0x68, 0xdd, 0xcd, 0x55, 0xfc, 0xc8, 0x73, 0xf7, 0x2d, 0x6b, 0x32,
+ 0x97, 0xd6, 0x20, 0xd1, 0x67, 0x16, 0x40, 0xbd, 0x49, 0xe2, 0x05, 0x7d,
+ 0x59, 0x93, 0xf1, 0x59, 0xb4, 0x72, 0x59, 0x5f, 0x30, 0x56, 0xad, 0x25,
+ 0x5e, 0xbc, 0xc8, 0x1e, 0x87, 0xc9, 0xc5, 0x2c, 0xc7, 0x33, 0x9c, 0xf8,
+ 0x37, 0x65, 0x4d, 0x52, 0xe2, 0x57, 0x7e, 0x5d, 0xb3, 0x12, 0xfd, 0x7b,
+ 0x57, 0x40, 0xaf, 0xca, 0x61, 0xa0, 0x1a, 0x6d, 0xc2, 0xc2, 0xbe, 0x40,
+ 0x41, 0x2e, 0x7f, 0x28, 0x43, 0xef, 0xde, 0x30, 0xd2, 0xd3, 0x9d, 0xfa,
+ 0xbc, 0xe7, 0x85, 0x60, 0xf4, 0xf6, 0xbd, 0xd7, 0xca, 0x7a, 0x40, 0x40,
+ 0xda, 0x8d, 0xd3, 0x77, 0x54, 0xe3, 0x43, 0xdb, 0xd2, 0xa4, 0xfd, 0xa3,
+ 0x37, 0x10, 0x47, 0xcc, 0xc5, 0xa8, 0x6f, 0x3f, 0x84, 0x33, 0xe4, 0xa4,
+ 0x4e, 0xbe, 0xa4, 0x17, 0x46, 0xc7, 0x1f, 0xf6, 0x20, 0x14, 0x1f, 0x21,
+ 0x0e, 0xf8, 0x46, 0xbd, 0xe4, 0x56, 0x33, 0x9d, 0x75, 0xaf, 0x85, 0xc4,
+ 0x96, 0x38, 0x79, 0xf9, 0xd7, 0xdc, 0x6e, 0xac, 0x25, 0x66, 0x1c, 0x34,
+ 0xea, 0x3b, 0x0e, 0xe1, 0x1f, 0x89, 0xb3, 0x52, 0x5e, 0x65, 0x7f, 0xd2,
+ 0xa6, 0x9b, 0xfd, 0xc1, 0x4b, 0x2e, 0x70, 0x2f, 0xf9, 0xac, 0xdb, 0x63,
+ 0xfc, 0xc4, 0x23, 0xbc, 0x43, 0x78, 0xf7, 0xae, 0xbd, 0x0a, 0x5a, 0xd8,
+ 0xce, 0x4e, 0xda, 0xcc, 0xc3, 0x21, 0xb8, 0x5b, 0x6f, 0x24, 0xbf, 0x02,
+ 0x5d, 0x70, 0xba, 0x0f, 0x3b, 0x46, 0x10, 0xc9, 0x18, 0xe3, 0x33, 0x7c,
+ 0xa8, 0x62, 0x3b, 0x12, 0x53, 0x0a, 0x26, 0xdb, 0x89, 0xdc, 0x77, 0x65,
+ 0x3b, 0x65, 0x78, 0x72, 0xb2, 0x9d, 0x7d, 0x6c, 0xe7, 0xe6, 0xd9, 0x70,
+ 0x97, 0xdd, 0x2c, 0x73, 0xd5, 0x40, 0xff, 0x29, 0x43, 0xca, 0x89, 0x2b,
+ 0xe4, 0xa3, 0x5f, 0x85, 0x62, 0xd4, 0x4a, 0xee, 0x72, 0xd6, 0xa9, 0xb7,
+ 0xb8, 0x61, 0xfc, 0x02, 0x69, 0x91, 0x72, 0x7e, 0xf6, 0x38, 0x1d, 0x35,
+ 0xaf, 0x9b, 0x2a, 0x6c, 0xdd, 0x5b, 0x9c, 0x97, 0x97, 0xfd, 0xe4, 0xfb,
+ 0xa8, 0xe4, 0x3d, 0x3f, 0x76, 0x30, 0x07, 0x5d, 0xcc, 0x7e, 0x0e, 0x9b,
+ 0xc2, 0x23, 0xeb, 0xcd, 0x22, 0x45, 0x72, 0xf2, 0x00, 0x39, 0x45, 0x25,
+ 0x36, 0x3b, 0x71, 0x28, 0xc0, 0xfa, 0x0d, 0x65, 0x39, 0x7e, 0x02, 0xcf,
+ 0x32, 0x96, 0x6d, 0x09, 0xe7, 0xfa, 0x23, 0x0e, 0x33, 0xcf, 0x6d, 0xc4,
+ 0xc1, 0xc1, 0x4b, 0xcf, 0x83, 0x8b, 0x8d, 0xa9, 0xf3, 0x35, 0x1e, 0xf4,
+ 0xa0, 0x8d, 0xdf, 0x05, 0x12, 0x67, 0xae, 0x18, 0xfb, 0x96, 0x91, 0x47,
+ 0xf8, 0x5d, 0x8c, 0xad, 0x23, 0x36, 0xb6, 0x38, 0x39, 0x4e, 0x01, 0xba,
+ 0x1b, 0x04, 0x0f, 0xc5, 0x96, 0xa6, 0x4b, 0xec, 0x88, 0xa4, 0x21, 0xf1,
+ 0x55, 0xec, 0x27, 0xea, 0xd8, 0x8f, 0x4b, 0x99, 0x6a, 0x3f, 0x5d, 0x78,
+ 0xcd, 0x38, 0xba, 0xa2, 0x10, 0x47, 0xef, 0x97, 0xb5, 0xfb, 0x8e, 0x30,
+ 0x8e, 0xdd, 0x46, 0xdf, 0x7c, 0x97, 0xd8, 0xb2, 0x65, 0x36, 0xe3, 0x97,
+ 0x83, 0x59, 0x0a, 0x0a, 0xc9, 0x2b, 0xb6, 0xed, 0x0d, 0xea, 0x05, 0xaa,
+ 0xc6, 0x3e, 0xaf, 0xc6, 0x2e, 0x91, 0xdf, 0x64, 0x9e, 0x7e, 0xf4, 0xb1,
+ 0x42, 0xf8, 0x24, 0x5f, 0x7a, 0xfb, 0x0c, 0xdb, 0x58, 0x6c, 0xe6, 0x75,
+ 0xe5, 0xe8, 0x69, 0xb2, 0x9d, 0x4a, 0x24, 0xf7, 0xe6, 0xeb, 0x2b, 0x38,
+ 0x15, 0x0a, 0x4c, 0xae, 0x9d, 0x57, 0xa2, 0x77, 0xe4, 0xe8, 0x49, 0xf2,
+ 0x1c, 0xc6, 0xa9, 0xa3, 0x9d, 0x01, 0xca, 0x72, 0x3e, 0x9c, 0x9f, 0x53,
+ 0xf1, 0xcd, 0xa9, 0x6d, 0x88, 0xed, 0x42, 0x29, 0xab, 0xc5, 0x96, 0x32,
+ 0xda, 0x68, 0x26, 0x84, 0x78, 0x49, 0xb4, 0x0c, 0x89, 0x11, 0xfa, 0xd6,
+ 0x68, 0x01, 0xdc, 0xf3, 0x24, 0xee, 0x0a, 0xd7, 0x72, 0xdf, 0x72, 0x3a,
+ 0x51, 0x80, 0x07, 0xcc, 0x8b, 0xb6, 0xe0, 0xe2, 0x49, 0x03, 0xd7, 0x15,
+ 0x10, 0x13, 0x6b, 0xc3, 0xa1, 0xd8, 0x3a, 0xe6, 0xb4, 0xc7, 0x1b, 0xdc,
+ 0xb7, 0x7c, 0x90, 0xf9, 0x3d, 0x79, 0xf1, 0xd5, 0xe3, 0x11, 0x7d, 0xe0,
+ 0xc4, 0xd2, 0x90, 0xf4, 0x29, 0xfd, 0xe5, 0x6d, 0x54, 0xfa, 0xb7, 0xed,
+ 0x50, 0xd8, 0xe7, 0xcc, 0x79, 0x7e, 0x0c, 0xef, 0x19, 0xf9, 0x31, 0xf8,
+ 0x9c, 0xf8, 0xcd, 0x1c, 0x98, 0x98, 0x23, 0x79, 0xc1, 0x11, 0xe5, 0xa8,
+ 0x93, 0x03, 0x5b, 0x31, 0xe6, 0xbe, 0x91, 0x9e, 0xc9, 0xdc, 0x77, 0x9c,
+ 0x3c, 0xf7, 0x38, 0x79, 0xee, 0xcb, 0x93, 0xb9, 0xef, 0x8b, 0x19, 0xa9,
+ 0x33, 0xb5, 0x7c, 0x24, 0x26, 0x6b, 0xd6, 0x23, 0x89, 0x50, 0x5d, 0xbe,
+ 0xce, 0xcb, 0x2c, 0x7f, 0xfc, 0x52, 0xf9, 0xd5, 0xcc, 0x57, 0x57, 0x61,
+ 0x5b, 0xaa, 0x04, 0x0f, 0x6a, 0x4e, 0x6e, 0xe9, 0x2d, 0x8c, 0x9e, 0xb8,
+ 0xef, 0x7d, 0x63, 0xbc, 0xce, 0x45, 0x1c, 0x1a, 0xe1, 0xe0, 0x5b, 0x12,
+ 0x0a, 0xfd, 0xce, 0x83, 0x1e, 0xad, 0x1c, 0x6b, 0xcd, 0x7f, 0xb2, 0x1f,
+ 0x5c, 0x25, 0xcf, 0xf2, 0x7b, 0x14, 0x52, 0xfe, 0x35, 0x96, 0x0f, 0x9a,
+ 0x23, 0x93, 0xb9, 0xe0, 0xd1, 0x04, 0xfa, 0x24, 0xcf, 0x5a, 0xd3, 0x1c,
+ 0xd2, 0xbb, 0x9d, 0x75, 0x63, 0x1d, 0xeb, 0x32, 0x3a, 0xd6, 0x53, 0x9e,
+ 0xb4, 0x7b, 0x32, 0x47, 0xca, 0xc5, 0x62, 0x4b, 0x78, 0xe6, 0x22, 0x96,
+ 0xdb, 0x3c, 0x89, 0x33, 0x2d, 0x97, 0x78, 0xae, 0x6d, 0xf7, 0x9b, 0x79,
+ 0xae, 0xcb, 0x58, 0x50, 0x29, 0xb9, 0x35, 0x68, 0x17, 0x15, 0x48, 0xfb,
+ 0x65, 0x4f, 0x66, 0xea, 0x18, 0x11, 0x2b, 0x8c, 0x86, 0xf4, 0xd9, 0xea,
+ 0x54, 0xec, 0x92, 0xb1, 0x0a, 0x6e, 0x59, 0x8e, 0x7e, 0x8e, 0x5d, 0x1a,
+ 0x6f, 0x7d, 0xa1, 0x60, 0xd6, 0xc1, 0x44, 0x77, 0x01, 0x6d, 0x4b, 0x2d,
+ 0x10, 0x7b, 0x40, 0xee, 0x1e, 0xb2, 0xb6, 0xbd, 0xfd, 0x0a, 0xdd, 0x15,
+ 0xc4, 0x98, 0x0a, 0xe0, 0xe9, 0x44, 0x28, 0x76, 0x16, 0x96, 0x72, 0x32,
+ 0xe3, 0xa6, 0xad, 0x4b, 0xbb, 0x5b, 0xd8, 0x5e, 0x8f, 0x72, 0xe2, 0x52,
+ 0x9b, 0x17, 0x2e, 0x6e, 0x76, 0xd6, 0x71, 0xf3, 0xbe, 0xe2, 0xc5, 0x43,
+ 0x7d, 0xf9, 0xbd, 0xc6, 0x18, 0xde, 0x33, 0x05, 0x17, 0xbd, 0xe4, 0x3d,
+ 0xcc, 0xd2, 0x13, 0xdb, 0x90, 0xf3, 0x4b, 0xf9, 0xe4, 0xe7, 0xfd, 0xa0,
+ 0x5b, 0x30, 0xec, 0x27, 0xb3, 0x63, 0x93, 0x6b, 0x2e, 0x7f, 0xac, 0x4c,
+ 0x1e, 0xdb, 0x2f, 0x5c, 0xec, 0x4b, 0x55, 0x4f, 0xc9, 0xb3, 0x69, 0x5f,
+ 0x03, 0xc1, 0x1e, 0x0b, 0x95, 0x6c, 0xc3, 0x8d, 0xbf, 0x65, 0xfc, 0x76,
+ 0x0f, 0x1c, 0xbd, 0x41, 0x52, 0x32, 0xcf, 0xa1, 0x18, 0x36, 0x37, 0x7b,
+ 0xe0, 0x1a, 0xaa, 0x2e, 0xcc, 0xad, 0xf3, 0x91, 0x3c, 0x3b, 0xdf, 0x8a,
+ 0x83, 0xd3, 0x6a, 0x56, 0xf2, 0x6a, 0xd2, 0x88, 0x43, 0xa2, 0xd7, 0x4a,
+ 0x7e, 0x8b, 0x5e, 0xfc, 0xfc, 0x16, 0x1d, 0x55, 0xf1, 0xbb, 0x1c, 0xb1,
+ 0x2a, 0xd9, 0xf3, 0x6a, 0x47, 0x82, 0x98, 0x55, 0x12, 0xed, 0xc4, 0xd7,
+ 0x7b, 0x6d, 0xbb, 0x87, 0x7e, 0x59, 0xc4, 0x18, 0xff, 0x48, 0xa8, 0x3e,
+ 0x32, 0x47, 0x29, 0x20, 0xdf, 0x69, 0x47, 0xcf, 0x48, 0x41, 0xbc, 0x3c,
+ 0x5a, 0xc5, 0x98, 0xae, 0xe1, 0x93, 0xb9, 0x6d, 0xc8, 0x8e, 0x5e, 0xbd,
+ 0x57, 0x36, 0x75, 0x9f, 0x2c, 0xbf, 0x3f, 0x26, 0xe3, 0x11, 0xb9, 0x45,
+ 0xfe, 0x0b, 0x17, 0xb7, 0xa6, 0x44, 0x36, 0x0f, 0x0e, 0xf4, 0x89, 0xbc,
+ 0x36, 0x3a, 0xcc, 0x5b, 0x29, 0x27, 0x91, 0xbe, 0x72, 0xea, 0xfc, 0xe6,
+ 0xdb, 0x91, 0x75, 0xf0, 0x4e, 0x65, 0x98, 0xf3, 0x65, 0xb9, 0x0b, 0xc5,
+ 0xbf, 0x34, 0xe6, 0x15, 0xca, 0x73, 0x19, 0x69, 0xa3, 0x45, 0x19, 0x49,
+ 0x4f, 0xad, 0xd3, 0xa9, 0x1c, 0xca, 0x3c, 0x5c, 0x28, 0x9c, 0xe3, 0xb2,
+ 0x1e, 0xf3, 0x32, 0x90, 0xdc, 0xd2, 0x5e, 0x2a, 0x92, 0xa2, 0x7f, 0xd1,
+ 0x8f, 0x0e, 0x77, 0x96, 0xbf, 0xb3, 0x5f, 0xd6, 0xe7, 0xd5, 0x3e, 0x36,
+ 0xf7, 0x0a, 0x9f, 0x3c, 0x4e, 0x9f, 0x1c, 0xff, 0xa3, 0x3e, 0x39, 0xef,
+ 0x4f, 0x94, 0xcf, 0xaf, 0xb7, 0xda, 0xf6, 0x6e, 0x53, 0xd6, 0xe8, 0x65,
+ 0xdd, 0xb5, 0xe1, 0x4b, 0xf6, 0x5e, 0x65, 0x3d, 0x7e, 0x36, 0xd2, 0x95,
+ 0xc1, 0xb4, 0xac, 0xbf, 0x0c, 0xa4, 0x80, 0x45, 0x49, 0xe9, 0x27, 0x46,
+ 0x7d, 0xa9, 0xb7, 0x32, 0x1a, 0x31, 0x43, 0xe8, 0xc2, 0x19, 0xd3, 0xd8,
+ 0xf7, 0x20, 0x79, 0x77, 0x37, 0x73, 0xd2, 0x83, 0xe6, 0x72, 0xfa, 0x7b,
+ 0x31, 0x36, 0x34, 0xd0, 0x18, 0x57, 0x98, 0xf4, 0x7b, 0xab, 0x9d, 0xae,
+ 0xe8, 0xf5, 0x45, 0xdb, 0x57, 0x25, 0x42, 0xc1, 0xb6, 0x8d, 0xc4, 0xf3,
+ 0xa5, 0xbd, 0x5e, 0xe8, 0x8a, 0xc3, 0x07, 0x5a, 0x7f, 0xa1, 0x0a, 0x46,
+ 0x9d, 0x29, 0xc8, 0xe5, 0xcd, 0xb2, 0xe6, 0x22, 0xfd, 0x2c, 0x67, 0x5e,
+ 0x22, 0x75, 0x75, 0xb4, 0xd7, 0x2a, 0x48, 0xd5, 0x06, 0xfb, 0xe0, 0xb2,
+ 0xed, 0xdf, 0x91, 0x17, 0x8e, 0x3b, 0xb9, 0x7c, 0x7d, 0xdd, 0x6e, 0xf5,
+ 0x7f, 0x10, 0x0b, 0x9d, 0x36, 0x34, 0x59, 0xf3, 0x7f, 0xe1, 0x4f, 0xae,
+ 0x7b, 0x9b, 0x90, 0xbd, 0x89, 0x42, 0x63, 0x89, 0x32, 0xe2, 0xcf, 0x71,
+ 0x8a, 0xdb, 0x06, 0x3e, 0xbf, 0xf8, 0x64, 0x4a, 0xec, 0x1c, 0x55, 0x01,
+ 0x63, 0x06, 0x66, 0x1f, 0x28, 0xc5, 0xb2, 0x01, 0xe1, 0x0a, 0x3e, 0xab,
+ 0x30, 0x1a, 0xc0, 0x9c, 0x03, 0x95, 0x68, 0xd9, 0x23, 0xfb, 0x50, 0x76,
+ 0x57, 0x45, 0x74, 0x35, 0xdc, 0x87, 0x34, 0x3c, 0xb0, 0xc7, 0xb6, 0x67,
+ 0xcd, 0x23, 0xb5, 0x63, 0x4c, 0x7c, 0xb7, 0x69, 0x15, 0x3c, 0xd9, 0x6a,
+ 0x2c, 0x49, 0xd6, 0x39, 0x6b, 0xad, 0x1f, 0x26, 0x5a, 0x5b, 0xce, 0xf5,
+ 0xd6, 0x6e, 0xa8, 0x55, 0x82, 0xe6, 0x29, 0x25, 0x82, 0x82, 0x6c, 0x04,
+ 0xae, 0xa4, 0x82, 0x57, 0x0d, 0x74, 0x95, 0x45, 0xa3, 0x70, 0x65, 0xa3,
+ 0xf0, 0x25, 0xdd, 0x68, 0xa0, 0xbe, 0x4b, 0x38, 0xf7, 0xd3, 0x92, 0xd5,
+ 0x98, 0x96, 0xbd, 0x0e, 0xfa, 0x81, 0x06, 0xfa, 0x48, 0x25, 0xfb, 0xf3,
+ 0xa3, 0x25, 0xd9, 0x86, 0x69, 0x46, 0x33, 0x6d, 0xa3, 0x19, 0x33, 0x93,
+ 0x7e, 0x2c, 0xe0, 0x7c, 0x2c, 0x4e, 0xb6, 0xb2, 0x1f, 0x1f, 0xda, 0x07,
+ 0xee, 0x44, 0x60, 0xc8, 0x8b, 0xf2, 0x01, 0x1d, 0x1f, 0xce, 0xf5, 0xa2,
+ 0x68, 0x28, 0x80, 0xd2, 0xa4, 0xec, 0x8d, 0x21, 0xb6, 0xb1, 0x39, 0x00,
+ 0x5f, 0x16, 0x28, 0x19, 0xb0, 0xf1, 0xad, 0xf0, 0xa8, 0x7a, 0x77, 0xa5,
+ 0x65, 0x4f, 0x73, 0x62, 0x41, 0x6b, 0xfb, 0x16, 0xe3, 0xce, 0x49, 0xbf,
+ 0x77, 0x33, 0xcf, 0x52, 0xc8, 0xd7, 0x25, 0x06, 0xb6, 0xb6, 0x1f, 0x4c,
+ 0xc8, 0xda, 0x46, 0x88, 0x7e, 0xeb, 0x81, 0x77, 0xa8, 0x53, 0xe9, 0xa3,
+ 0xed, 0xa0, 0x40, 0xf4, 0xaf, 0xd2, 0xbf, 0xa0, 0x95, 0xd2, 0xce, 0xb7,
+ 0x66, 0x5a, 0x94, 0x64, 0xba, 0x53, 0xe9, 0xcd, 0x94, 0x78, 0x51, 0x2c,
+ 0xf3, 0xf2, 0x15, 0x8c, 0x36, 0x3c, 0x69, 0xa7, 0x2b, 0x9c, 0xb9, 0xb5,
+ 0x3c, 0x90, 0x9c, 0xdb, 0x5a, 0x15, 0xae, 0x0d, 0x76, 0x56, 0xa8, 0xb2,
+ 0x9f, 0x42, 0x1c, 0x52, 0x72, 0x7d, 0x69, 0x46, 0x12, 0xcf, 0xfa, 0x65,
+ 0x7d, 0x55, 0xe6, 0xbf, 0xb5, 0x3d, 0xd1, 0x7b, 0xe1, 0xa2, 0xcc, 0xe9,
+ 0xc7, 0xb4, 0xc3, 0xdb, 0x93, 0x9f, 0x5f, 0xdc, 0x97, 0x6a, 0x63, 0x9e,
+ 0x66, 0xe2, 0x55, 0xfe, 0x5e, 0xc4, 0x71, 0xbf, 0x98, 0xf1, 0x61, 0x61,
+ 0xb2, 0xd9, 0xd9, 0x8b, 0x5b, 0x96, 0x8c, 0xe0, 0x15, 0x7e, 0xb7, 0x24,
+ 0x57, 0xe1, 0x18, 0xf3, 0xd4, 0x07, 0x92, 0x51, 0xbc, 0x9d, 0x09, 0xe0,
+ 0x7e, 0xea, 0x6f, 0x06, 0xed, 0xf4, 0xae, 0xa4, 0x8e, 0x37, 0x32, 0xc0,
+ 0xcf, 0xfa, 0x6c, 0x84, 0x1a, 0xbf, 0xa3, 0x3e, 0xed, 0xac, 0x8d, 0x35,
+ 0xe3, 0x67, 0x09, 0x13, 0x6f, 0x24, 0x6a, 0xcc, 0x9b, 0xd5, 0xdf, 0x62,
+ 0xdc, 0x9d, 0xa0, 0x4d, 0x9d, 0x47, 0xbc, 0x52, 0xd6, 0xf1, 0x72, 0xf2,
+ 0x77, 0x8f, 0x79, 0x98, 0x63, 0x6d, 0xc0, 0x11, 0xbf, 0xb3, 0x2e, 0x71,
+ 0x85, 0x5c, 0xb2, 0x36, 0xb1, 0x88, 0x72, 0x3d, 0x95, 0x22, 0x57, 0x34,
+ 0xaa, 0x29, 0x8f, 0x17, 0x0b, 0x07, 0xbc, 0xa8, 0xa4, 0x6d, 0x9c, 0x3e,
+ 0x10, 0xc5, 0xce, 0x54, 0x11, 0x5a, 0xfa, 0x03, 0x38, 0xc3, 0xeb, 0xad,
+ 0xb4, 0xf1, 0x1f, 0xb1, 0x6f, 0xa3, 0x49, 0xc3, 0x80, 0x56, 0x84, 0x9e,
+ 0xba, 0x1f, 0x93, 0xef, 0xa9, 0xcc, 0x39, 0x98, 0x1b, 0x18, 0x25, 0xd8,
+ 0xc1, 0xb4, 0xbe, 0xb0, 0x39, 0x88, 0xfe, 0x3a, 0xda, 0x7a, 0x15, 0xe3,
+ 0x87, 0x11, 0x43, 0x39, 0x31, 0x26, 0xc5, 0x5c, 0xb1, 0x30, 0x6a, 0x51,
+ 0x06, 0x15, 0xfb, 0x34, 0x55, 0xd6, 0xe4, 0xf8, 0x2c, 0x80, 0x63, 0x09,
+ 0xd8, 0xc5, 0x51, 0xe3, 0xc2, 0x4e, 0x84, 0x4e, 0xbc, 0xcf, 0xb8, 0xfe,
+ 0xf7, 0x99, 0x12, 0x7c, 0xbf, 0x6f, 0x36, 0xfe, 0x36, 0x2d, 0xeb, 0xbd,
+ 0x3e, 0xac, 0x1f, 0x0c, 0xab, 0xb9, 0xb5, 0x4a, 0x1f, 0x1e, 0x1a, 0x84,
+ 0x35, 0x93, 0xf6, 0xf8, 0xf2, 0x70, 0x19, 0xd6, 0xf4, 0xbd, 0x60, 0x33,
+ 0x77, 0xa6, 0x5d, 0x7b, 0x71, 0x34, 0x2d, 0x32, 0x96, 0x53, 0xc6, 0x22,
+ 0x1c, 0xe3, 0x75, 0x0f, 0x6d, 0xbf, 0xb2, 0xf7, 0xdb, 0xf8, 0x2c, 0x55,
+ 0x53, 0x77, 0xbf, 0xda, 0x8e, 0xe3, 0xce, 0x7e, 0x6c, 0x03, 0xde, 0xa2,
+ 0x1e, 0xcb, 0x77, 0xdb, 0xf6, 0x6f, 0xc2, 0x31, 0xfc, 0x2c, 0x73, 0x2d,
+ 0x8a, 0x78, 0x6d, 0x86, 0x5b, 0xf0, 0x66, 0xa6, 0x1a, 0x65, 0xbd, 0xad,
+ 0x78, 0x9d, 0x9c, 0xbf, 0x74, 0x77, 0x27, 0x4e, 0xb1, 0x7d, 0x5f, 0xbf,
+ 0x17, 0xaf, 0xa5, 0xbd, 0x78, 0xb5, 0xcf, 0xd0, 0xd6, 0x2a, 0x7f, 0xa7,
+ 0xc4, 0x2b, 0x73, 0xfd, 0x0c, 0xa4, 0x72, 0xfa, 0xdc, 0x3e, 0x56, 0x00,
+ 0xc1, 0xf2, 0x43, 0x7e, 0x59, 0xbf, 0x95, 0xf3, 0x31, 0xad, 0xed, 0x5a,
+ 0xf2, 0x77, 0x17, 0x13, 0xd4, 0xe7, 0x9b, 0xa3, 0x01, 0xdc, 0x91, 0x14,
+ 0xdd, 0x7e, 0x7e, 0x71, 0x17, 0xb1, 0xa3, 0x77, 0x34, 0x82, 0x13, 0x09,
+ 0x8f, 0xb3, 0xe7, 0xd8, 0x33, 0x2a, 0xfb, 0xb1, 0xdf, 0xe5, 0xdc, 0x00,
+ 0x6b, 0x47, 0x73, 0x6d, 0x6d, 0x19, 0x2b, 0xa4, 0xee, 0x6e, 0xc7, 0xd3,
+ 0x5a, 0x81, 0xc4, 0xdf, 0x9c, 0x8d, 0x1a, 0x41, 0xda, 0xee, 0x77, 0x9d,
+ 0xf5, 0xbd, 0x81, 0x54, 0xbd, 0x36, 0x0d, 0xf9, 0x79, 0xac, 0xc1, 0x4c,
+ 0xe3, 0xf7, 0xf6, 0x0b, 0x7e, 0x59, 0x77, 0x15, 0xbe, 0xd8, 0xda, 0xbe,
+ 0x36, 0x21, 0xfd, 0xe8, 0xd8, 0x3c, 0x7a, 0xe1, 0x62, 0x3f, 0xf9, 0xfa,
+ 0x12, 0xda, 0xc8, 0xba, 0x90, 0x1f, 0x8b, 0x6b, 0xeb, 0x50, 0x9b, 0x95,
+ 0x35, 0xdd, 0x08, 0x39, 0xab, 0x89, 0x8e, 0x50, 0xd4, 0xd9, 0xd7, 0x82,
+ 0x9a, 0xbf, 0xe7, 0xc5, 0xbb, 0x7f, 0xe0, 0x2b, 0xc0, 0xac, 0x81, 0x36,
+ 0xf6, 0x6b, 0x63, 0x99, 0xf9, 0x0f, 0x76, 0xcb, 0x3d, 0xd2, 0x7f, 0x4d,
+ 0x59, 0xee, 0x19, 0x27, 0xbc, 0x58, 0x7e, 0x37, 0xd1, 0x97, 0x1a, 0x71,
+ 0xd8, 0x2f, 0x3c, 0x43, 0xfc, 0xa0, 0xb5, 0x3d, 0x4c, 0xfb, 0xd9, 0x41,
+ 0x19, 0x56, 0xd0, 0x76, 0x96, 0x11, 0x17, 0xca, 0x8d, 0x0b, 0x17, 0x7b,
+ 0x53, 0x26, 0xe6, 0x8c, 0xfa, 0x68, 0xcb, 0x45, 0xec, 0xaf, 0x19, 0xc6,
+ 0x28, 0x71, 0x84, 0xf6, 0xbd, 0x60, 0xd4, 0x4f, 0x7b, 0xd6, 0x31, 0x7f,
+ 0x54, 0x7c, 0xdc, 0x40, 0x88, 0xb1, 0xac, 0x9d, 0x75, 0x22, 0xa3, 0x15,
+ 0xb8, 0x79, 0xbf, 0x1b, 0x77, 0x26, 0xc3, 0xd4, 0x4f, 0x1d, 0x63, 0xdc,
+ 0x65, 0x7d, 0x6f, 0x1b, 0x9b, 0x85, 0x0a, 0xe3, 0x88, 0xfd, 0x9c, 0x83,
+ 0x61, 0x85, 0x8e, 0x9e, 0x02, 0xec, 0x37, 0x90, 0x82, 0x55, 0xce, 0xf8,
+ 0x72, 0x61, 0xf4, 0xb9, 0x2f, 0xe2, 0xf7, 0x8a, 0x2e, 0xa7, 0x8e, 0x47,
+ 0x30, 0xe5, 0x02, 0xb1, 0x0e, 0x68, 0x7c, 0xc2, 0xc6, 0xe2, 0xc6, 0x8d,
+ 0xca, 0x0f, 0x1c, 0x5b, 0x92, 0x76, 0x85, 0x3b, 0xe4, 0xf5, 0x9f, 0xd7,
+ 0xf9, 0x6f, 0x0a, 0x72, 0x3a, 0xcf, 0x8f, 0x33, 0xb8, 0x4f, 0x70, 0x7a,
+ 0x7d, 0x63, 0x1e, 0xa7, 0xa5, 0xbc, 0xdc, 0x5f, 0x61, 0xf7, 0x6a, 0x70,
+ 0x17, 0x1a, 0x2e, 0x6c, 0xaf, 0x7b, 0x46, 0x99, 0xd0, 0xc4, 0xe7, 0x15,
+ 0x62, 0xc7, 0xed, 0x36, 0xdd, 0x96, 0x76, 0xfd, 0x12, 0xcb, 0x41, 0x29,
+ 0xbc, 0x34, 0x97, 0xc2, 0x3f, 0xba, 0x27, 0xe7, 0x52, 0x78, 0x6f, 0x7e,
+ 0x4c, 0x79, 0x59, 0x23, 0xe4, 0x76, 0x22, 0xaf, 0xd8, 0x86, 0x94, 0x79,
+ 0xb0, 0xc8, 0x59, 0x8f, 0x46, 0xf7, 0x14, 0x7b, 0xc8, 0x73, 0x18, 0xa7,
+ 0x0d, 0x0d, 0x97, 0xec, 0xc1, 0x8d, 0xb6, 0xa4, 0xcc, 0x3b, 0xac, 0x62,
+ 0xea, 0xa1, 0x6d, 0xd4, 0xc3, 0xf9, 0x13, 0x2e, 0xae, 0x62, 0x89, 0xb9,
+ 0x5d, 0x19, 0xf7, 0xef, 0x64, 0x1b, 0x9f, 0x5f, 0x64, 0x1d, 0xde, 0xeb,
+ 0xe5, 0xf5, 0x75, 0xb8, 0x9d, 0x38, 0xba, 0x36, 0x6c, 0x29, 0xb9, 0x73,
+ 0x05, 0x45, 0xb8, 0x71, 0xa0, 0x12, 0x3e, 0x43, 0xd6, 0x2d, 0xfe, 0xb3,
+ 0xe2, 0xab, 0x90, 0xf1, 0x3b, 0x9c, 0x81, 0x76, 0x72, 0x1d, 0x16, 0x0f,
+ 0x30, 0x64, 0x3b, 0x7b, 0x04, 0x0b, 0xf1, 0x74, 0xf3, 0x75, 0x58, 0xea,
+ 0x70, 0x9d, 0x10, 0x6e, 0x1a, 0x12, 0x0c, 0xed, 0x54, 0xfa, 0x89, 0x9d,
+ 0x4c, 0x38, 0xe8, 0xd7, 0x31, 0xa5, 0x8f, 0x98, 0xb9, 0xcf, 0xf1, 0x11,
+ 0x59, 0x2f, 0xee, 0x54, 0x52, 0x99, 0x0a, 0x8e, 0x43, 0x6c, 0xf7, 0xb2,
+ 0x8c, 0x33, 0x29, 0xe3, 0x79, 0x62, 0xd1, 0xfc, 0x49, 0x19, 0x67, 0x37,
+ 0x49, 0x2e, 0x2b, 0x32, 0x16, 0xa1, 0x96, 0x72, 0x54, 0x52, 0x8e, 0x63,
+ 0x66, 0x85, 0x32, 0xa0, 0xe5, 0x64, 0xab, 0x61, 0xff, 0x8c, 0x39, 0x58,
+ 0x63, 0xfa, 0x94, 0x65, 0xce, 0xbd, 0xbc, 0x6c, 0x9f, 0x5f, 0xec, 0x49,
+ 0x7d, 0x61, 0xfb, 0x8c, 0x9c, 0x9c, 0x65, 0xfd, 0x3a, 0x4e, 0xcd, 0xbd,
+ 0x0e, 0xa5, 0xfb, 0x8b, 0xd0, 0x48, 0x5c, 0xaf, 0x1f, 0x30, 0xfa, 0x36,
+ 0x2a, 0x22, 0xab, 0x87, 0xbf, 0x9d, 0x75, 0x03, 0xea, 0xf3, 0xff, 0x2f,
+ 0xbc, 0xd2, 0x8e, 0xdd, 0x58, 0x91, 0xcc, 0xd9, 0xb0, 0xe3, 0xbf, 0xb5,
+ 0x62, 0xbf, 0xb2, 0x46, 0x48, 0x7b, 0xce, 0xb8, 0xb0, 0x84, 0x7d, 0x1f,
+ 0x33, 0x1f, 0x56, 0x2c, 0xed, 0xc2, 0x45, 0xd9, 0xaf, 0x57, 0x29, 0x63,
+ 0x77, 0xfa, 0x3a, 0xdc, 0x31, 0x30, 0x6e, 0x7b, 0x8d, 0x05, 0xc8, 0x84,
+ 0x43, 0xed, 0x3d, 0x8a, 0x17, 0xbb, 0xd2, 0x2e, 0x2c, 0x1a, 0x20, 0x5f,
+ 0x33, 0xe3, 0x4a, 0x6c, 0x7a, 0x8e, 0x87, 0x2f, 0x4c, 0x32, 0x1f, 0xcd,
+ 0x4a, 0x7e, 0xd8, 0xd6, 0xbe, 0x30, 0xf1, 0x80, 0x12, 0xd3, 0x3e, 0xbf,
+ 0x98, 0x4c, 0x1d, 0xfd, 0xae, 0xea, 0xf0, 0x30, 0x1f, 0xde, 0x3c, 0xe8,
+ 0xa3, 0x2f, 0x28, 0xf4, 0x13, 0x3f, 0x7d, 0xbf, 0x01, 0x6f, 0xd3, 0x37,
+ 0xee, 0x67, 0x5c, 0xfc, 0xfb, 0xd1, 0x2a, 0xdc, 0xb6, 0x27, 0x8a, 0x97,
+ 0x0f, 0xfa, 0xd1, 0xbe, 0xe7, 0x56, 0xbc, 0xc5, 0x72, 0x63, 0x8c, 0x07,
+ 0x63, 0xc3, 0x95, 0xfc, 0xf8, 0xf9, 0xa9, 0xe2, 0x67, 0x2d, 0xf1, 0xa8,
+ 0x02, 0x27, 0xf7, 0xbb, 0xd0, 0x32, 0xa0, 0x62, 0xc0, 0x54, 0x70, 0xf7,
+ 0x4d, 0x32, 0x1e, 0x2f, 0xd6, 0xd4, 0x5e, 0xb6, 0x8b, 0x25, 0x49, 0xe1,
+ 0x70, 0x5e, 0xce, 0x93, 0x8e, 0x43, 0xf4, 0xcb, 0xdb, 0xc8, 0xc1, 0x76,
+ 0xf4, 0xb5, 0xd1, 0x8f, 0x6c, 0xcc, 0x0a, 0xff, 0x18, 0x2b, 0xb4, 0x1e,
+ 0xc9, 0x6b, 0x9d, 0x75, 0xfe, 0x14, 0xe7, 0x71, 0xc2, 0x53, 0x6f, 0x4d,
+ 0x43, 0x51, 0x2c, 0x10, 0x0d, 0x69, 0x47, 0xb0, 0x1c, 0x7d, 0x63, 0xd0,
+ 0x64, 0xcd, 0x7f, 0x1b, 0x79, 0xd4, 0x76, 0xf2, 0xa8, 0xee, 0xcc, 0x11,
+ 0xce, 0xb1, 0xcf, 0x2b, 0x7b, 0xdf, 0xdb, 0xa8, 0xbb, 0xc5, 0x0e, 0x27,
+ 0xf2, 0x5a, 0x45, 0x6c, 0xff, 0x38, 0x63, 0xd2, 0x82, 0xfe, 0x1c, 0x6e,
+ 0x7c, 0xd6, 0xf4, 0x3c, 0x8c, 0x69, 0x3d, 0xf4, 0xf9, 0x5c, 0xdb, 0x3b,
+ 0x85, 0x9b, 0x79, 0xca, 0x62, 0x65, 0xd1, 0xd0, 0x86, 0xd7, 0xa9, 0x7c,
+ 0x2f, 0xdb, 0xdc, 0x3a, 0xb9, 0x8f, 0xd0, 0xcb, 0x36, 0x7b, 0x58, 0xb7,
+ 0xbe, 0xdf, 0xe2, 0x5c, 0xba, 0x59, 0x3f, 0x14, 0xd8, 0xa8, 0x98, 0xac,
+ 0xeb, 0xe4, 0x11, 0xa8, 0xd9, 0x7f, 0x79, 0xae, 0xda, 0x88, 0x31, 0xfd,
+ 0x93, 0xfe, 0x7e, 0x7e, 0xf4, 0x3a, 0x84, 0x68, 0x24, 0x4f, 0x9b, 0x9b,
+ 0xa0, 0xd3, 0x66, 0x5d, 0x93, 0x7d, 0x6d, 0x97, 0x71, 0xb8, 0x67, 0xc6,
+ 0x66, 0xb2, 0x8f, 0xbe, 0x4c, 0x48, 0xeb, 0x42, 0xfd, 0x89, 0x69, 0x90,
+ 0x71, 0x48, 0x7f, 0xcb, 0xf1, 0xe4, 0xd8, 0xd5, 0xe3, 0xa8, 0x26, 0x3e,
+ 0x5d, 0x2c, 0x98, 0x3c, 0x33, 0xe7, 0xe4, 0xe2, 0x31, 0xc7, 0xc7, 0x76,
+ 0x38, 0xf2, 0x7b, 0xd8, 0x66, 0x36, 0xb7, 0x07, 0x22, 0x69, 0x95, 0x32,
+ 0xc2, 0x58, 0xd1, 0x96, 0x54, 0x62, 0x15, 0xd1, 0xfa, 0xce, 0x69, 0x08,
+ 0x45, 0x7e, 0xc6, 0xb6, 0xa7, 0xb1, 0xed, 0x67, 0xd9, 0x76, 0x8a, 0x6d,
+ 0x8f, 0xb0, 0xed, 0x1f, 0x5c, 0x6a, 0x5b, 0xc5, 0xfd, 0x7b, 0xf2, 0xb6,
+ 0xe5, 0x46, 0xa4, 0x89, 0x59, 0xdf, 0x34, 0xd9, 0x03, 0xad, 0xe6, 0xdc,
+ 0x8b, 0xee, 0x74, 0xc6, 0xf6, 0x9c, 0xbd, 0x2d, 0x60, 0xec, 0xb9, 0x6b,
+ 0x8f, 0x82, 0xf7, 0xc3, 0xef, 0x63, 0xc2, 0x9f, 0xe3, 0x11, 0x79, 0x1b,
+ 0xd2, 0x68, 0x43, 0x5a, 0xf2, 0x7f, 0xd2, 0xf4, 0xa5, 0x8e, 0xd8, 0x8f,
+ 0xec, 0x3f, 0x90, 0x3f, 0x27, 0x44, 0x1f, 0xbf, 0x23, 0xee, 0x86, 0x4e,
+ 0xbc, 0xc7, 0xd8, 0xf9, 0xa3, 0x8c, 0x07, 0xe9, 0xb4, 0x0f, 0xcf, 0x66,
+ 0x04, 0x1b, 0xdb, 0x88, 0x8d, 0x82, 0xf7, 0xe4, 0x81, 0xc3, 0x47, 0x1f,
+ 0x0b, 0xb0, 0xf2, 0xb3, 0xb4, 0x9f, 0x67, 0x69, 0x3f, 0xcf, 0x0e, 0xfb,
+ 0x70, 0xf3, 0x21, 0x2f, 0xce, 0x11, 0x6b, 0x7a, 0x59, 0x26, 0x91, 0x6a,
+ 0xc0, 0x4d, 0xe4, 0x59, 0x87, 0x7b, 0x19, 0x97, 0x19, 0xff, 0xeb, 0xb2,
+ 0x1a, 0x76, 0xf5, 0x57, 0xa0, 0x7e, 0x48, 0x62, 0x70, 0x05, 0x1e, 0xe9,
+ 0xf3, 0x62, 0xce, 0x7e, 0xd9, 0x87, 0x24, 0x2f, 0xec, 0xbb, 0x13, 0xc3,
+ 0x8e, 0x8f, 0x4f, 0xa3, 0x7f, 0x54, 0xa2, 0x76, 0x48, 0xae, 0xc9, 0x53,
+ 0x68, 0xb3, 0x0b, 0x0e, 0x55, 0x71, 0xbc, 0xb7, 0x62, 0xfe, 0xa1, 0x00,
+ 0xf1, 0xdc, 0x8f, 0x48, 0x76, 0xf9, 0x45, 0xc1, 0xe4, 0xed, 0x63, 0x53,
+ 0x63, 0x9a, 0xf8, 0xa1, 0x83, 0x61, 0x91, 0x3c, 0x86, 0x5d, 0x7e, 0x3e,
+ 0x15, 0x27, 0x7f, 0xcb, 0x67, 0x52, 0x26, 0x1f, 0x7b, 0xa6, 0xe2, 0xe2,
+ 0x65, 0x7c, 0x6a, 0x1c, 0x90, 0x6f, 0x0d, 0xed, 0xf3, 0xc4, 0xd7, 0xaf,
+ 0x43, 0xc4, 0x91, 0xe7, 0xfe, 0x62, 0x96, 0x0b, 0xe4, 0xfc, 0x7d, 0x2a,
+ 0x9e, 0xfb, 0x26, 0xfd, 0xd4, 0x85, 0x58, 0x45, 0x8e, 0x0b, 0xdf, 0xbe,
+ 0xa7, 0x01, 0xbb, 0xa8, 0x8f, 0x56, 0xfa, 0x91, 0x2f, 0x1c, 0xb5, 0xad,
+ 0x0a, 0xc9, 0x5b, 0x2b, 0x71, 0xe7, 0x1e, 0x3f, 0x63, 0xf8, 0xb5, 0x48,
+ 0x0e, 0xcf, 0x66, 0x5b, 0xd5, 0xe8, 0x9d, 0xcc, 0xe7, 0xb7, 0xa7, 0x96,
+ 0xd9, 0x0f, 0x39, 0x7b, 0xf2, 0xb2, 0xf6, 0xff, 0xda, 0x7d, 0xde, 0xd0,
+ 0xb8, 0xce, 0x7c, 0xde, 0x64, 0xce, 0x41, 0x0e, 0x76, 0x02, 0xa1, 0x4a,
+ 0xe6, 0xe7, 0x46, 0x39, 0x16, 0x31, 0x9f, 0x7f, 0xc8, 0x2f, 0xcf, 0x6e,
+ 0x15, 0x59, 0x9c, 0xf2, 0x97, 0xc7, 0xb8, 0x6b, 0xca, 0x18, 0xeb, 0x23,
+ 0xd3, 0x90, 0xe7, 0x63, 0x5f, 0xd8, 0x7f, 0x6f, 0x40, 0xe9, 0x0f, 0xd1,
+ 0x6a, 0x1b, 0x83, 0x7d, 0x0f, 0x29, 0x86, 0xd6, 0xa4, 0x12, 0xba, 0x46,
+ 0xdf, 0xc4, 0x92, 0xec, 0x2f, 0x10, 0xcb, 0xae, 0xf6, 0x8a, 0x2c, 0xf7,
+ 0x67, 0x57, 0x61, 0x9c, 0x73, 0x5c, 0xc4, 0x3a, 0x37, 0xf4, 0xfa, 0x68,
+ 0xa3, 0x50, 0x0e, 0x37, 0xd7, 0xe1, 0x43, 0xf2, 0x9c, 0xb6, 0xe4, 0x9b,
+ 0xd0, 0x18, 0x5f, 0xef, 0x4c, 0xfe, 0x02, 0x65, 0xc4, 0x94, 0x3b, 0x92,
+ 0x5f, 0xd8, 0x23, 0xa1, 0x7d, 0x4e, 0xbd, 0xc2, 0xd1, 0x03, 0x17, 0xfb,
+ 0x2e, 0xc7, 0x27, 0xad, 0xd0, 0x78, 0xe5, 0x2a, 0x3c, 0x6c, 0x68, 0xd9,
+ 0x9c, 0x18, 0xfd, 0x5f, 0x9e, 0xe8, 0xaf, 0x7f, 0xfa, 0xfd, 0xe6, 0x9c,
+ 0x5d, 0xea, 0x99, 0xbb, 0xf0, 0x2d, 0x07, 0x77, 0xd7, 0x6c, 0x74, 0x47,
+ 0x3b, 0x1e, 0x93, 0xb5, 0xd0, 0x35, 0xce, 0x3a, 0x41, 0x3b, 0x76, 0xee,
+ 0x6d, 0xc3, 0xe6, 0xbd, 0x82, 0xad, 0xf5, 0xad, 0x8b, 0x94, 0x19, 0xf4,
+ 0xc3, 0x01, 0x27, 0x97, 0x71, 0x1b, 0x9f, 0xca, 0x9a, 0xab, 0xea, 0x71,
+ 0xf6, 0xc0, 0x74, 0xac, 0x19, 0xcd, 0xb5, 0x35, 0x2b, 0x53, 0x4a, 0xff,
+ 0x8a, 0x22, 0xc9, 0x9c, 0xc5, 0xc7, 0xd8, 0xc9, 0x79, 0xc1, 0xa9, 0x7e,
+ 0x89, 0x3b, 0x0a, 0x7c, 0xf7, 0xc8, 0x5e, 0xe6, 0x32, 0xe4, 0xf9, 0x7a,
+ 0x4c, 0xdb, 0xcc, 0xdf, 0x3b, 0x8a, 0x73, 0x72, 0x6d, 0xbe, 0x8a, 0x17,
+ 0xe5, 0xed, 0x41, 0x74, 0x97, 0xb7, 0xa1, 0x4f, 0x39, 0x06, 0xe6, 0xd8,
+ 0xe4, 0x83, 0x97, 0xfd, 0xf9, 0x8b, 0x22, 0x67, 0x5d, 0x30, 0x3b, 0x35,
+ 0xbe, 0x6f, 0x9f, 0xd4, 0xfd, 0x75, 0xc5, 0xf9, 0xd8, 0x94, 0x93, 0xd7,
+ 0x24, 0x16, 0x5e, 0x83, 0x98, 0x3f, 0xef, 0xff, 0xdf, 0xe4, 0xf3, 0xcd,
+ 0x82, 0x01, 0x93, 0x75, 0xef, 0x2e, 0x41, 0xf1, 0x76, 0x87, 0xc3, 0x5d,
+ 0x6e, 0x9f, 0x64, 0xf8, 0x8a, 0xf6, 0xa7, 0xda, 0xaf, 0xb4, 0x2f, 0x71,
+ 0x5a, 0x74, 0xda, 0xc8, 0xba, 0xa2, 0x3f, 0x07, 0xa3, 0x65, 0x4d, 0x96,
+ 0xdc, 0xad, 0xcd, 0xd9, 0xa7, 0x29, 0x26, 0x6f, 0xee, 0x66, 0x0e, 0x55,
+ 0xb2, 0x9f, 0xd7, 0xe4, 0x3e, 0x4b, 0x07, 0x02, 0x28, 0xda, 0xef, 0x21,
+ 0xae, 0xcf, 0x80, 0x7b, 0x7f, 0x01, 0xed, 0x55, 0x38, 0xc2, 0x6b, 0xf7,
+ 0x6d, 0x31, 0xae, 0x85, 0x6b, 0x7f, 0x21, 0x79, 0xb9, 0x70, 0xbe, 0x13,
+ 0xf7, 0xad, 0x65, 0x1c, 0x57, 0xf7, 0x7b, 0x19, 0x9f, 0xab, 0xe1, 0x61,
+ 0xcc, 0x5b, 0x32, 0xf0, 0x67, 0x28, 0xd8, 0x5f, 0x8c, 0x07, 0x06, 0xae,
+ 0xc7, 0xcc, 0xfd, 0x25, 0xb8, 0x7f, 0x60, 0x26, 0x66, 0xec, 0x97, 0xdc,
+ 0x49, 0x47, 0x60, 0x7f, 0x29, 0x56, 0x0c, 0x04, 0x51, 0xb1, 0xbf, 0x0c,
+ 0x6d, 0x03, 0xb3, 0xa0, 0xed, 0x2f, 0xc7, 0x5d, 0x03, 0x35, 0x28, 0xdf,
+ 0xaf, 0xe1, 0xce, 0x01, 0x03, 0x65, 0xfb, 0x2b, 0x18, 0xd3, 0x42, 0x8c,
+ 0x9d, 0x7e, 0x2c, 0xdf, 0xc3, 0xb9, 0x39, 0x58, 0x45, 0xbf, 0x58, 0x45,
+ 0x4e, 0xbd, 0x1a, 0xfb, 0x52, 0x73, 0x50, 0x72, 0x30, 0x80, 0xa5, 0x7b,
+ 0xc6, 0x35, 0x52, 0x1a, 0x2c, 0x0e, 0x35, 0xa0, 0xe8, 0xa0, 0xe4, 0x7e,
+ 0xc1, 0x13, 0x2d, 0x08, 0x5e, 0x58, 0x84, 0x72, 0xe6, 0xbe, 0xc0, 0x7b,
+ 0x63, 0xc0, 0xec, 0x31, 0x17, 0x8e, 0x68, 0xab, 0xb0, 0x75, 0xec, 0x9b,
+ 0x93, 0x36, 0x2f, 0xfb, 0x47, 0xe5, 0x9c, 0x5f, 0xb9, 0x96, 0x7b, 0xab,
+ 0xd1, 0x33, 0x96, 0x5f, 0x07, 0x0b, 0xf6, 0x6d, 0xa7, 0x06, 0xc7, 0x33,
+ 0xf2, 0x4c, 0x7c, 0x04, 0xb4, 0x6f, 0xa5, 0x5b, 0xce, 0x8f, 0xbb, 0xa2,
+ 0x6a, 0x59, 0x77, 0xf3, 0x86, 0x5b, 0xe2, 0x99, 0x4d, 0xcc, 0xbb, 0x24,
+ 0x87, 0xdd, 0x78, 0xcb, 0x9a, 0xcc, 0x07, 0x97, 0xf6, 0x13, 0xfa, 0xcc,
+ 0x85, 0x01, 0x0d, 0x5f, 0xc3, 0x1a, 0x67, 0x0d, 0x55, 0xe5, 0x9c, 0xc9,
+ 0x79, 0x56, 0xe7, 0x2c, 0x39, 0xed, 0x2c, 0x0e, 0xd3, 0xc1, 0xd4, 0x75,
+ 0xa8, 0xc9, 0x38, 0x6b, 0xb5, 0x75, 0x71, 0xbc, 0xa0, 0xb6, 0x1a, 0xd6,
+ 0xe4, 0xd9, 0x0f, 0x6b, 0xbe, 0x86, 0x98, 0xa9, 0x5d, 0x3a, 0x1f, 0x12,
+ 0xd4, 0x47, 0x10, 0x0c, 0x6c, 0xc3, 0x3a, 0xe7, 0x7c, 0xa0, 0x12, 0x6d,
+ 0x97, 0x73, 0x46, 0xfc, 0x5e, 0x0d, 0x23, 0x93, 0x5f, 0x6b, 0x94, 0xb3,
+ 0xd7, 0xb2, 0x8f, 0x65, 0x33, 0xe7, 0x97, 0x3c, 0xf9, 0x88, 0xa2, 0xf6,
+ 0x3a, 0xeb, 0x63, 0xab, 0x5c, 0x8c, 0x01, 0x2d, 0x0a, 0xe2, 0x45, 0xd1,
+ 0x90, 0xfe, 0xe1, 0xe4, 0xba, 0x83, 0x67, 0x74, 0x8b, 0x52, 0x30, 0xda,
+ 0xa3, 0xb8, 0x47, 0x73, 0xeb, 0x0e, 0x2e, 0xf2, 0xd8, 0x6d, 0xa9, 0x4a,
+ 0x96, 0xd1, 0x30, 0x7b, 0xae, 0x1b, 0xaf, 0x26, 0xca, 0x9c, 0xb3, 0xc7,
+ 0x5b, 0xe7, 0x16, 0xe0, 0x11, 0xda, 0x7e, 0xeb, 0x8d, 0xc7, 0xf0, 0x41,
+ 0x86, 0x5c, 0x23, 0x61, 0x85, 0x87, 0xd9, 0xe7, 0xd1, 0x84, 0x8a, 0x17,
+ 0x07, 0xb7, 0x84, 0x87, 0x9c, 0xfe, 0xbf, 0x8d, 0xcd, 0x23, 0x92, 0x77,
+ 0xb5, 0xd9, 0xdb, 0x53, 0xed, 0xb6, 0xc4, 0xdd, 0x6c, 0xa2, 0x92, 0xb9,
+ 0xb9, 0x86, 0x0f, 0xe6, 0x6e, 0xc0, 0x39, 0x96, 0x19, 0x4d, 0x6c, 0xc4,
+ 0x27, 0xe4, 0x08, 0x99, 0xc4, 0x72, 0xbc, 0xc6, 0x5c, 0xf2, 0x7b, 0x89,
+ 0x56, 0xe6, 0x96, 0xab, 0xf0, 0xca, 0xa0, 0xf0, 0x8f, 0x16, 0x2c, 0x4c,
+ 0x28, 0x58, 0x1a, 0x5a, 0x85, 0x93, 0xc3, 0xcc, 0x29, 0x07, 0xe5, 0xbc,
+ 0xeb, 0x35, 0x58, 0x93, 0x3b, 0x0f, 0xc5, 0xe7, 0x31, 0x3e, 0x5f, 0x89,
+ 0xa3, 0xc3, 0x01, 0x1c, 0x60, 0x0e, 0xf9, 0x0e, 0x31, 0x64, 0x28, 0xd1,
+ 0x80, 0xd3, 0xcc, 0x95, 0x7e, 0x94, 0x88, 0xe0, 0x33, 0xfe, 0x3e, 0x92,
+ 0x90, 0xf5, 0xef, 0x66, 0x5c, 0xc8, 0xfc, 0x18, 0x05, 0xbd, 0x33, 0x70,
+ 0xbc, 0xed, 0x79, 0x52, 0xc9, 0x23, 0xfc, 0xb4, 0xe2, 0xf4, 0x70, 0x2b,
+ 0xce, 0x0c, 0x2e, 0xc3, 0x99, 0xe1, 0x5f, 0xe1, 0x83, 0x41, 0x91, 0x57,
+ 0xce, 0x2c, 0x3a, 0xef, 0x16, 0xb0, 0x5d, 0xe2, 0xd4, 0xf0, 0xbf, 0xa5,
+ 0xed, 0x8f, 0xec, 0xe3, 0xab, 0xa4, 0xdd, 0xe7, 0xff, 0x48, 0xdb, 0xa2,
+ 0x4b, 0x89, 0xf5, 0x5e, 0x9c, 0x4c, 0x78, 0x99, 0x57, 0x8d, 0xdf, 0x50,
+ 0x84, 0xf1, 0xf9, 0xcc, 0x36, 0xb1, 0x3d, 0x53, 0x88, 0x17, 0xfb, 0xdc,
+ 0xe4, 0x8a, 0x5f, 0x25, 0x7e, 0x74, 0xd2, 0x0e, 0x0b, 0x99, 0xbf, 0x79,
+ 0xa9, 0xe3, 0xf9, 0xc4, 0xfb, 0x55, 0xd4, 0x9f, 0x0f, 0xa7, 0x12, 0x7e,
+ 0xbc, 0x9e, 0xa8, 0x8f, 0x67, 0x95, 0x46, 0x58, 0x15, 0xb9, 0xbc, 0xf2,
+ 0x68, 0xa2, 0xc3, 0x91, 0xe9, 0xd5, 0x44, 0x9b, 0xbd, 0x95, 0x3a, 0xee,
+ 0x49, 0x7d, 0xdb, 0x39, 0x6f, 0xf8, 0x4a, 0xe2, 0x82, 0x2d, 0xe7, 0x88,
+ 0x9f, 0xa1, 0x4e, 0x4f, 0x26, 0xe2, 0x28, 0x62, 0x9e, 0x72, 0x2c, 0x31,
+ 0x8e, 0x61, 0xda, 0xe5, 0x3b, 0x7d, 0xc6, 0x89, 0x35, 0xd8, 0x84, 0xcf,
+ 0xd2, 0x85, 0x78, 0x8b, 0x7d, 0x94, 0x37, 0xb9, 0x31, 0xe1, 0xb4, 0xb7,
+ 0x09, 0x9f, 0xf4, 0x29, 0xc8, 0xcc, 0xdd, 0x84, 0x8f, 0xf9, 0xec, 0x0d,
+ 0x5e, 0x9f, 0x0b, 0x53, 0xc2, 0xc9, 0x67, 0x67, 0xfa, 0x54, 0x27, 0x07,
+ 0xee, 0x6e, 0xde, 0x84, 0xd3, 0xe9, 0x8f, 0x71, 0x80, 0xb9, 0xf4, 0x63,
+ 0xe6, 0x34, 0x44, 0xa6, 0x11, 0x70, 0x8d, 0x42, 0x9c, 0xe4, 0xf3, 0x5a,
+ 0x59, 0xef, 0xd1, 0x72, 0xe5, 0x3f, 0xe2, 0x78, 0x1e, 0x61, 0x5b, 0x67,
+ 0xd3, 0xdf, 0x61, 0xbb, 0xc2, 0x39, 0xbf, 0xc3, 0x76, 0x7f, 0x85, 0x91,
+ 0x49, 0x7d, 0x9c, 0x36, 0x65, 0x5c, 0x1b, 0x7c, 0x28, 0xf6, 0x73, 0x1c,
+ 0x0f, 0xf3, 0xbb, 0x03, 0x13, 0x99, 0x9d, 0xfc, 0x7e, 0x0d, 0x87, 0x33,
+ 0x12, 0xdb, 0xf3, 0x67, 0x87, 0x64, 0x7d, 0x4b, 0xfc, 0x47, 0x9f, 0x5c,
+ 0x97, 0x9b, 0x8e, 0x54, 0x7f, 0x59, 0x7c, 0x1a, 0xed, 0xe8, 0x3f, 0xcc,
+ 0x2b, 0xc7, 0x47, 0x61, 0x0b, 0xbb, 0x0e, 0xb8, 0x91, 0xea, 0x25, 0x9f,
+ 0xed, 0xad, 0xc4, 0x53, 0xbb, 0x35, 0x3c, 0xb9, 0xfb, 0x5a, 0x6c, 0xd9,
+ 0x7d, 0x3d, 0xf6, 0xed, 0xae, 0x46, 0x92, 0xb9, 0xf2, 0x27, 0x4d, 0xb6,
+ 0x3d, 0x87, 0x9f, 0x1d, 0xf4, 0x05, 0x2f, 0xbf, 0x5f, 0x0e, 0x8b, 0x9f,
+ 0x18, 0xb8, 0xd1, 0xf1, 0x97, 0x16, 0xdc, 0xe0, 0x7c, 0xc7, 0x30, 0x27,
+ 0xd3, 0x19, 0xde, 0x90, 0xdd, 0x14, 0x7e, 0x28, 0x3b, 0x1d, 0x5b, 0xfb,
+ 0xab, 0xd0, 0xbf, 0xbb, 0x32, 0x5e, 0xc9, 0x7e, 0x56, 0xce, 0xb3, 0x31,
+ 0xc4, 0xba, 0x66, 0x63, 0x4f, 0x78, 0x4d, 0xf6, 0x79, 0xb4, 0x65, 0xfd,
+ 0xd8, 0xdc, 0x1f, 0x60, 0x5f, 0xb2, 0x86, 0xef, 0x3e, 0xf1, 0x20, 0x6c,
+ 0xfb, 0x42, 0xd3, 0x11, 0xc6, 0xb7, 0x1f, 0xa3, 0x9d, 0xcf, 0x92, 0xfd,
+ 0x1b, 0xc8, 0xa9, 0x0a, 0xe2, 0xde, 0xa8, 0x8d, 0x53, 0xe1, 0x71, 0xdc,
+ 0xc1, 0xf6, 0x76, 0xf6, 0x97, 0x51, 0xa6, 0xe2, 0x78, 0x21, 0xef, 0x2d,
+ 0x0d, 0x6f, 0xc4, 0xae, 0x31, 0x59, 0x03, 0x3c, 0x81, 0xa5, 0xe4, 0x2c,
+ 0x15, 0x73, 0x7f, 0x56, 0x82, 0x32, 0xcd, 0x7d, 0xbe, 0x59, 0xec, 0x2f,
+ 0x4e, 0xfb, 0x13, 0xac, 0x5c, 0x87, 0xb5, 0xce, 0xd9, 0xc2, 0x76, 0xbc,
+ 0x94, 0x10, 0x9c, 0x5e, 0x8d, 0x83, 0x89, 0x75, 0xd8, 0x92, 0x92, 0x7d,
+ 0xc0, 0xe5, 0xa8, 0xc9, 0xfe, 0x55, 0x78, 0x3d, 0xe3, 0xa9, 0x2b, 0xfb,
+ 0x3f, 0xb0, 0x38, 0x9b, 0xa6, 0x5c, 0xc3, 0xe1, 0xb5, 0xd9, 0x7d, 0xe1,
+ 0x07, 0xb3, 0xad, 0x98, 0x95, 0x95, 0xf5, 0xb4, 0x36, 0xe2, 0xbb, 0xac,
+ 0xa7, 0x4d, 0x60, 0x61, 0xf6, 0x0c, 0x16, 0x65, 0xdf, 0x62, 0x2c, 0x16,
+ 0xdc, 0x90, 0x75, 0xb6, 0x5f, 0x31, 0x39, 0x91, 0x7d, 0xc3, 0xbf, 0xc4,
+ 0xd6, 0xbd, 0x71, 0xc6, 0xc2, 0x3c, 0x46, 0xd5, 0x6b, 0x07, 0x04, 0x5f,
+ 0xc6, 0x3c, 0x4e, 0x2c, 0xe8, 0x4b, 0xdd, 0x43, 0x7b, 0x54, 0xc9, 0xf3,
+ 0x25, 0xce, 0xac, 0xa3, 0x2f, 0x77, 0x92, 0x9f, 0x4b, 0xfc, 0xbb, 0x6b,
+ 0xf2, 0xbe, 0xf0, 0x3a, 0x89, 0x7d, 0x3a, 0x8e, 0x66, 0x9c, 0xbd, 0x0c,
+ 0xdd, 0x6b, 0xdc, 0xc1, 0x67, 0x52, 0xff, 0x2f, 0x91, 0xdc, 0xbb, 0xca,
+ 0xde, 0xe9, 0xac, 0x19, 0x29, 0x38, 0x1e, 0x62, 0x5f, 0xa4, 0x91, 0x4b,
+ 0xf7, 0xcb, 0x59, 0xce, 0x75, 0x72, 0x96, 0xd3, 0x72, 0x19, 0x6d, 0xf6,
+ 0x96, 0x14, 0x1e, 0x2c, 0x45, 0x00, 0xcb, 0x47, 0x0b, 0x10, 0x3b, 0x58,
+ 0x8c, 0xdb, 0x77, 0xb7, 0xd3, 0x96, 0x2d, 0xda, 0xaf, 0x61, 0xae, 0x55,
+ 0x8a, 0xb1, 0x84, 0xf7, 0x1e, 0xe8, 0x0f, 0xb6, 0x02, 0xa1, 0x13, 0xa7,
+ 0x5d, 0xc5, 0xb8, 0x9f, 0xb1, 0x23, 0x9d, 0x5e, 0x8e, 0xd8, 0xfe, 0xe3,
+ 0xb0, 0xd2, 0xb4, 0xc9, 0x3d, 0xc4, 0x99, 0xbd, 0x6e, 0xa8, 0xd1, 0x5f,
+ 0x61, 0xdf, 0xb0, 0x8a, 0xf2, 0x3d, 0x2f, 0xd8, 0x01, 0x43, 0x31, 0xce,
+ 0x85, 0xb2, 0xe4, 0x40, 0x6e, 0x94, 0x26, 0x5b, 0x30, 0x4a, 0xac, 0xf1,
+ 0x25, 0x63, 0xc8, 0x64, 0xda, 0x90, 0x26, 0x96, 0xa4, 0xc9, 0x9b, 0x4a,
+ 0x92, 0x26, 0x63, 0x79, 0x1d, 0x76, 0xd1, 0x5f, 0x0a, 0x98, 0xcb, 0x6f,
+ 0xcb, 0xdc, 0x0a, 0x6b, 0xf8, 0x4e, 0x6c, 0x1f, 0x6e, 0xe3, 0x87, 0xfc,
+ 0x71, 0xf8, 0xdb, 0x58, 0x38, 0x7a, 0x02, 0x3d, 0x99, 0x38, 0xed, 0xf1,
+ 0x63, 0x6c, 0x4f, 0x1f, 0xc3, 0x53, 0x7d, 0x5d, 0xcc, 0x11, 0x8e, 0xe1,
+ 0x49, 0x5e, 0xf7, 0xf5, 0x19, 0x9d, 0x01, 0xf5, 0x18, 0x52, 0xe9, 0x4d,
+ 0xb8, 0xb3, 0x5f, 0x61, 0x0e, 0xb7, 0x09, 0x77, 0xec, 0xa7, 0x2d, 0x3e,
+ 0xd1, 0x81, 0xd6, 0xd1, 0xd7, 0x90, 0xc8, 0xbc, 0xc4, 0xfc, 0x6a, 0x23,
+ 0x7a, 0x52, 0x1b, 0xc8, 0xbd, 0x9e, 0x67, 0x3b, 0x47, 0xe8, 0xe7, 0x9d,
+ 0x1c, 0xe3, 0xe3, 0xfc, 0x5c, 0xc2, 0x70, 0x4d, 0x57, 0xf2, 0x58, 0x4d,
+ 0xbf, 0x4f, 0x49, 0xee, 0xb0, 0x8e, 0x38, 0x71, 0x6f, 0x29, 0x8a, 0x45,
+ 0xbf, 0xf9, 0x35, 0x69, 0x99, 0x0b, 0xb1, 0x7d, 0x59, 0x9b, 0x76, 0xa3,
+ 0x28, 0x29, 0xeb, 0xd1, 0xe3, 0xc1, 0x22, 0x72, 0x00, 0x6f, 0x52, 0x74,
+ 0xd8, 0x6e, 0x77, 0xa7, 0x04, 0x4b, 0x72, 0xdc, 0xfc, 0xe5, 0xcc, 0xaf,
+ 0xb0, 0x75, 0x70, 0x1a, 0x16, 0xf5, 0x55, 0x23, 0xee, 0xb7, 0xed, 0xe7,
+ 0xe8, 0x6b, 0x09, 0xe6, 0x58, 0xbb, 0xfa, 0x63, 0xc4, 0x94, 0x12, 0xe4,
+ 0x72, 0x3d, 0xd1, 0x4d, 0xd0, 0xd4, 0xaf, 0xd8, 0x23, 0x99, 0xc5, 0x79,
+ 0x13, 0xee, 0x3a, 0x7e, 0x43, 0x29, 0xce, 0x97, 0xe4, 0xd6, 0xc5, 0xff,
+ 0xfc, 0x12, 0xb7, 0xf9, 0xd7, 0x95, 0xbf, 0xff, 0xdf, 0x58, 0x7e, 0x62,
+ 0xca, 0xd9, 0xb5, 0xfc, 0x7b, 0x39, 0x32, 0xd6, 0xeb, 0xe5, 0xdc, 0x9a,
+ 0x25, 0x7c, 0x49, 0xce, 0xdc, 0x1e, 0x4f, 0x14, 0x30, 0x4e, 0xaa, 0x0b,
+ 0x3c, 0x50, 0xfd, 0x1e, 0x14, 0x32, 0x9e, 0x55, 0x61, 0xb3, 0xdf, 0xc6,
+ 0x62, 0xb3, 0x00, 0x87, 0x1b, 0x62, 0x72, 0xce, 0xa2, 0xdd, 0xe3, 0xf0,
+ 0xd1, 0xd5, 0xf7, 0xfc, 0xe1, 0xba, 0xf5, 0x26, 0x72, 0x37, 0x39, 0x5f,
+ 0xd0, 0x86, 0x53, 0x15, 0xf2, 0xae, 0xd0, 0x26, 0xe7, 0xdc, 0x59, 0x51,
+ 0xad, 0xac, 0xa3, 0xe9, 0x38, 0x61, 0xd4, 0xeb, 0x95, 0x2a, 0xe3, 0xb9,
+ 0xf2, 0xae, 0x6d, 0xf9, 0xa3, 0x8c, 0xf5, 0x72, 0x86, 0xe2, 0x5f, 0xda,
+ 0xa7, 0x58, 0x83, 0xed, 0x4f, 0x34, 0x63, 0x62, 0x95, 0xc4, 0xff, 0xff,
+ 0xe6, 0xcb, 0x73, 0xba, 0x6d, 0xa9, 0x1f, 0x96, 0xca, 0xb9, 0x24, 0x69,
+ 0x7b, 0x3b, 0xf3, 0x27, 0x8f, 0x11, 0xc6, 0xbb, 0xc2, 0xd2, 0x9c, 0xfd,
+ 0xa4, 0x1c, 0xa7, 0x28, 0x34, 0xce, 0x4f, 0xbe, 0x3b, 0xf2, 0xd7, 0xa5,
+ 0xc2, 0x0f, 0xb7, 0xa5, 0x36, 0x91, 0x9b, 0x8b, 0x3c, 0xbf, 0xb7, 0xd7,
+ 0xf8, 0x2b, 0x59, 0xf6, 0xee, 0xc9, 0xf6, 0xc4, 0x16, 0xe4, 0x4c, 0x8e,
+ 0xdc, 0x93, 0x3a, 0xa2, 0xb3, 0xa9, 0x75, 0x5c, 0xcc, 0x85, 0x6f, 0xc0,
+ 0xa3, 0xf4, 0xc1, 0x99, 0xc6, 0xeb, 0x76, 0x97, 0x9c, 0x9f, 0xa9, 0xd5,
+ 0xa6, 0xf4, 0xf5, 0x0b, 0x47, 0x96, 0x42, 0xca, 0xd2, 0x9f, 0x92, 0xb3,
+ 0xa8, 0x9f, 0xd9, 0xb5, 0x55, 0xf2, 0xfc, 0xc2, 0x64, 0xfb, 0x35, 0xce,
+ 0xd9, 0xbe, 0x7d, 0xa9, 0xbc, 0xdc, 0xb2, 0xde, 0xea, 0xcf, 0xf7, 0x55,
+ 0x77, 0x79, 0x3c, 0x22, 0x5b, 0xbc, 0xf4, 0x4a, 0x99, 0xe1, 0xcb, 0x9f,
+ 0x59, 0x9d, 0xe1, 0xd4, 0xc9, 0xf7, 0x29, 0x32, 0x6e, 0x62, 0x9e, 0x7a,
+ 0xf5, 0x18, 0xb5, 0x29, 0x63, 0x92, 0x3a, 0x32, 0x2e, 0x6d, 0xd2, 0x0e,
+ 0x4a, 0xcb, 0x50, 0x2c, 0x75, 0x84, 0xbb, 0x6a, 0x0e, 0x07, 0x2f, 0x17,
+ 0x5e, 0x2e, 0xb6, 0x51, 0x66, 0xdb, 0xef, 0x39, 0x31, 0x53, 0xda, 0xe1,
+ 0x38, 0xc6, 0x56, 0xd1, 0xce, 0xed, 0x2e, 0xe2, 0xa7, 0xfd, 0x5e, 0x73,
+ 0x00, 0x5b, 0x13, 0xa2, 0x6b, 0x23, 0x70, 0x88, 0xd8, 0xb1, 0xd9, 0xe1,
+ 0x1b, 0x1e, 0x74, 0xa7, 0xf3, 0xfb, 0xa3, 0x85, 0x72, 0xf6, 0x36, 0x20,
+ 0x3a, 0xef, 0x36, 0xc9, 0xb3, 0xb4, 0x85, 0xba, 0x9b, 0x5c, 0x69, 0x3d,
+ 0xfe, 0x99, 0xf3, 0x2b, 0xe7, 0x8f, 0x73, 0x7b, 0x95, 0x71, 0xda, 0x51,
+ 0x2e, 0x5e, 0x81, 0xf1, 0x9d, 0x3c, 0x69, 0xf2, 0x5c, 0x66, 0x77, 0xe6,
+ 0x9f, 0xed, 0x71, 0xe7, 0x5c, 0xe6, 0xe5, 0x77, 0x3a, 0xd2, 0x9a, 0x6d,
+ 0x1f, 0xe0, 0xb3, 0xcb, 0x67, 0x34, 0x19, 0xd3, 0x0d, 0x39, 0xcb, 0xf9,
+ 0x4f, 0x9c, 0xbb, 0xa9, 0x65, 0xc7, 0x2b, 0x72, 0x67, 0x96, 0x63, 0xea,
+ 0x42, 0x23, 0x8f, 0xab, 0x41, 0xcb, 0x72, 0x70, 0xf5, 0x0e, 0x67, 0x0f,
+ 0x3e, 0x8d, 0x60, 0x6b, 0x1b, 0x2c, 0xbb, 0xd8, 0xc8, 0xe3, 0x80, 0x61,
+ 0xce, 0x51, 0xba, 0x30, 0x3b, 0x5c, 0x2c, 0x1c, 0x3b, 0xe8, 0x8e, 0x06,
+ 0xb5, 0x0f, 0x10, 0xaa, 0x3b, 0xe6, 0xec, 0x95, 0x0a, 0x36, 0x18, 0x58,
+ 0x9f, 0x21, 0xdf, 0x1e, 0x93, 0x77, 0x1d, 0xe5, 0xda, 0x69, 0x9f, 0xd7,
+ 0x82, 0xa5, 0xed, 0xc4, 0x52, 0xeb, 0xcf, 0x3d, 0x4e, 0x7b, 0xc1, 0xf6,
+ 0x61, 0x25, 0xd8, 0xba, 0x51, 0xc9, 0xb7, 0xe7, 0xfb, 0x92, 0xf6, 0xea,
+ 0x58, 0xbf, 0x7a, 0xf2, 0xfd, 0x42, 0x83, 0x6d, 0x5c, 0xbd, 0x9f, 0x3c,
+ 0x3d, 0x2e, 0x7b, 0x51, 0x87, 0x27, 0x39, 0xe1, 0xb1, 0x3f, 0xd8, 0x8b,
+ 0xfa, 0xd2, 0x3e, 0x63, 0xec, 0xb3, 0xb5, 0x58, 0x89, 0x91, 0x31, 0x74,
+ 0xa1, 0x30, 0x1c, 0xaa, 0x7b, 0x19, 0xd0, 0xdd, 0xd1, 0x50, 0x60, 0xd8,
+ 0xd9, 0xd3, 0x35, 0xbd, 0x8b, 0x9c, 0xfa, 0xd5, 0xe4, 0xc5, 0x7f, 0x5c,
+ 0x27, 0x25, 0x86, 0xd1, 0x56, 0xaf, 0xc4, 0xe6, 0x17, 0xb3, 0x9d, 0xba,
+ 0x30, 0xf4, 0x82, 0x68, 0x5e, 0x47, 0xa1, 0xba, 0x0f, 0x38, 0x9f, 0x47,
+ 0x9b, 0x43, 0x81, 0x21, 0xe7, 0x8c, 0xa7, 0xe8, 0xc5, 0xf4, 0xe6, 0xe6,
+ 0x5e, 0x17, 0xbe, 0xcd, 0x7c, 0x32, 0x8e, 0x91, 0x84, 0x97, 0x63, 0xa9,
+ 0xd7, 0xb6, 0xa3, 0x82, 0x36, 0x8e, 0xd8, 0xe6, 0x06, 0xe2, 0x77, 0x02,
+ 0x31, 0xd7, 0x8d, 0xe5, 0x88, 0x93, 0x40, 0xbb, 0x8c, 0x38, 0x39, 0x51,
+ 0x7d, 0xdd, 0x0e, 0xda, 0x6f, 0xda, 0x1f, 0x0c, 0x58, 0x88, 0xe3, 0xc5,
+ 0xc4, 0xc2, 0xff, 0xc7, 0x05, 0xcb, 0x2c, 0x81, 0xbc, 0x5f, 0x90, 0xbe,
+ 0x67, 0x59, 0x28, 0xa8, 0xbf, 0x32, 0xb9, 0x27, 0xdd, 0x9d, 0xf8, 0xad,
+ 0xbc, 0xc7, 0xc4, 0x7a, 0x7f, 0xac, 0x8c, 0xf4, 0xed, 0xc5, 0xa1, 0xbe,
+ 0x3e, 0x6c, 0x79, 0x82, 0x32, 0x1a, 0x36, 0x16, 0x9a, 0x5d, 0xcc, 0xa5,
+ 0x7d, 0x58, 0xa7, 0xcd, 0x8e, 0xa8, 0x2c, 0x37, 0x94, 0xce, 0xad, 0x3b,
+ 0x6e, 0x75, 0xf6, 0xbc, 0x7b, 0x98, 0xa3, 0x38, 0xf1, 0x53, 0xf3, 0x46,
+ 0x63, 0xca, 0xce, 0x4c, 0x8b, 0xb2, 0x23, 0x2d, 0x6d, 0x75, 0x2a, 0x3d,
+ 0x99, 0xbf, 0xa5, 0x4f, 0x58, 0x38, 0x6d, 0xca, 0xbb, 0x39, 0xd2, 0xae,
+ 0x85, 0xe1, 0xe6, 0x7f, 0xcd, 0x3b, 0x3a, 0xa2, 0xd3, 0x4e, 0x6c, 0x1e,
+ 0x7c, 0x1c, 0xdd, 0x83, 0xa7, 0x9c, 0x33, 0x46, 0x1e, 0xc3, 0x6b, 0x5d,
+ 0x1f, 0x0d, 0x1e, 0xb1, 0x90, 0x2d, 0x97, 0xf3, 0xf9, 0x55, 0xd1, 0x13,
+ 0xd8, 0xa9, 0xc9, 0xbb, 0x27, 0x3d, 0xe4, 0x11, 0xb2, 0x6f, 0xbb, 0x1a,
+ 0x5f, 0xef, 0x95, 0x39, 0x2c, 0xb3, 0x0a, 0xa3, 0xc1, 0xd8, 0x3a, 0x67,
+ 0x0e, 0x1b, 0x70, 0x32, 0xfb, 0x38, 0xde, 0xdb, 0xd3, 0x05, 0x35, 0x1c,
+ 0x0c, 0xdc, 0x06, 0xbb, 0xeb, 0xb8, 0x19, 0xb3, 0x3c, 0x08, 0x1e, 0x76,
+ 0xa9, 0xc0, 0x0b, 0x7b, 0xe0, 0x9d, 0xc1, 0xf9, 0x9f, 0xcf, 0x18, 0x5d,
+ 0x6e, 0xd8, 0x0b, 0xfe, 0xb1, 0x29, 0xd8, 0x63, 0xb8, 0xac, 0xbf, 0x99,
+ 0x8e, 0x60, 0x5f, 0x44, 0x35, 0xda, 0xef, 0x52, 0xa1, 0xf8, 0xa2, 0xf2,
+ 0x5e, 0x69, 0x17, 0xee, 0x6c, 0xf4, 0x59, 0xa5, 0xd1, 0x60, 0xdf, 0x29,
+ 0x25, 0x58, 0x67, 0xa9, 0x6d, 0x9c, 0xe7, 0x3a, 0xbc, 0x42, 0x0e, 0xd2,
+ 0xca, 0xd8, 0xbb, 0x34, 0xa9, 0x3b, 0xeb, 0x4c, 0xaa, 0x51, 0x13, 0x29,
+ 0x52, 0x34, 0xdc, 0x96, 0x05, 0x8e, 0xa6, 0x57, 0xe3, 0x9d, 0x3d, 0x26,
+ 0xf3, 0x54, 0x9d, 0xb8, 0xf5, 0xbd, 0x32, 0xc1, 0x80, 0x0e, 0xd3, 0xaa,
+ 0x57, 0x19, 0xfb, 0x3d, 0x2a, 0x16, 0xce, 0x8c, 0x86, 0xc6, 0x17, 0xb8,
+ 0xdc, 0x88, 0x64, 0x65, 0xfd, 0x53, 0x97, 0xb3, 0xc9, 0xb8, 0x2b, 0xe9,
+ 0x25, 0xff, 0xac, 0xc6, 0x6f, 0xc8, 0x83, 0x7f, 0x4d, 0xbe, 0x3b, 0xc1,
+ 0x78, 0x3e, 0x91, 0x29, 0x66, 0xbe, 0xe8, 0x91, 0x1c, 0x78, 0xdc, 0xc3,
+ 0xb9, 0x28, 0x6b, 0xf4, 0xe3, 0xdc, 0xb0, 0x17, 0x77, 0xec, 0x09, 0xee,
+ 0x9b, 0x50, 0xab, 0xf0, 0xc9, 0x70, 0x31, 0x96, 0x0f, 0x78, 0x29, 0x9b,
+ 0x8d, 0x5d, 0xc4, 0xff, 0x8f, 0xf8, 0xac, 0x65, 0x0f, 0x94, 0xcc, 0xdc,
+ 0x59, 0xe4, 0xec, 0x06, 0xeb, 0x97, 0x60, 0xd9, 0x80, 0xf0, 0x34, 0x15,
+ 0x1f, 0x0e, 0x2b, 0xf8, 0x20, 0x6d, 0x62, 0x21, 0xfb, 0xdb, 0x9c, 0x7a,
+ 0xc1, 0xf6, 0xd2, 0xcf, 0xd7, 0x64, 0x4c, 0x3c, 0x98, 0xd6, 0x19, 0x53,
+ 0xde, 0xb6, 0x5d, 0x46, 0x23, 0xde, 0xde, 0x6d, 0x9c, 0x78, 0xd7, 0x15,
+ 0x1a, 0x9f, 0xeb, 0x6a, 0xc4, 0x5b, 0x07, 0x1b, 0xf1, 0xb3, 0xfe, 0x05,
+ 0xb8, 0xb9, 0x31, 0x86, 0xf3, 0x73, 0x1b, 0xf1, 0xe6, 0x7e, 0x1d, 0x3b,
+ 0x52, 0xcd, 0xd0, 0x47, 0xc7, 0xc9, 0x4f, 0x23, 0xa8, 0x67, 0x4e, 0x65,
+ 0xf4, 0xdb, 0x5d, 0x25, 0xd1, 0x2e, 0xec, 0x34, 0xa3, 0x98, 0xb3, 0x5f,
+ 0xf4, 0x60, 0xdb, 0xeb, 0xe6, 0x46, 0xf1, 0x72, 0x9f, 0x41, 0x3f, 0x8d,
+ 0x52, 0x0f, 0x3a, 0x9e, 0x24, 0x36, 0x87, 0x9e, 0x30, 0x2e, 0x1c, 0xe0,
+ 0xef, 0x05, 0x07, 0x9a, 0xd1, 0xce, 0xfe, 0x13, 0xa9, 0x18, 0xf6, 0x8d,
+ 0x36, 0x70, 0xcc, 0x26, 0xc7, 0x5f, 0x63, 0xfd, 0x46, 0x69, 0x41, 0xdf,
+ 0x68, 0x2b, 0xf9, 0x66, 0x17, 0x79, 0x66, 0x2b, 0x7a, 0xd9, 0xd6, 0xd6,
+ 0x94, 0x89, 0x65, 0xc9, 0x56, 0x3c, 0x9d, 0x90, 0x33, 0x8d, 0x46, 0x64,
+ 0x9e, 0x22, 0xef, 0x7d, 0xb5, 0xe2, 0x10, 0x75, 0xb2, 0x70, 0x60, 0x39,
+ 0xed, 0xd0, 0x8b, 0x45, 0x7b, 0x74, 0x3c, 0x95, 0xba, 0x13, 0xef, 0x8c,
+ 0x98, 0x68, 0x4b, 0x8a, 0xbe, 0xe5, 0x5c, 0x4d, 0x1c, 0xc7, 0x19, 0x5b,
+ 0x7e, 0x33, 0x10, 0xfb, 0x1b, 0x4e, 0xf3, 0x49, 0x15, 0xc1, 0xce, 0x19,
+ 0x9c, 0xf0, 0x9b, 0x1a, 0xe5, 0x6c, 0x94, 0x8b, 0xa8, 0x16, 0xb4, 0xca,
+ 0x55, 0x4b, 0xe7, 0x7d, 0xcb, 0xad, 0x6e, 0xc2, 0x37, 0x06, 0xdc, 0xe4,
+ 0xf4, 0x2a, 0x73, 0x11, 0xab, 0x83, 0xb6, 0x61, 0x95, 0xa9, 0xb9, 0x79,
+ 0xdb, 0x2e, 0xef, 0xa1, 0x19, 0x2e, 0xec, 0x32, 0x6b, 0xda, 0x4a, 0x58,
+ 0x6f, 0x69, 0x38, 0x18, 0x2b, 0x52, 0x9b, 0x99, 0x27, 0x3e, 0x8e, 0x75,
+ 0x7b, 0x1e, 0xc7, 0x1a, 0x7e, 0x3a, 0xf6, 0xd8, 0x5d, 0x4b, 0x4c, 0x05,
+ 0x2f, 0x1a, 0x76, 0x57, 0x97, 0x69, 0x70, 0x6e, 0x65, 0x5e, 0x1f, 0x47,
+ 0xe7, 0xa1, 0xc7, 0xf1, 0x28, 0xed, 0xab, 0x92, 0x7e, 0xbc, 0x32, 0x69,
+ 0x77, 0xdd, 0xdc, 0x58, 0x87, 0x4f, 0x9d, 0xfc, 0x43, 0xec, 0x75, 0xab,
+ 0x93, 0x13, 0xa7, 0x55, 0xb9, 0xde, 0xed, 0x5c, 0x5b, 0xea, 0x2b, 0x65,
+ 0xf9, 0xd8, 0xf2, 0x5b, 0xb6, 0xfb, 0xbb, 0x3d, 0xe5, 0x78, 0xa2, 0x52,
+ 0xe2, 0x87, 0xac, 0xed, 0x42, 0x31, 0xe6, 0x32, 0xcf, 0x7a, 0xe2, 0x38,
+ 0xb6, 0x93, 0xb7, 0xf9, 0xc3, 0x92, 0x03, 0xd7, 0x9b, 0x5b, 0xd4, 0x5b,
+ 0x89, 0xed, 0x0a, 0x76, 0xd6, 0xf6, 0xa1, 0x97, 0xbe, 0xba, 0xab, 0x36,
+ 0x18, 0xef, 0x45, 0xd4, 0xde, 0x35, 0xbd, 0xe7, 0xdf, 0xf0, 0x5e, 0x96,
+ 0xbc, 0xb7, 0x9d, 0x7f, 0x37, 0xeb, 0x71, 0x74, 0xed, 0x91, 0xf9, 0x7f,
+ 0x1c, 0x8f, 0x51, 0xfe, 0xce, 0x81, 0xc7, 0xf1, 0x4d, 0xda, 0x4e, 0x45,
+ 0xd3, 0xd1, 0xc7, 0x2a, 0x30, 0xbb, 0xaf, 0x1c, 0xe3, 0x0f, 0x57, 0xca,
+ 0x39, 0x28, 0x62, 0x62, 0xaf, 0xf2, 0x38, 0xd6, 0x0f, 0x1d, 0xa0, 0x2f,
+ 0x3a, 0xfe, 0x47, 0x2c, 0xce, 0xc7, 0xab, 0x00, 0xd6, 0x11, 0x93, 0x73,
+ 0xb8, 0xee, 0xc7, 0x9a, 0xc4, 0x61, 0xc7, 0xf7, 0x0b, 0xa2, 0xab, 0xe8,
+ 0xf7, 0x6d, 0xf4, 0xfb, 0xe5, 0xf4, 0xfb, 0x56, 0xfa, 0x7d, 0x0b, 0xfd,
+ 0x3e, 0x46, 0xbf, 0x8f, 0xd2, 0xef, 0x23, 0xf4, 0xfb, 0x66, 0xfa, 0xbd,
+ 0x49, 0xbf, 0x87, 0x72, 0xa2, 0xf9, 0x38, 0x3c, 0xfd, 0x5e, 0xda, 0x50,
+ 0xee, 0x3d, 0x99, 0x83, 0xc4, 0x9f, 0xd3, 0xe6, 0x9c, 0xc0, 0x62, 0xc6,
+ 0xd5, 0x61, 0x62, 0x44, 0x7a, 0xe4, 0xaf, 0x9c, 0x77, 0x2a, 0xd2, 0xc4,
+ 0xfd, 0x57, 0xa8, 0x8f, 0xa5, 0xe1, 0x1a, 0xf3, 0x69, 0xc6, 0xb0, 0x5f,
+ 0x18, 0xf5, 0x3d, 0x7e, 0x96, 0xf9, 0x41, 0xaa, 0xbe, 0x6f, 0x1a, 0x0c,
+ 0xab, 0x51, 0xdd, 0x0a, 0xac, 0xf4, 0x73, 0xcc, 0x72, 0xde, 0x6e, 0x25,
+ 0x1e, 0x1b, 0x6c, 0xc3, 0x7f, 0x19, 0xd4, 0xa8, 0x8b, 0x9a, 0xf1, 0x5b,
+ 0x5d, 0xf8, 0x71, 0x00, 0x2e, 0xff, 0x35, 0xc0, 0xe7, 0x55, 0x98, 0x73,
+ 0x58, 0xde, 0xef, 0x4b, 0x57, 0xb9, 0x1a, 0x66, 0x42, 0x6c, 0x04, 0x44,
+ 0x6a, 0x17, 0x33, 0xc1, 0x39, 0xce, 0x3b, 0x40, 0xb1, 0x55, 0x82, 0xe9,
+ 0x45, 0xd8, 0x5a, 0xe7, 0xe0, 0xec, 0xb3, 0x72, 0x6e, 0xb0, 0x8a, 0x78,
+ 0xe4, 0x8b, 0xb6, 0x62, 0x5b, 0xaf, 0x75, 0x7f, 0x15, 0x96, 0xa3, 0xa7,
+ 0x37, 0xa7, 0x83, 0x87, 0xc3, 0x1a, 0xa9, 0x42, 0x48, 0x9f, 0xa3, 0xc0,
+ 0xdd, 0xd1, 0x1c, 0xc1, 0x83, 0x99, 0x04, 0xfa, 0x38, 0xc6, 0x0d, 0xf4,
+ 0xb3, 0x75, 0x7f, 0xfa, 0xdd, 0x4e, 0x7c, 0x33, 0xa1, 0xd3, 0xfe, 0x2f,
+ 0xda, 0xe9, 0x8a, 0x39, 0x7d, 0x55, 0x30, 0x3a, 0x57, 0xa8, 0xf3, 0x98,
+ 0xd3, 0x06, 0x8f, 0xc8, 0xc2, 0xf7, 0xf4, 0xa8, 0xd7, 0xaa, 0x20, 0x36,
+ 0xcf, 0x1a, 0x80, 0x32, 0x9c, 0x94, 0xf7, 0x20, 0xba, 0xf0, 0xff, 0x99,
+ 0x6d, 0x8e, 0xfd, 0x8c, 0xbb, 0x34, 0xcc, 0x4c, 0xca, 0x7d, 0x7b, 0xc1,
+ 0x67, 0x4d, 0xc1, 0x3a, 0xdd, 0xb5, 0x81, 0xf7, 0xab, 0xf1, 0x23, 0xc6,
+ 0xd9, 0xc0, 0xc0, 0x02, 0xa8, 0x4d, 0x5e, 0xdc, 0xdd, 0x50, 0x8a, 0xf8,
+ 0x4a, 0xe1, 0xa1, 0x92, 0xef, 0xbb, 0xa9, 0xcf, 0xff, 0x17, 0x0f, 0x99,
+ 0xcf, 0x61, 0xc2, 0x9f, 0x70, 0xf6, 0xdd, 0xd7, 0x99, 0x77, 0x28, 0x16,
+ 0xaf, 0xb7, 0xa5, 0x2c, 0x6c, 0x30, 0x99, 0x0b, 0xdd, 0x53, 0xc9, 0x9c,
+ 0x44, 0xca, 0x4b, 0xbb, 0x5b, 0x9d, 0xf6, 0x0e, 0xa6, 0xe4, 0x7a, 0xf7,
+ 0x64, 0x9f, 0x77, 0x01, 0x95, 0x5e, 0xe2, 0xad, 0x82, 0x33, 0xb5, 0x09,
+ 0xfa, 0x34, 0x7e, 0xec, 0x46, 0x4d, 0xba, 0x5f, 0x75, 0xfd, 0xf8, 0x1a,
+ 0xcc, 0x31, 0x7f, 0xaf, 0xca, 0x7c, 0xc4, 0xf0, 0x54, 0x48, 0x41, 0xa5,
+ 0x61, 0x9c, 0xff, 0x19, 0x7d, 0x6b, 0xc2, 0x95, 0xc0, 0x53, 0x63, 0xa7,
+ 0xec, 0xf1, 0x6b, 0xfc, 0x9c, 0x73, 0xa9, 0xdb, 0x86, 0x0f, 0x06, 0x65,
+ 0xce, 0x64, 0x9d, 0x9f, 0xb1, 0x5d, 0xd5, 0x51, 0xca, 0x7b, 0xa7, 0x87,
+ 0x4d, 0xe6, 0x3a, 0x6d, 0xf8, 0xc7, 0xc1, 0x95, 0xf8, 0xfd, 0x60, 0x4d,
+ 0xdb, 0x7f, 0x52, 0x6d, 0x7b, 0x69, 0xf8, 0x6b, 0xf8, 0x65, 0xa5, 0x86,
+ 0xa7, 0x69, 0x43, 0xbf, 0x4f, 0x58, 0x4b, 0xaf, 0x21, 0x16, 0xfc, 0xef,
+ 0x44, 0xf0, 0xc2, 0x49, 0x67, 0x5f, 0xa9, 0xde, 0xfc, 0xd0, 0x15, 0x8c,
+ 0x9f, 0x51, 0x83, 0xd6, 0x36, 0x65, 0x39, 0xec, 0x4c, 0x2b, 0xce, 0x67,
+ 0xa6, 0xda, 0x42, 0x97, 0x8d, 0x2a, 0xb1, 0x03, 0xb1, 0x07, 0xda, 0x22,
+ 0x73, 0xb9, 0x9f, 0x92, 0x47, 0x77, 0x7f, 0x95, 0xf6, 0x98, 0xa2, 0x3d,
+ 0xa6, 0x68, 0x8f, 0xc4, 0xa4, 0xe7, 0x89, 0x55, 0x3f, 0x48, 0xd1, 0x1e,
+ 0xe9, 0x3f, 0xcf, 0xd1, 0x7f, 0x72, 0x5c, 0xb9, 0xdd, 0x39, 0xb7, 0xf6,
+ 0x06, 0x63, 0x62, 0xe2, 0x09, 0x79, 0x27, 0xad, 0x66, 0x43, 0x16, 0xc1,
+ 0xf6, 0x5e, 0xe5, 0xb3, 0x72, 0x39, 0x67, 0xfb, 0xed, 0x90, 0xf8, 0x40,
+ 0x6e, 0x3f, 0xe0, 0xc8, 0xc8, 0x63, 0x65, 0xf2, 0x7e, 0xd4, 0xc1, 0xbd,
+ 0xff, 0x92, 0xce, 0xfe, 0x3b, 0xe5, 0x10, 0x7d, 0xfd, 0x5b, 0xc7, 0x2e,
+ 0xba, 0xfc, 0x1b, 0xfb, 0x97, 0x55, 0x32, 0xfe, 0x55, 0xf8, 0x62, 0xb0,
+ 0x05, 0xe7, 0x19, 0x7f, 0xdf, 0x6a, 0x1a, 0xef, 0x0c, 0x20, 0xd8, 0x51,
+ 0xae, 0x46, 0x91, 0xcd, 0xb4, 0xe0, 0xb3, 0x44, 0x14, 0x07, 0x12, 0x35,
+ 0xed, 0x35, 0xae, 0xb3, 0x6a, 0x7c, 0x86, 0x58, 0x54, 0x0c, 0x9f, 0x92,
+ 0x5f, 0x2e, 0xac, 0x8d, 0x60, 0x88, 0x6d, 0x7a, 0xa2, 0x1a, 0x46, 0x9a,
+ 0xc5, 0x56, 0x73, 0xef, 0x4e, 0xfd, 0xa9, 0xbf, 0x2e, 0xda, 0xe3, 0x7b,
+ 0x4d, 0x17, 0xed, 0x71, 0xcd, 0x6b, 0x69, 0xf4, 0xe1, 0xd2, 0x3d, 0xf2,
+ 0x6e, 0xa9, 0xf8, 0xb3, 0x82, 0x1f, 0x84, 0xc7, 0xdb, 0xa6, 0x21, 0xf8,
+ 0xec, 0x7d, 0xb4, 0xf5, 0x93, 0x49, 0x59, 0x53, 0x6c, 0xc1, 0xfb, 0x2c,
+ 0xef, 0xa6, 0x5f, 0x9c, 0xcc, 0xb8, 0xdd, 0xbf, 0x4c, 0x2a, 0xcc, 0x4b,
+ 0x97, 0xe3, 0x97, 0x99, 0x37, 0xd5, 0x8f, 0x35, 0x13, 0x67, 0xb2, 0x2b,
+ 0x69, 0x4f, 0x92, 0xff, 0xc7, 0x98, 0xff, 0x07, 0x3b, 0x8f, 0x60, 0x25,
+ 0xca, 0x0f, 0xad, 0x42, 0xd9, 0x1e, 0xe2, 0x67, 0x88, 0xf9, 0x3f, 0xaf,
+ 0x67, 0xec, 0x91, 0xf7, 0x0d, 0xca, 0xed, 0xed, 0xab, 0x44, 0x2f, 0x82,
+ 0x27, 0x7f, 0x57, 0x8e, 0xb2, 0x55, 0xc0, 0x21, 0xa9, 0x67, 0xb0, 0xde,
+ 0x4a, 0x54, 0xee, 0xa9, 0x89, 0x2c, 0x46, 0xcd, 0xf9, 0xdb, 0xd4, 0x95,
+ 0xb8, 0xfe, 0xd0, 0x3f, 0x73, 0x0e, 0xa4, 0x6c, 0x35, 0x9e, 0xa0, 0xdd,
+ 0x16, 0x92, 0x13, 0xb6, 0x24, 0x7f, 0x6d, 0xcf, 0xa4, 0x2f, 0x7e, 0xf6,
+ 0x15, 0x60, 0x5d, 0xd6, 0x60, 0xbc, 0x2b, 0x46, 0x7c, 0xe8, 0x29, 0xbb,
+ 0x3c, 0xea, 0xc6, 0x9a, 0x6c, 0x03, 0x16, 0x0f, 0xd8, 0xf6, 0xb9, 0xb9,
+ 0x31, 0xf8, 0xa2, 0x3e, 0x62, 0x98, 0x0f, 0x8f, 0x26, 0x4b, 0xf8, 0x2d,
+ 0xc7, 0x4f, 0x42, 0xe3, 0xb3, 0x55, 0x63, 0xc3, 0x0c, 0x97, 0xd1, 0x9e,
+ 0x55, 0x24, 0xee, 0xfb, 0xf0, 0x08, 0xe3, 0xf3, 0xd2, 0x64, 0x00, 0xf1,
+ 0xac, 0x6d, 0xbf, 0xd9, 0xec, 0xc7, 0xc3, 0xac, 0xdf, 0x9a, 0xec, 0x41,
+ 0x37, 0xed, 0x22, 0x7e, 0xc8, 0xd0, 0x35, 0xc6, 0xfb, 0x75, 0x59, 0x2f,
+ 0x63, 0x58, 0x25, 0x6e, 0x63, 0x2c, 0x7a, 0x54, 0xce, 0xca, 0xd0, 0x07,
+ 0xdf, 0x31, 0xad, 0x1b, 0x5c, 0x30, 0xd0, 0x99, 0xf5, 0x63, 0x79, 0x32,
+ 0x78, 0x41, 0xde, 0xcd, 0xfb, 0xcc, 0xac, 0xc3, 0xc6, 0x6c, 0x00, 0xb7,
+ 0x27, 0x8f, 0x3e, 0x3a, 0x13, 0xd6, 0x7f, 0x9e, 0x81, 0x06, 0x7c, 0x3d,
+ 0x5b, 0xcd, 0xf6, 0x83, 0x1b, 0xde, 0x50, 0xaa, 0xf1, 0x8d, 0x43, 0x26,
+ 0xdb, 0x57, 0xb1, 0x8c, 0xed, 0x2c, 0x49, 0x5e, 0x8f, 0x47, 0x0e, 0x35,
+ 0xe3, 0xc1, 0x6c, 0x13, 0x16, 0x31, 0x3e, 0x75, 0x30, 0x37, 0xc4, 0xbd,
+ 0xc0, 0xed, 0x03, 0xa2, 0x7b, 0x28, 0x6f, 0x36, 0x8f, 0x33, 0x5f, 0x36,
+ 0x41, 0x43, 0x74, 0xf6, 0x92, 0x77, 0xd2, 0x56, 0x6f, 0xdf, 0xdf, 0x84,
+ 0xa5, 0x03, 0x2a, 0x6a, 0xc2, 0x85, 0x88, 0xb7, 0x29, 0x68, 0x19, 0x90,
+ 0x38, 0x2b, 0xdc, 0xc6, 0x64, 0x5c, 0x0d, 0xb1, 0x0f, 0x93, 0x71, 0x35,
+ 0x77, 0xbf, 0x3b, 0x25, 0x6b, 0x0b, 0x6f, 0x93, 0x2f, 0x85, 0xd1, 0xe2,
+ 0xc4, 0x68, 0x59, 0x13, 0xb7, 0xe0, 0x66, 0xec, 0x0e, 0xd3, 0xc6, 0x17,
+ 0x34, 0x4a, 0xac, 0xd6, 0x9d, 0xbd, 0xa9, 0xb1, 0x7e, 0xa3, 0xe3, 0x82,
+ 0x42, 0xfb, 0xda, 0x2f, 0x31, 0xd1, 0x8f, 0x8d, 0xc9, 0x28, 0xde, 0xe9,
+ 0x63, 0xbc, 0xb9, 0x31, 0xb6, 0xb4, 0x04, 0x86, 0xf9, 0x08, 0x42, 0xd6,
+ 0x49, 0xc6, 0xf6, 0xf3, 0xe9, 0x4a, 0x2c, 0xde, 0x23, 0x65, 0x1a, 0xf1,
+ 0xee, 0xb0, 0xec, 0x4d, 0x6e, 0xc2, 0x53, 0x7d, 0x2e, 0x0c, 0x99, 0x35,
+ 0x3d, 0x2a, 0xe3, 0xe7, 0xfc, 0xc6, 0xa0, 0xf6, 0x23, 0x72, 0xd5, 0x0b,
+ 0x4d, 0x8c, 0xca, 0xd7, 0x34, 0xa3, 0x85, 0x72, 0xb5, 0x18, 0xe2, 0x93,
+ 0x16, 0x1e, 0x6c, 0xde, 0x84, 0x93, 0x7d, 0x86, 0xf5, 0xb4, 0xac, 0x03,
+ 0x34, 0xf2, 0xf9, 0x74, 0x37, 0x36, 0x1b, 0xc2, 0x69, 0x75, 0xfa, 0x16,
+ 0x59, 0xa7, 0xd1, 0x8c, 0x77, 0x68, 0xaf, 0x3d, 0xe9, 0x05, 0x8c, 0xfd,
+ 0x12, 0xf3, 0xbd, 0x56, 0x80, 0xf5, 0xca, 0xbf, 0xa2, 0xe0, 0xf4, 0x01,
+ 0xe1, 0x58, 0x0b, 0x70, 0xff, 0x80, 0xec, 0x0b, 0xa8, 0x98, 0x7f, 0x68,
+ 0x35, 0xce, 0xed, 0xce, 0x71, 0xae, 0x37, 0xc3, 0xd6, 0xd7, 0xc9, 0xb9,
+ 0xda, 0x4b, 0xc9, 0xb9, 0xc8, 0xe5, 0xea, 0x36, 0x2a, 0x6e, 0x84, 0xb2,
+ 0x11, 0xf2, 0x0a, 0xe1, 0x17, 0x01, 0x3c, 0x93, 0x69, 0xc6, 0x6d, 0xc9,
+ 0x6a, 0x8c, 0x90, 0x6f, 0xa5, 0x89, 0x17, 0xe9, 0x0c, 0xe3, 0xca, 0x70,
+ 0x15, 0x3f, 0x3a, 0x3f, 0xb3, 0xf8, 0x31, 0x9c, 0x7b, 0x6b, 0x68, 0xcb,
+ 0xb1, 0x36, 0xc5, 0xd9, 0xdb, 0x18, 0xca, 0x48, 0xac, 0x56, 0x98, 0xb7,
+ 0xde, 0xa5, 0x49, 0x6e, 0x2a, 0xe7, 0x0e, 0x7e, 0xde, 0xa7, 0xe3, 0x5b,
+ 0x8d, 0x3b, 0x95, 0x58, 0xa5, 0xf3, 0x5e, 0x92, 0x55, 0x4c, 0xd9, 0x6e,
+ 0x9b, 0x2b, 0x6b, 0x94, 0x62, 0x97, 0x6c, 0x83, 0x39, 0xfa, 0xc3, 0x66,
+ 0x05, 0xf4, 0x0a, 0x5d, 0xce, 0x50, 0xd2, 0xdf, 0xfd, 0x78, 0x35, 0x11,
+ 0x47, 0x26, 0x51, 0xdf, 0xb3, 0x51, 0x71, 0xc9, 0xd9, 0xf3, 0xba, 0xb8,
+ 0x22, 0x3e, 0x16, 0x87, 0x27, 0xe9, 0xb5, 0xca, 0x59, 0xff, 0x9d, 0xb9,
+ 0x1d, 0x8c, 0x07, 0xf5, 0x9c, 0x62, 0xd5, 0x39, 0x7f, 0x9e, 0x46, 0x07,
+ 0xd6, 0x25, 0x0c, 0xc6, 0xc0, 0xd5, 0x76, 0x37, 0xe7, 0xe1, 0x58, 0xa2,
+ 0x03, 0xf7, 0x27, 0xea, 0xc7, 0x9f, 0xa4, 0x6d, 0xe1, 0xee, 0x0e, 0xb4,
+ 0xf0, 0xd9, 0x50, 0xaa, 0xe6, 0x42, 0x37, 0x75, 0x3d, 0x31, 0xad, 0xce,
+ 0x59, 0x97, 0x77, 0x1b, 0x3a, 0xcb, 0xeb, 0xc4, 0xb3, 0xfa, 0xd8, 0x80,
+ 0xfa, 0xef, 0x15, 0x4c, 0x97, 0x5c, 0x32, 0x82, 0xe3, 0x09, 0x1f, 0xbe,
+ 0x9e, 0xb4, 0xe8, 0x03, 0xc0, 0xfa, 0x6c, 0x33, 0xf3, 0x88, 0xa7, 0xec,
+ 0x0a, 0x87, 0xeb, 0xba, 0x69, 0x83, 0x0b, 0x70, 0x82, 0xb1, 0xb7, 0x66,
+ 0x9e, 0xa1, 0x2d, 0x52, 0xe4, 0x7d, 0xeb, 0x5f, 0xdb, 0xee, 0x68, 0x09,
+ 0x36, 0x0c, 0x85, 0x22, 0x2b, 0x19, 0x67, 0x9f, 0x6a, 0x36, 0xc6, 0x6d,
+ 0xc6, 0xc0, 0x19, 0xd1, 0x04, 0xe7, 0x3a, 0x24, 0xff, 0xaf, 0x03, 0x7f,
+ 0x41, 0x3b, 0xff, 0x24, 0x21, 0x7e, 0x62, 0x10, 0x37, 0xfd, 0xf8, 0x06,
+ 0xed, 0xfc, 0x7c, 0xa2, 0x0e, 0x59, 0xfa, 0x65, 0x07, 0xfd, 0xe3, 0xdd,
+ 0x44, 0x30, 0x7e, 0x93, 0xca, 0x7c, 0x8f, 0xfe, 0xf1, 0x51, 0x22, 0x42,
+ 0xdf, 0xf9, 0x2a, 0x3f, 0x0d, 0xf4, 0x87, 0x3a, 0xd6, 0xd1, 0xe9, 0x07,
+ 0x7e, 0x9c, 0x65, 0xf9, 0x03, 0xa9, 0x9a, 0xd6, 0x15, 0x4a, 0x8d, 0x59,
+ 0xa3, 0x54, 0x30, 0x9f, 0xd5, 0x68, 0xff, 0xb7, 0xe0, 0x43, 0x59, 0x4f,
+ 0x4e, 0x12, 0x8b, 0x92, 0xe8, 0x2f, 0x22, 0x97, 0x5b, 0xe9, 0x9c, 0xe5,
+ 0xaf, 0x3f, 0xf1, 0xa9, 0x12, 0x1c, 0x3f, 0xe3, 0x0a, 0x76, 0xcc, 0x20,
+ 0x8f, 0xfe, 0x0b, 0xfa, 0xc1, 0x37, 0x59, 0xf6, 0x93, 0xbe, 0x62, 0x7c,
+ 0x63, 0x88, 0x31, 0x37, 0x55, 0x80, 0x82, 0x3d, 0x5e, 0x3c, 0x78, 0x48,
+ 0xc7, 0x3e, 0x27, 0x57, 0x17, 0x9d, 0x52, 0x77, 0xc4, 0x88, 0x73, 0x73,
+ 0x81, 0x19, 0x07, 0x56, 0xe3, 0xd4, 0x6e, 0x9d, 0x71, 0x2f, 0x67, 0x27,
+ 0xcf, 0x86, 0x1d, 0x6e, 0x1e, 0x17, 0x6e, 0x5e, 0xc0, 0x71, 0x6d, 0x4d,
+ 0x85, 0xda, 0xb7, 0x51, 0x17, 0xb7, 0x67, 0xc5, 0xfe, 0x22, 0x78, 0x8e,
+ 0x63, 0xeb, 0xa7, 0xad, 0x1c, 0x48, 0x54, 0x33, 0x47, 0xf7, 0xc1, 0xa2,
+ 0xad, 0x58, 0xf2, 0x0e, 0x13, 0x6d, 0xc5, 0xa2, 0xad, 0x58, 0xb4, 0x15,
+ 0x8b, 0xb6, 0x62, 0x65, 0x16, 0xe0, 0x99, 0x3e, 0x03, 0x23, 0xec, 0x73,
+ 0xe7, 0x30, 0x39, 0xbc, 0xf3, 0x3e, 0x50, 0x9d, 0xe4, 0x29, 0xca, 0xc4,
+ 0xdd, 0xb7, 0x60, 0xa8, 0xef, 0x56, 0x7e, 0x14, 0xb4, 0xd2, 0x66, 0x7a,
+ 0xd2, 0x62, 0x83, 0x22, 0x93, 0x17, 0xc3, 0x99, 0x9b, 0x2b, 0x51, 0x2c,
+ 0xf1, 0x5d, 0xc1, 0x0e, 0xe7, 0x7e, 0xde, 0xd6, 0xe4, 0x9e, 0x85, 0x9a,
+ 0x79, 0x9b, 0xf0, 0x48, 0x9f, 0x8a, 0xdb, 0xc2, 0xf2, 0x7f, 0x08, 0x9a,
+ 0x99, 0x0f, 0xc8, 0xfe, 0x7c, 0x82, 0xfe, 0x99, 0xb3, 0x15, 0x19, 0x53,
+ 0xa6, 0x7f, 0x13, 0x4e, 0xf4, 0x1b, 0x8c, 0x59, 0x26, 0x32, 0xe9, 0x04,
+ 0x7d, 0x42, 0xfc, 0xdc, 0xc0, 0x33, 0x6c, 0x6b, 0xf6, 0x80, 0x0b, 0x95,
+ 0x8d, 0x6e, 0x94, 0xd0, 0xdf, 0x6f, 0x4b, 0xd7, 0x04, 0xbe, 0xa5, 0x24,
+ 0x9c, 0xf5, 0xd7, 0x5d, 0x29, 0x8c, 0xcf, 0x34, 0x2a, 0xb1, 0x6f, 0xb0,
+ 0x11, 0x8f, 0xed, 0x76, 0xd1, 0x46, 0xed, 0x05, 0xe5, 0x4d, 0x46, 0xc7,
+ 0x02, 0x97, 0xe0, 0x45, 0x23, 0xbe, 0xc1, 0x1c, 0x60, 0x7d, 0x7f, 0xd0,
+ 0x7c, 0x05, 0x41, 0xf3, 0x24, 0x16, 0xe0, 0x59, 0x93, 0xb8, 0x39, 0xaf,
+ 0x11, 0x1b, 0xf7, 0x1b, 0xb4, 0x29, 0x37, 0xf3, 0x63, 0xf9, 0xbf, 0x37,
+ 0xba, 0xb3, 0xc6, 0xf3, 0x32, 0xe4, 0x9c, 0x43, 0xb3, 0xfc, 0x4f, 0x06,
+ 0xa5, 0x87, 0xf8, 0x34, 0xa3, 0xd7, 0xe0, 0xb8, 0x5f, 0xb0, 0x4b, 0x0d,
+ 0xf9, 0x7f, 0x1c, 0xc4, 0x11, 0x8e, 0xfb, 0xc2, 0xcd, 0x6f, 0xdb, 0x95,
+ 0x86, 0xc4, 0x50, 0xe2, 0x49, 0x5a, 0xfa, 0x8f, 0xed, 0x08, 0x10, 0x3b,
+ 0x3a, 0xfa, 0x8d, 0x78, 0x29, 0x63, 0xd8, 0x46, 0x07, 0x63, 0x04, 0x5f,
+ 0x8c, 0xb6, 0x6f, 0x21, 0xa4, 0xad, 0x20, 0xee, 0x9c, 0xe6, 0x58, 0x7a,
+ 0x52, 0x82, 0x51, 0x3a, 0x8a, 0x7a, 0x63, 0xb8, 0x81, 0x39, 0x63, 0x41,
+ 0x6f, 0x0b, 0x6a, 0x99, 0x3f, 0xba, 0x7b, 0x5b, 0x61, 0x30, 0x97, 0x9c,
+ 0xd9, 0xbb, 0x1c, 0x0b, 0xc6, 0xf2, 0x1c, 0x5a, 0xc7, 0x11, 0x67, 0xdd,
+ 0xea, 0x29, 0x78, 0xee, 0xd3, 0x69, 0x53, 0x72, 0xe6, 0xc5, 0x6b, 0x55,
+ 0x12, 0x37, 0xcf, 0x50, 0xd7, 0xed, 0x03, 0xab, 0xed, 0x81, 0x94, 0xf0,
+ 0xa6, 0x2e, 0x78, 0x9a, 0x24, 0xf7, 0xd1, 0x31, 0x46, 0x8e, 0x3c, 0xcc,
+ 0x1c, 0xec, 0x8d, 0xfd, 0xab, 0x71, 0xff, 0x9e, 0xcb, 0x39, 0x9b, 0xd9,
+ 0x64, 0xfd, 0x7b, 0xda, 0xc5, 0x86, 0x12, 0xda, 0x85, 0x97, 0x76, 0xb1,
+ 0x2b, 0x15, 0x32, 0x0f, 0xd3, 0x2e, 0x6a, 0x89, 0x21, 0x1d, 0xbd, 0x92,
+ 0xef, 0x38, 0xef, 0xed, 0x55, 0x78, 0x10, 0xc0, 0x9b, 0xb4, 0x8f, 0x8d,
+ 0xbd, 0x76, 0x97, 0x9b, 0xb1, 0xa7, 0xa7, 0xb9, 0x1a, 0xaf, 0x65, 0x6e,
+ 0xc5, 0xa3, 0xfd, 0xd5, 0x78, 0x85, 0xb6, 0xf3, 0x76, 0x02, 0xf3, 0x2b,
+ 0xa0, 0xce, 0xac, 0x60, 0xac, 0xbe, 0x4d, 0x09, 0xb5, 0x2e, 0x42, 0xfd,
+ 0xf8, 0xcb, 0x4a, 0xb0, 0x93, 0x9c, 0xe5, 0xc4, 0x05, 0x62, 0xff, 0xeb,
+ 0x19, 0x39, 0x77, 0xe7, 0xc3, 0x38, 0xed, 0x6a, 0x9c, 0xf5, 0xbe, 0xd1,
+ 0x5f, 0xc7, 0x79, 0xf3, 0xa0, 0xd0, 0xf0, 0xe3, 0x14, 0xb1, 0xb4, 0x63,
+ 0x37, 0xc6, 0x03, 0x86, 0x71, 0xa2, 0x55, 0xa9, 0xc2, 0x9b, 0xc3, 0xb7,
+ 0x62, 0x63, 0x7f, 0x50, 0x8f, 0xd1, 0x37, 0x5f, 0xe3, 0xb3, 0xf5, 0xbb,
+ 0x67, 0xe1, 0x38, 0x6d, 0x6f, 0x9c, 0xb6, 0xb7, 0xb6, 0x5f, 0xc5, 0x8b,
+ 0xc3, 0xb7, 0xb0, 0x5f, 0x05, 0xb3, 0x6a, 0x15, 0x27, 0xff, 0xda, 0x91,
+ 0x72, 0xfe, 0x77, 0x81, 0xf3, 0x8e, 0xde, 0x9c, 0x51, 0x13, 0xb3, 0xf7,
+ 0xcb, 0xf8, 0xc8, 0xc3, 0x9c, 0xb5, 0xe9, 0x46, 0xdc, 0xbc, 0xa7, 0x12,
+ 0xe7, 0xf6, 0x1a, 0x56, 0xb9, 0xcb, 0x5e, 0x70, 0x2a, 0x1c, 0xe2, 0x3c,
+ 0x34, 0xa2, 0xe1, 0x50, 0x23, 0x42, 0x03, 0xb9, 0x18, 0xa1, 0x19, 0x0b,
+ 0xf0, 0x3d, 0xce, 0xfb, 0x5a, 0xe6, 0x80, 0x35, 0x43, 0x82, 0xbd, 0x36,
+ 0x73, 0xc5, 0x66, 0x4c, 0x8c, 0x8d, 0x73, 0x6c, 0x11, 0x9c, 0x25, 0xbf,
+ 0x7d, 0x9f, 0x31, 0xe3, 0x43, 0xe6, 0x80, 0x1f, 0x3a, 0x31, 0x43, 0xde,
+ 0xa5, 0xbd, 0x32, 0x6e, 0xec, 0xe2, 0x9c, 0x6e, 0xec, 0x37, 0xea, 0xfa,
+ 0xf8, 0x7b, 0xbd, 0x33, 0xc7, 0x31, 0xe2, 0xb9, 0x60, 0x85, 0xe0, 0x7f,
+ 0x0b, 0x73, 0xde, 0x56, 0x9c, 0xed, 0x0b, 0x99, 0x0b, 0x95, 0x56, 0xbc,
+ 0x47, 0x99, 0xfb, 0x28, 0x5f, 0x92, 0xbc, 0x6c, 0x66, 0xd2, 0x18, 0xff,
+ 0xd0, 0x25, 0x18, 0xd3, 0x8a, 0xf2, 0xec, 0xad, 0x38, 0xd5, 0xbf, 0x1c,
+ 0xa5, 0x43, 0xc2, 0x35, 0xa5, 0x4d, 0x37, 0xb6, 0xee, 0xbe, 0x13, 0xeb,
+ 0x0f, 0xe6, 0x72, 0xbe, 0xf5, 0x89, 0x4d, 0xcc, 0x75, 0x85, 0xbf, 0xd7,
+ 0xe1, 0x50, 0x2a, 0x26, 0x47, 0x42, 0x77, 0x30, 0x9f, 0x8b, 0xac, 0x20,
+ 0x7e, 0x2e, 0x0d, 0x13, 0x63, 0x2b, 0x82, 0x81, 0x97, 0x61, 0xe9, 0xbc,
+ 0x17, 0x58, 0x07, 0xd1, 0x89, 0x85, 0x65, 0x8c, 0x3b, 0xb7, 0xf5, 0xbb,
+ 0x29, 0xbb, 0x3c, 0xaf, 0xc3, 0x8f, 0x52, 0x56, 0x5c, 0x9e, 0x6f, 0x84,
+ 0xf8, 0x8a, 0xe8, 0xc9, 0x05, 0xb3, 0xa9, 0x26, 0xd6, 0x41, 0x8c, 0x2e,
+ 0x0d, 0x07, 0xcd, 0x6f, 0xa0, 0x99, 0x73, 0x2f, 0x32, 0x47, 0xb0, 0xfe,
+ 0x10, 0x9c, 0x7d, 0x7f, 0x79, 0x47, 0xe4, 0x3f, 0xf4, 0xed, 0x76, 0xec,
+ 0x69, 0x7d, 0xe3, 0x65, 0x1b, 0x3c, 0x90, 0xaa, 0xef, 0x74, 0xa1, 0xc6,
+ 0x2a, 0x87, 0x91, 0xee, 0x23, 0x2f, 0x8d, 0x23, 0xd8, 0x13, 0x87, 0xc4,
+ 0x8c, 0x7a, 0x4b, 0x43, 0x35, 0xdb, 0x8e, 0xe0, 0xad, 0x84, 0x4b, 0xb0,
+ 0x09, 0xf2, 0x4f, 0x8a, 0x22, 0xc4, 0xe1, 0x37, 0x12, 0xc5, 0xd0, 0x87,
+ 0x12, 0xce, 0xff, 0x11, 0xba, 0x39, 0x6b, 0x91, 0xaf, 0x2d, 0xc0, 0xab,
+ 0xfd, 0x3e, 0xcc, 0x27, 0x4f, 0xa9, 0x4b, 0x3e, 0x65, 0x97, 0x12, 0x87,
+ 0xeb, 0x87, 0x42, 0x9a, 0x47, 0xb1, 0xed, 0x03, 0x73, 0x7f, 0x6d, 0x4f,
+ 0x8b, 0x4a, 0x59, 0x23, 0xb2, 0x48, 0xfe, 0x9f, 0xd4, 0x3c, 0xa3, 0xf5,
+ 0x2c, 0x7c, 0xb8, 0x81, 0x58, 0x7a, 0xac, 0xb7, 0x12, 0x6f, 0xed, 0xee,
+ 0x91, 0x35, 0x4b, 0x18, 0xfc, 0xfd, 0x5a, 0x6f, 0x00, 0x3a, 0xb1, 0x4c,
+ 0xe7, 0x75, 0x03, 0x31, 0x5a, 0x27, 0x3e, 0xbf, 0xdd, 0x6b, 0x2f, 0xf0,
+ 0x35, 0x59, 0x6c, 0xbd, 0x0e, 0x0b, 0x88, 0xd1, 0x6f, 0xf4, 0x06, 0x4f,
+ 0x2c, 0x51, 0x15, 0x94, 0x34, 0x99, 0xec, 0xdb, 0x87, 0x17, 0x69, 0xdf,
+ 0x4f, 0xa4, 0x8e, 0x7e, 0x6d, 0x06, 0xac, 0xfa, 0x12, 0x04, 0x37, 0x78,
+ 0x14, 0x59, 0xe3, 0x90, 0xd8, 0x56, 0x8d, 0x1b, 0xc9, 0x4d, 0x74, 0xe2,
+ 0x77, 0x4d, 0x56, 0xe2, 0x1c, 0xb0, 0x66, 0x68, 0x35, 0x3e, 0x1c, 0x14,
+ 0x1f, 0xc5, 0x42, 0xb1, 0xff, 0x05, 0xe1, 0x90, 0x79, 0x86, 0xb8, 0x5c,
+ 0x3b, 0x96, 0x20, 0xfe, 0xca, 0xb9, 0x3c, 0x8c, 0xab, 0xc4, 0x81, 0xca,
+ 0x94, 0x60, 0x57, 0x00, 0x8d, 0xcc, 0xf7, 0xca, 0x53, 0xe2, 0x93, 0x96,
+ 0x9c, 0x1b, 0xc1, 0xcd, 0x63, 0x3e, 0xe8, 0x63, 0x1a, 0x3f, 0x7e, 0xe8,
+ 0x23, 0x55, 0xfc, 0x50, 0xd6, 0x91, 0x59, 0xfc, 0x50, 0x56, 0xc6, 0x31,
+ 0x73, 0x44, 0xc1, 0x4d, 0x8e, 0x6d, 0x89, 0x0f, 0x7a, 0xf1, 0xec, 0x28,
+ 0xb0, 0xa1, 0xdf, 0xc4, 0xe1, 0xfd, 0x39, 0x9c, 0xdb, 0xcc, 0x3e, 0x42,
+ 0x03, 0x61, 0xac, 0x4f, 0x8b, 0x7d, 0x36, 0xe2, 0xb7, 0x7b, 0x8d, 0xb6,
+ 0x35, 0x6a, 0x28, 0xb2, 0x9c, 0x18, 0xf6, 0xfe, 0x48, 0x23, 0x3e, 0x7c,
+ 0x62, 0x01, 0x8c, 0x70, 0x23, 0xce, 0x1c, 0xd8, 0x84, 0xf2, 0x27, 0x54,
+ 0xe2, 0x8f, 0x8a, 0xf1, 0xe9, 0x82, 0xed, 0x82, 0xa3, 0x5e, 0xab, 0x8c,
+ 0xb8, 0xb5, 0x8d, 0xb8, 0xf5, 0xb3, 0xb9, 0xe3, 0x98, 0x9f, 0x94, 0x73,
+ 0xad, 0xcc, 0xaf, 0xd4, 0x08, 0x9e, 0x24, 0x6e, 0xed, 0xea, 0x93, 0xf9,
+ 0xe2, 0xdc, 0x12, 0xb3, 0xb6, 0xa6, 0x73, 0x9c, 0xe8, 0x70, 0xbf, 0xa1,
+ 0xb9, 0x68, 0xcb, 0x43, 0x93, 0x78, 0xf5, 0x5b, 0xc6, 0xff, 0x47, 0xe6,
+ 0x45, 0x71, 0x36, 0x2d, 0x7e, 0x25, 0x71, 0x45, 0xc7, 0x87, 0xb4, 0xf1,
+ 0xa5, 0xd4, 0xf5, 0x19, 0xe6, 0x16, 0x2d, 0x8c, 0x73, 0x1f, 0xd3, 0x9e,
+ 0x97, 0x93, 0x3f, 0xbe, 0x97, 0x12, 0x1b, 0x59, 0x8e, 0x25, 0x59, 0xb1,
+ 0x05, 0x67, 0x9d, 0x95, 0xdf, 0x31, 0x9c, 0x4e, 0xfc, 0xb1, 0xb8, 0xb0,
+ 0x12, 0xaf, 0x0e, 0xca, 0x79, 0x17, 0x03, 0xde, 0xde, 0xa0, 0x56, 0xa2,
+ 0xc8, 0x9e, 0x6e, 0x9e, 0xfb, 0x4e, 0x38, 0x39, 0x76, 0x69, 0x34, 0xbf,
+ 0xbf, 0x98, 0xdf, 0x77, 0xb0, 0xf0, 0xfd, 0xb9, 0x01, 0xf2, 0x4f, 0x28,
+ 0x87, 0xe7, 0x16, 0xe0, 0xf6, 0x3d, 0x6d, 0x18, 0xd9, 0xfd, 0x31, 0x8a,
+ 0xfa, 0xd5, 0x7b, 0x7d, 0xa8, 0xa9, 0x7b, 0x48, 0xe9, 0xc2, 0xa2, 0xb0,
+ 0xbc, 0xe7, 0x23, 0x6b, 0xe6, 0x7d, 0xd8, 0x7c, 0x80, 0x79, 0xcc, 0xd8,
+ 0x75, 0x38, 0xaa, 0x31, 0x1e, 0x9a, 0x1f, 0xa3, 0xa0, 0xdf, 0xe3, 0x9c,
+ 0x05, 0x3c, 0x6a, 0x36, 0x61, 0xe5, 0xe4, 0x59, 0x40, 0x54, 0x5d, 0xbd,
+ 0x97, 0x00, 0x5f, 0xe9, 0xe4, 0xff, 0x1f, 0xc8, 0xbd, 0xdb, 0x63, 0xa0,
+ 0x77, 0xf4, 0x7f, 0x95, 0xe7, 0xce, 0x06, 0xfd, 0x6b, 0xca, 0x76, 0xa2,
+ 0x7d, 0xcf, 0xe3, 0x58, 0xb1, 0xe7, 0x3b, 0xb8, 0x73, 0xa0, 0xb6, 0x33,
+ 0xc2, 0x5c, 0xe7, 0x83, 0xf0, 0x38, 0x8e, 0x85, 0x8b, 0x60, 0xf9, 0xc9,
+ 0xb1, 0x6e, 0xfc, 0x8a, 0xbc, 0x4e, 0xca, 0xbf, 0xd3, 0xb6, 0x7e, 0xaf,
+ 0xb4, 0xf7, 0xf6, 0xa4, 0x7f, 0xfd, 0x7c, 0x9a, 0x9c, 0xa7, 0x79, 0x21,
+ 0xf5, 0x2b, 0x5b, 0x77, 0x9e, 0xe7, 0xef, 0xbf, 0x65, 0xc7, 0xfc, 0x72,
+ 0x7f, 0xd6, 0x64, 0xbd, 0xef, 0xe0, 0x01, 0xe6, 0xbf, 0xa7, 0x9b, 0xbe,
+ 0x83, 0x85, 0x43, 0x97, 0xea, 0xa0, 0x68, 0xf7, 0x3a, 0x07, 0xbb, 0xe9,
+ 0x61, 0xe4, 0x48, 0xb2, 0x57, 0x25, 0xfb, 0x27, 0x7f, 0x89, 0xcd, 0x7b,
+ 0x65, 0x6d, 0xd3, 0xb6, 0xd7, 0x1b, 0xb2, 0xc7, 0x97, 0x3f, 0x37, 0x27,
+ 0xed, 0x58, 0x8a, 0x95, 0x91, 0xba, 0x5b, 0x94, 0xbe, 0xcc, 0xd4, 0x31,
+ 0x4d, 0x93, 0xff, 0x97, 0xa7, 0x95, 0x44, 0xa7, 0x8e, 0xad, 0x47, 0xd9,
+ 0x9e, 0x39, 0xa2, 0xec, 0xca, 0x5c, 0xad, 0x8f, 0xe7, 0xec, 0x58, 0x9b,
+ 0xb4, 0x21, 0x32, 0xc1, 0x8f, 0x62, 0x91, 0x2b, 0xff, 0xec, 0x99, 0x49,
+ 0xb9, 0x0b, 0xa1, 0x57, 0xe6, 0xe4, 0xbe, 0x9f, 0x72, 0x9b, 0x4d, 0x31,
+ 0xa8, 0xf3, 0xa6, 0xca, 0x9e, 0x1f, 0xe7, 0x7f, 0xbb, 0xd4, 0x56, 0xae,
+ 0xdc, 0xcd, 0x7e, 0xb1, 0x21, 0x75, 0xde, 0xd4, 0x35, 0xfb, 0x02, 0xe2,
+ 0x47, 0x48, 0xdb, 0x8a, 0x5c, 0xbe, 0xb7, 0xe6, 0xca, 0x7c, 0x4f, 0xb0,
+ 0x0b, 0x23, 0x09, 0x0d, 0xef, 0x99, 0x92, 0xdf, 0xc9, 0xad, 0x28, 0xbe,
+ 0xc7, 0xfc, 0xf1, 0x99, 0x44, 0xb0, 0x75, 0x9d, 0x52, 0x1f, 0x9b, 0xc3,
+ 0x38, 0x87, 0x0a, 0x59, 0x4f, 0x8f, 0x38, 0xff, 0xaf, 0x2a, 0x13, 0x8a,
+ 0x20, 0x43, 0x7f, 0x78, 0x23, 0x11, 0xec, 0x38, 0xa3, 0xe4, 0xfe, 0x0f,
+ 0xd6, 0xeb, 0xce, 0xfb, 0x1c, 0x79, 0xbb, 0x13, 0xce, 0x39, 0x75, 0x3d,
+ 0x57, 0x6c, 0x30, 0xd8, 0x97, 0x46, 0xa5, 0xac, 0x9b, 0x58, 0x16, 0xf3,
+ 0xa1, 0xee, 0x94, 0x15, 0x50, 0xf1, 0x15, 0xc4, 0xfd, 0xb2, 0x47, 0x72,
+ 0xcb, 0xe4, 0xff, 0xa9, 0x11, 0x7e, 0xf4, 0x2f, 0xaf, 0x4f, 0xc9, 0xff,
+ 0x06, 0xca, 0xdb, 0x8b, 0x35, 0x76, 0x3d, 0xd2, 0x9a, 0xac, 0x7d, 0xc0,
+ 0x9a, 0x46, 0x5d, 0xfb, 0x8d, 0x4d, 0x1c, 0xb7, 0x07, 0xd3, 0x99, 0xdb,
+ 0x85, 0x6b, 0xeb, 0xdb, 0x1a, 0xd5, 0x6b, 0x10, 0xab, 0x08, 0x6a, 0x31,
+ 0x72, 0xcd, 0x1e, 0xe7, 0xff, 0xed, 0xc8, 0xb9, 0x14, 0xab, 0xd5, 0x4b,
+ 0x4c, 0x6f, 0x52, 0x14, 0x14, 0x84, 0xe0, 0x7e, 0x28, 0xe3, 0x86, 0x56,
+ 0xfb, 0x5b, 0xfb, 0x17, 0x7e, 0x03, 0xdb, 0xc6, 0x6e, 0xb9, 0xf4, 0xff,
+ 0x87, 0xfe, 0x63, 0xf6, 0xea, 0xec, 0x37, 0xdf, 0xe6, 0xc7, 0x76, 0x6c,
+ 0xba, 0xf4, 0x2d, 0xed, 0xfe, 0x31, 0x59, 0xf3, 0xef, 0x7a, 0xd4, 0xe8,
+ 0x2e, 0x94, 0x63, 0xab, 0xb9, 0xde, 0x2f, 0x67, 0xe5, 0xd6, 0x43, 0xf6,
+ 0xff, 0x65, 0x0e, 0xe4, 0x1d, 0xc3, 0x08, 0xf3, 0x6e, 0xd1, 0x4b, 0x14,
+ 0x0f, 0x66, 0xe4, 0x9d, 0xa0, 0x59, 0x90, 0xff, 0xfb, 0xf5, 0x60, 0x26,
+ 0xa7, 0xbf, 0x47, 0x33, 0x3e, 0xe6, 0x00, 0x3e, 0xda, 0x60, 0x07, 0xf9,
+ 0x0b, 0xf9, 0xd3, 0x25, 0x5d, 0xde, 0xeb, 0x97, 0x75, 0x85, 0xef, 0xd3,
+ 0xa7, 0xdd, 0xb5, 0x72, 0x6d, 0xc9, 0xb9, 0x51, 0x25, 0x77, 0x7d, 0xde,
+ 0x79, 0x37, 0x52, 0x8d, 0xae, 0xc3, 0xc2, 0xc4, 0x34, 0x39, 0x3f, 0x29,
+ 0x6b, 0x36, 0x96, 0x3f, 0x2a, 0xef, 0x61, 0xf8, 0x88, 0xb1, 0x5f, 0xf5,
+ 0x4f, 0xbe, 0x73, 0xd5, 0xba, 0x82, 0x38, 0x36, 0x27, 0x6c, 0xc4, 0x9a,
+ 0x94, 0xa0, 0xbe, 0x52, 0x69, 0x63, 0xbd, 0x3a, 0xf4, 0x64, 0xa5, 0x0d,
+ 0xc5, 0xf9, 0xdf, 0x92, 0x1e, 0xb6, 0x71, 0x30, 0x51, 0xaf, 0x7b, 0xd4,
+ 0x4f, 0x6d, 0xcb, 0x39, 0x03, 0x29, 0xfb, 0xf6, 0x71, 0xbc, 0x94, 0x98,
+ 0x4e, 0x94, 0xba, 0xba, 0xdd, 0x4b, 0xeb, 0xe7, 0x7f, 0xa3, 0x21, 0xc6,
+ 0xb6, 0x82, 0x9d, 0x61, 0x57, 0x70, 0xc3, 0x05, 0xe2, 0x4a, 0x36, 0x6c,
+ 0xc4, 0x7f, 0xc0, 0x3e, 0xfe, 0x56, 0xa9, 0x43, 0x62, 0x4a, 0xfb, 0xb9,
+ 0xb6, 0xea, 0xdb, 0x0b, 0xd4, 0xf3, 0xce, 0xbb, 0xf8, 0xd2, 0xbe, 0x16,
+ 0x5d, 0x0d, 0x2d, 0x69, 0xd9, 0x7e, 0xb6, 0x39, 0x33, 0x1a, 0xdc, 0x57,
+ 0x41, 0x30, 0xfa, 0xb6, 0xda, 0x85, 0x35, 0x72, 0x3c, 0x24, 0x1a, 0xd4,
+ 0x1f, 0xa0, 0x7d, 0x34, 0x3a, 0x6d, 0xc4, 0xea, 0x0a, 0x20, 0x9c, 0xf2,
+ 0x4b, 0xed, 0x84, 0x39, 0x81, 0x70, 0x31, 0x96, 0x73, 0xce, 0x03, 0xc8,
+ 0xb9, 0x49, 0xe6, 0x0d, 0x09, 0xf9, 0xbf, 0x7d, 0x4e, 0x37, 0x93, 0x7b,
+ 0x5a, 0xcc, 0xd7, 0x19, 0xaf, 0xd7, 0xcb, 0xff, 0x48, 0x2a, 0xf6, 0xe1,
+ 0xc1, 0x84, 0xac, 0x81, 0xfc, 0x1f, 0x05, 0x3f, 0x96, 0xb4, 0x1c, 0x54,
+ 0x00, 0x00, 0x00 };
static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
@@ -2079,1076 +2057,1088 @@ static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000000 };
static const u32 bnx2_CP_b09FwRodata[(0x16c/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x08001744, 0x08001744, 0x0800177c,
- 0x0800177c, 0x08001790, 0x08001760, 0x080019b8, 0x08001984, 0x08001a10,
- 0x08001a10, 0x08001a98, 0x080019c8, 0x80080240, 0x08003260, 0x080031cc,
- 0x08003288, 0x080032b0, 0x080032d8, 0x080032fc, 0x08003344, 0x08003320,
- 0x08003368, 0x08003234, 0x0800345c, 0x0800344c, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080033bc, 0x080033bc, 0x080031e8, 0x080031e8, 0x0800343c,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x0800342c, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x0800341c, 0x080031e8, 0x080031e8, 0x0800340c, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080033f4, 0x080031e8,
- 0x080031e8, 0x080033e4, 0x080033d4, 0x08003d6c, 0x08003d40, 0x08003d0c,
- 0x08003ce0, 0x08003cc0, 0x08003c74, 0x80080100, 0x80080080, 0x80080000,
+ 0x80080100, 0x80080080, 0x80080000, 0x08001800, 0x08001800, 0x08001838,
+ 0x08001838, 0x0800184c, 0x0800181c, 0x08001a74, 0x08001a40, 0x08001acc,
+ 0x08001acc, 0x08001b54, 0x08001a84, 0x80080240, 0x080021c4, 0x08002010,
+ 0x080021ec, 0x08002284, 0x080023d4, 0x08002420, 0x08002544, 0x0800244c,
+ 0x080024d0, 0x08002080, 0x080029f8, 0x0800299c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x080025b8, 0x080025b8, 0x0800202c, 0x0800202c, 0x08002874,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x080028d4, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x08002440, 0x0800202c, 0x0800202c, 0x08002944, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c,
+ 0x0800202c, 0x0800202c, 0x0800202c, 0x0800202c, 0x08002798, 0x0800202c,
+ 0x0800202c, 0x08002700, 0x0800265c, 0x080037c0, 0x08003794, 0x08003760,
+ 0x08003734, 0x08003714, 0x080036c8, 0x80080100, 0x80080080, 0x80080000,
0x80080080, 0x00000000 };
static struct fw_info bnx2_cp_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
.start_addr = 0x08000080,
.text_addr = 0x08000000,
- .text_len = 0x5938,
+ .text_len = 0x5418,
.text_index = 0x0,
.gz_text = bnx2_CP_b09FwText,
.gz_text_len = sizeof(bnx2_CP_b09FwText),
- .data_addr = 0x08005ac0,
+ .data_addr = 0x080055a0,
.data_len = 0x84,
.data_index = 0x0,
.data = bnx2_CP_b09FwData,
- .sbss_addr = 0x08005b44,
+ .sbss_addr = 0x08005624,
.sbss_len = 0x91,
.sbss_index = 0x0,
- .bss_addr = 0x08005bd8,
+ .bss_addr = 0x080056b8,
.bss_len = 0x19c,
.bss_index = 0x0,
- .rodata_addr = 0x08005938,
+ .rodata_addr = 0x08005418,
.rodata_len = 0x16c,
.rodata_index = 0x0,
.rodata = bnx2_CP_b09FwRodata,
};
static u8 bnx2_RXP_b09FwText[] = {
- 0xec, 0x5c, 0x7f, 0x70, 0x1c, 0xd5, 0x7d, 0xff, 0xbc, 0xbd, 0xbd, 0xbb,
- 0x95, 0x74, 0x3e, 0xed, 0x9d, 0x4e, 0xb2, 0x04, 0x06, 0xef, 0xa2, 0x95,
- 0x74, 0x58, 0xc6, 0xec, 0x9d, 0x4e, 0xb6, 0x48, 0xb7, 0xc9, 0xd5, 0x36,
- 0x20, 0x17, 0x52, 0x84, 0xa1, 0xc1, 0xcc, 0x30, 0x9d, 0x1b, 0x63, 0x8c,
- 0xb0, 0x1d, 0xa2, 0x00, 0x33, 0xc8, 0x29, 0x13, 0x16, 0xfc, 0xb3, 0xf8,
- 0xa4, 0x93, 0x8d, 0x8c, 0xc9, 0xf4, 0xd7, 0x21, 0xcb, 0x8a, 0x81, 0x93,
- 0xce, 0x04, 0xda, 0x98, 0x69, 0xa8, 0x15, 0x6c, 0x53, 0x87, 0x5f, 0x21,
- 0x19, 0x68, 0x4d, 0x9b, 0x99, 0xa8, 0x06, 0x1c, 0xd3, 0xa6, 0xd4, 0xb4,
- 0x0e, 0xb5, 0x8b, 0xeb, 0xd7, 0xef, 0x77, 0x4f, 0x97, 0x50, 0x42, 0xcb,
- 0x64, 0xa6, 0x7f, 0xee, 0x77, 0xe6, 0xe6, 0xf6, 0xde, 0xfb, 0xbe, 0xef,
- 0x7b, 0xdf, 0xdf, 0x9f, 0xb7, 0x1a, 0xfb, 0xbe, 0x08, 0x6a, 0x31, 0x4b,
- 0x73, 0xe8, 0x93, 0x19, 0x18, 0xbc, 0x27, 0xbd, 0x28, 0xb3, 0x88, 0x1e,
- 0xbb, 0x02, 0x73, 0x55, 0x95, 0xc7, 0x05, 0x7c, 0xf2, 0xc9, 0x27, 0x9f,
- 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2,
- 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27,
- 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c,
- 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9,
- 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xfa, 0xff, 0xa4, 0x00,
- 0xa0, 0xf3, 0xf7, 0x9c, 0xd9, 0x0f, 0x34, 0xc5, 0x71, 0x37, 0x2e, 0xb5,
- 0xa0, 0x05, 0x9c, 0x33, 0x1b, 0x6f, 0xb7, 0x80, 0x6c, 0xa9, 0xd3, 0x58,
- 0x86, 0xff, 0x92, 0x6e, 0x42, 0x05, 0x8f, 0x5f, 0xe2, 0x9c, 0xff, 0xf3,
- 0x17, 0x96, 0x98, 0xa7, 0x8b, 0x01, 0x68, 0xba, 0xf3, 0x46, 0x4a, 0x6f,
- 0x87, 0x36, 0x8f, 0xd6, 0xfc, 0x49, 0xc7, 0x95, 0x71, 0x44, 0xab, 0xb2,
- 0xe0, 0x2a, 0x8e, 0x94, 0xfb, 0x6c, 0x89, 0x97, 0x6c, 0x57, 0xf4, 0x66,
- 0xe0, 0x06, 0x9c, 0x83, 0xe2, 0xae, 0xfc, 0x05, 0x69, 0x04, 0x2b, 0x3b,
- 0xab, 0x93, 0x1a, 0x82, 0xfb, 0xa0, 0xab, 0x8e, 0x82, 0xa0, 0x55, 0x8b,
- 0xd0, 0x13, 0x75, 0x08, 0x3e, 0xd1, 0x8c, 0xf0, 0xe4, 0x01, 0x91, 0x2b,
- 0x6a, 0x98, 0x09, 0x1c, 0x14, 0x6b, 0x4a, 0xc8, 0x05, 0x9d, 0xb3, 0x37,
- 0x8c, 0xd1, 0xba, 0xac, 0xf7, 0xef, 0x4b, 0xa6, 0x6f, 0x18, 0x2f, 0x41,
- 0x0f, 0x38, 0x50, 0x54, 0xe7, 0x08, 0x3d, 0x33, 0xdf, 0xd9, 0x1b, 0xf6,
- 0x96, 0x4e, 0xc9, 0x17, 0x3a, 0x12, 0x38, 0x54, 0xd6, 0x71, 0xa0, 0xfc,
- 0x10, 0x9d, 0xc3, 0x74, 0x5d, 0x68, 0xae, 0xea, 0xb8, 0xd8, 0x92, 0x09,
- 0x62, 0x62, 0xe4, 0x82, 0x0c, 0x58, 0xa6, 0x01, 0xc5, 0xd2, 0x0f, 0x83,
- 0xf8, 0x0a, 0xc4, 0x57, 0x08, 0x62, 0xac, 0xb8, 0x23, 0x8e, 0xda, 0x66,
- 0xbc, 0xd0, 0xc1, 0xeb, 0x79, 0x2d, 0xcb, 0xf8, 0x38, 0x5a, 0x5d, 0x1f,
- 0xa2, 0xf5, 0x47, 0x33, 0xc0, 0xf8, 0x48, 0x1f, 0x2d, 0x95, 0xd8, 0x64,
- 0x87, 0xb1, 0x5a, 0x87, 0x5b, 0xe3, 0xb0, 0xac, 0xaa, 0x1c, 0x57, 0x18,
- 0x93, 0xff, 0x5c, 0x5f, 0x91, 0x03, 0xa1, 0x59, 0x70, 0xc3, 0x9f, 0x9a,
- 0x3f, 0x55, 0xaa, 0xce, 0x6f, 0xa7, 0x7d, 0x34, 0x9a, 0xef, 0xc7, 0x5f,
- 0x96, 0xd7, 0xe0, 0x2f, 0xca, 0xb7, 0xe1, 0xd9, 0x72, 0x1f, 0xed, 0x7b,
- 0x1f, 0xed, 0x3b, 0x80, 0xbf, 0x2e, 0x6f, 0xc0, 0x77, 0xcb, 0x39, 0x3c,
- 0x57, 0x5e, 0x85, 0xef, 0x94, 0x6f, 0xc6, 0x33, 0x65, 0x78, 0x67, 0x38,
- 0x95, 0x49, 0x8a, 0x1f, 0xe5, 0x6b, 0xa0, 0xee, 0xdc, 0x8c, 0xe9, 0x52,
- 0x10, 0xc1, 0x9d, 0x12, 0x23, 0xb6, 0xf9, 0x38, 0xd0, 0xa1, 0x07, 0x21,
- 0xb0, 0xcc, 0x36, 0xf7, 0x03, 0x5f, 0x40, 0x2e, 0x61, 0x1e, 0x00, 0x9a,
- 0xc4, 0x8f, 0x47, 0x9b, 0xc4, 0x6b, 0xa3, 0xaa, 0x78, 0x3d, 0x2f, 0x50,
- 0xef, 0x20, 0xf2, 0x72, 0x46, 0xca, 0xeb, 0xd2, 0x52, 0x96, 0x52, 0x56,
- 0xef, 0x0f, 0x85, 0x69, 0x3f, 0x22, 0x2e, 0x85, 0xd1, 0x68, 0x66, 0xd7,
- 0x09, 0xcd, 0xad, 0x25, 0xf9, 0x2b, 0xba, 0x01, 0x6b, 0xa7, 0x41, 0x7e,
- 0x60, 0x1d, 0x37, 0xe1, 0x0e, 0x2f, 0x26, 0xfa, 0xd0, 0x60, 0x2d, 0xc5,
- 0xbd, 0x7d, 0x36, 0x8a, 0x65, 0x68, 0x31, 0xe7, 0x0c, 0x52, 0xc3, 0x02,
- 0x36, 0xf9, 0x5b, 0xd0, 0xb3, 0x5d, 0x5a, 0xdf, 0x50, 0xf1, 0x37, 0x9d,
- 0xbd, 0x40, 0x67, 0x2f, 0xd0, 0xd9, 0x0b, 0xa4, 0x57, 0x81, 0xf4, 0x2a,
- 0x90, 0x0e, 0x05, 0xd2, 0xad, 0x40, 0x7a, 0x14, 0x48, 0x8f, 0x02, 0xe9,
- 0x58, 0x60, 0x5f, 0x0d, 0x92, 0x0d, 0x22, 0xf8, 0xbb, 0xfc, 0x3c, 0x9c,
- 0xe1, 0xcf, 0x4a, 0x1d, 0xc7, 0xe9, 0x8c, 0x8a, 0xf5, 0x9b, 0xca, 0xf8,
- 0x6e, 0x84, 0x7c, 0x64, 0xfc, 0xe6, 0x7b, 0x2f, 0xc4, 0xc9, 0xfc, 0xbb,
- 0x32, 0x34, 0x97, 0xf7, 0xfc, 0x22, 0xe4, 0x28, 0x70, 0xe9, 0x6e, 0x29,
- 0xcf, 0x75, 0xcd, 0xc8, 0xb7, 0x6f, 0x61, 0x59, 0x0e, 0x4e, 0x8c, 0x2a,
- 0x08, 0xd0, 0xd8, 0xb5, 0xf6, 0xdf, 0xcb, 0x3b, 0x13, 0xcc, 0xf7, 0x51,
- 0x04, 0xb5, 0x6c, 0x27, 0x68, 0x0d, 0xce, 0xbb, 0x1b, 0xef, 0x6d, 0x87,
- 0x1b, 0x75, 0x54, 0xf1, 0xe6, 0x90, 0x81, 0xb9, 0x4e, 0x16, 0x73, 0x1c,
- 0x6b, 0x64, 0x8f, 0xd2, 0x39, 0x18, 0x47, 0xf6, 0xf2, 0x7a, 0xd8, 0xd8,
- 0x57, 0x56, 0xc5, 0xab, 0x43, 0x73, 0x10, 0xdf, 0x69, 0xad, 0x1a, 0x12,
- 0x0a, 0x72, 0x8d, 0x59, 0x8c, 0x67, 0x4c, 0xa3, 0x08, 0x03, 0xab, 0xd2,
- 0x0a, 0x30, 0xd7, 0xc5, 0xd6, 0x8c, 0x69, 0xbb, 0x78, 0x08, 0xd3, 0x09,
- 0x1b, 0x13, 0x65, 0x8d, 0x72, 0xc3, 0xc5, 0x9d, 0x19, 0x0d, 0x72, 0x24,
- 0x8b, 0x93, 0x5d, 0x21, 0x4c, 0xf7, 0x71, 0x8c, 0xa8, 0xb4, 0xf7, 0x56,
- 0x28, 0xf1, 0x38, 0xf9, 0xe5, 0xb0, 0x0c, 0xc6, 0x79, 0x0c, 0xe2, 0x5f,
- 0x32, 0xbc, 0xff, 0x45, 0xe2, 0xd5, 0xdd, 0x51, 0xd4, 0xee, 0xd6, 0xf0,
- 0xf4, 0x4e, 0x15, 0x2b, 0xc8, 0xb7, 0x7b, 0x52, 0xaa, 0xb1, 0x4e, 0x38,
- 0x18, 0x2f, 0xab, 0x48, 0x0c, 0xb5, 0xc0, 0x88, 0x69, 0xb8, 0x74, 0xc8,
- 0xc5, 0x3b, 0x24, 0x77, 0x90, 0xe4, 0xd6, 0x77, 0xe9, 0x98, 0x69, 0xac,
- 0xf8, 0xf5, 0xeb, 0xf9, 0x56, 0x77, 0xa7, 0x12, 0x02, 0x42, 0x70, 0x35,
- 0x27, 0x83, 0xfb, 0xf3, 0xad, 0xa4, 0xc3, 0xad, 0x58, 0x1a, 0xd2, 0xb0,
- 0x7a, 0x98, 0xc7, 0x96, 0x03, 0x93, 0x73, 0xe7, 0xa0, 0x96, 0xf5, 0xe7,
- 0x7c, 0x5e, 0x4a, 0xcf, 0x1c, 0x07, 0xbf, 0x9d, 0x60, 0xbb, 0xbb, 0xca,
- 0x7f, 0xc8, 0x6c, 0x82, 0xf9, 0x2a, 0x39, 0x72, 0x38, 0x93, 0xc1, 0xc6,
- 0x7c, 0x6b, 0xf6, 0x5b, 0x4a, 0x03, 0x10, 0x34, 0x0d, 0x43, 0x81, 0x96,
- 0x70, 0x90, 0x1a, 0xa5, 0x78, 0x79, 0xd4, 0x8b, 0x17, 0xa4, 0xba, 0x4a,
- 0x9c, 0x97, 0x9a, 0xab, 0x13, 0xff, 0xfc, 0xc5, 0x6d, 0xf8, 0xe8, 0x51,
- 0xe6, 0x53, 0xf1, 0x03, 0x7a, 0x7e, 0x7f, 0xef, 0x8e, 0xd9, 0xda, 0xf1,
- 0xa7, 0x9e, 0x5f, 0x0d, 0xa5, 0xba, 0xb7, 0x8d, 0x3b, 0xf3, 0xad, 0x67,
- 0xb7, 0x29, 0xe4, 0xbf, 0x8b, 0x23, 0xa8, 0xa1, 0xfa, 0x13, 0x24, 0x59,
- 0xfb, 0xf2, 0xe7, 0xb1, 0x32, 0x6d, 0x1e, 0xe4, 0x7f, 0x6f, 0x36, 0x66,
- 0x55, 0xe4, 0x5f, 0x56, 0xb2, 0xf1, 0x64, 0xd9, 0xc6, 0xed, 0x74, 0x8e,
- 0xfb, 0xf0, 0x8f, 0x40, 0xcb, 0x02, 0xe3, 0x94, 0x72, 0x42, 0xba, 0x37,
- 0xb3, 0xbc, 0x79, 0x38, 0x15, 0x6f, 0xcd, 0x9d, 0x52, 0xcc, 0xe2, 0x76,
- 0x85, 0x6d, 0xa5, 0xe0, 0xcb, 0xe9, 0x0c, 0x8a, 0x31, 0x1d, 0xb7, 0xa6,
- 0x35, 0xf7, 0x52, 0x3a, 0xd3, 0x1b, 0x4b, 0x34, 0x34, 0xed, 0xca, 0xe2,
- 0xad, 0xf4, 0x9b, 0x28, 0xae, 0x64, 0x3b, 0xf0, 0x3a, 0x3e, 0x73, 0x33,
- 0xe2, 0x56, 0x0d, 0xe2, 0x63, 0x41, 0xd4, 0xef, 0xba, 0x20, 0x9b, 0x2d,
- 0x1e, 0xb7, 0x06, 0xce, 0x0a, 0x3e, 0x73, 0x10, 0xd1, 0xb1, 0xab, 0xa0,
- 0x5a, 0x66, 0x92, 0x1c, 0x9b, 0x60, 0xde, 0x90, 0x55, 0x3d, 0xbb, 0xc0,
- 0x75, 0x5f, 0x10, 0x58, 0x97, 0xfa, 0xbe, 0xcc, 0x36, 0xf2, 0x9a, 0x67,
- 0x68, 0x9c, 0xcf, 0x50, 0x73, 0x36, 0x8b, 0x26, 0x5a, 0x53, 0xe5, 0x8b,
- 0xa0, 0x7f, 0x57, 0xe5, 0x0c, 0x6f, 0x2f, 0xc1, 0xb3, 0x1a, 0x7a, 0xd0,
- 0x51, 0x78, 0x08, 0x6f, 0x2d, 0xf6, 0xf6, 0x3f, 0xbd, 0x2f, 0xbd, 0x83,
- 0x6c, 0xc2, 0x75, 0xf4, 0xd3, 0x7e, 0xe1, 0xf9, 0xff, 0x64, 0x7f, 0x24,
- 0x21, 0x9a, 0x69, 0x8c, 0xe3, 0x77, 0xa7, 0x34, 0x6e, 0xaa, 0xf8, 0x25,
- 0x4c, 0xf2, 0xde, 0xcf, 0xf4, 0xa0, 0x75, 0x48, 0x85, 0xcc, 0xb7, 0xda,
- 0x3f, 0x0d, 0x3c, 0x22, 0xa7, 0x6f, 0xe3, 0xb9, 0x56, 0xfd, 0x70, 0x40,
- 0x60, 0xa9, 0x6a, 0x9e, 0xce, 0xa1, 0x19, 0xfb, 0xa9, 0xc6, 0xb4, 0x38,
- 0x3a, 0xd5, 0x9c, 0x04, 0xd5, 0x1e, 0x43, 0x74, 0xec, 0xb1, 0xb1, 0x60,
- 0xe8, 0x36, 0x7c, 0x69, 0xb7, 0x83, 0x83, 0x05, 0x1b, 0x4f, 0x17, 0xa4,
- 0x3c, 0x69, 0x4b, 0xf9, 0xaf, 0x5d, 0x66, 0xff, 0x31, 0x6a, 0x07, 0x8b,
- 0x96, 0x74, 0xe6, 0xea, 0x03, 0x2a, 0xd9, 0xa7, 0xcd, 0xd8, 0x20, 0xcc,
- 0xe6, 0x29, 0x61, 0x53, 0xcc, 0xf5, 0x92, 0xed, 0x0d, 0xec, 0x2d, 0x27,
- 0xf1, 0x54, 0xd9, 0xa2, 0xcf, 0x42, 0x8a, 0x95, 0x0c, 0xd5, 0x33, 0xd6,
- 0x55, 0xc7, 0x78, 0x07, 0xe5, 0x45, 0x41, 0xc1, 0x7e, 0x9b, 0xe2, 0x3f,
- 0x46, 0xbc, 0x85, 0x0b, 0xe4, 0x3f, 0x0d, 0xc9, 0x9d, 0x59, 0xd4, 0xa4,
- 0x1a, 0x60, 0xdc, 0x68, 0x61, 0xbc, 0xa0, 0xb9, 0x41, 0x8a, 0xf9, 0xb1,
- 0xfc, 0x38, 0xfe, 0x40, 0x4f, 0xa0, 0x96, 0xec, 0xb7, 0x2a, 0x1d, 0x01,
- 0x6e, 0xe2, 0xb9, 0x08, 0x5a, 0xac, 0xef, 0xa3, 0x25, 0x3e, 0x07, 0xa1,
- 0x05, 0x7f, 0x85, 0x69, 0x3d, 0x8a, 0x30, 0xf5, 0x8c, 0xf9, 0xc4, 0x33,
- 0x9f, 0x7c, 0xd5, 0x68, 0x59, 0x24, 0x53, 0xc0, 0x6a, 0x23, 0x5e, 0xca,
- 0xa7, 0x66, 0xd2, 0x3d, 0xb8, 0x24, 0x81, 0x32, 0x9d, 0x7f, 0x2a, 0x2f,
- 0x65, 0x24, 0x63, 0xf6, 0x17, 0x28, 0x37, 0x27, 0x4b, 0x3d, 0x98, 0x2a,
- 0xff, 0x1e, 0xd5, 0x73, 0x1b, 0x7b, 0xf3, 0x0e, 0xc6, 0x0a, 0xea, 0xaa,
- 0x3c, 0xcc, 0xbe, 0xf5, 0xc8, 0xe0, 0x29, 0x8a, 0x9f, 0x89, 0x82, 0x69,
- 0xbc, 0x18, 0xd0, 0x70, 0xcc, 0xae, 0xa3, 0x73, 0x52, 0xde, 0x92, 0x4e,
- 0xcf, 0xe7, 0x47, 0x60, 0x35, 0xb0, 0xfd, 0xd9, 0x4f, 0x19, 0x7c, 0xbb,
- 0xe0, 0xc5, 0xf7, 0x75, 0x1a, 0x5c, 0xd8, 0xdd, 0xec, 0x1b, 0xf7, 0x74,
- 0x30, 0x5d, 0xa9, 0xa3, 0x7d, 0xdd, 0x36, 0xc2, 0xc3, 0x3d, 0x24, 0xb7,
- 0xd5, 0x3e, 0x81, 0x3b, 0x30, 0xdd, 0xec, 0x62, 0x11, 0xc5, 0xbf, 0xea,
- 0x3c, 0x9e, 0xda, 0x9c, 0x77, 0x65, 0xbd, 0x65, 0xf5, 0xff, 0x50, 0x3c,
- 0x88, 0x57, 0x53, 0x5c, 0xd7, 0x55, 0xca, 0x7b, 0x1d, 0x3b, 0xec, 0x11,
- 0xbc, 0x56, 0xfa, 0x2d, 0xe4, 0x62, 0x66, 0x72, 0x93, 0x58, 0x8f, 0x83,
- 0x23, 0x57, 0x01, 0xb7, 0x70, 0x9e, 0x90, 0x6e, 0xd6, 0x7a, 0x1c, 0x2a,
- 0x7e, 0x03, 0x47, 0x47, 0x6b, 0xf1, 0xbc, 0x15, 0x47, 0xcb, 0x44, 0x65,
- 0x9f, 0xab, 0xbb, 0x35, 0x8c, 0x51, 0x4e, 0x5f, 0x6b, 0xab, 0x98, 0x49,
- 0x70, 0xfd, 0xa0, 0x58, 0x4b, 0x6f, 0xa0, 0x5a, 0xe3, 0xb5, 0x5e, 0xac,
- 0xc9, 0x18, 0xc8, 0xe7, 0xb3, 0x54, 0xff, 0x6a, 0xb0, 0x2b, 0x06, 0x71,
- 0x3b, 0xf5, 0xb0, 0xbb, 0xf3, 0xad, 0xfd, 0xc3, 0x4a, 0x1c, 0xc5, 0x96,
- 0x2c, 0xf9, 0x42, 0xa0, 0xc9, 0x32, 0xb0, 0xa5, 0x44, 0x15, 0xb4, 0xa4,
- 0xe2, 0x9b, 0xa5, 0x2b, 0x50, 0x6c, 0xe2, 0xb5, 0x1d, 0x98, 0xf6, 0xbe,
- 0x83, 0x98, 0x89, 0x9b, 0xcd, 0x20, 0x9b, 0x8d, 0x17, 0x54, 0xec, 0xb6,
- 0xf7, 0x5c, 0x28, 0xae, 0x34, 0xf5, 0x1c, 0xe5, 0x5b, 0xc0, 0x8b, 0x5b,
- 0x7e, 0x06, 0xbe, 0x96, 0xff, 0x50, 0x9e, 0xf1, 0xf6, 0x54, 0x39, 0xff,
- 0xa7, 0xdf, 0x0e, 0xbc, 0x2f, 0x45, 0x98, 0xe5, 0xdf, 0x1f, 0xad, 0xfc,
- 0x5b, 0xd1, 0x67, 0x99, 0x37, 0x0b, 0x70, 0x1c, 0xcc, 0xfd, 0x44, 0xcc,
- 0x57, 0xea, 0x80, 0xbe, 0x98, 0xcf, 0x51, 0xcd, 0xb3, 0x38, 0x9a, 0x26,
- 0xda, 0x50, 0xb3, 0x8b, 0x7f, 0xf3, 0xb8, 0xc0, 0x65, 0xdd, 0x9c, 0x63,
- 0x6d, 0x50, 0xc6, 0x56, 0x47, 0x2b, 0x35, 0xb8, 0x5a, 0x1f, 0xfe, 0x70,
- 0x56, 0xbe, 0xd7, 0xeb, 0xe9, 0x77, 0xa5, 0x86, 0x7e, 0x33, 0xc3, 0xcf,
- 0xbc, 0xa6, 0x06, 0x6f, 0xed, 0x35, 0xed, 0xa2, 0xb2, 0x84, 0xf7, 0xac,
- 0xe4, 0x08, 0x36, 0xce, 0xae, 0xa1, 0x98, 0x2f, 0x4c, 0x49, 0xdc, 0xca,
- 0xf2, 0xaa, 0xeb, 0xdb, 0x10, 0xfa, 0xe5, 0xbe, 0x2a, 0x5e, 0xcc, 0x7c,
- 0x7a, 0xdf, 0xdb, 0x64, 0xed, 0xca, 0x38, 0xc5, 0x59, 0x23, 0xd4, 0x05,
- 0xd4, 0xe0, 0xf5, 0x26, 0xd4, 0x51, 0xde, 0x06, 0xac, 0x5b, 0x64, 0xe0,
- 0x2b, 0x1c, 0xa7, 0x9a, 0x1b, 0x71, 0x2e, 0xc6, 0xf0, 0xce, 0x17, 0xc8,
- 0xc7, 0x51, 0x8e, 0x47, 0xf2, 0xf3, 0xc5, 0x18, 0x7a, 0xe2, 0x92, 0x28,
- 0xeb, 0xbb, 0x2a, 0x0d, 0x77, 0x3e, 0xd5, 0xec, 0xf7, 0xf6, 0xdc, 0x2d,
- 0x8b, 0x7d, 0x3a, 0x5e, 0xca, 0xfc, 0x0e, 0x8d, 0x73, 0x3c, 0xd9, 0x78,
- 0x2e, 0xaf, 0xe1, 0xfe, 0xe1, 0x66, 0x3a, 0x27, 0xd7, 0xca, 0x9a, 0xb3,
- 0x33, 0x8a, 0x8d, 0x67, 0x29, 0x16, 0x9f, 0x29, 0xb0, 0xad, 0x54, 0x5c,
- 0x96, 0x5e, 0x21, 0xc3, 0x4d, 0x1c, 0xdf, 0x49, 0x5a, 0xa3, 0x93, 0xec,
- 0x28, 0x74, 0x6b, 0x99, 0x3c, 0xb0, 0x92, 0x9f, 0x3b, 0x68, 0xac, 0x89,
- 0xbe, 0xbb, 0x65, 0xdd, 0xaf, 0x9d, 0x43, 0xff, 0xac, 0x73, 0x50, 0xdc,
- 0x9b, 0xf6, 0x5a, 0x74, 0x12, 0x0e, 0x52, 0x91, 0xa5, 0x3e, 0x3f, 0x41,
- 0x31, 0xb0, 0x8d, 0x7a, 0xf0, 0x7b, 0x84, 0xf5, 0xb6, 0x78, 0x78, 0xca,
- 0x83, 0x67, 0x1e, 0x5e, 0x5b, 0x5d, 0xc1, 0x5d, 0x9a, 0x6a, 0x31, 0x16,
- 0xab, 0xce, 0x71, 0x9e, 0xf6, 0x62, 0x6c, 0x54, 0xca, 0xcd, 0x76, 0x0b,
- 0xc9, 0x88, 0x63, 0xb3, 0x45, 0x39, 0x3d, 0xca, 0x6b, 0xa4, 0x4c, 0xa6,
- 0x16, 0xf4, 0xa8, 0xa2, 0x01, 0x33, 0xba, 0x2b, 0xd6, 0x66, 0x0c, 0xf1,
- 0xd5, 0x51, 0x15, 0xf9, 0xc2, 0x45, 0x64, 0x2f, 0x29, 0x9f, 0x4a, 0x21,
- 0xbb, 0x29, 0x55, 0x87, 0x57, 0x8a, 0x3a, 0x72, 0xfa, 0x05, 0xb9, 0xbc,
- 0xad, 0x17, 0x65, 0x92, 0xf3, 0x41, 0xaa, 0x33, 0x79, 0x44, 0x44, 0x50,
- 0x4c, 0x44, 0xf0, 0x78, 0x21, 0x81, 0x23, 0xe3, 0x11, 0x6c, 0xa5, 0x18,
- 0x7d, 0x31, 0xc3, 0x7b, 0x46, 0xf0, 0x70, 0x99, 0x31, 0x55, 0x80, 0x6c,
- 0xe4, 0x8a, 0x13, 0xde, 0x58, 0x1d, 0x96, 0x17, 0x99, 0xf7, 0x82, 0x6c,
- 0xb1, 0x2c, 0xbd, 0x25, 0x50, 0xe5, 0x3b, 0x4e, 0xf8, 0xca, 0xa0, 0x5a,
- 0x36, 0x8f, 0x70, 0x55, 0x33, 0x61, 0xa8, 0x04, 0x61, 0x28, 0x6b, 0x16,
- 0x17, 0x9a, 0x94, 0x8d, 0x52, 0x3e, 0x4b, 0xb5, 0xec, 0xc7, 0xf4, 0x39,
- 0x43, 0xf5, 0x34, 0x46, 0x3a, 0x5e, 0x36, 0xcc, 0x3a, 0xba, 0xc2, 0xa6,
- 0x7a, 0x9b, 0x55, 0x94, 0x7a, 0xee, 0x43, 0x81, 0x29, 0xde, 0x5f, 0xc5,
- 0x96, 0x02, 0xb0, 0xa9, 0x00, 0xf7, 0x08, 0xe5, 0x7e, 0xc3, 0x44, 0x14,
- 0xf1, 0x09, 0x1d, 0xc1, 0x89, 0x24, 0xcd, 0x6b, 0x48, 0xd0, 0x6f, 0x97,
- 0xb0, 0x60, 0xbd, 0xd3, 0x24, 0x16, 0x3e, 0x76, 0x5e, 0xee, 0x48, 0xa9,
- 0x58, 0xd7, 0x66, 0xf6, 0xde, 0x28, 0x90, 0x4d, 0x0e, 0x49, 0x19, 0x4e,
- 0x85, 0x29, 0x37, 0xe5, 0xa1, 0x04, 0xe9, 0x1d, 0x75, 0xe4, 0x83, 0xaf,
- 0x75, 0x5b, 0xf6, 0x6b, 0x20, 0xb9, 0x65, 0x5e, 0xc3, 0xe3, 0xae, 0xf8,
- 0xb0, 0xdb, 0x7a, 0xfc, 0x4d, 0xb4, 0xa3, 0x6b, 0x42, 0x15, 0xff, 0x36,
- 0xb4, 0x10, 0xe9, 0x29, 0xe8, 0x21, 0xe7, 0x80, 0x98, 0x79, 0xe2, 0xa0,
- 0x38, 0x39, 0x49, 0xe7, 0x2e, 0x90, 0x2e, 0x05, 0xd2, 0xa5, 0x40, 0xba,
- 0x90, 0x5d, 0x9e, 0xf1, 0xf0, 0x24, 0xeb, 0x9a, 0x24, 0x2c, 0x73, 0xdc,
- 0xc3, 0xbc, 0x8c, 0x11, 0x63, 0x8e, 0x99, 0x75, 0xc1, 0x7a, 0xb3, 0x9e,
- 0x52, 0xbe, 0x69, 0x57, 0xf4, 0x71, 0xa9, 0xdc, 0x6a, 0x53, 0x55, 0x5b,
- 0x48, 0xf9, 0xef, 0x36, 0xdb, 0x82, 0x75, 0x94, 0xf2, 0x3b, 0xa4, 0xd3,
- 0x16, 0xd2, 0x71, 0x53, 0x41, 0x1e, 0x0a, 0x59, 0x96, 0x31, 0x41, 0x67,
- 0x8b, 0x93, 0x4e, 0x89, 0x09, 0x8d, 0x74, 0x6d, 0x87, 0x4a, 0xba, 0x06,
- 0x26, 0xa0, 0x2b, 0x74, 0x1e, 0x63, 0x8c, 0xec, 0x34, 0xf5, 0x79, 0xe7,
- 0x61, 0xcc, 0xef, 0x8a, 0xab, 0x09, 0x9f, 0xa8, 0x64, 0xd7, 0x4d, 0x14,
- 0x3b, 0x39, 0x15, 0x46, 0xd8, 0x52, 0xa8, 0x27, 0x6a, 0xf8, 0xf6, 0x78,
- 0x1d, 0x26, 0xc8, 0xef, 0xc5, 0x71, 0xe8, 0x41, 0x92, 0xe9, 0x16, 0x0f,
- 0x8a, 0x4f, 0xc6, 0x5b, 0xd0, 0x19, 0x20, 0x9c, 0x04, 0x3c, 0x92, 0x8f,
- 0x8b, 0x89, 0x11, 0x15, 0x9b, 0x0b, 0xa7, 0x49, 0x3f, 0x89, 0xc3, 0xf6,
- 0xc3, 0xcd, 0xc4, 0x22, 0x1e, 0xb6, 0xcd, 0x1e, 0xe0, 0x2a, 0x8a, 0xb7,
- 0x00, 0xd6, 0x5a, 0xc8, 0x6e, 0xb3, 0xaf, 0xc2, 0x4c, 0x1f, 0x8c, 0xed,
- 0xb6, 0xab, 0x87, 0x60, 0x1e, 0xbb, 0x9a, 0x7a, 0xd3, 0x95, 0xa4, 0xcf,
- 0xa0, 0xe5, 0x0e, 0x50, 0xe1, 0x42, 0xb9, 0x6c, 0xf6, 0x1f, 0x25, 0x5f,
- 0x94, 0xa8, 0xff, 0x95, 0xca, 0x4d, 0xe2, 0xe9, 0xd1, 0xf3, 0xf2, 0xae,
- 0x94, 0x99, 0x6d, 0xa3, 0xb1, 0xe0, 0x90, 0x46, 0x38, 0x4d, 0xa3, 0x9c,
- 0x32, 0x6d, 0x80, 0x6b, 0x03, 0xb4, 0x30, 0xd5, 0xe2, 0x9f, 0x59, 0x47,
- 0x08, 0xa7, 0x6b, 0x20, 0x0c, 0x8f, 0xa5, 0x23, 0x02, 0xfb, 0x28, 0xc7,
- 0x27, 0x17, 0x9a, 0xc7, 0x56, 0xc3, 0x9d, 0x6e, 0x81, 0x39, 0x18, 0x0e,
- 0x9c, 0xc6, 0x07, 0x43, 0x21, 0xc2, 0x0d, 0xed, 0xf6, 0xeb, 0x30, 0xf5,
- 0x7d, 0x81, 0x5f, 0xc8, 0xfd, 0x09, 0x5c, 0x14, 0xc4, 0x19, 0x69, 0xfc,
- 0x3e, 0xaf, 0x61, 0xdd, 0x07, 0xb0, 0x2d, 0xc3, 0x38, 0x45, 0x25, 0x9c,
- 0x02, 0xbc, 0x93, 0x37, 0xb0, 0x7f, 0x61, 0x0d, 0xf5, 0x93, 0xd6, 0x9e,
- 0x75, 0x70, 0x57, 0xd1, 0xf5, 0x47, 0x8b, 0xd0, 0x5e, 0x79, 0x8a, 0x95,
- 0x0d, 0x42, 0xe0, 0x29, 0xeb, 0xac, 0xdd, 0x31, 0xc9, 0x18, 0x46, 0x4d,
- 0x2d, 0xa0, 0x5c, 0xdc, 0x5a, 0x16, 0xd4, 0xdb, 0x4c, 0x7d, 0x06, 0x6c,
- 0x1b, 0x9d, 0xec, 0x7a, 0x5e, 0x22, 0xc6, 0xba, 0xbb, 0x39, 0xd2, 0x73,
- 0xd5, 0x16, 0x3a, 0xff, 0x1a, 0xd2, 0xe9, 0x2e, 0xcb, 0xed, 0x21, 0xa9,
- 0xd4, 0xa3, 0xcc, 0xe6, 0xf7, 0x48, 0xf7, 0xb5, 0x54, 0x47, 0x8a, 0xe5,
- 0xe7, 0xea, 0xb9, 0x66, 0x4c, 0x94, 0xf9, 0x1e, 0xd7, 0x83, 0xa5, 0xf9,
- 0x6a, 0x3e, 0xb0, 0xff, 0xd9, 0xf7, 0x1c, 0x0b, 0x1c, 0x33, 0x1c, 0x27,
- 0x8c, 0xd1, 0x7a, 0x30, 0xda, 0xae, 0x20, 0x9b, 0x90, 0x72, 0xa5, 0x65,
- 0x8e, 0x70, 0x1d, 0xa7, 0x98, 0xcf, 0xee, 0xb5, 0xeb, 0x29, 0x3f, 0xe1,
- 0x3e, 0x69, 0x1b, 0x08, 0x39, 0x1c, 0x1b, 0x75, 0x14, 0xeb, 0x11, 0x6c,
- 0xa3, 0x58, 0xd1, 0x2c, 0x2b, 0x49, 0x97, 0x0d, 0xfd, 0x9d, 0x0c, 0xf1,
- 0x96, 0x61, 0x94, 0xed, 0x5a, 0xc2, 0x95, 0x2a, 0x62, 0xce, 0x21, 0xd9,
- 0x60, 0x35, 0xea, 0xd4, 0xb8, 0xf5, 0x7b, 0xb1, 0x9a, 0xee, 0x17, 0x06,
- 0xea, 0x1c, 0x9e, 0x3f, 0x27, 0x67, 0x62, 0x11, 0x8a, 0x33, 0xe6, 0xb1,
- 0xdc, 0x67, 0xf0, 0x91, 0x44, 0x9c, 0x79, 0xb3, 0x58, 0x9d, 0x81, 0x38,
- 0x48, 0x7b, 0xa1, 0x81, 0x73, 0xd7, 0xc0, 0x7c, 0xc7, 0x3a, 0x76, 0x88,
- 0x7a, 0x8f, 0xd1, 0x00, 0xaa, 0xb9, 0x2a, 0x02, 0x8e, 0xa5, 0xef, 0xc5,
- 0x51, 0xaf, 0x4e, 0x11, 0x52, 0x17, 0x2b, 0x76, 0xcf, 0x13, 0xbd, 0x84,
- 0xcd, 0xdb, 0x53, 0x70, 0x34, 0xb4, 0x19, 0x7f, 0x43, 0xa3, 0x9b, 0x29,
- 0xfe, 0xe7, 0x38, 0x11, 0x51, 0xda, 0x0d, 0xfd, 0x69, 0x5b, 0xa3, 0x3e,
- 0x2a, 0xe5, 0xd6, 0x94, 0x81, 0x29, 0x9b, 0x70, 0x74, 0x63, 0x10, 0x31,
- 0x0b, 0xba, 0xee, 0x58, 0x83, 0x07, 0x30, 0xc0, 0xf8, 0x37, 0x3a, 0x9f,
- 0x7a, 0x25, 0x8d, 0x89, 0x31, 0xbb, 0x06, 0xd9, 0x9b, 0x05, 0x22, 0x4e,
- 0x82, 0xce, 0x16, 0x42, 0xce, 0x7b, 0x66, 0x1d, 0x91, 0x7d, 0xd7, 0xde,
- 0x43, 0xfa, 0x8a, 0xf9, 0xb5, 0x0e, 0x8f, 0x59, 0x76, 0x09, 0x77, 0x11,
- 0x56, 0xa7, 0x21, 0x9a, 0xdf, 0x4c, 0xf3, 0x8f, 0x92, 0xec, 0x5c, 0xdc,
- 0xbb, 0x87, 0xd6, 0xb7, 0x38, 0xd6, 0xf4, 0xf3, 0xd8, 0x4e, 0x3a, 0x70,
- 0x8d, 0xe7, 0x31, 0x3e, 0xf3, 0x42, 0x3e, 0x33, 0xf5, 0x78, 0x8e, 0x2b,
- 0x1b, 0x3f, 0xcb, 0xd3, 0xde, 0x09, 0x64, 0xb7, 0xdb, 0x10, 0x13, 0xf6,
- 0x6e, 0xc2, 0x2f, 0xa8, 0x8f, 0x3a, 0x56, 0xff, 0x14, 0xa0, 0x44, 0x9c,
- 0x9d, 0x28, 0xc5, 0x80, 0x47, 0x0b, 0x96, 0x7b, 0x8f, 0x62, 0x0e, 0x26,
- 0x08, 0x13, 0x9f, 0x21, 0x4c, 0xbf, 0xab, 0x7d, 0xda, 0x8c, 0x83, 0xb1,
- 0x7e, 0x54, 0xbc, 0xb4, 0x5b, 0x41, 0xc7, 0x62, 0xea, 0x4b, 0x54, 0x4b,
- 0xae, 0xb1, 0xf9, 0xbe, 0x7c, 0x79, 0x7d, 0x05, 0x2f, 0xff, 0x6f, 0x39,
- 0x69, 0x92, 0xc5, 0xaa, 0x79, 0x69, 0xf5, 0x3d, 0x8d, 0x3f, 0x93, 0xd9,
- 0x18, 0xfb, 0x22, 0x42, 0xb5, 0xf8, 0x97, 0xf5, 0x28, 0x39, 0x49, 0xf2,
- 0x37, 0x75, 0x07, 0x75, 0x8e, 0x19, 0xf2, 0x65, 0xf6, 0x8d, 0x3c, 0x44,
- 0x7d, 0x9a, 0xf2, 0x2a, 0xc6, 0x7e, 0xe1, 0xfb, 0x3d, 0x19, 0x6f, 0x38,
- 0x41, 0xba, 0xa9, 0xe8, 0x4a, 0xa3, 0x5e, 0x71, 0xac, 0xb3, 0x63, 0x74,
- 0xe6, 0x16, 0xa7, 0x1e, 0xe7, 0x1a, 0xb8, 0x36, 0x46, 0xc5, 0x0f, 0x46,
- 0xcd, 0x1e, 0xc2, 0xc3, 0xab, 0xee, 0x21, 0x1c, 0x75, 0x9f, 0x50, 0xd1,
- 0x4b, 0x67, 0xb7, 0xda, 0xc8, 0x07, 0x84, 0x4d, 0x12, 0x6d, 0xd3, 0x66,
- 0x02, 0xd5, 0xf3, 0x5e, 0x90, 0x71, 0xcb, 0x72, 0xe3, 0xca, 0xc7, 0x32,
- 0x95, 0xe6, 0x18, 0xdf, 0x80, 0x70, 0x5c, 0x20, 0x94, 0x1e, 0xf2, 0x6c,
- 0x4b, 0x77, 0x2a, 0xd4, 0xa7, 0x1f, 0x62, 0x1f, 0x11, 0x7e, 0x7b, 0x59,
- 0xe6, 0xbe, 0xc2, 0xba, 0x6d, 0x9f, 0xd5, 0x73, 0x2d, 0xc7, 0x15, 0xfd,
- 0x96, 0x73, 0xd8, 0xde, 0x87, 0xa8, 0x8e, 0x77, 0x2d, 0xe9, 0xdc, 0x3e,
- 0xa8, 0x0c, 0x49, 0x63, 0x25, 0xfb, 0x93, 0x2e, 0x37, 0xb5, 0x9e, 0xaf,
- 0xb5, 0xa8, 0x73, 0x1c, 0xaf, 0x0f, 0x45, 0x45, 0xfd, 0x63, 0xae, 0xd7,
- 0x53, 0x5f, 0xa3, 0xb3, 0x9c, 0x4c, 0xf1, 0x19, 0x38, 0xc7, 0x8e, 0xe3,
- 0x8a, 0xd2, 0xed, 0xc4, 0x1b, 0xa0, 0xfd, 0xa1, 0x51, 0xbc, 0x41, 0x52,
- 0x9f, 0x39, 0xd7, 0x35, 0x25, 0x8d, 0x06, 0x96, 0x4f, 0xb6, 0x1e, 0x65,
- 0x5b, 0xf3, 0xdd, 0xb2, 0x6a, 0x6f, 0xe6, 0xe7, 0xf5, 0x74, 0xe9, 0x8e,
- 0xb1, 0xff, 0x50, 0x5f, 0xe7, 0xb0, 0x4d, 0x21, 0x6a, 0x9c, 0x4e, 0x63,
- 0x81, 0xd8, 0x21, 0xdd, 0x44, 0xb5, 0x86, 0x45, 0xc5, 0x84, 0xb7, 0x9e,
- 0xf7, 0xfe, 0xf4, 0xfa, 0x26, 0xf1, 0xce, 0x9e, 0xdf, 0xa5, 0x67, 0x2f,
- 0x46, 0x7a, 0x9f, 0xa2, 0x1c, 0xd2, 0x9c, 0x7e, 0x99, 0x6c, 0xe4, 0x18,
- 0x83, 0xf2, 0x8a, 0xbd, 0x56, 0xe6, 0x1a, 0x39, 0xd6, 0xe0, 0x26, 0x48,
- 0xce, 0xae, 0xc7, 0x7e, 0x75, 0x8e, 0xab, 0xdb, 0xa5, 0x9c, 0xb0, 0xd7,
- 0x90, 0x2d, 0x58, 0x4e, 0xd5, 0x16, 0x7b, 0x66, 0x6d, 0xd3, 0x5e, 0xf1,
- 0x5f, 0xc1, 0x3b, 0x83, 0x16, 0x72, 0xde, 0xc0, 0x4b, 0x79, 0xa5, 0x89,
- 0x6e, 0x2b, 0xe8, 0xb3, 0x05, 0x7e, 0xda, 0x43, 0xfa, 0x5d, 0x49, 0x58,
- 0x65, 0x91, 0x35, 0xdd, 0x1a, 0x58, 0x2f, 0x31, 0x77, 0x9a, 0x82, 0xe3,
- 0xbc, 0xd4, 0xda, 0x55, 0x84, 0xaf, 0xe0, 0x1e, 0xc5, 0xb6, 0x57, 0xf0,
- 0x32, 0xf1, 0xad, 0xb8, 0xc2, 0x32, 0x5a, 0x05, 0xf5, 0xb5, 0xbe, 0xa5,
- 0xe9, 0xe0, 0x2f, 0x63, 0x8f, 0xcf, 0x90, 0xf3, 0x74, 0xe0, 0x18, 0xec,
- 0x22, 0xdf, 0xe5, 0x56, 0x2a, 0x48, 0x2d, 0x06, 0x61, 0x8d, 0xa8, 0xd8,
- 0xba, 0x9b, 0xfd, 0xff, 0x3d, 0x9a, 0x67, 0xbe, 0xce, 0x66, 0x1d, 0xd6,
- 0xaa, 0xc3, 0x74, 0xb1, 0x24, 0x2c, 0x4a, 0xf6, 0xe0, 0xbd, 0xaa, 0x72,
- 0xaa, 0x32, 0xa2, 0x62, 0x72, 0x94, 0x79, 0x59, 0x17, 0xaa, 0xcd, 0x1c,
- 0x2b, 0x29, 0x8e, 0x8f, 0x8f, 0x65, 0x47, 0x3a, 0x1a, 0x43, 0x2d, 0xaf,
- 0x89, 0x0a, 0x7d, 0x0f, 0xcb, 0x85, 0x60, 0x3b, 0xc6, 0x48, 0xff, 0xf6,
- 0xf4, 0xe5, 0xb3, 0xfa, 0xff, 0xb1, 0x5e, 0xc1, 0x71, 0x51, 0x71, 0xd4,
- 0xdb, 0xbb, 0x62, 0xa3, 0x49, 0xb2, 0xf5, 0x44, 0xaa, 0xca, 0xf3, 0x38,
- 0xf1, 0x70, 0x9c, 0x7d, 0x66, 0x4f, 0x22, 0xea, 0x15, 0x8f, 0xe4, 0xe9,
- 0x92, 0x6a, 0x29, 0xd7, 0xd7, 0x52, 0x9e, 0x3c, 0x49, 0xbd, 0x69, 0x7f,
- 0xb1, 0x57, 0x6c, 0xcb, 0xeb, 0xd4, 0xa7, 0x96, 0x8b, 0xad, 0x79, 0x8b,
- 0x71, 0xd1, 0x6c, 0x9f, 0xaa, 0xbc, 0x8b, 0xda, 0x52, 0xfa, 0xe4, 0x3b,
- 0xa2, 0x48, 0x4e, 0x77, 0xd0, 0x37, 0x7f, 0xf8, 0x41, 0xa9, 0x58, 0xfc,
- 0x3e, 0xc8, 0x3a, 0x76, 0x22, 0x10, 0xe9, 0xe9, 0x59, 0x12, 0x40, 0xbd,
- 0x85, 0xbe, 0x66, 0xc2, 0x07, 0x57, 0x7a, 0x35, 0xdd, 0x80, 0x51, 0x6a,
- 0x6f, 0xac, 0xf8, 0x89, 0xf3, 0x0e, 0x6a, 0xad, 0x83, 0x5c, 0x0d, 0xd5,
- 0x91, 0x6b, 0xba, 0x43, 0xda, 0xd1, 0xee, 0xde, 0x96, 0xf6, 0xc9, 0xa6,
- 0x5c, 0xad, 0x73, 0x7d, 0x4b, 0xdb, 0xa4, 0xdb, 0xb2, 0x70, 0x08, 0xf8,
- 0xf2, 0x90, 0x0e, 0xcd, 0xb9, 0xd1, 0x0d, 0x74, 0x23, 0xa7, 0x52, 0x5c,
- 0xec, 0xe8, 0xb6, 0x7a, 0xa6, 0xc4, 0x4d, 0x37, 0x91, 0x1e, 0x2d, 0x9d,
- 0x93, 0x86, 0xb1, 0x39, 0xf3, 0xc0, 0x4d, 0x81, 0x29, 0xee, 0x2f, 0x1b,
- 0x06, 0xf7, 0xf1, 0x7b, 0x33, 0xba, 0x9b, 0x9e, 0xd0, 0xf1, 0xc0, 0xb2,
- 0xee, 0x41, 0x0c, 0xe4, 0x1f, 0x40, 0x7f, 0x9e, 0xdf, 0x3b, 0x69, 0x18,
- 0xe1, 0x1a, 0x5f, 0xe0, 0x77, 0x4e, 0x0f, 0x35, 0x30, 0x6e, 0xdc, 0x5e,
- 0x56, 0x71, 0xed, 0x10, 0xcf, 0x99, 0xcd, 0xef, 0xa3, 0xca, 0xfb, 0x59,
- 0x7c, 0x9f, 0xd4, 0x93, 0x6b, 0x1e, 0xb2, 0x81, 0x61, 0x29, 0x95, 0x0c,
- 0xdf, 0x63, 0x4e, 0x13, 0xd6, 0xe3, 0xbd, 0x7f, 0x4e, 0xbd, 0x71, 0x2e,
- 0xbf, 0x0b, 0x63, 0xca, 0x86, 0x87, 0x79, 0xee, 0xd4, 0xec, 0xdc, 0xbb,
- 0x34, 0x07, 0x71, 0x92, 0xea, 0xfa, 0x74, 0x25, 0x2f, 0xb2, 0xb5, 0xc3,
- 0x1a, 0xfe, 0xa8, 0xc0, 0x3c, 0x33, 0xb3, 0x3c, 0x3f, 0x21, 0x9e, 0x04,
- 0x56, 0xc4, 0xb8, 0x76, 0x53, 0xce, 0xec, 0xae, 0xbe, 0x2b, 0x93, 0xf2,
- 0x25, 0xfb, 0xc3, 0x68, 0xe5, 0x5d, 0x59, 0x54, 0x68, 0x8f, 0xd1, 0x33,
- 0x61, 0x95, 0x50, 0x2a, 0x2a, 0x42, 0x8f, 0xf1, 0xfa, 0x57, 0x53, 0x95,
- 0xf5, 0xc7, 0x52, 0xbc, 0xfe, 0xd7, 0xd7, 0xa8, 0xd9, 0xc8, 0x30, 0xdd,
- 0xa9, 0x0a, 0xff, 0x24, 0x77, 0x34, 0x56, 0x64, 0x57, 0xd6, 0x7d, 0x6f,
- 0x76, 0xdd, 0x41, 0x5a, 0xb7, 0x8f, 0x62, 0x8c, 0xd7, 0xb2, 0x9e, 0x1c,
- 0xa3, 0xd5, 0xf7, 0x86, 0x49, 0x71, 0x80, 0x7a, 0xf5, 0x81, 0x92, 0x2a,
- 0xf6, 0x52, 0x1d, 0x1c, 0xcf, 0x13, 0x36, 0xf2, 0xde, 0x05, 0x52, 0xcd,
- 0x2f, 0x7f, 0x23, 0x56, 0xf1, 0x21, 0xf7, 0xd5, 0x69, 0xea, 0xab, 0xed,
- 0x54, 0xdf, 0x55, 0x4f, 0xa7, 0xb0, 0x73, 0x84, 0xea, 0xbb, 0xc0, 0x49,
- 0xaf, 0xbe, 0x1c, 0x41, 0x7b, 0x89, 0xfb, 0x80, 0x25, 0xce, 0x15, 0x8c,
- 0x5c, 0x33, 0xc9, 0x6e, 0x29, 0x57, 0x6a, 0x03, 0xf5, 0x82, 0x2c, 0xf5,
- 0x64, 0xf1, 0x62, 0x89, 0x7f, 0x52, 0xf1, 0x8c, 0xf3, 0x19, 0xb2, 0x62,
- 0x4e, 0xbb, 0x8b, 0xfa, 0x76, 0x97, 0x71, 0xec, 0xc0, 0xf3, 0xc2, 0x9a,
- 0x3e, 0x27, 0xb2, 0xb7, 0x36, 0xe3, 0x41, 0xfc, 0x3c, 0x95, 0x5d, 0x11,
- 0xa5, 0x6f, 0xc2, 0xcc, 0x86, 0xc6, 0xef, 0x48, 0xbb, 0xdb, 0x7a, 0x36,
- 0x88, 0x36, 0xaa, 0x37, 0x6d, 0xee, 0x16, 0xb4, 0x51, 0xcf, 0xb7, 0xb5,
- 0xc3, 0x25, 0x5b, 0x7b, 0xa3, 0x54, 0xb5, 0x03, 0xc7, 0x29, 0xdb, 0x80,
- 0x42, 0xdf, 0xb1, 0xb2, 0x0b, 0x04, 0xf5, 0x55, 0xea, 0xbb, 0xc3, 0xd4,
- 0xb3, 0x2b, 0xf7, 0xce, 0x30, 0xe1, 0x16, 0xde, 0x7b, 0xdd, 0xec, 0xbb,
- 0x96, 0x7f, 0x90, 0x95, 0x1e, 0xf5, 0x0a, 0xd9, 0x83, 0xcf, 0xfc, 0xa3,
- 0x48, 0x65, 0xfc, 0x4c, 0x6c, 0xf6, 0xff, 0xf9, 0x21, 0x9c, 0x42, 0xf7,
- 0xc8, 0x21, 0x81, 0x1d, 0x6d, 0x95, 0x58, 0xee, 0xe4, 0xf7, 0x98, 0xde,
- 0x7b, 0xb7, 0x2a, 0x4f, 0xc5, 0x86, 0x0a, 0xe1, 0x99, 0x43, 0xe5, 0xac,
- 0xb8, 0x26, 0x8f, 0x01, 0xea, 0x89, 0xd9, 0x20, 0xf1, 0x5e, 0x53, 0xea,
- 0x15, 0xcb, 0xf3, 0x96, 0xb1, 0x89, 0x74, 0xdd, 0xa2, 0x77, 0xea, 0xe3,
- 0x84, 0x21, 0x68, 0x3f, 0x23, 0x4c, 0xf1, 0xaf, 0x39, 0x73, 0xb1, 0x7d,
- 0x36, 0x76, 0x28, 0x1f, 0x28, 0x7f, 0x06, 0xc5, 0x82, 0x49, 0xfe, 0xa9,
- 0x7b, 0xb1, 0x5b, 0xd1, 0xe3, 0x9c, 0xdc, 0x76, 0x33, 0xcf, 0x5f, 0x31,
- 0x6b, 0xfb, 0xa6, 0x38, 0xed, 0x49, 0xbf, 0x47, 0x66, 0xcf, 0xff, 0x7f,
- 0xad, 0xbd, 0xf6, 0x92, 0xff, 0xb9, 0x66, 0x86, 0xce, 0xc9, 0x18, 0x08,
- 0x6e, 0xdc, 0x61, 0xfc, 0x33, 0x6f, 0xd6, 0xe7, 0xd4, 0x15, 0xa3, 0x03,
- 0xb8, 0x71, 0x31, 0xdd, 0x7c, 0xe9, 0x0e, 0xb6, 0x8d, 0x7c, 0x95, 0x1c,
- 0x66, 0xbd, 0xcf, 0x93, 0xde, 0xd0, 0x6a, 0x9c, 0xb3, 0xb8, 0x7c, 0xa8,
- 0xb5, 0x3f, 0x2c, 0xcc, 0xe4, 0x90, 0x30, 0xfb, 0xa8, 0xbe, 0xd9, 0x93,
- 0x30, 0x9b, 0x17, 0x08, 0xd3, 0x58, 0x0b, 0xb6, 0xc9, 0x79, 0xb4, 0x95,
- 0xf8, 0xfb, 0x2c, 0x2c, 0xf2, 0x6b, 0xdf, 0x70, 0x00, 0x4a, 0xfa, 0x03,
- 0xb2, 0x2b, 0xe1, 0x35, 0xd1, 0x4c, 0xb9, 0xc4, 0xb1, 0x77, 0x1e, 0x9b,
- 0xf3, 0xd0, 0x5a, 0x88, 0xe7, 0x2a, 0xaa, 0xd1, 0xad, 0xc3, 0xe6, 0x59,
- 0xc2, 0x9c, 0x83, 0x5f, 0x0a, 0xb4, 0x26, 0xfb, 0x61, 0x0e, 0x6c, 0x41,
- 0xe7, 0xf4, 0x51, 0x61, 0x66, 0xcf, 0x12, 0x16, 0x0c, 0xa7, 0x2b, 0x32,
- 0x17, 0xcd, 0xca, 0x4c, 0x32, 0x3e, 0xf6, 0x72, 0x88, 0x30, 0x74, 0xfa,
- 0x6f, 0xe5, 0xb4, 0x67, 0xb3, 0xe0, 0xac, 0xfe, 0x4b, 0xe2, 0x15, 0x1f,
- 0x3c, 0x37, 0x6b, 0x1f, 0x42, 0x24, 0xb5, 0xcc, 0xc7, 0xf7, 0x30, 0x88,
- 0x35, 0xf9, 0x2f, 0xe2, 0x61, 0xc2, 0x43, 0x59, 0x6f, 0x7d, 0x2f, 0x72,
- 0x25, 0x88, 0xb5, 0xf9, 0xe9, 0xf0, 0x51, 0x3b, 0x88, 0xa2, 0x27, 0xe7,
- 0x7a, 0x1a, 0xeb, 0xa3, 0x0f, 0xdb, 0x8c, 0xef, 0xe4, 0x37, 0xd3, 0x73,
- 0xd6, 0xe3, 0xeb, 0xcf, 0xa3, 0x27, 0x9c, 0x22, 0xdc, 0xe6, 0xf1, 0x79,
- 0xf7, 0x75, 0xe2, 0x59, 0xce, 0x73, 0x23, 0xfc, 0xae, 0x61, 0x75, 0xa6,
- 0xcd, 0x78, 0xd8, 0xbb, 0x23, 0x1a, 0x58, 0x53, 0x32, 0x70, 0x07, 0xd5,
- 0xd5, 0xa2, 0x57, 0x57, 0x7f, 0x85, 0xe7, 0x15, 0xe2, 0x5b, 0x46, 0x7c,
- 0x9b, 0xbc, 0x31, 0x03, 0xcb, 0x4b, 0xc7, 0xbd, 0x58, 0x51, 0x1d, 0xf6,
- 0x03, 0xdb, 0x9e, 0xf1, 0x68, 0xf5, 0xae, 0xc6, 0x3e, 0xc9, 0x8a, 0x47,
- 0xf3, 0xbd, 0x62, 0x67, 0x3e, 0x4a, 0xfb, 0xb9, 0x62, 0x24, 0xa3, 0x8c,
- 0xc6, 0x20, 0xb1, 0x2c, 0x7d, 0x35, 0xd5, 0x19, 0x2b, 0x69, 0xd1, 0xb5,
- 0x65, 0x6d, 0x72, 0x2e, 0x61, 0xa7, 0x25, 0x58, 0x97, 0x0c, 0x51, 0xff,
- 0xfe, 0x16, 0xee, 0xd4, 0xc3, 0xe8, 0x4f, 0xde, 0x0b, 0xdc, 0x58, 0x43,
- 0xfd, 0xf6, 0x61, 0x0f, 0xb3, 0x86, 0x68, 0xdf, 0x1a, 0xaa, 0x0d, 0x77,
- 0x79, 0x7a, 0x4f, 0xb1, 0xae, 0x74, 0xce, 0xe5, 0x62, 0x84, 0xea, 0x7d,
- 0xa2, 0x82, 0x01, 0x36, 0x66, 0x8a, 0xfc, 0x3d, 0xb3, 0xb1, 0xcb, 0xb3,
- 0xf3, 0x4f, 0x36, 0xda, 0xa5, 0x5f, 0xc4, 0x2b, 0x3d, 0x75, 0x29, 0xb2,
- 0x8d, 0xdd, 0x58, 0x9f, 0xec, 0xc1, 0x1c, 0x6b, 0x39, 0xbe, 0xaa, 0xbb,
- 0x88, 0x5a, 0x63, 0xb8, 0xdb, 0x93, 0xc1, 0xf2, 0xbc, 0xbf, 0x6d, 0x10,
- 0x4d, 0x13, 0xc8, 0xf9, 0xbc, 0xfb, 0x50, 0xe5, 0xdd, 0x42, 0x4e, 0x09,
- 0x62, 0xd3, 0x2e, 0xfe, 0x56, 0x71, 0x77, 0xa6, 0xf2, 0xce, 0x70, 0x78,
- 0x2c, 0x88, 0xa1, 0x5d, 0xd4, 0xfb, 0x52, 0x21, 0xb8, 0x8d, 0x9f, 0x96,
- 0xdd, 0x4f, 0xb2, 0x2b, 0xf7, 0xef, 0xaf, 0x91, 0x5d, 0x67, 0x82, 0x41,
- 0x34, 0x13, 0x0c, 0x4b, 0x10, 0x4f, 0xc3, 0x54, 0x1d, 0x9a, 0xc7, 0xf8,
- 0xef, 0x23, 0x07, 0xc5, 0x7d, 0xa5, 0x0a, 0xcf, 0x46, 0xfe, 0x9b, 0x4a,
- 0x58, 0xc1, 0x7c, 0x8b, 0xd5, 0x55, 0x89, 0x47, 0xa3, 0x7b, 0x5c, 0x2d,
- 0xe6, 0x8f, 0xd5, 0xd1, 0x47, 0x47, 0x6c, 0x82, 0x26, 0xa6, 0x96, 0x8b,
- 0xaf, 0xe7, 0x93, 0x88, 0xd1, 0xfd, 0x32, 0xee, 0x54, 0xd6, 0xdf, 0x53,
- 0xfa, 0xbc, 0xf3, 0x07, 0xff, 0xbb, 0xb2, 0x6f, 0x01, 0x8e, 0xea, 0xbc,
- 0xd2, 0xfc, 0x6e, 0x3f, 0xa4, 0xd6, 0x93, 0xab, 0x27, 0x2d, 0x1e, 0xa6,
- 0x9b, 0xbe, 0x2d, 0xb5, 0xad, 0x4e, 0xb8, 0x0d, 0xa2, 0x90, 0x3d, 0xbd,
- 0xa5, 0x06, 0x0b, 0x5b, 0x04, 0x63, 0xcb, 0xb6, 0x32, 0x83, 0x67, 0x53,
- 0x63, 0x05, 0x03, 0xc6, 0xd8, 0x33, 0x91, 0x09, 0x35, 0x25, 0xef, 0xce,
- 0x44, 0x77, 0x25, 0x10, 0x02, 0xf5, 0x4b, 0x12, 0x04, 0x98, 0xaa, 0x2d,
- 0x37, 0x92, 0x40, 0xd8, 0x69, 0x49, 0x78, 0x92, 0xec, 0x90, 0x4c, 0xd5,
- 0x58, 0x01, 0x61, 0x20, 0x04, 0xe3, 0xec, 0x4e, 0x6d, 0x91, 0x5d, 0xcf,
- 0x98, 0xc2, 0x06, 0x9c, 0x18, 0x3f, 0x33, 0x59, 0x8b, 0x78, 0xe2, 0xbb,
- 0xdf, 0xb9, 0xdd, 0x0d, 0x82, 0x21, 0x99, 0x1a, 0x57, 0x75, 0x89, 0xee,
- 0x7b, 0xff, 0xff, 0x9e, 0xff, 0xfc, 0xe7, 0x7c, 0xe7, 0x3b, 0xe7, 0xfc,
- 0xb7, 0x4c, 0x2e, 0x2d, 0xfb, 0xb5, 0x08, 0xc5, 0xda, 0x94, 0xf9, 0x42,
- 0x96, 0xe3, 0x48, 0x1c, 0xed, 0xbe, 0xd9, 0x8f, 0x11, 0x99, 0x84, 0xcb,
- 0x41, 0xad, 0x08, 0x4b, 0x9e, 0xc7, 0x1f, 0xad, 0x3c, 0x51, 0x64, 0x90,
- 0xb9, 0x0b, 0x91, 0x3f, 0x2c, 0x73, 0x17, 0x21, 0xef, 0xa6, 0x2c, 0xf2,
- 0x1c, 0xa6, 0x5c, 0x13, 0x12, 0x5b, 0xe5, 0x79, 0xc7, 0x95, 0xa1, 0xb4,
- 0xc8, 0x90, 0x7b, 0xee, 0x59, 0x73, 0xa3, 0x5a, 0xc4, 0x18, 0x3e, 0x62,
- 0x6e, 0x62, 0x5e, 0xe2, 0x5f, 0xfa, 0x86, 0x99, 0x6a, 0x93, 0xb5, 0xba,
- 0xcd, 0xbd, 0x09, 0x27, 0xfa, 0xa9, 0xb7, 0xad, 0xa1, 0xa3, 0xc2, 0x67,
- 0xb3, 0xff, 0xe5, 0xf4, 0xf6, 0x97, 0xd4, 0xdb, 0xa9, 0xec, 0x3e, 0x1e,
- 0x57, 0x4e, 0xde, 0x8c, 0xf5, 0x22, 0xa3, 0xc8, 0xa5, 0xa0, 0x42, 0x13,
- 0xb9, 0x6c, 0x28, 0x67, 0xdc, 0xac, 0xa0, 0x7e, 0xca, 0x2d, 0x99, 0x9a,
- 0x95, 0x9f, 0x47, 0xa1, 0xce, 0x21, 0x17, 0x2c, 0x9b, 0xc8, 0xc8, 0x35,
- 0x45, 0xfd, 0x5c, 0xb8, 0x69, 0x13, 0xb3, 0xf5, 0x2c, 0x74, 0x46, 0x7c,
- 0xfa, 0xe2, 0x4b, 0x3b, 0x92, 0x32, 0xaf, 0x5d, 0xf2, 0x04, 0x2b, 0xdf,
- 0xb3, 0xd1, 0x9e, 0x56, 0x45, 0x33, 0x3a, 0xb0, 0x59, 0x7b, 0x20, 0x3e,
- 0x20, 0xeb, 0xcf, 0xad, 0xbd, 0x59, 0x79, 0x3a, 0x2a, 0xe3, 0x35, 0x2c,
- 0xb2, 0xc6, 0x59, 0xfb, 0xce, 0x71, 0x6f, 0x73, 0x5c, 0x80, 0x63, 0x32,
- 0xb6, 0xe9, 0x49, 0x7d, 0x26, 0x7e, 0xcd, 0x7d, 0x3a, 0xae, 0x74, 0xf2,
- 0x99, 0xb0, 0xf6, 0xf6, 0xfd, 0xac, 0xaf, 0x1f, 0xa7, 0x6f, 0xf2, 0x37,
- 0xa7, 0x8d, 0xf6, 0x5e, 0x04, 0xc7, 0xb0, 0xcb, 0xaa, 0x49, 0xc8, 0xdc,
- 0xcf, 0x45, 0xcb, 0x51, 0x70, 0x24, 0x37, 0x36, 0x13, 0xc3, 0x33, 0xbd,
- 0xac, 0x9c, 0x3f, 0x0a, 0x3e, 0x0a, 0x76, 0x1b, 0x4a, 0xe4, 0x66, 0x3f,
- 0x4a, 0x6a, 0x38, 0xd2, 0xa7, 0xcb, 0xa7, 0x3c, 0x52, 0xef, 0x53, 0x88,
- 0x19, 0xcc, 0x07, 0xd5, 0x55, 0x1e, 0x07, 0x71, 0x6e, 0x13, 0xbe, 0x20,
- 0xb7, 0x8d, 0x04, 0x9c, 0x96, 0x0f, 0x4b, 0xcd, 0x2f, 0x1f, 0x19, 0x0c,
- 0x02, 0x86, 0xa3, 0x8c, 0xbb, 0x5c, 0x2b, 0x63, 0x3d, 0xba, 0xd3, 0x5f,
- 0x98, 0x53, 0x95, 0xcc, 0xd9, 0xb5, 0x9b, 0x35, 0x22, 0xfa, 0x9d, 0x69,
- 0x8e, 0xf0, 0x5a, 0x6f, 0x3a, 0xb7, 0x4f, 0xe4, 0x10, 0xe4, 0x68, 0xcf,
- 0x68, 0xbf, 0x35, 0x37, 0xdc, 0x76, 0x6f, 0x0e, 0x9b, 0x73, 0x79, 0xa9,
- 0x60, 0x73, 0x31, 0x7a, 0xf7, 0x7a, 0x93, 0x29, 0x54, 0x22, 0xa9, 0xd9,
- 0xe6, 0xd3, 0x4b, 0x98, 0xf5, 0x7b, 0xfb, 0x9a, 0x61, 0xe5, 0xeb, 0x9e,
- 0x14, 0xfa, 0x2b, 0xc4, 0x8f, 0x9c, 0x5a, 0xbd, 0xa7, 0xcc, 0x56, 0x2e,
- 0xb2, 0x5b, 0x52, 0xd9, 0x07, 0x0b, 0xb0, 0x89, 0xb9, 0x76, 0xaa, 0x95,
- 0x98, 0x35, 0x68, 0xb4, 0x70, 0x7a, 0x57, 0x61, 0x38, 0xd5, 0xf9, 0x35,
- 0xbf, 0x97, 0xf1, 0x10, 0xc8, 0x67, 0xde, 0x7f, 0x09, 0x59, 0x4c, 0x1b,
- 0xf4, 0x1a, 0x36, 0x9b, 0x8c, 0xff, 0xcc, 0x34, 0xda, 0x64, 0xac, 0xcc,
- 0xc1, 0x67, 0xff, 0x1b, 0x5f, 0xf0, 0x50, 0x4f, 0x87, 0x2b, 0xa4, 0x7e,
- 0xa6, 0xd6, 0x92, 0xab, 0x0f, 0x16, 0xa3, 0x88, 0xb9, 0x6b, 0x7f, 0x95,
- 0xaf, 0x43, 0xb7, 0x15, 0xe2, 0xfc, 0x57, 0xfe, 0x13, 0x52, 0x55, 0x79,
- 0x70, 0xd5, 0x02, 0x0f, 0xc6, 0x6d, 0xb0, 0xd5, 0x12, 0x7b, 0x1b, 0x80,
- 0xe6, 0x09, 0xee, 0xdb, 0xa0, 0x82, 0xa7, 0x92, 0x36, 0x3c, 0x9a, 0xb4,
- 0x63, 0x6d, 0x12, 0xdf, 0x59, 0x04, 0x4c, 0xd7, 0xc0, 0xdf, 0x3e, 0xa3,
- 0x60, 0x6b, 0x29, 0xfc, 0xad, 0x31, 0xc5, 0xdf, 0xb2, 0x96, 0x39, 0xd3,
- 0x9a, 0x09, 0xe2, 0x19, 0xef, 0x75, 0x0e, 0x70, 0x5f, 0x07, 0xec, 0xa8,
- 0x19, 0xc0, 0x3d, 0xf9, 0x40, 0x83, 0x13, 0xfe, 0x19, 0xc6, 0x99, 0x72,
- 0x07, 0xfc, 0x53, 0x97, 0xed, 0xfe, 0xce, 0x1a, 0x3b, 0x37, 0xb7, 0x56,
- 0x64, 0x71, 0xe1, 0x31, 0xda, 0xf3, 0xa2, 0x41, 0xde, 0xcf, 0xfc, 0x5d,
- 0x65, 0x9e, 0xf3, 0xc9, 0x9f, 0x48, 0xfd, 0x52, 0xae, 0x49, 0xef, 0x52,
- 0x41, 0xe9, 0xa0, 0x9d, 0x18, 0x76, 0xce, 0x3c, 0x5f, 0x25, 0xf8, 0x0d,
- 0x3c, 0x45, 0xd9, 0xdc, 0xfc, 0x4d, 0xad, 0x25, 0x37, 0x5d, 0xa1, 0x62,
- 0xfd, 0xb0, 0xdc, 0x0b, 0x6b, 0x1e, 0x27, 0x7d, 0x2a, 0x8f, 0x3e, 0x7e,
- 0xc4, 0xea, 0x77, 0xd9, 0xb8, 0x46, 0x3b, 0x8a, 0x06, 0x81, 0x35, 0x71,
- 0x3c, 0x51, 0x0c, 0x7f, 0x44, 0x64, 0xac, 0x5b, 0xee, 0xe0, 0xd8, 0x62,
- 0xb4, 0x4c, 0x64, 0xc6, 0x3d, 0x3c, 0xf1, 0xa3, 0x8a, 0x4c, 0x2d, 0xf7,
- 0xf7, 0xf7, 0x5e, 0x7b, 0x1a, 0xfc, 0xd8, 0x94, 0xa4, 0xcd, 0xd9, 0x3c,
- 0x18, 0xce, 0xd6, 0x54, 0x37, 0xa4, 0xbc, 0xb3, 0x7a, 0xa3, 0xff, 0xbd,
- 0x38, 0xdb, 0x37, 0xa5, 0x2f, 0xcc, 0x70, 0x1e, 0x43, 0xd9, 0x40, 0xdd,
- 0x0d, 0x4f, 0x9a, 0x88, 0xea, 0x26, 0xc6, 0xf9, 0x79, 0x53, 0x87, 0x51,
- 0x44, 0x5f, 0xd8, 0x18, 0xfb, 0xd2, 0x34, 0xb2, 0xfe, 0xfc, 0x4a, 0x22,
- 0xa0, 0x6c, 0x21, 0x57, 0x7e, 0x95, 0xf1, 0x74, 0x8c, 0x9f, 0x51, 0xe6,
- 0x70, 0x4e, 0xca, 0x6d, 0xa3, 0x5f, 0xef, 0x4c, 0x01, 0x23, 0xcc, 0xd1,
- 0x0f, 0x2e, 0x17, 0xfe, 0x5e, 0xc4, 0xe7, 0xd1, 0x6b, 0x78, 0x4f, 0x9a,
- 0x9f, 0x23, 0xfc, 0x4c, 0x72, 0x4f, 0xf9, 0x3c, 0x04, 0xc6, 0x1d, 0x88,
- 0x8c, 0x13, 0x68, 0xc7, 0x03, 0x98, 0x62, 0x0c, 0xbc, 0x31, 0xaa, 0xa2,
- 0x64, 0xac, 0x1c, 0x1f, 0x1d, 0x26, 0x3e, 0x1e, 0xca, 0x70, 0xfe, 0x4d,
- 0xe3, 0xd2, 0xdf, 0x92, 0xf5, 0x49, 0x1f, 0x58, 0xfc, 0xa9, 0x00, 0x63,
- 0xa4, 0x1f, 0xd2, 0x0b, 0x7e, 0x57, 0xe7, 0xdc, 0xaa, 0xf4, 0xf1, 0x5a,
- 0x71, 0x34, 0xea, 0xf3, 0xf4, 0xd1, 0xe6, 0x0d, 0x87, 0xf8, 0x58, 0x03,
- 0x5e, 0x8d, 0xe6, 0x7a, 0x42, 0xbe, 0x96, 0x9f, 0x4a, 0x3d, 0x83, 0x21,
- 0x3b, 0x4f, 0x93, 0x6b, 0xb9, 0x58, 0x2a, 0x6b, 0x96, 0xba, 0x74, 0x8e,
- 0xb7, 0xcc, 0xfe, 0xfd, 0x8c, 0x29, 0x7d, 0xca, 0xd7, 0x26, 0xbd, 0x7d,
- 0x29, 0xe8, 0x56, 0xac, 0x3c, 0x5c, 0xe7, 0x4d, 0x1a, 0x90, 0xfd, 0x6d,
- 0xa0, 0x0c, 0xdf, 0xa5, 0xed, 0x07, 0x44, 0xd7, 0x8c, 0xed, 0x52, 0xef,
- 0x2d, 0x43, 0xff, 0x40, 0x39, 0xf6, 0x0c, 0x18, 0xe8, 0x5d, 0xde, 0x86,
- 0x33, 0x51, 0x13, 0x9b, 0x42, 0x26, 0xd6, 0x84, 0xbc, 0x81, 0x57, 0x50,
- 0xdf, 0x78, 0x14, 0x8f, 0x91, 0x43, 0xa8, 0xd4, 0xc9, 0x37, 0xf0, 0xce,
- 0x5e, 0x07, 0x36, 0xeb, 0x7f, 0x4c, 0x1f, 0x36, 0xcd, 0xf7, 0x96, 0x2d,
- 0xc0, 0x70, 0xa2, 0x5e, 0xed, 0xa6, 0x7c, 0x91, 0x36, 0xee, 0x55, 0xd0,
- 0x81, 0x67, 0xf5, 0xef, 0xf0, 0x5e, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b,
- 0xe3, 0xa9, 0xec, 0xa5, 0x41, 0xfb, 0xca, 0xc4, 0xb2, 0x48, 0xb6, 0xce,
- 0xbe, 0xb9, 0x41, 0x30, 0xbf, 0x18, 0xa7, 0xa9, 0xb7, 0x13, 0xc9, 0x08,
- 0xc3, 0x2e, 0x94, 0x67, 0x1b, 0xba, 0xf0, 0x34, 0xf9, 0xc6, 0x3b, 0x24,
- 0x02, 0xf7, 0xc7, 0x15, 0x34, 0xd6, 0xe9, 0xb8, 0x98, 0xfe, 0x06, 0xde,
- 0x1a, 0x0d, 0xe3, 0x4d, 0xc6, 0xf4, 0x25, 0xdf, 0xf5, 0x92, 0x83, 0x7a,
- 0x70, 0x3e, 0x1d, 0xc6, 0xb9, 0xa8, 0xb7, 0xf5, 0x05, 0x65, 0x01, 0x7e,
- 0x9a, 0x76, 0xe0, 0xde, 0x38, 0xf0, 0x4b, 0xce, 0xe3, 0x8f, 0x3b, 0x70,
- 0x25, 0xad, 0xe2, 0x28, 0xf7, 0xc7, 0x11, 0x5a, 0x02, 0xa3, 0xcd, 0x83,
- 0x23, 0x43, 0x8f, 0x62, 0x2a, 0xf5, 0x28, 0x4e, 0x25, 0xdf, 0x31, 0x5d,
- 0x9a, 0xf4, 0x75, 0x5c, 0xb8, 0xc2, 0x7c, 0x6c, 0x9a, 0xda, 0x28, 0x5e,
- 0xd1, 0xca, 0x38, 0xaf, 0x19, 0xa2, 0xf7, 0xb7, 0xf8, 0xdb, 0xfd, 0xf1,
- 0x46, 0x1c, 0x1c, 0xa7, 0x4a, 0x13, 0x3a, 0x12, 0x31, 0x79, 0x56, 0x03,
- 0x62, 0xe4, 0x85, 0xfd, 0x4c, 0xdb, 0xb7, 0x86, 0xee, 0x95, 0x5c, 0x43,
- 0x69, 0xa9, 0xed, 0xcf, 0xae, 0xa3, 0x71, 0x56, 0xcf, 0x4e, 0x72, 0x28,
- 0xea, 0x95, 0xe3, 0xfe, 0x36, 0x11, 0xb4, 0x62, 0xd3, 0xb1, 0x9b, 0xfb,
- 0xd1, 0xc8, 0xfd, 0xf8, 0x06, 0x2e, 0xee, 0x6d, 0xc3, 0x5b, 0xc4, 0xbb,
- 0xd2, 0x65, 0xbe, 0x4e, 0xa7, 0xad, 0x9e, 0x73, 0xa7, 0xcd, 0x54, 0x95,
- 0xe8, 0xb4, 0x0d, 0xbf, 0x88, 0x8a, 0x4e, 0xd3, 0xc4, 0x3f, 0x9f, 0xc7,
- 0x6f, 0xff, 0xcb, 0x4a, 0xda, 0xb3, 0xad, 0x3b, 0x98, 0xe9, 0x41, 0x15,
- 0xaf, 0x70, 0xe1, 0xaa, 0x25, 0x9b, 0xc8, 0xfa, 0x87, 0xe4, 0xfb, 0x85,
- 0xb9, 0xa6, 0x4a, 0xe4, 0x33, 0xcc, 0x3c, 0x4d, 0x0b, 0xe4, 0x29, 0x12,
- 0x67, 0x03, 0x56, 0x3d, 0xbe, 0x2e, 0xde, 0x05, 0x7b, 0xa8, 0x98, 0x79,
- 0x98, 0x77, 0xa6, 0x03, 0x6f, 0xe1, 0xda, 0xa4, 0x0b, 0x8b, 0xe3, 0x1a,
- 0x5e, 0x9e, 0x7c, 0x8d, 0xcf, 0xfa, 0x47, 0x5c, 0xe6, 0x77, 0x5f, 0x3c,
- 0xe3, 0x6f, 0xdd, 0x0d, 0x6d, 0x78, 0x30, 0x2d, 0xeb, 0xcb, 0xe3, 0x83,
- 0x74, 0x44, 0xd2, 0xb2, 0xce, 0x18, 0x7d, 0x43, 0xd6, 0x59, 0xfe, 0xef,
- 0xac, 0xf3, 0xbf, 0x72, 0xbe, 0x05, 0xf4, 0xa5, 0x5c, 0xec, 0x28, 0xc1,
- 0x91, 0xa4, 0x8a, 0xd3, 0x7a, 0x31, 0x2e, 0xa9, 0x52, 0x5f, 0x76, 0x31,
- 0x86, 0x38, 0xd0, 0xcc, 0x9c, 0x71, 0x84, 0x9f, 0x8d, 0xcc, 0x7f, 0xce,
- 0xea, 0x0e, 0x9c, 0xd2, 0x17, 0x10, 0xeb, 0xef, 0xb4, 0x61, 0xb9, 0x46,
- 0xb2, 0x5f, 0x56, 0x8e, 0x73, 0x52, 0xff, 0xb3, 0xae, 0xbb, 0xa4, 0x2f,
- 0x89, 0x31, 0xea, 0x2b, 0x2f, 0xf6, 0x1b, 0xf3, 0xaa, 0x85, 0x35, 0x77,
- 0xca, 0x77, 0xe7, 0x3c, 0x12, 0x82, 0x7f, 0x69, 0x6e, 0xad, 0xca, 0xc6,
- 0x2e, 0xe5, 0x4f, 0x2b, 0x33, 0x78, 0x21, 0x71, 0xec, 0xef, 0x72, 0xd8,
- 0x21, 0xf9, 0x64, 0x1b, 0xe3, 0x10, 0xe3, 0xf2, 0xf1, 0x6d, 0x92, 0xe7,
- 0xd9, 0xc2, 0xef, 0xb5, 0xad, 0xd2, 0xf2, 0x60, 0xb7, 0xf8, 0xde, 0x7b,
- 0x2f, 0x65, 0x38, 0xfa, 0xfb, 0x2f, 0x69, 0xd6, 0xdf, 0xeb, 0x2f, 0x2d,
- 0xb6, 0xfe, 0x7e, 0xf2, 0x92, 0x2f, 0x75, 0x2b, 0x5e, 0x65, 0x38, 0xb0,
- 0x75, 0x6e, 0x05, 0x7d, 0xba, 0xa1, 0x3c, 0xdc, 0x20, 0x5c, 0x72, 0x36,
- 0x8f, 0x08, 0x28, 0x67, 0xa3, 0x92, 0xa7, 0x15, 0x1a, 0xcc, 0xe3, 0x95,
- 0x46, 0xbf, 0x46, 0x3c, 0xee, 0x42, 0xc9, 0x32, 0x0d, 0x17, 0xa8, 0x73,
- 0xc2, 0x28, 0xed, 0xf8, 0xff, 0x20, 0xba, 0x17, 0xed, 0x85, 0x16, 0xf6,
- 0x98, 0x66, 0x7f, 0x48, 0x6a, 0x0c, 0x32, 0xaf, 0x03, 0x1f, 0x70, 0x2f,
- 0x7f, 0x35, 0x5a, 0x84, 0xf7, 0x53, 0x1a, 0x2e, 0xa5, 0xdb, 0xb0, 0x7b,
- 0x32, 0xc3, 0x33, 0x4e, 0x59, 0xfc, 0x5b, 0x63, 0x8e, 0xe9, 0xc0, 0xc1,
- 0xa8, 0x86, 0x58, 0xe2, 0x75, 0xb3, 0x40, 0xf3, 0x4d, 0xf9, 0xed, 0x0e,
- 0x1c, 0x48, 0x4f, 0x63, 0x72, 0xe0, 0x63, 0xd3, 0xae, 0x75, 0xe1, 0xa3,
- 0xd0, 0x34, 0x26, 0x0e, 0x49, 0x5f, 0x4f, 0x47, 0xff, 0x90, 0x86, 0xde,
- 0x84, 0x0d, 0x7b, 0x96, 0xb7, 0xa0, 0x7f, 0xb2, 0x19, 0xc6, 0x98, 0x07,
- 0x7b, 0xd2, 0x69, 0x4c, 0x8d, 0x4e, 0xe3, 0x4c, 0x52, 0x6b, 0x2c, 0x50,
- 0xa6, 0x71, 0x9a, 0xcf, 0xd9, 0x91, 0x78, 0x1b, 0x06, 0xe7, 0xd8, 0x99,
- 0x94, 0x9a, 0xa4, 0x3c, 0x67, 0x1a, 0xdd, 0xa9, 0xbb, 0xd5, 0x44, 0x28,
- 0x4f, 0xa2, 0xa7, 0x3d, 0x53, 0xab, 0x27, 0xbe, 0xa6, 0x35, 0xa5, 0x8f,
- 0xfb, 0x74, 0x34, 0x9d, 0xab, 0xdb, 0xdf, 0x59, 0x0b, 0xd1, 0xd1, 0x37,
- 0xd4, 0xc2, 0x31, 0x1a, 0xba, 0x13, 0xd2, 0x1b, 0xf5, 0xf1, 0x99, 0x26,
- 0x7e, 0xa9, 0x7b, 0xdd, 0x8b, 0xf9, 0xf7, 0xb0, 0xde, 0x89, 0x2d, 0x9c,
- 0x6b, 0x8a, 0x79, 0x90, 0xa6, 0x78, 0x1b, 0x0d, 0xd8, 0xf1, 0x9e, 0x4e,
- 0xce, 0x53, 0x69, 0xc7, 0xab, 0x7a, 0x09, 0x22, 0x65, 0x76, 0xd4, 0x87,
- 0x18, 0xa7, 0xb3, 0x71, 0xfb, 0xc3, 0xa4, 0x82, 0x47, 0x89, 0xa9, 0x27,
- 0x42, 0xf5, 0xed, 0xab, 0x85, 0xd1, 0x1d, 0x52, 0x70, 0x4d, 0xbb, 0x61,
- 0x1a, 0x8c, 0x5d, 0x2e, 0x7f, 0x6e, 0x8f, 0x7e, 0x6d, 0x66, 0xfa, 0x9b,
- 0x5f, 0x98, 0xb9, 0x71, 0x33, 0x94, 0xf1, 0x29, 0x8e, 0x5b, 0xbc, 0xac,
- 0xbe, 0x53, 0xc6, 0xb9, 0x89, 0xe9, 0x32, 0x4e, 0xea, 0xd1, 0xb7, 0xc6,
- 0xe9, 0xd8, 0x39, 0x14, 0xb1, 0xe4, 0xdd, 0x95, 0xc0, 0x52, 0x07, 0xc4,
- 0x9f, 0xea, 0xd5, 0x2b, 0x40, 0xd7, 0xb4, 0x3e, 0x87, 0x5c, 0xc7, 0x1f,
- 0xd8, 0x08, 0xd1, 0x95, 0xe4, 0x92, 0x6f, 0x63, 0x4f, 0x74, 0x14, 0xcc,
- 0x27, 0x89, 0x73, 0xfe, 0xf5, 0x23, 0x48, 0xe1, 0xf9, 0x74, 0x0a, 0x2f,
- 0x50, 0x47, 0x86, 0x75, 0x6e, 0x29, 0x8d, 0x3f, 0x8f, 0xbe, 0x8d, 0x98,
- 0xb5, 0x67, 0x47, 0xb1, 0x21, 0xfa, 0xf7, 0x55, 0xc2, 0x11, 0x77, 0x24,
- 0x56, 0x72, 0x7e, 0xd1, 0xab, 0xb7, 0xd5, 0xc0, 0x97, 0x9c, 0x7f, 0x25,
- 0x7a, 0x46, 0x4c, 0xf3, 0x7b, 0x8c, 0x5f, 0x3f, 0x23, 0xbf, 0xba, 0x96,
- 0x3d, 0x03, 0x55, 0x40, 0x7d, 0x6b, 0x56, 0x1c, 0x6b, 0xe3, 0x3e, 0x57,
- 0x0b, 0xaf, 0x47, 0xc9, 0xb8, 0xa6, 0x2c, 0x8e, 0xc9, 0xbe, 0x93, 0x37,
- 0x8e, 0x7b, 0xf0, 0x14, 0x39, 0x4a, 0xfe, 0xe1, 0x1f, 0x28, 0x12, 0xcb,
- 0x6a, 0x0e, 0x91, 0xef, 0x1f, 0xf2, 0x28, 0x4b, 0xf6, 0xb9, 0xf0, 0x68,
- 0x4c, 0xea, 0x37, 0xcd, 0xe8, 0xd9, 0xaf, 0xf1, 0x1e, 0xaf, 0x7e, 0x81,
- 0x39, 0xe9, 0x69, 0xf8, 0x3c, 0x23, 0xe4, 0x55, 0x6e, 0x62, 0xb1, 0xe3,
- 0x70, 0x29, 0x8a, 0x0e, 0xab, 0xb0, 0x1d, 0x2e, 0x47, 0xf1, 0x61, 0x37,
- 0x6a, 0x18, 0xdb, 0xdc, 0xe3, 0x17, 0x31, 0xb9, 0x0f, 0x6a, 0x51, 0xf8,
- 0x73, 0x33, 0x5f, 0x93, 0x3e, 0x5b, 0x00, 0xa5, 0xe3, 0xdb, 0x91, 0x8e,
- 0x05, 0x51, 0x3c, 0x4e, 0x2a, 0x35, 0x7e, 0x5c, 0xa9, 0xe7, 0x33, 0x1f,
- 0x8a, 0x69, 0x9c, 0x2b, 0xc3, 0x75, 0x56, 0x73, 0x5c, 0x5f, 0xc2, 0xbb,
- 0x5e, 0x7a, 0x65, 0xd7, 0xf4, 0x37, 0x50, 0x30, 0x70, 0xeb, 0x2c, 0x97,
- 0x16, 0xc2, 0x3c, 0x72, 0x91, 0xd6, 0x67, 0x91, 0x39, 0xd7, 0xf5, 0x70,
- 0x76, 0x4d, 0x41, 0x59, 0x93, 0xb3, 0x8d, 0xb6, 0x30, 0x57, 0xea, 0x5f,
- 0xb8, 0x4c, 0xfb, 0xb9, 0x9f, 0xf2, 0xde, 0x60, 0x6e, 0xd8, 0x19, 0x13,
- 0xbb, 0xff, 0x81, 0x42, 0xbf, 0xc1, 0x4c, 0xaa, 0x08, 0x1f, 0xa7, 0x3c,
- 0x8a, 0x8f, 0xeb, 0xf9, 0x0b, 0x5e, 0xff, 0x73, 0xae, 0x67, 0xc7, 0x7e,
- 0x6f, 0xeb, 0x49, 0xc5, 0xdb, 0xbe, 0x4e, 0xf1, 0xa9, 0x3b, 0x94, 0x62,
- 0x5c, 0x1e, 0x2d, 0xc5, 0x15, 0xc6, 0xe2, 0x1b, 0xa3, 0xe5, 0xb8, 0x3a,
- 0x5a, 0x49, 0x5f, 0xd1, 0x38, 0x87, 0x69, 0x96, 0x68, 0x6e, 0xcc, 0xa4,
- 0x5f, 0xc0, 0x9c, 0xd8, 0x02, 0x7c, 0x9c, 0xde, 0x82, 0xd2, 0x98, 0x70,
- 0x76, 0x0f, 0x3e, 0xe2, 0xf5, 0x0f, 0xd3, 0x13, 0x28, 0xdc, 0xf7, 0x39,
- 0xef, 0x31, 0xcd, 0x87, 0xb8, 0xc6, 0xab, 0xe9, 0x0e, 0x14, 0xef, 0xdb,
- 0x06, 0xc7, 0x3e, 0xb3, 0xab, 0x27, 0x84, 0x9f, 0xda, 0xb9, 0x96, 0x6e,
- 0xdd, 0x3b, 0xb5, 0xd8, 0x1e, 0xe4, 0x1c, 0x3a, 0xe7, 0x3c, 0xae, 0x2c,
- 0x19, 0xdf, 0x86, 0xd2, 0x7d, 0x1e, 0x6c, 0xa5, 0x2e, 0x27, 0xa0, 0x05,
- 0xd6, 0x29, 0xdb, 0x90, 0x77, 0x38, 0xa3, 0x83, 0x4d, 0xe3, 0x19, 0x1f,
- 0x79, 0xa8, 0x41, 0xea, 0x43, 0xc7, 0x95, 0x11, 0xcb, 0x47, 0xdc, 0x72,
- 0xfe, 0x04, 0xd3, 0xe9, 0x22, 0x9c, 0x4d, 0x89, 0x8e, 0xe4, 0xec, 0xda,
- 0x04, 0xf2, 0xf7, 0x11, 0x23, 0x47, 0x75, 0x8b, 0x43, 0x88, 0x6f, 0x8c,
- 0xa6, 0xef, 0xe6, 0x5f, 0x41, 0xec, 0x49, 0xd4, 0xd0, 0xb7, 0x16, 0x60,
- 0xcd, 0x3e, 0xe9, 0x91, 0x4e, 0xdd, 0xef, 0xa2, 0x35, 0x8d, 0xa5, 0xef,
- 0xe6, 0x5b, 0x0d, 0xb4, 0x53, 0x6f, 0x8b, 0x01, 0x39, 0xab, 0x61, 0x62,
- 0x5a, 0x3f, 0xae, 0xd8, 0x62, 0x92, 0x6f, 0xb5, 0xd1, 0xe7, 0x5b, 0xd1,
- 0x33, 0x84, 0xf6, 0x83, 0x0d, 0xd2, 0xb7, 0x75, 0x62, 0x84, 0xf9, 0xd3,
- 0x65, 0xe6, 0x1c, 0xd4, 0xb9, 0x9a, 0x17, 0xce, 0xc3, 0xf0, 0xa8, 0x0b,
- 0x3f, 0x1a, 0xf5, 0xa0, 0x31, 0xf6, 0x39, 0x31, 0xa3, 0x10, 0xc7, 0xa9,
- 0xef, 0x49, 0xf2, 0x9f, 0x8f, 0xa2, 0x2a, 0x26, 0x18, 0x6b, 0x3f, 0x8c,
- 0x56, 0x62, 0x9c, 0xb9, 0xd6, 0x75, 0xe2, 0x4c, 0x9a, 0x7b, 0xf3, 0x01,
- 0xf3, 0x8e, 0xef, 0xa5, 0x83, 0xf8, 0x55, 0x34, 0x88, 0x57, 0xa9, 0xc7,
- 0xba, 0x98, 0x9b, 0x32, 0x1d, 0x53, 0x70, 0xe8, 0xb8, 0x92, 0x47, 0xbb,
- 0xf0, 0xc7, 0x34, 0xcf, 0x48, 0xd6, 0x2e, 0xb4, 0xf1, 0x56, 0xfa, 0x91,
- 0xf4, 0xff, 0x25, 0x3e, 0x38, 0xf4, 0x11, 0x90, 0xd3, 0x05, 0x73, 0x75,
- 0x42, 0xaf, 0x7b, 0x0a, 0x15, 0xf4, 0xa5, 0x2f, 0x4d, 0x55, 0x93, 0x9a,
- 0x58, 0x32, 0x74, 0x2d, 0xaa, 0xa9, 0x57, 0xad, 0x35, 0x18, 0x8a, 0x73,
- 0x39, 0x39, 0x46, 0xe5, 0x0e, 0xae, 0x5f, 0x23, 0x66, 0x38, 0xe8, 0x32,
- 0x26, 0xef, 0xbb, 0x8e, 0xfb, 0x0e, 0xfd, 0x69, 0x75, 0x86, 0x03, 0xd1,
- 0x9f, 0x6d, 0x77, 0xd6, 0xb1, 0xa4, 0x96, 0xbd, 0x37, 0xf4, 0x46, 0x34,
- 0x56, 0x2d, 0x3d, 0xa5, 0x93, 0x08, 0x52, 0x2f, 0x77, 0xcb, 0x15, 0x4c,
- 0xbc, 0x45, 0x4c, 0xb9, 0x9a, 0x14, 0xbe, 0x24, 0x3c, 0xa9, 0x8b, 0x31,
- 0xa9, 0x84, 0x3c, 0x41, 0xc3, 0x4e, 0x72, 0x79, 0x5f, 0x7c, 0x8a, 0xb9,
- 0xca, 0x57, 0xc9, 0xd5, 0x4a, 0x39, 0x8d, 0xc1, 0xe7, 0xb5, 0x62, 0x0f,
- 0x7d, 0xb3, 0x40, 0x5b, 0x8c, 0x35, 0xe4, 0x41, 0x0e, 0x8d, 0xa1, 0xe4,
- 0x09, 0x89, 0x27, 0x40, 0x6d, 0x5c, 0x95, 0x7e, 0xcf, 0xfa, 0x9f, 0xe1,
- 0x7e, 0xb4, 0x57, 0xb9, 0x20, 0x3d, 0x9a, 0x37, 0xd1, 0x84, 0xd4, 0xd7,
- 0xad, 0xde, 0x30, 0xdc, 0x61, 0xcd, 0xb8, 0x88, 0x45, 0x16, 0x23, 0x2f,
- 0x0c, 0x8b, 0x3c, 0x95, 0xd4, 0xbf, 0x8a, 0x77, 0xa9, 0xd7, 0x2b, 0x51,
- 0xdf, 0xcc, 0x83, 0xa8, 0x3f, 0x73, 0xc5, 0x2e, 0xfd, 0x2b, 0xb9, 0x3f,
- 0x08, 0x8d, 0xf3, 0x7d, 0x1a, 0x0d, 0x61, 0x40, 0x95, 0xef, 0xc2, 0x1b,
- 0x5b, 0xd1, 0x3d, 0x22, 0x32, 0x98, 0x66, 0x39, 0xf1, 0xf1, 0x09, 0xeb,
- 0xf9, 0xf2, 0xec, 0x3b, 0xf3, 0x0e, 0xaf, 0x6a, 0x20, 0x97, 0x7b, 0x4c,
- 0xe3, 0x68, 0xd2, 0x03, 0xc7, 0xf2, 0xff, 0x41, 0x3d, 0x4c, 0x63, 0x34,
- 0xa5, 0x91, 0x53, 0x16, 0xc1, 0x53, 0x15, 0x44, 0x3f, 0xe3, 0x78, 0x8c,
- 0xf7, 0xa7, 0x63, 0x45, 0x30, 0xaa, 0x32, 0xcf, 0xfc, 0x6a, 0xfc, 0xba,
- 0x39, 0xf5, 0xb8, 0xcc, 0x29, 0xdf, 0x7f, 0xce, 0x31, 0x73, 0xe5, 0xd8,
- 0x23, 0x36, 0xc7, 0xae, 0x9a, 0x53, 0xad, 0xb3, 0x7f, 0x2f, 0xb3, 0xce,
- 0x10, 0x45, 0x6c, 0x55, 0x52, 0x6f, 0xb1, 0xf4, 0xd2, 0x4d, 0xbd, 0xcc,
- 0xd1, 0xde, 0x36, 0x1f, 0xb3, 0xe4, 0x9a, 0xaa, 0x16, 0x9e, 0x5f, 0x1b,
- 0xff, 0xbc, 0x5a, 0xea, 0xa5, 0x12, 0xc3, 0x5c, 0x61, 0xad, 0xf1, 0x0c,
- 0xfe, 0xd1, 0xbc, 0x74, 0xdb, 0x3c, 0x15, 0xbc, 0x26, 0xf1, 0xe8, 0x52,
- 0xb6, 0x1f, 0xed, 0xce, 0xe6, 0x02, 0xd3, 0x38, 0x99, 0x94, 0x58, 0xe0,
- 0xc1, 0x06, 0xa9, 0x43, 0xa9, 0xde, 0x3e, 0x03, 0x53, 0xe4, 0x7e, 0xef,
- 0x50, 0xf7, 0x4c, 0x80, 0xfc, 0x53, 0xe4, 0x7f, 0xb3, 0xe3, 0x55, 0x04,
- 0xa9, 0x4a, 0xe9, 0x29, 0x08, 0x9e, 0x4e, 0x63, 0x57, 0xf2, 0x75, 0xe2,
- 0xda, 0xc7, 0xe4, 0x43, 0x5d, 0xe4, 0xda, 0xd3, 0xe8, 0x49, 0x35, 0xe3,
- 0xe5, 0xfd, 0x2d, 0xc4, 0x18, 0xc1, 0x4a, 0xdf, 0x99, 0xcb, 0xf6, 0x66,
- 0x1c, 0x1c, 0x4b, 0x23, 0x75, 0x58, 0x62, 0xa4, 0x9c, 0xc7, 0x92, 0xf8,
- 0xa8, 0x21, 0x9a, 0x38, 0x0d, 0x83, 0x7f, 0xf7, 0x24, 0xb6, 0x21, 0x72,
- 0xf8, 0x6d, 0x72, 0xfc, 0x69, 0xac, 0x1e, 0xd0, 0xd6, 0x1f, 0xc1, 0x34,
- 0xd6, 0x32, 0x7e, 0x26, 0x13, 0x2d, 0x9c, 0xbf, 0x19, 0xbd, 0xfb, 0xbd,
- 0x01, 0x87, 0x6d, 0x0e, 0x63, 0x94, 0x07, 0x3b, 0x27, 0x23, 0x30, 0x46,
- 0xe4, 0x8c, 0x81, 0x0b, 0xc1, 0xb8, 0x47, 0xf9, 0x90, 0x3c, 0xb9, 0x3e,
- 0xee, 0x65, 0x7e, 0xe6, 0x35, 0xd6, 0x2a, 0x3e, 0x4f, 0x9e, 0x4d, 0xfa,
- 0x59, 0x73, 0x70, 0x46, 0x57, 0x50, 0x70, 0xbf, 0x82, 0x10, 0x63, 0x97,
- 0xa7, 0x9a, 0x31, 0x65, 0x44, 0x47, 0xef, 0x10, 0xd7, 0x7b, 0x73, 0xdf,
- 0x64, 0xbf, 0x1e, 0xe1, 0x7c, 0xb2, 0x77, 0x2d, 0xe8, 0x9d, 0xf4, 0x75,
- 0x9c, 0x81, 0xdb, 0xe2, 0x5c, 0xbd, 0x43, 0xb9, 0x7b, 0x50, 0xfc, 0x71,
- 0x83, 0x37, 0x30, 0x47, 0x91, 0x7b, 0x77, 0x10, 0xbf, 0x66, 0xdf, 0x6f,
- 0x28, 0xc9, 0xe5, 0xe4, 0xa5, 0x36, 0xf1, 0x8b, 0x6e, 0xcb, 0x5f, 0x44,
- 0x17, 0xbd, 0xc9, 0x08, 0x6d, 0xfa, 0xc7, 0x66, 0xaa, 0xb5, 0x95, 0x72,
- 0x36, 0x48, 0xaf, 0xc7, 0xe2, 0x26, 0xe7, 0xa5, 0xee, 0xe6, 0x94, 0xd8,
- 0xdd, 0xdd, 0xee, 0xa2, 0x3d, 0xe5, 0x13, 0x9f, 0x0a, 0x26, 0x5c, 0x70,
- 0x1d, 0x29, 0x42, 0xfe, 0xb0, 0xf0, 0x34, 0xa8, 0xa5, 0xcc, 0xfb, 0xe5,
- 0x3c, 0xc3, 0x30, 0x6d, 0xd4, 0x36, 0x41, 0x1f, 0x8b, 0xba, 0xb1, 0x68,
- 0xc2, 0x8d, 0x1f, 0x11, 0x03, 0x6a, 0x26, 0x34, 0x1c, 0x27, 0x06, 0xb8,
- 0x27, 0x02, 0x98, 0x24, 0x06, 0xcc, 0xc9, 0xd6, 0x3e, 0xde, 0x4c, 0xcf,
- 0x9f, 0x8b, 0x42, 0x79, 0x96, 0xe8, 0x31, 0xb7, 0xaf, 0xb2, 0xa7, 0x2d,
- 0xc4, 0x3d, 0xd9, 0xdf, 0x00, 0x76, 0x0f, 0xa5, 0xb1, 0x6a, 0x9f, 0x89,
- 0x9f, 0xeb, 0xf5, 0xee, 0x02, 0x45, 0xf2, 0x04, 0x13, 0x69, 0x5d, 0xce,
- 0x4d, 0x7a, 0xd7, 0xcb, 0xb9, 0xe2, 0xf6, 0x4a, 0x13, 0x79, 0x21, 0xaf,
- 0x4e, 0xb4, 0x5f, 0x5f, 0xa0, 0x48, 0xdc, 0xaa, 0xf7, 0x6c, 0xc1, 0x7c,
- 0x64, 0x7a, 0x65, 0x0f, 0x62, 0x8b, 0xaa, 0xd0, 0x1f, 0x5b, 0xb0, 0xa7,
- 0xcc, 0x70, 0x5d, 0x6b, 0x30, 0xcd, 0x4d, 0xa1, 0xdf, 0x56, 0x59, 0xb5,
- 0x65, 0xdb, 0x1f, 0x71, 0xed, 0x6d, 0x5c, 0xb7, 0xac, 0xbd, 0x03, 0xb1,
- 0xbd, 0x0a, 0xd2, 0xfe, 0x0e, 0x44, 0x47, 0x3b, 0xd0, 0xbf, 0x57, 0x30,
- 0xa1, 0x8f, 0x98, 0x60, 0x76, 0x3d, 0x1b, 0x7a, 0x0c, 0x57, 0x2d, 0x16,
- 0x20, 0x63, 0xbc, 0x01, 0x8f, 0x6d, 0xf6, 0x3e, 0xe4, 0x53, 0xfe, 0x8c,
- 0xef, 0x34, 0x0f, 0x08, 0xa7, 0xf6, 0xf7, 0xf5, 0x72, 0xff, 0x1f, 0x3f,
- 0x24, 0xf1, 0xc6, 0x34, 0xfb, 0xc8, 0x59, 0x51, 0x26, 0x6b, 0xd0, 0xa4,
- 0x3e, 0xfe, 0x71, 0x8d, 0xe6, 0x9b, 0xe9, 0x67, 0x6c, 0xbf, 0xb8, 0xaf,
- 0x7e, 0xcb, 0x16, 0xe1, 0x31, 0xcb, 0x84, 0xdb, 0xa5, 0x71, 0xe1, 0xf0,
- 0x7d, 0x48, 0x3d, 0xce, 0xf5, 0x70, 0xaf, 0x9c, 0xf1, 0x2f, 0x4c, 0xe1,
- 0x72, 0x76, 0x4d, 0x53, 0x8f, 0x12, 0xfb, 0x6c, 0x13, 0x7e, 0xf4, 0x94,
- 0xc1, 0xb8, 0xd6, 0x20, 0xcf, 0xbf, 0x29, 0x3f, 0xd7, 0xdb, 0x8c, 0xfe,
- 0xfd, 0xc2, 0x35, 0x84, 0x97, 0xf9, 0x8c, 0x0f, 0xd0, 0x82, 0xe4, 0x64,
- 0xe6, 0x59, 0xd1, 0xc4, 0x9d, 0xb6, 0x22, 0xfb, 0x7e, 0x1a, 0xbb, 0x69,
- 0x97, 0x2e, 0xce, 0xcf, 0xf8, 0xc2, 0xf9, 0xb4, 0x40, 0x81, 0x3c, 0x6f,
- 0xe2, 0xc7, 0xe6, 0x9e, 0x2a, 0xd1, 0x8d, 0xcc, 0x7f, 0xba, 0x4a, 0x30,
- 0x63, 0x53, 0xe8, 0x0f, 0xad, 0xf5, 0x75, 0xfe, 0xf5, 0xb6, 0x64, 0xf4,
- 0x21, 0xf7, 0x9e, 0xfe, 0x3d, 0xf2, 0x5c, 0xe0, 0x7d, 0x22, 0x53, 0x07,
- 0x76, 0xef, 0x85, 0x51, 0xa8, 0x49, 0xaf, 0xa0, 0x03, 0x7d, 0xd4, 0xef,
- 0xce, 0x64, 0x07, 0x0e, 0xd2, 0x67, 0x87, 0xf5, 0x13, 0x35, 0x36, 0xd4,
- 0xcd, 0xd8, 0x31, 0xf5, 0x93, 0x45, 0xc4, 0xd3, 0x25, 0xcb, 0xfc, 0xf4,
- 0xaf, 0x0e, 0xc4, 0x53, 0x63, 0x73, 0xad, 0x3e, 0x9f, 0x4d, 0xe2, 0x9f,
- 0xe8, 0xa2, 0x13, 0x85, 0x03, 0xa7, 0xe1, 0x1c, 0xe8, 0x44, 0x81, 0xbf,
- 0x09, 0x0f, 0x87, 0x2e, 0x99, 0x57, 0x35, 0x87, 0xfb, 0x24, 0xf5, 0x73,
- 0x22, 0x58, 0xc3, 0x7c, 0x92, 0x39, 0xcc, 0xc8, 0x3c, 0xfa, 0x7e, 0x03,
- 0xf9, 0xae, 0xf4, 0xf4, 0x6d, 0x58, 0xbb, 0x5c, 0x72, 0x75, 0x85, 0xb6,
- 0x5d, 0xcd, 0x5c, 0x53, 0x53, 0x9f, 0xb7, 0xce, 0x5f, 0x90, 0x87, 0x55,
- 0x7a, 0xf0, 0x8c, 0x75, 0xee, 0x40, 0xae, 0x6f, 0x67, 0x8e, 0xb0, 0x1d,
- 0x35, 0x31, 0xc3, 0x14, 0x7d, 0x9f, 0x44, 0xe4, 0x25, 0x1b, 0xe5, 0x68,
- 0x5c, 0xe6, 0xdf, 0x32, 0xa3, 0x88, 0x4d, 0xfb, 0xdb, 0x27, 0x14, 0xdd,
- 0xf5, 0xc8, 0xb8, 0x82, 0xc0, 0x00, 0xe7, 0x0a, 0xfd, 0xf5, 0xdc, 0x4c,
- 0x7d, 0x2c, 0xc7, 0xf9, 0xb6, 0x93, 0x27, 0x6c, 0x47, 0x09, 0xc7, 0xbb,
- 0x35, 0xc1, 0x86, 0xc8, 0x4a, 0xe9, 0xa5, 0xa4, 0x43, 0xfe, 0xd6, 0x62,
- 0x45, 0xf8, 0x90, 0xbf, 0x71, 0xad, 0x22, 0xdc, 0x45, 0xc6, 0xe9, 0xae,
- 0xba, 0xf1, 0x8b, 0xd9, 0x9e, 0x57, 0x03, 0xf1, 0xc1, 0x63, 0x9d, 0x85,
- 0x7c, 0xed, 0xe6, 0x79, 0x89, 0x4c, 0xbd, 0xda, 0x19, 0x97, 0xbc, 0xe2,
- 0x58, 0x68, 0x55, 0xb4, 0x91, 0x58, 0x67, 0x36, 0x8d, 0xd1, 0xee, 0x2f,
- 0xa3, 0x12, 0xff, 0x33, 0x2a, 0xb8, 0xe6, 0xc1, 0xff, 0x8a, 0xe6, 0x4b,
- 0xbe, 0x9c, 0x92, 0x7a, 0xe4, 0xb9, 0xa4, 0x61, 0x52, 0xaf, 0x2d, 0x6b,
- 0x69, 0x4b, 0x81, 0x50, 0x31, 0x50, 0xd5, 0xfd, 0x8c, 0xd3, 0xca, 0xdf,
- 0x4b, 0x50, 0xc6, 0x18, 0x30, 0x30, 0xf2, 0xfb, 0x6a, 0xaf, 0xc4, 0xe1,
- 0x42, 0xa9, 0x81, 0xda, 0xb1, 0x33, 0xf4, 0x2f, 0x66, 0x2a, 0x7b, 0x76,
- 0xf5, 0xc2, 0x5e, 0xb1, 0xd3, 0x00, 0xf2, 0xe3, 0x17, 0x69, 0x93, 0x2a,
- 0xce, 0x47, 0x7d, 0xfa, 0x3a, 0xdb, 0x37, 0x68, 0xff, 0x8b, 0x6e, 0xc3,
- 0xee, 0x45, 0xda, 0xa3, 0x78, 0xda, 0xc2, 0xee, 0x30, 0x7a, 0x18, 0x1b,
- 0xc8, 0xe3, 0x0e, 0x3c, 0x63, 0x53, 0x51, 0x10, 0xf3, 0xa9, 0x3e, 0xe6,
- 0xdb, 0x3d, 0x7c, 0x86, 0x70, 0xcc, 0x0a, 0x72, 0xc0, 0x67, 0xa3, 0xf5,
- 0x9e, 0x5f, 0x63, 0x03, 0xfd, 0x51, 0x9e, 0x21, 0x6b, 0xd2, 0x50, 0xcc,
- 0xbc, 0xf2, 0x14, 0xd7, 0xb1, 0xb3, 0x2c, 0xf3, 0xdc, 0xd2, 0xec, 0xdc,
- 0xf1, 0x11, 0xe1, 0x5f, 0x2b, 0xb0, 0xce, 0x9a, 0x3b, 0x68, 0xf9, 0xe6,
- 0x01, 0x39, 0x5b, 0x5e, 0xa7, 0x21, 0x91, 0x6e, 0xc6, 0xb6, 0xf2, 0x05,
- 0x38, 0x98, 0xd8, 0x8e, 0xa5, 0xe4, 0xc1, 0x4f, 0x96, 0x1b, 0x8c, 0x8d,
- 0xc4, 0xa1, 0xb8, 0xa6, 0xde, 0xa7, 0x3c, 0x90, 0xed, 0x3f, 0x54, 0xc2,
- 0x11, 0x97, 0x98, 0x97, 0x87, 0x41, 0x75, 0x3e, 0x8a, 0xac, 0x33, 0x7f,
- 0x99, 0xb9, 0xfb, 0x47, 0xbc, 0xd9, 0x38, 0x48, 0xd4, 0x88, 0x5b, 0xe7,
- 0x2d, 0x02, 0x2f, 0x90, 0x4b, 0xa4, 0x18, 0x01, 0xf3, 0xc2, 0x5a, 0x6a,
- 0x33, 0x0a, 0x60, 0x54, 0x0b, 0x26, 0xca, 0x98, 0x79, 0x77, 0xc8, 0x54,
- 0x9e, 0x95, 0x29, 0x77, 0x3d, 0xc5, 0x6b, 0x62, 0x5b, 0xc2, 0x2f, 0xe4,
- 0xf7, 0x42, 0xb4, 0xd2, 0x9e, 0x2a, 0x29, 0x73, 0xc2, 0x3a, 0xb7, 0xe9,
- 0xd5, 0x0d, 0x5b, 0x03, 0x3e, 0xdb, 0x97, 0xb1, 0xc1, 0xf5, 0xb5, 0xdc,
- 0xff, 0xd2, 0x06, 0xcc, 0x1c, 0x96, 0x78, 0xf6, 0xfb, 0xcf, 0x52, 0x18,
- 0x37, 0xcf, 0x52, 0x88, 0x5e, 0xbd, 0x67, 0xde, 0x45, 0xfd, 0xd4, 0x53,
- 0xb6, 0xa3, 0x26, 0x2a, 0x44, 0xc7, 0x9b, 0xdd, 0x92, 0x87, 0xda, 0xc8,
- 0x23, 0x8c, 0x74, 0xd2, 0x2d, 0xb1, 0xd2, 0x11, 0x07, 0x16, 0xc5, 0x0d,
- 0xe4, 0x87, 0xb5, 0x03, 0xd7, 0xec, 0x37, 0xcc, 0xf6, 0xea, 0x79, 0xcc,
- 0x03, 0x6f, 0xad, 0xb9, 0x8f, 0xb2, 0xdb, 0xb5, 0x1f, 0x9b, 0x0f, 0x56,
- 0x8a, 0x8c, 0x3f, 0x72, 0x67, 0xea, 0xcc, 0x0b, 0xa9, 0x97, 0x9c, 0x4e,
- 0x4c, 0xda, 0xcf, 0xdf, 0x98, 0x5f, 0xbb, 0xed, 0xba, 0xf0, 0x19, 0xb1,
- 0xd3, 0xd9, 0x67, 0xdb, 0xc4, 0x66, 0x3d, 0xb4, 0xd3, 0x69, 0x8c, 0x25,
- 0x1b, 0x30, 0x90, 0x10, 0x1d, 0x47, 0x70, 0x99, 0xfc, 0xb0, 0x76, 0x70,
- 0x1a, 0xc3, 0xe4, 0x87, 0xbe, 0xb8, 0xf7, 0x00, 0x35, 0x89, 0x6d, 0x6a,
- 0x93, 0xc5, 0x93, 0x5c, 0x5a, 0x4e, 0x86, 0xaf, 0x5a, 0x7a, 0x97, 0x18,
- 0xb3, 0x87, 0xeb, 0xbd, 0x97, 0x3c, 0xa9, 0x39, 0x96, 0x0f, 0xad, 0xac,
- 0x14, 0xc5, 0x9a, 0xf4, 0x2b, 0x32, 0xf7, 0x45, 0x29, 0x4b, 0x91, 0xe6,
- 0xc3, 0x5a, 0xeb, 0x5e, 0x8f, 0x75, 0xae, 0xc1, 0x51, 0x2e, 0x31, 0x58,
- 0xe2, 0x2e, 0xf9, 0xf7, 0x72, 0x89, 0xbb, 0x61, 0xca, 0xb6, 0x98, 0x7b,
- 0xb6, 0x14, 0xee, 0x07, 0x3c, 0xa8, 0x79, 0x80, 0x31, 0x72, 0x89, 0x82,
- 0xf2, 0x25, 0x7e, 0x63, 0xa9, 0xad, 0x19, 0xa8, 0xd6, 0x88, 0x3f, 0x6e,
- 0xb3, 0x27, 0xf1, 0x3b, 0xce, 0xd1, 0x01, 0x73, 0x6f, 0x21, 0x36, 0xec,
- 0x9d, 0x43, 0x5b, 0xf5, 0x48, 0x7d, 0xdd, 0xe5, 0x0a, 0x47, 0x43, 0xae,
- 0x58, 0xbd, 0xee, 0x54, 0x16, 0x33, 0x1e, 0xcb, 0xfe, 0xc9, 0xf3, 0xbf,
- 0x72, 0x1b, 0x5f, 0xaa, 0x60, 0x7c, 0x7b, 0xd2, 0x92, 0x41, 0x6a, 0xc0,
- 0x32, 0xee, 0xdf, 0xee, 0xd3, 0xd4, 0xcd, 0x7d, 0xba, 0x0f, 0x8e, 0x27,
- 0x2a, 0xc9, 0xbf, 0xee, 0x1e, 0x43, 0x0a, 0x18, 0x43, 0xee, 0x8d, 0x99,
- 0x5d, 0x5b, 0x43, 0x45, 0x52, 0x17, 0xb2, 0x62, 0x48, 0xbb, 0x8d, 0x38,
- 0x5a, 0x2a, 0x76, 0xe1, 0xab, 0x21, 0xc6, 0xe9, 0x99, 0xdf, 0xc4, 0x3e,
- 0xac, 0x3a, 0x5e, 0xf6, 0xb7, 0x0e, 0xec, 0x22, 0x66, 0xca, 0xd9, 0x6e,
- 0xa7, 0xa6, 0xd1, 0xff, 0x3b, 0xd0, 0xc3, 0x39, 0x5f, 0x26, 0x6e, 0x0e,
- 0x10, 0x37, 0x6f, 0x2c, 0x3b, 0xf1, 0x93, 0x1a, 0xd4, 0xd1, 0x08, 0xa6,
- 0xfe, 0x5b, 0xb9, 0xe0, 0xe6, 0x52, 0x7f, 0xc7, 0x27, 0x16, 0x6e, 0xca,
- 0xdc, 0x32, 0xdf, 0xec, 0xb9, 0x17, 0xf2, 0xdf, 0x85, 0x52, 0x4b, 0x34,
- 0x9d, 0xda, 0xff, 0x36, 0x77, 0x56, 0x8a, 0xac, 0x77, 0x93, 0x43, 0xb0,
- 0x76, 0x76, 0x4f, 0x7e, 0x9a, 0x98, 0x6b, 0xe5, 0x08, 0x8c, 0xb9, 0x11,
- 0xac, 0x59, 0xae, 0xe2, 0x6a, 0x74, 0x1a, 0x05, 0x87, 0x72, 0xf8, 0x64,
- 0x36, 0x9d, 0x22, 0x36, 0x0d, 0x43, 0xf0, 0xa8, 0x91, 0xfb, 0x62, 0xd0,
- 0x4f, 0x4a, 0x30, 0x91, 0xd4, 0x88, 0x99, 0x26, 0xfa, 0x43, 0x2e, 0x72,
- 0xdb, 0xee, 0x93, 0x79, 0x56, 0x9c, 0x28, 0x21, 0x86, 0xe7, 0x78, 0xb7,
- 0x70, 0x6e, 0xc1, 0x1f, 0xe6, 0x18, 0x23, 0x76, 0xe4, 0x2d, 0x93, 0xbc,
- 0xe2, 0x73, 0xf3, 0x42, 0x9b, 0xdc, 0xb7, 0x00, 0xc3, 0x7b, 0xc5, 0xfe,
- 0x7c, 0xa8, 0xd1, 0x2e, 0x32, 0xcf, 0x00, 0xde, 0x8f, 0xda, 0xee, 0x71,
- 0x91, 0x1b, 0x77, 0xe9, 0xcb, 0x71, 0xa3, 0xa2, 0x87, 0x3e, 0xef, 0xe6,
- 0x6f, 0x53, 0x38, 0x12, 0x75, 0x21, 0xcf, 0xd2, 0x69, 0x29, 0xd7, 0x90,
- 0xb1, 0xa1, 0x9d, 0xb4, 0xa1, 0x7c, 0xe6, 0x6f, 0x0f, 0x5b, 0xbe, 0x2a,
- 0xf3, 0x4c, 0xe3, 0x15, 0x72, 0x5a, 0x6d, 0xb9, 0xf0, 0xd9, 0x20, 0xe3,
- 0x62, 0x09, 0xe2, 0x03, 0x5d, 0x38, 0x1f, 0x2a, 0x41, 0xec, 0x90, 0xf8,
- 0xd8, 0x02, 0xc1, 0x52, 0x3e, 0xb7, 0x91, 0x3a, 0x51, 0x89, 0x35, 0xf5,
- 0x9d, 0x76, 0x7b, 0x09, 0x2e, 0x95, 0x31, 0xaf, 0xb5, 0xde, 0xe3, 0x69,
- 0xc5, 0xc1, 0xac, 0x5d, 0xa8, 0xb4, 0x8b, 0xd6, 0x9b, 0x3c, 0x3a, 0xb7,
- 0x96, 0x9c, 0xcf, 0x66, 0xfa, 0xe1, 0xbd, 0xe4, 0x36, 0x2f, 0x4b, 0xfd,
- 0xc8, 0xe6, 0x63, 0x2c, 0x61, 0xce, 0x34, 0x29, 0xfa, 0xfd, 0xeb, 0xb9,
- 0x19, 0xac, 0x78, 0xa5, 0x26, 0x73, 0x76, 0x25, 0xa7, 0xf7, 0xdc, 0x77,
- 0x6d, 0x7d, 0xa1, 0xf2, 0x0b, 0x73, 0x6b, 0x95, 0xc8, 0x77, 0x9d, 0x79,
- 0xda, 0x77, 0xf9, 0xfb, 0x2a, 0xf4, 0x8e, 0xcc, 0x8e, 0x15, 0xe2, 0x87,
- 0x9e, 0xdb, 0xce, 0xd5, 0x95, 0xc5, 0xe5, 0xdd, 0xa9, 0x63, 0xa1, 0x67,
- 0xb8, 0x0f, 0xfe, 0xa5, 0xf5, 0x56, 0xdd, 0x85, 0xdc, 0x97, 0x79, 0x89,
- 0x60, 0xac, 0xc1, 0x18, 0x5f, 0x82, 0x9f, 0x26, 0x25, 0xe6, 0x9a, 0xc8,
- 0xa7, 0xfd, 0x5d, 0xaa, 0xec, 0x7e, 0xbe, 0xcc, 0xe2, 0xd2, 0x25, 0x28,
- 0xa7, 0xbd, 0x0f, 0x8e, 0xdc, 0xcd, 0xb6, 0x6f, 0xc5, 0x85, 0x74, 0x48,
- 0x21, 0x4e, 0xfc, 0x8b, 0xd9, 0xff, 0xf5, 0xcc, 0x98, 0x0b, 0x49, 0x17,
- 0x3e, 0x0a, 0xb5, 0x63, 0xaa, 0x2c, 0x8c, 0xa1, 0x44, 0x01, 0xda, 0xab,
- 0xeb, 0xac, 0x77, 0x0a, 0x6a, 0xe2, 0x1e, 0x5c, 0x8c, 0x3a, 0xd1, 0x38,
- 0xd7, 0x63, 0xd5, 0xd3, 0x6c, 0xf4, 0x85, 0x77, 0xa2, 0x11, 0xcb, 0xe7,
- 0x66, 0xc7, 0x8c, 0x3c, 0x6d, 0x19, 0x1e, 0xca, 0xe2, 0xfa, 0xc1, 0xc4,
- 0xe7, 0xc4, 0x9d, 0x52, 0xa3, 0x22, 0x5c, 0x82, 0x7b, 0x87, 0x0c, 0xc1,
- 0x64, 0xa3, 0x24, 0xac, 0xcd, 0xdc, 0xa7, 0x94, 0xa0, 0x69, 0x44, 0x30,
- 0x5e, 0x7c, 0x35, 0x4d, 0x5f, 0x6d, 0xe3, 0x1e, 0x75, 0xa2, 0x6e, 0xbf,
- 0xa5, 0x57, 0xd5, 0xae, 0x98, 0x5d, 0x57, 0xf4, 0x88, 0xce, 0x18, 0xd7,
- 0xf9, 0x10, 0xed, 0x7e, 0x26, 0xe4, 0x6d, 0xaf, 0xb0, 0x6b, 0x1d, 0xef,
- 0x29, 0x41, 0x4c, 0x8c, 0x03, 0x03, 0x87, 0x03, 0xf8, 0x20, 0x21, 0x9c,
- 0x3f, 0x80, 0x5f, 0x4d, 0x06, 0xf1, 0x2e, 0x63, 0x53, 0x41, 0xdc, 0x1b,
- 0x79, 0x8e, 0x39, 0xdd, 0xfb, 0xfc, 0x9e, 0x1f, 0xd7, 0x71, 0x8d, 0xfa,
- 0x73, 0xc6, 0x1b, 0x70, 0x65, 0xf2, 0x01, 0x5c, 0xdd, 0xaf, 0xe0, 0x84,
- 0xf6, 0x00, 0x2e, 0x8f, 0x75, 0x62, 0xd9, 0x7e, 0x39, 0x87, 0x76, 0x2c,
- 0xa4, 0x32, 0x36, 0x3c, 0x53, 0x6b, 0x76, 0xbd, 0xa8, 0xd7, 0x41, 0x2f,
- 0xf7, 0xea, 0xed, 0xcc, 0x99, 0x04, 0xd3, 0x23, 0x36, 0xd9, 0x33, 0xd9,
- 0xbb, 0x4e, 0x5c, 0xb5, 0x70, 0xfc, 0xee, 0xd8, 0x70, 0x0b, 0xc3, 0xe5,
- 0x39, 0x82, 0x27, 0x0b, 0xf1, 0x7d, 0x26, 0xab, 0x3d, 0xbc, 0xcf, 0x45,
- 0xec, 0x7b, 0x36, 0x5a, 0x80, 0xfc, 0xaa, 0x52, 0x2b, 0x97, 0x29, 0x8c,
- 0x07, 0x70, 0x96, 0xba, 0x5b, 0x53, 0xe5, 0xe5, 0x77, 0x89, 0xbb, 0x41,
- 0xe6, 0x2d, 0x15, 0xf8, 0xe0, 0xb6, 0x78, 0xfb, 0x7d, 0xf3, 0x49, 0x0b,
- 0x9f, 0xeb, 0xe7, 0x09, 0xff, 0x7a, 0x3d, 0xf1, 0xeb, 0x1a, 0xc1, 0x69,
- 0xa9, 0x21, 0x96, 0x6a, 0xda, 0x96, 0xbf, 0x80, 0xbc, 0x6f, 0x75, 0xe2,
- 0x3f, 0x17, 0x93, 0x17, 0xbf, 0x18, 0xaa, 0x33, 0xca, 0xa0, 0xf1, 0xbe,
- 0xa9, 0x65, 0x2a, 0x56, 0xf1, 0xaf, 0x9f, 0xf7, 0x05, 0x29, 0xc7, 0x75,
- 0x33, 0xa5, 0xfa, 0xf8, 0xef, 0x05, 0x8c, 0xef, 0xdb, 0x71, 0x3e, 0x56,
- 0xdf, 0x7e, 0x58, 0xb9, 0x66, 0x1a, 0x55, 0xb5, 0xfc, 0xad, 0x12, 0x17,
- 0xa2, 0xde, 0xa9, 0x31, 0xd4, 0x7b, 0x66, 0x94, 0x83, 0xa6, 0xa1, 0xca,
- 0xfe, 0xc8, 0x7a, 0x65, 0xfc, 0x62, 0x5e, 0xbf, 0x34, 0xcb, 0x0e, 0x6f,
- 0xe5, 0x5d, 0xce, 0x9b, 0xf6, 0x27, 0xbc, 0xc4, 0x6c, 0x1a, 0xd5, 0xeb,
- 0xd5, 0x1e, 0x62, 0x41, 0x44, 0xbd, 0x9b, 0xfd, 0x15, 0xd0, 0xfe, 0xc2,
- 0xcc, 0x23, 0x4b, 0xa0, 0x5a, 0xf1, 0xa9, 0x15, 0xc9, 0x91, 0xd9, 0xdc,
- 0x52, 0xec, 0x2e, 0xc3, 0x53, 0xdb, 0xcb, 0xba, 0x4f, 0x3a, 0x89, 0x45,
- 0x09, 0xe2, 0x78, 0x9c, 0x38, 0x9e, 0x4f, 0x1c, 0xbf, 0xbe, 0xaf, 0x10,
- 0xe7, 0xf7, 0x35, 0x22, 0x5d, 0x26, 0x63, 0xec, 0x70, 0x72, 0x75, 0xa9,
- 0xec, 0x79, 0x85, 0x9a, 0xc1, 0x95, 0x72, 0x8e, 0x13, 0x82, 0x5f, 0x79,
- 0x71, 0xe6, 0x59, 0xad, 0x76, 0x38, 0xac, 0x33, 0xf6, 0x73, 0x6e, 0xb3,
- 0x3f, 0x97, 0x96, 0x8f, 0x96, 0x4a, 0xc1, 0x87, 0xd7, 0xe7, 0x49, 0x1c,
- 0x7d, 0x9d, 0xb2, 0x9c, 0xa4, 0x4d, 0x6f, 0xd4, 0x57, 0x48, 0x5f, 0x8f,
- 0xf7, 0xcb, 0x38, 0xc9, 0x6d, 0x4c, 0xec, 0xa6, 0x85, 0xd5, 0x55, 0x99,
- 0x48, 0xe8, 0x61, 0xc6, 0xac, 0x10, 0x22, 0x65, 0x41, 0xc6, 0x2a, 0xf9,
- 0xae, 0xe2, 0x0a, 0xf3, 0xb2, 0xf1, 0xa0, 0x82, 0x8f, 0xbe, 0x22, 0x5c,
- 0xc0, 0xaf, 0x9f, 0x57, 0x84, 0x0b, 0xc8, 0x78, 0xc1, 0x88, 0x52, 0x0b,
- 0x23, 0xf2, 0x2d, 0x5e, 0x34, 0xd7, 0xc2, 0x16, 0x79, 0x47, 0xa9, 0x86,
- 0x71, 0xe7, 0xfe, 0x44, 0xfd, 0x94, 0xcf, 0x4e, 0x8e, 0xf6, 0x27, 0x5f,
- 0x21, 0x37, 0xb3, 0x38, 0x02, 0xf1, 0x3e, 0x87, 0x0d, 0x72, 0xee, 0x76,
- 0xb6, 0x3e, 0x72, 0xe7, 0x72, 0x3d, 0x19, 0xac, 0x2c, 0x15, 0x2e, 0xf7,
- 0xff, 0xcc, 0xd6, 0xdb, 0xe4, 0xcf, 0xe1, 0xc8, 0x3f, 0xf0, 0xbb, 0x8c,
- 0x17, 0xbf, 0xa3, 0x5d, 0xc4, 0x7f, 0x62, 0x3e, 0x6d, 0xf1, 0xb9, 0x97,
- 0xe7, 0xc9, 0xf9, 0x43, 0xc7, 0xe0, 0xd0, 0x3c, 0x39, 0x6f, 0x65, 0x9b,
- 0xc5, 0x0b, 0x32, 0xb1, 0xf6, 0x5d, 0x73, 0xad, 0x25, 0xeb, 0x91, 0xec,
- 0x7d, 0x92, 0x43, 0x8b, 0x2c, 0x0a, 0x5e, 0xd1, 0xea, 0xd5, 0xb3, 0x28,
- 0x16, 0x3c, 0x89, 0x48, 0x0f, 0xb3, 0x50, 0xf3, 0xb9, 0x8f, 0xf0, 0x6f,
- 0x3f, 0xaf, 0xbf, 0xa1, 0x39, 0x1a, 0xb7, 0x42, 0xfa, 0xb6, 0x36, 0xee,
- 0x55, 0xbd, 0xfb, 0x2c, 0xfc, 0x91, 0x7c, 0x65, 0xc6, 0x6c, 0xaf, 0x94,
- 0x7b, 0x32, 0xfd, 0x5b, 0x28, 0x17, 0xad, 0xfa, 0x49, 0xc6, 0x66, 0x16,
- 0xd0, 0x66, 0x04, 0xbb, 0x84, 0x8b, 0x2c, 0xe1, 0xda, 0x55, 0x8c, 0x4c,
- 0x02, 0x79, 0x83, 0x2e, 0x8b, 0x1b, 0xa9, 0xb5, 0xb5, 0x9e, 0xcd, 0xf8,
- 0xe7, 0x79, 0xf2, 0xee, 0xd1, 0x0e, 0x1d, 0xf7, 0xd8, 0xf0, 0xf6, 0x3d,
- 0xb6, 0xf0, 0xca, 0x6f, 0x3d, 0xd4, 0x90, 0x37, 0x5f, 0xde, 0xff, 0x20,
- 0xc3, 0x93, 0xfa, 0xad, 0x5b, 0x7a, 0x8d, 0xab, 0x19, 0xc3, 0x86, 0x99,
- 0xe3, 0xaf, 0x0e, 0xfe, 0xd6, 0xfc, 0xa6, 0x23, 0xe2, 0xb1, 0xa3, 0xd6,
- 0xd3, 0x8b, 0x1b, 0x66, 0xaa, 0x52, 0xae, 0xcb, 0x1c, 0xf2, 0x6e, 0xa1,
- 0xf4, 0x4b, 0x4c, 0xf3, 0xde, 0x5a, 0x93, 0xf9, 0xb3, 0x6d, 0x95, 0x9d,
- 0x7e, 0x91, 0xaf, 0x5d, 0x36, 0xeb, 0xaa, 0x6b, 0xdd, 0x36, 0xa5, 0x8e,
- 0xd6, 0x51, 0x89, 0x57, 0x69, 0xbf, 0xaf, 0x4e, 0x4a, 0xcc, 0x53, 0x71,
- 0x94, 0x7e, 0x3a, 0x56, 0xe7, 0xeb, 0xbc, 0xca, 0x5c, 0xf2, 0x43, 0x72,
- 0xfc, 0x37, 0x35, 0x6f, 0xfb, 0x19, 0xa9, 0x3b, 0x86, 0x1c, 0x38, 0x17,
- 0xbc, 0x61, 0xd5, 0x82, 0x63, 0x87, 0x54, 0x0c, 0x27, 0x32, 0xfe, 0xfe,
- 0x1a, 0xfd, 0xf8, 0xd6, 0xd9, 0x05, 0x1d, 0x3d, 0x43, 0xe2, 0x1f, 0x0d,
- 0x96, 0x1f, 0xdd, 0xaa, 0x15, 0x09, 0x5e, 0x8b, 0x5f, 0x6c, 0x90, 0xde,
- 0x9d, 0x91, 0x02, 0xb9, 0xcc, 0xe0, 0x6a, 0x72, 0x60, 0x89, 0xb1, 0x01,
- 0xe6, 0xbb, 0x0e, 0xfa, 0xcf, 0x19, 0xe6, 0x1e, 0x94, 0x2d, 0x6c, 0x9a,
- 0xef, 0x32, 0x17, 0x1b, 0x41, 0xbd, 0x7a, 0x0a, 0xeb, 0xc8, 0x63, 0xc9,
- 0x71, 0x26, 0x9b, 0xb1, 0xc7, 0xca, 0xa5, 0x7c, 0xea, 0xc3, 0xca, 0x52,
- 0xae, 0xbf, 0x19, 0xdd, 0x63, 0x0b, 0x70, 0x80, 0xeb, 0x7a, 0x44, 0xff,
- 0x2b, 0x94, 0x0f, 0x75, 0x77, 0x96, 0x53, 0x1f, 0x9f, 0x86, 0x8c, 0x0e,
- 0x62, 0xfa, 0x96, 0x53, 0x4a, 0xfd, 0xfa, 0x98, 0xf2, 0x4d, 0xee, 0x87,
- 0xd4, 0x47, 0x3c, 0xcc, 0xd3, 0x1f, 0x61, 0x3c, 0xfb, 0x33, 0xec, 0x56,
- 0x95, 0x26, 0x5b, 0x58, 0x38, 0x22, 0xfc, 0xaa, 0x75, 0x76, 0xf0, 0xbf,
- 0x40, 0x9f, 0xdb, 0xc0, 0x6b, 0x12, 0xd7, 0xe5, 0x5e, 0x39, 0x37, 0xde,
- 0x89, 0x93, 0x69, 0xda, 0x75, 0xb4, 0x0f, 0xa7, 0xd2, 0xf2, 0x4c, 0xe1,
- 0x58, 0x01, 0xc4, 0x86, 0xec, 0x98, 0xd0, 0x7d, 0x91, 0x52, 0xea, 0xa5,
- 0x30, 0xe4, 0x8d, 0xac, 0x53, 0x02, 0xe4, 0x72, 0x69, 0x9c, 0xdb, 0xeb,
- 0x6d, 0xaf, 0x63, 0xde, 0x18, 0x9d, 0x84, 0xfa, 0xdc, 0xf2, 0x34, 0xce,
- 0x8e, 0x3e, 0x0e, 0x4f, 0xb5, 0xd7, 0xb3, 0x5a, 0x69, 0xc1, 0x8e, 0xc9,
- 0x7f, 0xaf, 0xc6, 0xe4, 0xe1, 0xb3, 0x5b, 0x60, 0x50, 0xf7, 0xbb, 0xf0,
- 0xad, 0xf9, 0xe2, 0xf3, 0xbd, 0x93, 0xc5, 0x58, 0xc4, 0x78, 0xf4, 0xb2,
- 0x15, 0x67, 0x33, 0x7e, 0x54, 0xa3, 0x7d, 0x64, 0x3e, 0x95, 0x8d, 0xe1,
- 0x7f, 0x58, 0x5f, 0x3f, 0x34, 0x23, 0xaa, 0xe8, 0x4b, 0xc6, 0xd5, 0xa0,
- 0x80, 0xf3, 0xec, 0xce, 0xc6, 0xeb, 0x32, 0xed, 0x9f, 0xcc, 0xc7, 0xad,
- 0x39, 0x56, 0xce, 0x97, 0x44, 0x61, 0xa7, 0x95, 0xe7, 0xcb, 0xba, 0x75,
- 0x7c, 0x16, 0x95, 0x5a, 0x87, 0x8a, 0x53, 0xba, 0xe0, 0x48, 0x0b, 0x7d,
- 0xd5, 0x89, 0x2d, 0x41, 0xba, 0xa3, 0x55, 0xf7, 0x9f, 0xc6, 0x9e, 0xe4,
- 0xbf, 0x9a, 0xcf, 0xd3, 0x8e, 0xd6, 0x90, 0xc3, 0x78, 0x88, 0x03, 0x1b,
- 0x43, 0x8f, 0x90, 0x87, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2,
- 0x91, 0xfe, 0x1f, 0x5a, 0x82, 0x29, 0xeb, 0xfe, 0x4f, 0xe7, 0x65, 0x6a,
- 0x8b, 0x67, 0xe6, 0x67, 0x72, 0x43, 0xd1, 0xff, 0x7f, 0x44, 0x7f, 0xaf,
- 0x99, 0x9e, 0x72, 0xd1, 0x9f, 0x03, 0x6e, 0xc6, 0xad, 0x03, 0xbc, 0xe7,
- 0xc2, 0x5e, 0x07, 0x06, 0xb5, 0x16, 0x0c, 0x4e, 0xc2, 0xf3, 0x29, 0xef,
- 0xf9, 0xf9, 0x68, 0xc7, 0xfc, 0x0c, 0x57, 0x78, 0x1b, 0xdd, 0xd1, 0x17,
- 0xcc, 0x55, 0xe5, 0xb2, 0x5e, 0x39, 0xaf, 0xd3, 0xca, 0xfb, 0x73, 0x75,
- 0xbe, 0xcd, 0xe6, 0x13, 0x56, 0x9c, 0x78, 0x71, 0xbe, 0xf4, 0xd7, 0x5e,
- 0x4f, 0x98, 0xb8, 0xa2, 0xf7, 0x58, 0xb9, 0xb9, 0x60, 0x43, 0x6f, 0x42,
- 0xf6, 0x56, 0x64, 0xfb, 0x66, 0x56, 0x1f, 0x13, 0x55, 0xb7, 0xcb, 0xbd,
- 0x2a, 0x6b, 0xcb, 0xd2, 0xdf, 0xce, 0xf1, 0x7e, 0xb1, 0x65, 0xb1, 0x63,
- 0xeb, 0xbd, 0x96, 0xa4, 0xbc, 0xd3, 0xb9, 0x41, 0xfd, 0x1d, 0x9f, 0x21,
- 0x75, 0x96, 0x16, 0xce, 0x61, 0x9a, 0x9b, 0xf5, 0x7a, 0xcf, 0x29, 0xfc,
- 0x31, 0x6d, 0x5b, 0xc7, 0xae, 0x21, 0xa9, 0xc3, 0x7a, 0x14, 0xc7, 0xbe,
- 0x75, 0xb8, 0xc2, 0xf8, 0xbf, 0xc7, 0xb2, 0x43, 0xc1, 0x15, 0x91, 0x43,
- 0xb0, 0xa5, 0x8d, 0x71, 0x5c, 0x6a, 0xdd, 0x46, 0xa4, 0x26, 0xdc, 0xa9,
- 0x7c, 0x58, 0xd7, 0x89, 0x63, 0x21, 0xc3, 0x2c, 0xd5, 0xfc, 0xeb, 0x6b,
- 0x6c, 0x28, 0x98, 0x6c, 0xc8, 0xc7, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2,
- 0x69, 0xaf, 0x31, 0xc7, 0xae, 0xba, 0xbe, 0x97, 0xce, 0x62, 0xa5, 0xad,
- 0x7e, 0xbe, 0xe4, 0x50, 0x49, 0x0b, 0x47, 0xbe, 0x8a, 0x07, 0xad, 0xbd,
- 0x55, 0x19, 0x43, 0xa5, 0x0e, 0x7c, 0x2c, 0x74, 0x2d, 0x2a, 0x98, 0x62,
- 0x36, 0x35, 0x87, 0xea, 0xd5, 0x5d, 0xb8, 0x87, 0xd8, 0xd5, 0x84, 0x73,
- 0xba, 0xf4, 0x3f, 0x8c, 0x6f, 0x3a, 0xac, 0xb3, 0x34, 0x47, 0x43, 0x3b,
- 0xa2, 0x2b, 0x71, 0x60, 0xc8, 0x50, 0x9c, 0x61, 0x6f, 0x24, 0x46, 0x2e,
- 0xc4, 0x1c, 0xdd, 0xaa, 0x03, 0x4a, 0x8d, 0x61, 0xb8, 0xa1, 0x13, 0xbb,
- 0xf4, 0x7c, 0xf4, 0xea, 0x91, 0x82, 0x9e, 0xe5, 0x5d, 0x38, 0xa8, 0x17,
- 0x1b, 0x8b, 0xc2, 0x06, 0x31, 0x5d, 0xdb, 0x92, 0x84, 0xbf, 0xe5, 0x32,
- 0x39, 0xc7, 0x49, 0x78, 0x3b, 0x9a, 0xec, 0xc4, 0xdc, 0x15, 0x0e, 0x57,
- 0x6c, 0xbc, 0x11, 0x89, 0xc9, 0x4a, 0xd7, 0xee, 0xf1, 0x20, 0xe2, 0x93,
- 0xdc, 0x6f, 0xe6, 0xba, 0x8e, 0xf1, 0x95, 0xe4, 0xa0, 0xa2, 0x47, 0x3b,
- 0x6d, 0xb1, 0x0e, 0xcf, 0xb5, 0x5e, 0x32, 0x9f, 0xf1, 0x0b, 0x7e, 0x2e,
- 0xc0, 0x56, 0xd5, 0x67, 0x71, 0xca, 0x88, 0xed, 0x0f, 0xf9, 0x87, 0x9d,
- 0x36, 0xf7, 0x7d, 0xd3, 0xf3, 0x75, 0xd1, 0x9b, 0x63, 0x01, 0x0a, 0x1f,
- 0x21, 0x7e, 0xca, 0xbf, 0x45, 0x77, 0xa2, 0x43, 0x13, 0x9b, 0x74, 0xa9,
- 0xf1, 0x35, 0xd0, 0x67, 0xdc, 0x78, 0x47, 0xbd, 0xb5, 0x0f, 0xcf, 0xea,
- 0x3e, 0x7d, 0x0c, 0x52, 0xdb, 0x5b, 0xc1, 0x71, 0x52, 0x83, 0x69, 0xc4,
- 0x4b, 0xd9, 0x9c, 0xc3, 0x63, 0x2b, 0x22, 0xee, 0xe6, 0xe2, 0x88, 0x5c,
- 0xf7, 0x26, 0x23, 0xb4, 0xd3, 0x6d, 0xc1, 0x19, 0x33, 0x52, 0x6e, 0x74,
- 0xca, 0xf9, 0x15, 0x77, 0x78, 0xba, 0xd3, 0x5d, 0xe7, 0xed, 0x98, 0x51,
- 0x80, 0x73, 0x31, 0xc6, 0x61, 0xeb, 0x7f, 0xb1, 0x28, 0x73, 0x3b, 0x31,
- 0x12, 0x5c, 0x88, 0xf6, 0x36, 0x79, 0x56, 0x33, 0xfa, 0xf6, 0x9b, 0x66,
- 0x71, 0xc8, 0xa7, 0xa6, 0xe1, 0xc4, 0xc3, 0x41, 0x3b, 0x2e, 0xa9, 0x26,
- 0x1c, 0xa1, 0x7f, 0x35, 0xc7, 0x19, 0x1f, 0x47, 0xe9, 0x27, 0xbb, 0x69,
- 0x63, 0xf2, 0xbe, 0x8f, 0x9f, 0x7e, 0x12, 0xa7, 0x9f, 0x9c, 0x0b, 0xdd,
- 0x97, 0x7d, 0x5f, 0x50, 0x23, 0xaf, 0x98, 0x46, 0xd3, 0x90, 0x8a, 0x4f,
- 0x57, 0x4c, 0x23, 0x34, 0x92, 0x93, 0x5d, 0xfc, 0x32, 0x27, 0xbf, 0xf4,
- 0x11, 0x45, 0x76, 0x91, 0x51, 0xd6, 0x22, 0xff, 0xce, 0x5d, 0xcb, 0xfd,
- 0x26, 0x71, 0xd6, 0x89, 0x56, 0x6b, 0x6d, 0x7f, 0x56, 0x93, 0xc1, 0x8c,
- 0xdc, 0x9a, 0x2e, 0xb9, 0x6f, 0xff, 0x7e, 0xe2, 0x8e, 0xeb, 0x2b, 0xee,
- 0xb8, 0xbe, 0x71, 0xde, 0xed, 0xdf, 0x73, 0x3e, 0x71, 0x4b, 0xaf, 0x1d,
- 0xba, 0x6f, 0xea, 0x18, 0xd7, 0x3a, 0x67, 0xc9, 0x98, 0x79, 0xa9, 0x4c,
- 0x64, 0x91, 0x3c, 0x36, 0x23, 0xeb, 0xaa, 0xf1, 0xd9, 0xb2, 0xbe, 0x95,
- 0xed, 0x19, 0x58, 0x67, 0x7c, 0xe9, 0x37, 0x1a, 0x7e, 0x78, 0xdb, 0xb9,
- 0x43, 0xb1, 0xb5, 0x80, 0xd2, 0x17, 0x93, 0xf7, 0x33, 0x0b, 0xad, 0x77,
- 0xac, 0x55, 0xbf, 0x81, 0x22, 0xbf, 0xb6, 0x65, 0x8e, 0xad, 0x0b, 0xce,
- 0xa5, 0x5a, 0xc7, 0xb7, 0x94, 0x24, 0xe2, 0xe3, 0xde, 0xc0, 0x18, 0x75,
- 0x15, 0x1b, 0xbf, 0xce, 0x5c, 0xbb, 0x0b, 0xcf, 0x85, 0x1c, 0x46, 0x61,
- 0x58, 0xce, 0x82, 0xae, 0xc2, 0xae, 0x91, 0xbf, 0xc2, 0xe6, 0xa4, 0x70,
- 0xfc, 0x05, 0xe8, 0x99, 0xb4, 0xe1, 0x04, 0xed, 0xbb, 0x8f, 0xcf, 0x21,
- 0xfe, 0xb9, 0x53, 0x90, 0xf7, 0x6b, 0x1a, 0x98, 0x37, 0xeb, 0xd6, 0x67,
- 0xc7, 0xc8, 0xcf, 0xb0, 0x39, 0x6a, 0xe2, 0x53, 0x9d, 0xb1, 0x47, 0x13,
- 0xf9, 0x1c, 0xd0, 0xca, 0x5b, 0x2d, 0x2c, 0x7d, 0x32, 0xce, 0xfd, 0xac,
- 0x16, 0x5f, 0x5d, 0x49, 0x9f, 0x55, 0xf0, 0x99, 0xf4, 0x27, 0xcb, 0x29,
- 0x33, 0xb9, 0xe1, 0xf1, 0xe8, 0x76, 0x8c, 0x5a, 0xfd, 0x67, 0xad, 0xaf,
- 0xc6, 0x1e, 0x79, 0xb1, 0x8c, 0x3c, 0x3b, 0xa1, 0xfb, 0xdb, 0x2f, 0x28,
- 0xf0, 0x94, 0x84, 0xfd, 0x8c, 0x33, 0x5f, 0xe2, 0x37, 0xba, 0xd4, 0xd8,
- 0x74, 0xd7, 0x5a, 0xda, 0xfb, 0xbe, 0x91, 0x80, 0x55, 0x33, 0xf8, 0xe1,
- 0x5d, 0x6b, 0x1a, 0x99, 0x77, 0xab, 0x33, 0xf5, 0xc7, 0x9f, 0xe1, 0x48,
- 0xda, 0x85, 0xa7, 0xe2, 0x1e, 0x65, 0xd1, 0x3e, 0x15, 0x0f, 0xc5, 0xbd,
- 0x53, 0x4d, 0x76, 0xf2, 0x8f, 0x65, 0x73, 0x38, 0x9f, 0x82, 0x1f, 0x2c,
- 0x95, 0x58, 0xf0, 0x47, 0x30, 0xaa, 0x23, 0x9c, 0x13, 0xc5, 0x79, 0xcb,
- 0xbd, 0xea, 0x11, 0x9b, 0xcf, 0xfd, 0x1b, 0xec, 0x80, 0x7d, 0xfc, 0x11,
- 0x74, 0x53, 0xfe, 0x35, 0x71, 0xe9, 0x69, 0xd5, 0x03, 0x65, 0xcd, 0xd8,
- 0x3d, 0x26, 0xbe, 0x09, 0xa3, 0x2a, 0x0c, 0x4f, 0x65, 0xd8, 0xbf, 0x10,
- 0x85, 0x5f, 0x92, 0x6b, 0x4f, 0x4b, 0xfe, 0xb9, 0xa5, 0xd4, 0x66, 0x32,
- 0x7f, 0xb9, 0x2f, 0xdb, 0xab, 0x58, 0x89, 0x1d, 0x43, 0x52, 0x87, 0x27,
- 0x6e, 0xeb, 0xcc, 0x83, 0xca, 0xb4, 0xc0, 0x46, 0x9b, 0xf4, 0x87, 0xb6,
- 0xc3, 0x17, 0xdb, 0x8e, 0x40, 0x4c, 0x7c, 0x56, 0x53, 0x3b, 0x10, 0x39,
- 0x2b, 0xb5, 0xbf, 0x45, 0x21, 0x3f, 0xe5, 0xf2, 0xf7, 0x55, 0xda, 0x75,
- 0xd7, 0x6b, 0x13, 0x2a, 0xa6, 0xd4, 0x4c, 0x1e, 0x39, 0x96, 0xd4, 0xd6,
- 0xe7, 0xdb, 0xe4, 0x0c, 0xc5, 0x55, 0xeb, 0x3d, 0xeb, 0x88, 0xed, 0x9f,
- 0x89, 0x47, 0xcd, 0x18, 0xd8, 0xff, 0x3e, 0x63, 0x90, 0x3c, 0xe3, 0x77,
- 0xcc, 0xaf, 0x9d, 0x58, 0xdd, 0xe6, 0xc1, 0x83, 0x71, 0xa9, 0x9d, 0xae,
- 0xaf, 0xca, 0x9c, 0x01, 0x91, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xd9, 0xea,
- 0x2f, 0xcc, 0x4a, 0x2b, 0x2f, 0xfd, 0xbf, 0x19, 0x9b, 0x49, 0xe4, 0x2d,
- 0x14, 0x1f, 0xef, 0x9d, 0x64, 0x02, 0x69, 0xd9, 0x5d, 0x15, 0xbf, 0xcb,
- 0x5c, 0xda, 0x81, 0xed, 0xd8, 0x56, 0x25, 0x7c, 0xe6, 0xc9, 0x89, 0xd9,
- 0xf7, 0xe7, 0xea, 0x32, 0x95, 0x59, 0x4e, 0x95, 0xb3, 0x37, 0xe9, 0x05,
- 0x46, 0x94, 0x27, 0xa2, 0x2d, 0xca, 0xda, 0xa8, 0xf4, 0x03, 0x6d, 0xd1,
- 0x22, 0x72, 0x18, 0xdf, 0x52, 0x13, 0xdf, 0x0e, 0x1d, 0x57, 0x76, 0x5a,
- 0xe7, 0x66, 0xe5, 0xac, 0x2b, 0x50, 0x3e, 0xd1, 0xac, 0xec, 0x8a, 0x7e,
- 0x62, 0x6e, 0xb4, 0x7a, 0xf0, 0x79, 0xd6, 0x79, 0x9c, 0xfc, 0x09, 0x17,
- 0xca, 0x8e, 0xc8, 0xf9, 0x41, 0x0d, 0x15, 0x13, 0x8f, 0x91, 0xb7, 0x0a,
- 0xd7, 0x31, 0x5a, 0x1c, 0xd6, 0xb9, 0xb6, 0xe6, 0x97, 0x72, 0xe7, 0xda,
- 0x1c, 0x31, 0x79, 0x1b, 0xd9, 0xfa, 0x8f, 0xb9, 0xd2, 0x51, 0xe6, 0x4a,
- 0x66, 0xd3, 0xb7, 0x43, 0xc6, 0xee, 0x0a, 0x78, 0x03, 0xe5, 0x36, 0xc3,
- 0x94, 0x7a, 0xce, 0x6b, 0x24, 0x8c, 0xeb, 0x6a, 0x0d, 0x3c, 0x5c, 0x2b,
- 0xef, 0x1f, 0xca, 0xbb, 0xc7, 0x5d, 0x38, 0x1a, 0xea, 0xc2, 0x2f, 0xf5,
- 0x2e, 0xec, 0xd1, 0xe5, 0x4c, 0x43, 0x31, 0x65, 0xd5, 0xa6, 0xa2, 0xd0,
- 0xf4, 0xb4, 0xa2, 0x9d, 0xb9, 0x0e, 0xef, 0x01, 0x9f, 0xe2, 0x35, 0x56,
- 0x29, 0x1a, 0xae, 0x8e, 0x7b, 0x67, 0x4a, 0xe9, 0x03, 0x37, 0xc6, 0x03,
- 0x98, 0x21, 0xae, 0x26, 0x27, 0xe5, 0xfc, 0xc9, 0x02, 0x0c, 0x4d, 0x7e,
- 0x4d, 0xb8, 0x81, 0x41, 0x4c, 0xb2, 0xce, 0x48, 0x3e, 0x2f, 0xbd, 0x4e,
- 0x67, 0x30, 0xcb, 0x61, 0x0c, 0x65, 0x53, 0x43, 0x09, 0x6e, 0x30, 0x3a,
- 0xfd, 0x6d, 0xba, 0x93, 0xf9, 0x1c, 0xde, 0xa8, 0x81, 0xfd, 0x3b, 0x6e,
- 0xd4, 0x25, 0xe7, 0xe0, 0x44, 0x5d, 0x39, 0xf2, 0x70, 0x6c, 0xf4, 0x45,
- 0x72, 0xfc, 0xee, 0xf6, 0x52, 0xe6, 0xa7, 0x13, 0xa3, 0x4e, 0xa4, 0x52,
- 0x52, 0x73, 0xb0, 0x7a, 0x96, 0xd3, 0x0e, 0xfa, 0x52, 0x7f, 0x02, 0x75,
- 0x35, 0x61, 0x7f, 0xb2, 0xc6, 0xae, 0x72, 0x8e, 0x4a, 0xa4, 0xd2, 0x1a,
- 0x3f, 0x01, 0x7e, 0x82, 0xfc, 0x34, 0xe2, 0xdb, 0xf4, 0xd9, 0x32, 0xe2,
- 0xed, 0xf7, 0xd3, 0x25, 0xf8, 0x24, 0xa9, 0x05, 0x74, 0xda, 0xc1, 0x28,
- 0x73, 0x04, 0xc3, 0xd2, 0x53, 0x09, 0xae, 0xd3, 0x4f, 0x5f, 0x0e, 0x95,
- 0xc0, 0x4c, 0xdd, 0x2d, 0x27, 0x94, 0xdc, 0x16, 0x6a, 0x61, 0x58, 0xf8,
- 0xe2, 0x31, 0x25, 0x95, 0x3d, 0xf3, 0xf5, 0xea, 0x38, 0xda, 0xcb, 0xc3,
- 0xae, 0xe0, 0xea, 0xb8, 0xfd, 0x13, 0x79, 0x9f, 0x75, 0x43, 0x83, 0xbc,
- 0xf3, 0xe4, 0x0a, 0x3e, 0x3d, 0xe1, 0x0a, 0xae, 0x8f, 0x1f, 0x53, 0x28,
- 0xcf, 0x81, 0x1a, 0xbb, 0x2b, 0xf8, 0xe4, 0xc4, 0xb1, 0x85, 0x99, 0xbc,
- 0x0f, 0xca, 0xd3, 0xb5, 0x06, 0x6d, 0x8c, 0x79, 0xef, 0x32, 0xe9, 0xcb,
- 0x68, 0x9d, 0x57, 0xec, 0x85, 0x46, 0x4d, 0xd8, 0xeb, 0xa9, 0xb1, 0xcb,
- 0xd9, 0x90, 0x69, 0xc4, 0x93, 0xf2, 0xae, 0x97, 0xd8, 0xfe, 0x3f, 0x99,
- 0x46, 0x99, 0x9c, 0xf5, 0xe8, 0x44, 0x5c, 0x2b, 0x67, 0xee, 0x24, 0x67,
- 0xcd, 0x8f, 0x86, 0xa2, 0xb1, 0x62, 0x79, 0x77, 0xb6, 0xe9, 0x7b, 0x21,
- 0x6f, 0xcb, 0xa0, 0x62, 0x3c, 0x5e, 0x04, 0xd9, 0xd7, 0x2e, 0xe2, 0xb7,
- 0xa6, 0x3a, 0x15, 0x6f, 0x63, 0x0f, 0x02, 0x38, 0x91, 0x16, 0x5d, 0x07,
- 0xe5, 0x8c, 0xba, 0xa5, 0xeb, 0x5b, 0x67, 0xae, 0x33, 0xb6, 0xb3, 0x2d,
- 0xea, 0xe0, 0x5f, 0xb1, 0x17, 0x1b, 0x63, 0x0a, 0xe3, 0x8a, 0x65, 0x33,
- 0xb7, 0x64, 0x5c, 0x57, 0xdb, 0x85, 0xc9, 0x50, 0xa1, 0xbc, 0x77, 0xcd,
- 0xb8, 0xee, 0x0d, 0x7c, 0xa2, 0x58, 0xf1, 0xdc, 0x28, 0x62, 0x9c, 0x7d,
- 0x61, 0xfc, 0xef, 0xcc, 0xf6, 0x6a, 0xc1, 0x2b, 0x3b, 0xc7, 0x5e, 0xc7,
- 0x6b, 0xa9, 0x5b, 0xe3, 0x5a, 0x38, 0xae, 0x90, 0xe3, 0x8a, 0xc2, 0x92,
- 0x3b, 0x7a, 0xf5, 0xb5, 0x8a, 0xe6, 0x29, 0x50, 0xa4, 0x57, 0xa6, 0xe1,
- 0xbd, 0xf4, 0xe4, 0x42, 0xc9, 0x79, 0x7b, 0x27, 0xcb, 0xb1, 0x6e, 0xaf,
- 0xd9, 0xb4, 0x68, 0xa9, 0xd9, 0x94, 0x0e, 0x45, 0xcd, 0x97, 0xab, 0x64,
- 0x4f, 0xa5, 0xff, 0x27, 0x63, 0x34, 0xd5, 0xc7, 0x5c, 0xf3, 0x6b, 0x7a,
- 0x6f, 0xf6, 0xcc, 0x2e, 0xed, 0x9a, 0xcf, 0x38, 0x9d, 0x12, 0x3b, 0xd9,
- 0xd1, 0xee, 0x62, 0x3e, 0x2a, 0xef, 0x87, 0x1e, 0xe5, 0xfe, 0x1f, 0x49,
- 0xfd, 0xcd, 0x42, 0x39, 0xc3, 0x2e, 0x67, 0x08, 0x80, 0xff, 0x0f, 0x1d,
- 0xab, 0x22, 0x97, 0x70, 0x78, 0x00, 0x00, 0x00 };
+ 0xec, 0x5c, 0x7d, 0x70, 0x1c, 0xe5, 0x79, 0xff, 0xbd, 0x7b, 0x7b, 0xd2,
+ 0x4a, 0x3a, 0x9d, 0x56, 0xa7, 0x93, 0x7c, 0x22, 0x04, 0xef, 0xa2, 0x3d,
+ 0xf9, 0xb0, 0x0c, 0xec, 0x9d, 0x4f, 0xb6, 0xa0, 0xdb, 0xb2, 0x83, 0x0d,
+ 0x11, 0x21, 0x13, 0x84, 0x4d, 0x52, 0x33, 0x49, 0x27, 0x37, 0xc6, 0x18,
+ 0x81, 0x4d, 0x70, 0x0d, 0x6d, 0x55, 0x86, 0x19, 0x6f, 0x2c, 0x7f, 0x01,
+ 0x27, 0x9d, 0x62, 0x64, 0x63, 0xd2, 0x0e, 0x68, 0x6c, 0x59, 0x08, 0x7c,
+ 0xd2, 0x61, 0x20, 0xad, 0xe8, 0x84, 0xfa, 0x26, 0xd8, 0xe0, 0x94, 0xcf,
+ 0x21, 0x0c, 0xc3, 0x1f, 0xcd, 0xa0, 0x62, 0x3e, 0xcc, 0x94, 0xa1, 0x26,
+ 0x38, 0xa9, 0xdd, 0xb8, 0x7e, 0xfb, 0x3c, 0x7b, 0x3a, 0x9b, 0x90, 0x26,
+ 0x9d, 0xfc, 0xd1, 0xff, 0xf6, 0x99, 0xb9, 0xb9, 0xbd, 0x77, 0xdf, 0xf7,
+ 0xf9, 0xfe, 0x7c, 0x3d, 0xf2, 0x5f, 0x47, 0x50, 0x8f, 0x39, 0x68, 0xa4,
+ 0x4f, 0x76, 0xc3, 0xc0, 0xc6, 0xf4, 0x65, 0x4b, 0x2e, 0xa3, 0xc7, 0xee,
+ 0x50, 0x53, 0x8d, 0xca, 0xeb, 0x02, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01,
+ 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10,
+ 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00,
+ 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
+ 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40,
+ 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0xfc, 0x7f, 0x40, 0x08, 0xd0,
+ 0xf9, 0xbb, 0x71, 0xee, 0x03, 0x4d, 0x71, 0xdc, 0x7b, 0xaf, 0xb6, 0xa0,
+ 0x85, 0x9c, 0x99, 0x7b, 0x6f, 0xb1, 0x00, 0xb7, 0xd8, 0x65, 0x2c, 0xc3,
+ 0x7f, 0x4b, 0x2f, 0xae, 0x82, 0xd7, 0xbf, 0xea, 0x9c, 0x79, 0xec, 0xf9,
+ 0xa5, 0xe6, 0x89, 0xb1, 0x10, 0x34, 0xdd, 0x79, 0x27, 0xad, 0x77, 0x42,
+ 0xbb, 0x90, 0xce, 0xfc, 0xfd, 0x82, 0x95, 0x31, 0x44, 0xab, 0xb8, 0xe0,
+ 0x29, 0x8e, 0x94, 0xfb, 0x6d, 0x89, 0x17, 0x6d, 0x4f, 0x2c, 0xcb, 0xc2,
+ 0xd3, 0x9c, 0x19, 0x51, 0x37, 0x74, 0x56, 0x1a, 0xe1, 0x0a, 0xe5, 0x35,
+ 0x45, 0x05, 0xaa, 0xa5, 0xe1, 0xd6, 0xf1, 0x7a, 0xac, 0x1d, 0x6b, 0xc0,
+ 0x9a, 0xb1, 0x04, 0x6e, 0x2b, 0x42, 0x0f, 0x39, 0x1a, 0x66, 0x43, 0x33,
+ 0x22, 0x34, 0x85, 0x5c, 0xd8, 0x39, 0x75, 0xc3, 0xde, 0xfc, 0x59, 0xe9,
+ 0xfa, 0x7f, 0x63, 0x52, 0xbe, 0x61, 0xdc, 0x7f, 0x0f, 0x45, 0x75, 0x0e,
+ 0xd3, 0x33, 0xef, 0x3b, 0x75, 0xc3, 0xbe, 0xe2, 0x71, 0xf9, 0xfc, 0x82,
+ 0x38, 0x0e, 0x95, 0x74, 0x3c, 0x55, 0xda, 0x4f, 0x3c, 0x98, 0x9e, 0x07,
+ 0xcd, 0x53, 0x1d, 0x0f, 0x5b, 0xb3, 0x61, 0x4c, 0x8c, 0x9c, 0x95, 0x21,
+ 0xcb, 0x34, 0xa0, 0x58, 0xfa, 0x0b, 0xa0, 0x7d, 0x05, 0xda, 0x57, 0x08,
+ 0x63, 0xef, 0x58, 0x29, 0x86, 0xfa, 0x04, 0x9e, 0x5f, 0xc0, 0xe7, 0xf9,
+ 0x2c, 0xe3, 0x78, 0x3b, 0x5a, 0x3d, 0x5f, 0x43, 0xe7, 0x8f, 0x64, 0x81,
+ 0xf1, 0x91, 0x3e, 0x3a, 0x2a, 0x31, 0x68, 0xd7, 0x62, 0xb5, 0x0e, 0xaf,
+ 0xce, 0x61, 0x5c, 0x55, 0x3c, 0x9e, 0x30, 0xa6, 0x8e, 0x34, 0x55, 0xf0,
+ 0x40, 0x68, 0x16, 0xbc, 0xda, 0x2f, 0xbd, 0x3f, 0x5e, 0xac, 0xbe, 0xdf,
+ 0x41, 0x74, 0x34, 0xd2, 0xc3, 0x06, 0xfc, 0x73, 0xa9, 0x1f, 0xff, 0x50,
+ 0xca, 0xe1, 0xd9, 0x52, 0x1f, 0xd1, 0xbd, 0x87, 0xe8, 0xae, 0xc7, 0x3f,
+ 0x96, 0xd6, 0xe0, 0xc7, 0xa5, 0xef, 0xe2, 0x99, 0xd2, 0x2a, 0x3c, 0x5d,
+ 0xba, 0x09, 0x07, 0x4b, 0x1e, 0xc2, 0xdd, 0x8c, 0x2f, 0x25, 0x3e, 0xcb,
+ 0xd7, 0x11, 0x1f, 0x5b, 0x30, 0x5b, 0x64, 0x79, 0x24, 0x46, 0x6c, 0x73,
+ 0x0c, 0x58, 0x90, 0xa8, 0x81, 0xc0, 0x6a, 0xdb, 0x7c, 0x0a, 0xb8, 0x0d,
+ 0x6e, 0xdc, 0x3c, 0xc1, 0x5a, 0x7a, 0x62, 0xc4, 0x40, 0x98, 0xf8, 0xb5,
+ 0xd2, 0x6d, 0xd8, 0xaa, 0xf7, 0xa1, 0xde, 0x1a, 0xc2, 0x03, 0xbe, 0x8d,
+ 0xa1, 0x45, 0x9c, 0x7f, 0x45, 0x7e, 0x48, 0xe0, 0xc1, 0x24, 0x34, 0x41,
+ 0xcf, 0x5d, 0xc5, 0xbf, 0x6b, 0xa9, 0xd8, 0x8c, 0x78, 0x28, 0x10, 0x5f,
+ 0x05, 0xe2, 0xa3, 0x40, 0xbc, 0x15, 0x88, 0x97, 0x02, 0xf1, 0x57, 0x20,
+ 0x7e, 0x0a, 0xc4, 0x4f, 0x81, 0xf8, 0x29, 0x10, 0xaf, 0x05, 0xd6, 0xf9,
+ 0x00, 0xc9, 0x52, 0xb1, 0x71, 0xab, 0x63, 0x63, 0xac, 0xd4, 0x26, 0xf6,
+ 0xee, 0x56, 0xc5, 0x73, 0xc3, 0x06, 0xe6, 0x3b, 0x88, 0x3c, 0xbd, 0xc4,
+ 0x2a, 0x5f, 0x15, 0xea, 0x9a, 0x49, 0xc0, 0x4d, 0xcf, 0x83, 0x8d, 0x89,
+ 0x92, 0x2a, 0xa6, 0x87, 0xa5, 0x5c, 0x69, 0xbb, 0x68, 0x72, 0xcc, 0x9e,
+ 0x8d, 0x8a, 0xd5, 0xff, 0xba, 0x68, 0xc4, 0x2f, 0x47, 0x7a, 0x31, 0xd6,
+ 0xec, 0xe2, 0x70, 0xd6, 0xc0, 0xb2, 0x8c, 0x82, 0x5c, 0xdc, 0xc3, 0xb6,
+ 0xac, 0x69, 0x7b, 0x18, 0x45, 0x39, 0xce, 0xe7, 0x34, 0xd2, 0xb5, 0x87,
+ 0x64, 0xb7, 0x86, 0xc9, 0x11, 0x17, 0x35, 0xe9, 0x1a, 0x94, 0xfb, 0x58,
+ 0x7f, 0x2a, 0xc9, 0xb4, 0x0f, 0xf5, 0xb1, 0x18, 0x1a, 0xac, 0x4b, 0xd0,
+ 0x10, 0xe3, 0x35, 0x88, 0x56, 0xd2, 0xd5, 0x3c, 0xe7, 0x02, 0xf1, 0xf9,
+ 0xee, 0x28, 0x3e, 0x1d, 0xd5, 0x50, 0xda, 0xa9, 0xe2, 0x1b, 0x19, 0x29,
+ 0xff, 0x2a, 0xa3, 0xf6, 0x7f, 0x2a, 0x1c, 0x4c, 0x95, 0x54, 0x7c, 0x9e,
+ 0x4f, 0xc3, 0x6b, 0xd6, 0xf0, 0x9f, 0x79, 0x0f, 0x21, 0xc2, 0x3b, 0x40,
+ 0x78, 0x6b, 0x17, 0xa7, 0x30, 0x1b, 0x67, 0x71, 0xfa, 0xb0, 0x31, 0xdf,
+ 0xb1, 0x63, 0xa3, 0x52, 0x03, 0xa3, 0x06, 0x64, 0xff, 0x2c, 0x36, 0xe5,
+ 0x3b, 0x8e, 0x6e, 0x52, 0xb6, 0xe0, 0xe2, 0x5a, 0x0d, 0x9b, 0x87, 0x79,
+ 0x6d, 0x39, 0xca, 0x45, 0x41, 0xfe, 0xf0, 0xc7, 0xea, 0x6b, 0x26, 0x42,
+ 0x7e, 0x65, 0xfc, 0xf1, 0x7a, 0x4e, 0x34, 0xa2, 0xde, 0x34, 0xca, 0x58,
+ 0x1f, 0xe7, 0xf3, 0x39, 0xe5, 0x5d, 0xe9, 0xc6, 0x99, 0x0f, 0xcd, 0x0b,
+ 0x91, 0x6e, 0x6e, 0xc9, 0x66, 0xb1, 0x26, 0xdf, 0xa1, 0xaf, 0x51, 0x48,
+ 0xdb, 0x6a, 0xc5, 0xc6, 0x71, 0x07, 0xe9, 0xd1, 0x61, 0x81, 0x91, 0x4e,
+ 0xb6, 0x31, 0xd2, 0x76, 0xd1, 0x8f, 0x09, 0xc3, 0x50, 0x2a, 0x31, 0xf1,
+ 0x58, 0x36, 0x89, 0xb3, 0x0f, 0xf1, 0x6f, 0x15, 0x3f, 0x5b, 0x9a, 0xc4,
+ 0xc7, 0xfb, 0x4a, 0x73, 0x71, 0xfb, 0x68, 0xa4, 0xb2, 0xef, 0x1a, 0xa2,
+ 0xc9, 0x32, 0x32, 0xae, 0xc9, 0x7b, 0x47, 0x3b, 0x6b, 0xe9, 0x77, 0xc5,
+ 0xd6, 0xfd, 0xf9, 0x0e, 0xbb, 0x5f, 0xd1, 0x50, 0x4e, 0x44, 0x48, 0xf7,
+ 0xd0, 0xea, 0x08, 0xff, 0x25, 0x43, 0x67, 0xb0, 0x22, 0x63, 0x4e, 0xf2,
+ 0xdf, 0x80, 0x25, 0x93, 0x15, 0x9a, 0xc9, 0xa2, 0x8d, 0x03, 0x25, 0x1b,
+ 0x77, 0xe4, 0x3b, 0xdc, 0x95, 0x62, 0x16, 0x68, 0x5f, 0x98, 0x9b, 0x54,
+ 0x7e, 0x21, 0xbd, 0x56, 0xa6, 0xb3, 0x10, 0x93, 0xb1, 0x8e, 0x81, 0x49,
+ 0xc5, 0xdc, 0xd3, 0xaf, 0x48, 0xf9, 0xab, 0xb4, 0x82, 0xaf, 0x65, 0xb2,
+ 0x98, 0xd5, 0x75, 0xdc, 0x9c, 0xd1, 0xbc, 0x16, 0xe2, 0x71, 0xc3, 0x12,
+ 0x0d, 0x17, 0xed, 0x74, 0xf1, 0xf6, 0xe2, 0x9f, 0xa3, 0xbc, 0x82, 0x75,
+ 0xcf, 0x7c, 0xb1, 0x1c, 0x09, 0xc4, 0xac, 0x3a, 0xc4, 0xf6, 0x86, 0x31,
+ 0x6f, 0xe7, 0x59, 0x99, 0xb0, 0x78, 0xdd, 0x9a, 0x3c, 0xa5, 0xb0, 0x0c,
+ 0x61, 0xb4, 0xee, 0xbd, 0x82, 0x72, 0x8a, 0x99, 0x02, 0xbe, 0x16, 0xe7,
+ 0xbd, 0x35, 0x56, 0x55, 0x96, 0x08, 0x76, 0xef, 0xac, 0xc8, 0xff, 0x68,
+ 0xb6, 0x07, 0x2f, 0x15, 0xb0, 0xaf, 0x0d, 0x3f, 0xc0, 0xc8, 0x12, 0xce,
+ 0x4f, 0x8c, 0x63, 0x88, 0x64, 0xff, 0xc1, 0x89, 0x70, 0xa6, 0x6a, 0xe3,
+ 0xea, 0x39, 0x81, 0x6f, 0x5e, 0x29, 0xf0, 0x6a, 0x7a, 0x5a, 0x8e, 0xb5,
+ 0x32, 0xbf, 0x0f, 0x37, 0x56, 0xfe, 0x16, 0xae, 0xee, 0x94, 0x8b, 0x36,
+ 0xa2, 0x55, 0xdd, 0xc7, 0x38, 0x2e, 0x69, 0x25, 0xfd, 0xa5, 0x66, 0xf1,
+ 0x5f, 0x11, 0xd4, 0xb3, 0x9d, 0xef, 0x96, 0x46, 0x4b, 0x85, 0xe6, 0xfd,
+ 0x44, 0xb3, 0x63, 0x48, 0xc5, 0xe6, 0x7c, 0xc7, 0xa9, 0xf7, 0x94, 0xef,
+ 0xcb, 0xd9, 0xf9, 0x4c, 0xa7, 0xc3, 0x3e, 0xa6, 0x08, 0xfc, 0x54, 0x35,
+ 0x67, 0x72, 0x48, 0x60, 0xb2, 0x04, 0xaf, 0xdd, 0xd1, 0x29, 0xfe, 0xe3,
+ 0x94, 0x07, 0x0c, 0xd1, 0xf9, 0xb0, 0x8d, 0x85, 0x43, 0xdf, 0x85, 0xb5,
+ 0xcb, 0xc1, 0x4c, 0xc1, 0xc6, 0x54, 0x41, 0xca, 0xed, 0xb6, 0x94, 0xef,
+ 0xda, 0xe6, 0x86, 0xe3, 0x21, 0xb8, 0x97, 0x2f, 0xed, 0x4a, 0xd5, 0x86,
+ 0x54, 0xd6, 0x4d, 0xee, 0x75, 0x91, 0x5c, 0xb5, 0x5f, 0xf4, 0xe2, 0x89,
+ 0x92, 0x81, 0x62, 0x29, 0x85, 0x27, 0x4b, 0xac, 0x7f, 0x8b, 0xbe, 0x17,
+ 0x51, 0x7c, 0x66, 0x29, 0xb7, 0x30, 0xbf, 0x3a, 0xc6, 0x17, 0xd8, 0x98,
+ 0x2c, 0x28, 0x08, 0x91, 0xce, 0x73, 0x3a, 0xed, 0x2f, 0x9c, 0x25, 0xdb,
+ 0x69, 0xe8, 0xf8, 0xa1, 0x8b, 0xdb, 0xed, 0x16, 0x18, 0x37, 0x5a, 0x18,
+ 0x2f, 0x68, 0x94, 0xbb, 0x55, 0xf4, 0xe6, 0xc7, 0x31, 0xaf, 0x39, 0x4e,
+ 0xb1, 0x26, 0xb0, 0x2a, 0x13, 0x01, 0x56, 0xf2, 0xbb, 0x08, 0xda, 0xad,
+ 0x32, 0xda, 0x63, 0x8d, 0x98, 0xbf, 0xf0, 0x9f, 0x30, 0xdb, 0x12, 0x25,
+ 0x1d, 0xd7, 0x93, 0x1e, 0x04, 0x54, 0xb2, 0x53, 0x9b, 0x65, 0x11, 0x4e,
+ 0x01, 0x2b, 0x49, 0x7b, 0x29, 0x7e, 0x13, 0x24, 0x7b, 0x78, 0x69, 0x1c,
+ 0x8f, 0x13, 0xff, 0xa5, 0xbc, 0x94, 0x91, 0xac, 0xb9, 0x61, 0x3b, 0xe5,
+ 0x84, 0xe9, 0x62, 0x0f, 0x4a, 0xa5, 0x6f, 0x62, 0x6a, 0x84, 0xf8, 0xcc,
+ 0x3b, 0xc4, 0x93, 0xaa, 0x17, 0x85, 0xd9, 0xb7, 0x5a, 0x64, 0xf1, 0x24,
+ 0xf9, 0xce, 0x44, 0xc1, 0x34, 0x8e, 0x93, 0x9f, 0xbd, 0x60, 0x37, 0x10,
+ 0x9f, 0x2e, 0xe1, 0x32, 0xf0, 0x5c, 0xbe, 0x00, 0xab, 0x85, 0xed, 0x15,
+ 0xc1, 0xfd, 0x3b, 0xb3, 0x84, 0x13, 0x83, 0x75, 0xf0, 0xa0, 0x2e, 0xf1,
+ 0x4e, 0x6c, 0xb5, 0x87, 0x22, 0x55, 0x1f, 0xaf, 0x27, 0x9a, 0x7d, 0xdd,
+ 0x36, 0x42, 0xc3, 0x3d, 0x84, 0x97, 0xfc, 0x15, 0xb7, 0x92, 0xbf, 0x7a,
+ 0xb8, 0x9c, 0xe2, 0x21, 0xea, 0xec, 0x49, 0xbf, 0x36, 0xe4, 0xc9, 0x5a,
+ 0xcb, 0xea, 0xff, 0x48, 0x6c, 0xc2, 0x27, 0x69, 0xb6, 0x83, 0x4a, 0xf2,
+ 0xea, 0x78, 0x39, 0x3d, 0x82, 0x57, 0x8b, 0x7f, 0x82, 0x5c, 0xb3, 0x99,
+ 0xda, 0x2c, 0xd6, 0x61, 0x66, 0xe4, 0x0a, 0xe0, 0xcf, 0xd9, 0x7e, 0x02,
+ 0xf3, 0xad, 0x75, 0x38, 0x34, 0x76, 0x2f, 0x8e, 0x8c, 0xd6, 0xe3, 0x39,
+ 0x2b, 0x86, 0xf6, 0x89, 0x0a, 0x9d, 0x6b, 0xe6, 0x72, 0x93, 0x9e, 0xa6,
+ 0xe0, 0x6b, 0xe3, 0x98, 0x14, 0xb8, 0x3e, 0xb3, 0x0e, 0x39, 0xdf, 0xcf,
+ 0x3d, 0xac, 0xa1, 0xdc, 0x96, 0xcf, 0xbb, 0x14, 0xd7, 0x75, 0xd8, 0xd9,
+ 0x0c, 0x71, 0x0b, 0xd5, 0x93, 0x3b, 0x29, 0x5e, 0xef, 0x54, 0x62, 0x70,
+ 0x13, 0x2e, 0xd9, 0x55, 0xe0, 0x22, 0xcb, 0xc0, 0x9e, 0x22, 0x70, 0x77,
+ 0x51, 0xc5, 0xdf, 0x14, 0x2f, 0x45, 0xb9, 0x8d, 0xcf, 0x2e, 0x40, 0x79,
+ 0x1e, 0x7f, 0x87, 0x31, 0x16, 0x33, 0x13, 0x20, 0x9d, 0xed, 0x2f, 0xa8,
+ 0xf8, 0xb1, 0xbd, 0xeb, 0xec, 0xd8, 0x0a, 0x53, 0xcf, 0x51, 0xac, 0x85,
+ 0xac, 0xd3, 0xe4, 0x67, 0xfc, 0x0c, 0x7c, 0x3f, 0xff, 0x99, 0xfc, 0xb9,
+ 0x4f, 0x53, 0xc5, 0x6d, 0xf9, 0x8e, 0x81, 0x8f, 0x94, 0x8f, 0xe5, 0xbf,
+ 0x85, 0x19, 0xff, 0x77, 0xa2, 0x15, 0x7f, 0xdd, 0xc3, 0x79, 0xc4, 0xad,
+ 0xf8, 0xed, 0xbc, 0x2f, 0xf8, 0x6d, 0xc5, 0x3f, 0x47, 0xb2, 0xcc, 0x47,
+ 0x35, 0xc6, 0x62, 0xb8, 0x68, 0x22, 0x89, 0xba, 0x9d, 0xfc, 0x9b, 0xd7,
+ 0x05, 0x2e, 0xee, 0xe6, 0xf8, 0x4a, 0x42, 0xd9, 0x7b, 0x2d, 0xe1, 0x63,
+ 0xd9, 0xab, 0xb9, 0xe2, 0x7b, 0x73, 0xf8, 0xcf, 0xe7, 0x98, 0x76, 0xc2,
+ 0xb7, 0x74, 0x29, 0x3f, 0xf3, 0x99, 0x3a, 0xfc, 0x7a, 0xaf, 0x69, 0x97,
+ 0x95, 0xa5, 0x44, 0x93, 0x63, 0x92, 0x63, 0xf3, 0x2f, 0xe6, 0xce, 0x24,
+ 0xc8, 0xce, 0xd3, 0xb2, 0xbc, 0x8a, 0xf1, 0x55, 0xcf, 0x27, 0x11, 0x3a,
+ 0x47, 0x57, 0xc5, 0xea, 0xec, 0x97, 0xe9, 0xda, 0x94, 0xf7, 0x5b, 0xd1,
+ 0xb0, 0xd0, 0x22, 0x3b, 0xb5, 0xa1, 0x91, 0xe2, 0x3a, 0x62, 0xad, 0x92,
+ 0x91, 0x6f, 0xb3, 0x8f, 0x6a, 0x5e, 0xd8, 0xf9, 0x0a, 0x4a, 0x23, 0xcf,
+ 0x93, 0x7d, 0xa3, 0xec, 0x8b, 0x1b, 0x3e, 0x12, 0x5f, 0xc1, 0xf4, 0x98,
+ 0x88, 0xb2, 0xac, 0xab, 0x28, 0xb6, 0xe7, 0x53, 0x7d, 0xf8, 0xe0, 0xe1,
+ 0xbb, 0xe4, 0x58, 0x9f, 0x8e, 0x17, 0xb3, 0x49, 0x5a, 0x67, 0x5f, 0xb2,
+ 0xf1, 0x4c, 0x5e, 0xc3, 0xee, 0xe1, 0x84, 0xef, 0xc7, 0xf7, 0x74, 0xd6,
+ 0x9d, 0x2a, 0x2b, 0x36, 0x9e, 0x25, 0x3f, 0x3c, 0x58, 0x60, 0x1d, 0xab,
+ 0xb8, 0x38, 0xf3, 0x75, 0x59, 0xd3, 0xc6, 0xbe, 0x1d, 0xa1, 0x33, 0x3a,
+ 0xe1, 0x8e, 0x42, 0xb7, 0x96, 0xcb, 0x37, 0x56, 0xf0, 0x73, 0x03, 0xad,
+ 0xb5, 0xd1, 0xf7, 0x12, 0xd9, 0xf8, 0x3b, 0x7c, 0xe8, 0xff, 0x1b, 0x1f,
+ 0xf4, 0x1d, 0xa3, 0x75, 0x90, 0xbf, 0xcc, 0x88, 0xd5, 0x95, 0xfe, 0x46,
+ 0x53, 0xad, 0x19, 0xb1, 0xc6, 0xef, 0x69, 0xfc, 0x34, 0x4e, 0x38, 0x7a,
+ 0xb1, 0x77, 0x54, 0xca, 0x2d, 0x76, 0x3b, 0x5c, 0x3d, 0x86, 0x2d, 0x16,
+ 0xc5, 0xeb, 0x28, 0x9f, 0x91, 0x32, 0x95, 0x5e, 0xd8, 0xa3, 0x8a, 0x16,
+ 0xca, 0x99, 0x9e, 0x58, 0x9b, 0x35, 0xc4, 0x9d, 0xa3, 0x2a, 0xf2, 0x85,
+ 0x0b, 0x28, 0x27, 0x4b, 0xf9, 0x64, 0x1a, 0xee, 0x60, 0xba, 0x01, 0x2f,
+ 0x8f, 0xe9, 0x14, 0x3b, 0x67, 0xe5, 0xf2, 0x64, 0x2f, 0x4a, 0x84, 0xe7,
+ 0xd3, 0x74, 0x57, 0xea, 0xb0, 0x88, 0x60, 0x2c, 0x1e, 0xc1, 0x9e, 0x42,
+ 0x1c, 0x87, 0xc7, 0x23, 0xd8, 0x46, 0xfe, 0xf7, 0xd3, 0x2c, 0xd3, 0x8c,
+ 0x60, 0x73, 0x89, 0x7b, 0x8d, 0x10, 0xe9, 0xc0, 0x13, 0xef, 0xf9, 0x6b,
+ 0x0d, 0x58, 0x3e, 0xc6, 0x7b, 0xcf, 0xca, 0x76, 0xcb, 0xd2, 0xdb, 0x43,
+ 0xd5, 0x7d, 0xef, 0x50, 0x1f, 0x63, 0x50, 0xef, 0x72, 0x21, 0xe5, 0xaa,
+ 0x04, 0xf5, 0x2a, 0x71, 0xea, 0x55, 0xac, 0xb9, 0xfe, 0xcb, 0xa4, 0x48,
+ 0x93, 0xf2, 0x19, 0xca, 0x53, 0x6f, 0xd2, 0xe7, 0xa4, 0x4d, 0xe5, 0x96,
+ 0x64, 0xbc, 0x78, 0x98, 0x65, 0xf4, 0x84, 0xbd, 0x84, 0x3a, 0xce, 0x69,
+ 0xd3, 0x70, 0x95, 0x5f, 0x50, 0x9f, 0x65, 0xa0, 0x63, 0x9a, 0x79, 0x50,
+ 0xb1, 0xb5, 0x00, 0x0c, 0x16, 0xe0, 0x1d, 0xa6, 0xd8, 0x6e, 0x99, 0x88,
+ 0x22, 0x36, 0xa1, 0x23, 0x3c, 0x91, 0xa2, 0xbd, 0x1a, 0xe2, 0xf4, 0xdb,
+ 0xa3, 0xbe, 0xab, 0xc9, 0x69, 0x13, 0x8b, 0x76, 0x9f, 0x91, 0x0f, 0x52,
+ 0xac, 0xdd, 0x91, 0x34, 0x7b, 0x6f, 0x14, 0x70, 0x53, 0x43, 0x52, 0xd6,
+ 0xa6, 0x6b, 0xa9, 0x7e, 0xcb, 0x43, 0x71, 0x92, 0x3d, 0xea, 0xc8, 0x4d,
+ 0xaf, 0x76, 0x5b, 0xf6, 0xab, 0x20, 0xbc, 0x25, 0x3e, 0xc3, 0xeb, 0x9e,
+ 0xf8, 0xac, 0xdb, 0xda, 0xf3, 0x16, 0x3a, 0xb1, 0x78, 0x42, 0x15, 0xbf,
+ 0x1c, 0x5a, 0x84, 0xcc, 0x34, 0xf4, 0x1a, 0xe2, 0xeb, 0xc3, 0x29, 0xe2,
+ 0xbb, 0x40, 0xb2, 0x14, 0x48, 0x96, 0x02, 0xc9, 0x42, 0x7a, 0x39, 0xe8,
+ 0xf7, 0x6d, 0x2c, 0x6b, 0x8a, 0xea, 0xef, 0x3b, 0x7e, 0x6f, 0x79, 0xb0,
+ 0xc4, 0x72, 0x98, 0xae, 0x07, 0x96, 0x9b, 0xe5, 0x94, 0xf2, 0x2d, 0x9b,
+ 0xe5, 0x31, 0x0d, 0x4f, 0x21, 0x6b, 0x4d, 0x1b, 0x48, 0x4d, 0x57, 0xf5,
+ 0x21, 0xe5, 0xe7, 0x36, 0xeb, 0x83, 0x65, 0x94, 0xf2, 0x69, 0x92, 0x69,
+ 0x2b, 0xc9, 0x38, 0x58, 0x90, 0x87, 0x6a, 0x2c, 0xcb, 0x98, 0x20, 0xde,
+ 0x62, 0x24, 0x53, 0x7c, 0x42, 0x23, 0x59, 0x3b, 0xa1, 0x92, 0xac, 0xa1,
+ 0x09, 0xe8, 0x0a, 0xeb, 0x69, 0xfa, 0xff, 0xe2, 0x87, 0xfb, 0x6a, 0x4f,
+ 0x5c, 0x43, 0xfd, 0xb4, 0x4a, 0xfb, 0x07, 0xc9, 0x77, 0x72, 0x2a, 0x8c,
+ 0x5a, 0x4b, 0xa1, 0x3c, 0xac, 0xe1, 0xf1, 0xf1, 0x06, 0x4c, 0x90, 0xdd,
+ 0xc7, 0xc6, 0xa1, 0x87, 0xe9, 0xfd, 0xd6, 0x73, 0xfe, 0x04, 0xf2, 0xa7,
+ 0x0d, 0x18, 0xa7, 0xfc, 0xf3, 0x40, 0x3e, 0x26, 0x26, 0x46, 0x54, 0x6c,
+ 0x29, 0x9c, 0x20, 0xd9, 0x24, 0xe5, 0xd8, 0xcd, 0x09, 0xda, 0x22, 0x36,
+ 0xdb, 0x66, 0x0f, 0x70, 0x05, 0xf9, 0x5a, 0x08, 0x6b, 0x2d, 0xb8, 0xdb,
+ 0xed, 0x2b, 0x30, 0xdb, 0x07, 0x63, 0x87, 0xed, 0xe9, 0x35, 0x30, 0x8f,
+ 0x5e, 0x43, 0xa3, 0xc0, 0xe5, 0x24, 0xc7, 0x80, 0xe5, 0x6d, 0xa0, 0x84,
+ 0x44, 0xf9, 0xdb, 0xec, 0x3f, 0x42, 0x36, 0x28, 0x52, 0x5d, 0x2b, 0x52,
+ 0x0f, 0x78, 0x60, 0xf4, 0x8c, 0xbc, 0x3d, 0x6d, 0xba, 0x49, 0x5a, 0x0b,
+ 0x0f, 0x69, 0xd8, 0x5f, 0xd2, 0x28, 0x5e, 0x4c, 0x1b, 0xe0, 0x98, 0x87,
+ 0x56, 0x4b, 0x3d, 0xda, 0x47, 0xd6, 0xa3, 0xd4, 0x0b, 0x6b, 0xa0, 0x3e,
+ 0x19, 0x57, 0x8f, 0x08, 0xec, 0xa7, 0xf8, 0x9d, 0x5a, 0x64, 0x1e, 0x5d,
+ 0x0d, 0xaf, 0xdc, 0x0e, 0x73, 0xa0, 0x96, 0x18, 0xf9, 0x74, 0xa8, 0x86,
+ 0xfa, 0xc2, 0x4e, 0xfb, 0x35, 0x98, 0xfa, 0xfe, 0xd0, 0xaf, 0xe4, 0x64,
+ 0x1c, 0x17, 0x84, 0x71, 0x52, 0x1a, 0xdf, 0xe2, 0x33, 0x2c, 0xf7, 0x06,
+ 0x6c, 0xcf, 0x42, 0x0b, 0x3b, 0x6a, 0x7a, 0x7f, 0x1e, 0x38, 0x96, 0x37,
+ 0x30, 0xb9, 0xa8, 0x0e, 0x68, 0xee, 0xe8, 0xb9, 0x03, 0xde, 0xaa, 0xb0,
+ 0xdf, 0xe7, 0x6a, 0xe9, 0x3c, 0xf9, 0xc8, 0x7a, 0x21, 0xf0, 0x24, 0xd1,
+ 0x5a, 0x30, 0xc5, 0x7d, 0x89, 0x9a, 0x5e, 0x48, 0x79, 0x76, 0x5b, 0x49,
+ 0xa0, 0xd6, 0x32, 0xf5, 0x59, 0xb0, 0x6e, 0x74, 0xd2, 0xe9, 0x19, 0x89,
+ 0x66, 0x96, 0xdd, 0xcb, 0x91, 0x9c, 0xab, 0xb6, 0x12, 0xff, 0x6b, 0x48,
+ 0xa6, 0xdb, 0x2d, 0xaf, 0x87, 0xb0, 0x52, 0xed, 0x31, 0x13, 0x1f, 0x90,
+ 0xec, 0x6b, 0x29, 0x47, 0x8c, 0x95, 0x86, 0x9b, 0x38, 0x1f, 0x4c, 0x94,
+ 0x78, 0x4e, 0xea, 0xc1, 0xd5, 0xf9, 0x6a, 0x2c, 0xb0, 0xdd, 0xd9, 0xe6,
+ 0x17, 0xfa, 0xf5, 0xfb, 0xa0, 0xef, 0x23, 0xdc, 0x3f, 0xf5, 0x60, 0xb4,
+ 0x53, 0xa1, 0xde, 0x5c, 0xca, 0x15, 0x96, 0x39, 0xc2, 0xf9, 0x99, 0x7c,
+ 0xdd, 0xdd, 0x67, 0x37, 0x51, 0x6c, 0xc2, 0x7b, 0xc2, 0x36, 0x50, 0xe3,
+ 0xb0, 0x4f, 0x34, 0x90, 0x8f, 0x47, 0xb0, 0x9d, 0x7c, 0x44, 0xb3, 0xac,
+ 0x14, 0x35, 0x53, 0xfa, 0xb1, 0x2c, 0xed, 0x2d, 0xc1, 0x28, 0xd9, 0xf5,
+ 0x98, 0x6d, 0x55, 0xd1, 0xec, 0x1c, 0x92, 0x2d, 0xd6, 0x7f, 0x10, 0x7d,
+ 0x4b, 0xbf, 0x1b, 0xab, 0x61, 0xb4, 0x1a, 0x68, 0x70, 0xf8, 0xfd, 0x69,
+ 0x39, 0xdb, 0x1c, 0x21, 0xff, 0xe2, 0x3d, 0x96, 0x77, 0x10, 0xbf, 0x96,
+ 0x88, 0xf1, 0x5e, 0x97, 0xf2, 0x27, 0xc4, 0x0c, 0xd1, 0x42, 0x0b, 0xc7,
+ 0x2d, 0xf7, 0xe7, 0xd6, 0xd1, 0x43, 0x54, 0x53, 0x8c, 0x16, 0x50, 0x2e,
+ 0x55, 0x11, 0x72, 0x2c, 0x7d, 0x1f, 0x8e, 0x92, 0xcd, 0xd9, 0x45, 0x2e,
+ 0x12, 0xd7, 0xed, 0xba, 0x50, 0xf4, 0xee, 0x92, 0xb2, 0x33, 0x0d, 0x9a,
+ 0xc2, 0x92, 0xc6, 0x4b, 0xb4, 0xba, 0x85, 0x7c, 0xbf, 0xd1, 0x89, 0x88,
+ 0xe2, 0x2e, 0xe8, 0x07, 0x6c, 0x8d, 0xf2, 0xae, 0x94, 0xdb, 0xd2, 0x06,
+ 0xa6, 0x6d, 0xea, 0xc7, 0x5b, 0xc3, 0x68, 0xb6, 0xa0, 0xeb, 0x8e, 0x35,
+ 0xf0, 0x14, 0xee, 0x26, 0x3e, 0x11, 0x99, 0x4f, 0x35, 0x90, 0xd6, 0xc4,
+ 0x5e, 0xbb, 0x0e, 0xee, 0x4d, 0x02, 0x11, 0x27, 0x4e, 0xbc, 0xd5, 0x20,
+ 0xe7, 0x3f, 0xb3, 0x8c, 0x70, 0xdf, 0xb7, 0x7f, 0x44, 0xf2, 0x8a, 0xf9,
+ 0xf5, 0x0e, 0xaf, 0x59, 0x76, 0x11, 0xeb, 0xa9, 0xe7, 0xa7, 0x25, 0x7a,
+ 0xbf, 0x85, 0xde, 0x3f, 0x44, 0xb8, 0x73, 0x31, 0x7f, 0xd6, 0x6b, 0x6a,
+ 0x77, 0xac, 0xf2, 0x73, 0x78, 0x90, 0x64, 0xe0, 0xfc, 0xcd, 0x6b, 0xcc,
+ 0xf3, 0x22, 0xe6, 0x99, 0x6a, 0x37, 0xfb, 0x95, 0x8d, 0x8f, 0xf2, 0x77,
+ 0x73, 0x0f, 0xef, 0xee, 0xb0, 0x21, 0x26, 0xec, 0x3d, 0x28, 0xeb, 0x68,
+ 0x8a, 0x3a, 0x56, 0xff, 0x34, 0xa0, 0x44, 0x9c, 0x51, 0x14, 0x9b, 0x81,
+ 0x87, 0x0a, 0x96, 0xb7, 0x51, 0x31, 0x07, 0xe2, 0xd4, 0xf7, 0x9e, 0xfc,
+ 0xa1, 0x8a, 0x9d, 0x9d, 0x65, 0x33, 0x46, 0x46, 0x8f, 0x3a, 0x51, 0xf1,
+ 0xe2, 0x2e, 0x05, 0x0b, 0x96, 0xa8, 0x78, 0x8b, 0x72, 0xc8, 0x36, 0x9a,
+ 0x45, 0xc2, 0x96, 0xda, 0x54, 0xe9, 0x89, 0x7f, 0x5f, 0x3c, 0x9a, 0xa4,
+ 0xb1, 0x6a, 0x4c, 0x5a, 0x7d, 0x07, 0xf0, 0xa8, 0x74, 0x9b, 0xd9, 0x16,
+ 0x11, 0xca, 0xc3, 0xe7, 0xf2, 0x50, 0x6a, 0x8a, 0xf0, 0x0f, 0x76, 0xbf,
+ 0xeb, 0xfb, 0x0c, 0xd9, 0xd2, 0x7d, 0x23, 0x0f, 0xd1, 0x94, 0x71, 0x30,
+ 0xdb, 0xcc, 0x76, 0xe1, 0xf9, 0x99, 0x94, 0x37, 0x4c, 0xc3, 0x47, 0x8b,
+ 0x8a, 0xc5, 0x19, 0x34, 0x29, 0x8e, 0x75, 0x6a, 0x2f, 0xf1, 0xdc, 0xee,
+ 0x34, 0xe1, 0x74, 0x0b, 0xe7, 0xc4, 0xa8, 0xf8, 0xd9, 0xa8, 0xd9, 0x43,
+ 0x3d, 0xee, 0xaa, 0x8d, 0x30, 0xfb, 0xee, 0x11, 0xd4, 0x97, 0x11, 0xef,
+ 0x56, 0x92, 0xf8, 0xb4, 0x55, 0xc4, 0x93, 0x65, 0x33, 0x8e, 0x2a, 0xbf,
+ 0x67, 0x65, 0xcc, 0xb2, 0xbc, 0x98, 0xf2, 0x1b, 0x99, 0xce, 0xb0, 0x8f,
+ 0xdf, 0x85, 0xda, 0x98, 0x40, 0x4d, 0x66, 0xc4, 0xd7, 0x6d, 0x94, 0xec,
+ 0xdd, 0x94, 0x51, 0x89, 0xb6, 0x4a, 0x39, 0x9d, 0x68, 0x2f, 0x1e, 0xa0,
+ 0x9e, 0x85, 0x75, 0xfa, 0x92, 0xcc, 0x7d, 0x9b, 0xe5, 0xbc, 0x65, 0x4e,
+ 0x66, 0xd2, 0x6c, 0x3d, 0xff, 0x96, 0x0d, 0xac, 0xfb, 0x43, 0x94, 0xcf,
+ 0x17, 0x2f, 0xed, 0xda, 0x31, 0xa0, 0x3c, 0x20, 0x8d, 0x15, 0x6c, 0xdb,
+ 0x46, 0x7a, 0xef, 0xdb, 0x9d, 0xfa, 0xa9, 0x77, 0xf0, 0xda, 0x50, 0x54,
+ 0x34, 0xed, 0xf6, 0xfc, 0xda, 0xf9, 0x2a, 0xf1, 0xf5, 0x61, 0x9a, 0xf9,
+ 0xe1, 0x78, 0x7b, 0x07, 0x97, 0x16, 0xff, 0x94, 0xf6, 0x86, 0x88, 0x17,
+ 0x68, 0x31, 0x92, 0x75, 0x05, 0xcd, 0x25, 0x57, 0x67, 0x0e, 0x48, 0x57,
+ 0x67, 0xfc, 0xa4, 0xf7, 0x51, 0xd6, 0x3b, 0xcf, 0x45, 0x55, 0xdd, 0xf3,
+ 0x7e, 0x3e, 0x3f, 0x4c, 0x31, 0xc9, 0xb6, 0x44, 0x53, 0x83, 0xc3, 0xfa,
+ 0x85, 0xa8, 0x73, 0xba, 0x8c, 0x85, 0x62, 0x87, 0xf4, 0xe2, 0xd5, 0x7c,
+ 0x16, 0x15, 0x13, 0xfe, 0x79, 0xa6, 0xfd, 0xe5, 0xf3, 0x6d, 0xe2, 0xd8,
+ 0xc3, 0x54, 0x7c, 0xeb, 0x7d, 0x7f, 0xe9, 0x7d, 0x92, 0xe2, 0x49, 0x73,
+ 0x6e, 0x95, 0xa9, 0x56, 0xf6, 0x37, 0x28, 0x2f, 0xdb, 0xb7, 0xc8, 0x5c,
+ 0x2b, 0xfb, 0x1d, 0xbc, 0x38, 0xe1, 0xd9, 0xb9, 0xfb, 0x3c, 0x1f, 0xd7,
+ 0x74, 0x4a, 0x39, 0x61, 0x5f, 0x45, 0xba, 0x60, 0x3c, 0x55, 0x5d, 0xfc,
+ 0xe5, 0x9c, 0x6e, 0xa8, 0x89, 0xae, 0xaf, 0xd4, 0x2b, 0xce, 0x69, 0x35,
+ 0xce, 0x1b, 0x78, 0x31, 0xaf, 0xb4, 0x85, 0xd1, 0x84, 0x3e, 0x5b, 0xe0,
+ 0xdd, 0x1e, 0x81, 0xd3, 0x97, 0x47, 0x10, 0xba, 0xcc, 0x2a, 0x77, 0x84,
+ 0xfa, 0x25, 0xe6, 0x95, 0xc9, 0x51, 0xce, 0x48, 0xad, 0x53, 0x45, 0xed,
+ 0xa5, 0x5c, 0xa7, 0xd8, 0x0e, 0x0a, 0xfe, 0x85, 0xf6, 0x5d, 0x77, 0xa9,
+ 0x65, 0x74, 0x50, 0x4b, 0xe0, 0xf5, 0x5d, 0x9d, 0x09, 0x9f, 0xf3, 0x43,
+ 0xe6, 0xe1, 0x4a, 0x5f, 0x06, 0xf6, 0xc7, 0xc5, 0x64, 0xc7, 0xdc, 0x0a,
+ 0x05, 0xe9, 0x25, 0xf0, 0x22, 0xf4, 0x7e, 0xdb, 0x2e, 0xf6, 0x85, 0x47,
+ 0x74, 0x9e, 0x09, 0x81, 0xae, 0x84, 0x0e, 0x6b, 0xd5, 0x0b, 0x44, 0x9b,
+ 0xfa, 0x4d, 0xd2, 0x07, 0xd3, 0xaa, 0xe2, 0xa9, 0xe2, 0x88, 0x8a, 0xd3,
+ 0x0f, 0xf3, 0x19, 0x08, 0xd6, 0x51, 0x7a, 0x01, 0xc5, 0x76, 0x46, 0x9d,
+ 0x93, 0x6d, 0x40, 0xaf, 0xf4, 0x61, 0x51, 0x31, 0x35, 0xca, 0xf8, 0x7c,
+ 0x3f, 0x42, 0x91, 0x7d, 0x2b, 0xcd, 0x7b, 0x7e, 0x23, 0x17, 0x64, 0xfe,
+ 0x9d, 0xf6, 0x30, 0xde, 0xa8, 0x38, 0xe2, 0xd3, 0xae, 0xe8, 0x68, 0x8a,
+ 0x74, 0x3d, 0x91, 0xae, 0xe2, 0xd9, 0x48, 0x7b, 0xd8, 0xe7, 0x98, 0x87,
+ 0x5e, 0xf1, 0x78, 0x9e, 0xf2, 0x0a, 0xd5, 0xdc, 0x89, 0xac, 0x62, 0xd5,
+ 0x42, 0x62, 0xb3, 0xad, 0x63, 0x99, 0x5e, 0xa9, 0x57, 0xf7, 0xe7, 0xab,
+ 0xf7, 0x3f, 0xbd, 0xa2, 0x90, 0x57, 0xa8, 0x7f, 0x83, 0x5e, 0xef, 0x28,
+ 0xf7, 0x34, 0x51, 0x2c, 0xbd, 0x46, 0xb5, 0xeb, 0xd5, 0xb1, 0x5e, 0x91,
+ 0xcf, 0xeb, 0x78, 0x65, 0x7c, 0xb9, 0x78, 0x30, 0x6f, 0xe1, 0xe5, 0x62,
+ 0xe5, 0x2e, 0xe8, 0x81, 0xa2, 0x2b, 0xc6, 0xf3, 0xdc, 0xfb, 0x98, 0xa9,
+ 0x32, 0x66, 0xc4, 0x5a, 0xc2, 0x53, 0x56, 0x2f, 0xf4, 0xeb, 0xc8, 0x78,
+ 0xb1, 0x01, 0x93, 0x63, 0x95, 0x7a, 0x77, 0xeb, 0xb9, 0x7a, 0xf7, 0xc5,
+ 0x3b, 0x9d, 0x48, 0x4e, 0x77, 0xd0, 0xd7, 0x38, 0xbc, 0x49, 0x46, 0xad,
+ 0x10, 0xd5, 0x49, 0x2b, 0x37, 0x2d, 0x22, 0x3d, 0x3b, 0xba, 0x99, 0x5f,
+ 0xf4, 0x69, 0xd4, 0x63, 0x4c, 0x14, 0xd9, 0x5f, 0x0d, 0x18, 0xc5, 0x6f,
+ 0xb5, 0x56, 0xec, 0xdc, 0x96, 0xd3, 0x1c, 0xa0, 0x9e, 0xfa, 0x8b, 0x06,
+ 0x9a, 0x0d, 0xea, 0x9c, 0x1b, 0xbd, 0x8e, 0x6e, 0xe4, 0x54, 0xc7, 0xea,
+ 0xb9, 0x5e, 0xac, 0x5c, 0xa9, 0x38, 0xf7, 0xad, 0x0c, 0x4d, 0x1b, 0xc6,
+ 0x16, 0xbf, 0x0e, 0x9d, 0x1c, 0xd8, 0x4f, 0x33, 0x50, 0x0d, 0xcd, 0xa5,
+ 0xef, 0xe9, 0xb8, 0x2f, 0xd4, 0x7d, 0x1f, 0x36, 0xe5, 0x07, 0xf0, 0xb7,
+ 0x79, 0xce, 0x13, 0x3a, 0x1e, 0x63, 0x1e, 0x0a, 0x7c, 0xff, 0x73, 0xb0,
+ 0x85, 0x6b, 0xdf, 0x23, 0x25, 0x8a, 0xc3, 0x21, 0xe4, 0x12, 0x8e, 0x9f,
+ 0x47, 0x12, 0xa7, 0xc4, 0xf9, 0xfd, 0xbf, 0xbb, 0x97, 0xf5, 0x46, 0xfd,
+ 0x1c, 0xcd, 0x4e, 0x4a, 0xf6, 0x4a, 0xbe, 0x7f, 0xf2, 0x03, 0x74, 0x3b,
+ 0xe5, 0x91, 0x0f, 0x6c, 0x13, 0x63, 0x7a, 0xc5, 0x7e, 0xdb, 0x47, 0xb9,
+ 0x1e, 0x7d, 0x42, 0xf5, 0x28, 0x2a, 0xb6, 0xd2, 0x73, 0xa3, 0xf3, 0x4a,
+ 0x7a, 0x8a, 0x78, 0x3f, 0x46, 0x39, 0x26, 0xe1, 0x1c, 0x47, 0xa2, 0xc0,
+ 0xb3, 0xfa, 0x51, 0x9a, 0xd5, 0xcd, 0xdc, 0x32, 0x8a, 0xe7, 0x03, 0x76,
+ 0xd7, 0xc0, 0xa0, 0x30, 0x8f, 0x52, 0x6d, 0x4e, 0x1c, 0xa0, 0xb9, 0x8b,
+ 0xbe, 0x37, 0xb4, 0x87, 0xba, 0xec, 0x75, 0x30, 0xdd, 0x85, 0xc2, 0x34,
+ 0x5e, 0x17, 0xa6, 0x5e, 0x23, 0x58, 0x27, 0x9f, 0x60, 0x91, 0xaf, 0x9b,
+ 0xe3, 0xb0, 0xfc, 0xef, 0x57, 0xd2, 0x1d, 0xfe, 0xf7, 0xd1, 0xf4, 0xc5,
+ 0xe7, 0x7b, 0x0b, 0x77, 0x07, 0xd5, 0xc6, 0x7c, 0x21, 0x83, 0x48, 0x33,
+ 0xd7, 0x8a, 0xa8, 0x38, 0xb0, 0x0b, 0x5a, 0xbd, 0xf3, 0x3e, 0xbe, 0x3e,
+ 0x04, 0x4d, 0x73, 0xa8, 0xd2, 0x12, 0x2f, 0xd4, 0x1b, 0xa4, 0xae, 0x13,
+ 0xdc, 0x0f, 0x74, 0xe5, 0x9e, 0x80, 0xd9, 0x53, 0x43, 0x34, 0x3e, 0x01,
+ 0xe3, 0x7a, 0x1f, 0x49, 0x1f, 0xe7, 0x2c, 0xce, 0xe3, 0x8c, 0x8a, 0xc1,
+ 0xd1, 0xa8, 0xd8, 0x4c, 0xb2, 0xb4, 0x3b, 0x27, 0x71, 0x85, 0xcf, 0xff,
+ 0x2b, 0xc4, 0x3f, 0xe7, 0x9c, 0x13, 0x94, 0x73, 0x18, 0xef, 0xd1, 0x34,
+ 0xe3, 0x1d, 0xa0, 0x3e, 0xf3, 0x7a, 0xdb, 0x4c, 0xf5, 0x84, 0xcc, 0x44,
+ 0x97, 0x30, 0x29, 0xa9, 0xb1, 0x3c, 0x5d, 0xfd, 0x33, 0xe0, 0xb9, 0xd8,
+ 0x97, 0xa9, 0xa7, 0x9e, 0x64, 0x1a, 0x22, 0x7a, 0x1f, 0xfa, 0xf4, 0x4e,
+ 0xce, 0xd1, 0x3b, 0xf1, 0x07, 0x64, 0x52, 0xdd, 0xfb, 0xc9, 0x1e, 0xdb,
+ 0x0a, 0xaf, 0xc8, 0xce, 0xd6, 0x8a, 0x4c, 0x83, 0x3e, 0x2f, 0x3f, 0x49,
+ 0x33, 0x2f, 0x51, 0x67, 0x86, 0xe6, 0x48, 0xa6, 0x6d, 0xae, 0x22, 0xba,
+ 0x44, 0xb3, 0xcb, 0x18, 0x10, 0x66, 0x3f, 0xe9, 0xad, 0x6f, 0xdc, 0xd7,
+ 0xdb, 0x4f, 0xd2, 0x5d, 0x3e, 0xce, 0x19, 0xea, 0x39, 0xbe, 0xe8, 0x93,
+ 0xec, 0x73, 0xd5, 0xbb, 0xca, 0x94, 0x78, 0x8a, 0x7a, 0x97, 0xa7, 0x8a,
+ 0xaa, 0xd8, 0x47, 0xf6, 0x1c, 0xa7, 0xb8, 0x19, 0xf4, 0xef, 0x1f, 0xa9,
+ 0x06, 0x96, 0xbe, 0xd7, 0x3c, 0x97, 0x6f, 0xc8, 0xae, 0x65, 0xb2, 0x6b,
+ 0x27, 0x65, 0x65, 0xee, 0xd9, 0xb8, 0xde, 0x1d, 0xa6, 0x7a, 0x27, 0xf0,
+ 0xa1, 0x9f, 0x63, 0x0f, 0xa3, 0xb3, 0xc8, 0x3d, 0xa1, 0x25, 0x96, 0xe7,
+ 0x8d, 0xdc, 0x7c, 0xc2, 0xfd, 0x7e, 0xa9, 0x92, 0x1f, 0xa9, 0x36, 0xba,
+ 0x21, 0xa7, 0x47, 0xbc, 0x50, 0xe4, 0x9f, 0x54, 0x4c, 0x62, 0xec, 0x5b,
+ 0xae, 0x68, 0xea, 0xf4, 0xd0, 0xde, 0xe9, 0x49, 0xd5, 0xb2, 0xca, 0xef,
+ 0x0b, 0xeb, 0x94, 0x15, 0x72, 0x6f, 0x9f, 0x8f, 0x4d, 0xb8, 0x6c, 0xb1,
+ 0x7b, 0x73, 0x02, 0xfe, 0x4c, 0x6c, 0x50, 0x4c, 0xa2, 0xb7, 0x3b, 0xd9,
+ 0x33, 0x2d, 0x92, 0xd4, 0x43, 0x25, 0xbd, 0x94, 0x48, 0xa6, 0x8e, 0xc3,
+ 0xd6, 0x8e, 0x14, 0x6d, 0xed, 0x8d, 0x62, 0xf5, 0x6e, 0x93, 0xe5, 0x62,
+ 0x5f, 0xe5, 0xf8, 0xb0, 0xdc, 0xfb, 0x29, 0x0f, 0xc1, 0xef, 0x43, 0xe4,
+ 0xa1, 0x46, 0x8a, 0xb1, 0x3b, 0x51, 0x4b, 0x4d, 0xb3, 0xdc, 0xde, 0x44,
+ 0xf3, 0xcf, 0x5d, 0x44, 0xbf, 0xdc, 0x9a, 0x03, 0xd7, 0x93, 0x47, 0xf8,
+ 0xc2, 0xb9, 0x85, 0x79, 0x7a, 0x33, 0x52, 0x91, 0x91, 0xca, 0x70, 0xe5,
+ 0xff, 0x17, 0xd2, 0x1a, 0x28, 0x06, 0xd7, 0x0d, 0x09, 0xea, 0xef, 0x2b,
+ 0xf1, 0xb8, 0x90, 0xef, 0x4e, 0xfd, 0x7b, 0xb3, 0x57, 0x64, 0xa5, 0xde,
+ 0x7f, 0xdc, 0xcc, 0x77, 0x51, 0x8a, 0x33, 0x1c, 0xfb, 0xed, 0xb3, 0x15,
+ 0xdd, 0xf2, 0x1c, 0x7f, 0xa8, 0xe4, 0x8a, 0x6b, 0xf3, 0xd8, 0x40, 0xbd,
+ 0x83, 0x1b, 0x26, 0x1c, 0xd7, 0x16, 0x7b, 0x49, 0x37, 0x96, 0x31, 0x48,
+ 0x44, 0xb7, 0xea, 0x5d, 0xfa, 0x38, 0xf5, 0x5a, 0x84, 0xcb, 0xa0, 0x7e,
+ 0x94, 0x62, 0x7c, 0x1e, 0x76, 0xcc, 0xc5, 0x54, 0xbd, 0xc3, 0x77, 0xbb,
+ 0x03, 0x62, 0xe1, 0x54, 0x25, 0xcd, 0x1f, 0x3a, 0x27, 0xdf, 0x69, 0xb9,
+ 0xfd, 0x26, 0x7e, 0x5f, 0x3f, 0x67, 0x93, 0x2b, 0x99, 0x26, 0xfd, 0x7e,
+ 0x76, 0x8e, 0x87, 0x3f, 0x74, 0xf6, 0x8e, 0xaf, 0xfe, 0xf6, 0x99, 0x59,
+ 0xe2, 0x93, 0x7b, 0x45, 0x78, 0x31, 0x87, 0xfb, 0xc4, 0x0b, 0xe7, 0x7c,
+ 0xe1, 0x52, 0xc2, 0xbd, 0x01, 0x37, 0xd2, 0x7c, 0xd4, 0x49, 0x73, 0x28,
+ 0xcd, 0x2e, 0x48, 0x0d, 0xb3, 0x3e, 0xce, 0x90, 0x3e, 0xd8, 0xe6, 0xa7,
+ 0xc8, 0xe6, 0x1d, 0x39, 0x8a, 0x99, 0xd4, 0x7a, 0x61, 0xf6, 0x92, 0xbf,
+ 0x51, 0xed, 0x32, 0x13, 0x1f, 0xc3, 0x34, 0xd6, 0xfa, 0x3e, 0x7d, 0x66,
+ 0xce, 0xa7, 0x4f, 0xb1, 0x4f, 0xa3, 0x6f, 0x38, 0x04, 0x25, 0xf3, 0x29,
+ 0xe9, 0x8c, 0xe2, 0x4d, 0x30, 0x4e, 0xce, 0x53, 0x67, 0x40, 0xfd, 0xb2,
+ 0x36, 0x9f, 0xf6, 0xc8, 0x42, 0x47, 0xe2, 0x28, 0xf5, 0xdb, 0xfb, 0xc0,
+ 0x25, 0xa3, 0xeb, 0xe8, 0x31, 0x61, 0x96, 0xdf, 0x0b, 0x71, 0x0e, 0x10,
+ 0x68, 0xcc, 0x54, 0xf0, 0x5d, 0x5e, 0x4c, 0x60, 0x47, 0xa9, 0x82, 0xf3,
+ 0x32, 0xf2, 0xe1, 0x31, 0xff, 0x7e, 0x41, 0x81, 0x96, 0x79, 0x9b, 0x6b,
+ 0x33, 0xc1, 0x25, 0x73, 0xf2, 0x7f, 0x67, 0xce, 0x06, 0x6f, 0xce, 0xe9,
+ 0x67, 0x4b, 0x8c, 0x6b, 0x8f, 0x96, 0xe1, 0x7c, 0x0d, 0xb1, 0x26, 0xff,
+ 0x67, 0x54, 0x03, 0x34, 0xea, 0x81, 0xfd, 0xbc, 0x8f, 0x5c, 0x11, 0x94,
+ 0xbf, 0xcb, 0xb5, 0x47, 0xec, 0xf0, 0x5c, 0xfe, 0xfa, 0x06, 0xad, 0xf5,
+ 0xd1, 0x87, 0x75, 0xc6, 0x77, 0x12, 0x37, 0xd1, 0xb3, 0xeb, 0xef, 0xeb,
+ 0xcf, 0xa3, 0xa7, 0x36, 0x4d, 0xfd, 0xad, 0xbf, 0xcf, 0xbf, 0xaf, 0xa0,
+ 0x3d, 0xcb, 0xf9, 0xdd, 0x08, 0xdf, 0xb5, 0xac, 0xce, 0x26, 0x8d, 0xcd,
+ 0x60, 0x3a, 0x06, 0xd6, 0x14, 0x0d, 0xdc, 0x4a, 0x75, 0x61, 0xcc, 0xbf,
+ 0x07, 0x3d, 0x3f, 0xf7, 0x28, 0xb4, 0x6f, 0x19, 0xed, 0x1b, 0xf4, 0xd7,
+ 0x0c, 0x2c, 0x2f, 0x9e, 0x9f, 0xe9, 0x54, 0x3a, 0x77, 0xe8, 0xdc, 0x1c,
+ 0xcb, 0x76, 0x70, 0xc5, 0xce, 0x7c, 0xaf, 0x18, 0xc9, 0x47, 0x89, 0x96,
+ 0x42, 0x19, 0x40, 0xa2, 0x23, 0x73, 0x33, 0xe5, 0x5d, 0x2b, 0xa5, 0x2a,
+ 0x4d, 0x58, 0x9b, 0x22, 0x3f, 0xd6, 0x97, 0xe2, 0x8e, 0x54, 0x0d, 0xf5,
+ 0x34, 0xc3, 0xb8, 0x4d, 0xaf, 0x45, 0x7f, 0xea, 0x52, 0xe0, 0xc6, 0x3a,
+ 0xea, 0x41, 0x06, 0xfc, 0x9e, 0xbe, 0x86, 0xe8, 0xd5, 0x59, 0x4f, 0xe1,
+ 0xf6, 0x73, 0xff, 0xae, 0x42, 0x34, 0x7e, 0xef, 0x3c, 0x77, 0x33, 0xdc,
+ 0xe6, 0x1e, 0xaa, 0x83, 0xdd, 0x58, 0x97, 0x0a, 0x53, 0x6f, 0xcd, 0xf9,
+ 0x61, 0x3e, 0x22, 0xd6, 0x67, 0x72, 0xfd, 0xb9, 0x3e, 0x67, 0x46, 0xcc,
+ 0x90, 0x5c, 0xa8, 0xf5, 0xc4, 0x73, 0x34, 0xbf, 0x65, 0x4a, 0x7c, 0x1f,
+ 0xa5, 0x20, 0x66, 0xf1, 0xcc, 0x48, 0xc3, 0x1f, 0xcd, 0x59, 0xe9, 0xc7,
+ 0xeb, 0x71, 0xd5, 0xbe, 0x06, 0x64, 0xf6, 0xe9, 0xb0, 0x1f, 0xb7, 0x68,
+ 0x2d, 0x45, 0x9f, 0x19, 0xb1, 0xb7, 0xf8, 0x87, 0x68, 0x77, 0x60, 0x8d,
+ 0xfe, 0x3f, 0x95, 0x7d, 0x0b, 0x70, 0x54, 0xe7, 0x95, 0xe6, 0x77, 0xfb,
+ 0x21, 0xb5, 0x9e, 0x5c, 0x09, 0x09, 0x5a, 0x20, 0x9b, 0x6e, 0xf7, 0x6d,
+ 0xa9, 0x8d, 0x3a, 0xe1, 0x36, 0x88, 0xb5, 0x9c, 0xed, 0x2d, 0x1a, 0x2c,
+ 0x8c, 0x08, 0x60, 0xcb, 0xb6, 0x3c, 0x83, 0x77, 0x32, 0x6b, 0xc5, 0x36,
+ 0x18, 0x3f, 0x92, 0x91, 0x09, 0x5b, 0x25, 0x53, 0x53, 0xd1, 0x1d, 0x01,
+ 0x42, 0x40, 0xbf, 0x24, 0xc1, 0x00, 0x33, 0x53, 0xe3, 0x46, 0x0f, 0x20,
+ 0xb8, 0x5b, 0xc2, 0x71, 0x66, 0x4a, 0xc9, 0xd4, 0x56, 0x34, 0x20, 0x0c,
+ 0x04, 0x63, 0x3c, 0x93, 0x99, 0x29, 0xb2, 0xeb, 0x2d, 0x13, 0x1c, 0xc0,
+ 0x0f, 0xfc, 0x4c, 0xb2, 0x16, 0xf1, 0xc4, 0x77, 0xbf, 0x73, 0xbb, 0x1b,
+ 0x04, 0x45, 0x3c, 0x35, 0x54, 0x75, 0xb5, 0x6e, 0xdf, 0xff, 0xfe, 0x8f,
+ 0xf3, 0x9f, 0xf3, 0x9d, 0xef, 0x9c, 0xf3, 0xdf, 0xa2, 0x84, 0xfe, 0xfb,
+ 0xdf, 0xcc, 0x75, 0x8c, 0x4f, 0xdc, 0x0b, 0x69, 0x66, 0xb3, 0x65, 0xbc,
+ 0x0b, 0x5f, 0x0e, 0x24, 0x9c, 0xe8, 0xea, 0x77, 0xe0, 0xda, 0xa2, 0x73,
+ 0xa6, 0x67, 0xf6, 0x8d, 0xfc, 0x4e, 0xc4, 0xe6, 0xc4, 0x33, 0xfd, 0xf2,
+ 0xed, 0x40, 0x60, 0x71, 0x36, 0xe7, 0xba, 0x61, 0xd0, 0x89, 0xa7, 0xd9,
+ 0xf6, 0xa2, 0x6e, 0xcb, 0xed, 0xb1, 0x55, 0x1b, 0xc0, 0x73, 0xfd, 0x8c,
+ 0x6d, 0x34, 0x13, 0xcf, 0x86, 0x8a, 0x71, 0x7f, 0x75, 0x76, 0x1d, 0xc3,
+ 0x5c, 0x87, 0xe1, 0x30, 0x94, 0x4c, 0xa3, 0x13, 0xe5, 0x9c, 0x3f, 0xb9,
+ 0x18, 0x7e, 0x98, 0x29, 0xc1, 0xe8, 0x81, 0x71, 0x25, 0x9d, 0xce, 0xb6,
+ 0x19, 0xb2, 0x62, 0x5a, 0x43, 0x19, 0x6b, 0xb4, 0x61, 0x26, 0xfd, 0xfb,
+ 0x85, 0x8c, 0x03, 0x9f, 0x65, 0x5c, 0xf8, 0x74, 0xa4, 0x18, 0xbf, 0x3e,
+ 0x50, 0xc2, 0x8f, 0x8a, 0x4f, 0x46, 0x34, 0xfe, 0xde, 0xac, 0xbc, 0x12,
+ 0x95, 0xd8, 0x23, 0x80, 0x4f, 0x33, 0xe3, 0xca, 0xd1, 0xaf, 0x5c, 0x6b,
+ 0xc6, 0xfc, 0x8e, 0x6a, 0x70, 0xcc, 0xbf, 0x36, 0xbf, 0x3b, 0x4d, 0xae,
+ 0xd3, 0xc7, 0xaa, 0xd4, 0x4a, 0xf0, 0xd9, 0x01, 0x19, 0x47, 0xfa, 0x6f,
+ 0x56, 0x5e, 0x8d, 0x8a, 0x7c, 0x2b, 0xf1, 0xeb, 0x11, 0x91, 0xe3, 0x27,
+ 0xd4, 0x69, 0xe9, 0x7f, 0x5c, 0x39, 0x9e, 0x7b, 0xe6, 0xe7, 0xdc, 0x8b,
+ 0x8d, 0xa3, 0x0e, 0x90, 0x4c, 0xf0, 0x59, 0x17, 0x5e, 0x38, 0x68, 0x23,
+ 0x27, 0x2e, 0xc6, 0xc6, 0xc1, 0x12, 0xbc, 0x30, 0xa8, 0xa2, 0xe3, 0x60,
+ 0xb3, 0x42, 0xbe, 0xaf, 0xce, 0x20, 0xef, 0xed, 0x18, 0x0d, 0xb0, 0xdd,
+ 0xb8, 0x72, 0x2e, 0xdd, 0x30, 0x33, 0xdb, 0x4f, 0x36, 0xf7, 0x93, 0xe5,
+ 0x31, 0x86, 0xc2, 0x38, 0x8d, 0x5c, 0x72, 0xdf, 0xe6, 0xd7, 0x18, 0x21,
+ 0x3e, 0x9c, 0xb6, 0x53, 0xc7, 0x24, 0x1e, 0x15, 0xbb, 0x4f, 0x6d, 0xbe,
+ 0x12, 0x95, 0xb9, 0x1a, 0xca, 0x91, 0x46, 0x9b, 0xc5, 0xb1, 0x5f, 0x67,
+ 0x5c, 0xb8, 0x82, 0xb6, 0xf2, 0x10, 0xe5, 0xb1, 0x9a, 0xf2, 0x68, 0xa6,
+ 0x3c, 0x5a, 0x39, 0xdf, 0x97, 0xa3, 0x82, 0x93, 0xde, 0x40, 0x44, 0xd1,
+ 0xb0, 0x2a, 0x23, 0x7d, 0x58, 0xe3, 0xb8, 0x1c, 0xe1, 0xbf, 0xd9, 0xbc,
+ 0x35, 0x7a, 0xab, 0x5c, 0xa0, 0x96, 0x87, 0xc5, 0xaf, 0x89, 0x6c, 0x02,
+ 0xe4, 0x50, 0xe3, 0xca, 0xa8, 0x15, 0x23, 0xef, 0xdb, 0xec, 0x49, 0xe5,
+ 0x6d, 0xa7, 0x44, 0xec, 0x53, 0xf2, 0xe1, 0xca, 0x3e, 0x72, 0xb5, 0x1a,
+ 0x2d, 0x7b, 0xff, 0xde, 0x94, 0x7c, 0xa7, 0x36, 0x2f, 0xb4, 0xf0, 0xe6,
+ 0x6f, 0x36, 0x37, 0x5d, 0x5f, 0xd3, 0xb8, 0xf2, 0x36, 0xd7, 0x73, 0x81,
+ 0x7a, 0x7a, 0x92, 0x73, 0x2d, 0x92, 0xbd, 0x4b, 0x73, 0xef, 0x38, 0xd7,
+ 0x4f, 0x87, 0x8b, 0xf1, 0x5e, 0xaa, 0x84, 0x1f, 0xca, 0x76, 0x98, 0x7b,
+ 0x97, 0x6e, 0x56, 0x4e, 0x59, 0xf2, 0x0d, 0xe0, 0x5d, 0x8e, 0x7d, 0xec,
+ 0x7a, 0x1f, 0x59, 0xde, 0x96, 0xad, 0xc3, 0xe5, 0xed, 0x57, 0xf0, 0x54,
+ 0xd6, 0x66, 0x28, 0x91, 0xeb, 0xb5, 0x34, 0xc9, 0x8b, 0x49, 0x7d, 0x91,
+ 0x3e, 0x46, 0x95, 0xfc, 0xa8, 0x42, 0x8c, 0xa1, 0xfe, 0xa9, 0xcb, 0x3c,
+ 0x0e, 0xe2, 0xe2, 0x3a, 0x7c, 0xc1, 0x38, 0x21, 0x42, 0x8b, 0x92, 0xb5,
+ 0x48, 0x8e, 0xb4, 0x50, 0x62, 0x42, 0xeb, 0xdf, 0x20, 0xb9, 0xd4, 0x6b,
+ 0xe4, 0xb9, 0x54, 0x21, 0x74, 0xa7, 0xbf, 0x30, 0x27, 0xaa, 0xe8, 0x57,
+ 0xb5, 0xeb, 0x79, 0x37, 0xae, 0xd9, 0x34, 0x87, 0x78, 0xaf, 0x27, 0x8d,
+ 0xdc, 0x3f, 0x72, 0x2f, 0xf2, 0xdd, 0x27, 0xb5, 0xdf, 0x99, 0x4f, 0xdc,
+ 0xd4, 0x36, 0x8f, 0xe5, 0xf9, 0x78, 0x5f, 0xb0, 0xbc, 0x14, 0x3d, 0xbb,
+ 0xbd, 0xc9, 0x14, 0xaa, 0x90, 0xd4, 0x6c, 0x73, 0x0b, 0x38, 0x3b, 0x3b,
+ 0xbc, 0xbd, 0xcd, 0xb0, 0xf2, 0x20, 0x9e, 0x14, 0xfe, 0x61, 0xa6, 0xd8,
+ 0x8c, 0x53, 0x6b, 0xf0, 0x54, 0xd8, 0x2a, 0x65, 0xee, 0xd6, 0xac, 0xec,
+ 0xfd, 0x45, 0x58, 0x17, 0x2c, 0x42, 0xaa, 0x95, 0x18, 0xd7, 0x6f, 0xb4,
+ 0xb0, 0x7b, 0xf2, 0xa7, 0xc0, 0x8b, 0xdf, 0xf4, 0x0b, 0x1f, 0x03, 0x0a,
+ 0x63, 0x1c, 0x13, 0x39, 0x0c, 0xec, 0xf7, 0x1a, 0x36, 0x9b, 0x3c, 0xff,
+ 0x99, 0x69, 0xb4, 0xc9, 0xb3, 0xd2, 0x47, 0xad, 0xc5, 0x1b, 0x6f, 0xd6,
+ 0x7b, 0x0f, 0xe5, 0xf4, 0xaf, 0x33, 0x25, 0xe7, 0xa8, 0xd6, 0x31, 0xee,
+ 0xe9, 0x97, 0x9a, 0x4d, 0x04, 0xbb, 0xaa, 0x7d, 0x1d, 0xba, 0xad, 0x18,
+ 0x67, 0xbf, 0xf6, 0xdf, 0x88, 0xe9, 0x05, 0x70, 0xd5, 0x01, 0xf7, 0xc5,
+ 0x6d, 0xb0, 0xd5, 0x11, 0xab, 0xa9, 0xd3, 0xcd, 0xa3, 0x36, 0xcc, 0xeb,
+ 0x57, 0xf0, 0x58, 0xd2, 0x86, 0x07, 0x92, 0x76, 0xac, 0x4a, 0xe2, 0xfb,
+ 0xf3, 0x80, 0xc9, 0x1a, 0xf8, 0xdb, 0xa7, 0xe8, 0x9a, 0xcb, 0xe1, 0x6f,
+ 0x8d, 0x91, 0x17, 0xac, 0x62, 0x2c, 0xba, 0x72, 0x94, 0x38, 0xc8, 0xb6,
+ 0xce, 0x3e, 0xea, 0x66, 0x9f, 0x1d, 0x35, 0x7d, 0xb8, 0xb3, 0x10, 0xa0,
+ 0x75, 0xfb, 0xa7, 0xe8, 0x97, 0x2a, 0x1d, 0xf0, 0xd3, 0xaf, 0xf8, 0x3b,
+ 0x6b, 0xec, 0x0c, 0xc4, 0xea, 0xfe, 0xd5, 0xe2, 0xb4, 0x0f, 0xd2, 0x5e,
+ 0xe6, 0xf5, 0xb3, 0x7d, 0x9d, 0x0d, 0x2a, 0xf5, 0xf9, 0x93, 0x3f, 0x96,
+ 0x7c, 0xaf, 0xdc, 0x93, 0xba, 0xab, 0x82, 0xf2, 0x7e, 0x3b, 0xf1, 0xf0,
+ 0x8c, 0x79, 0xb6, 0xda, 0xaa, 0x41, 0xe1, 0x31, 0xce, 0xcd, 0xcd, 0xdf,
+ 0xd4, 0x3a, 0x17, 0x16, 0xdc, 0xa3, 0x62, 0xed, 0xa0, 0xb4, 0x85, 0xd5,
+ 0x8f, 0x93, 0xb8, 0x53, 0xa0, 0x4d, 0x98, 0x07, 0xab, 0xa4, 0xad, 0x8d,
+ 0x6b, 0xb4, 0xa3, 0xa4, 0x1f, 0x58, 0x19, 0xc7, 0xc3, 0xa5, 0xf0, 0x47,
+ 0x64, 0x8e, 0xf5, 0x8b, 0x1d, 0x7c, 0xb6, 0x14, 0x2d, 0xa3, 0xd9, 0xe7,
+ 0x56, 0x8c, 0xbe, 0x37, 0x33, 0x9b, 0xfb, 0xfe, 0xc3, 0x75, 0xe3, 0x2d,
+ 0x8d, 0x7e, 0xac, 0x4b, 0x52, 0xe7, 0x6c, 0x1e, 0x0c, 0xe6, 0x72, 0xd0,
+ 0x4f, 0xa4, 0xbc, 0xd3, 0xea, 0xba, 0x7f, 0x5b, 0x9a, 0xab, 0xf9, 0xd2,
+ 0x8e, 0xa7, 0xd8, 0x8f, 0x65, 0xc3, 0x18, 0x1c, 0x33, 0x11, 0xd5, 0x4d,
+ 0x64, 0xf8, 0x79, 0x43, 0x87, 0x51, 0x42, 0x1b, 0x7f, 0x2a, 0x26, 0x98,
+ 0x97, 0xd5, 0xa4, 0x1f, 0x24, 0x02, 0xca, 0x86, 0x18, 0x70, 0x84, 0xf1,
+ 0xe3, 0x21, 0x7e, 0x86, 0x13, 0x5c, 0x03, 0xe7, 0x6d, 0x23, 0x6e, 0x6c,
+ 0x4b, 0x01, 0x43, 0x09, 0x44, 0xf6, 0x2f, 0x96, 0x58, 0xa6, 0x84, 0xe3,
+ 0x01, 0xe3, 0x6c, 0x93, 0xe6, 0xe7, 0x20, 0x3f, 0x63, 0xdc, 0x53, 0x8e,
+ 0x87, 0x00, 0xf1, 0x30, 0x92, 0xd1, 0x60, 0x64, 0x02, 0x98, 0xa0, 0x6d,
+ 0x5d, 0x1b, 0x56, 0x51, 0x76, 0xa8, 0x12, 0x1f, 0x8d, 0x64, 0x63, 0xa5,
+ 0x75, 0x19, 0xa9, 0x5d, 0xcb, 0xda, 0xa4, 0x7e, 0x2d, 0xb6, 0x54, 0x84,
+ 0x43, 0xc9, 0x4a, 0xab, 0x86, 0xfd, 0x8e, 0xce, 0x7e, 0x55, 0xa9, 0xb1,
+ 0xb6, 0xe2, 0x70, 0xd4, 0xe7, 0xe9, 0xa5, 0xbe, 0x1b, 0x0e, 0xb1, 0xaf,
+ 0x46, 0x1c, 0x89, 0xe6, 0x6b, 0x67, 0xbe, 0x96, 0x9f, 0x49, 0x8e, 0xc8,
+ 0x59, 0x49, 0xd9, 0xca, 0xbd, 0xbc, 0xdf, 0x95, 0xf5, 0x4a, 0x0e, 0x3f,
+ 0xcf, 0x71, 0xa6, 0xff, 0x7e, 0x8a, 0xe3, 0x05, 0x69, 0x07, 0xde, 0xde,
+ 0x14, 0x74, 0xcb, 0x97, 0x8e, 0xd4, 0x7b, 0x93, 0x06, 0x64, 0x6f, 0x1b,
+ 0x39, 0x87, 0xd7, 0xa8, 0xf7, 0x01, 0xca, 0xf9, 0x2f, 0xe8, 0x23, 0x5c,
+ 0x8c, 0x65, 0x2b, 0xb0, 0xab, 0xaf, 0x12, 0x3b, 0xfb, 0x0c, 0xf4, 0x2c,
+ 0x6e, 0xc3, 0xa9, 0xa8, 0x89, 0x75, 0x21, 0x13, 0x2b, 0x19, 0x23, 0xfc,
+ 0x00, 0x0d, 0x4d, 0x87, 0xf1, 0x20, 0x63, 0x65, 0x95, 0xf2, 0xf8, 0x16,
+ 0xde, 0xde, 0xed, 0xc0, 0x7a, 0xfd, 0x8f, 0x68, 0xbf, 0xa6, 0xf9, 0xab,
+ 0x45, 0xb5, 0x18, 0x4c, 0x34, 0xa8, 0xdd, 0x9c, 0x5f, 0xa4, 0x8d, 0xfb,
+ 0x14, 0x74, 0xe0, 0x69, 0xfd, 0xfb, 0x6c, 0xeb, 0xb6, 0x39, 0x34, 0xb9,
+ 0x96, 0xba, 0x96, 0xec, 0xa3, 0x41, 0xdd, 0xca, 0xfb, 0xac, 0x6c, 0xad,
+ 0x74, 0x7d, 0xa3, 0xe4, 0x44, 0x4a, 0x71, 0x92, 0x32, 0x3b, 0x96, 0x8c,
+ 0xd0, 0x55, 0x43, 0x79, 0xba, 0xb1, 0x0b, 0x8f, 0x93, 0x9b, 0xbc, 0x4d,
+ 0xd2, 0x70, 0x6f, 0x5c, 0x41, 0x53, 0xbd, 0x8e, 0xf3, 0xe9, 0x6f, 0xe1,
+ 0xcd, 0xe1, 0x30, 0xde, 0x20, 0x07, 0x58, 0xf0, 0x97, 0xc2, 0xe9, 0x3d,
+ 0x38, 0x9b, 0x0e, 0xe3, 0x4c, 0xd4, 0xdb, 0xfa, 0xbc, 0x52, 0x8b, 0x9f,
+ 0x11, 0xd3, 0xee, 0x8e, 0x03, 0xef, 0xb1, 0x1f, 0x7f, 0xdc, 0x81, 0x4b,
+ 0x69, 0x15, 0x87, 0xb9, 0x37, 0x8e, 0xd0, 0x02, 0x18, 0x6d, 0x1e, 0x1c,
+ 0x1c, 0x78, 0x00, 0x13, 0xa9, 0x07, 0x70, 0x22, 0xf9, 0xb6, 0xe9, 0xd2,
+ 0xa4, 0x06, 0xe6, 0xc2, 0x25, 0x62, 0xea, 0x24, 0xa5, 0x51, 0x7a, 0x4f,
+ 0x2b, 0x71, 0x51, 0x33, 0x44, 0xee, 0x6f, 0xf2, 0xb7, 0x7b, 0xe3, 0x4d,
+ 0xd8, 0x9f, 0xa1, 0x48, 0x13, 0x3a, 0x12, 0x31, 0x19, 0xab, 0x11, 0x31,
+ 0x72, 0xc8, 0x5d, 0x7d, 0xe2, 0x37, 0xef, 0xc6, 0xca, 0x0a, 0x28, 0x2d,
+ 0x75, 0x63, 0xb9, 0x75, 0x34, 0x4d, 0xab, 0x6d, 0x4a, 0xbc, 0x49, 0xb9,
+ 0xf2, 0xb9, 0x1f, 0x26, 0x28, 0xf7, 0x04, 0x65, 0x7b, 0x7d, 0x3f, 0x9a,
+ 0xb8, 0x1f, 0xdf, 0xc2, 0xf9, 0xdd, 0x6d, 0x78, 0x93, 0x58, 0x57, 0xbe,
+ 0xc8, 0xd7, 0xe9, 0xb4, 0x35, 0xb0, 0xef, 0xb4, 0x99, 0xaa, 0x16, 0x99,
+ 0xb6, 0xe1, 0x17, 0x51, 0x91, 0x69, 0x9a, 0xd8, 0xe7, 0xf3, 0xf8, 0xed,
+ 0x23, 0x55, 0xd4, 0x65, 0x5b, 0x77, 0x30, 0x5b, 0xaf, 0x2b, 0xbd, 0xc7,
+ 0x85, 0xcb, 0xd6, 0xdc, 0x64, 0xae, 0x5f, 0x35, 0xbf, 0x5f, 0x98, 0x2b,
+ 0xab, 0x65, 0x7e, 0x86, 0xc9, 0x98, 0x3a, 0xc0, 0x78, 0x91, 0xb6, 0x13,
+ 0x80, 0xe4, 0x9c, 0xeb, 0xe3, 0x5d, 0xb0, 0x87, 0x4a, 0x0d, 0x35, 0xec,
+ 0x9d, 0xea, 0xc0, 0x9b, 0xb8, 0x42, 0x8e, 0x72, 0x57, 0x5c, 0x63, 0x7c,
+ 0x7b, 0x81, 0x63, 0xfd, 0x0b, 0x2e, 0xf2, 0xda, 0x17, 0xcf, 0xda, 0x5a,
+ 0x77, 0x63, 0x1b, 0xee, 0x4b, 0xcb, 0xfa, 0xfe, 0x0b, 0x07, 0xd2, 0x11,
+ 0x49, 0xcb, 0x3a, 0x63, 0xb4, 0x0b, 0x59, 0x67, 0xe5, 0x7f, 0xb0, 0xce,
+ 0x23, 0xec, 0xaf, 0x96, 0x76, 0x94, 0xf7, 0x1b, 0x65, 0x38, 0x98, 0x54,
+ 0x71, 0x52, 0x2f, 0xc5, 0x05, 0x55, 0xf2, 0xf5, 0xd9, 0x5a, 0x66, 0x33,
+ 0xe3, 0xd3, 0x21, 0x7e, 0x9e, 0x62, 0x0c, 0x75, 0x5a, 0x77, 0xe0, 0x84,
+ 0x5e, 0x4b, 0x9c, 0xbf, 0x55, 0x87, 0xe5, 0x1e, 0x03, 0x83, 0x8a, 0x4a,
+ 0x9c, 0x91, 0x9c, 0xaa, 0x75, 0x5f, 0xce, 0x16, 0xb8, 0x20, 0x39, 0x8d,
+ 0x82, 0xd8, 0x6f, 0xcd, 0xcb, 0x16, 0xce, 0xdc, 0x3a, 0xbf, 0x5b, 0xfb,
+ 0x21, 0x55, 0xd0, 0xde, 0x33, 0x9f, 0xad, 0xce, 0xf9, 0x2d, 0x65, 0x47,
+ 0x55, 0x16, 0x2b, 0xc4, 0x87, 0x8d, 0xe7, 0x71, 0x83, 0x7c, 0x7c, 0xdf,
+ 0xa3, 0xf4, 0x41, 0xf4, 0xcf, 0xcd, 0xdf, 0xdb, 0xaa, 0x49, 0x9c, 0x97,
+ 0x7a, 0x74, 0x99, 0x56, 0x00, 0xbb, 0xe5, 0x67, 0x0f, 0x6f, 0xce, 0xf2,
+ 0xf9, 0xf4, 0xe6, 0x6c, 0x8c, 0x7a, 0x74, 0xf3, 0x5d, 0xd6, 0xf7, 0x8f,
+ 0x36, 0xfb, 0x52, 0x37, 0x7c, 0x55, 0x96, 0x2f, 0x5b, 0x67, 0x6d, 0xd0,
+ 0xab, 0x1b, 0xca, 0x8a, 0x46, 0xf1, 0xd7, 0x79, 0x8e, 0x22, 0x6d, 0x02,
+ 0xca, 0x89, 0xa8, 0x61, 0xba, 0xb5, 0x62, 0xfa, 0x7a, 0x28, 0x63, 0x8c,
+ 0xc5, 0xa6, 0xac, 0xba, 0xa7, 0x86, 0x37, 0xd2, 0x12, 0x13, 0x83, 0xfa,
+ 0xfb, 0xbf, 0xb1, 0x6b, 0x37, 0xda, 0x8b, 0x16, 0x93, 0xb3, 0xd3, 0xcf,
+ 0x3d, 0x1b, 0x72, 0xe0, 0xfd, 0x74, 0x76, 0x3d, 0xef, 0x0d, 0x97, 0xe0,
+ 0xdd, 0x94, 0xf8, 0x6b, 0xa8, 0x85, 0xec, 0xf7, 0x64, 0x5a, 0x63, 0x6c,
+ 0x2a, 0xe3, 0xb6, 0x61, 0xdb, 0x98, 0x03, 0xfb, 0xa3, 0x1a, 0x62, 0x89,
+ 0x9f, 0x9a, 0x45, 0x9a, 0x6f, 0xc2, 0x6f, 0x77, 0x60, 0x5f, 0x7a, 0x12,
+ 0x63, 0x7d, 0x1f, 0x9b, 0x76, 0xad, 0x0b, 0x1f, 0x85, 0x26, 0xc9, 0xeb,
+ 0xa4, 0xfe, 0xa9, 0x63, 0xd7, 0x80, 0xc6, 0x58, 0xda, 0x86, 0x9d, 0x8b,
+ 0x5b, 0xb0, 0x6b, 0xac, 0x19, 0xc6, 0x21, 0x0f, 0x76, 0x92, 0xf0, 0x4d,
+ 0x0c, 0x4f, 0xe2, 0x54, 0x52, 0x6b, 0x2a, 0x52, 0x26, 0x71, 0x92, 0xe3,
+ 0x6c, 0x4d, 0xbc, 0x05, 0x83, 0x7d, 0x6c, 0x4b, 0x4a, 0x8e, 0x57, 0xc6,
+ 0x99, 0x44, 0x77, 0xea, 0x76, 0x35, 0x8f, 0x36, 0xec, 0x48, 0x6c, 0x69,
+ 0xcf, 0xd6, 0x3d, 0x88, 0xab, 0x69, 0x4d, 0xe9, 0xe5, 0x1e, 0x1d, 0x4e,
+ 0xe7, 0x6b, 0x20, 0x82, 0xa1, 0x59, 0x3c, 0xdc, 0x96, 0xd6, 0xd1, 0x3b,
+ 0xd0, 0xc2, 0xf6, 0x1a, 0xba, 0x13, 0x52, 0x3f, 0xf6, 0x71, 0x3c, 0x13,
+ 0xef, 0xe9, 0x5e, 0xf7, 0x5d, 0xfc, 0x1e, 0xd1, 0x3b, 0xb1, 0x81, 0xfd,
+ 0x08, 0xe7, 0xd2, 0x14, 0x6f, 0x93, 0x01, 0x3b, 0x7e, 0xa5, 0xdb, 0x61,
+ 0x54, 0xd9, 0x71, 0x44, 0x2f, 0x23, 0x3f, 0xb7, 0xa3, 0x21, 0x44, 0xdf,
+ 0x9c, 0xf3, 0xd5, 0x1f, 0x26, 0x15, 0x3c, 0x40, 0x2c, 0x3d, 0x16, 0x6a,
+ 0x68, 0x5f, 0x2e, 0x6c, 0xf7, 0x80, 0x82, 0x2b, 0xda, 0x35, 0xd3, 0xa0,
+ 0xbf, 0x72, 0xf9, 0xf3, 0x7b, 0xf3, 0x6b, 0x33, 0x5b, 0x03, 0xfe, 0xc2,
+ 0xcc, 0x3f, 0x37, 0xc5, 0xf9, 0x3d, 0xc6, 0xe7, 0xee, 0x5a, 0xd4, 0xd0,
+ 0x29, 0xcf, 0xb9, 0x89, 0xe3, 0xf2, 0x9c, 0xe4, 0xf6, 0x6f, 0x3c, 0xa7,
+ 0x63, 0xdb, 0x40, 0xc4, 0x9a, 0xef, 0xf6, 0x04, 0x16, 0x3a, 0x20, 0x76,
+ 0xd4, 0xa0, 0x5e, 0x02, 0xba, 0x26, 0xf5, 0x19, 0xe4, 0x37, 0xfe, 0xc0,
+ 0x53, 0x10, 0x39, 0x49, 0xbc, 0xf9, 0x16, 0x76, 0x46, 0x87, 0xc1, 0x98,
+ 0x93, 0xf8, 0xe6, 0x5f, 0x3b, 0x84, 0x14, 0x9e, 0x4b, 0xa7, 0xf0, 0xbc,
+ 0x70, 0x6c, 0x2b, 0xc7, 0x96, 0xc6, 0x77, 0xa2, 0x6f, 0x21, 0x66, 0xc5,
+ 0x55, 0x87, 0xf1, 0x44, 0xf4, 0xdd, 0x6a, 0xc9, 0x65, 0x6e, 0x4d, 0x2c,
+ 0x65, 0xff, 0x22, 0x53, 0x6f, 0xab, 0x81, 0x2f, 0xd9, 0xff, 0x52, 0x6c,
+ 0x19, 0x92, 0x9c, 0x90, 0x89, 0xd7, 0xc9, 0xa9, 0xae, 0x50, 0x8f, 0x5a,
+ 0x1a, 0xa5, 0xff, 0x71, 0x45, 0xb3, 0x7c, 0x57, 0x1b, 0xf7, 0x78, 0x16,
+ 0xdc, 0x94, 0x73, 0x59, 0x46, 0x53, 0xee, 0x8a, 0xc9, 0x9e, 0x3b, 0x60,
+ 0xcb, 0x78, 0xf0, 0x18, 0x79, 0x49, 0xe1, 0xc8, 0x8f, 0x14, 0xf1, 0x5f,
+ 0x35, 0xe4, 0xa2, 0xee, 0x03, 0x1e, 0x65, 0xc1, 0x1e, 0x17, 0x1e, 0x88,
+ 0x91, 0xa3, 0xc6, 0x9a, 0xb1, 0x65, 0xaf, 0xc6, 0x36, 0x5e, 0xfd, 0x1c,
+ 0xe3, 0xd6, 0x93, 0xf0, 0x79, 0x86, 0xc8, 0xa5, 0xdc, 0xc4, 0x60, 0xc7,
+ 0x48, 0x39, 0x4a, 0xc8, 0xb3, 0xa5, 0xdc, 0x5c, 0x3a, 0xe2, 0x46, 0x0d,
+ 0xfd, 0x99, 0x3b, 0x73, 0x1e, 0x63, 0x7b, 0xa0, 0x96, 0x84, 0x3f, 0x37,
+ 0x0b, 0x35, 0xa9, 0x57, 0x06, 0x50, 0x9e, 0xd9, 0x84, 0x74, 0x2c, 0x88,
+ 0x52, 0xf2, 0xfb, 0x06, 0x8e, 0x77, 0x7f, 0x4c, 0x63, 0x3f, 0x59, 0x6e,
+ 0xb3, 0x9c, 0xcf, 0xf4, 0x26, 0xbc, 0x6b, 0xa5, 0xde, 0x78, 0x45, 0x7f,
+ 0x0d, 0x45, 0x7d, 0x37, 0xce, 0x9c, 0x69, 0x21, 0xcc, 0x21, 0xf7, 0x68,
+ 0x7d, 0x1a, 0xd9, 0xf3, 0x67, 0x2b, 0x72, 0xeb, 0x09, 0xca, 0x7a, 0x9c,
+ 0x6d, 0xd4, 0x83, 0xd9, 0x98, 0xc1, 0xf5, 0x5c, 0xa4, 0xde, 0xdc, 0xcb,
+ 0xb9, 0x5e, 0x63, 0xec, 0xd0, 0xc9, 0xb5, 0xbc, 0x3f, 0xfc, 0x23, 0xa5,
+ 0x86, 0x6b, 0x99, 0x22, 0x57, 0xfd, 0x38, 0xe5, 0x51, 0x7c, 0x5c, 0xcb,
+ 0x77, 0x79, 0xff, 0x3b, 0x5c, 0xcb, 0xd6, 0xbd, 0xde, 0xd6, 0xe3, 0x8a,
+ 0xb7, 0x7d, 0x8d, 0xe2, 0x53, 0xb7, 0x2a, 0xa5, 0xb8, 0x38, 0x5c, 0x8e,
+ 0x4b, 0xf4, 0xbd, 0xd7, 0x86, 0x2b, 0x71, 0x79, 0xb8, 0x8a, 0x36, 0xa2,
+ 0xb1, 0x0f, 0xd3, 0x2c, 0xd3, 0xdc, 0x98, 0x4a, 0x3f, 0x8f, 0x19, 0xb1,
+ 0x5a, 0x7c, 0x9c, 0xde, 0x80, 0xf2, 0x98, 0xc4, 0x00, 0x1e, 0x7c, 0xc4,
+ 0xfb, 0x1f, 0xa6, 0x47, 0x51, 0xbc, 0xe7, 0x73, 0xb6, 0x31, 0xcd, 0xfb,
+ 0xb9, 0xbe, 0xcb, 0xe9, 0x0e, 0x94, 0xee, 0xd9, 0x08, 0xc7, 0x1e, 0xb3,
+ 0x6b, 0x4b, 0x08, 0x3f, 0xb3, 0x73, 0x2d, 0xdd, 0xba, 0x77, 0xe2, 0x2e,
+ 0x7b, 0x90, 0x7d, 0x8c, 0x2b, 0x0b, 0x32, 0x1b, 0x51, 0xbe, 0xc7, 0x83,
+ 0x67, 0x29, 0xc3, 0x51, 0x68, 0x81, 0x35, 0xca, 0x46, 0x14, 0x8c, 0x64,
+ 0xd7, 0xbf, 0x2e, 0x93, 0xb5, 0x8b, 0xfb, 0x1b, 0xa7, 0xc7, 0x32, 0x6e,
+ 0x8b, 0x77, 0x4f, 0xa6, 0x4b, 0x70, 0x3a, 0x25, 0xf2, 0x81, 0xea, 0x08,
+ 0x8f, 0xa2, 0x70, 0x0f, 0x31, 0x71, 0x58, 0xb7, 0xf8, 0x82, 0xd8, 0xc4,
+ 0x70, 0xfa, 0x76, 0x36, 0x15, 0xc4, 0xce, 0x44, 0x0d, 0xed, 0xa9, 0x16,
+ 0x2b, 0xf7, 0x48, 0x8d, 0x79, 0xe2, 0x5e, 0x17, 0xb5, 0xe8, 0x50, 0xfa,
+ 0x56, 0x7b, 0x6a, 0xa4, 0x6e, 0x0a, 0xb6, 0x9a, 0x98, 0xd4, 0xb3, 0x78,
+ 0x73, 0xcc, 0xaa, 0x61, 0x8b, 0x4d, 0xb6, 0x62, 0xcb, 0x00, 0xda, 0xf7,
+ 0x37, 0x8a, 0x4d, 0x3a, 0x31, 0x44, 0xbe, 0x7f, 0x91, 0xb1, 0xc3, 0x0c,
+ 0xed, 0x73, 0x62, 0x42, 0x01, 0x06, 0x87, 0x5d, 0xf8, 0xf1, 0xb0, 0x07,
+ 0xee, 0x58, 0x31, 0xc6, 0x29, 0xe3, 0x31, 0x72, 0x9c, 0x8f, 0x18, 0x65,
+ 0x8f, 0xd2, 0xa7, 0x7e, 0x18, 0xad, 0x42, 0x26, 0x5d, 0x8b, 0xab, 0xc4,
+ 0x94, 0x34, 0xf7, 0xe3, 0x83, 0x68, 0x00, 0x2f, 0xa7, 0x83, 0x78, 0x3f,
+ 0x2a, 0xd8, 0x13, 0xc4, 0x11, 0xca, 0xaf, 0x28, 0xe6, 0x66, 0xbf, 0x82,
+ 0x43, 0x1e, 0x38, 0x63, 0x9a, 0x67, 0x28, 0xa7, 0x0b, 0x8e, 0x4c, 0x2b,
+ 0xed, 0x46, 0xce, 0x44, 0x88, 0x1f, 0x70, 0xe8, 0x43, 0x8c, 0xb9, 0x07,
+ 0x83, 0xf9, 0xfc, 0xaf, 0xd7, 0x3d, 0x81, 0x99, 0xb4, 0x9d, 0x2f, 0x4d,
+ 0x55, 0x93, 0x98, 0x2a, 0x19, 0xba, 0x12, 0xd5, 0x24, 0x17, 0x48, 0x6c,
+ 0x37, 0x14, 0xe7, 0x62, 0x72, 0x89, 0xaa, 0xad, 0x92, 0x17, 0xe6, 0xfc,
+ 0xe5, 0x6c, 0x99, 0xc9, 0x76, 0x57, 0x31, 0xff, 0xc0, 0xd6, 0x59, 0xb9,
+ 0x1c, 0x93, 0x7a, 0x83, 0xf7, 0xe5, 0x31, 0x5e, 0xe2, 0xb5, 0xdd, 0xa1,
+ 0xd7, 0xa2, 0x7f, 0x3f, 0x4b, 0xea, 0x71, 0xc7, 0x11, 0xa4, 0x4c, 0x6e,
+ 0x17, 0x0f, 0x98, 0x78, 0x93, 0x18, 0x72, 0x39, 0x29, 0xbc, 0x48, 0xf8,
+ 0x50, 0x17, 0x7d, 0x4f, 0x19, 0xf9, 0x80, 0x86, 0x6d, 0xe4, 0xeb, 0xbe,
+ 0xf8, 0x04, 0xe3, 0x91, 0xaf, 0x93, 0x93, 0x95, 0xb3, 0x9b, 0x1f, 0x70,
+ 0xbc, 0x56, 0xec, 0xa4, 0x2d, 0x16, 0x69, 0x77, 0x61, 0x25, 0xf9, 0x8e,
+ 0x43, 0xa3, 0xcb, 0x78, 0x58, 0xfc, 0x86, 0xe4, 0x70, 0x54, 0xa9, 0x95,
+ 0xad, 0x7d, 0x1d, 0xf7, 0xa2, 0xbd, 0xda, 0x05, 0xa9, 0x6f, 0xbd, 0x81,
+ 0x25, 0x48, 0x3d, 0x2a, 0xbe, 0x93, 0x1c, 0x39, 0xac, 0x19, 0xe7, 0x31,
+ 0xcf, 0x62, 0xdd, 0xc5, 0x61, 0x99, 0x4f, 0x15, 0x65, 0xaf, 0xe2, 0x1d,
+ 0xca, 0xf5, 0x52, 0xd4, 0x37, 0x75, 0x1f, 0x1a, 0x4e, 0x5d, 0xb2, 0x4b,
+ 0xed, 0x4f, 0xda, 0x07, 0xa1, 0xb1, 0xbf, 0x4f, 0xa3, 0x21, 0xf4, 0xa9,
+ 0x72, 0x2d, 0xfc, 0xb0, 0x15, 0xdd, 0x43, 0x32, 0x07, 0xd3, 0xac, 0x24,
+ 0x1e, 0x3e, 0x6c, 0x8d, 0x2f, 0x63, 0xdf, 0x1a, 0x5b, 0x78, 0x19, 0x49,
+ 0xe7, 0xe3, 0x8b, 0x49, 0x1c, 0x4e, 0x52, 0xfe, 0x8b, 0xdf, 0xa6, 0x1c,
+ 0x26, 0x31, 0x9c, 0xd2, 0xc8, 0x1d, 0x4b, 0xe0, 0xa9, 0x0e, 0x62, 0x17,
+ 0xfd, 0x75, 0x8c, 0xed, 0xd3, 0xb1, 0x12, 0x18, 0xd5, 0xd9, 0x31, 0xbf,
+ 0x1e, 0xbf, 0x6a, 0x4e, 0x3c, 0x64, 0xc5, 0xa9, 0xbc, 0xfe, 0x1d, 0x9f,
+ 0x99, 0x2d, 0xc7, 0x32, 0xb1, 0x3e, 0x76, 0xd9, 0x9c, 0x68, 0x9d, 0xfe,
+ 0x7b, 0x85, 0x75, 0xa6, 0x2a, 0x62, 0xab, 0xe6, 0x77, 0x56, 0x2e, 0xdd,
+ 0x94, 0xcb, 0x0c, 0xed, 0x2d, 0xf3, 0x41, 0x6b, 0x5e, 0xef, 0xcd, 0x12,
+ 0x2e, 0x5f, 0x17, 0xf7, 0xcc, 0x46, 0x71, 0x15, 0xdb, 0x10, 0x43, 0xc3,
+ 0x5a, 0xd3, 0x29, 0xfc, 0x8b, 0x79, 0xe1, 0xa6, 0x7e, 0x66, 0xf2, 0x9e,
+ 0xf8, 0x9e, 0x0b, 0xb9, 0x9c, 0x8f, 0x3b, 0xc7, 0xf7, 0x27, 0x71, 0x3c,
+ 0x29, 0xd8, 0xef, 0xc1, 0x13, 0x92, 0x9b, 0x52, 0xbd, 0xbd, 0x06, 0x26,
+ 0xc8, 0xf1, 0xde, 0xa6, 0xec, 0x25, 0xff, 0x38, 0x41, 0x9e, 0x37, 0xdd,
+ 0x37, 0x45, 0x90, 0xaa, 0x92, 0x1a, 0x8c, 0xe0, 0xe7, 0x24, 0xb6, 0x27,
+ 0x7f, 0x4a, 0x1c, 0xfb, 0x98, 0xbc, 0xa7, 0x8b, 0x9c, 0x7a, 0x12, 0x5b,
+ 0x52, 0xcd, 0x78, 0x69, 0x6f, 0x0b, 0x71, 0x45, 0xb0, 0xd1, 0x77, 0xea,
+ 0xa2, 0xbd, 0x19, 0xfb, 0x0f, 0xa5, 0x91, 0x1a, 0x11, 0x7f, 0x28, 0x3e,
+ 0x57, 0x7c, 0xa1, 0x86, 0x68, 0xe2, 0x24, 0x0c, 0x7e, 0xef, 0x4c, 0x6c,
+ 0x44, 0x64, 0xe4, 0x2d, 0xf2, 0xf8, 0x49, 0x2c, 0xef, 0xd3, 0xd6, 0x1e,
+ 0xc4, 0x24, 0x56, 0xd1, 0x57, 0x26, 0x13, 0x2d, 0xec, 0xbf, 0x19, 0x3d,
+ 0x7b, 0xbd, 0x56, 0xbe, 0x49, 0x62, 0xf8, 0x6d, 0x63, 0x11, 0x18, 0x43,
+ 0x72, 0x36, 0xc3, 0x85, 0x60, 0xdc, 0xa3, 0x7c, 0x48, 0x3e, 0xdc, 0x10,
+ 0xf7, 0x32, 0x06, 0xf3, 0x1a, 0xab, 0x14, 0x9f, 0xa7, 0xc0, 0x26, 0xb5,
+ 0xc0, 0x19, 0x38, 0xa5, 0x2b, 0x28, 0xba, 0x57, 0x41, 0x88, 0xbe, 0xca,
+ 0x33, 0x8b, 0x3e, 0x64, 0x48, 0x47, 0xcf, 0x00, 0xd7, 0x7b, 0x7d, 0xdf,
+ 0x64, 0xbf, 0x56, 0xb3, 0x3f, 0xd9, 0xbb, 0x16, 0xf4, 0x8c, 0xf9, 0x3a,
+ 0x4e, 0xc1, 0x6d, 0x71, 0xab, 0x9e, 0x81, 0xeb, 0x79, 0x81, 0xd2, 0x8f,
+ 0x1b, 0xbd, 0x81, 0x19, 0x8a, 0xb4, 0xdd, 0x4a, 0xcc, 0x9a, 0xde, 0xde,
+ 0x50, 0x92, 0x8b, 0xc9, 0x3f, 0x6d, 0x62, 0x17, 0xdd, 0x96, 0xbd, 0x88,
+ 0x2c, 0x7a, 0x92, 0x11, 0xea, 0xf4, 0x4f, 0xcc, 0x54, 0x6b, 0x2b, 0xe7,
+ 0xd9, 0x28, 0xb5, 0x31, 0x0b, 0x13, 0xce, 0x4a, 0x2e, 0xce, 0x29, 0x98,
+ 0xd0, 0xdd, 0xee, 0xa2, 0x3e, 0x15, 0x12, 0x97, 0x8a, 0x46, 0x5d, 0x70,
+ 0x1d, 0x2c, 0x41, 0xe1, 0xa0, 0xf0, 0x31, 0xc9, 0x41, 0xa8, 0xb0, 0x8f,
+ 0x96, 0xd2, 0x06, 0xb8, 0x87, 0xa3, 0xb4, 0xb1, 0xa8, 0x1b, 0xf3, 0x46,
+ 0xdd, 0xf8, 0x31, 0x31, 0xa0, 0x66, 0x54, 0xc3, 0x38, 0x31, 0xc0, 0x3d,
+ 0x1a, 0xc0, 0x58, 0x34, 0x88, 0x19, 0xa3, 0xe3, 0xca, 0x1b, 0xe9, 0x66,
+ 0xee, 0xb7, 0x8c, 0x23, 0x32, 0xcc, 0xef, 0xa9, 0xec, 0x67, 0x0b, 0xb1,
+ 0x4e, 0xf6, 0x36, 0x80, 0x1d, 0x03, 0x69, 0x2c, 0xdb, 0x63, 0xe2, 0x9f,
+ 0xf4, 0x06, 0x77, 0x91, 0x22, 0xb1, 0x80, 0x89, 0x34, 0xfd, 0xda, 0x0a,
+ 0xdd, 0xbb, 0x56, 0xce, 0x3b, 0xb7, 0x57, 0x99, 0x28, 0x08, 0x79, 0x75,
+ 0xa2, 0xfb, 0xda, 0x22, 0x45, 0x7c, 0x54, 0x83, 0x67, 0x03, 0xe6, 0x22,
+ 0x5b, 0x57, 0xbc, 0x0f, 0x1b, 0x54, 0x85, 0xb6, 0xd8, 0x82, 0x9d, 0x15,
+ 0x86, 0xeb, 0x4a, 0xa3, 0x69, 0xae, 0x0b, 0xd5, 0xcd, 0xb2, 0x72, 0xd0,
+ 0xb6, 0xf5, 0xfc, 0x6e, 0xe3, 0x9a, 0x65, 0xdd, 0x1d, 0x88, 0xed, 0x56,
+ 0x90, 0xf6, 0x77, 0x20, 0x3a, 0xdc, 0x21, 0xfc, 0x89, 0x78, 0xd0, 0x4b,
+ 0x3c, 0x30, 0xbb, 0x9e, 0x0e, 0x3d, 0x88, 0xcb, 0x96, 0xc7, 0x97, 0x67,
+ 0xbc, 0x01, 0x8f, 0x6d, 0xfa, 0x1e, 0xe8, 0xb3, 0x25, 0xcf, 0x21, 0x76,
+ 0xd3, 0xdc, 0x27, 0xbc, 0xd9, 0xdf, 0xdb, 0xc3, 0xbd, 0x7f, 0xe8, 0x80,
+ 0xf8, 0x17, 0xd3, 0xec, 0x25, 0x2f, 0x45, 0x85, 0xac, 0x41, 0x43, 0x3c,
+ 0x61, 0x7e, 0x5c, 0xa3, 0xf9, 0xa6, 0x76, 0xd1, 0x8f, 0x9f, 0xdf, 0xd3,
+ 0xb0, 0x61, 0x83, 0x70, 0x96, 0x45, 0x1a, 0x63, 0xe9, 0x34, 0xce, 0x8d,
+ 0xcc, 0x47, 0xea, 0x21, 0xae, 0x87, 0xfb, 0xe4, 0x8c, 0x7f, 0xc1, 0x38,
+ 0x43, 0xb0, 0x4f, 0x53, 0x0f, 0x13, 0xf7, 0x6c, 0xa3, 0x7e, 0x6c, 0xa9,
+ 0x80, 0x71, 0xa5, 0x51, 0xc6, 0xbf, 0x3e, 0x7f, 0xae, 0xb7, 0x19, 0xbb,
+ 0xf6, 0x0a, 0xaf, 0x10, 0xfe, 0xe5, 0x33, 0x3e, 0x40, 0x0b, 0x92, 0x63,
+ 0xd9, 0xb1, 0xa2, 0x89, 0x5b, 0xf5, 0x44, 0xf6, 0xfc, 0x24, 0x76, 0x50,
+ 0x27, 0x5d, 0xec, 0x9f, 0x3e, 0x85, 0xfd, 0x69, 0x81, 0x22, 0x19, 0x6f,
+ 0xf4, 0x27, 0xe6, 0xce, 0x6a, 0x91, 0x8d, 0xf4, 0xff, 0x9b, 0x6a, 0xc1,
+ 0x8b, 0x75, 0xa1, 0xaf, 0x5a, 0xeb, 0x15, 0x7e, 0x4b, 0xce, 0x3a, 0x3f,
+ 0x1f, 0x79, 0xe6, 0x76, 0xf3, 0xf9, 0x9c, 0xed, 0x64, 0x4e, 0x1d, 0xd8,
+ 0xb1, 0x1b, 0x46, 0xb1, 0xa6, 0x45, 0xe6, 0x2b, 0x1d, 0xe8, 0xa5, 0x7c,
+ 0xb7, 0x25, 0x3b, 0xb0, 0x9f, 0xf6, 0x3a, 0xa8, 0x1f, 0xab, 0xb1, 0xa1,
+ 0x7e, 0xca, 0x8e, 0x89, 0x7f, 0x94, 0x9a, 0xc5, 0x82, 0x45, 0x7e, 0xda,
+ 0x56, 0x07, 0xe2, 0xa9, 0x73, 0xb3, 0xad, 0x9a, 0xa8, 0x4d, 0x7c, 0x9e,
+ 0xc8, 0xa2, 0x13, 0xc5, 0x7d, 0x27, 0xe1, 0xec, 0xeb, 0x44, 0x91, 0x7f,
+ 0x09, 0x56, 0x84, 0x2e, 0x98, 0x97, 0x35, 0x87, 0xfb, 0x38, 0xe5, 0x73,
+ 0x2c, 0x58, 0xc3, 0x98, 0x91, 0x71, 0xca, 0xd0, 0x1c, 0xda, 0x7d, 0x23,
+ 0x76, 0x8c, 0xc9, 0x59, 0x08, 0x1b, 0x56, 0x2d, 0x96, 0x58, 0x5c, 0xa1,
+ 0x5e, 0xcf, 0x62, 0x3c, 0xa9, 0xa9, 0xcf, 0x59, 0xe7, 0x56, 0xc8, 0xb9,
+ 0xaa, 0x3c, 0x78, 0xd2, 0x3a, 0xaf, 0x21, 0xf7, 0x37, 0x31, 0x0e, 0xd8,
+ 0x84, 0x9a, 0x98, 0x61, 0x8a, 0xbc, 0x8f, 0x23, 0xf2, 0xa2, 0x8d, 0xf3,
+ 0x68, 0x5a, 0xe4, 0xdf, 0x30, 0xa5, 0x88, 0x3e, 0xfb, 0xdb, 0x47, 0x15,
+ 0xdd, 0xb5, 0x3a, 0xa3, 0x20, 0xd0, 0xc7, 0xbe, 0x42, 0x23, 0xb3, 0xb3,
+ 0xb9, 0xf1, 0x3c, 0xbf, 0xdb, 0x44, 0x5e, 0xb0, 0x09, 0x65, 0x31, 0xe1,
+ 0xe4, 0x82, 0x0b, 0x91, 0xa5, 0xe5, 0x7c, 0x3e, 0x1d, 0xf2, 0xb7, 0x96,
+ 0x2a, 0xc2, 0x7d, 0xfc, 0x4d, 0xab, 0x14, 0xe1, 0x2a, 0xf2, 0x9c, 0xee,
+ 0xaa, 0xcf, 0x9c, 0xcf, 0xd5, 0x31, 0x1b, 0x89, 0x0d, 0x72, 0xce, 0x24,
+ 0x7f, 0xd6, 0xea, 0x46, 0xce, 0xda, 0x19, 0x97, 0xd8, 0xe1, 0x68, 0x68,
+ 0x59, 0xb4, 0x89, 0x38, 0x67, 0x2e, 0x39, 0x44, 0xbd, 0xbf, 0x88, 0x2a,
+ 0xfc, 0x73, 0x54, 0x30, 0xcd, 0x83, 0x9f, 0x47, 0x0b, 0x25, 0x26, 0x4e,
+ 0x49, 0x5e, 0xf6, 0x4c, 0xd2, 0x30, 0x29, 0xd7, 0x96, 0x55, 0xd4, 0xa5,
+ 0x40, 0xa8, 0x14, 0xa8, 0xee, 0x7e, 0xd2, 0x69, 0xc5, 0xe8, 0x65, 0xa8,
+ 0x20, 0xfe, 0xf7, 0x0d, 0xfd, 0xa1, 0xf3, 0x0e, 0xc4, 0xe0, 0x62, 0xc9,
+ 0x15, 0xda, 0xb1, 0x2d, 0xf4, 0x1b, 0x33, 0xd5, 0x26, 0xcf, 0xd4, 0xe2,
+ 0xdc, 0x6e, 0xd1, 0xd3, 0x00, 0x0a, 0xe3, 0xe7, 0xa9, 0x93, 0x2a, 0xce,
+ 0x46, 0x7d, 0xfa, 0x1a, 0xdb, 0xb7, 0xa8, 0xff, 0xf3, 0x6e, 0xc2, 0xed,
+ 0x79, 0xda, 0x03, 0x78, 0xdc, 0xc2, 0xed, 0x30, 0xb6, 0xd0, 0x2f, 0x90,
+ 0xb7, 0xed, 0x7b, 0xd2, 0xa6, 0xd2, 0x9f, 0xfb, 0x54, 0x1f, 0x63, 0xea,
+ 0x2d, 0x1c, 0x43, 0xf8, 0xe4, 0x4c, 0xf2, 0xbd, 0xa7, 0xa3, 0x0d, 0x9e,
+ 0x5f, 0xe3, 0x09, 0xda, 0xa3, 0x8c, 0x21, 0x6b, 0xd2, 0x50, 0xca, 0xd8,
+ 0xf1, 0x04, 0xd7, 0xb1, 0xad, 0x22, 0x3b, 0x6e, 0x79, 0xae, 0xef, 0xf8,
+ 0x90, 0xf0, 0xad, 0x7b, 0xb0, 0xc6, 0xea, 0x3b, 0x68, 0xd9, 0xe6, 0xbe,
+ 0xa8, 0x82, 0x19, 0xf5, 0x1a, 0x12, 0xe9, 0x66, 0x6c, 0xac, 0xac, 0xc5,
+ 0xfe, 0xc4, 0x26, 0x2c, 0x24, 0xe7, 0x7d, 0xa4, 0xd2, 0xa0, 0x5f, 0x24,
+ 0x06, 0xc5, 0x35, 0x75, 0xbe, 0xf2, 0x8d, 0x5c, 0xae, 0xba, 0x0a, 0x8e,
+ 0xb8, 0xf8, 0xbb, 0x02, 0xf4, 0xab, 0x73, 0x51, 0x62, 0x9d, 0x81, 0xcc,
+ 0xf6, 0xbd, 0x6b, 0xc8, 0x9b, 0xf3, 0x81, 0x44, 0x8d, 0xb8, 0x75, 0x4e,
+ 0x25, 0xf0, 0x3c, 0x79, 0x44, 0x8a, 0xde, 0xaf, 0x20, 0xac, 0xa5, 0xd6,
+ 0xa3, 0x08, 0xc6, 0x2c, 0xc1, 0x43, 0x79, 0x66, 0xce, 0x2d, 0x73, 0xaa,
+ 0xcc, 0xcd, 0x29, 0x7f, 0xff, 0x34, 0xef, 0x89, 0x6e, 0x09, 0xb7, 0x90,
+ 0xdf, 0x8b, 0xd1, 0x4a, 0x7d, 0xaa, 0xe2, 0x9c, 0x13, 0x09, 0xb9, 0xef,
+ 0xd5, 0x0d, 0x5b, 0x23, 0x3e, 0xdb, 0x93, 0xd5, 0xc1, 0xb5, 0x75, 0xdc,
+ 0xff, 0xf2, 0x46, 0x4c, 0x8d, 0x88, 0x2f, 0xfb, 0xc3, 0x67, 0x50, 0x8c,
+ 0xeb, 0x67, 0x50, 0x44, 0xae, 0xde, 0x53, 0xef, 0xa0, 0x61, 0xe2, 0x31,
+ 0xdb, 0x61, 0x13, 0x33, 0x45, 0xc6, 0x71, 0xb7, 0xc4, 0x9a, 0x36, 0x72,
+ 0x08, 0x23, 0x3d, 0xee, 0x16, 0x3f, 0xe9, 0x88, 0x03, 0xf3, 0xe2, 0x06,
+ 0x0a, 0xc3, 0xda, 0xbe, 0x2b, 0xf6, 0x6b, 0x66, 0xfb, 0xac, 0x39, 0x8c,
+ 0xf9, 0x6e, 0xac, 0xb9, 0x97, 0x73, 0xb7, 0x6b, 0x3f, 0x31, 0xef, 0xab,
+ 0x92, 0x39, 0xfe, 0xd2, 0x9d, 0x3d, 0xfb, 0x70, 0x07, 0xe5, 0x92, 0x97,
+ 0x89, 0x49, 0xfd, 0xf9, 0x2b, 0xf3, 0x9b, 0x37, 0xdd, 0x17, 0x2e, 0x23,
+ 0x7a, 0x3a, 0xfd, 0x3c, 0xa0, 0xe8, 0xac, 0xd4, 0x56, 0x26, 0x71, 0x28,
+ 0x29, 0xba, 0x2b, 0x32, 0x8e, 0xe0, 0x22, 0x79, 0x61, 0x41, 0xff, 0x24,
+ 0x06, 0xc9, 0x0b, 0xed, 0x71, 0xef, 0x3e, 0x4a, 0x12, 0x1b, 0xd5, 0x25,
+ 0xc4, 0xea, 0x32, 0xce, 0x23, 0x3f, 0x87, 0x3a, 0x4b, 0xee, 0xe2, 0x5f,
+ 0x76, 0x72, 0xbd, 0x45, 0xe4, 0x48, 0xcd, 0xb1, 0x42, 0x68, 0x15, 0xe5,
+ 0x28, 0xd5, 0xe4, 0x0c, 0x7c, 0xb6, 0x5d, 0x94, 0x73, 0x29, 0xd1, 0xe6,
+ 0x62, 0x95, 0xd5, 0xd6, 0x63, 0x9d, 0x01, 0xd1, 0x2a, 0xc5, 0xff, 0x8a,
+ 0xcf, 0x25, 0xdf, 0x5e, 0x2c, 0x3e, 0x37, 0xcc, 0xb9, 0xcd, 0xc9, 0xd5,
+ 0x99, 0x56, 0x59, 0xf7, 0xf7, 0x25, 0x2e, 0x7c, 0xd9, 0x9f, 0xf8, 0x3d,
+ 0x9f, 0xe9, 0x80, 0xba, 0xb7, 0x18, 0x0f, 0xfd, 0x65, 0x09, 0xf4, 0xca,
+ 0x6c, 0xae, 0x7c, 0x5e, 0x38, 0x1a, 0x32, 0x13, 0xc2, 0x93, 0xee, 0x84,
+ 0x67, 0xb6, 0x8c, 0x25, 0x18, 0x20, 0x7b, 0x21, 0x7b, 0x27, 0x39, 0xdc,
+ 0xdb, 0xd5, 0x18, 0xbc, 0xea, 0xc4, 0xf5, 0x7d, 0x98, 0x0f, 0xed, 0xe1,
+ 0x2a, 0xae, 0x2d, 0xeb, 0x23, 0x76, 0xd0, 0x47, 0x04, 0xfc, 0x59, 0x0c,
+ 0x93, 0x1a, 0xbd, 0x93, 0x3e, 0x62, 0x84, 0x3e, 0xe2, 0xa2, 0x5e, 0x8e,
+ 0xe5, 0x39, 0x1f, 0xd1, 0x6e, 0xd3, 0xad, 0xfe, 0x9d, 0xda, 0x7d, 0x35,
+ 0xc4, 0x30, 0x8e, 0xf1, 0xb5, 0x9b, 0xb8, 0xd8, 0x4c, 0xed, 0x97, 0xe6,
+ 0x23, 0x55, 0xb2, 0xc6, 0xe6, 0x9a, 0x6c, 0x8e, 0xbc, 0x03, 0xfb, 0x88,
+ 0x8f, 0x35, 0x9a, 0x3c, 0xa3, 0x25, 0x6b, 0xec, 0x1d, 0xe8, 0x67, 0xff,
+ 0x7d, 0xc4, 0xc8, 0x18, 0x31, 0x52, 0x5f, 0x78, 0xec, 0x45, 0x15, 0xf5,
+ 0x1d, 0x64, 0x0f, 0xdf, 0x16, 0x6c, 0x79, 0x99, 0xd8, 0xf2, 0x3c, 0x31,
+ 0x72, 0x67, 0x4a, 0xc6, 0x91, 0xf1, 0xf2, 0xe3, 0x48, 0x9f, 0xff, 0x66,
+ 0xae, 0xaf, 0x92, 0xb9, 0xde, 0x6e, 0x1e, 0xf2, 0xdb, 0x9f, 0xf2, 0xef,
+ 0x62, 0x8b, 0x43, 0xf5, 0x26, 0xa6, 0x9f, 0xa9, 0x98, 0x24, 0xbe, 0x5a,
+ 0x71, 0x00, 0xfd, 0x6b, 0x04, 0x2b, 0x17, 0xab, 0xb8, 0x1c, 0x9d, 0x44,
+ 0xd1, 0x81, 0x3c, 0x16, 0x99, 0x4b, 0x4e, 0x10, 0x87, 0x06, 0x21, 0xd8,
+ 0xd3, 0xc4, 0x3d, 0x30, 0x68, 0x13, 0x65, 0x18, 0x4d, 0xca, 0xd9, 0x0b,
+ 0x13, 0xbb, 0x42, 0x2e, 0x72, 0xd8, 0xee, 0xe3, 0x05, 0x96, 0x4f, 0x28,
+ 0x23, 0x5e, 0xe7, 0xf9, 0xb5, 0x70, 0x6b, 0xc1, 0x1a, 0xc6, 0x11, 0x43,
+ 0x76, 0x14, 0x2c, 0xca, 0xc6, 0x0e, 0xe7, 0xda, 0xa4, 0x5d, 0x2d, 0x06,
+ 0x77, 0x8b, 0xae, 0xf9, 0x50, 0xa3, 0x9d, 0x67, 0x2c, 0x01, 0xbc, 0x1b,
+ 0xb5, 0xdd, 0xe9, 0x22, 0x07, 0xee, 0xd2, 0x17, 0xe3, 0xda, 0xcc, 0x2d,
+ 0xb4, 0x6f, 0x37, 0x7f, 0x9b, 0xc0, 0xc1, 0xa8, 0x0b, 0x05, 0x56, 0x8d,
+ 0xb2, 0x9c, 0xeb, 0xc9, 0xea, 0xcb, 0x36, 0xea, 0x4b, 0x21, 0x63, 0xb3,
+ 0x15, 0x96, 0x5d, 0x4a, 0x3f, 0x93, 0xd6, 0xbb, 0x32, 0xda, 0x62, 0xe1,
+ 0xad, 0x41, 0xfa, 0xc0, 0x32, 0xc4, 0xfb, 0xba, 0x70, 0x36, 0x54, 0x86,
+ 0xd8, 0x01, 0xb1, 0xa7, 0x5a, 0xc1, 0x4d, 0x8e, 0xdb, 0x44, 0xf9, 0xa8,
+ 0xc4, 0x95, 0x86, 0x4e, 0xbb, 0xbd, 0x0c, 0x17, 0x2a, 0x18, 0xaf, 0x5a,
+ 0xef, 0x13, 0xb5, 0x62, 0x7f, 0x6e, 0x8f, 0x54, 0xf2, 0x9b, 0xd6, 0xeb,
+ 0x7c, 0x39, 0xbf, 0x96, 0xbc, 0x7d, 0x66, 0x6b, 0xe4, 0x3d, 0xe4, 0x30,
+ 0x2f, 0x49, 0x3e, 0xc8, 0xe6, 0xa3, 0xdf, 0x60, 0x5c, 0x34, 0x26, 0xb2,
+ 0xce, 0xeb, 0xd6, 0xeb, 0x35, 0xd9, 0x33, 0x3d, 0xf9, 0x3d, 0xc8, 0x5f,
+ 0x6b, 0x6b, 0x8b, 0x95, 0x5f, 0x98, 0xcf, 0x56, 0xcb, 0xfc, 0xae, 0x32,
+ 0x0e, 0xfb, 0x31, 0x7f, 0x5f, 0x86, 0x9e, 0xa1, 0xe9, 0x7e, 0x41, 0x6c,
+ 0xce, 0x73, 0xd3, 0xd9, 0xc3, 0x8a, 0xb8, 0xbc, 0xbf, 0x75, 0x34, 0xf4,
+ 0x24, 0xf7, 0xc1, 0xbf, 0xb0, 0xc1, 0xca, 0xa5, 0x90, 0xe3, 0x32, 0xfe,
+ 0x10, 0x3c, 0x35, 0xe8, 0xcf, 0xcb, 0xf0, 0xb3, 0xa4, 0xf8, 0x57, 0x13,
+ 0x85, 0xa1, 0x12, 0xfa, 0xbb, 0xee, 0xe7, 0x2a, 0x2c, 0xce, 0x5c, 0x86,
+ 0x4a, 0xea, 0x5e, 0xff, 0xd0, 0xed, 0xf4, 0xfc, 0x86, 0x0f, 0x48, 0x87,
+ 0x14, 0x62, 0xc2, 0x6f, 0xcc, 0x5d, 0x8f, 0x66, 0x9f, 0x39, 0x97, 0x74,
+ 0xe1, 0xa3, 0x50, 0x3b, 0x26, 0x2a, 0xc2, 0x18, 0x48, 0x14, 0xa1, 0x7d,
+ 0x56, 0xbd, 0xf5, 0xce, 0x45, 0x4d, 0xdc, 0x83, 0xf3, 0x51, 0x27, 0x9a,
+ 0x66, 0x7b, 0xac, 0x7c, 0x92, 0x8d, 0x76, 0xf1, 0x76, 0x34, 0x42, 0x5f,
+ 0xe0, 0xb9, 0xc9, 0x3f, 0x14, 0x68, 0x8b, 0x70, 0x7f, 0x0e, 0xc3, 0xf7,
+ 0x27, 0x3e, 0x27, 0xc6, 0x94, 0x1b, 0x33, 0xc3, 0x65, 0xb8, 0x7b, 0x40,
+ 0xce, 0x29, 0x48, 0x9d, 0x4a, 0x9b, 0x9a, 0xaf, 0x94, 0x61, 0xc9, 0x90,
+ 0xe0, 0xb9, 0x9c, 0xfd, 0x48, 0x87, 0x5c, 0xb1, 0x36, 0xee, 0x51, 0x27,
+ 0xea, 0xf7, 0x5a, 0x72, 0x55, 0xed, 0x8a, 0xd9, 0x75, 0x49, 0x8f, 0xe8,
+ 0xf4, 0x67, 0x9d, 0xf7, 0x53, 0xef, 0xa7, 0x42, 0xde, 0xf6, 0x99, 0x76,
+ 0xad, 0xe3, 0x57, 0x4a, 0x10, 0xa3, 0x19, 0xa0, 0x6f, 0x24, 0x80, 0x0f,
+ 0x12, 0xc2, 0xed, 0x03, 0x78, 0x7f, 0x2c, 0x88, 0x77, 0xe8, 0x87, 0x8a,
+ 0xe2, 0xde, 0xc8, 0x33, 0x8c, 0xdd, 0xde, 0xe5, 0x75, 0x61, 0x5c, 0xc7,
+ 0x15, 0xca, 0xcf, 0x19, 0x6f, 0xc4, 0xa5, 0xb1, 0x6f, 0xe0, 0xf2, 0x5e,
+ 0x05, 0xc7, 0xb4, 0x6f, 0xe0, 0xe2, 0xa1, 0x4e, 0x2c, 0xda, 0x2b, 0x67,
+ 0xf5, 0x8e, 0x86, 0x54, 0xfa, 0x81, 0x27, 0xeb, 0xcc, 0xae, 0x17, 0xf4,
+ 0x7a, 0x62, 0x86, 0x57, 0x6f, 0x67, 0x6c, 0x24, 0xf8, 0x1d, 0xb1, 0xc9,
+ 0x9e, 0xc9, 0xde, 0x75, 0xe2, 0xb2, 0x85, 0xd9, 0xb7, 0xc7, 0x89, 0x1b,
+ 0x78, 0x2d, 0xe3, 0x88, 0x6d, 0xdf, 0x81, 0x57, 0x19, 0x94, 0x6e, 0x61,
+ 0x3b, 0x17, 0x71, 0xee, 0xe9, 0x68, 0x11, 0x0a, 0xab, 0xcb, 0x2d, 0x7b,
+ 0x2b, 0x8e, 0x07, 0x70, 0x9a, 0xb2, 0x5b, 0x59, 0xed, 0xe5, 0xb5, 0xf8,
+ 0xd8, 0x20, 0xe3, 0x93, 0x99, 0xf8, 0xe0, 0x26, 0xdf, 0xfa, 0xaa, 0x85,
+ 0x0d, 0x0e, 0xed, 0x81, 0x39, 0x59, 0x6c, 0x20, 0xa0, 0x13, 0x93, 0x25,
+ 0x27, 0x58, 0xae, 0x69, 0x1b, 0xbe, 0x4b, 0x1b, 0x4f, 0x87, 0x8e, 0xfd,
+ 0x49, 0x29, 0x39, 0xf0, 0x0b, 0xa1, 0x7a, 0xa3, 0x02, 0x2b, 0x78, 0x7f,
+ 0x62, 0x91, 0x8a, 0x75, 0xfc, 0xf6, 0xb3, 0x5d, 0x90, 0xf3, 0xb8, 0x6a,
+ 0xa6, 0x54, 0x1f, 0xff, 0xae, 0xa5, 0x2f, 0xdf, 0x84, 0xb3, 0xb1, 0x86,
+ 0xf6, 0x11, 0xe5, 0x8a, 0x69, 0x54, 0xd7, 0xf1, 0xb7, 0x2a, 0x9c, 0x8b,
+ 0x7a, 0x27, 0x0e, 0xa1, 0xc1, 0x33, 0xa5, 0xec, 0x37, 0x0d, 0x55, 0xf6,
+ 0x47, 0xd6, 0x2b, 0xcf, 0xdf, 0xc5, 0xfb, 0x17, 0xa6, 0xe9, 0xe1, 0x8d,
+ 0xf8, 0xca, 0x79, 0x5d, 0xff, 0x84, 0x83, 0x98, 0x4b, 0x86, 0xf5, 0x06,
+ 0x75, 0x0b, 0xb1, 0x20, 0xa2, 0xde, 0x4e, 0xff, 0x8a, 0xa8, 0x7f, 0x61,
+ 0xc6, 0x8b, 0x65, 0x50, 0x2d, 0x5f, 0xd4, 0x8a, 0xe4, 0xd0, 0x74, 0x1e,
+ 0x29, 0x7a, 0x97, 0xe5, 0xa4, 0xed, 0x15, 0xdd, 0xc7, 0x9d, 0xf4, 0x87,
+ 0x09, 0x62, 0x78, 0x9c, 0x18, 0x5e, 0x48, 0x0c, 0xbf, 0xba, 0xa7, 0x18,
+ 0x67, 0xf7, 0x34, 0x21, 0x5d, 0x21, 0xcf, 0xd8, 0xe1, 0xe4, 0xea, 0x52,
+ 0x96, 0x6f, 0xb7, 0xa1, 0xa6, 0x7f, 0xa9, 0x9c, 0x75, 0x85, 0xf8, 0xd0,
+ 0x82, 0x38, 0x11, 0xb1, 0xd5, 0x0e, 0x87, 0xf5, 0x7e, 0xc1, 0x8c, 0x9b,
+ 0xf4, 0xcf, 0xa5, 0x15, 0xa2, 0xa5, 0x4a, 0xf0, 0xe1, 0xe2, 0x1c, 0xf1,
+ 0x99, 0x3f, 0xe5, 0x5c, 0x8e, 0x53, 0xa7, 0x9f, 0xd2, 0xef, 0x91, 0x1a,
+ 0x1d, 0xdb, 0xcb, 0x73, 0x12, 0xc3, 0x98, 0xd8, 0x41, 0x0d, 0xab, 0xaf,
+ 0x36, 0x91, 0xd0, 0xc3, 0xf4, 0x4f, 0x21, 0x44, 0x2a, 0x82, 0xf4, 0x4b,
+ 0x72, 0xad, 0xe2, 0x12, 0xe3, 0xaf, 0x4c, 0x50, 0xc1, 0x47, 0x5f, 0x13,
+ 0xbf, 0xef, 0xd7, 0xcf, 0x2a, 0xa7, 0x67, 0x65, 0xdf, 0x6b, 0x10, 0x8c,
+ 0x28, 0xb7, 0x30, 0xa2, 0xd0, 0xe2, 0x40, 0xb3, 0x2d, 0x6c, 0xf1, 0xd8,
+ 0xe4, 0x4c, 0x51, 0x34, 0x74, 0x6f, 0xa2, 0x61, 0xc2, 0x67, 0x27, 0x1f,
+ 0xfb, 0xe3, 0xaf, 0x91, 0x87, 0x59, 0x7c, 0x60, 0xba, 0xdf, 0x69, 0x02,
+ 0xa6, 0xcb, 0x23, 0x7f, 0x76, 0xd9, 0x93, 0xc5, 0xca, 0x72, 0xe1, 0x6d,
+ 0xff, 0xcf, 0x6c, 0xbd, 0x69, 0xfe, 0x79, 0x1c, 0xf9, 0x25, 0xaf, 0xe5,
+ 0x79, 0xb1, 0x3b, 0xea, 0x45, 0xfc, 0x1f, 0xcd, 0xc7, 0x2d, 0xee, 0x76,
+ 0x6c, 0x8e, 0x9c, 0xcb, 0x74, 0xf4, 0xff, 0xfd, 0x1c, 0x79, 0x9f, 0xc1,
+ 0x36, 0x8d, 0x03, 0x64, 0xfd, 0xea, 0x3b, 0xe6, 0x2a, 0x6b, 0xae, 0xa7,
+ 0x73, 0xed, 0x24, 0x56, 0x96, 0xb9, 0x28, 0xf8, 0x81, 0xd6, 0xa0, 0x9e,
+ 0x46, 0xa9, 0xe0, 0x49, 0x44, 0xea, 0x91, 0xc5, 0x9a, 0xcf, 0x7d, 0x90,
+ 0xdf, 0xbb, 0x78, 0xff, 0x35, 0xcd, 0xd1, 0xf4, 0x2c, 0xa4, 0x06, 0x6b,
+ 0xe3, 0x5e, 0x35, 0xb8, 0x4f, 0xc3, 0x1f, 0x29, 0x54, 0xa6, 0xcc, 0xf6,
+ 0x2a, 0x69, 0x93, 0xad, 0xc5, 0x42, 0x39, 0x6f, 0xe5, 0x49, 0xb2, 0x3a,
+ 0x53, 0x4b, 0x9d, 0x11, 0xec, 0x12, 0xde, 0xb1, 0x80, 0x6b, 0x57, 0x31,
+ 0x34, 0x26, 0x1c, 0xc1, 0x65, 0xf1, 0x20, 0xb5, 0xae, 0xce, 0xb3, 0x1e,
+ 0xca, 0x5c, 0x62, 0x2c, 0xb6, 0xea, 0xb8, 0xd3, 0x86, 0xb7, 0xee, 0xb4,
+ 0x85, 0x97, 0xfe, 0xd9, 0xfd, 0x8d, 0x77, 0xcf, 0x95, 0x77, 0x5f, 0xc8,
+ 0xe6, 0x24, 0x2f, 0xeb, 0x96, 0xba, 0xe1, 0x72, 0xf2, 0xaa, 0x41, 0xc6,
+ 0xf2, 0xcb, 0x83, 0xbf, 0x33, 0xbf, 0xed, 0x88, 0x78, 0xec, 0xa8, 0xf3,
+ 0xf4, 0xe0, 0x9a, 0x99, 0xaa, 0xb2, 0xee, 0xcf, 0x95, 0xf7, 0x0d, 0x9c,
+ 0xd2, 0x3f, 0xb9, 0xc8, 0xdd, 0x75, 0x26, 0xe3, 0x64, 0xdb, 0x32, 0x3b,
+ 0xed, 0x82, 0x32, 0x33, 0xeb, 0x67, 0xd5, 0xb9, 0x6d, 0x4a, 0x3d, 0xb5,
+ 0xa3, 0x0a, 0x47, 0xa8, 0xbf, 0x47, 0xc6, 0xc4, 0xff, 0xa9, 0x38, 0x4c,
+ 0x3b, 0x3d, 0x54, 0xef, 0xeb, 0xbc, 0xcc, 0xb8, 0xf1, 0x43, 0xf2, 0xf9,
+ 0x37, 0x34, 0x6f, 0xfb, 0x29, 0xc9, 0x29, 0x86, 0x1c, 0x38, 0x13, 0xbc,
+ 0x66, 0xe5, 0x78, 0x63, 0x07, 0x54, 0x0c, 0x26, 0xb2, 0xf6, 0xfe, 0x0a,
+ 0xed, 0xf8, 0xc6, 0x99, 0x03, 0x1d, 0x5b, 0x06, 0xc4, 0x3e, 0x1a, 0x2d,
+ 0x3b, 0xba, 0x91, 0x13, 0x12, 0xbc, 0x16, 0xbb, 0x78, 0x42, 0x6a, 0x71,
+ 0x46, 0x0a, 0x0e, 0xca, 0x77, 0x39, 0xf9, 0xae, 0xf8, 0xd8, 0x00, 0x63,
+ 0x5b, 0x07, 0xed, 0xe7, 0x14, 0xe3, 0x0c, 0xce, 0x2d, 0x6c, 0x9a, 0xef,
+ 0x30, 0xee, 0x1a, 0x42, 0x83, 0x7a, 0x02, 0x6b, 0xc8, 0x59, 0xc9, 0x67,
+ 0xc6, 0x9a, 0xb1, 0xd3, 0x8a, 0x9b, 0x7c, 0xea, 0x0a, 0x65, 0x21, 0xd7,
+ 0xdf, 0x8c, 0xee, 0x43, 0xb5, 0xe4, 0x35, 0xa6, 0xb9, 0x5a, 0xff, 0x73,
+ 0x54, 0x0e, 0x74, 0x77, 0x56, 0x52, 0x1e, 0x9f, 0x86, 0x8c, 0x0e, 0x62,
+ 0xfa, 0x86, 0x13, 0x4a, 0xc3, 0xda, 0x98, 0xf2, 0x6d, 0xee, 0x87, 0xe4,
+ 0x41, 0x3c, 0x8c, 0xc7, 0x57, 0xd3, 0x9f, 0xfd, 0x0f, 0xec, 0x50, 0x95,
+ 0x25, 0xb6, 0xb0, 0xf0, 0x41, 0xf8, 0xd5, 0xb0, 0x76, 0xea, 0xa2, 0x7d,
+ 0x33, 0xbd, 0x4f, 0x23, 0xef, 0x89, 0x5f, 0x97, 0xb6, 0x72, 0xb6, 0xbe,
+ 0x13, 0xc7, 0xd3, 0xd4, 0xeb, 0x68, 0x2f, 0x4e, 0xa4, 0x65, 0x4c, 0xe1,
+ 0x53, 0x01, 0xc4, 0x06, 0xec, 0x18, 0xd5, 0x7d, 0x91, 0x72, 0xca, 0xa5,
+ 0x38, 0xe4, 0x8d, 0xac, 0x51, 0x02, 0xe4, 0x6d, 0x69, 0x9c, 0xd9, 0xed,
+ 0x6d, 0xaf, 0x67, 0x8c, 0x18, 0x1d, 0x83, 0xfa, 0xcc, 0xe2, 0x34, 0x4e,
+ 0x0f, 0x3f, 0x04, 0xcf, 0x2c, 0xaf, 0x67, 0xb9, 0xd2, 0x82, 0xad, 0x63,
+ 0xff, 0x51, 0x2e, 0xc9, 0xc3, 0xb1, 0x5b, 0x60, 0x50, 0xf6, 0xdb, 0xd1,
+ 0x3f, 0x57, 0x6c, 0xbe, 0x67, 0xac, 0x14, 0xf3, 0xe8, 0x8f, 0x5e, 0xb2,
+ 0xfc, 0x6c, 0xd6, 0x8e, 0x6a, 0xb4, 0x8f, 0xcc, 0xc7, 0x72, 0x3e, 0xfc,
+ 0xab, 0xe5, 0xf5, 0x77, 0x66, 0x44, 0x15, 0x79, 0xc9, 0x73, 0x35, 0x28,
+ 0x62, 0x3f, 0x3b, 0x72, 0xfe, 0xba, 0x42, 0xfb, 0xbf, 0xe6, 0x43, 0x56,
+ 0x1f, 0x4f, 0xcd, 0x95, 0xa0, 0x60, 0x9b, 0x15, 0xd3, 0xcb, 0xba, 0x75,
+ 0x7c, 0x16, 0x95, 0x9c, 0x86, 0x8a, 0x13, 0xba, 0xe0, 0x48, 0x0b, 0x6d,
+ 0xd5, 0x89, 0x0d, 0x41, 0x9a, 0xa3, 0x95, 0xcf, 0x9f, 0xc4, 0xce, 0xe4,
+ 0xbf, 0x9b, 0xcf, 0x51, 0x8f, 0x56, 0x92, 0xc3, 0x78, 0x88, 0x03, 0x4f,
+ 0x85, 0x56, 0x93, 0x73, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2,
+ 0x89, 0xf6, 0x1f, 0x5a, 0x80, 0x09, 0xab, 0x7d, 0xd5, 0xdc, 0x6c, 0x0e,
+ 0xf1, 0x83, 0xb9, 0xd9, 0x38, 0x50, 0xe4, 0xff, 0x9f, 0x91, 0xdf, 0x2b,
+ 0xa6, 0xa7, 0x52, 0xe4, 0xe7, 0x80, 0x9b, 0x7e, 0x6b, 0x1f, 0xdb, 0x9c,
+ 0xdb, 0xed, 0x40, 0xbf, 0xd6, 0x82, 0xfe, 0x31, 0x78, 0x3e, 0x65, 0x9b,
+ 0x7f, 0x1a, 0x1e, 0x98, 0x9b, 0xe5, 0x0a, 0x6f, 0xa1, 0x3b, 0xfa, 0xbc,
+ 0xb9, 0xac, 0x52, 0xd6, 0xeb, 0x84, 0x9b, 0xeb, 0xdd, 0x77, 0x3d, 0x9f,
+ 0xb7, 0xde, 0x7c, 0xd8, 0xf2, 0x13, 0xbb, 0xe7, 0x4a, 0xbd, 0xec, 0xa7,
+ 0x09, 0x13, 0x97, 0xf4, 0xa3, 0x56, 0x1c, 0x2e, 0xd8, 0xd0, 0x93, 0x90,
+ 0xbd, 0x95, 0xb9, 0x6d, 0xcd, 0xc9, 0xe3, 0xff, 0x54, 0xdf, 0x3c, 0xef,
+ 0x65, 0x39, 0x5d, 0x96, 0x5a, 0x75, 0x9e, 0xe3, 0x8b, 0x2e, 0x8b, 0x1e,
+ 0x5b, 0xef, 0xfd, 0x24, 0xe5, 0xfd, 0xd9, 0x27, 0xd4, 0xdf, 0x73, 0x0c,
+ 0xc9, 0xa9, 0xb4, 0xb0, 0x0f, 0xd3, 0x5c, 0xaf, 0x37, 0x78, 0x4e, 0xe0,
+ 0x8f, 0xa8, 0xdb, 0x3a, 0xb6, 0x0f, 0x48, 0xbe, 0xd5, 0xa3, 0x38, 0xf6,
+ 0xac, 0xc1, 0x25, 0xfa, 0xff, 0x9d, 0x96, 0x1e, 0x0a, 0xae, 0xc8, 0x3c,
+ 0x04, 0x5b, 0xda, 0xe8, 0xc7, 0xad, 0xb3, 0x2e, 0x91, 0x9a, 0x70, 0xa7,
+ 0xf2, 0x61, 0x7d, 0x27, 0x8e, 0x86, 0x0c, 0xb3, 0x5c, 0xf3, 0xaf, 0x65,
+ 0xd0, 0x5f, 0x34, 0xd6, 0x58, 0x88, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2,
+ 0x69, 0xaf, 0x31, 0xc3, 0xae, 0xba, 0x5e, 0x4e, 0xe7, 0xb0, 0xd2, 0xf6,
+ 0xc0, 0x5c, 0x89, 0x97, 0x92, 0x16, 0x8e, 0x7c, 0x1d, 0xf7, 0x59, 0x7b,
+ 0xab, 0xd2, 0x87, 0x4a, 0xbe, 0xf7, 0x68, 0xe8, 0x4a, 0x54, 0x30, 0xc5,
+ 0x5c, 0xd2, 0x1c, 0x6a, 0x50, 0xb7, 0xe3, 0x4e, 0x62, 0xd7, 0x12, 0x9c,
+ 0xd1, 0xa5, 0xae, 0x61, 0x7c, 0xdb, 0x01, 0xa9, 0xc1, 0x1d, 0x0e, 0x6d,
+ 0x8d, 0x2e, 0xc5, 0xbe, 0x01, 0x43, 0x71, 0x86, 0xbd, 0x91, 0x18, 0xb9,
+ 0x10, 0xe3, 0x71, 0x2b, 0xdf, 0x27, 0xf9, 0x84, 0xc1, 0xc6, 0x4e, 0x6c,
+ 0xd7, 0x0b, 0xd1, 0xa3, 0x47, 0x8a, 0xb6, 0x2c, 0xee, 0xc2, 0x7e, 0xbd,
+ 0xd4, 0x98, 0x17, 0x36, 0x88, 0xe9, 0xda, 0x86, 0x24, 0xfc, 0x2d, 0x17,
+ 0xc9, 0x39, 0x8e, 0xc3, 0xdb, 0xb1, 0xc4, 0x4e, 0xcc, 0xbd, 0xc7, 0xe1,
+ 0x8a, 0x65, 0x9a, 0x90, 0x18, 0xab, 0x72, 0xed, 0xc8, 0x04, 0x11, 0x1f,
+ 0xe3, 0x7e, 0x33, 0xae, 0x75, 0x64, 0x96, 0x92, 0x83, 0x8a, 0x1c, 0xed,
+ 0xd4, 0xc5, 0x7a, 0x3c, 0xd3, 0x7a, 0xc1, 0x7c, 0xd2, 0x2f, 0xf8, 0x59,
+ 0x8b, 0x67, 0x55, 0x9f, 0xc5, 0x29, 0x23, 0xb6, 0xaf, 0xb2, 0x0f, 0x3b,
+ 0x75, 0xee, 0x55, 0xd3, 0xf3, 0xa8, 0xc8, 0x8d, 0xc1, 0x56, 0xf1, 0x6a,
+ 0xe2, 0xa7, 0xfc, 0x2d, 0xb2, 0x13, 0x19, 0x9a, 0x58, 0xa7, 0x4b, 0x2e,
+ 0xaf, 0x91, 0x36, 0xe3, 0xc6, 0xdb, 0xea, 0x8d, 0x7d, 0x78, 0x5a, 0xf7,
+ 0xe9, 0x87, 0x20, 0x39, 0xbc, 0xff, 0xce, 0xe7, 0x24, 0xdf, 0xd2, 0x84,
+ 0x17, 0x2b, 0xb2, 0xf1, 0x87, 0xc7, 0x56, 0x42, 0xdc, 0xcd, 0xfb, 0x11,
+ 0xb9, 0xef, 0x4d, 0x46, 0xa8, 0xa7, 0x1b, 0x83, 0x53, 0x66, 0xa4, 0xd2,
+ 0xe8, 0x94, 0xb3, 0x28, 0xee, 0xf0, 0xea, 0x17, 0xdd, 0xf5, 0xde, 0x8e,
+ 0x29, 0x05, 0x38, 0x13, 0xa3, 0x1f, 0xb6, 0xfe, 0xbb, 0x47, 0xe9, 0xdb,
+ 0x89, 0xa1, 0xe0, 0x1d, 0x68, 0x6f, 0x93, 0xb1, 0x9a, 0xd1, 0xbb, 0xd7,
+ 0x34, 0x4b, 0x43, 0x3e, 0x35, 0x0d, 0x27, 0x56, 0x04, 0xed, 0xb8, 0xa0,
+ 0x9a, 0x70, 0x84, 0xfe, 0xdd, 0xcc, 0xd0, 0x3f, 0x0e, 0xd3, 0x4e, 0x76,
+ 0x50, 0xc7, 0xe4, 0x5d, 0x28, 0x3f, 0xed, 0x24, 0x4e, 0x3b, 0x39, 0x13,
+ 0x9a, 0x9f, 0x7b, 0x57, 0x52, 0x23, 0xaf, 0x98, 0xc4, 0x92, 0x01, 0x15,
+ 0x9f, 0xde, 0x33, 0x89, 0xd0, 0x50, 0x7e, 0xee, 0x62, 0x97, 0xf9, 0xf9,
+ 0x4b, 0x6d, 0x50, 0xe6, 0x2e, 0x73, 0x94, 0xb5, 0xc8, 0xdf, 0xf9, 0x7b,
+ 0xf9, 0xdf, 0xc4, 0xcf, 0x3a, 0xd1, 0x6a, 0xad, 0xed, 0x2f, 0x6a, 0xb2,
+ 0x98, 0x91, 0x5f, 0x93, 0xeb, 0x96, 0xeb, 0x4b, 0xb7, 0x5c, 0x3f, 0xee,
+ 0xbe, 0xf9, 0x7a, 0xfb, 0x9c, 0x9b, 0xaf, 0xf3, 0x36, 0x71, 0x43, 0xae,
+ 0x1d, 0xba, 0x6f, 0xe2, 0x28, 0xd7, 0x3a, 0x63, 0xc1, 0x21, 0xf3, 0x42,
+ 0x85, 0xcc, 0x45, 0x62, 0xd6, 0xec, 0x5c, 0x97, 0x65, 0xa6, 0xcf, 0xf5,
+ 0xcd, 0x5c, 0x6d, 0xc0, 0x3a, 0xf7, 0x4b, 0xbb, 0xd1, 0xe4, 0x1d, 0xdf,
+ 0xdc, 0x3b, 0x74, 0xd9, 0xb3, 0x88, 0xa5, 0xe1, 0x80, 0xd2, 0x1b, 0x33,
+ 0xcc, 0x19, 0x5a, 0xb1, 0x21, 0xef, 0x4a, 0xa9, 0x7e, 0x03, 0x25, 0x7e,
+ 0x6d, 0xc3, 0x0c, 0x5b, 0x17, 0x9c, 0x0b, 0xb5, 0x8e, 0x3f, 0x53, 0x92,
+ 0x88, 0x67, 0xbc, 0x81, 0x43, 0x94, 0x55, 0x2c, 0x73, 0x95, 0x71, 0x75,
+ 0x17, 0x9e, 0x09, 0x39, 0x8c, 0xe2, 0xb0, 0xd7, 0x3d, 0x5f, 0x59, 0x86,
+ 0xed, 0x43, 0x7f, 0x8e, 0xf5, 0x49, 0xe1, 0xf8, 0xb5, 0xd8, 0x32, 0x66,
+ 0xc3, 0x31, 0xea, 0x77, 0x2f, 0xc7, 0x21, 0xfe, 0xb9, 0x53, 0x90, 0xb3,
+ 0x79, 0x8d, 0x8c, 0x91, 0x75, 0xeb, 0xb3, 0x75, 0xe8, 0x75, 0xac, 0x8f,
+ 0x9a, 0xf8, 0x54, 0xa7, 0xef, 0xd1, 0x64, 0x7e, 0x12, 0x3b, 0xb7, 0x5a,
+ 0x58, 0xfa, 0x48, 0x9c, 0xfb, 0x39, 0x4b, 0x6c, 0x75, 0x29, 0x6d, 0x56,
+ 0xc1, 0x67, 0x52, 0x77, 0xac, 0xe4, 0x9c, 0xc9, 0x0d, 0xc7, 0xa3, 0x9b,
+ 0x30, 0x1c, 0x35, 0xe4, 0x7d, 0xc0, 0xde, 0x1a, 0x7b, 0xe4, 0x85, 0x0a,
+ 0xf2, 0xec, 0x84, 0xee, 0x6f, 0x3f, 0xa7, 0xc0, 0x53, 0x16, 0xf6, 0xd3,
+ 0xcf, 0x7c, 0x89, 0xdf, 0xea, 0x92, 0x4f, 0xd3, 0x5d, 0xab, 0xa8, 0xef,
+ 0x7b, 0x86, 0x02, 0x56, 0x7e, 0xe0, 0xef, 0x6e, 0x9b, 0xbf, 0x90, 0x1a,
+ 0xb3, 0x9e, 0xcb, 0x35, 0xbe, 0x8e, 0x83, 0x69, 0x17, 0x1e, 0x8b, 0x7b,
+ 0x94, 0x79, 0x7b, 0x54, 0xdc, 0x1f, 0xf7, 0x4e, 0x2c, 0xb1, 0x93, 0x7f,
+ 0x2c, 0x9a, 0xc1, 0xfe, 0x14, 0xfc, 0x68, 0xa1, 0xf8, 0x82, 0xff, 0x0a,
+ 0x63, 0x56, 0x84, 0x7d, 0xa2, 0xb4, 0x60, 0xb1, 0x57, 0x3d, 0x68, 0xf3,
+ 0xb9, 0x7f, 0x8b, 0xad, 0xb0, 0x67, 0x56, 0xa3, 0x9b, 0xf3, 0x5f, 0x19,
+ 0x97, 0x9a, 0x55, 0x03, 0x50, 0xd1, 0x8c, 0x1d, 0x87, 0xc4, 0x36, 0xe5,
+ 0x9d, 0x75, 0x78, 0xaa, 0xc2, 0x2d, 0x77, 0xa0, 0xf8, 0x4b, 0x72, 0xed,
+ 0x49, 0x89, 0x3f, 0x37, 0x94, 0xdb, 0x4c, 0xc6, 0x2f, 0xf3, 0x73, 0x35,
+ 0x89, 0xa5, 0xd8, 0x3a, 0x20, 0xf9, 0x76, 0xe2, 0xb6, 0xce, 0x38, 0xa8,
+ 0x42, 0x0b, 0x3c, 0x65, 0x93, 0x3a, 0xd0, 0x26, 0xf8, 0x62, 0x9b, 0x10,
+ 0x88, 0x89, 0xcd, 0x6a, 0x6a, 0x07, 0x22, 0xa7, 0x25, 0xcf, 0x37, 0x2f,
+ 0xe4, 0xe7, 0xbc, 0xfc, 0xbd, 0x55, 0x76, 0xdd, 0xf5, 0xca, 0xa8, 0x8a,
+ 0x09, 0x35, 0x1b, 0x47, 0x1e, 0x4a, 0x6a, 0x6b, 0x0b, 0x6d, 0x72, 0x26,
+ 0xe2, 0xb2, 0x19, 0xb1, 0xfa, 0x55, 0x6a, 0x51, 0xde, 0x8c, 0xbe, 0xbd,
+ 0xef, 0xd2, 0x07, 0xc9, 0x18, 0xbf, 0x37, 0x9d, 0xd4, 0xcb, 0xe5, 0x6d,
+ 0x1e, 0xdc, 0x17, 0x97, 0x3c, 0x69, 0x4f, 0x75, 0xf6, 0x4c, 0x87, 0x5c,
+ 0x3b, 0xd0, 0xa1, 0x13, 0x64, 0x67, 0x7d, 0x61, 0x56, 0x59, 0x71, 0xe9,
+ 0x97, 0x59, 0x9d, 0x49, 0xdc, 0x7d, 0x87, 0xd8, 0x78, 0xcf, 0x58, 0x83,
+ 0x3b, 0xab, 0x77, 0x4d, 0xbc, 0x96, 0xbe, 0xb4, 0x7d, 0x9b, 0xe4, 0x34,
+ 0x2e, 0xf9, 0xcc, 0x23, 0xa3, 0xd3, 0xdb, 0xe7, 0x73, 0x30, 0x55, 0x39,
+ 0x4e, 0x95, 0xd7, 0x37, 0xa9, 0xf5, 0x45, 0x94, 0x87, 0xa3, 0x2d, 0xca,
+ 0xaa, 0xa8, 0xd4, 0xfb, 0x6c, 0xd1, 0x12, 0xeb, 0x5c, 0xab, 0x89, 0xef,
+ 0x85, 0xc6, 0x95, 0x6d, 0xd6, 0x99, 0x59, 0x43, 0x49, 0x36, 0x02, 0x95,
+ 0xa3, 0xcd, 0xca, 0xf6, 0xe8, 0x27, 0xe6, 0x53, 0x56, 0x5d, 0x7d, 0xa6,
+ 0x75, 0xbe, 0xa6, 0x70, 0xd4, 0x85, 0x8a, 0x83, 0x25, 0x28, 0x18, 0xd4,
+ 0x30, 0x73, 0xf4, 0x41, 0xf2, 0x56, 0xe1, 0x3a, 0x46, 0x8b, 0xc3, 0x3a,
+ 0xa3, 0xf6, 0xfa, 0xf5, 0x33, 0x6a, 0x0e, 0xe2, 0x82, 0x01, 0xeb, 0x1f,
+ 0x63, 0xa5, 0xc3, 0x8c, 0x95, 0xcc, 0x25, 0xdf, 0x0b, 0x19, 0x3b, 0x66,
+ 0xc2, 0x1b, 0xa8, 0xb4, 0x19, 0xa6, 0xe4, 0x6e, 0x5e, 0x21, 0x61, 0x5c,
+ 0x53, 0x67, 0x60, 0x45, 0x9d, 0xbc, 0x9b, 0xe9, 0x30, 0xec, 0xe1, 0x2e,
+ 0x1c, 0x0e, 0x75, 0xe1, 0x3d, 0xbd, 0x0b, 0x3b, 0xf5, 0x62, 0xa3, 0x3c,
+ 0x5c, 0x2a, 0x67, 0xd9, 0x27, 0xa2, 0xd0, 0xf4, 0xb4, 0xa2, 0x9d, 0xba,
+ 0x0a, 0xef, 0x3e, 0x9f, 0xe2, 0x35, 0x96, 0x29, 0x1a, 0x2e, 0x67, 0xbc,
+ 0x53, 0xe5, 0xb4, 0x81, 0x6b, 0x99, 0x00, 0xa6, 0x88, 0xab, 0xc9, 0x31,
+ 0x39, 0x4f, 0x52, 0x8b, 0x81, 0xb1, 0xff, 0x29, 0xdc, 0xc0, 0x20, 0x26,
+ 0x59, 0x67, 0x2a, 0x9f, 0x93, 0x5a, 0xa6, 0x33, 0x98, 0xe3, 0x30, 0x86,
+ 0xb2, 0xae, 0xb1, 0x0c, 0xd7, 0xe8, 0x9d, 0x7e, 0x98, 0xee, 0x64, 0x3c,
+ 0x87, 0xd7, 0x6a, 0x60, 0xff, 0xbe, 0x1b, 0xf5, 0xc9, 0x19, 0x38, 0x56,
+ 0x5f, 0x89, 0x02, 0x1c, 0x1d, 0xee, 0x20, 0xc7, 0xef, 0x6e, 0x2f, 0x67,
+ 0x7c, 0x3a, 0x3a, 0xec, 0x44, 0x2a, 0x25, 0x39, 0x07, 0xab, 0x36, 0x39,
+ 0xe9, 0xa0, 0x2d, 0xed, 0x4a, 0xa0, 0xbe, 0x26, 0xec, 0x4f, 0xd6, 0xd8,
+ 0x55, 0xf6, 0x51, 0x85, 0x54, 0x5a, 0xe3, 0x27, 0xc0, 0x4f, 0x90, 0x9f,
+ 0x26, 0x7c, 0x8f, 0x36, 0x5b, 0x41, 0xbc, 0x7d, 0x35, 0x5d, 0x86, 0x4f,
+ 0x92, 0x5a, 0x40, 0xa7, 0x1e, 0x0c, 0x33, 0x46, 0x30, 0x2c, 0x39, 0x95,
+ 0xe1, 0x2a, 0xed, 0xf4, 0xa5, 0x50, 0x19, 0xcc, 0xd4, 0xed, 0x62, 0x42,
+ 0x79, 0xff, 0x25, 0x7f, 0x0e, 0x33, 0x5b, 0x5f, 0x3d, 0x92, 0x81, 0xf2,
+ 0x78, 0x9d, 0x41, 0x7d, 0x61, 0x0c, 0xbb, 0x48, 0x6a, 0x29, 0x5a, 0xe7,
+ 0x25, 0x7b, 0xb1, 0x51, 0x13, 0xf6, 0x7a, 0x6a, 0xec, 0x1a, 0xce, 0xa5,
+ 0x27, 0x11, 0x4f, 0xca, 0xbb, 0x6d, 0xa2, 0xc7, 0xef, 0x9b, 0x46, 0x85,
+ 0x9c, 0xc9, 0xe8, 0x44, 0x5c, 0xab, 0x64, 0x1c, 0x24, 0xef, 0x3e, 0x1e,
+ 0x0e, 0x45, 0x63, 0xa5, 0xf2, 0x9e, 0xf0, 0x92, 0x97, 0x43, 0xde, 0x96,
+ 0x7e, 0xc5, 0x78, 0xa8, 0xc4, 0x7a, 0xaf, 0xa3, 0x8b, 0x58, 0xac, 0xa9,
+ 0x4e, 0xc5, 0xdb, 0xb4, 0x05, 0x01, 0x1c, 0x4b, 0x8b, 0xdc, 0x28, 0xa7,
+ 0xb1, 0xac, 0xdc, 0x6e, 0x9c, 0x9d, 0xce, 0xea, 0xc1, 0xc6, 0xa8, 0x83,
+ 0xdf, 0xb2, 0xf7, 0x72, 0xae, 0x95, 0x3e, 0xc2, 0xda, 0xff, 0x9f, 0xdf,
+ 0x91, 0x3b, 0xbf, 0xda, 0x5e, 0x19, 0x76, 0x05, 0x97, 0xc7, 0xed, 0x9f,
+ 0xc8, 0xfb, 0xc8, 0x4f, 0x34, 0xca, 0x7b, 0x6b, 0xae, 0xe0, 0xe3, 0xa3,
+ 0xae, 0xe0, 0xda, 0xf8, 0x51, 0x85, 0xf2, 0xda, 0x57, 0x63, 0x77, 0x05,
+ 0x1f, 0xb9, 0xd1, 0x9e, 0xfb, 0xde, 0x85, 0xb1, 0x50, 0xb1, 0xa1, 0x86,
+ 0xc5, 0xa7, 0x7b, 0x03, 0x9f, 0x28, 0x96, 0x2f, 0x37, 0x4a, 0xe8, 0x63,
+ 0x9f, 0xcf, 0x8c, 0x9b, 0xed, 0xb3, 0x04, 0xab, 0xec, 0x1c, 0xeb, 0x2a,
+ 0x5e, 0x49, 0xdd, 0x78, 0xae, 0x85, 0xcf, 0x15, 0xf3, 0xb9, 0x92, 0xb0,
+ 0xc4, 0x8d, 0x5e, 0x7d, 0x95, 0xa2, 0x79, 0x8a, 0x14, 0xa9, 0x87, 0x69,
+ 0xf8, 0x55, 0xfa, 0x9f, 0xef, 0x90, 0x78, 0xb7, 0x67, 0xac, 0x12, 0x6b,
+ 0x76, 0x9b, 0x4b, 0xe6, 0x2d, 0x34, 0x97, 0xa4, 0x43, 0x31, 0xf3, 0xa5,
+ 0x6a, 0xd9, 0x4f, 0xa9, 0xf1, 0xc9, 0x33, 0x9a, 0xea, 0x63, 0x9c, 0xf9,
+ 0x4d, 0x7d, 0xbb, 0xbc, 0xa3, 0x07, 0x79, 0x7f, 0xa9, 0x90, 0x63, 0x9c,
+ 0x4c, 0x89, 0x8e, 0x6c, 0x6d, 0x77, 0x31, 0x16, 0x95, 0x77, 0x67, 0x0f,
+ 0x73, 0xef, 0x0f, 0xa6, 0xfe, 0xd7, 0x1d, 0x72, 0x76, 0x5d, 0xce, 0x06,
+ 0x00, 0xff, 0x1f, 0x17, 0x23, 0xca, 0x76, 0xf8, 0x78, 0x00, 0x00, 0x00 };
static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b09FwRodata[(0xf0/4) + 1] = {
+static const u32 bnx2_RXP_b09FwRodata[(0x124/4) + 1] = {
0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e,
0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x80080100, 0x80080080,
- 0x80080000, 0x08004efc, 0x08004efc, 0x08004fd8, 0x08004fac, 0x08004f90,
- 0x08004ecc, 0x08004ecc, 0x08004ecc, 0x08004f04, 0x08007220, 0x0800726c,
- 0x0800722c, 0x08007150, 0x0800722c, 0x0800725c, 0x0800722c, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x0800724c, 0x0800723c, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x0800723c,
- 0x080077f4, 0x080076bc, 0x080077bc, 0x08007718, 0x080076e8, 0x080075a4,
- 0x00000000 };
+ 0x80080000, 0x08004fbc, 0x08004fbc, 0x08005098, 0x0800506c, 0x08005050,
+ 0x08004f8c, 0x08004f8c, 0x08004f8c, 0x08004fc4, 0x080072ac, 0x080072f8,
+ 0x080072b8, 0x080071dc, 0x080072b8, 0x080072e8, 0x080072b8, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080072d8, 0x080072c8, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc,
+ 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080071dc, 0x080072c8,
+ 0x0800787c, 0x08007748, 0x08007844, 0x08007748, 0x08007814, 0x08007630,
+ 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748,
+ 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748, 0x08007748,
+ 0x08007770, 0x00000000 };
static struct fw_info bnx2_rxp_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
- .start_addr = 0x080031d0,
+ .start_addr = 0x080031d8,
.text_addr = 0x08000000,
- .text_len = 0x786c,
+ .text_len = 0x78f4,
.text_index = 0x0,
.gz_text = bnx2_RXP_b09FwText,
.gz_text_len = sizeof(bnx2_RXP_b09FwText),
@@ -3158,548 +3148,492 @@ static struct fw_info bnx2_rxp_fw_09 = {
.data_index = 0x0,
.data = bnx2_RXP_b09FwData,
- .sbss_addr = 0x08007980,
+ .sbss_addr = 0x08007a40,
.sbss_len = 0x58,
.sbss_index = 0x0,
- .bss_addr = 0x080079d8,
- .bss_len = 0x1c,
+ .bss_addr = 0x08007a98,
+ .bss_len = 0x20,
.bss_index = 0x0,
- .rodata_addr = 0x0800786c,
- .rodata_len = 0xf0,
+ .rodata_addr = 0x080078f4,
+ .rodata_len = 0x124,
.rodata_index = 0x0,
.rodata = bnx2_RXP_b09FwRodata,
};
static u8 bnx2_xi_rv2p_proc1[] = {
- /* Date: 06/17/2008 16:52 */
- 0xbd, 0x56, 0xcf, 0x6b, 0x1c, 0x75, 0x14, 0x7f, 0x3b, 0xbb, 0x33, 0x3b,
- 0x99, 0x9d, 0xdd, 0x99, 0xda, 0x34, 0x4c, 0xb7, 0x2b, 0xd9, 0x86, 0x5e,
- 0x36, 0x99, 0x62, 0xa2, 0x11, 0x0a, 0x46, 0x5b, 0x72, 0x09, 0xd8, 0x9e,
- 0x02, 0x95, 0x22, 0x82, 0x71, 0xa9, 0x3d, 0xd8, 0x96, 0xe2, 0x5f, 0xe0,
- 0x90, 0x9a, 0x08, 0x45, 0x0f, 0x0b, 0x36, 0x90, 0x20, 0x1a, 0x7b, 0x50,
- 0x09, 0x0a, 0x3b, 0x07, 0x41, 0x44, 0x2d, 0xa8, 0x88, 0x60, 0x3d, 0x08,
- 0x85, 0xda, 0x8b, 0x51, 0x8b, 0x8a, 0x07, 0x0f, 0x01, 0x8f, 0x9a, 0xf1,
- 0xfb, 0x7e, 0x7c, 0x37, 0x33, 0x93, 0xdd, 0x24, 0x27, 0x03, 0xed, 0x87,
- 0xf7, 0x9d, 0xf7, 0x7d, 0xdf, 0xf7, 0xde, 0xf7, 0xf3, 0x3e, 0xdf, 0xf5,
- 0x01, 0xc0, 0x80, 0x28, 0x1e, 0x55, 0x08, 0x87, 0x8c, 0xa2, 0xad, 0xa0,
- 0x00, 0xf0, 0x21, 0xf0, 0x9f, 0xe9, 0x92, 0x1d, 0x3d, 0x22, 0xf6, 0x04,
- 0x43, 0x34, 0xe1, 0xab, 0xff, 0xaf, 0xc2, 0xe9, 0x26, 0x62, 0x11, 0x4e,
- 0x1f, 0x47, 0x7c, 0x12, 0x6e, 0x37, 0x03, 0x85, 0xff, 0x26, 0x10, 0xa1,
- 0x3d, 0xdc, 0xfd, 0x24, 0xae, 0x50, 0xfc, 0x4d, 0xd9, 0xff, 0x63, 0x91,
- 0xf1, 0x54, 0x68, 0x73, 0x1c, 0x41, 0x38, 0xe9, 0x13, 0xdc, 0xed, 0xa0,
- 0x7d, 0xfe, 0x3c, 0x58, 0x18, 0xe7, 0x6d, 0xe5, 0x80, 0x76, 0xa3, 0x10,
- 0x9d, 0x94, 0xbc, 0x0c, 0xf6, 0xfb, 0xa9, 0xe3, 0xe1, 0x3a, 0xfc, 0x3c,
- 0x8b, 0xf6, 0x51, 0xe7, 0xd5, 0x0e, 0x62, 0x00, 0x97, 0x6c, 0x97, 0xeb,
- 0x19, 0xe5, 0xb0, 0x9b, 0xe3, 0xb8, 0x4f, 0xf9, 0x8e, 0x4b, 0x5c, 0x13,
- 0xe3, 0xfe, 0x99, 0x70, 0x5c, 0x8c, 0x97, 0x8e, 0xd3, 0x50, 0x71, 0x70,
- 0xdd, 0x92, 0xbc, 0xac, 0x5c, 0x5e, 0x96, 0xca, 0x43, 0xfa, 0x00, 0x3a,
- 0x0f, 0xc4, 0x23, 0xea, 0x5c, 0x8c, 0xbb, 0x25, 0x75, 0x03, 0x3c, 0xdf,
- 0x94, 0xf8, 0x31, 0xa2, 0x5b, 0xe0, 0x78, 0xea, 0x9f, 0xd4, 0xb1, 0x3b,
- 0x8e, 0xee, 0x53, 0x36, 0xff, 0x72, 0xa8, 0xbf, 0xeb, 0xfb, 0xc0, 0x73,
- 0x7e, 0x50, 0xe7, 0xa4, 0xfd, 0x61, 0x1f, 0xff, 0xef, 0x94, 0x7f, 0x36,
- 0x2e, 0xaf, 0x7f, 0xbb, 0xb3, 0xde, 0xea, 0xd7, 0x37, 0x33, 0xd7, 0xb7,
- 0x2f, 0xa5, 0x6f, 0x73, 0x70, 0xc2, 0x08, 0xc8, 0xaf, 0x04, 0x88, 0xc7,
- 0x54, 0x02, 0x88, 0x0f, 0x0b, 0x5e, 0x13, 0xbc, 0x25, 0xf8, 0xae, 0xe0,
- 0x11, 0xc1, 0x61, 0xc1, 0xc3, 0x82, 0x0f, 0x09, 0x6e, 0x09, 0xfa, 0x82,
- 0x9e, 0x60, 0x4d, 0xf0, 0x2f, 0x41, 0x57, 0xb0, 0x92, 0x8b, 0x57, 0x17,
- 0xb4, 0x05, 0x3f, 0x17, 0x7c, 0x22, 0xb7, 0xff, 0x68, 0x81, 0xf1, 0x81,
- 0xd8, 0x4f, 0x89, 0x7d, 0x41, 0x6c, 0x6c, 0xa8, 0xf0, 0x3e, 0xd3, 0xaf,
- 0x5b, 0xbd, 0xfb, 0xbd, 0xdb, 0x91, 0xef, 0x2d, 0xed, 0x67, 0x53, 0xff,
- 0x60, 0x3c, 0xed, 0xff, 0xd6, 0x1e, 0xfe, 0xec, 0x36, 0xdb, 0xea, 0xb7,
- 0xef, 0x66, 0xc2, 0x79, 0xbc, 0x29, 0xfb, 0x83, 0xee, 0x67, 0x03, 0xe6,
- 0x68, 0x26, 0xcc, 0xf3, 0xab, 0xdf, 0x1c, 0x3d, 0x2e, 0x73, 0x34, 0xbd,
- 0x8b, 0xbf, 0xcc, 0xd3, 0x33, 0xb2, 0x7f, 0x46, 0xf8, 0xd9, 0x18, 0xe0,
- 0x17, 0xa5, 0xe6, 0x95, 0xce, 0x1b, 0x30, 0x0f, 0x1f, 0x15, 0xda, 0x61,
- 0xc0, 0xfc, 0x89, 0xf6, 0xca, 0x0f, 0xf7, 0x0b, 0x7f, 0x5b, 0x9a, 0xc7,
- 0x59, 0xfe, 0x32, 0x0f, 0xad, 0x1c, 0x0f, 0x5f, 0xde, 0xe7, 0x1e, 0x2a,
- 0xb9, 0x7e, 0x5e, 0x56, 0xfe, 0x6c, 0x1a, 0x06, 0xe3, 0x1a, 0x63, 0xe8,
- 0x5a, 0x25, 0xc4, 0x69, 0xf7, 0x1b, 0x8e, 0x37, 0x4a, 0x75, 0xb8, 0xc1,
- 0x0a, 0xcd, 0x6d, 0x09, 0x56, 0xac, 0x21, 0x85, 0xff, 0x24, 0x6f, 0xb0,
- 0x5f, 0xdd, 0xfc, 0x9e, 0x30, 0x58, 0xbb, 0xc3, 0xfe, 0xf7, 0x9a, 0x9c,
- 0xf7, 0x33, 0x13, 0x90, 0xfb, 0xd3, 0xdf, 0x65, 0xde, 0x3d, 0xb4, 0xff,
- 0x2e, 0x44, 0xb1, 0x3e, 0x47, 0xf6, 0x5d, 0xd6, 0x73, 0xc4, 0x7f, 0x8b,
- 0x96, 0x4f, 0xf5, 0xde, 0x88, 0xc9, 0x1c, 0x76, 0x97, 0x7d, 0xfa, 0xfa,
- 0x7a, 0xac, 0xeb, 0x11, 0x5d, 0x19, 0xd7, 0xf5, 0xf3, 0xfe, 0x2a, 0x9d,
- 0x77, 0xb8, 0xbb, 0x9e, 0xe3, 0x49, 0xf3, 0x40, 0x3a, 0xbb, 0x95, 0xec,
- 0xe8, 0x6c, 0xba, 0x0f, 0x5a, 0x67, 0x6d, 0x58, 0x98, 0xf3, 0xe8, 0xdc,
- 0x9a, 0xc5, 0x61, 0x2e, 0x78, 0x8c, 0x17, 0x1d, 0xc6, 0xdf, 0x1c, 0xec,
- 0x53, 0x92, 0x5c, 0xaa, 0xb0, 0xfd, 0x42, 0x55, 0xcf, 0xb7, 0xde, 0xaf,
- 0xf3, 0xda, 0x2b, 0x1f, 0x3c, 0x5f, 0x9f, 0xa3, 0xf3, 0xd0, 0xe7, 0x65,
- 0x79, 0x31, 0xf8, 0x5c, 0xc6, 0xb6, 0x91, 0xed, 0xc3, 0xda, 0x24, 0x63,
- 0x69, 0x0a, 0xf3, 0xba, 0x9d, 0xf4, 0xe6, 0xbb, 0xe5, 0x93, 0xdf, 0x18,
- 0xb0, 0x3d, 0x2f, 0x3c, 0x9c, 0xa7, 0xb9, 0x54, 0xba, 0x63, 0x20, 0xd6,
- 0x21, 0xa2, 0x77, 0xc7, 0x70, 0xbe, 0x26, 0x5e, 0x14, 0x65, 0x5d, 0xdd,
- 0xc3, 0x58, 0x76, 0x9e, 0x37, 0x99, 0x77, 0x76, 0x96, 0xaf, 0xc7, 0x84,
- 0xaf, 0x4e, 0x77, 0xbd, 0xb3, 0xdf, 0x3c, 0x48, 0xc1, 0xbd, 0xfe, 0x6b,
- 0x3d, 0xd4, 0xef, 0xb2, 0xd6, 0x3d, 0xfa, 0xdc, 0x8d, 0x8a, 0x99, 0x3a,
- 0xcf, 0x40, 0xd8, 0xef, 0x7e, 0x3f, 0x16, 0x3d, 0x99, 0x16, 0x7d, 0x53,
- 0x97, 0x18, 0x65, 0xf6, 0xd5, 0x80, 0xf2, 0x29, 0xe7, 0xe6, 0xac, 0xd4,
- 0x9b, 0x9b, 0x45, 0x6b, 0x80, 0xde, 0x99, 0xfc, 0x7e, 0x2e, 0xcc, 0xe1,
- 0xb9, 0x76, 0xe3, 0x06, 0xcd, 0x7f, 0x19, 0xfe, 0x70, 0xf9, 0x5e, 0xda,
- 0x26, 0xda, 0xe6, 0xf0, 0x95, 0x4f, 0x33, 0xfd, 0x01, 0x38, 0xae, 0xdf,
- 0x97, 0xf4, 0x1c, 0x07, 0xd0, 0x9e, 0x3a, 0xe8, 0x7b, 0x99, 0xe6, 0x7d,
- 0x6d, 0x17, 0xef, 0xb5, 0x3e, 0x36, 0xc3, 0xf4, 0x9c, 0xe0, 0x3b, 0xc1,
- 0xf7, 0xcd, 0xfa, 0x54, 0xc9, 0xf7, 0x41, 0xbd, 0x9f, 0xba, 0xbe, 0x7e,
- 0xef, 0xe8, 0xaf, 0xdb, 0x07, 0xd3, 0xb3, 0x74, 0x9f, 0xfa, 0xe9, 0x99,
- 0x93, 0xd3, 0xa7, 0x7b, 0xdb, 0x3d, 0x7d, 0x32, 0xfb, 0xd5, 0xff, 0x7f,
- 0xe8, 0x36, 0xf7, 0xd3, 0x81, 0x74, 0x3d, 0x1b, 0x1b, 0xcc, 0x9f, 0xab,
- 0xa9, 0x79, 0x49, 0xdf, 0xff, 0x90, 0xf0, 0x45, 0xf9, 0x51, 0x1d, 0x5f,
- 0x6c, 0xef, 0xe8, 0x72, 0x9a, 0x7f, 0x2f, 0x0a, 0xff, 0x8d, 0x99, 0x75,
- 0xe6, 0x47, 0xfb, 0xf7, 0xdc, 0x7d, 0x4d, 0x85, 0xc8, 0x97, 0x57, 0x20,
- 0x96, 0x3c, 0xef, 0x67, 0xf2, 0xad, 0x8a, 0x2e, 0x95, 0xe1, 0x83, 0x58,
- 0xd7, 0xc5, 0x9f, 0x9b, 0x21, 0xe3, 0xfb, 0xe4, 0xef, 0xef, 0xf3, 0x2e,
- 0xf9, 0xf0, 0x5e, 0x4f, 0x7f, 0x3d, 0x8a, 0x37, 0x29, 0x3a, 0xb6, 0x20,
- 0x7a, 0xf2, 0x8b, 0xc3, 0x7a, 0xd5, 0x3e, 0x4b, 0xfc, 0x85, 0x11, 0xd1,
- 0x95, 0x76, 0x95, 0xed, 0x7a, 0x95, 0x7f, 0xef, 0x4e, 0x96, 0x5d, 0xf2,
- 0xab, 0x57, 0x19, 0x47, 0x2a, 0xb8, 0x2f, 0x80, 0x07, 0xe7, 0xc8, 0x3d,
- 0x5c, 0x75, 0xf9, 0x5d, 0x59, 0xbd, 0x23, 0x7a, 0xe7, 0xe9, 0xfe, 0x49,
- 0xbd, 0x8f, 0xe1, 0xfa, 0x88, 0xd2, 0x0f, 0xb6, 0x99, 0x17, 0x6e, 0x6f,
- 0x1e, 0xde, 0x91, 0xec, 0x9b, 0x5e, 0xba, 0xdf, 0x7a, 0x2e, 0x3b, 0xb9,
- 0x3e, 0xeb, 0x7b, 0x3a, 0x95, 0x68, 0xbd, 0x1d, 0x9b, 0xc3, 0x7c, 0x3d,
- 0xa8, 0x95, 0x99, 0x47, 0x8c, 0x2a, 0x8e, 0x51, 0xc6, 0x6d, 0x8d, 0x25,
- 0xd1, 0xaf, 0xa5, 0x45, 0x0a, 0x73, 0x6e, 0x49, 0xaf, 0xcf, 0xd2, 0xe0,
- 0xcc, 0x6f, 0x7c, 0x45, 0xeb, 0xb5, 0xb8, 0xc8, 0xeb, 0xe5, 0xb3, 0xba,
- 0x5f, 0x1e, 0xd5, 0xbf, 0xc2, 0xfd, 0x7a, 0xee, 0x26, 0xe3, 0xb3, 0xf0,
- 0x34, 0xa1, 0xb3, 0x22, 0x73, 0xbf, 0xea, 0xda, 0x84, 0x40, 0xfd, 0x32,
- 0x1e, 0xe5, 0xf7, 0xd4, 0x94, 0x77, 0x70, 0x28, 0x75, 0x8f, 0xf9, 0xf7,
- 0xea, 0xa0, 0xf7, 0x99, 0xd6, 0x6f, 0xfd, 0x9e, 0x16, 0x72, 0xbf, 0x5f,
- 0xab, 0x39, 0x7e, 0xbe, 0x34, 0x80, 0x9f, 0x87, 0x06, 0xf0, 0x3b, 0xaf,
- 0x87, 0x6d, 0x99, 0xff, 0x12, 0x98, 0x45, 0x7a, 0x08, 0xdd, 0xd2, 0x75,
- 0xba, 0x5f, 0x63, 0x89, 0x7f, 0x4f, 0xb8, 0xe6, 0x72, 0x81, 0xfa, 0xe6,
- 0x2e, 0xb3, 0x5f, 0x89, 0xd7, 0x03, 0x8d, 0xaf, 0x5d, 0xe7, 0x39, 0x33,
- 0xe0, 0x3f, 0xdd, 0xd1, 0x99, 0x07, 0x78, 0x0d, 0x00, 0x00, 0x00 };
+ /* Date: 01/27/2009 19:01 */
+#define XI_RV2P_PROC1_POST_WAIT_TIMEOUT_MSK 0xffff
+ 0xa5, 0x56, 0xdd, 0x6b, 0x1c, 0x55, 0x14, 0x3f, 0x33, 0xbb, 0x33, 0xb3,
+ 0xd9, 0x9d, 0xd9, 0x5d, 0x9a, 0x34, 0x8e, 0xb1, 0x34, 0xdb, 0x20, 0xca,
+ 0xa6, 0x13, 0xdd, 0x68, 0x1f, 0x04, 0x03, 0x2d, 0x01, 0x29, 0x98, 0xe2,
+ 0x43, 0xa0, 0x52, 0x8a, 0x60, 0x5c, 0xb4, 0x08, 0xf6, 0x2f, 0x10, 0xc1,
+ 0x21, 0x31, 0x11, 0xc4, 0xaf, 0x7d, 0xe8, 0x42, 0x02, 0x6a, 0x40, 0x50,
+ 0x09, 0x11, 0x77, 0xdf, 0x24, 0x16, 0x7c, 0x68, 0xf1, 0x41, 0xda, 0xa7,
+ 0x16, 0xd4, 0x97, 0x46, 0x11, 0xbf, 0x5e, 0x04, 0xd1, 0xc7, 0x9a, 0xf1,
+ 0x9e, 0x8f, 0xbb, 0x3b, 0x73, 0xb3, 0x9b, 0x14, 0x5c, 0x48, 0x7e, 0x9c,
+ 0x7b, 0xcf, 0x39, 0xf7, 0x7c, 0x9f, 0xa9, 0x02, 0x80, 0x0d, 0x71, 0x77,
+ 0x52, 0x21, 0x58, 0xb9, 0x5c, 0x01, 0x01, 0x60, 0x1b, 0xf8, 0xe7, 0xf8,
+ 0x44, 0xc7, 0x8f, 0x0a, 0x7d, 0x92, 0x21, 0x3e, 0x59, 0x55, 0xff, 0x2f,
+ 0xc3, 0xe9, 0x1a, 0x62, 0x0e, 0x4e, 0x9f, 0x40, 0x7c, 0x12, 0xbe, 0xae,
+ 0x85, 0x0a, 0xff, 0x4d, 0x20, 0x46, 0xfa, 0x68, 0xe7, 0xcb, 0x6e, 0x89,
+ 0xf4, 0xef, 0x8a, 0xfc, 0xf7, 0x39, 0xc6, 0x27, 0xa2, 0x02, 0xeb, 0x11,
+ 0x84, 0x99, 0x2a, 0xc1, 0xed, 0x16, 0xd2, 0xe7, 0xcf, 0x83, 0x8b, 0x7a,
+ 0xde, 0x53, 0x0c, 0x48, 0x1f, 0xb3, 0xe2, 0x19, 0xb1, 0xcb, 0x66, 0xbe,
+ 0x3b, 0xad, 0x0a, 0x9e, 0xc3, 0x8f, 0xf3, 0x48, 0xdf, 0x57, 0x7c, 0xa3,
+ 0x85, 0x38, 0x0e, 0x97, 0x0a, 0x3e, 0xfb, 0x53, 0x17, 0x9c, 0x64, 0xf5,
+ 0xbb, 0xd3, 0x28, 0xaf, 0x64, 0xa6, 0x45, 0xbf, 0x83, 0xfa, 0x7f, 0x4f,
+ 0x58, 0x3f, 0xea, 0x4d, 0xeb, 0xbb, 0x5f, 0xe9, 0xc3, 0x73, 0x57, 0xec,
+ 0x73, 0x0d, 0xfb, 0x5c, 0x65, 0x0f, 0xca, 0xaf, 0x00, 0xfb, 0x39, 0xaa,
+ 0xde, 0x45, 0xfa, 0xaf, 0xbe, 0xbe, 0x2e, 0xa2, 0x6f, 0xb1, 0xbc, 0xfa,
+ 0x13, 0xfb, 0x59, 0xee, 0x35, 0x25, 0xa7, 0xe3, 0x92, 0xb5, 0xd3, 0x8b,
+ 0xb4, 0x7f, 0x3a, 0xfe, 0xc8, 0x7f, 0x2b, 0xc9, 0xf2, 0xc3, 0x21, 0xfc,
+ 0x37, 0x15, 0x7f, 0x56, 0x2f, 0x9f, 0x7f, 0xdb, 0x3f, 0x1f, 0x18, 0x1f,
+ 0xc7, 0x88, 0xcf, 0x75, 0xf1, 0xe7, 0x29, 0x78, 0xd0, 0x0e, 0x89, 0x2f,
+ 0x0f, 0x21, 0xc5, 0x09, 0x62, 0xc4, 0xe3, 0x82, 0x2f, 0x09, 0x7e, 0x2e,
+ 0xb8, 0x2d, 0x08, 0xff, 0x13, 0xff, 0x1e, 0x72, 0x7e, 0x54, 0xf0, 0x01,
+ 0xe3, 0xfc, 0x9a, 0xe0, 0x23, 0x86, 0xfc, 0x71, 0x8b, 0xf1, 0x0f, 0xa1,
+ 0xe7, 0x85, 0x7e, 0xc6, 0x90, 0x8f, 0x81, 0xe3, 0x63, 0x19, 0x71, 0xfb,
+ 0x58, 0xea, 0x19, 0xf3, 0x2f, 0xf7, 0x75, 0xcd, 0x57, 0xa0, 0x38, 0xc2,
+ 0x74, 0x9a, 0xff, 0x83, 0x03, 0xf8, 0x99, 0x6d, 0xbe, 0x3e, 0x48, 0xae,
+ 0x9d, 0xb0, 0x1d, 0x57, 0x44, 0xbe, 0xd8, 0xb9, 0x3a, 0xa4, 0x7f, 0xe6,
+ 0xa2, 0x41, 0xfd, 0x52, 0x17, 0x3f, 0xbe, 0x92, 0xba, 0xdc, 0xb1, 0x9a,
+ 0x51, 0xc8, 0x79, 0xa5, 0x3c, 0x06, 0x52, 0x8f, 0x23, 0x46, 0x3d, 0x7b,
+ 0xaa, 0x9e, 0xa5, 0xae, 0xea, 0xba, 0xbe, 0xb2, 0x75, 0xc5, 0xf5, 0xe1,
+ 0x1a, 0xf5, 0x11, 0x1f, 0x12, 0x97, 0x92, 0xe1, 0xdf, 0xab, 0x09, 0x86,
+ 0x18, 0x7f, 0xb6, 0xcd, 0xb8, 0xc1, 0x18, 0xf9, 0x6e, 0x1e, 0xf1, 0x94,
+ 0xff, 0x0d, 0xeb, 0x9b, 0x04, 0x44, 0x3f, 0x6c, 0x53, 0x1f, 0xe5, 0xa1,
+ 0xed, 0x2a, 0x9b, 0xe1, 0x6e, 0xf2, 0x0e, 0xf3, 0x4d, 0x38, 0x37, 0x09,
+ 0xc3, 0x8d, 0x1b, 0xcc, 0xff, 0x5d, 0x8d, 0xed, 0x7e, 0x56, 0xe6, 0x53,
+ 0xff, 0xa7, 0xef, 0xa5, 0xff, 0x2a, 0x48, 0xff, 0x63, 0xc5, 0x5d, 0xfd,
+ 0x8e, 0xc8, 0xbd, 0xa2, 0xeb, 0x9b, 0x7f, 0xcb, 0x6e, 0x95, 0xfc, 0x7d,
+ 0xab, 0x4b, 0xe4, 0x98, 0xbf, 0x56, 0xa5, 0xdb, 0xb7, 0xbb, 0xda, 0x1f,
+ 0xe9, 0xf3, 0x69, 0xed, 0x3f, 0xcb, 0x07, 0x72, 0x6d, 0x3b, 0x3a, 0x7e,
+ 0x7c, 0x5e, 0x24, 0x3b, 0x46, 0x3b, 0x9b, 0x46, 0x3e, 0x6b, 0xf7, 0x34,
+ 0x07, 0xff, 0x4c, 0xfa, 0x73, 0x30, 0x1d, 0x1f, 0x3d, 0x07, 0x0b, 0xb0,
+ 0x74, 0xb6, 0x42, 0xf6, 0x94, 0x5d, 0x56, 0x73, 0xa1, 0xc2, 0xf8, 0x62,
+ 0x91, 0xf1, 0x97, 0x22, 0xc6, 0x2f, 0x49, 0x2e, 0x95, 0x98, 0x7e, 0x21,
+ 0x40, 0xbd, 0xa3, 0xea, 0x61, 0x2d, 0xaf, 0xed, 0x3a, 0xc8, 0x1e, 0x7c,
+ 0x5f, 0xbf, 0xa3, 0xed, 0xd0, 0xef, 0x65, 0xeb, 0x65, 0xf8, 0xbb, 0x8c,
+ 0x4d, 0x3b, 0x1b, 0x87, 0xfc, 0x2c, 0xe3, 0x46, 0x03, 0xed, 0xba, 0x9a,
+ 0xf4, 0xfa, 0xb0, 0x5e, 0x25, 0xbe, 0x29, 0x60, 0x7a, 0x51, 0xea, 0x73,
+ 0x91, 0xfa, 0xa7, 0xac, 0xae, 0x10, 0x27, 0x20, 0xa6, 0xbd, 0x60, 0x17,
+ 0xaf, 0x53, 0xbd, 0xe4, 0xe4, 0x5c, 0xe5, 0x67, 0x2a, 0xdb, 0x77, 0xbb,
+ 0x5c, 0x8f, 0x85, 0x6c, 0x1d, 0x3f, 0x9c, 0x9a, 0xaf, 0x69, 0x7f, 0xad,
+ 0x5e, 0xfd, 0xee, 0xcf, 0x53, 0x36, 0x1f, 0xb7, 0x5b, 0xda, 0x7f, 0x73,
+ 0x6f, 0x30, 0x7b, 0xdc, 0x90, 0x40, 0xcd, 0xca, 0xfd, 0x8c, 0xd9, 0x2f,
+ 0x83, 0xfa, 0xad, 0x6a, 0xf4, 0xcf, 0x11, 0xe9, 0xb7, 0x91, 0xce, 0x66,
+ 0xeb, 0xb0, 0x7e, 0x46, 0xfe, 0x2f, 0x64, 0x9e, 0x54, 0xa1, 0xb7, 0x97,
+ 0xb6, 0x91, 0x2e, 0x81, 0xf4, 0x61, 0x27, 0xce, 0x65, 0xf2, 0x70, 0x06,
+ 0x06, 0xce, 0x95, 0x0f, 0x45, 0x4f, 0x43, 0xe6, 0x8b, 0x9b, 0xda, 0x5f,
+ 0xc4, 0x5e, 0x06, 0xb2, 0xc3, 0x33, 0xe6, 0xc3, 0xdd, 0x3d, 0xdd, 0xef,
+ 0xcb, 0xee, 0x20, 0x7f, 0x3d, 0xf8, 0xcd, 0xe7, 0xfa, 0x68, 0x52, 0xbf,
+ 0x38, 0x63, 0x97, 0x77, 0x32, 0x79, 0x02, 0x38, 0xa1, 0xf7, 0x52, 0xda,
+ 0xae, 0xf4, 0x5e, 0x45, 0x7d, 0x21, 0x34, 0x67, 0xd3, 0xfb, 0xf5, 0xfd,
+ 0x44, 0xcf, 0xf5, 0x80, 0xfa, 0xa4, 0xbc, 0xaf, 0xef, 0xf4, 0x1c, 0xad,
+ 0x45, 0xe9, 0xfe, 0x1d, 0x93, 0xb9, 0x69, 0x03, 0xcf, 0xcd, 0x92, 0xe9,
+ 0xa7, 0xda, 0xb7, 0x83, 0xf3, 0xc5, 0xfe, 0xde, 0xd9, 0xbb, 0xb7, 0x39,
+ 0x7b, 0x58, 0xde, 0x8b, 0x46, 0xde, 0x6f, 0xf5, 0xe2, 0x68, 0x3b, 0x83,
+ 0xbe, 0x2b, 0x4e, 0x29, 0xbd, 0xc2, 0x2f, 0x73, 0xe1, 0x79, 0x9a, 0x77,
+ 0x67, 0x84, 0x6f, 0x2e, 0x55, 0xaf, 0x83, 0xf8, 0x62, 0xa3, 0xae, 0x0b,
+ 0xfb, 0xf8, 0xb2, 0x73, 0x4c, 0xfb, 0xb3, 0xb5, 0xc5, 0xf5, 0x71, 0x31,
+ 0xd5, 0xaf, 0xe9, 0xf9, 0x3f, 0x22, 0xf5, 0xa0, 0xf8, 0xc8, 0x8f, 0x9d,
+ 0xbd, 0xfe, 0xbe, 0x48, 0xd7, 0xd7, 0xa2, 0xd4, 0xb5, 0x3d, 0xb7, 0x49,
+ 0x7d, 0xe4, 0x35, 0x7f, 0x35, 0xf2, 0x35, 0x1b, 0x61, 0x9d, 0xbc, 0x0e,
+ 0x5d, 0xb1, 0xf3, 0x87, 0x8c, 0xbd, 0x81, 0xf4, 0xa1, 0x0b, 0x9f, 0x75,
+ 0xb5, 0x5f, 0x7c, 0x5d, 0x8b, 0x18, 0x3f, 0x8d, 0xa4, 0x9f, 0x7a, 0xfe,
+ 0xe1, 0xbb, 0x0b, 0xf2, 0x6e, 0x15, 0x3e, 0xe9, 0xed, 0x03, 0x9c, 0x6f,
+ 0x1e, 0x34, 0x64, 0x7e, 0x2e, 0xc9, 0x1c, 0xfb, 0xa9, 0xc8, 0x73, 0xb2,
+ 0xb9, 0x40, 0xf5, 0x0a, 0xe3, 0x32, 0xcf, 0x9a, 0x01, 0xd3, 0x13, 0x01,
+ 0x7f, 0x07, 0x37, 0x3c, 0x9f, 0xf8, 0x26, 0x02, 0xc6, 0xf1, 0x12, 0xca,
+ 0x85, 0xf0, 0xf3, 0x39, 0x62, 0x8f, 0xd6, 0x7d, 0xde, 0x73, 0xeb, 0x37,
+ 0x64, 0x9e, 0x54, 0x74, 0xdc, 0xc4, 0xcf, 0xc7, 0xf1, 0x7c, 0x5c, 0xcd,
+ 0x2d, 0xa6, 0xb9, 0x1e, 0xfc, 0x5e, 0xfd, 0x7f, 0x24, 0x59, 0xa9, 0x55,
+ 0xd2, 0x71, 0xd6, 0xfd, 0xf6, 0xae, 0x11, 0x5f, 0x9d, 0x9f, 0x87, 0x12,
+ 0x3d, 0xe7, 0xa7, 0xce, 0xa2, 0xbd, 0x15, 0x28, 0x7b, 0x5c, 0x3f, 0x8c,
+ 0x4a, 0x8f, 0xed, 0xa1, 0xd8, 0xb1, 0x55, 0x99, 0x9b, 0xab, 0xcb, 0xa4,
+ 0xe6, 0xdc, 0xaa, 0x3e, 0x9f, 0xa7, 0x86, 0x59, 0xdc, 0xba, 0x46, 0xe7,
+ 0xe5, 0x6e, 0x8e, 0xcf, 0xbd, 0x05, 0x1d, 0xaf, 0x0a, 0xf9, 0xdf, 0xe6,
+ 0x78, 0x3d, 0x77, 0x85, 0xf1, 0x22, 0x3c, 0x4d, 0x58, 0x6c, 0x4b, 0x9f,
+ 0xaf, 0xfb, 0x05, 0x42, 0xa0, 0x78, 0xd9, 0x8f, 0xf1, 0x7e, 0x77, 0x64,
+ 0x2f, 0x17, 0x52, 0xf9, 0x33, 0xf7, 0xe4, 0x41, 0x79, 0x3c, 0x62, 0xec,
+ 0x0b, 0xbd, 0xd7, 0x2d, 0xe3, 0xfb, 0x36, 0x30, 0xea, 0xf1, 0xe5, 0x21,
+ 0xf5, 0x08, 0x43, 0xea, 0xd9, 0x9c, 0x6f, 0x4b, 0xd2, 0xef, 0x79, 0x70,
+ 0x72, 0xb4, 0x78, 0xfd, 0xfc, 0x0a, 0xe5, 0xd5, 0x5e, 0xe5, 0xef, 0x1a,
+ 0xdf, 0x59, 0xb3, 0x28, 0x5e, 0xfe, 0x1a, 0xf3, 0xe5, 0xf9, 0x3c, 0xd4,
+ 0xf8, 0xe6, 0x0a, 0xf7, 0x95, 0x0d, 0xff, 0x01, 0xd7, 0x0e, 0x41, 0x60,
+ 0x88, 0x0d, 0x00, 0x00, 0x00 };
static u8 bnx2_xi_rv2p_proc2[] = {
- /* Date: 06/17/2008 16:52 */
+ /* Date: 01/27/2009 19:01 */
#define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5
#define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
#define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
- 0xad, 0x58, 0x4d, 0x4c, 0x54, 0x57, 0x14, 0xbe, 0xf3, 0xc3, 0xcc, 0x30,
- 0xbc, 0x99, 0x41, 0x98, 0x0e, 0x7f, 0xa6, 0x22, 0x28, 0x82, 0x1d, 0x14,
- 0x06, 0xd4, 0xb6, 0x36, 0xa9, 0xc1, 0x06, 0xb5, 0xb5, 0x11, 0x69, 0x63,
- 0xba, 0x68, 0x8a, 0x60, 0x45, 0x06, 0xc1, 0x10, 0x31, 0x2e, 0xdc, 0x74,
- 0x02, 0x16, 0xbb, 0x98, 0x85, 0x98, 0xe2, 0x60, 0xd3, 0x18, 0x52, 0x37,
- 0xa6, 0x3b, 0x92, 0xb6, 0x62, 0xbb, 0x30, 0x31, 0x2d, 0xb1, 0xb6, 0x89,
- 0x36, 0xb1, 0x7f, 0x9b, 0xa6, 0xa6, 0x5a, 0x8a, 0x4a, 0x2d, 0xda, 0xb2,
- 0xaa, 0xd0, 0x77, 0xcf, 0x77, 0xee, 0x9b, 0x37, 0x33, 0x6f, 0x44, 0x53,
- 0xd9, 0x1c, 0xee, 0x7d, 0xe7, 0x9e, 0x7b, 0xce, 0x77, 0x7e, 0xef, 0xe4,
- 0x0b, 0x21, 0x9c, 0x22, 0x36, 0xbe, 0x4c, 0xa7, 0x62, 0x89, 0xdd, 0xe1,
- 0xd1, 0xc9, 0x82, 0x10, 0x39, 0xc5, 0x72, 0x2d, 0xec, 0x82, 0xff, 0x56,
- 0xe7, 0x13, 0xb9, 0x36, 0x2e, 0xbf, 0xbb, 0xc5, 0xeb, 0x76, 0x7c, 0x77,
- 0x0a, 0x49, 0x03, 0x42, 0xc4, 0x24, 0xcd, 0x67, 0xba, 0x9d, 0xe9, 0x4a,
- 0x1b, 0xe8, 0x46, 0xa6, 0x51, 0xa6, 0x2b, 0x98, 0xd6, 0xdb, 0x41, 0x57,
- 0x31, 0xad, 0xe6, 0x7d, 0x8d, 0xcf, 0xd7, 0xf2, 0xfe, 0x7b, 0x4c, 0x8f,
- 0xf2, 0xbe, 0xa6, 0xf3, 0x29, 0xbd, 0xe4, 0x7a, 0x66, 0x41, 0xc4, 0xf4,
- 0x33, 0x42, 0xdf, 0xae, 0x51, 0xfb, 0x1a, 0x91, 0x58, 0x0d, 0xf4, 0x7e,
- 0xad, 0x5c, 0xf2, 0xfd, 0x61, 0xc1, 0x27, 0xf7, 0x6f, 0x2e, 0x28, 0x79,
- 0x03, 0x0e, 0xb9, 0xfe, 0x55, 0x5f, 0xdb, 0xe4, 0x32, 0x18, 0x82, 0x98,
- 0x60, 0x71, 0x5c, 0xca, 0x71, 0x88, 0xd1, 0x61, 0x0f, 0xa1, 0x72, 0x52,
- 0xc3, 0x3a, 0x46, 0x78, 0xd8, 0xf4, 0x35, 0xcb, 0x63, 0x5a, 0xe2, 0xc3,
- 0xbd, 0xbb, 0xca, 0x71, 0xdf, 0x8f, 0xcf, 0x80, 0x2f, 0x16, 0x50, 0x80,
- 0xe2, 0xfb, 0x32, 0xc1, 0xdf, 0xf7, 0xcb, 0xf5, 0xac, 0xad, 0xd0, 0x06,
- 0x5c, 0xdd, 0xcc, 0x65, 0xcf, 0x91, 0xfb, 0xcb, 0x1b, 0x4f, 0x0e, 0x83,
- 0xbf, 0xad, 0x1c, 0xfb, 0x4f, 0x87, 0xa5, 0x3c, 0x97, 0x88, 0x31, 0x15,
- 0xb5, 0xa4, 0x97, 0x2d, 0x56, 0x9b, 0x2a, 0xff, 0x97, 0x61, 0xac, 0xda,
- 0x7d, 0x90, 0xeb, 0x4d, 0x91, 0x1b, 0xca, 0x90, 0xfb, 0x53, 0xae, 0x59,
- 0xbe, 0xdf, 0x06, 0xf9, 0xde, 0x45, 0xe5, 0x77, 0xf8, 0x40, 0x0b, 0xc3,
- 0x56, 0xf7, 0xe4, 0x2e, 0xa2, 0x7f, 0xf7, 0xa2, 0xf2, 0x8f, 0x18, 0xfa,
- 0x2b, 0xff, 0xa9, 0xef, 0xe9, 0x38, 0xd2, 0xf2, 0xe3, 0xd8, 0x5a, 0x16,
- 0xb3, 0x5a, 0xd9, 0xcf, 0x7a, 0x3a, 0x40, 0x37, 0x85, 0x89, 0xc4, 0xf7,
- 0x70, 0x80, 0x37, 0x57, 0xc9, 0xfb, 0x0b, 0x84, 0xd3, 0x2e, 0xe5, 0xd5,
- 0x79, 0x5c, 0xe7, 0xb1, 0xff, 0x06, 0xfb, 0xeb, 0x6d, 0x36, 0xe8, 0xa6,
- 0x57, 0x02, 0xb4, 0xb0, 0xd0, 0x99, 0xc7, 0xf2, 0xd9, 0xdf, 0xb1, 0x3c,
- 0x9c, 0x9f, 0xd4, 0xa4, 0x9e, 0x5f, 0xeb, 0xf1, 0x63, 0xe5, 0x7f, 0xc7,
- 0x43, 0xfc, 0x8f, 0xf3, 0x4b, 0x56, 0xe1, 0xeb, 0xf1, 0x4e, 0xac, 0xcb,
- 0xce, 0xe4, 0x13, 0x4e, 0xa3, 0xe3, 0x56, 0xf1, 0x92, 0x2e, 0x5f, 0xcf,
- 0xe3, 0x00, 0xee, 0x11, 0x15, 0x1e, 0x52, 0x0e, 0xf8, 0xea, 0x3c, 0xb5,
- 0x96, 0x38, 0x89, 0x93, 0x2b, 0xe5, 0xbe, 0x5d, 0xb4, 0x3a, 0x34, 0xba,
- 0xa7, 0x35, 0xaa, 0xf2, 0x06, 0xdf, 0x3b, 0x5d, 0x44, 0x8a, 0xdb, 0x87,
- 0xa4, 0xdd, 0x01, 0xb1, 0xdb, 0x1e, 0x20, 0x7e, 0xe0, 0xe4, 0xf0, 0x68,
- 0x9f, 0x81, 0xff, 0xc2, 0x32, 0x8d, 0x6c, 0xea, 0x6c, 0xc0, 0xb9, 0x60,
- 0x04, 0x74, 0x24, 0x92, 0x23, 0x49, 0xb8, 0xb3, 0x9f, 0x96, 0x6b, 0x7e,
- 0xab, 0xf7, 0x10, 0x5f, 0xac, 0x56, 0xe5, 0xa5, 0xf2, 0xa3, 0xc4, 0xed,
- 0x90, 0x91, 0x87, 0xa2, 0x12, 0x38, 0xff, 0xbe, 0x52, 0xf2, 0xeb, 0x60,
- 0x57, 0xe0, 0x9e, 0xa4, 0x7e, 0xe6, 0xbc, 0xee, 0x35, 0xe5, 0xf5, 0xe3,
- 0xc5, 0xc5, 0x26, 0xc2, 0x67, 0x13, 0xe3, 0x54, 0xce, 0x71, 0xb8, 0xd4,
- 0x22, 0x0e, 0x03, 0xf4, 0xff, 0xad, 0xa6, 0x7c, 0xc2, 0x79, 0x07, 0xf6,
- 0x4f, 0x34, 0x9f, 0x83, 0x9f, 0xb6, 0x11, 0x1e, 0xc2, 0x7b, 0xf4, 0x53,
- 0x9c, 0x6a, 0xa7, 0xfc, 0xef, 0x6d, 0xec, 0xfc, 0x1c, 0xeb, 0x0e, 0x87,
- 0x5c, 0xef, 0xd7, 0xf6, 0x4c, 0x80, 0x3f, 0x67, 0x10, 0xb8, 0xef, 0xe0,
- 0x5b, 0xb6, 0x39, 0xa8, 0xde, 0xc4, 0x5d, 0x83, 0xb4, 0xd4, 0x26, 0xe9,
- 0x7b, 0xbe, 0x38, 0x36, 0x8e, 0xef, 0x07, 0xf2, 0xa4, 0x9d, 0xaf, 0x1a,
- 0x75, 0x29, 0xea, 0xc2, 0xf9, 0xf8, 0x30, 0xea, 0xca, 0xf4, 0x27, 0x72,
- 0xdd, 0x16, 0x9e, 0x06, 0x7f, 0x38, 0x3a, 0xc4, 0x82, 0xed, 0xc0, 0xf1,
- 0x96, 0x1d, 0xfc, 0x1c, 0xae, 0x5e, 0x27, 0xf9, 0xd1, 0x26, 0xb4, 0x66,
- 0xd0, 0x77, 0xe9, 0xfb, 0xbf, 0xb6, 0x38, 0xe1, 0xb6, 0xcb, 0xef, 0x3c,
- 0xa7, 0xf0, 0x61, 0x1a, 0x50, 0x76, 0x81, 0x3e, 0x6a, 0x3e, 0x0c, 0x69,
- 0xd9, 0xf2, 0x80, 0xfd, 0x59, 0xb3, 0x58, 0x1e, 0x80, 0x36, 0x57, 0x81,
- 0xba, 0x2a, 0xa9, 0x9e, 0x3c, 0x46, 0x3e, 0xb0, 0x5e, 0x19, 0xf9, 0x86,
- 0xdd, 0x64, 0x9c, 0x12, 0xd1, 0xe3, 0x33, 0x25, 0x5e, 0x39, 0x3f, 0x96,
- 0xeb, 0x7e, 0x50, 0x71, 0x27, 0x05, 0xba, 0xc5, 0x7e, 0x96, 0x1b, 0x65,
- 0x3c, 0x7a, 0x18, 0x8f, 0x19, 0xa6, 0x07, 0xf2, 0x14, 0x0e, 0xa0, 0xc7,
- 0x34, 0xdc, 0xdb, 0x1a, 0x95, 0x7e, 0x0c, 0x5a, 0xf4, 0x17, 0xd5, 0x47,
- 0xe0, 0xa7, 0x51, 0xf6, 0xeb, 0x29, 0xa3, 0x9f, 0x28, 0x7c, 0xb3, 0xf5,
- 0x95, 0xd4, 0x7c, 0x4a, 0xb3, 0x33, 0xfe, 0x55, 0x05, 0x8e, 0x17, 0x54,
- 0x82, 0x1a, 0xf8, 0x56, 0x51, 0x1e, 0xfb, 0x8b, 0x26, 0x94, 0x7d, 0x52,
- 0xbf, 0x3b, 0x2a, 0x0f, 0xfd, 0x89, 0x01, 0xa2, 0xde, 0x82, 0x33, 0xf2,
- 0x9e, 0x52, 0x8b, 0xba, 0x92, 0x9a, 0xcf, 0xe9, 0xf8, 0x1e, 0xf0, 0x51,
- 0xc1, 0x6d, 0xbc, 0x32, 0x95, 0x9a, 0xb7, 0xc8, 0x4f, 0xb7, 0x11, 0xdf,
- 0xc1, 0xf5, 0xec, 0x07, 0xa6, 0xa1, 0x0d, 0x52, 0x6e, 0x0b, 0xdf, 0x53,
- 0xc7, 0xf7, 0x68, 0xa6, 0xba, 0x21, 0xf5, 0xfc, 0x73, 0x5e, 0xd5, 0x0b,
- 0x15, 0x1f, 0xc9, 0xba, 0xa1, 0xfc, 0x40, 0xf7, 0x87, 0xaf, 0x4c, 0xc9,
- 0xf3, 0x65, 0x8b, 0xd4, 0x91, 0x1b, 0x86, 0xbc, 0xef, 0x8d, 0x3a, 0x21,
- 0xbf, 0xe7, 0x89, 0x17, 0x79, 0x99, 0x5a, 0x0f, 0xff, 0xd2, 0xeb, 0x21,
- 0xd9, 0xe1, 0xd1, 0xce, 0x71, 0xfd, 0xeb, 0x97, 0xf7, 0x14, 0xb3, 0xde,
- 0xc5, 0xaa, 0xaf, 0xe9, 0x7a, 0x73, 0x9d, 0x6c, 0x33, 0xd7, 0xbb, 0x1f,
- 0xe6, 0x93, 0x75, 0x4b, 0xae, 0xaf, 0xcd, 0x67, 0xce, 0x27, 0x96, 0xb8,
- 0xc6, 0x44, 0x00, 0x73, 0x58, 0x2c, 0x20, 0xcf, 0xe5, 0xd8, 0x32, 0xeb,
- 0x5f, 0xba, 0x1d, 0xc0, 0xa5, 0xdd, 0xee, 0x23, 0xbe, 0xeb, 0x7d, 0xf2,
- 0xdc, 0xb4, 0x50, 0xf6, 0xa2, 0x0e, 0x96, 0x73, 0xbf, 0x5f, 0xca, 0x7a,
- 0xeb, 0xf2, 0x6a, 0x29, 0x1f, 0x3c, 0xd7, 0xfb, 0xcc, 0x7a, 0x5f, 0x98,
- 0xcf, 0x7e, 0x9f, 0x75, 0x1c, 0xf4, 0x71, 0x9f, 0xe5, 0x39, 0xc1, 0xb3,
- 0xe7, 0x0b, 0xa5, 0x17, 0xdf, 0x1f, 0x50, 0x7a, 0x68, 0xe4, 0xa7, 0xa9,
- 0x7e, 0x29, 0xa7, 0x50, 0x70, 0xd8, 0x88, 0xde, 0x6a, 0xd4, 0xdf, 0x99,
- 0xbd, 0xb0, 0xa3, 0xb7, 0x4a, 0xea, 0xa1, 0x7b, 0x25, 0x86, 0x3c, 0x17,
- 0xdc, 0x8f, 0xbe, 0x1c, 0xb6, 0xf2, 0xeb, 0xb7, 0xcc, 0x17, 0x64, 0xfb,
- 0xf2, 0xd9, 0xbe, 0xb0, 0x48, 0xaf, 0xf3, 0x6d, 0xe5, 0xd4, 0x0f, 0x98,
- 0xef, 0x05, 0xd5, 0x0f, 0x74, 0x3e, 0xc2, 0x99, 0xe5, 0x58, 0xe1, 0x64,
- 0x25, 0x67, 0x82, 0xe3, 0xa0, 0x8b, 0xf9, 0x9c, 0x59, 0xe7, 0x9b, 0xb9,
- 0x55, 0xd4, 0x57, 0x4e, 0x1f, 0xa1, 0xfe, 0xe0, 0x33, 0xe2, 0x34, 0xd5,
- 0x8e, 0xe3, 0x4f, 0x10, 0x77, 0x9a, 0xff, 0xc4, 0x3e, 0x7f, 0x36, 0x7c,
- 0x9d, 0x72, 0x7b, 0x6c, 0x76, 0x42, 0xf9, 0x47, 0x23, 0x7b, 0xa7, 0xfa,
- 0xd5, 0x9c, 0x6f, 0xc6, 0xdd, 0x6e, 0xc2, 0x1d, 0xfc, 0x98, 0xef, 0xfe,
- 0x0f, 0xde, 0x56, 0xf3, 0x41, 0x9f, 0x91, 0x9f, 0x03, 0x2e, 0xab, 0xfa,
- 0xbf, 0xd6, 0x88, 0x97, 0x83, 0x3c, 0xe7, 0xcd, 0x69, 0xf4, 0x4f, 0x64,
- 0x26, 0x4e, 0x4b, 0xad, 0xe4, 0xac, 0xe4, 0x5b, 0x1d, 0x39, 0xc8, 0x76,
- 0x5d, 0x76, 0xc0, 0xee, 0xae, 0xbd, 0x58, 0x5f, 0xe1, 0x7a, 0x7d, 0x8f,
- 0xeb, 0xe3, 0x4e, 0x0f, 0xe8, 0x4c, 0x35, 0xe1, 0x11, 0x39, 0x78, 0x5e,
- 0xc9, 0x27, 0xb9, 0xda, 0x1c, 0xe3, 0xf9, 0x92, 0x83, 0xed, 0xac, 0x20,
- 0x3f, 0x46, 0xee, 0x52, 0x3d, 0x70, 0x8a, 0xa6, 0xe5, 0x92, 0x96, 0xe8,
- 0xb8, 0xb1, 0x3e, 0x1b, 0x41, 0x5b, 0xd5, 0x80, 0x5f, 0x93, 0xee, 0x67,
- 0x6c, 0xbb, 0x2a, 0xf8, 0x7c, 0x3b, 0xd6, 0x6e, 0xae, 0x67, 0x09, 0xd6,
- 0xeb, 0xfd, 0x6a, 0x50, 0x7f, 0x0d, 0xe6, 0x84, 0x29, 0xea, 0x0b, 0x81,
- 0x48, 0xff, 0x04, 0xec, 0xe9, 0xd9, 0x0c, 0x7b, 0xef, 0x33, 0x0e, 0x4c,
- 0xfd, 0xa7, 0x06, 0xa9, 0xef, 0xf8, 0x87, 0x30, 0x67, 0xf8, 0x5d, 0x83,
- 0xb0, 0xa3, 0x67, 0x0e, 0xeb, 0xfb, 0xcf, 0x81, 0xfe, 0xf3, 0x3c, 0xce,
- 0x1d, 0x3a, 0xc2, 0xf8, 0x6c, 0xb6, 0x3e, 0xd7, 0xf5, 0x37, 0xf8, 0x7a,
- 0xab, 0xe5, 0xfd, 0x6f, 0x8d, 0xf1, 0xfc, 0x21, 0xa2, 0x34, 0xef, 0xbc,
- 0xa9, 0xcd, 0xf1, 0xba, 0x9b, 0xfb, 0xe2, 0x6d, 0x9e, 0x17, 0x7a, 0xd2,
- 0xe6, 0x85, 0x69, 0xd4, 0xe9, 0xb1, 0xb9, 0xb8, 0xdc, 0xd0, 0xeb, 0x65,
- 0xae, 0x95, 0x7f, 0x7d, 0x91, 0x22, 0xf6, 0x5b, 0x70, 0x1d, 0xe8, 0xc8,
- 0x3a, 0xf4, 0xeb, 0x9e, 0xc3, 0x8c, 0x4f, 0x23, 0xf9, 0x69, 0xcd, 0xec,
- 0x44, 0xfa, 0x79, 0x19, 0x3f, 0xed, 0xf3, 0x78, 0x3f, 0x6e, 0xd6, 0xa9,
- 0xba, 0x0f, 0xe7, 0x3a, 0xe8, 0x7d, 0x71, 0xcf, 0x98, 0x3f, 0xa7, 0x49,
- 0xff, 0xb2, 0xb1, 0x39, 0x92, 0x53, 0x2a, 0x0a, 0x29, 0x0e, 0x4b, 0xfc,
- 0xb3, 0xb0, 0x27, 0x92, 0x60, 0x1c, 0xfa, 0x9e, 0x05, 0x3d, 0xcc, 0x71,
- 0xa0, 0xfc, 0x7b, 0x75, 0x83, 0x46, 0xe7, 0xa6, 0xfa, 0x71, 0x8f, 0xca,
- 0xa3, 0xf4, 0xb9, 0x58, 0xc5, 0x45, 0x49, 0x03, 0xad, 0x45, 0xd7, 0x21,
- 0xb2, 0x53, 0xf7, 0xa7, 0x8c, 0x27, 0x1d, 0x2b, 0xee, 0xdb, 0xa9, 0xf1,
- 0x22, 0xe3, 0x49, 0xc5, 0xad, 0x39, 0xce, 0xcc, 0x71, 0x94, 0x1a, 0x3f,
- 0x7e, 0xea, 0x2f, 0x7a, 0x31, 0xa0, 0x77, 0x89, 0x2b, 0x92, 0x18, 0x7e,
- 0x38, 0x8e, 0xa7, 0x80, 0x63, 0x84, 0xf5, 0xd6, 0xa2, 0x34, 0x8f, 0x3e,
- 0x25, 0x86, 0xd8, 0x9f, 0xd3, 0xd5, 0x9c, 0xff, 0x15, 0xf0, 0x67, 0xdf,
- 0x0a, 0xe8, 0xd3, 0xc7, 0x79, 0x74, 0x87, 0xe7, 0x0c, 0xc4, 0x81, 0x5b,
- 0xeb, 0x9c, 0x60, 0xbf, 0x73, 0x3c, 0x76, 0x33, 0x0e, 0xb7, 0x81, 0x83,
- 0xa6, 0x70, 0x88, 0x1a, 0x38, 0xa8, 0x7a, 0x63, 0x96, 0x53, 0xa0, 0xc7,
- 0x93, 0xa4, 0x4b, 0xb4, 0xab, 0x34, 0x8f, 0xe5, 0xb0, 0xdd, 0x3a, 0x5f,
- 0x83, 0xb4, 0xcf, 0xcf, 0xf6, 0xf9, 0xc4, 0xbe, 0x35, 0xe6, 0x73, 0x79,
- 0x7c, 0xce, 0xab, 0x9f, 0xc3, 0x3e, 0xf2, 0x55, 0xcb, 0x82, 0xaf, 0xc4,
- 0x51, 0xc9, 0x4d, 0xcf, 0x4b, 0x33, 0x9e, 0x54, 0xa9, 0xe9, 0x0f, 0xf5,
- 0x48, 0xf7, 0x1b, 0xd5, 0x2d, 0xcd, 0xa8, 0x43, 0xf7, 0xa8, 0xae, 0x7b,
- 0x4f, 0xf7, 0xa2, 0x6e, 0x9c, 0xee, 0x3d, 0xcb, 0x7d, 0x98, 0x71, 0x69,
- 0xa1, 0xf7, 0x83, 0x8e, 0x5d, 0x45, 0x6a, 0x1d, 0x4a, 0xd5, 0xa3, 0xcc,
- 0xa4, 0x87, 0xba, 0x77, 0xb1, 0x39, 0x01, 0x73, 0xea, 0x16, 0x9a, 0x13,
- 0x3c, 0xc6, 0xbc, 0x9d, 0xda, 0x4f, 0x26, 0x1f, 0x3c, 0x6e, 0x3f, 0xd9,
- 0xd9, 0x60, 0xbe, 0xaf, 0x46, 0x4c, 0x8e, 0xe3, 0x9e, 0x16, 0xee, 0xdf,
- 0xbb, 0x39, 0xcf, 0xaf, 0x7b, 0x03, 0x74, 0x6f, 0xc7, 0x2b, 0x64, 0xaf,
- 0x08, 0xe5, 0xc1, 0xbe, 0x8e, 0xed, 0xf8, 0xde, 0xe1, 0xc3, 0x7e, 0xa9,
- 0x0f, 0xbf, 0xa3, 0xb4, 0xb8, 0x35, 0xe2, 0x2f, 0xf5, 0x81, 0x86, 0xb8,
- 0x3e, 0x4c, 0x1a, 0xef, 0x09, 0xd0, 0x51, 0x57, 0xb6, 0xf7, 0x04, 0xde,
- 0x65, 0x17, 0x5d, 0xa8, 0x1f, 0xa2, 0x06, 0x73, 0x74, 0x53, 0x95, 0x46,
- 0xdf, 0x5b, 0x6b, 0xd0, 0xa7, 0x51, 0x9f, 0x33, 0xed, 0x2a, 0x43, 0xbc,
- 0x96, 0x26, 0xdf, 0x1d, 0xe6, 0xf7, 0x89, 0x16, 0x49, 0x18, 0xf3, 0x7f,
- 0xaa, 0x1e, 0xc8, 0x33, 0x29, 0x9f, 0x96, 0xfa, 0x9c, 0xfd, 0x28, 0xef,
- 0x12, 0x07, 0xcf, 0x6d, 0x77, 0xf9, 0x77, 0x82, 0x42, 0x71, 0x69, 0x1c,
- 0x38, 0x4c, 0x8e, 0x5b, 0xe5, 0xb1, 0xd4, 0x43, 0xdd, 0x03, 0xbb, 0x94,
- 0x9d, 0xc9, 0x7b, 0xa1, 0xd7, 0x5e, 0xd6, 0xff, 0x06, 0xfd, 0x9e, 0x11,
- 0x62, 0x7b, 0xa5, 0x5c, 0xec, 0x6f, 0xa5, 0xf7, 0x53, 0x8e, 0x88, 0x19,
- 0xeb, 0xd4, 0x77, 0x4d, 0x0b, 0xe9, 0x55, 0xc0, 0xfd, 0x3d, 0x64, 0x9a,
- 0x43, 0xc0, 0x1f, 0xac, 0x03, 0x1d, 0xa9, 0x53, 0x7e, 0x53, 0xfe, 0x55,
- 0xfe, 0x84, 0xdf, 0x43, 0xf5, 0xc4, 0xd6, 0xd8, 0x51, 0x4f, 0x09, 0x5f,
- 0xd7, 0x31, 0xab, 0xfa, 0x3d, 0xce, 0xef, 0x0c, 0x4b, 0xfe, 0x77, 0xc4,
- 0x77, 0x61, 0x34, 0xd8, 0x9f, 0x99, 0x26, 0xe7, 0x7c, 0xc1, 0x7f, 0xe6,
- 0xf7, 0x82, 0x43, 0x5c, 0xcc, 0xe1, 0xed, 0x06, 0x35, 0xff, 0x66, 0x7b,
- 0xf7, 0x48, 0x3b, 0xba, 0x1f, 0xa4, 0xcf, 0xd3, 0xc9, 0x79, 0x58, 0xd9,
- 0x2b, 0xcf, 0xd5, 0x71, 0x1c, 0x7b, 0x44, 0xd3, 0x16, 0xfc, 0xce, 0xe1,
- 0x77, 0x23, 0x6f, 0xfc, 0x6e, 0xab, 0xf7, 0xa9, 0x1e, 0x47, 0xb9, 0x54,
- 0x30, 0x96, 0x16, 0xe4, 0x92, 0x7d, 0x27, 0x2e, 0x7f, 0x43, 0x6c, 0x1f,
- 0x25, 0xf2, 0xb0, 0x5f, 0xd4, 0x84, 0x6b, 0x9c, 0x14, 0xf7, 0x0e, 0x71,
- 0x14, 0x79, 0xf1, 0xe1, 0x08, 0xe8, 0x07, 0xe2, 0x65, 0xc8, 0x29, 0x18,
- 0xa0, 0xbe, 0xea, 0x29, 0x02, 0xcc, 0xf1, 0x04, 0xc7, 0x7b, 0xb1, 0x9d,
- 0x7e, 0x87, 0x5d, 0x10, 0x3e, 0xfe, 0x9d, 0x8c, 0xf3, 0x17, 0x71, 0xed,
- 0x34, 0xf9, 0xff, 0x51, 0xe3, 0x1c, 0xfd, 0x33, 0xc1, 0x7e, 0xe7, 0x78,
- 0xf7, 0xa4, 0xc7, 0xbb, 0xc2, 0xa9, 0xd8, 0x6e, 0x19, 0xdf, 0xeb, 0x33,
- 0xe3, 0x5b, 0xe9, 0x97, 0xda, 0x3f, 0x33, 0xe5, 0xe3, 0x1d, 0x75, 0xe9,
- 0x89, 0xc5, 0x37, 0xe8, 0xd6, 0x4a, 0x79, 0x7f, 0x51, 0xc6, 0xbc, 0x9c,
- 0x9e, 0x7f, 0xa8, 0x77, 0xd5, 0x7a, 0x3c, 0xfc, 0x07, 0xd7, 0x0d, 0x36,
- 0x4f, 0xf0, 0x16, 0x00, 0x00, 0x00 };
+ 0xad, 0x57, 0x4d, 0x68, 0x5c, 0x55, 0x14, 0xbe, 0x33, 0x6f, 0x7e, 0xde,
+ 0xcc, 0xbc, 0xc9, 0x4c, 0x93, 0x38, 0x99, 0x26, 0xc5, 0xa4, 0x09, 0x8d,
+ 0x4e, 0x9d, 0x69, 0x27, 0x3f, 0x44, 0xb0, 0x42, 0x43, 0x90, 0xb4, 0xb5,
+ 0x4a, 0xd3, 0x28, 0xc5, 0x5d, 0x92, 0xa9, 0x1d, 0x8c, 0x69, 0x23, 0x18,
+ 0x70, 0xe1, 0xc6, 0x47, 0x5a, 0xd3, 0xcd, 0x2c, 0x4c, 0x31, 0x3f, 0x8a,
+ 0xa0, 0xd8, 0x9d, 0xb8, 0x19, 0x50, 0xdb, 0x8a, 0x22, 0x14, 0x0c, 0x52,
+ 0x17, 0x45, 0xb0, 0x58, 0x37, 0x8a, 0x58, 0x1b, 0x1a, 0x11, 0x8d, 0x8b,
+ 0xae, 0x24, 0xe3, 0xbd, 0xe7, 0x3b, 0xf7, 0xcd, 0xbc, 0xc9, 0x8b, 0x89,
+ 0x62, 0x36, 0x27, 0xe7, 0xbe, 0x73, 0xcf, 0x39, 0xf7, 0x9c, 0xef, 0x7c,
+ 0xf7, 0x4e, 0x52, 0x08, 0x11, 0x10, 0x76, 0xb9, 0x5d, 0x4a, 0xe1, 0x33,
+ 0x0c, 0x53, 0x8a, 0x8a, 0x10, 0xc1, 0xb4, 0xd2, 0x85, 0x5f, 0xf0, 0xdf,
+ 0xfe, 0x24, 0x89, 0x6f, 0xcb, 0x96, 0x32, 0x13, 0x76, 0x46, 0xd9, 0x45,
+ 0xc4, 0xb3, 0xfe, 0x88, 0x94, 0x87, 0xc5, 0x68, 0x06, 0xf6, 0x01, 0xa1,
+ 0xa4, 0xb4, 0xb5, 0x95, 0xdc, 0xc5, 0xf2, 0x38, 0xcb, 0xc7, 0x7d, 0x90,
+ 0x87, 0x58, 0x3e, 0x56, 0x27, 0x05, 0xdb, 0x3d, 0xcd, 0xfa, 0x00, 0x4b,
+ 0x8b, 0xd7, 0x47, 0x59, 0xff, 0x90, 0xa5, 0xcd, 0xeb, 0x61, 0xd6, 0x1f,
+ 0xf0, 0xa9, 0x25, 0xe4, 0xab, 0xf4, 0xb5, 0x4a, 0x55, 0xb7, 0xe0, 0x3e,
+ 0x83, 0x73, 0x3c, 0xd3, 0xa1, 0xbe, 0xdf, 0xad, 0xb8, 0xed, 0xef, 0x38,
+ 0xfa, 0xac, 0xa1, 0xf4, 0x1f, 0xa5, 0xee, 0x53, 0x6a, 0x73, 0x0a, 0xdb,
+ 0x9b, 0xd3, 0x25, 0xb5, 0xdf, 0x10, 0xcb, 0xf3, 0x26, 0x55, 0x67, 0xd1,
+ 0x82, 0x6e, 0x97, 0x4d, 0xaa, 0xcb, 0xa2, 0xc5, 0xfe, 0x58, 0xee, 0x8e,
+ 0x23, 0xde, 0xa9, 0x0e, 0xd4, 0xed, 0xbb, 0x47, 0x60, 0x67, 0x27, 0x74,
+ 0x61, 0xf1, 0xbd, 0x5d, 0xf0, 0xf7, 0x29, 0xa5, 0xaf, 0xfb, 0x9a, 0x7c,
+ 0xa8, 0x47, 0x98, 0xad, 0xfc, 0x41, 0xb5, 0xbe, 0xb7, 0x7f, 0x71, 0x1e,
+ 0xf6, 0x63, 0x1d, 0x58, 0x7f, 0x30, 0xab, 0xfc, 0x85, 0x84, 0xcd, 0x52,
+ 0xe4, 0x28, 0x2f, 0x9f, 0x9d, 0x73, 0xfb, 0xff, 0x61, 0x1e, 0xda, 0x44,
+ 0x1c, 0x7e, 0xa3, 0x2e, 0xbf, 0xa9, 0x4d, 0x7e, 0x6f, 0x47, 0x6a, 0xfd,
+ 0x37, 0xf8, 0xe0, 0x3f, 0xba, 0xad, 0xff, 0x42, 0x1c, 0xb2, 0x29, 0xeb,
+ 0x15, 0x27, 0xb2, 0x4d, 0xfe, 0x2f, 0x6e, 0xeb, 0xff, 0x55, 0x27, 0x7f,
+ 0xbd, 0x5e, 0x5f, 0x3f, 0x52, 0x3f, 0xb0, 0x0f, 0xf2, 0xf6, 0xfd, 0xfa,
+ 0xdc, 0x9c, 0x9f, 0x01, 0x39, 0x98, 0x25, 0x51, 0x3a, 0xcd, 0x00, 0x1f,
+ 0xee, 0x56, 0x71, 0x1b, 0x45, 0xc0, 0xaf, 0xfc, 0x1d, 0x30, 0x43, 0xd7,
+ 0xb0, 0xfe, 0x1c, 0xf7, 0xe9, 0x79, 0x3e, 0xc8, 0x2f, 0x51, 0x55, 0x98,
+ 0x4a, 0xa5, 0x18, 0x63, 0xff, 0xdc, 0x67, 0x3b, 0x86, 0xfd, 0x2b, 0x96,
+ 0xca, 0xef, 0x86, 0xc4, 0x8d, 0x57, 0xdf, 0x8d, 0x7f, 0xe8, 0x3b, 0xf6,
+ 0xef, 0x7a, 0x08, 0x5f, 0xdf, 0x28, 0x42, 0x6f, 0xbb, 0x9c, 0xa4, 0xfa,
+ 0x2c, 0x97, 0xbd, 0x70, 0x52, 0xef, 0x5f, 0xce, 0x71, 0x02, 0x71, 0x44,
+ 0xa7, 0x49, 0xc9, 0xa1, 0xae, 0xd2, 0x26, 0xe7, 0x59, 0x27, 0xb1, 0xb8,
+ 0x4f, 0xcf, 0x05, 0xf4, 0x62, 0x88, 0x44, 0x7a, 0x62, 0x4e, 0x9d, 0x33,
+ 0x21, 0xc6, 0xfd, 0x2a, 0x61, 0x3f, 0xd7, 0xc5, 0x30, 0xad, 0x4f, 0x60,
+ 0xff, 0x45, 0xbb, 0x45, 0x67, 0x28, 0xf6, 0x61, 0x5f, 0x73, 0x2f, 0xe4,
+ 0x42, 0x6f, 0x50, 0x89, 0x6c, 0x71, 0x86, 0xd4, 0x03, 0x3f, 0xf7, 0x98,
+ 0x64, 0x67, 0xe7, 0xf4, 0xdc, 0xe9, 0xbe, 0xa9, 0x3a, 0xbd, 0x52, 0x9d,
+ 0xbf, 0x2e, 0xd4, 0xf5, 0xee, 0x3e, 0x65, 0x2f, 0x8b, 0xdb, 0x89, 0x38,
+ 0xa3, 0x93, 0x5e, 0x73, 0xfb, 0x92, 0x53, 0xdf, 0x9d, 0xf6, 0x7f, 0x90,
+ 0xea, 0x30, 0xc8, 0xf5, 0xe8, 0x60, 0x9c, 0xed, 0xf1, 0xc0, 0x59, 0x82,
+ 0xfe, 0x5f, 0x1b, 0x4a, 0x52, 0x3d, 0x4f, 0x60, 0xfd, 0xd2, 0xf0, 0x15,
+ 0xf4, 0xe3, 0x18, 0xd5, 0x41, 0x44, 0x2f, 0x7c, 0x8c, 0x5d, 0x13, 0x34,
+ 0xdf, 0xe7, 0xfa, 0x8b, 0x9f, 0x42, 0x2f, 0x18, 0x4a, 0x9f, 0xb2, 0x4e,
+ 0x5f, 0x85, 0x7d, 0xf0, 0x7c, 0x92, 0xea, 0x77, 0x82, 0xa3, 0x1c, 0x33,
+ 0x88, 0x4f, 0x4a, 0xa1, 0xf3, 0xa4, 0x5a, 0x2b, 0xf4, 0x3d, 0x29, 0x2e,
+ 0x96, 0xf1, 0x7d, 0x3a, 0xa6, 0xce, 0x37, 0xe2, 0xf0, 0xce, 0x64, 0x08,
+ 0xfb, 0x4b, 0xf3, 0xe0, 0x8d, 0x7b, 0x1f, 0x29, 0x7d, 0x2c, 0x7b, 0x0f,
+ 0xf6, 0xd9, 0xc9, 0x39, 0x76, 0xec, 0x47, 0xfd, 0xd6, 0xfc, 0xb0, 0x67,
+ 0x58, 0x46, 0x03, 0xd4, 0x3f, 0x9f, 0xb0, 0x86, 0x21, 0x5f, 0xa7, 0xef,
+ 0x7f, 0xf9, 0x4a, 0x54, 0xb7, 0x53, 0x0d, 0x81, 0x2b, 0xba, 0x3e, 0x2c,
+ 0x13, 0xfa, 0x5c, 0x90, 0x3b, 0xc5, 0xfd, 0x9c, 0xb5, 0x15, 0xde, 0xb9,
+ 0x8f, 0x99, 0xed, 0xf0, 0x0e, 0x39, 0xdc, 0x0d, 0x19, 0xea, 0x22, 0xbe,
+ 0xf8, 0x17, 0xb8, 0xe7, 0xbc, 0x36, 0xcd, 0x15, 0x56, 0xab, 0xf8, 0x24,
+ 0x21, 0x71, 0xe9, 0xc2, 0xa9, 0x9c, 0x03, 0xe2, 0x57, 0xd9, 0x07, 0x8d,
+ 0x37, 0xe5, 0x30, 0x2c, 0xa6, 0xd8, 0xef, 0x24, 0xd7, 0xe3, 0x2c, 0xd7,
+ 0xe3, 0x37, 0x96, 0xd3, 0x31, 0x5d, 0x07, 0xc8, 0x8b, 0x34, 0xff, 0x69,
+ 0x8f, 0x7b, 0x43, 0xdf, 0x0f, 0xe8, 0xcf, 0x32, 0xf7, 0xf3, 0x2d, 0xe7,
+ 0x9e, 0xd0, 0x75, 0xdd, 0xea, 0xbe, 0xd0, 0xf8, 0xc7, 0xfa, 0xe8, 0xa4,
+ 0xe7, 0x39, 0x4b, 0x5f, 0x76, 0xc2, 0x4d, 0x63, 0x17, 0xa4, 0x53, 0xdf,
+ 0x6e, 0x9a, 0xdf, 0x86, 0x96, 0xab, 0xfa, 0x7c, 0x2a, 0xcf, 0x5f, 0xf5,
+ 0xfc, 0x35, 0x2c, 0xcd, 0x92, 0x8c, 0x36, 0x5e, 0x56, 0xf1, 0x5a, 0x3d,
+ 0xf8, 0xc3, 0x3d, 0xc7, 0xf5, 0xf5, 0x9d, 0x8e, 0x13, 0xb1, 0xf6, 0xdf,
+ 0x5c, 0x75, 0xcf, 0x2b, 0xe6, 0x33, 0xec, 0xe0, 0xbb, 0x79, 0x80, 0xfb,
+ 0xc0, 0x32, 0xf5, 0xa8, 0xf2, 0x3b, 0xc2, 0x71, 0xf2, 0x1c, 0xc7, 0xaa,
+ 0xe1, 0x0b, 0x95, 0xe7, 0xfa, 0x86, 0xe6, 0x09, 0x8d, 0x8f, 0x2a, 0x5f,
+ 0xe8, 0x3e, 0x50, 0xfc, 0xec, 0xcd, 0x55, 0xb5, 0xbf, 0x6d, 0x1b, 0xfe,
+ 0x58, 0x75, 0xfc, 0xdd, 0x72, 0x78, 0x22, 0x49, 0x71, 0x0f, 0xb3, 0xea,
+ 0xe6, 0xc1, 0x3f, 0x24, 0x0f, 0xaa, 0xef, 0xa6, 0x69, 0x39, 0xf3, 0xc2,
+ 0xfc, 0x37, 0xa3, 0xe2, 0xa5, 0x39, 0xff, 0xb4, 0xbe, 0xbf, 0x64, 0xfe,
+ 0xcc, 0x93, 0x63, 0xb5, 0x7c, 0x77, 0xdb, 0x23, 0xee, 0x7f, 0xf5, 0xc7,
+ 0xf3, 0x95, 0x65, 0xbe, 0xcf, 0x51, 0x9e, 0x95, 0xf1, 0x3c, 0xe3, 0x25,
+ 0x57, 0xdf, 0x07, 0xf4, 0x15, 0xf6, 0xb2, 0xbf, 0x9a, 0xf7, 0xfa, 0xb4,
+ 0x7f, 0xa8, 0x76, 0x4f, 0xad, 0x7d, 0x7d, 0xff, 0x03, 0x5b, 0xf0, 0xf8,
+ 0xe7, 0x1b, 0x78, 0x7f, 0x7d, 0xb6, 0x51, 0x7d, 0x4f, 0x79, 0xe2, 0xc4,
+ 0x16, 0x74, 0x3f, 0x85, 0x25, 0x9e, 0xe9, 0xbd, 0x26, 0xb4, 0xbd, 0x3f,
+ 0x88, 0xf7, 0xa4, 0x60, 0xfc, 0x9e, 0x7b, 0x98, 0xfd, 0x64, 0xc0, 0xc7,
+ 0x2f, 0x9c, 0xa1, 0xfe, 0xbe, 0x79, 0xf6, 0x3e, 0xf1, 0xf2, 0x7b, 0x2f,
+ 0x5f, 0x53, 0x7e, 0x77, 0x8b, 0xd5, 0x19, 0x8b, 0xf2, 0x1a, 0xda, 0x0b,
+ 0xf3, 0xfb, 0x87, 0xea, 0xfb, 0xad, 0xfc, 0x9a, 0x8c, 0x07, 0x69, 0x37,
+ 0xe1, 0x7e, 0x97, 0x6c, 0xce, 0x13, 0x73, 0x7f, 0x24, 0x81, 0x7d, 0x9a,
+ 0xbf, 0xdc, 0xf8, 0x79, 0x77, 0xa3, 0x7a, 0xff, 0xc0, 0xcd, 0xad, 0x83,
+ 0xde, 0x73, 0x71, 0xb2, 0xaf, 0x36, 0x4e, 0x46, 0xac, 0x94, 0xe1, 0x7f,
+ 0x84, 0x79, 0x65, 0x9c, 0x13, 0xf9, 0x29, 0x9a, 0xa0, 0x78, 0x85, 0xe3,
+ 0x84, 0x6b, 0x91, 0x8a, 0xe1, 0xdc, 0x85, 0xa7, 0xf0, 0xbd, 0x10, 0xc7,
+ 0x7a, 0x6b, 0x1c, 0xef, 0xcd, 0x91, 0xb0, 0x45, 0xf6, 0xad, 0x71, 0xc8,
+ 0x14, 0xf3, 0xcf, 0x8a, 0xc3, 0xcb, 0x90, 0xcb, 0xa1, 0xad, 0x78, 0x19,
+ 0xf7, 0xdb, 0xf5, 0x90, 0x5a, 0x97, 0x8f, 0xa0, 0x0c, 0x78, 0x69, 0xa8,
+ 0xdb, 0xa2, 0xef, 0xa3, 0x19, 0xe0, 0x48, 0x74, 0x7a, 0x9f, 0xab, 0x0d,
+ 0xfc, 0xd2, 0x5a, 0xe5, 0xef, 0x5a, 0x9e, 0xb7, 0x7a, 0x97, 0x1c, 0x1e,
+ 0x75, 0xe7, 0x01, 0xfe, 0x52, 0xfe, 0x49, 0x95, 0x7c, 0xb5, 0x13, 0x7e,
+ 0x37, 0x18, 0x2f, 0xbf, 0xf3, 0xbd, 0xdf, 0x24, 0xbe, 0x2a, 0xa3, 0x0e,
+ 0x2b, 0xe5, 0xfa, 0xfe, 0xe8, 0x3c, 0x74, 0x1c, 0x9c, 0x4b, 0x9f, 0xb3,
+ 0x1a, 0x17, 0x79, 0x9d, 0xe1, 0xfc, 0xef, 0xd0, 0xfb, 0x2f, 0xc5, 0xe7,
+ 0x55, 0x7e, 0xb1, 0x7e, 0x94, 0xee, 0xa1, 0xa0, 0x7c, 0xdf, 0x6b, 0xdd,
+ 0x7d, 0x3f, 0x8c, 0x50, 0x5e, 0x8d, 0x72, 0x41, 0xef, 0x77, 0x9f, 0xbb,
+ 0x39, 0x0f, 0xb9, 0x90, 0xd7, 0x7d, 0xd3, 0xfd, 0xd5, 0xfd, 0x44, 0xdf,
+ 0x53, 0x3d, 0x64, 0xd6, 0x5f, 0xe8, 0x21, 0x9c, 0xe7, 0x0b, 0xeb, 0xee,
+ 0x77, 0xf2, 0xc9, 0xac, 0xb2, 0x7f, 0x4d, 0x7c, 0x43, 0xf3, 0x28, 0xc4,
+ 0xf7, 0x2c, 0xab, 0x7c, 0x29, 0xf8, 0xaf, 0x96, 0x77, 0x0d, 0x71, 0x3d,
+ 0xc8, 0xcb, 0x7d, 0x7a, 0xee, 0xdc, 0xf3, 0x5b, 0xad, 0xbb, 0x3a, 0xc7,
+ 0x13, 0x1e, 0xfc, 0xa4, 0xcf, 0xa9, 0xec, 0xf3, 0x8c, 0x5f, 0x53, 0x0c,
+ 0x1d, 0xc1, 0xfb, 0xb0, 0x21, 0x8c, 0x39, 0x69, 0x08, 0x7b, 0xdd, 0xef,
+ 0x12, 0x3f, 0x11, 0xfa, 0x05, 0xb3, 0xa7, 0x31, 0x42, 0xe7, 0xba, 0x74,
+ 0xe3, 0x6b, 0x32, 0x7b, 0x7f, 0x29, 0x86, 0xf5, 0x96, 0x21, 0x84, 0x09,
+ 0x10, 0xde, 0x0d, 0x71, 0x01, 0xf3, 0xf0, 0xce, 0x02, 0xe4, 0xdb, 0xe2,
+ 0x49, 0xf8, 0x69, 0x9c, 0xa5, 0xfb, 0xd4, 0x6c, 0x41, 0x79, 0x4b, 0x4b,
+ 0x8c, 0xf3, 0xb4, 0x9f, 0x7e, 0xaf, 0x56, 0x44, 0x9c, 0x7f, 0x47, 0xf0,
+ 0xbc, 0x02, 0xcf, 0x81, 0x9a, 0xbe, 0xef, 0x14, 0xdf, 0x4a, 0x8f, 0x4b,
+ 0xfc, 0xc2, 0x0d, 0xe3, 0xdc, 0xac, 0xc7, 0xb9, 0xee, 0x6f, 0xda, 0xef,
+ 0x89, 0xeb, 0x81, 0xcd, 0xb8, 0xd6, 0xf9, 0xa9, 0x3a, 0xff, 0xe9, 0xbc,
+ 0x7b, 0x37, 0xfb, 0x57, 0xfb, 0x62, 0x12, 0xdf, 0xff, 0x17, 0xae, 0x21,
+ 0x8f, 0x76, 0xa9, 0xf8, 0x2d, 0x35, 0xf8, 0xf4, 0x9e, 0x3b, 0xf0, 0x9b,
+ 0x21, 0x79, 0xfc, 0x6f, 0x6a, 0x8c, 0x09, 0xd0, 0x18, 0x10, 0x00, 0x00,
+ 0x00 };
static u8 bnx2_TPAT_b09FwText[] = {
- 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0x7a,
- 0x6d, 0x39, 0xf1, 0xb8, 0x99, 0x96, 0x4d, 0x63, 0xd4, 0x99, 0x78, 0xfc,
- 0x43, 0x6d, 0x95, 0x69, 0x59, 0x15, 0x17, 0x56, 0x68, 0xba, 0xbb, 0x71,
- 0xad, 0xaa, 0xaa, 0x5c, 0x29, 0x88, 0x4a, 0x8d, 0x90, 0x59, 0x37, 0x6d,
- 0x79, 0x4b, 0x11, 0x0f, 0x48, 0x45, 0xca, 0xb2, 0x76, 0xd2, 0x08, 0x2d,
- 0x99, 0xd6, 0x85, 0x44, 0x42, 0x7d, 0x88, 0x9c, 0x3a, 0xee, 0xc3, 0xca,
- 0x9b, 0x8a, 0x07, 0x24, 0xa4, 0xa8, 0x55, 0x80, 0xc0, 0x1b, 0x7d, 0xa8,
- 0xf8, 0x79, 0x22, 0x12, 0x0f, 0x54, 0x08, 0x90, 0x85, 0x04, 0x2a, 0xa5,
- 0xe4, 0xf2, 0x7d, 0x77, 0x67, 0x92, 0xc5, 0x4d, 0x41, 0xe5, 0x81, 0x95,
- 0x56, 0x77, 0xe6, 0xde, 0x73, 0xce, 0x3d, 0xf7, 0xfc, 0x7c, 0xe7, 0xdc,
- 0x39, 0xec, 0xc8, 0x88, 0x64, 0xbf, 0x7d, 0xf8, 0x57, 0xbe, 0x72, 0xe2,
- 0xeb, 0x0f, 0xdc, 0x57, 0xb9, 0x0f, 0x8f, 0x0f, 0x3a, 0x77, 0x6b, 0x2d,
- 0xff, 0xc7, 0x9f, 0x2b, 0xe2, 0xe5, 0x7a, 0xf0, 0x2f, 0x25, 0x55, 0x4d,
- 0x0e, 0xd6, 0x22, 0x29, 0xb9, 0xd5, 0xea, 0xfc, 0x6a, 0x24, 0x92, 0x74,
- 0xe7, 0x82, 0xba, 0xfc, 0xd3, 0xb4, 0x7c, 0x2d, 0x9c, 0xff, 0x64, 0xf5,
- 0x83, 0x4f, 0x5f, 0xf9, 0x6c, 0xb8, 0x7b, 0xc1, 0x95, 0x92, 0x57, 0x3d,
- 0xa3, 0xbd, 0x69, 0x29, 0x4d, 0x80, 0xe7, 0xd5, 0x99, 0x6f, 0x17, 0x64,
- 0x7f, 0x2e, 0xab, 0x65, 0x54, 0x74, 0xdd, 0x5c, 0x99, 0x89, 0xbc, 0x36,
- 0x36, 0xb8, 0xdc, 0x0b, 0xa4, 0xd6, 0x2b, 0xcb, 0x9b, 0x3d, 0x5f, 0xde,
- 0xe8, 0x69, 0x39, 0xfe, 0xca, 0x49, 0x59, 0x8f, 0xc3, 0x72, 0xc3, 0x2d,
- 0x89, 0xaa, 0x86, 0xe5, 0xa6, 0x04, 0xb2, 0x15, 0x87, 0xad, 0x15, 0x77,
- 0xdc, 0x29, 0x55, 0x4b, 0xf2, 0xc2, 0x8c, 0x92, 0x0b, 0xfe, 0x31, 0x79,
- 0x26, 0x7a, 0x12, 0x7f, 0x2d, 0x6a, 0x43, 0x3b, 0xf5, 0xf3, 0x5a, 0xf4,
- 0xc6, 0x98, 0x3c, 0x12, 0x1b, 0xb3, 0x1a, 0x27, 0xe0, 0x9f, 0x9c, 0x7d,
- 0x56, 0x86, 0xa5, 0xe5, 0x85, 0x4b, 0x22, 0x05, 0xd2, 0x48, 0x2d, 0x2e,
- 0x48, 0xe2, 0xf5, 0xcf, 0x75, 0xc1, 0x8e, 0x1f, 0x98, 0x2d, 0xf0, 0x0f,
- 0x47, 0xf9, 0xfa, 0x1d, 0xd9, 0xba, 0x97, 0xad, 0x2b, 0x51, 0xe7, 0xc2,
- 0x60, 0x5b, 0xa6, 0x12, 0xed, 0xdc, 0x30, 0xb5, 0xe8, 0x2e, 0xaf, 0xb6,
- 0xad, 0xc5, 0xdd, 0xa0, 0xfe, 0x91, 0x57, 0x17, 0x03, 0x1e, 0x97, 0x3c,
- 0x5a, 0x55, 0xbf, 0x06, 0xbf, 0x4d, 0x25, 0xca, 0x11, 0xb9, 0xda, 0x29,
- 0x7b, 0xb5, 0xde, 0x37, 0x9c, 0x5a, 0x7a, 0xc3, 0x24, 0x7a, 0x44, 0x54,
- 0x94, 0x38, 0xb5, 0x6d, 0xca, 0x1a, 0x16, 0x1d, 0x0d, 0x81, 0x67, 0xd2,
- 0x53, 0xc2, 0xb1, 0x96, 0xcd, 0x53, 0x76, 0x03, 0xcf, 0x8b, 0x4e, 0xb2,
- 0xad, 0x9d, 0xda, 0xf9, 0x25, 0x3c, 0x97, 0xc0, 0x0f, 0xbb, 0xc4, 0x8e,
- 0x24, 0xcb, 0x0e, 0xf8, 0x78, 0x4e, 0x0f, 0xef, 0x4a, 0x12, 0xdf, 0x93,
- 0xb5, 0x4a, 0x58, 0x6e, 0xc9, 0xa3, 0x4e, 0x7d, 0xfb, 0x43, 0x4e, 0xf3,
- 0x96, 0x7a, 0x1f, 0x9e, 0xa3, 0x2e, 0x0f, 0x6b, 0x63, 0xd4, 0xfd, 0x43,
- 0xd9, 0x19, 0x29, 0x2f, 0xe9, 0xeb, 0xef, 0xf3, 0x1d, 0x3a, 0xa7, 0xd0,
- 0xbd, 0x5b, 0x84, 0x3e, 0xc6, 0x70, 0x9f, 0x5a, 0x54, 0x87, 0x9e, 0x09,
- 0xfe, 0xe1, 0x99, 0x26, 0x42, 0xe1, 0xf0, 0xb9, 0x7d, 0x12, 0x8c, 0x1b,
- 0xd3, 0x88, 0x43, 0x6f, 0x5b, 0x26, 0x64, 0x2d, 0x9d, 0xf0, 0x8e, 0xa4,
- 0x6d, 0xac, 0xb7, 0x48, 0x03, 0x7b, 0x88, 0x1c, 0xe9, 0x1a, 0x73, 0x29,
- 0x3e, 0x50, 0x94, 0xfd, 0x6a, 0xbe, 0x20, 0x61, 0x90, 0x60, 0xee, 0xf0,
- 0xa5, 0xbd, 0x36, 0xbb, 0x27, 0xd3, 0x81, 0x76, 0xc7, 0x3e, 0xf1, 0xa1,
- 0xec, 0x7d, 0xd4, 0xab, 0x9d, 0xcf, 0xed, 0x6c, 0xf5, 0x86, 0x5d, 0x63,
- 0xa9, 0x55, 0xa0, 0xff, 0x47, 0x9e, 0x29, 0xe7, 0xa3, 0x2e, 0xd4, 0x1b,
- 0xf4, 0xd1, 0x2d, 0x9d, 0x9e, 0xfa, 0x90, 0x4e, 0xd4, 0x47, 0x89, 0x3e,
- 0x57, 0x92, 0xf5, 0xe8, 0x71, 0x25, 0xfb, 0x8d, 0x59, 0x8f, 0xb5, 0xd3,
- 0x38, 0x7f, 0x2c, 0x7b, 0x46, 0x1c, 0xa6, 0x88, 0xc3, 0x14, 0x71, 0x99,
- 0x8a, 0xa7, 0xaa, 0x81, 0x5c, 0x99, 0x29, 0xc9, 0x75, 0x17, 0xfe, 0xec,
- 0xcd, 0x79, 0xaf, 0x21, 0xa6, 0x12, 0xcf, 0x11, 0x37, 0x4a, 0x66, 0x0b,
- 0xc2, 0x77, 0xc4, 0x92, 0x4e, 0xca, 0x2e, 0x62, 0x29, 0x39, 0xca, 0xb9,
- 0x21, 0x59, 0xb1, 0x67, 0x99, 0xf3, 0x4e, 0x09, 0x7d, 0x55, 0xc3, 0xda,
- 0x64, 0x70, 0x4a, 0x76, 0x11, 0x1f, 0x35, 0xac, 0x53, 0x56, 0xe8, 0xb5,
- 0x40, 0xd1, 0x4e, 0xdf, 0x45, 0x0e, 0xf8, 0x88, 0xfb, 0x99, 0xb2, 0x12,
- 0x47, 0x56, 0xe7, 0x61, 0x8b, 0xf9, 0x29, 0xd8, 0x88, 0x39, 0xc1, 0xb8,
- 0xfa, 0xeb, 0xb4, 0x8e, 0x4e, 0x22, 0x7e, 0x40, 0x8b, 0xf3, 0x9f, 0x4a,
- 0x67, 0xc0, 0x1f, 0x15, 0xa9, 0xe7, 0x56, 0xac, 0x65, 0x3d, 0xbd, 0xa2,
- 0x0a, 0xd1, 0xef, 0x1d, 0xd9, 0x1f, 0xb6, 0x12, 0x09, 0x5b, 0x4a, 0x29,
- 0x9f, 0x5b, 0xbf, 0x84, 0x3c, 0x7a, 0xd3, 0xea, 0xaf, 0xc1, 0x57, 0xce,
- 0xf4, 0xa7, 0xdd, 0x45, 0x36, 0x3b, 0x61, 0xbc, 0x08, 0xdd, 0xae, 0xc2,
- 0xff, 0xb4, 0xf9, 0xa5, 0x2e, 0x64, 0x77, 0x1c, 0xe6, 0xae, 0xb4, 0xbb,
- 0xa4, 0xb3, 0x69, 0xbe, 0xa2, 0xab, 0xb2, 0xdc, 0xee, 0x9c, 0x34, 0x6e,
- 0x24, 0x2b, 0x85, 0x2a, 0xfd, 0x36, 0xba, 0x00, 0x3f, 0x2c, 0xb7, 0xbb,
- 0x13, 0x8f, 0x6d, 0x76, 0xa4, 0x75, 0x77, 0x55, 0x5a, 0x6e, 0x45, 0xdd,
- 0xa5, 0x64, 0x0c, 0x72, 0xab, 0xd8, 0x87, 0x71, 0x15, 0x06, 0x75, 0x77,
- 0xe2, 0xb1, 0x8b, 0x9d, 0x7b, 0x90, 0xb7, 0xf2, 0x41, 0xad, 0x12, 0x21,
- 0x77, 0xaf, 0x1e, 0x74, 0x25, 0x92, 0xb5, 0x5e, 0x49, 0x6a, 0xe9, 0x84,
- 0xac, 0xf7, 0x24, 0x79, 0x6a, 0x06, 0xfb, 0x55, 0xf0, 0xde, 0x9b, 0x97,
- 0x56, 0x6f, 0x62, 0x45, 0x55, 0x5b, 0x92, 0xf4, 0xd6, 0xf1, 0x2f, 0x49,
- 0xa3, 0x53, 0x2a, 0x5d, 0xec, 0xb4, 0xc8, 0x5f, 0x72, 0xaa, 0x81, 0x3e,
- 0xdc, 0xdd, 0x65, 0xdc, 0x40, 0xce, 0xf0, 0x97, 0x54, 0x55, 0x4b, 0xd3,
- 0xf7, 0x21, 0xc3, 0x81, 0x4d, 0xa8, 0xeb, 0x2c, 0xf6, 0xed, 0x8f, 0xad,
- 0x1e, 0x7d, 0x37, 0x24, 0xed, 0x78, 0x1e, 0x76, 0x62, 0xd4, 0x0e, 0xc9,
- 0x5a, 0xf4, 0x9e, 0x79, 0x1a, 0xb1, 0xfa, 0x9a, 0x98, 0x7b, 0x6a, 0xc0,
- 0x93, 0x1a, 0x4c, 0xfa, 0x42, 0x54, 0x96, 0x53, 0xd8, 0xb7, 0xcf, 0xb7,
- 0x0e, 0x1d, 0xc8, 0x37, 0x06, 0xbe, 0x06, 0xf8, 0x7c, 0x39, 0x6d, 0x79,
- 0xc7, 0xc0, 0xbb, 0x9b, 0xf1, 0xce, 0x95, 0x17, 0x25, 0x06, 0xcf, 0x64,
- 0xb0, 0x08, 0x7f, 0xae, 0xf8, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x54,
- 0x5a, 0xba, 0x42, 0xb9, 0x61, 0xf9, 0x69, 0xe6, 0x83, 0x95, 0xd9, 0x82,
- 0x4c, 0xe8, 0x95, 0x96, 0x20, 0x67, 0x01, 0xe3, 0x3b, 0xa6, 0x9d, 0x02,
- 0x77, 0x7c, 0x3e, 0xbf, 0x69, 0x54, 0x15, 0x31, 0x5a, 0x89, 0x82, 0xb6,
- 0xf0, 0xbd, 0x28, 0x75, 0xe4, 0x99, 0x8a, 0xc6, 0xa4, 0xe9, 0x39, 0x8e,
- 0xaa, 0xba, 0xd2, 0x44, 0x84, 0x26, 0xcb, 0xda, 0xce, 0xad, 0x20, 0xce,
- 0x54, 0xf5, 0x7b, 0xaa, 0x5f, 0x0f, 0x0a, 0xa0, 0x41, 0x6e, 0x46, 0xa3,
- 0xb0, 0xc1, 0x38, 0x68, 0xcf, 0x62, 0x7e, 0x0a, 0xf8, 0x39, 0x0e, 0x1a,
- 0x8e, 0xcc, 0x11, 0xda, 0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60,
- 0x9b, 0xc1, 0xb4, 0xc9, 0x7d, 0x0c, 0x9a, 0x54, 0x67, 0x79, 0x37, 0x98,
- 0x4b, 0xf9, 0x7a, 0x80, 0xf5, 0xab, 0x9f, 0x52, 0xb2, 0x6b, 0x2e, 0x46,
- 0x8c, 0x61, 0x79, 0xaf, 0x11, 0x25, 0xe3, 0xae, 0xcd, 0xf3, 0x3c, 0xdf,
- 0x39, 0xb2, 0x16, 0x9c, 0x39, 0xb8, 0x1a, 0x39, 0xee, 0xfa, 0xfc, 0x01,
- 0x69, 0xf9, 0x61, 0x5c, 0x87, 0xbf, 0xd7, 0x53, 0xe6, 0xc6, 0x18, 0xce,
- 0x1d, 0x22, 0xea, 0x26, 0xf1, 0x9c, 0x1c, 0x04, 0x0f, 0xfc, 0xd8, 0x82,
- 0x2c, 0x8e, 0x88, 0x99, 0x34, 0x84, 0x8e, 0xb0, 0x47, 0x34, 0xe7, 0x1d,
- 0x61, 0x3c, 0xfa, 0x5c, 0x63, 0x8d, 0x79, 0xf5, 0x50, 0x2d, 0x0a, 0xe3,
- 0x66, 0x96, 0x2b, 0x6f, 0xc1, 0xb6, 0xed, 0x94, 0xf5, 0x22, 0xaf, 0x11,
- 0xcc, 0x0f, 0xc6, 0x4a, 0x8e, 0xb1, 0xe0, 0x89, 0x98, 0x9f, 0xa5, 0x0c,
- 0x6b, 0x6b, 0x19, 0x8e, 0x2e, 0x40, 0x0f, 0x63, 0x9e, 0x00, 0x86, 0xb6,
- 0x63, 0x1b, 0x9f, 0xad, 0x40, 0xdd, 0x30, 0x93, 0xd3, 0xb4, 0xb9, 0x31,
- 0x27, 0xe2, 0x45, 0xd0, 0xfe, 0x16, 0xf6, 0x5a, 0x02, 0x8e, 0x12, 0x7b,
- 0xb9, 0x77, 0x55, 0xd7, 0x3a, 0xfb, 0xa0, 0x4b, 0x00, 0x7c, 0x83, 0x0d,
- 0x2c, 0xde, 0x0e, 0x23, 0xdf, 0x99, 0xf3, 0x61, 0xb0, 0x22, 0x9c, 0x97,
- 0x61, 0x85, 0xf7, 0x26, 0xfc, 0xb4, 0x5e, 0x79, 0xd4, 0x69, 0x6c, 0xbf,
- 0x9f, 0xf9, 0x48, 0xc6, 0x14, 0x6a, 0x49, 0xd3, 0x27, 0x5f, 0x11, 0x7c,
- 0xfb, 0xc0, 0xf3, 0x77, 0xac, 0x15, 0x30, 0x0e, 0xca, 0xb1, 0xb8, 0x8d,
- 0xbd, 0x02, 0xec, 0xb5, 0x24, 0xba, 0xfa, 0x3c, 0xb0, 0x67, 0x2a, 0x68,
- 0xc8, 0xf7, 0x55, 0xbf, 0x46, 0xd2, 0x37, 0x5f, 0x18, 0xf0, 0x4d, 0x20,
- 0xae, 0xcd, 0xc1, 0x87, 0xb2, 0x98, 0x22, 0x66, 0x3e, 0x98, 0xad, 0xfb,
- 0xc0, 0xbe, 0xcf, 0x64, 0x18, 0x5e, 0x22, 0x0e, 0xca, 0x19, 0x8b, 0x83,
- 0x45, 0xe2, 0x20, 0x70, 0xa5, 0xb5, 0x00, 0x7b, 0xc7, 0xef, 0x02, 0x5f,
- 0xea, 0xf0, 0xc4, 0x4f, 0x3a, 0x1a, 0x71, 0xe5, 0x82, 0x9f, 0x75, 0xf8,
- 0xf3, 0xae, 0x8c, 0x84, 0xde, 0xbb, 0xc0, 0x9b, 0xe4, 0x28, 0xf3, 0xc0,
- 0x18, 0xe4, 0x3a, 0xb0, 0x6a, 0xba, 0x7c, 0x0a, 0x71, 0xef, 0x02, 0x27,
- 0xb4, 0x70, 0xdf, 0xbc, 0x6e, 0xe6, 0xf5, 0x9b, 0xbf, 0xb7, 0x1d, 0xb8,
- 0x19, 0xb5, 0xee, 0x73, 0x90, 0x31, 0x15, 0x1c, 0x81, 0x1f, 0xd7, 0x16,
- 0xfe, 0x1b, 0xcf, 0x6f, 0x32, 0x1e, 0xd4, 0x90, 0x0a, 0xf7, 0x15, 0x69,
- 0x74, 0x69, 0x87, 0x18, 0x76, 0xb0, 0x18, 0x84, 0x9c, 0x8f, 0x91, 0xf3,
- 0x22, 0x4d, 0x62, 0x05, 0x30, 0x8c, 0xb8, 0xb7, 0x06, 0x7a, 0x55, 0x19,
- 0x82, 0x5d, 0x11, 0x4b, 0x4a, 0x4a, 0xba, 0x7a, 0x54, 0xaf, 0x83, 0xb6,
- 0x50, 0x5d, 0xd6, 0x5b, 0xd1, 0x31, 0x37, 0xef, 0x97, 0xda, 0x1d, 0x71,
- 0x6a, 0x7d, 0x3f, 0x67, 0x74, 0x8f, 0x65, 0x74, 0x4b, 0x83, 0x74, 0x98,
- 0x6f, 0x64, 0xf3, 0x09, 0xe6, 0x3f, 0x91, 0xd9, 0x9c, 0xb5, 0xa0, 0x84,
- 0x3a, 0xcb, 0x3a, 0x10, 0x06, 0x81, 0xfa, 0x4f, 0x75, 0x60, 0x61, 0x00,
- 0xbb, 0x45, 0xd9, 0xbe, 0xc2, 0x67, 0x4c, 0x0e, 0x9e, 0x75, 0x58, 0x49,
- 0x74, 0x33, 0x3e, 0xf1, 0xdb, 0xcc, 0xf6, 0x21, 0x2d, 0xf1, 0x7a, 0x90,
- 0x16, 0x69, 0x04, 0xbb, 0xa8, 0xb3, 0xb7, 0xb3, 0xd9, 0x01, 0xac, 0x21,
- 0xe7, 0x53, 0x57, 0x1e, 0xd6, 0xcc, 0xef, 0x7b, 0xb5, 0x3d, 0xc7, 0x0e,
- 0xe8, 0x77, 0x26, 0x2c, 0xce, 0x2c, 0x75, 0x86, 0x20, 0x7e, 0x54, 0x8e,
- 0x23, 0x9f, 0x9f, 0x86, 0xef, 0x2f, 0xc6, 0x0a, 0xdd, 0x02, 0x6b, 0x8e,
- 0x41, 0x1c, 0x86, 0xd6, 0x17, 0xb5, 0x68, 0x0d, 0x91, 0xfc, 0x2d, 0xb9,
- 0x3a, 0x3f, 0x22, 0x85, 0x4b, 0xd4, 0x01, 0xfd, 0xd2, 0xe6, 0xe0, 0x3e,
- 0x73, 0xd8, 0x67, 0x02, 0x18, 0x78, 0x3f, 0xea, 0x8b, 0x2f, 0x7a, 0x1a,
- 0x58, 0x9b, 0x96, 0x9c, 0x3a, 0xe4, 0xab, 0x4b, 0x3c, 0x3f, 0x31, 0xb8,
- 0x94, 0xd5, 0x36, 0xe6, 0xd6, 0x10, 0x6a, 0xfa, 0x1f, 0x91, 0xbb, 0x4a,
- 0x56, 0x2b, 0xc6, 0x1c, 0x89, 0x7f, 0x00, 0xfb, 0x62, 0x6e, 0x93, 0x6b,
- 0xbb, 0x98, 0xe7, 0x1c, 0x65, 0x30, 0x16, 0x0f, 0xa0, 0xae, 0x61, 0xcf,
- 0xa3, 0xe4, 0x19, 0x42, 0xcd, 0x27, 0xfe, 0x63, 0xdc, 0xe4, 0x3b, 0xcf,
- 0x44, 0x6c, 0x73, 0x31, 0x8e, 0x60, 0xe4, 0x99, 0x7e, 0x91, 0xf9, 0x8a,
- 0xcf, 0xc6, 0xe8, 0xea, 0xa8, 0xd4, 0x3b, 0x11, 0x30, 0x76, 0xaa, 0x7c,
- 0x5c, 0xb8, 0x86, 0xf7, 0x2e, 0xe7, 0xbd, 0x81, 0x79, 0x3c, 0x77, 0xad,
- 0xce, 0xa8, 0xed, 0x79, 0xff, 0xb2, 0x06, 0xc3, 0xa2, 0xc7, 0xd8, 0x64,
- 0xaf, 0xc2, 0xfa, 0x67, 0x71, 0x6b, 0x96, 0x7d, 0xca, 0xeb, 0x1d, 0xd6,
- 0x42, 0xcd, 0xbc, 0x44, 0x00, 0x1c, 0x92, 0xba, 0x9f, 0x9f, 0x0b, 0x71,
- 0x1c, 0x53, 0x36, 0x65, 0x4c, 0xc2, 0x76, 0xec, 0x47, 0xa2, 0xb2, 0x76,
- 0xa6, 0x92, 0x26, 0xf9, 0xba, 0x05, 0x29, 0x6c, 0xcc, 0x8b, 0x7b, 0xd6,
- 0xc8, 0x66, 0x5f, 0x9e, 0xb7, 0x2c, 0xbe, 0xd4, 0x5e, 0xa2, 0x1e, 0x98,
- 0xdf, 0x61, 0x3d, 0x0c, 0x81, 0x67, 0xc5, 0x6c, 0xdf, 0xb2, 0x34, 0x3b,
- 0x91, 0xd7, 0x10, 0x8c, 0xdd, 0x3b, 0xe0, 0xbb, 0x22, 0xce, 0xac, 0xe5,
- 0x62, 0xa7, 0xbf, 0x17, 0x73, 0xee, 0xb9, 0xb8, 0xbf, 0x57, 0x43, 0x7e,
- 0x89, 0xbd, 0xc4, 0x57, 0xc2, 0x3e, 0x12, 0x7d, 0xe3, 0x39, 0x8d, 0xfd,
- 0x68, 0xa3, 0x02, 0x7a, 0xdb, 0xd9, 0xec, 0x3c, 0x21, 0xe8, 0x34, 0x6c,
- 0x4e, 0x5b, 0x73, 0x0f, 0xc6, 0xe2, 0x3f, 0x0c, 0xf1, 0x05, 0x75, 0x05,
- 0xfa, 0xe2, 0xbd, 0xc7, 0x3d, 0x26, 0xe4, 0xc5, 0xd4, 0x62, 0xad, 0x77,
- 0x02, 0x98, 0xd5, 0xe8, 0xfc, 0x2d, 0xaf, 0x3d, 0x49, 0x1b, 0xf8, 0xfb,
- 0xac, 0x8c, 0x8a, 0xde, 0x19, 0x95, 0xe7, 0xd0, 0xef, 0x15, 0x36, 0x50,
- 0xe7, 0x61, 0x63, 0x75, 0xb6, 0x35, 0xcb, 0x9e, 0xed, 0x32, 0x72, 0x79,
- 0xb5, 0x12, 0xc5, 0xae, 0x33, 0x2d, 0x67, 0xbe, 0x1b, 0xce, 0x6e, 0xdb,
- 0x7c, 0xc6, 0xfa, 0x4e, 0x20, 0xa7, 0xbb, 0x91, 0x9c, 0xe9, 0x7a, 0xd0,
- 0xcb, 0xbb, 0xd5, 0xd7, 0x46, 0xc4, 0xdb, 0x06, 0xfe, 0xc4, 0x53, 0x9e,
- 0x0b, 0x3e, 0xa8, 0xd2, 0x6e, 0xec, 0x63, 0xe9, 0x5f, 0xe2, 0xdb, 0xa3,
- 0x78, 0x1e, 0x11, 0xf7, 0x1c, 0xfb, 0x4e, 0xc6, 0x24, 0xfd, 0x33, 0xd8,
- 0x0b, 0x13, 0xfb, 0x20, 0x73, 0x87, 0xb9, 0x9f, 0xe7, 0x66, 0x9e, 0xab,
- 0xc4, 0x01, 0xed, 0x2c, 0xc2, 0x5e, 0xd7, 0x62, 0xe6, 0xeb, 0x0d, 0x73,
- 0xcd, 0xf6, 0x6e, 0x1e, 0xfb, 0xe2, 0x81, 0xde, 0x2d, 0xef, 0x7b, 0x18,
- 0xaf, 0xe5, 0x81, 0x7c, 0xbd, 0x6e, 0x73, 0xf5, 0x0d, 0xe4, 0xed, 0xcb,
- 0x69, 0xd9, 0xe6, 0xec, 0xe1, 0x07, 0x6e, 0x97, 0xb3, 0x97, 0x3f, 0x46,
- 0xce, 0xfe, 0x30, 0xcb, 0xd9, 0xa2, 0x8d, 0x6b, 0xb5, 0x31, 0xb8, 0xf6,
- 0x23, 0xac, 0x0d, 0x65, 0x77, 0x0a, 0x6d, 0x3b, 0xe8, 0xc3, 0x0f, 0xd2,
- 0x47, 0xb9, 0x7f, 0xfa, 0x71, 0x5a, 0xd7, 0xa4, 0x81, 0x0f, 0x37, 0x46,
- 0x11, 0x4f, 0xcc, 0xe9, 0x3c, 0x9e, 0x02, 0xc4, 0x72, 0xce, 0x8f, 0x7e,
- 0xf3, 0x28, 0x63, 0xa1, 0x60, 0xf3, 0xc6, 0xad, 0xe6, 0x34, 0x65, 0x59,
- 0x44, 0x2f, 0xf7, 0x63, 0x8e, 0xdd, 0x7e, 0xac, 0x14, 0x37, 0x4a, 0xf2,
- 0xfc, 0x0c, 0xb1, 0x2b, 0x8c, 0xaf, 0x42, 0xe7, 0x6b, 0x91, 0x2f, 0x85,
- 0x69, 0xe6, 0x33, 0xab, 0x51, 0x11, 0x31, 0x84, 0xbb, 0x55, 0x6a, 0x4e,
- 0xa2, 0xdf, 0x0a, 0x34, 0xfc, 0xfc, 0x32, 0xe2, 0x88, 0xd8, 0x8a, 0x98,
- 0x98, 0xdd, 0x44, 0x4c, 0x1c, 0xe7, 0xbb, 0xdd, 0xb7, 0x60, 0x69, 0x5d,
- 0xbb, 0xbf, 0x0f, 0xfd, 0x4b, 0x32, 0x74, 0xce, 0xe0, 0x4e, 0x75, 0x8b,
- 0xef, 0xb4, 0x8d, 0x5f, 0x60, 0x09, 0xe6, 0x57, 0x6d, 0xfc, 0xd2, 0xa7,
- 0x8c, 0x7b, 0x63, 0x7e, 0x67, 0xf3, 0xe6, 0xd7, 0x16, 0x03, 0xae, 0xc5,
- 0x36, 0x9e, 0x63, 0xf6, 0x9b, 0xa7, 0xbb, 0x3f, 0xd7, 0x16, 0x23, 0x36,
- 0x8c, 0x9c, 0x8a, 0x6d, 0xac, 0xcd, 0xbe, 0x81, 0x63, 0xbf, 0xd6, 0xcf,
- 0x85, 0x01, 0x39, 0x93, 0xde, 0x23, 0x90, 0x83, 0x9a, 0x17, 0xac, 0xb1,
- 0x3f, 0x88, 0xa7, 0xd0, 0x2f, 0x81, 0xae, 0xbb, 0x17, 0x2f, 0xc6, 0x31,
- 0xd2, 0xde, 0x7f, 0x80, 0x5c, 0x0f, 0x36, 0xa4, 0x1c, 0xea, 0x4d, 0xbd,
- 0x46, 0x25, 0x3a, 0x9b, 0xeb, 0xf4, 0x17, 0xab, 0xcb, 0xbf, 0xcb, 0xc3,
- 0xfa, 0xce, 0xed, 0xf8, 0xbc, 0x01, 0xbe, 0x3f, 0xdf, 0x86, 0x0f, 0xeb,
- 0x3b, 0xe4, 0x19, 0xb9, 0xd9, 0x6b, 0xd4, 0x6f, 0xc6, 0x75, 0x82, 0xb8,
- 0x27, 0xef, 0xde, 0xbb, 0xdc, 0x60, 0x0e, 0xe4, 0x35, 0x9e, 0x71, 0xce,
- 0x3d, 0xf3, 0x58, 0xcf, 0x63, 0x3c, 0x8f, 0xf9, 0x3c, 0xd6, 0xc3, 0xf8,
- 0x19, 0xe9, 0xfb, 0x57, 0x6f, 0x84, 0xd8, 0x7f, 0xe4, 0x7f, 0xb8, 0xb7,
- 0x10, 0x23, 0x24, 0xb9, 0x75, 0xd7, 0xfb, 0x69, 0xd6, 0xaf, 0x94, 0x98,
- 0x6b, 0xf8, 0xb3, 0x8f, 0xdf, 0x45, 0x7f, 0x10, 0x67, 0xb6, 0x4d, 0xb2,
- 0xb1, 0x4f, 0xd3, 0xef, 0x07, 0xbf, 0x9a, 0x61, 0xf2, 0x17, 0xfb, 0xf5,
- 0x47, 0xf2, 0x9c, 0x62, 0x0e, 0xd9, 0x9c, 0xe2, 0x79, 0x70, 0x0f, 0x37,
- 0x66, 0x19, 0x7e, 0x7c, 0x3e, 0xce, 0xf3, 0x08, 0xf1, 0xf4, 0x40, 0x9e,
- 0xe3, 0xb0, 0x53, 0x74, 0xc3, 0xe8, 0xe9, 0x04, 0x36, 0xe3, 0xdd, 0xb7,
- 0x81, 0xde, 0x89, 0x76, 0x5a, 0x72, 0x9e, 0xb8, 0x79, 0xdf, 0xdd, 0xdb,
- 0x27, 0xd1, 0x6e, 0xb4, 0xeb, 0xa0, 0xdd, 0xc2, 0x78, 0x5c, 0x11, 0x03,
- 0x6e, 0x87, 0x13, 0x79, 0x3d, 0x07, 0x06, 0x4d, 0xe7, 0x76, 0xfa, 0xd8,
- 0x35, 0x3d, 0xe9, 0x7f, 0x2b, 0xd8, 0x8b, 0x0f, 0xdb, 0xee, 0x00, 0x3e,
- 0xdc, 0xa6, 0xe7, 0xa4, 0x0c, 0xda, 0x00, 0xf5, 0xcd, 0xf6, 0x21, 0xec,
- 0x31, 0x6f, 0x18, 0xd7, 0xf6, 0x9b, 0xc4, 0x46, 0xf6, 0x99, 0xdf, 0x2c,
- 0xc8, 0xc8, 0x3e, 0xfb, 0x9e, 0x6c, 0x73, 0x64, 0x4c, 0x48, 0xbf, 0x6e,
- 0x59, 0xfd, 0x1f, 0xcf, 0xf4, 0xef, 0xeb, 0x2c, 0xea, 0xa3, 0x30, 0x8d,
- 0xba, 0x7a, 0xd0, 0x35, 0xcc, 0xed, 0xd2, 0x52, 0xd5, 0x13, 0xd2, 0xa8,
- 0xb0, 0x5f, 0x12, 0xdc, 0xb5, 0xa0, 0xc3, 0x02, 0xf5, 0x28, 0x43, 0x8f,
- 0x51, 0xdc, 0x4d, 0xc2, 0xa5, 0x96, 0x84, 0xc9, 0x0a, 0x08, 0x67, 0xbe,
- 0x43, 0xbb, 0x1d, 0xd3, 0x5b, 0x1d, 0xda, 0xed, 0x49, 0xbd, 0xde, 0x99,
- 0x44, 0x7f, 0x18, 0xc2, 0xdb, 0xe1, 0xec, 0x25, 0x61, 0x8c, 0xcd, 0xc5,
- 0x1c, 0x4f, 0x0b, 0xfb, 0xb1, 0x63, 0x7a, 0xaa, 0xcb, 0xf1, 0x49, 0x1d,
- 0x75, 0x07, 0xe5, 0xfe, 0xc9, 0x00, 0x13, 0x93, 0xeb, 0xc8, 0xa3, 0x17,
- 0x7b, 0xfd, 0xbd, 0x71, 0x3f, 0xcc, 0xe4, 0x62, 0x2e, 0xcd, 0x65, 0x0b,
- 0x71, 0x8a, 0xb2, 0x21, 0x77, 0x32, 0xfe, 0x99, 0xdd, 0x83, 0xf7, 0xa3,
- 0x8f, 0xda, 0xe3, 0xae, 0xfc, 0xfb, 0x04, 0x72, 0xa7, 0x60, 0xb1, 0x67,
- 0x2d, 0xc5, 0x9d, 0xda, 0x37, 0xa6, 0x19, 0xbd, 0x0d, 0xdb, 0xa1, 0x47,
- 0x98, 0xf7, 0xf0, 0x07, 0xae, 0x2e, 0x73, 0x0d, 0x7d, 0x38, 0xee, 0x82,
- 0xbc, 0xcf, 0xad, 0xa5, 0x5c, 0x63, 0x8c, 0xa3, 0x57, 0x9c, 0xff, 0x15,
- 0x68, 0xdf, 0x31, 0xad, 0x9e, 0xb2, 0xf7, 0x75, 0x15, 0xe1, 0x1e, 0xd6,
- 0x63, 0x3f, 0x23, 0x4e, 0x23, 0x95, 0xa0, 0x19, 0x2f, 0xd8, 0xfb, 0x5a,
- 0xe2, 0x05, 0xbc, 0x93, 0xa2, 0x07, 0x9d, 0x1f, 0xe8, 0x41, 0xe7, 0xd1,
- 0x83, 0x8e, 0x15, 0x11, 0xe7, 0x09, 0xee, 0xa1, 0xaa, 0xd9, 0xcf, 0x9b,
- 0x31, 0xde, 0x39, 0xdb, 0xbe, 0xec, 0x43, 0x77, 0x05, 0xdd, 0x22, 0xec,
- 0xcf, 0xf5, 0x3b, 0xb3, 0xef, 0x5a, 0xa3, 0xa0, 0x4f, 0x6c, 0x3f, 0xd6,
- 0xf6, 0x8b, 0xd2, 0x8c, 0x49, 0x73, 0x28, 0xa3, 0xf9, 0xf2, 0x1e, 0x9a,
- 0x3b, 0x79, 0x46, 0xca, 0x96, 0xe6, 0x2b, 0xcc, 0x3b, 0xd6, 0xd2, 0x62,
- 0x96, 0x6f, 0x27, 0xf0, 0x3c, 0x94, 0x3d, 0xe7, 0xf4, 0xf7, 0xee, 0xe1,
- 0x7f, 0xc8, 0xe9, 0xbf, 0xf3, 0x99, 0x3a, 0x27, 0xec, 0x93, 0x21, 0x6f,
- 0xc1, 0xe9, 0x7f, 0x27, 0xc1, 0x85, 0x73, 0x84, 0x3e, 0xe9, 0xf7, 0x17,
- 0xc0, 0x60, 0x74, 0x5f, 0x53, 0xb0, 0xbb, 0x31, 0xed, 0x05, 0xe2, 0xda,
- 0xdc, 0xec, 0x11, 0x8b, 0x6f, 0x6a, 0x42, 0x49, 0x8e, 0xb9, 0x83, 0xcf,
- 0x18, 0x17, 0xec, 0x37, 0x03, 0xbc, 0xf7, 0x65, 0x6c, 0xe1, 0xfe, 0x2c,
- 0xc8, 0xe1, 0x96, 0xd5, 0xcb, 0xe9, 0xdf, 0x8b, 0xbc, 0x1a, 0xeb, 0x01,
- 0xea, 0xc6, 0x0c, 0xf5, 0xba, 0xf9, 0x6d, 0x63, 0x05, 0xb5, 0xe6, 0x2d,
- 0xc4, 0x3e, 0xf2, 0xd3, 0xf6, 0x58, 0x5b, 0xf6, 0xdb, 0x02, 0xea, 0xd0,
- 0x08, 0xee, 0x4b, 0xd1, 0xcd, 0x6f, 0x0c, 0x72, 0x01, 0x34, 0x17, 0xb1,
- 0x76, 0xba, 0x9b, 0xf7, 0xbc, 0xe8, 0xf3, 0x81, 0x7b, 0xab, 0xd1, 0xfb,
- 0xa6, 0xe9, 0x0f, 0xd2, 0xf2, 0xf7, 0x2f, 0x97, 0xa2, 0x15, 0x3a, 0x18,
- 0x15, 0x00, 0x00, 0x00 };
+ 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0xee,
+ 0x78, 0xb1, 0xe3, 0x71, 0x3b, 0xa4, 0xdb, 0x62, 0xc8, 0x8c, 0x7d, 0xfd,
+ 0x03, 0xb6, 0xc2, 0x94, 0x6e, 0xdb, 0xad, 0x18, 0x45, 0xc3, 0xec, 0xda,
+ 0xb1, 0xa2, 0x3c, 0xb8, 0x52, 0xa4, 0x46, 0x6a, 0x04, 0x66, 0x1d, 0x93,
+ 0x3e, 0xa6, 0x88, 0x07, 0xa4, 0x3e, 0x64, 0x59, 0x3b, 0xa9, 0x1f, 0x96,
+ 0x2c, 0xb8, 0xc8, 0x7e, 0x41, 0x28, 0x72, 0x6a, 0xbb, 0x48, 0x8b, 0x37,
+ 0x11, 0x48, 0x3c, 0x45, 0x8d, 0x1c, 0x14, 0x55, 0xea, 0x0b, 0x0f, 0xfc,
+ 0x3d, 0x46, 0x6a, 0x45, 0xfb, 0x50, 0x90, 0x55, 0xa9, 0xa8, 0x82, 0xe0,
+ 0xcb, 0x77, 0x66, 0x67, 0x9c, 0x4d, 0xec, 0x08, 0x9e, 0xb0, 0xb4, 0xba,
+ 0x33, 0x73, 0xef, 0x39, 0xf7, 0xdc, 0x73, 0xbe, 0xef, 0x9c, 0x73, 0x3d,
+ 0x64, 0x50, 0x9e, 0x92, 0xbf, 0x3e, 0xfc, 0x8a, 0xdf, 0xbd, 0xf8, 0x83,
+ 0x67, 0x8f, 0xbf, 0x70, 0x1c, 0x8f, 0xcf, 0x1b, 0xfd, 0x59, 0x49, 0xff,
+ 0xc7, 0x3f, 0x93, 0xc8, 0x4e, 0xed, 0xe0, 0x1f, 0x59, 0x22, 0xb8, 0xfd,
+ 0x54, 0xa4, 0xc8, 0x32, 0x83, 0xdf, 0x7c, 0x6d, 0x5e, 0x11, 0x85, 0xad,
+ 0x09, 0xb7, 0x4c, 0xff, 0xd6, 0x35, 0x47, 0x12, 0x7f, 0xff, 0x72, 0x70,
+ 0xff, 0xeb, 0xb7, 0x5e, 0xf4, 0x76, 0xaf, 0x99, 0x64, 0xd9, 0xc1, 0xb2,
+ 0xb4, 0x47, 0xc9, 0x1a, 0x84, 0xcc, 0xcf, 0xc7, 0xbe, 0x2d, 0xe8, 0x48,
+ 0xaa, 0xab, 0xa6, 0x85, 0xba, 0xa7, 0x6f, 0x8d, 0x29, 0xbb, 0x8e, 0x0d,
+ 0x6e, 0xb4, 0x5d, 0x8a, 0xda, 0x05, 0x7a, 0xb7, 0xed, 0xd0, 0xcd, 0xb6,
+ 0xa4, 0x85, 0xb7, 0x2e, 0xd1, 0x92, 0xef, 0x15, 0x2a, 0xa6, 0x45, 0x22,
+ 0xf0, 0x0a, 0x55, 0x72, 0x69, 0xc3, 0xf7, 0x6a, 0x73, 0xe6, 0x80, 0x61,
+ 0x05, 0x16, 0xbd, 0x31, 0x26, 0xe8, 0x9a, 0x73, 0x8e, 0xbe, 0xa7, 0xce,
+ 0xe2, 0x27, 0x49, 0xac, 0x48, 0xa3, 0xbc, 0x26, 0x49, 0xae, 0xf4, 0xd3,
+ 0x49, 0x5f, 0xeb, 0x79, 0x3f, 0x84, 0xfc, 0xf0, 0xf8, 0x05, 0xea, 0xa1,
+ 0x9a, 0xed, 0xcd, 0x10, 0x65, 0x78, 0x0d, 0x45, 0x7e, 0x86, 0x42, 0xbb,
+ 0x73, 0xae, 0x6b, 0xf1, 0x78, 0x5f, 0x6f, 0x40, 0xbe, 0x47, 0xa5, 0xf3,
+ 0x4f, 0x24, 0xf3, 0x76, 0x32, 0x2f, 0x48, 0xac, 0x7a, 0xee, 0x16, 0x8d,
+ 0x84, 0xd2, 0xd8, 0xd3, 0x91, 0x3a, 0x6a, 0x47, 0x5b, 0x92, 0xcc, 0x15,
+ 0xb6, 0x5f, 0xd9, 0x65, 0xd2, 0x90, 0x31, 0x59, 0x46, 0x8a, 0xe0, 0xfb,
+ 0x88, 0xdb, 0x48, 0x28, 0x0c, 0xa2, 0x9d, 0x46, 0xc1, 0x8e, 0xda, 0x3f,
+ 0x34, 0xa2, 0xe6, 0x9e, 0x0e, 0x65, 0x9e, 0x84, 0x0a, 0x8d, 0x68, 0x8b,
+ 0x75, 0xf5, 0x90, 0x54, 0x39, 0xc8, 0x0c, 0xdb, 0x82, 0x78, 0x8c, 0x92,
+ 0xef, 0xac, 0xbb, 0x82, 0xe7, 0x69, 0x23, 0xdc, 0x92, 0x46, 0xb4, 0x36,
+ 0x83, 0x67, 0x0b, 0xf2, 0xf0, 0x8b, 0x6f, 0x50, 0x38, 0x6b, 0x40, 0x8e,
+ 0xcf, 0x69, 0xe3, 0x5d, 0x50, 0xe8, 0xd8, 0xb4, 0x58, 0xf4, 0x0a, 0x35,
+ 0x3a, 0x65, 0x94, 0xb7, 0x0e, 0x04, 0xcd, 0x9e, 0x69, 0x1f, 0xfc, 0xc6,
+ 0xb6, 0x7c, 0x4b, 0x6a, 0x2d, 0x9e, 0xcd, 0x25, 0x67, 0x64, 0x7d, 0x61,
+ 0xc7, 0x7e, 0x87, 0xdf, 0x61, 0x73, 0x13, 0xb6, 0xb7, 0xb2, 0xb0, 0x47,
+ 0x6b, 0xde, 0x27, 0x52, 0x65, 0xd8, 0x19, 0xe2, 0xe7, 0x2d, 0x57, 0x01,
+ 0x85, 0xa1, 0xd5, 0x3e, 0x72, 0x07, 0xb4, 0xae, 0xf8, 0x9e, 0xbd, 0x45,
+ 0x01, 0x2d, 0x36, 0x07, 0xed, 0xa9, 0x66, 0x1d, 0xf3, 0x35, 0x5e, 0x03,
+ 0x7f, 0x10, 0x4d, 0xb5, 0xb4, 0xde, 0xf4, 0x7f, 0x9b, 0xa1, 0x23, 0x62,
+ 0x32, 0x43, 0x9e, 0x1b, 0xe2, 0xdb, 0xd0, 0xe6, 0xa3, 0x3e, 0x3b, 0x96,
+ 0xd8, 0xc0, 0x7e, 0xc7, 0x3e, 0xfe, 0x97, 0x92, 0xf7, 0x5e, 0x3b, 0x5a,
+ 0x4b, 0xfd, 0x1c, 0xdb, 0x0d, 0xbf, 0xfa, 0x14, 0x15, 0x61, 0xff, 0x63,
+ 0xcf, 0x94, 0xca, 0xb1, 0x2d, 0x6c, 0x37, 0xd6, 0xab, 0x07, 0x36, 0xbd,
+ 0x7a, 0xc0, 0x26, 0xb6, 0x47, 0x90, 0x5c, 0xb5, 0x68, 0x49, 0x7d, 0x64,
+ 0xd0, 0x11, 0xad, 0x97, 0x7c, 0x69, 0x54, 0xd6, 0x3e, 0x4b, 0x9e, 0x81,
+ 0xc3, 0x26, 0x70, 0xd8, 0x04, 0x2e, 0x9b, 0x64, 0x8b, 0xc0, 0xa5, 0x5b,
+ 0x63, 0x16, 0xdd, 0x33, 0x11, 0xcf, 0x36, 0xcf, 0xe7, 0xa8, 0xee, 0x2b,
+ 0xba, 0xdc, 0x64, 0xcf, 0xe4, 0x68, 0x51, 0x7d, 0xae, 0xcf, 0xc3, 0x1f,
+ 0x6f, 0x93, 0x3e, 0x16, 0x01, 0xb3, 0x11, 0xdc, 0xf9, 0x86, 0x1a, 0xa7,
+ 0xcb, 0x6d, 0x45, 0xf5, 0x36, 0xcb, 0x2d, 0x51, 0x47, 0xae, 0x1f, 0x72,
+ 0x93, 0x90, 0x2b, 0xd2, 0x95, 0x58, 0xb6, 0x1f, 0xb2, 0xbb, 0x89, 0xec,
+ 0x44, 0x61, 0x9a, 0x7c, 0xc8, 0x0c, 0xbb, 0xd3, 0xc0, 0xdc, 0x9c, 0x33,
+ 0x09, 0xd9, 0x49, 0x5a, 0xc2, 0xaf, 0xde, 0xa4, 0x9a, 0x2c, 0xb2, 0x5e,
+ 0xaf, 0x70, 0x9e, 0x7d, 0x1e, 0xeb, 0xac, 0x41, 0xa7, 0x83, 0x39, 0x0b,
+ 0x7a, 0x24, 0xc6, 0x0f, 0x75, 0xbd, 0x09, 0x6c, 0x3b, 0xfc, 0xfc, 0xae,
+ 0x16, 0x01, 0xfc, 0x50, 0x54, 0x6e, 0x9d, 0xf8, 0x3d, 0x4b, 0x65, 0xc4,
+ 0x52, 0xa8, 0x7e, 0xaa, 0xda, 0x86, 0x21, 0x02, 0x93, 0xaa, 0xf0, 0x42,
+ 0x38, 0x2b, 0xe3, 0x6f, 0x73, 0xb6, 0x01, 0x8e, 0x1d, 0x17, 0x9d, 0x9c,
+ 0x93, 0xc1, 0x1a, 0xc4, 0x5f, 0xf5, 0x52, 0xd5, 0x19, 0xc0, 0x5a, 0x10,
+ 0x2d, 0x3f, 0x02, 0x8e, 0x0e, 0x60, 0x0d, 0x8f, 0x1c, 0x07, 0xac, 0x57,
+ 0xbc, 0xbe, 0x17, 0x36, 0xa6, 0xdf, 0x7a, 0xa9, 0xf6, 0x50, 0x7c, 0xd8,
+ 0xc6, 0x38, 0x2e, 0xd8, 0x5f, 0x26, 0xb1, 0xed, 0x8e, 0x57, 0x3a, 0x6f,
+ 0x63, 0x7e, 0xe7, 0xab, 0x82, 0x76, 0xf5, 0x75, 0x15, 0x15, 0xf0, 0xe9,
+ 0xf3, 0x8a, 0x0a, 0x07, 0xcc, 0x18, 0x4b, 0x29, 0xa6, 0x78, 0xe4, 0x7c,
+ 0x43, 0x85, 0x79, 0x65, 0x98, 0x4b, 0x93, 0x4f, 0x52, 0xcd, 0xf1, 0xfc,
+ 0x32, 0x15, 0x68, 0xa9, 0x39, 0x01, 0xdf, 0xf5, 0xe3, 0xdc, 0x9e, 0x4f,
+ 0x34, 0x8c, 0xe7, 0xf0, 0x69, 0xc8, 0x20, 0x5f, 0xd4, 0xa0, 0x8b, 0xc7,
+ 0x41, 0xe8, 0xf7, 0x60, 0x23, 0xfc, 0xa1, 0x26, 0xec, 0x29, 0xf8, 0x23,
+ 0x74, 0x78, 0x8e, 0xf3, 0x98, 0xf3, 0x4c, 0xa4, 0x3c, 0xbf, 0x1a, 0xdb,
+ 0xe2, 0xd9, 0xb7, 0x89, 0xf3, 0x51, 0x9a, 0x83, 0x38, 0x27, 0x59, 0x73,
+ 0x32, 0xa0, 0xd9, 0x7a, 0xe3, 0x92, 0x36, 0x15, 0xcd, 0x65, 0x03, 0xc6,
+ 0x6e, 0x6f, 0x09, 0x58, 0x9c, 0xad, 0xb7, 0x06, 0x4f, 0xef, 0x34, 0xa8,
+ 0xf6, 0x4c, 0x20, 0x8e, 0x0a, 0xec, 0x1f, 0xf9, 0xcc, 0x29, 0xec, 0xd5,
+ 0x1e, 0x3c, 0x7d, 0xa7, 0x71, 0x0c, 0xbe, 0xa2, 0xfb, 0xf0, 0x3f, 0xf6,
+ 0xdf, 0x79, 0xda, 0x84, 0x9d, 0x1c, 0x33, 0x70, 0x2b, 0x7c, 0x75, 0xcc,
+ 0x00, 0x96, 0xf1, 0x0c, 0x6c, 0xd4, 0xda, 0x83, 0x73, 0x22, 0xa8, 0x51,
+ 0xd8, 0x5e, 0xc2, 0xcf, 0xa2, 0xa9, 0x86, 0x65, 0xdd, 0x81, 0x4e, 0x51,
+ 0xf4, 0xdc, 0xc8, 0xdc, 0x65, 0xae, 0xf0, 0x39, 0x58, 0x97, 0x65, 0x04,
+ 0xae, 0x1c, 0x6a, 0xf5, 0xbc, 0x22, 0x82, 0x00, 0x98, 0x90, 0x88, 0x4d,
+ 0x11, 0x58, 0xe1, 0x38, 0x5c, 0x45, 0x1c, 0x80, 0x03, 0xd8, 0x0c, 0xff,
+ 0xd7, 0x44, 0x70, 0x91, 0x2a, 0x45, 0xa2, 0xc5, 0x06, 0x61, 0x3f, 0xec,
+ 0x55, 0xc2, 0x0f, 0x78, 0x0e, 0xed, 0x12, 0x6c, 0xf0, 0xc2, 0x1a, 0x79,
+ 0xfe, 0x1c, 0xbc, 0x9e, 0xfb, 0x31, 0x59, 0x99, 0xe0, 0x9c, 0xdc, 0x68,
+ 0x90, 0x25, 0x83, 0xb3, 0x72, 0xa9, 0x31, 0xec, 0xff, 0x15, 0xbe, 0x26,
+ 0xf2, 0xc6, 0x37, 0x69, 0xc2, 0xdf, 0x04, 0x6f, 0xeb, 0xf8, 0x5d, 0x21,
+ 0xde, 0xfb, 0x9c, 0x1c, 0x69, 0xf1, 0x78, 0x56, 0xaa, 0x56, 0xb7, 0xde,
+ 0xbf, 0x69, 0xf6, 0xfb, 0x3d, 0x2a, 0xd1, 0x9b, 0xc9, 0xde, 0xf0, 0x0d,
+ 0x9d, 0x6c, 0x94, 0x80, 0xef, 0x03, 0xfa, 0x4b, 0xa9, 0xfe, 0xad, 0x58,
+ 0x37, 0x63, 0x77, 0xc2, 0xdf, 0x3a, 0x74, 0x8f, 0xa3, 0x69, 0x7e, 0x42,
+ 0x1e, 0xec, 0xe4, 0xeb, 0xc5, 0x66, 0x0e, 0x9c, 0xd0, 0xba, 0xaa, 0x7e,
+ 0x8f, 0xf3, 0xe6, 0x81, 0x5f, 0x1b, 0x3f, 0xc4, 0x72, 0x96, 0xe7, 0x0c,
+ 0xaa, 0xa2, 0x0e, 0xd5, 0xdb, 0xfc, 0xcc, 0x73, 0x9c, 0xcf, 0x72, 0x18,
+ 0xff, 0x8c, 0xb5, 0x1f, 0xea, 0x5a, 0x9b, 0xb9, 0xc6, 0xbe, 0x02, 0x47,
+ 0xda, 0x96, 0x51, 0x6e, 0x92, 0x51, 0x69, 0x92, 0x5b, 0xf5, 0x65, 0x1c,
+ 0x97, 0xd0, 0xb6, 0xe1, 0x53, 0xc6, 0xc3, 0xa4, 0x8c, 0x1a, 0x46, 0x5c,
+ 0xc3, 0x0c, 0x3c, 0x0f, 0xb5, 0x7e, 0x9d, 0x01, 0x27, 0x42, 0xf8, 0x5f,
+ 0x2c, 0x20, 0x47, 0x5e, 0x73, 0xa8, 0x5f, 0xa8, 0x39, 0x51, 0x77, 0xa8,
+ 0x4f, 0x28, 0xb6, 0xed, 0x3d, 0x01, 0xdb, 0x78, 0x3e, 0xac, 0xfa, 0xbf,
+ 0xc2, 0x9e, 0x41, 0xcc, 0xc7, 0x4a, 0x23, 0xcd, 0xfb, 0xd0, 0xa9, 0x38,
+ 0x67, 0x58, 0x49, 0xfe, 0x8f, 0x92, 0xdc, 0x2e, 0x81, 0x5b, 0xad, 0x5f,
+ 0x46, 0x5e, 0xaf, 0xc7, 0xb8, 0xf1, 0x6a, 0xae, 0xd8, 0xd3, 0xc3, 0xa3,
+ 0xcc, 0x51, 0xad, 0x2f, 0xfa, 0xd3, 0x58, 0x2b, 0x4d, 0xca, 0xcf, 0x20,
+ 0xb7, 0x73, 0x3d, 0x60, 0xdb, 0x02, 0xd8, 0xd6, 0xd7, 0xc9, 0xfb, 0xa8,
+ 0x09, 0xf5, 0xb8, 0x06, 0xf4, 0x90, 0xa9, 0x0c, 0xfc, 0x3c, 0x77, 0x8e,
+ 0xf8, 0x3b, 0xf5, 0x08, 0xbc, 0x57, 0xc1, 0xeb, 0xa5, 0xe2, 0x29, 0xa3,
+ 0xb2, 0x75, 0xcc, 0x4c, 0xfa, 0x08, 0xd8, 0x0d, 0x5e, 0x3b, 0x2c, 0x97,
+ 0x85, 0x5c, 0x1f, 0x64, 0xbe, 0x82, 0xb9, 0x0c, 0xc6, 0x6e, 0x3d, 0x71,
+ 0x2d, 0xc1, 0x5e, 0x2e, 0xf6, 0x9a, 0x21, 0x19, 0xe4, 0x51, 0xaf, 0x47,
+ 0xdc, 0x0a, 0x3d, 0x97, 0xd4, 0x6d, 0xe6, 0xf2, 0x89, 0x2e, 0x2e, 0xbb,
+ 0x64, 0xc6, 0x9c, 0x78, 0x29, 0xc9, 0x41, 0x9c, 0xc7, 0x5f, 0x48, 0xe6,
+ 0x1d, 0xe4, 0xe3, 0xe7, 0x92, 0xba, 0x62, 0xe1, 0x39, 0xa0, 0xe5, 0x38,
+ 0x37, 0x67, 0x39, 0x37, 0x17, 0x90, 0x9b, 0x4b, 0xe0, 0xa7, 0xff, 0x31,
+ 0x19, 0xc8, 0x4d, 0x44, 0xbf, 0x6b, 0x48, 0xe4, 0x21, 0x13, 0xf2, 0xdc,
+ 0x1b, 0xcc, 0xc1, 0x36, 0xcf, 0xfe, 0x18, 0x67, 0x0a, 0xcf, 0x70, 0xde,
+ 0xd4, 0x3a, 0x13, 0x28, 0xf7, 0x32, 0x8d, 0x16, 0x2e, 0x23, 0x4f, 0x9a,
+ 0x34, 0x81, 0xdd, 0x78, 0xdf, 0xb4, 0x96, 0xa7, 0x3d, 0x05, 0xff, 0xbd,
+ 0x6f, 0x90, 0xe2, 0xfa, 0xfb, 0x1d, 0xe8, 0x18, 0x71, 0xa7, 0xc0, 0xfb,
+ 0xc5, 0xd2, 0x7f, 0x93, 0xf9, 0x43, 0x22, 0x83, 0xba, 0x56, 0xe4, 0x7d,
+ 0x89, 0x2a, 0x2d, 0xf6, 0x83, 0xdf, 0x85, 0x07, 0x1f, 0x78, 0x20, 0xaa,
+ 0x36, 0xc1, 0x3f, 0xc4, 0x38, 0xc6, 0x1a, 0xd6, 0x8b, 0x22, 0x72, 0xaa,
+ 0xc3, 0xb8, 0x66, 0xbc, 0x9f, 0x49, 0xf0, 0x3e, 0x0b, 0xbc, 0x7b, 0xe3,
+ 0x37, 0xc0, 0xa3, 0x1b, 0x0f, 0xf1, 0xe8, 0x4c, 0x82, 0xf1, 0x59, 0x60,
+ 0xfc, 0x97, 0xc0, 0x96, 0x85, 0x9a, 0x0e, 0xdc, 0x36, 0xc8, 0x88, 0x50,
+ 0x1b, 0x80, 0x83, 0x44, 0xcf, 0xe9, 0x44, 0xcf, 0xcc, 0x63, 0xf4, 0x9c,
+ 0x4e, 0xf4, 0xcc, 0x74, 0xeb, 0x81, 0x5c, 0x25, 0x91, 0x0b, 0x1f, 0x23,
+ 0x57, 0x49, 0xe4, 0xc2, 0x2e, 0x39, 0x0b, 0x67, 0xe2, 0x73, 0x71, 0x1e,
+ 0xdb, 0x45, 0x2c, 0x7c, 0x8a, 0xb1, 0x62, 0x87, 0x18, 0xef, 0x61, 0x04,
+ 0x66, 0x9a, 0x37, 0xb1, 0x96, 0xfd, 0x90, 0x61, 0x0e, 0x3c, 0xe2, 0xbb,
+ 0x3d, 0xf8, 0x6e, 0x1f, 0xef, 0xf8, 0xfb, 0x66, 0x82, 0x15, 0xae, 0x45,
+ 0x5e, 0x2d, 0x7c, 0x68, 0x6d, 0x46, 0xb0, 0x9f, 0xc5, 0xd5, 0xc3, 0x62,
+ 0x60, 0x61, 0x0e, 0x35, 0xa7, 0x69, 0x52, 0x59, 0x32, 0x57, 0x5f, 0x91,
+ 0x31, 0x76, 0xb7, 0xb1, 0x7e, 0xbb, 0xc3, 0xab, 0x99, 0x46, 0x8e, 0x68,
+ 0xbd, 0x97, 0x16, 0x50, 0x4f, 0xce, 0x03, 0x4b, 0xd7, 0x7d, 0xb0, 0x90,
+ 0x86, 0x81, 0x0b, 0x0d, 0x5c, 0x7b, 0x71, 0x6c, 0x23, 0xb5, 0x08, 0x66,
+ 0xfc, 0x88, 0x76, 0x26, 0xf3, 0x94, 0xd9, 0xec, 0xd4, 0x43, 0xb9, 0xde,
+ 0xbd, 0x8f, 0x8b, 0x7d, 0x02, 0xd4, 0xe0, 0x3f, 0xa2, 0x17, 0x70, 0x48,
+ 0x8e, 0x22, 0x97, 0x36, 0x39, 0x27, 0x80, 0xa3, 0x9b, 0x5c, 0xeb, 0x39,
+ 0xe7, 0x5a, 0xc0, 0x62, 0x9a, 0x7f, 0x72, 0xe8, 0x5b, 0x3e, 0x41, 0xed,
+ 0x10, 0x34, 0x5f, 0xd4, 0x7a, 0xca, 0xff, 0x04, 0xb8, 0xc2, 0xb7, 0x75,
+ 0x9e, 0xdb, 0xc5, 0x77, 0xfe, 0x66, 0x51, 0x76, 0xf5, 0x49, 0xec, 0x89,
+ 0xfd, 0xce, 0xf0, 0xfa, 0x1c, 0x7a, 0x1a, 0xce, 0xf3, 0x18, 0xd7, 0xf9,
+ 0xdd, 0x48, 0x7c, 0x6a, 0x62, 0xfc, 0x02, 0x46, 0x3e, 0x4f, 0x0f, 0xce,
+ 0xa7, 0xf5, 0x5d, 0x9f, 0x9f, 0xb5, 0x96, 0x41, 0x2f, 0x95, 0x1b, 0x0a,
+ 0xf5, 0x7d, 0xa4, 0xb0, 0x00, 0x9e, 0x95, 0x5b, 0xe9, 0x3c, 0xcf, 0xd9,
+ 0x5d, 0x73, 0x78, 0x6e, 0xf1, 0x77, 0x41, 0x3b, 0x6a, 0x11, 0x75, 0x11,
+ 0xfd, 0xd3, 0x3a, 0xf7, 0x61, 0xdc, 0x53, 0xc5, 0xf5, 0x72, 0x9c, 0x7b,
+ 0xb0, 0x77, 0x90, 0xff, 0xd7, 0xc1, 0x29, 0xf0, 0xfb, 0x29, 0x41, 0x4f,
+ 0x50, 0xd9, 0x49, 0xcf, 0xa3, 0x35, 0x38, 0x5b, 0x30, 0x0d, 0xe6, 0xe2,
+ 0xb0, 0x3d, 0x4d, 0xdc, 0x6b, 0x8d, 0x84, 0x55, 0x96, 0x69, 0x21, 0x1f,
+ 0xac, 0x68, 0xaa, 0x76, 0xf4, 0xd8, 0xb3, 0xc8, 0xd1, 0xd1, 0x4f, 0xb8,
+ 0xb6, 0xb1, 0x6f, 0x4f, 0xc0, 0x1e, 0xf4, 0x05, 0xeb, 0x92, 0xde, 0x6e,
+ 0xb0, 0x9e, 0x3c, 0x99, 0xe8, 0x11, 0x97, 0xfd, 0x54, 0xcf, 0x9f, 0xa0,
+ 0x87, 0x1c, 0x41, 0xdc, 0xff, 0x4a, 0xe8, 0x62, 0x1f, 0x64, 0xd0, 0x8f,
+ 0x8f, 0xd3, 0xbc, 0x5a, 0x8c, 0x6b, 0xf1, 0x79, 0xd4, 0xde, 0xa8, 0x98,
+ 0x85, 0xef, 0x72, 0xb1, 0x9e, 0x7a, 0xf3, 0x5f, 0x9a, 0xf3, 0x0f, 0xea,
+ 0x24, 0xf4, 0xe3, 0xbd, 0x8d, 0xb9, 0x95, 0x80, 0xde, 0x6c, 0xc6, 0xb5,
+ 0xdb, 0xbe, 0x88, 0x9e, 0xbf, 0xd2, 0xf8, 0x47, 0xda, 0xcb, 0x84, 0xc0,
+ 0x71, 0xe1, 0x02, 0x7c, 0x23, 0xb7, 0x7b, 0xe9, 0x35, 0xf4, 0xa8, 0x99,
+ 0x15, 0xd4, 0x65, 0xf8, 0x4d, 0x5c, 0xad, 0x8d, 0x73, 0x9f, 0x79, 0x03,
+ 0x5c, 0x9f, 0x2f, 0x2a, 0xdf, 0x34, 0x46, 0x69, 0xf9, 0x67, 0x5c, 0x67,
+ 0xe2, 0x7a, 0x0d, 0xfc, 0xb8, 0x74, 0xa5, 0xa5, 0x68, 0xb9, 0x65, 0xc3,
+ 0x2e, 0xfb, 0x41, 0x2f, 0xae, 0x38, 0x1f, 0x57, 0xf0, 0x8b, 0xf3, 0x2d,
+ 0xce, 0x04, 0x3e, 0x04, 0xec, 0x0f, 0xee, 0xbd, 0x39, 0x66, 0x9c, 0xff,
+ 0x4e, 0xe1, 0x99, 0xcf, 0xca, 0xbd, 0x32, 0xfb, 0x81, 0x7b, 0xe2, 0xee,
+ 0xfe, 0x9d, 0x73, 0x23, 0x74, 0x6e, 0x33, 0x87, 0xb8, 0x47, 0xa9, 0xc8,
+ 0xf9, 0x86, 0x1d, 0xf3, 0xaa, 0xde, 0xee, 0xf8, 0x3b, 0xf2, 0x59, 0xa7,
+ 0x57, 0x0a, 0xe9, 0xce, 0x8b, 0x22, 0xee, 0x3b, 0x42, 0xe4, 0x15, 0x3e,
+ 0xcb, 0x04, 0xee, 0x27, 0x1e, 0x7c, 0xe7, 0xa1, 0x2f, 0xe9, 0xf0, 0x73,
+ 0x38, 0xe1, 0xe7, 0x50, 0xeb, 0x44, 0x26, 0xed, 0xc7, 0x0e, 0x72, 0xee,
+ 0x17, 0xe2, 0x7f, 0xe7, 0xdc, 0x46, 0xc2, 0xb9, 0x6c, 0x8c, 0x4d, 0xb1,
+ 0xd2, 0x3d, 0xf7, 0x0e, 0xe6, 0x72, 0x5d, 0xf7, 0xa2, 0xc3, 0x62, 0x12,
+ 0xf3, 0x03, 0x9c, 0xe4, 0x75, 0x88, 0xff, 0x4a, 0x2f, 0x99, 0x57, 0x99,
+ 0x97, 0x29, 0x46, 0x5c, 0xe0, 0x31, 0xd5, 0xd1, 0x83, 0x3d, 0x70, 0xd7,
+ 0x59, 0xcd, 0xc4, 0xf8, 0x37, 0x83, 0x74, 0x4d, 0x81, 0xa6, 0x1b, 0x9e,
+ 0x7f, 0x87, 0xc7, 0x16, 0xcf, 0x4b, 0xca, 0xae, 0x58, 0xf4, 0xfa, 0x98,
+ 0xe7, 0xba, 0xc2, 0xf3, 0x77, 0x60, 0xf7, 0x5d, 0xe5, 0x50, 0x66, 0x94,
+ 0x39, 0xc9, 0x15, 0x2a, 0x0b, 0xdc, 0xe0, 0x0e, 0xd8, 0xd4, 0x97, 0xd0,
+ 0x1f, 0xb9, 0x12, 0xb1, 0xfd, 0x29, 0x6c, 0xe1, 0x7c, 0x0b, 0xbb, 0xc6,
+ 0xd7, 0x81, 0x83, 0x05, 0x7e, 0xdf, 0xc7, 0x18, 0xdf, 0x2d, 0x78, 0x7f,
+ 0x07, 0x67, 0xb0, 0x28, 0xb7, 0xaa, 0x71, 0xf7, 0x7b, 0x20, 0x77, 0x25,
+ 0xc1, 0x6b, 0x06, 0xdf, 0xe7, 0x63, 0xbc, 0x72, 0x1c, 0xd9, 0xe7, 0x5a,
+ 0x7f, 0x80, 0x38, 0x96, 0xe9, 0x2f, 0x31, 0x8f, 0xef, 0xfa, 0x31, 0x7e,
+ 0x61, 0x0f, 0x64, 0x5a, 0x9f, 0xca, 0x98, 0xe7, 0xe0, 0xc3, 0x65, 0x3f,
+ 0xc6, 0xd7, 0xf8, 0x4d, 0x1c, 0xbb, 0x83, 0xfd, 0x6e, 0x3d, 0xc3, 0xf6,
+ 0x49, 0x8a, 0x39, 0xe5, 0x2e, 0x72, 0x8f, 0xe9, 0x8f, 0x20, 0xdf, 0x62,
+ 0x5d, 0x2b, 0xe5, 0x7d, 0x16, 0x7c, 0x67, 0x5f, 0x33, 0xf7, 0x07, 0x92,
+ 0xe7, 0x2f, 0x22, 0xb6, 0x36, 0xfc, 0xd8, 0xe9, 0x05, 0xcc, 0x15, 0xb6,
+ 0xad, 0x97, 0xd4, 0xd5, 0xd4, 0xae, 0x4f, 0x63, 0x7b, 0x1e, 0xd6, 0x89,
+ 0xf9, 0xed, 0xc3, 0xe4, 0xec, 0x2e, 0xb9, 0xbf, 0x1f, 0x22, 0x87, 0xf9,
+ 0x6d, 0x96, 0xc9, 0xef, 0xf7, 0x20, 0xe5, 0x7d, 0x3c, 0x87, 0xc0, 0x3b,
+ 0xcb, 0x3e, 0x7a, 0xef, 0xec, 0xc6, 0x7e, 0x5a, 0xfb, 0x19, 0xdf, 0xbc,
+ 0xa7, 0xe7, 0x72, 0xef, 0xde, 0xc1, 0x76, 0x1e, 0x79, 0x2f, 0xf6, 0x03,
+ 0x72, 0xa6, 0x37, 0x3e, 0x47, 0x29, 0xfe, 0x1f, 0x60, 0x7c, 0x01, 0x76,
+ 0x55, 0x68, 0xa2, 0xc4, 0xe3, 0xc9, 0x03, 0x18, 0xe7, 0xfb, 0x3a, 0xd7,
+ 0xa6, 0x3c, 0xee, 0x61, 0x5c, 0xe7, 0xf9, 0x2e, 0xd6, 0xc9, 0x53, 0x95,
+ 0x35, 0x7e, 0xff, 0x2c, 0x79, 0xe7, 0xbc, 0xcc, 0x7d, 0xd4, 0x0d, 0x9c,
+ 0x9f, 0xeb, 0xd1, 0x18, 0xd5, 0x1d, 0xf8, 0xd5, 0x67, 0x1b, 0x2e, 0xd0,
+ 0x83, 0x1e, 0xec, 0xb0, 0xba, 0xb2, 0x6a, 0x76, 0x71, 0xe5, 0xb0, 0x7e,
+ 0x8c, 0xef, 0x27, 0x46, 0x79, 0xcd, 0x48, 0x7a, 0x78, 0xee, 0xbf, 0xf6,
+ 0xb4, 0x19, 0xf7, 0x62, 0x9c, 0x17, 0xb8, 0x07, 0x7b, 0x0d, 0xfb, 0xf6,
+ 0xc5, 0xef, 0xe1, 0x16, 0x8f, 0xec, 0x17, 0x8a, 0x79, 0xd1, 0xe1, 0x79,
+ 0x6a, 0x77, 0x84, 0x75, 0xf0, 0x8f, 0x88, 0x52, 0x9b, 0xa8, 0xfa, 0x16,
+ 0xd7, 0x54, 0x3b, 0xc9, 0xff, 0x17, 0x31, 0x3e, 0x9f, 0x60, 0x20, 0x3d,
+ 0x4b, 0xec, 0x57, 0xec, 0xaf, 0xf5, 0x2c, 0x30, 0xf5, 0xba, 0x9f, 0xda,
+ 0x0a, 0x6c, 0x7f, 0x23, 0xcd, 0x31, 0x88, 0x97, 0xda, 0xd3, 0x72, 0x34,
+ 0x84, 0x2d, 0xfc, 0xff, 0x82, 0x0a, 0x7a, 0x3b, 0xb6, 0x65, 0xc6, 0x78,
+ 0x79, 0xff, 0x7f, 0x04, 0x8f, 0xf6, 0x71, 0x1c, 0x3f, 0x8e, 0xef, 0x7e,
+ 0xfc, 0xac, 0x1c, 0x7c, 0xff, 0x51, 0xc3, 0xb3, 0x07, 0x04, 0xe7, 0x23,
+ 0xb2, 0xb2, 0x88, 0xc1, 0x5d, 0xc4, 0x28, 0x24, 0xaf, 0xf4, 0x41, 0xdc,
+ 0x9b, 0x13, 0x38, 0x37, 0x11, 0xe2, 0x19, 0x1c, 0xc0, 0xd9, 0x46, 0x3d,
+ 0xff, 0x3d, 0xe2, 0x38, 0x58, 0xb8, 0x6b, 0x74, 0x62, 0x37, 0x96, 0xc4,
+ 0x6e, 0xb4, 0xf5, 0xf0, 0x99, 0x5d, 0xf1, 0x52, 0xf2, 0xce, 0x67, 0xe2,
+ 0x5e, 0xc1, 0xe5, 0x1e, 0x09, 0x3e, 0x28, 0x19, 0x9d, 0x7b, 0x7b, 0x93,
+ 0xef, 0x97, 0x35, 0xce, 0xe5, 0xdc, 0xcf, 0x81, 0x6b, 0xa8, 0x96, 0x23,
+ 0xb8, 0x6b, 0x68, 0x5d, 0x2f, 0x31, 0x76, 0x27, 0xc6, 0xa7, 0x62, 0x0c,
+ 0x8b, 0x41, 0x41, 0x29, 0xb7, 0xba, 0x9f, 0x31, 0x96, 0xf8, 0x9e, 0xc6,
+ 0xef, 0x1d, 0x1d, 0x1b, 0xc0, 0x1d, 0x6e, 0x32, 0xb8, 0x1d, 0xb2, 0x7e,
+ 0xa3, 0xd3, 0x13, 0xdb, 0x11, 0xf3, 0x1e, 0xb8, 0x7b, 0x1f, 0x76, 0x85,
+ 0xe0, 0x6d, 0xe7, 0x6e, 0x37, 0x87, 0x9c, 0x72, 0x1b, 0xb1, 0xbd, 0xab,
+ 0x3a, 0x75, 0x71, 0x83, 0xfb, 0xae, 0x16, 0xf2, 0x4d, 0x1e, 0xbd, 0xb2,
+ 0x4a, 0xef, 0xa2, 0x16, 0x5d, 0xc3, 0x9a, 0xeb, 0x98, 0xbb, 0xd2, 0x4a,
+ 0x71, 0x84, 0x1e, 0x0f, 0xd8, 0x9c, 0x57, 0xff, 0xd4, 0x55, 0xa7, 0x7b,
+ 0x2d, 0xff, 0xfd, 0x07, 0x5d, 0xe7, 0x92, 0xbb, 0xa8, 0x13, 0x00, 0x00,
+ 0x00 };
static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = {
0x00000001, 0x00000000 };
static struct fw_info bnx2_tpat_fw_09 = {
- /* Firmware version: 4.4.26 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x1a,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
.start_addr = 0x08000488,
.text_addr = 0x08000400,
- .text_len = 0x1514,
+ .text_len = 0x13a4,
.text_index = 0x0,
.gz_text = bnx2_TPAT_b09FwText,
.gz_text_len = sizeof(bnx2_TPAT_b09FwText),
@@ -3709,871 +3643,868 @@ static struct fw_info bnx2_tpat_fw_09 = {
.data_index = 0x0,
.data = bnx2_TPAT_b09FwData,
- .sbss_addr = 0x08001940,
- .sbss_len = 0x48,
+ .sbss_addr = 0x080017c0,
+ .sbss_len = 0x40,
.sbss_index = 0x0,
- .bss_addr = 0x08001988,
+ .bss_addr = 0x08001800,
.bss_len = 0x12b4,
.bss_index = 0x0,
- .rodata_addr = 0x08001914,
+ .rodata_addr = 0x080017a4,
.rodata_len = 0x4,
.rodata_index = 0x0,
.rodata = bnx2_TPAT_b09FwRodata,
};
static u8 bnx2_TXP_b09FwText[] = {
- 0xc5, 0x7b, 0x7b, 0x74, 0x1c, 0x55, 0x9a, 0xdf, 0xef, 0x56, 0x3f, 0x54,
- 0xdd, 0x6a, 0xb5, 0x4a, 0x72, 0xdb, 0x6e, 0xed, 0x68, 0xc6, 0x5d, 0xee,
- 0x6a, 0xb9, 0xb1, 0x84, 0x5d, 0x2d, 0xb5, 0xec, 0x66, 0x5d, 0xb1, 0x7b,
- 0x8c, 0xb0, 0x65, 0x10, 0x3b, 0xc2, 0xeb, 0x9d, 0x88, 0x09, 0x27, 0xf4,
- 0x18, 0x19, 0x64, 0x63, 0x40, 0x30, 0x64, 0xa3, 0xd9, 0x25, 0xeb, 0x1a,
- 0xf9, 0x81, 0x1f, 0xad, 0xee, 0xd6, 0xc3, 0xc8, 0xec, 0xd9, 0x13, 0x64,
- 0x49, 0xb6, 0xcc, 0xd0, 0x0f, 0x33, 0xc0, 0xcc, 0x30, 0x27, 0x13, 0x77,
- 0x8c, 0x01, 0x03, 0x63, 0x98, 0xdd, 0x6c, 0x92, 0x99, 0x3d, 0x49, 0xd6,
- 0x07, 0xf3, 0xb0, 0xc1, 0x60, 0x32, 0x43, 0x12, 0xb1, 0xcb, 0x4c, 0xe5,
- 0xfb, 0xaa, 0x25, 0x63, 0x58, 0xb2, 0x9b, 0x6c, 0xfe, 0x88, 0xce, 0xd1,
- 0xe9, 0xee, 0xaa, 0x5b, 0xf7, 0x7e, 0xef, 0xef, 0xf7, 0x7d, 0xf7, 0x56,
- 0x04, 0xf0, 0x62, 0xee, 0xaf, 0x86, 0xfe, 0xe3, 0xfd, 0x03, 0x0f, 0xb7,
- 0xae, 0x88, 0xaf, 0xa0, 0xaf, 0x6d, 0x58, 0xec, 0x74, 0xf2, 0xcd, 0x55,
- 0x02, 0x48, 0xbd, 0x87, 0x7f, 0xd4, 0xdf, 0x57, 0xff, 0x71, 0x8f, 0xc1,
- 0x01, 0x28, 0xf3, 0x34, 0xf1, 0x3f, 0x64, 0xc9, 0x30, 0xd7, 0xac, 0xd7,
- 0x20, 0x3b, 0x8c, 0xc4, 0xda, 0xbb, 0x34, 0x20, 0x99, 0x6f, 0x0e, 0xdd,
- 0x88, 0xdf, 0x58, 0x66, 0xc0, 0x09, 0xbe, 0xfe, 0x55, 0xe3, 0xd3, 0x5d,
- 0x3f, 0x5d, 0xad, 0x7e, 0x34, 0xe1, 0x80, 0xac, 0x18, 0x63, 0x50, 0x9a,
- 0x20, 0x37, 0xd2, 0x33, 0x7f, 0xb6, 0xec, 0x79, 0x27, 0xfc, 0xf3, 0x73,
- 0xc1, 0x74, 0x19, 0x3a, 0x76, 0x67, 0xfb, 0x31, 0x13, 0x07, 0x2e, 0xa6,
- 0x23, 0xfa, 0x6e, 0x20, 0x27, 0x19, 0x91, 0xd0, 0x69, 0x84, 0x30, 0x9d,
- 0x87, 0x59, 0x65, 0x68, 0xd8, 0x5f, 0x0a, 0xe1, 0x52, 0xfa, 0xb7, 0x56,
- 0xc8, 0xd5, 0x8f, 0xb7, 0xe2, 0x90, 0x83, 0xc6, 0x23, 0x08, 0x66, 0x21,
- 0xd7, 0x18, 0x03, 0x28, 0x0c, 0x01, 0x7b, 0xd3, 0x6a, 0x3f, 0xa0, 0xf6,
- 0x14, 0x45, 0xf8, 0xec, 0x09, 0xa8, 0xdd, 0x0d, 0x8e, 0xe6, 0xd4, 0xed,
- 0x42, 0x4d, 0xee, 0x14, 0x90, 0x05, 0x8d, 0x5d, 0x9e, 0xe7, 0xcf, 0x01,
- 0x44, 0xf3, 0x32, 0xce, 0x3b, 0x78, 0x59, 0x83, 0xe4, 0x2c, 0xe0, 0xd4,
- 0x74, 0xec, 0xcd, 0xc2, 0x74, 0x1a, 0x02, 0xbb, 0xe3, 0x11, 0x65, 0x0a,
- 0x7c, 0x3f, 0x84, 0x41, 0x7b, 0x9c, 0x4a, 0x1c, 0x5b, 0xd6, 0x1e, 0xdd,
- 0xb2, 0x8e, 0xe9, 0x55, 0x30, 0x15, 0x35, 0x08, 0x08, 0x0c, 0xea, 0x12,
- 0x92, 0xca, 0xfa, 0x90, 0x13, 0x6a, 0x70, 0x1b, 0xfe, 0x96, 0xf8, 0x4d,
- 0x46, 0x5d, 0xa8, 0x8c, 0x4f, 0xa1, 0x0a, 0x65, 0xa5, 0x22, 0xb1, 0xc9,
- 0xb4, 0x65, 0xbd, 0xa4, 0x39, 0x71, 0x8c, 0x64, 0x33, 0x98, 0xff, 0x5b,
- 0xab, 0x4c, 0x72, 0xd9, 0xa3, 0xcd, 0xaf, 0x2f, 0x63, 0x42, 0xb1, 0xac,
- 0x29, 0xba, 0xb7, 0x2f, 0x3f, 0x2f, 0x63, 0xcb, 0x92, 0x34, 0xcb, 0xba,
- 0x4b, 0xfb, 0x1b, 0x6b, 0xeb, 0xe7, 0xc6, 0xc6, 0xf0, 0xfd, 0x9c, 0x82,
- 0xa7, 0xb2, 0x49, 0xe4, 0xd3, 0x16, 0x1c, 0x86, 0x13, 0x7d, 0x43, 0x21,
- 0xec, 0x2c, 0x74, 0xa0, 0x90, 0x56, 0x53, 0xe7, 0xe9, 0xb9, 0xad, 0x71,
- 0x0d, 0xf7, 0x15, 0x3a, 0x31, 0x93, 0x86, 0xe5, 0x31, 0xb4, 0xb2, 0x47,
- 0x44, 0x71, 0x4f, 0xa1, 0x0b, 0xc5, 0xb4, 0x76, 0x76, 0x50, 0x44, 0x06,
- 0x1a, 0x1c, 0x4e, 0x3c, 0x50, 0x68, 0xc1, 0xfd, 0x85, 0x04, 0x3d, 0x63,
- 0xe1, 0xe6, 0x58, 0x23, 0x8d, 0x6f, 0xc5, 0x93, 0x63, 0x96, 0x15, 0x8d,
- 0x29, 0xe8, 0x2b, 0xe8, 0x98, 0xc9, 0x49, 0x48, 0x1d, 0x73, 0x22, 0x75,
- 0x14, 0xb8, 0xe7, 0x68, 0x2b, 0xa6, 0x72, 0x16, 0xb6, 0xea, 0x83, 0x0d,
- 0x12, 0x5c, 0x48, 0x29, 0x02, 0x2e, 0xcd, 0x8f, 0x6d, 0x4a, 0x85, 0xf6,
- 0xf3, 0x0e, 0x81, 0x1d, 0x47, 0xa3, 0xf8, 0x45, 0xda, 0xc4, 0xcd, 0xed,
- 0x41, 0x0c, 0x14, 0x02, 0x78, 0x23, 0x1d, 0xa0, 0x35, 0x74, 0xbc, 0x9e,
- 0x96, 0x69, 0x9d, 0x16, 0x9c, 0x49, 0xf3, 0x18, 0x1e, 0xeb, 0x43, 0x6f,
- 0xa1, 0x11, 0xe7, 0xd2, 0x41, 0x5a, 0x33, 0x80, 0x57, 0x68, 0xdc, 0xf6,
- 0x82, 0x86, 0xb3, 0x34, 0xae, 0xaf, 0x10, 0xc2, 0xcb, 0x69, 0x1f, 0xd1,
- 0x1a, 0xc0, 0xe9, 0x74, 0x3f, 0x76, 0xa7, 0x9b, 0xcf, 0xde, 0x48, 0x32,
- 0x0c, 0x2d, 0xe0, 0x75, 0xf8, 0xda, 0x5b, 0x56, 0x57, 0xc0, 0x36, 0x13,
- 0x5a, 0x67, 0x7e, 0xdd, 0x7e, 0x0c, 0xa6, 0xcf, 0xcc, 0xf9, 0x89, 0x8e,
- 0x03, 0xb9, 0x59, 0xeb, 0xa7, 0xcb, 0x1a, 0x71, 0x22, 0x0b, 0x3c, 0x39,
- 0x05, 0x4c, 0x65, 0x4d, 0xab, 0xc6, 0xb0, 0xac, 0xc9, 0xf6, 0x16, 0x92,
- 0x97, 0xd6, 0xb3, 0x95, 0x46, 0x3d, 0x55, 0x72, 0x02, 0x47, 0xd5, 0x9e,
- 0x32, 0x24, 0x4c, 0xcc, 0x38, 0xe1, 0x1e, 0x52, 0x3b, 0x27, 0xa0, 0x9e,
- 0xbd, 0x87, 0x3c, 0xe9, 0x58, 0x56, 0xed, 0x36, 0xb1, 0xcb, 0x0a, 0x1a,
- 0x4d, 0xa1, 0x16, 0x87, 0x05, 0x3f, 0xd9, 0x42, 0xba, 0xc5, 0xb2, 0x6a,
- 0x57, 0x5b, 0xd6, 0xb9, 0x76, 0x58, 0x92, 0xa1, 0x9d, 0x2d, 0x41, 0x2b,
- 0x7f, 0x00, 0x6d, 0xe0, 0x34, 0xca, 0x5f, 0xf5, 0x21, 0xd2, 0x17, 0x76,
- 0x44, 0xfa, 0x67, 0xe9, 0xd9, 0x9a, 0x02, 0x99, 0x32, 0xf1, 0xa2, 0x91,
- 0x0d, 0x16, 0x4a, 0x32, 0x9c, 0xc4, 0x4f, 0xcb, 0x90, 0x65, 0x39, 0x35,
- 0x1f, 0x7c, 0x24, 0xdf, 0x8d, 0x87, 0x2d, 0xeb, 0x1d, 0x5d, 0x81, 0x9b,
- 0x74, 0x73, 0xd3, 0xb0, 0x85, 0x49, 0xfd, 0x34, 0xc9, 0x53, 0x20, 0xd5,
- 0x1d, 0xa7, 0x67, 0x02, 0x34, 0x3e, 0x81, 0x8d, 0x43, 0x41, 0x7c, 0x3f,
- 0x2b, 0xe3, 0xa7, 0xcb, 0xa2, 0xa8, 0xa6, 0xb9, 0xbc, 0x24, 0xab, 0x2a,
- 0x92, 0x1f, 0x0a, 0x64, 0x6e, 0x85, 0x8a, 0x3d, 0xa2, 0x70, 0x9e, 0x78,
- 0x0c, 0xe2, 0x07, 0xa5, 0x00, 0x9e, 0x2e, 0x29, 0x38, 0x59, 0x6a, 0xc4,
- 0xa9, 0x92, 0x8e, 0x6c, 0x4e, 0xdd, 0x5f, 0x86, 0x85, 0x1a, 0x32, 0xe7,
- 0x37, 0x26, 0x62, 0xc8, 0xe4, 0x2c, 0x2b, 0x4f, 0x34, 0x7b, 0x89, 0x87,
- 0xd7, 0x27, 0xbe, 0x86, 0xe3, 0x63, 0x4e, 0x84, 0x26, 0x03, 0x78, 0x2a,
- 0xed, 0xc4, 0x75, 0x19, 0xd5, 0x9c, 0x80, 0x16, 0xdd, 0x29, 0xb4, 0xe4,
- 0x72, 0xa1, 0xe6, 0x4c, 0x44, 0x42, 0x2e, 0x21, 0xa1, 0xe9, 0xb8, 0x13,
- 0x5a, 0x31, 0x04, 0x57, 0x93, 0x0c, 0xad, 0x89, 0xdc, 0xc8, 0x2f, 0xc1,
- 0x4d, 0x7e, 0xb1, 0x71, 0x24, 0x4a, 0xd7, 0x02, 0x74, 0x0d, 0x5f, 0xab,
- 0x82, 0x63, 0x91, 0x03, 0x24, 0x37, 0xcd, 0x81, 0xa4, 0xd3, 0xb2, 0x1c,
- 0x5a, 0x2b, 0x7a, 0x1e, 0xa3, 0xcf, 0x36, 0x1e, 0xaf, 0x20, 0x5c, 0x24,
- 0x19, 0x34, 0x11, 0x4d, 0x59, 0xa2, 0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6,
- 0xac, 0x83, 0x6c, 0x46, 0xd5, 0x81, 0x3f, 0x22, 0x5d, 0x85, 0x88, 0xbf,
- 0x5f, 0xd8, 0x7a, 0x7a, 0xba, 0x14, 0x24, 0xfa, 0x43, 0x36, 0xfd, 0x4f,
- 0xe6, 0x04, 0x24, 0x4d, 0xed, 0x3e, 0x8f, 0x75, 0x08, 0xc7, 0xd4, 0xe4,
- 0x04, 0x92, 0xf4, 0x9c, 0xba, 0xdf, 0x84, 0xda, 0x59, 0x26, 0xfd, 0x6f,
- 0x55, 0x12, 0x98, 0xc9, 0xba, 0x50, 0xad, 0xa9, 0x21, 0xd2, 0x57, 0xb4,
- 0x8c, 0x05, 0xb8, 0x57, 0xa1, 0x39, 0x25, 0xb7, 0xa8, 0xc4, 0x90, 0x47,
- 0x10, 0x19, 0x91, 0x30, 0xad, 0x3b, 0xc8, 0x3f, 0x75, 0x38, 0x9a, 0x68,
- 0xb9, 0x62, 0x9c, 0x3e, 0x69, 0xfe, 0x2c, 0xad, 0x45, 0xf4, 0xd0, 0x7c,
- 0xe4, 0x97, 0x2c, 0xc7, 0x28, 0xd1, 0xb0, 0xd7, 0xa6, 0xf7, 0x64, 0xa9,
- 0x4b, 0x54, 0xec, 0xc7, 0x20, 0x7b, 0x51, 0x43, 0x10, 0x6a, 0x34, 0x24,
- 0x54, 0x3d, 0x29, 0x14, 0x4c, 0x95, 0x7e, 0x46, 0x63, 0x02, 0xd7, 0x8c,
- 0xe9, 0xc6, 0x60, 0x56, 0xe0, 0x46, 0xcd, 0xc2, 0x7a, 0xbd, 0x1b, 0xbb,
- 0x4b, 0xf3, 0x7e, 0xc9, 0xb1, 0x4b, 0xf1, 0x4f, 0xa5, 0x3b, 0xb0, 0x27,
- 0x1b, 0xc2, 0xee, 0x7c, 0xd0, 0x3f, 0x99, 0xe6, 0x7b, 0x1a, 0xf9, 0x3b,
- 0xdf, 0x0b, 0x5c, 0x73, 0xaf, 0xf1, 0x9a, 0x7b, 0x09, 0x0c, 0x8e, 0x7e,
- 0x85, 0x62, 0x48, 0x2d, 0x76, 0x6b, 0x1f, 0x91, 0xad, 0x68, 0x89, 0x5e,
- 0x34, 0xe0, 0xbc, 0xd2, 0x82, 0x43, 0xe3, 0x5d, 0xd8, 0x33, 0xbe, 0x02,
- 0x07, 0x46, 0x1b, 0x53, 0x5e, 0x63, 0x88, 0xd6, 0x0f, 0x27, 0x7b, 0x85,
- 0xda, 0xef, 0x10, 0xe1, 0x68, 0x2f, 0xd9, 0x6e, 0x53, 0x9d, 0x65, 0x9d,
- 0x8e, 0x91, 0x6d, 0xeb, 0xcd, 0xfa, 0x46, 0x12, 0x40, 0xb9, 0x5b, 0xed,
- 0x7c, 0x0b, 0x3e, 0xdc, 0x4a, 0x36, 0x37, 0x15, 0x43, 0xaf, 0x03, 0x8e,
- 0x16, 0x1f, 0x7e, 0x6d, 0x1d, 0x75, 0xb2, 0xdc, 0xad, 0x5d, 0x77, 0xe9,
- 0x7b, 0x05, 0xc7, 0x39, 0xf7, 0xd5, 0x58, 0xc2, 0xf3, 0xf3, 0x33, 0x96,
- 0x15, 0xa6, 0x79, 0xfa, 0x62, 0xcd, 0x89, 0x3e, 0xcc, 0x5a, 0xe7, 0xb7,
- 0x74, 0x61, 0xf7, 0xcc, 0x0a, 0x1c, 0x1c, 0x75, 0x21, 0x59, 0x27, 0x50,
- 0xab, 0x85, 0xcb, 0xf7, 0x62, 0x05, 0xcc, 0x29, 0x7e, 0xae, 0x0b, 0x47,
- 0x66, 0x2a, 0xbf, 0xb3, 0x57, 0x7f, 0xcf, 0xcf, 0x77, 0x91, 0x74, 0xca,
- 0xf2, 0xe4, 0x38, 0x49, 0x2a, 0x30, 0x9a, 0x71, 0x62, 0x34, 0x40, 0xba,
- 0xed, 0x10, 0xce, 0xe3, 0x8b, 0xfc, 0xde, 0xc7, 0x2c, 0xbc, 0xa4, 0x93,
- 0x9e, 0xb3, 0x1b, 0x84, 0xf7, 0x78, 0xa7, 0x70, 0x15, 0x37, 0x0b, 0xf7,
- 0xe4, 0xb7, 0x84, 0x7c, 0x3c, 0x25, 0xaa, 0x8a, 0x2d, 0x24, 0xfb, 0x1e,
- 0xe1, 0x39, 0xae, 0x86, 0x42, 0xe2, 0xbb, 0xa4, 0xcf, 0x2d, 0xc2, 0x51,
- 0x84, 0x22, 0x19, 0x03, 0x42, 0x2a, 0xd2, 0x1c, 0xb6, 0x0d, 0xf1, 0x3a,
- 0x41, 0xd2, 0x1b, 0x4c, 0x87, 0xd1, 0x8f, 0xad, 0x94, 0x23, 0x6e, 0x49,
- 0x1b, 0x38, 0x98, 0xad, 0xa2, 0xf8, 0xc8, 0x7e, 0x3f, 0x4b, 0xeb, 0x6a,
- 0x38, 0x54, 0x82, 0xe9, 0x31, 0x0e, 0x62, 0x05, 0xf9, 0xdb, 0xb9, 0x18,
- 0xfb, 0x22, 0x90, 0xcf, 0x86, 0x93, 0x07, 0x85, 0x65, 0x55, 0x45, 0xac,
- 0x25, 0xef, 0xe8, 0xcd, 0xd1, 0x33, 0xf8, 0x9f, 0xd6, 0x44, 0xa0, 0x1f,
- 0xd1, 0x76, 0xc8, 0x55, 0xc6, 0x1e, 0xbc, 0x9b, 0x86, 0xec, 0x36, 0x4c,
- 0xbc, 0x94, 0x06, 0x7c, 0x43, 0x83, 0x8a, 0x17, 0x64, 0x07, 0x08, 0x07,
- 0x0f, 0x09, 0xb5, 0xfb, 0x02, 0xa5, 0xb3, 0x44, 0xbb, 0x39, 0x20, 0x81,
- 0xe2, 0x91, 0x50, 0x7b, 0xce, 0x90, 0x3d, 0x7e, 0x57, 0xa8, 0xca, 0xac,
- 0x60, 0x3f, 0xe5, 0x5c, 0xb2, 0x67, 0x2e, 0xa7, 0x98, 0xb8, 0xee, 0x9a,
- 0x9c, 0x32, 0x48, 0x74, 0xed, 0x23, 0xba, 0x5e, 0xd4, 0xd5, 0xe0, 0x24,
- 0xac, 0x25, 0xbd, 0x3a, 0xdf, 0x33, 0xb0, 0xa7, 0x64, 0x85, 0x1c, 0x06,
- 0xcb, 0x0a, 0xa9, 0x2a, 0x03, 0xa6, 0x6c, 0x28, 0xe4, 0x1b, 0xbf, 0xb1,
- 0x7a, 0xe3, 0xb2, 0xfe, 0x76, 0x5e, 0x21, 0x79, 0xc1, 0xef, 0x2c, 0x7c,
- 0x59, 0xde, 0xb5, 0x20, 0x19, 0xbf, 0xb1, 0xee, 0x8c, 0xc3, 0xbf, 0xa4,
- 0xe0, 0x4c, 0x55, 0x1b, 0xe8, 0x1e, 0x18, 0xda, 0x65, 0x35, 0x68, 0x12,
- 0xc5, 0x29, 0x8d, 0xe2, 0xba, 0x2f, 0x71, 0xb9, 0xdd, 0x23, 0xce, 0xb5,
- 0x07, 0xbb, 0x3e, 0xc8, 0x7b, 0x48, 0xcf, 0xe8, 0xde, 0x59, 0x48, 0x38,
- 0xdf, 0x23, 0x5b, 0x73, 0x53, 0x4c, 0x45, 0xa1, 0xb1, 0xeb, 0x12, 0xe5,
- 0xa1, 0x9b, 0x62, 0x9e, 0x7f, 0xea, 0x36, 0xa4, 0xaf, 0x79, 0xf0, 0xe0,
- 0xca, 0xe9, 0x44, 0x2d, 0xc5, 0x75, 0x05, 0x67, 0xe3, 0x9d, 0x18, 0x2c,
- 0x55, 0x91, 0x1d, 0x3e, 0x53, 0xde, 0xab, 0x35, 0x76, 0xbd, 0x9f, 0x5e,
- 0xc2, 0x71, 0xe4, 0xd3, 0x7c, 0xbb, 0xd6, 0xbd, 0x53, 0x9c, 0xde, 0xe4,
- 0x45, 0x1c, 0x07, 0x4a, 0xb2, 0xfc, 0x49, 0x1a, 0x1f, 0x2d, 0xd1, 0xb4,
- 0xf2, 0x3a, 0x47, 0x53, 0xbf, 0xec, 0x68, 0x1a, 0x70, 0x53, 0x0c, 0xbe,
- 0x78, 0xbd, 0xc0, 0x4b, 0xd7, 0x47, 0x12, 0x6e, 0xe1, 0xc1, 0xf9, 0xee,
- 0x04, 0xd9, 0x49, 0x63, 0xca, 0x63, 0x50, 0xfc, 0x20, 0x93, 0x75, 0x68,
- 0x09, 0xec, 0x9e, 0xc2, 0x23, 0x83, 0x7a, 0x17, 0xcc, 0x19, 0xb6, 0xa1,
- 0x16, 0x0c, 0xce, 0x74, 0xc3, 0x2c, 0x39, 0x30, 0x11, 0x20, 0xe6, 0x4b,
- 0x48, 0xb9, 0x8c, 0x96, 0x8e, 0x89, 0x7c, 0xaf, 0xab, 0xe2, 0xc3, 0xc4,
- 0x7f, 0xf6, 0xa8, 0x1f, 0x5e, 0xd6, 0xf3, 0x59, 0x92, 0x51, 0x0b, 0x9e,
- 0x29, 0x45, 0x29, 0xd6, 0xe9, 0x24, 0x17, 0x8d, 0xe2, 0x45, 0x88, 0xec,
- 0x4b, 0xc6, 0xd6, 0x51, 0xf5, 0x08, 0xc5, 0x85, 0xdc, 0x04, 0xda, 0x91,
- 0x0c, 0x28, 0x94, 0xbb, 0x5f, 0x9a, 0x8b, 0x01, 0xdb, 0xe8, 0x53, 0x35,
- 0x93, 0xc0, 0x19, 0x09, 0x68, 0x6d, 0x30, 0x22, 0xfb, 0x1b, 0x48, 0x1f,
- 0x75, 0x45, 0x0f, 0x1e, 0x18, 0xad, 0xc7, 0xfd, 0xe3, 0x5e, 0xec, 0x18,
- 0xb5, 0x70, 0x39, 0xc6, 0xb6, 0xa1, 0xf6, 0x10, 0x89, 0x1d, 0xd5, 0x24,
- 0xd7, 0x4d, 0xb1, 0x48, 0xc2, 0x23, 0x9c, 0xa8, 0x2a, 0x76, 0x13, 0x06,
- 0x48, 0xb2, 0x5f, 0xe8, 0x34, 0x47, 0x68, 0xb7, 0x7e, 0x2b, 0x52, 0x01,
- 0x19, 0xae, 0xa2, 0x8f, 0x62, 0x09, 0xfb, 0x31, 0xdf, 0xfb, 0x06, 0xb6,
- 0xba, 0x7d, 0x70, 0x64, 0x64, 0xe4, 0x28, 0xff, 0x63, 0x91, 0x1b, 0x9d,
- 0x4d, 0x12, 0xfd, 0x07, 0xfc, 0xd3, 0x63, 0x8d, 0xfe, 0x63, 0x14, 0x5f,
- 0xef, 0xc9, 0x4a, 0xbc, 0x0e, 0xe3, 0x05, 0x9a, 0x5b, 0xc1, 0x93, 0x14,
- 0xab, 0x1f, 0xa2, 0xf8, 0x73, 0xa2, 0x94, 0x17, 0x1c, 0x4f, 0x6c, 0x7e,
- 0xb2, 0xc4, 0x5b, 0x96, 0x78, 0xcb, 0x12, 0x5f, 0x14, 0x17, 0x4e, 0x66,
- 0x99, 0x8f, 0x2b, 0xe4, 0xa3, 0x09, 0xe2, 0xdd, 0x83, 0x6d, 0x44, 0xef,
- 0x83, 0xe3, 0xd5, 0xb8, 0x8f, 0xe8, 0x2d, 0xea, 0x6a, 0xcf, 0x9f, 0x0b,
- 0x0b, 0xf9, 0x98, 0x6a, 0xee, 0x14, 0x5e, 0x48, 0x4d, 0x96, 0xd5, 0xad,
- 0x33, 0xcf, 0x64, 0xa7, 0x92, 0xcd, 0xf3, 0xfe, 0x24, 0x3c, 0xe8, 0xa3,
- 0x67, 0x7a, 0xc7, 0xf1, 0xa9, 0x44, 0x3c, 0x79, 0x88, 0xc7, 0x83, 0xba,
- 0x9a, 0x58, 0x4e, 0x71, 0xfd, 0x82, 0x16, 0x29, 0x5f, 0x70, 0xe0, 0xeb,
- 0x24, 0x0f, 0x9d, 0xe5, 0xd1, 0x44, 0xfc, 0x3c, 0x40, 0x58, 0xc7, 0x6f,
- 0x30, 0x9f, 0x91, 0xe8, 0xaf, 0x89, 0xf7, 0x48, 0x31, 0xe0, 0x3f, 0x77,
- 0xb8, 0xd1, 0xff, 0xe2, 0x50, 0x85, 0xfe, 0x9d, 0x44, 0xff, 0x74, 0xcc,
- 0xc2, 0x21, 0xa2, 0xff, 0x29, 0xa2, 0xbf, 0x8f, 0xe3, 0xf9, 0x1c, 0xfd,
- 0x27, 0x4a, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x3d, 0xb6, 0x8e,
- 0xcf, 0xcb, 0xcb, 0xb2, 0xee, 0xd4, 0x9f, 0xb5, 0xbe, 0x4d, 0x32, 0x5b,
- 0x52, 0x64, 0xb9, 0x31, 0x8e, 0x8b, 0x1c, 0xb9, 0x07, 0x7d, 0x12, 0xbc,
- 0x3e, 0x2c, 0x28, 0x72, 0x2e, 0x08, 0xe1, 0x59, 0xd2, 0xef, 0x29, 0xca,
- 0x65, 0xcf, 0x94, 0xae, 0xcd, 0x6d, 0xac, 0xeb, 0x31, 0xd2, 0xb1, 0x3a,
- 0x61, 0x52, 0x6c, 0x4b, 0x95, 0x92, 0xd8, 0x3b, 0x8e, 0xe4, 0xb4, 0xfe,
- 0xaf, 0x29, 0xc0, 0x2c, 0x22, 0xfb, 0xaa, 0x4a, 0x2a, 0x9a, 0x17, 0x77,
- 0x4d, 0x05, 0xd0, 0x5f, 0x5a, 0x8f, 0x2c, 0xc5, 0x9b, 0x9d, 0x14, 0x9f,
- 0x3f, 0x8c, 0x25, 0x77, 0xf8, 0x11, 0x21, 0xfd, 0x06, 0x70, 0x2f, 0x3d,
- 0x73, 0x70, 0x9c, 0xe9, 0x57, 0xe6, 0xf4, 0x1c, 0xc0, 0x3d, 0x74, 0x6d,
- 0xdf, 0xb8, 0x8c, 0x17, 0xf4, 0x27, 0x08, 0xcf, 0x54, 0xf0, 0xc5, 0xdd,
- 0x59, 0x28, 0xe4, 0x9e, 0x84, 0xff, 0x22, 0xd1, 0x17, 0xe8, 0xf7, 0xb6,
- 0x92, 0xd7, 0x3f, 0x38, 0x86, 0xef, 0x2d, 0x31, 0xfc, 0x58, 0x40, 0x58,
- 0xec, 0x76, 0x3d, 0x42, 0x76, 0xef, 0xc4, 0x40, 0x49, 0xc2, 0x77, 0xa6,
- 0xbc, 0x78, 0x68, 0xf4, 0x53, 0xcb, 0x1d, 0x77, 0xe2, 0xb6, 0x26, 0x2f,
- 0x1e, 0x9c, 0x4a, 0x62, 0xff, 0x38, 0x42, 0x55, 0xb1, 0x61, 0x8a, 0xdd,
- 0x95, 0x7c, 0x50, 0x4d, 0xbc, 0x1f, 0x18, 0xf7, 0xf9, 0xfb, 0x0e, 0xb3,
- 0x0c, 0xd6, 0x07, 0x3d, 0x40, 0xb9, 0x2a, 0xe6, 0xc0, 0x36, 0xdd, 0xb1,
- 0xa0, 0x8a, 0x0c, 0xfd, 0x09, 0x9a, 0x6f, 0x12, 0x8e, 0x57, 0x97, 0x20,
- 0x72, 0xa4, 0xc1, 0x51, 0xce, 0x2d, 0x40, 0x3d, 0x1e, 0x9a, 0x49, 0x62,
- 0x98, 0x6c, 0xf4, 0x81, 0xd1, 0xc1, 0xef, 0xd5, 0x51, 0x0c, 0xf1, 0xb7,
- 0xaa, 0x7d, 0x6f, 0x08, 0x03, 0xf9, 0x88, 0x07, 0x3b, 0xa7, 0x7c, 0xfe,
- 0x1d, 0x87, 0xad, 0x75, 0x6c, 0x4f, 0xdb, 0x67, 0xea, 0x71, 0xdf, 0x38,
- 0x5d, 0x1b, 0x65, 0x1b, 0x26, 0x5b, 0x8b, 0x54, 0x11, 0x6f, 0xe1, 0xa4,
- 0x87, 0xf0, 0x92, 0x23, 0x56, 0x4d, 0xf2, 0xf0, 0xe0, 0x1e, 0xdb, 0x16,
- 0x14, 0x6c, 0x1b, 0xb7, 0xf0, 0xa6, 0x1e, 0x45, 0x8e, 0xec, 0xfa, 0xc8,
- 0xb8, 0x3a, 0xdb, 0x41, 0x58, 0xe7, 0x6d, 0x87, 0x7a, 0xa4, 0xc9, 0x91,
- 0x44, 0x7d, 0x1b, 0xc5, 0xf8, 0x7a, 0xcb, 0xba, 0xbb, 0xb5, 0xb9, 0xff,
- 0xe7, 0x44, 0x73, 0x9d, 0xb1, 0x08, 0xe5, 0x3a, 0x35, 0x07, 0x34, 0x0f,
- 0xb8, 0xa5, 0xeb, 0x71, 0x7e, 0x21, 0xc7, 0x41, 0x8e, 0xe5, 0x01, 0x7f,
- 0x7d, 0xa6, 0x92, 0xe3, 0xea, 0x8b, 0x8d, 0xfe, 0xba, 0x4c, 0xd0, 0x5f,
- 0x57, 0x84, 0xdf, 0x5d, 0x04, 0x7e, 0x4c, 0xf1, 0x65, 0x41, 0xdb, 0x6f,
- 0xac, 0x54, 0xbd, 0x8d, 0x07, 0xfd, 0xcf, 0x8f, 0xa9, 0x66, 0x19, 0xea,
- 0x7e, 0x0a, 0x9b, 0x78, 0x7c, 0xc6, 0xe9, 0x3f, 0x4e, 0xd8, 0xaf, 0x5e,
- 0x8b, 0x62, 0x1f, 0xe9, 0x73, 0x17, 0xd9, 0xc2, 0xaf, 0xdb, 0x80, 0x03,
- 0x99, 0x70, 0x48, 0x17, 0x3d, 0x34, 0x31, 0xb0, 0xa7, 0x48, 0x31, 0x5f,
- 0x4a, 0x52, 0x10, 0x53, 0xa3, 0x94, 0xd6, 0x90, 0xce, 0xb8, 0x60, 0x2e,
- 0xac, 0xe8, 0xe4, 0xbe, 0xec, 0x29, 0xcb, 0xaf, 0x69, 0x13, 0x45, 0xd2,
- 0xd9, 0xc3, 0x25, 0x1f, 0x06, 0x08, 0x0f, 0x2c, 0x20, 0x0c, 0xf9, 0x20,
- 0xd9, 0xc5, 0x03, 0xa3, 0x0e, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x54,
- 0xc1, 0xa2, 0x0f, 0x4d, 0xb1, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x4b,
- 0x39, 0xff, 0x99, 0xcf, 0x61, 0x10, 0x55, 0x31, 0xaf, 0xe6, 0xfe, 0x8a,
- 0x3c, 0x06, 0xc7, 0x99, 0x67, 0xf5, 0x08, 0xa4, 0x24, 0x6e, 0xd2, 0x7f,
- 0x49, 0x39, 0x81, 0x79, 0x27, 0x0c, 0x3c, 0x1e, 0xc5, 0xa3, 0x59, 0xc2,
- 0x34, 0xb1, 0xcb, 0xd6, 0x3d, 0x01, 0x96, 0x01, 0xf3, 0xb3, 0xca, 0xc1,
- 0xf9, 0xb3, 0x9e, 0xb0, 0xef, 0xff, 0xbb, 0xdd, 0xdd, 0x65, 0xa5, 0x6c,
- 0x2c, 0x4b, 0x18, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0xb4, 0xce,
- 0x07, 0x38, 0x5f, 0xd7, 0x23, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x44,
- 0x6f, 0xdd, 0xfd, 0xa0, 0x02, 0xb6, 0x87, 0xe8, 0x35, 0xf6, 0x50, 0x45,
- 0x34, 0x29, 0xd8, 0x31, 0xc3, 0xf6, 0x6b, 0x5d, 0x59, 0x62, 0xfc, 0xd6,
- 0xfa, 0x64, 0xb5, 0x76, 0xe4, 0x97, 0xe8, 0xa2, 0xeb, 0x01, 0x7c, 0x87,
- 0xfc, 0xe8, 0x5e, 0xe2, 0x73, 0x47, 0xfb, 0xbd, 0xb6, 0xdf, 0xee, 0x28,
- 0xad, 0xa1, 0xeb, 0x2c, 0xef, 0x0e, 0xec, 0xcf, 0xea, 0x48, 0x67, 0xcb,
- 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x11, 0xc5, 0xd9, 0x67, 0x4b, 0x8c,
- 0xc9, 0x12, 0x36, 0x1e, 0xfb, 0x61, 0xa9, 0x05, 0xcf, 0x91, 0x4f, 0x3e,
- 0x43, 0x31, 0xf7, 0x07, 0x36, 0x4e, 0x73, 0x8a, 0x43, 0x69, 0xc2, 0xa4,
- 0x43, 0x26, 0xd2, 0xf9, 0x10, 0x3c, 0x87, 0xc3, 0xfb, 0x77, 0x08, 0xf5,
- 0xc7, 0x24, 0x2f, 0xff, 0x81, 0xe9, 0xa5, 0xa8, 0x3a, 0xac, 0x4e, 0x10,
- 0xdd, 0xfe, 0x47, 0xa7, 0x35, 0xc2, 0xd4, 0x41, 0xff, 0xbe, 0xbc, 0xe2,
- 0xdf, 0x3b, 0x16, 0xf0, 0xef, 0x9d, 0xae, 0x27, 0x3f, 0x5a, 0xe4, 0x1f,
- 0x9c, 0x0e, 0xfa, 0x77, 0xa7, 0x1b, 0xfd, 0xbb, 0xf3, 0x6d, 0x08, 0xd5,
- 0xc3, 0x5c, 0x44, 0x39, 0xe2, 0xbe, 0xd1, 0x6f, 0x62, 0xa2, 0xae, 0x12,
- 0xf7, 0xfb, 0xc9, 0x36, 0x6a, 0xc9, 0x0e, 0x57, 0x4a, 0xb7, 0xa1, 0xbc,
- 0xb0, 0x72, 0xed, 0x3b, 0x74, 0xed, 0xa1, 0x56, 0xf8, 0xff, 0xc2, 0x8e,
- 0xbd, 0xc0, 0x73, 0x64, 0x6b, 0xcf, 0xb6, 0x52, 0x5d, 0x79, 0xd5, 0xd6,
- 0x9c, 0x14, 0x6f, 0x2d, 0x4b, 0x6f, 0x13, 0x08, 0xb6, 0x6e, 0x00, 0x16,
- 0xcc, 0xd7, 0x92, 0xc9, 0x09, 0x67, 0x6b, 0x12, 0x4b, 0xb4, 0x8d, 0x78,
- 0x42, 0xa1, 0x54, 0xd3, 0xfa, 0x75, 0xcc, 0x3d, 0x83, 0xef, 0x8c, 0x7a,
- 0x90, 0xda, 0xac, 0x60, 0x9a, 0xb0, 0xca, 0x76, 0x9a, 0x7f, 0x59, 0xac,
- 0x59, 0x99, 0x21, 0x3d, 0x24, 0x15, 0xbe, 0x46, 0x3e, 0xd1, 0xba, 0x8a,
- 0x7c, 0xa2, 0xb2, 0xfe, 0xd3, 0xa4, 0xaf, 0xdc, 0x4c, 0x14, 0x7b, 0x4b,
- 0x3f, 0x91, 0x2a, 0xf9, 0x45, 0x9d, 0x48, 0xe2, 0xac, 0x3d, 0xf6, 0xe9,
- 0xec, 0x1b, 0x56, 0xc8, 0xb6, 0x3b, 0x81, 0xc7, 0x56, 0x44, 0xf6, 0xff,
- 0x27, 0xa9, 0x81, 0xf8, 0x22, 0xd9, 0x65, 0xed, 0x3a, 0xb2, 0x76, 0xb1,
- 0xf6, 0x2f, 0xf0, 0x23, 0x85, 0x65, 0x3b, 0x20, 0xf6, 0x53, 0xbd, 0x4a,
- 0xa5, 0x53, 0xed, 0x02, 0xed, 0x30, 0x9e, 0xe9, 0xe6, 0x6b, 0x01, 0xff,
- 0x81, 0xb1, 0xa4, 0x14, 0xd0, 0xa0, 0xb8, 0x8c, 0x0e, 0x71, 0x60, 0x7a,
- 0x91, 0xff, 0xd1, 0xb1, 0x0d, 0xe2, 0xd1, 0xe9, 0x46, 0xff, 0x60, 0xba,
- 0x53, 0x0c, 0xe6, 0x37, 0x0b, 0x73, 0xe2, 0x5b, 0xc2, 0x9c, 0x4e, 0x09,
- 0x33, 0xdf, 0x43, 0x9f, 0x5b, 0xc4, 0x58, 0x7e, 0x40, 0xec, 0xcd, 0xf3,
- 0xfc, 0xa4, 0x2b, 0x5a, 0xe3, 0x87, 0x14, 0x7b, 0x9f, 0xa3, 0xd8, 0xfb,
- 0x2c, 0xc5, 0xde, 0x67, 0xc8, 0xde, 0x7f, 0x70, 0x15, 0xe3, 0xb2, 0x8d,
- 0x27, 0x19, 0x9b, 0xf8, 0xff, 0xbc, 0x78, 0x86, 0xf4, 0xcd, 0xb2, 0xfb,
- 0x37, 0x64, 0xdb, 0x2c, 0x93, 0x87, 0x38, 0x57, 0x90, 0x9e, 0xde, 0xb7,
- 0x6d, 0xf9, 0xb1, 0x15, 0x8c, 0xa5, 0x06, 0xc4, 0x56, 0xa2, 0x2f, 0xe9,
- 0x24, 0x0c, 0xa4, 0x11, 0x3e, 0xc9, 0x0e, 0x88, 0xbb, 0xf3, 0x7c, 0xfd,
- 0x20, 0x76, 0x52, 0x4d, 0x78, 0x28, 0x16, 0xee, 0xee, 0x25, 0xec, 0xb4,
- 0x89, 0xb0, 0xd3, 0xb2, 0x98, 0x8c, 0x8b, 0x2d, 0x9f, 0x58, 0x58, 0x88,
- 0xe4, 0xfd, 0x71, 0x75, 0x62, 0xa2, 0x92, 0x6f, 0x73, 0x19, 0x70, 0xdd,
- 0x8e, 0xda, 0x1a, 0x4d, 0x3d, 0x91, 0x44, 0x78, 0x7f, 0x5c, 0x82, 0xe9,
- 0x36, 0x5c, 0xb8, 0xcf, 0xae, 0x15, 0xd7, 0x63, 0x74, 0x54, 0x60, 0x5b,
- 0x6b, 0xf2, 0x8f, 0x5c, 0x24, 0xab, 0xb7, 0xdb, 0x11, 0x20, 0xf5, 0x0a,
- 0x99, 0xea, 0xfa, 0x4e, 0x92, 0x5e, 0x07, 0xe5, 0xdc, 0x27, 0xb2, 0xab,
- 0xd0, 0xd0, 0x2a, 0x93, 0x0e, 0x9d, 0xb8, 0xb3, 0x78, 0x13, 0xe9, 0x31,
- 0x72, 0xe4, 0x79, 0x78, 0xfd, 0x2f, 0x8c, 0x19, 0x18, 0xca, 0xe2, 0x7b,
- 0x3e, 0xaa, 0xe1, 0xee, 0x25, 0xfc, 0xf4, 0x03, 0xa2, 0x61, 0x63, 0x6b,
- 0xa4, 0x93, 0x6a, 0x79, 0xc5, 0x6b, 0xb8, 0x31, 0xd2, 0xe4, 0x87, 0xa2,
- 0xa5, 0xc4, 0x2b, 0xf9, 0xc8, 0x91, 0x1d, 0xd2, 0xb7, 0xc4, 0xcf, 0xa7,
- 0x0d, 0x3c, 0x5a, 0xea, 0x11, 0x7f, 0x31, 0x2d, 0x83, 0x74, 0x43, 0x71,
- 0x4b, 0xc7, 0x11, 0xa2, 0xcb, 0x45, 0x18, 0xc9, 0xf5, 0xfb, 0x02, 0x8b,
- 0xb5, 0x24, 0xbe, 0xb3, 0x8a, 0x7d, 0xa1, 0x12, 0xd3, 0x9c, 0xab, 0x80,
- 0xfd, 0x64, 0x93, 0x0d, 0x99, 0x0e, 0xb1, 0x84, 0xbe, 0x5f, 0xa4, 0xbc,
- 0x96, 0x94, 0x3a, 0x45, 0x03, 0x61, 0xd3, 0x85, 0x93, 0x5b, 0xc4, 0x82,
- 0x22, 0x63, 0x51, 0x28, 0x0b, 0x49, 0x46, 0x0b, 0x8b, 0x17, 0x1d, 0x95,
- 0x1a, 0xc0, 0xc5, 0xb6, 0x64, 0xfa, 0x0c, 0xd9, 0x7f, 0x88, 0x62, 0xfb,
- 0x8e, 0x58, 0x27, 0xe1, 0x64, 0xbe, 0x3e, 0x20, 0x86, 0x48, 0x8e, 0x13,
- 0x2e, 0xdb, 0x76, 0xfc, 0x4f, 0x8c, 0xc1, 0xd5, 0x60, 0x20, 0xe4, 0xa6,
- 0xdc, 0xf1, 0xdf, 0xdb, 0x22, 0xe6, 0xf3, 0x52, 0x97, 0xc8, 0xe5, 0x03,
- 0xfe, 0x23, 0x63, 0x9c, 0x67, 0x3a, 0xc4, 0x11, 0xd2, 0x79, 0x96, 0x74,
- 0x9e, 0x25, 0x9d, 0x67, 0x48, 0xe7, 0x99, 0x2f, 0xd1, 0xf9, 0x3e, 0xd2,
- 0xf9, 0xee, 0xfc, 0xaf, 0x6c, 0x1d, 0x3a, 0x0d, 0x03, 0x59, 0xca, 0xcb,
- 0x23, 0x4d, 0x15, 0xfe, 0x3e, 0x24, 0x59, 0xbc, 0x14, 0xfb, 0x86, 0x13,
- 0x5e, 0x83, 0x62, 0x6b, 0x17, 0x3d, 0xf3, 0x95, 0x39, 0x1b, 0x57, 0xfc,
- 0xc3, 0x63, 0x1d, 0x62, 0x98, 0xfc, 0x6e, 0x84, 0xe6, 0x1f, 0x21, 0xbf,
- 0x1b, 0x4c, 0xff, 0x9f, 0xd8, 0x0d, 0xdb, 0x1d, 0x4c, 0x2f, 0xe5, 0xad,
- 0x6a, 0xb2, 0x4b, 0xa7, 0xc1, 0x36, 0xb4, 0x59, 0x24, 0x8f, 0x7e, 0x4b,
- 0x24, 0x8f, 0xa5, 0x44, 0xb2, 0xd0, 0x43, 0x9f, 0x5b, 0xc4, 0x2d, 0x76,
- 0x1d, 0x3a, 0x20, 0x3a, 0x0a, 0x01, 0xff, 0x38, 0xad, 0x33, 0x4e, 0x7c,
- 0x3c, 0x46, 0xeb, 0x3c, 0x66, 0xdb, 0x2e, 0x15, 0x99, 0x5e, 0x5e, 0x8b,
- 0xed, 0x8c, 0xed, 0xeb, 0x32, 0xd1, 0xce, 0xbe, 0x71, 0xb5, 0xc7, 0x43,
- 0x7f, 0x37, 0x38, 0xa0, 0xed, 0x74, 0x56, 0x78, 0xe2, 0xdc, 0xcf, 0xb9,
- 0x9e, 0xe3, 0xb0, 0x62, 0xd7, 0x82, 0xcf, 0x5e, 0xc5, 0x00, 0x8c, 0x07,
- 0x20, 0x2f, 0x30, 0xb6, 0x18, 0xdf, 0x69, 0xfa, 0x1f, 0x34, 0x5f, 0x3f,
- 0xf4, 0x55, 0x90, 0x03, 0xc6, 0x5f, 0x1a, 0x63, 0x4d, 0x14, 0xa7, 0x69,
- 0x4e, 0x39, 0x03, 0x68, 0x19, 0x81, 0xdd, 0x09, 0x41, 0x38, 0x76, 0x11,
- 0xf9, 0x25, 0xd3, 0xaf, 0x76, 0x52, 0x36, 0xc1, 0xd2, 0x21, 0xc8, 0x4b,
- 0x8c, 0x9d, 0xb0, 0xb2, 0x90, 0x6b, 0x8d, 0x3e, 0x5c, 0x19, 0x0a, 0x07,
- 0x3b, 0xa1, 0xa6, 0x2e, 0x38, 0xd4, 0x32, 0xe5, 0xb7, 0xfe, 0xdd, 0x42,
- 0xed, 0x9b, 0x15, 0xdc, 0x27, 0x62, 0xec, 0xbe, 0x13, 0x2d, 0x36, 0x86,
- 0xef, 0x43, 0x73, 0x1e, 0x54, 0x87, 0x0b, 0xbc, 0x43, 0x73, 0xbe, 0xa8,
- 0x7f, 0xc0, 0x39, 0x21, 0x49, 0x58, 0xf0, 0x0b, 0x73, 0x81, 0x70, 0x0c,
- 0xcf, 0xc3, 0x73, 0x84, 0x95, 0x3e, 0x9a, 0xf7, 0x4d, 0x47, 0x73, 0xff,
- 0xa0, 0x50, 0x13, 0x5f, 0x9c, 0x6f, 0x59, 0x1e, 0x62, 0x59, 0xc6, 0xb4,
- 0xaa, 0x35, 0x2f, 0xe3, 0x21, 0xe9, 0x1d, 0x4d, 0x4b, 0xbe, 0x86, 0x10,
- 0x96, 0x51, 0x9d, 0x1c, 0x2d, 0x32, 0x0f, 0xbb, 0x70, 0x46, 0x57, 0xbb,
- 0xa9, 0x1a, 0xa5, 0xba, 0xa5, 0x03, 0x07, 0x29, 0xf6, 0x3e, 0x5a, 0xe2,
- 0x3e, 0xd7, 0x80, 0x58, 0x3e, 0x44, 0x7e, 0x69, 0xdb, 0x13, 0xe4, 0x06,
- 0xe3, 0x61, 0xdc, 0x40, 0xeb, 0xfb, 0xa9, 0xf6, 0x79, 0x9d, 0xd6, 0x97,
- 0x32, 0xea, 0x00, 0xad, 0x9f, 0x7a, 0x43, 0x84, 0x67, 0x89, 0xaf, 0x9e,
- 0x75, 0x8e, 0xe6, 0xbe, 0x5d, 0x42, 0x4d, 0x12, 0xe9, 0xe4, 0xc7, 0xbc,
- 0xf6, 0xc3, 0xcc, 0x0b, 0x7d, 0x52, 0x9d, 0x43, 0x76, 0xd4, 0x54, 0x90,
- 0x45, 0x64, 0x78, 0x3d, 0xf6, 0x4e, 0xad, 0xc7, 0x1e, 0xf2, 0xc7, 0x03,
- 0x7a, 0x2d, 0x42, 0x75, 0xa8, 0xa9, 0xd5, 0x30, 0x7b, 0x41, 0x13, 0x8e,
- 0x1d, 0x2d, 0x8d, 0x64, 0xc7, 0xa7, 0x1b, 0xaa, 0xf0, 0x91, 0xd5, 0xab,
- 0xad, 0xef, 0xa4, 0x88, 0x78, 0x83, 0x07, 0xe3, 0x0e, 0xf2, 0xef, 0x5f,
- 0xfc, 0x9a, 0x02, 0xaa, 0xc7, 0x60, 0xdc, 0x96, 0x10, 0x97, 0xf2, 0x67,
- 0x9d, 0x15, 0x3f, 0x68, 0xc2, 0x15, 0x05, 0xb5, 0x41, 0x6d, 0x39, 0x66,
- 0x15, 0x99, 0xe2, 0x85, 0x69, 0xd7, 0x64, 0x37, 0xe7, 0xba, 0xd1, 0x40,
- 0xf5, 0xf1, 0x9d, 0xb1, 0x5f, 0x5b, 0x9f, 0x2c, 0xe6, 0xe7, 0x4e, 0x7a,
- 0x2a, 0xb1, 0xf3, 0xcb, 0xe6, 0x88, 0x53, 0xbc, 0x69, 0xa6, 0x7a, 0xb6,
- 0x9a, 0x82, 0x74, 0x27, 0xe5, 0x23, 0xb5, 0x27, 0x4d, 0xf5, 0x68, 0x5f,
- 0xa4, 0x59, 0x77, 0x08, 0x37, 0xca, 0x81, 0x70, 0x7f, 0x2f, 0x92, 0xdb,
- 0xfd, 0x73, 0x74, 0x3c, 0x2b, 0x34, 0x17, 0x3d, 0xc7, 0xf3, 0x5c, 0x63,
- 0x4f, 0x27, 0xc9, 0x9e, 0xf8, 0x3e, 0x7f, 0xbf, 0x7a, 0x5f, 0xfe, 0x8a,
- 0xf1, 0x97, 0xff, 0xe4, 0x8f, 0x97, 0x7d, 0xd9, 0xf5, 0x8f, 0xbf, 0xe4,
- 0xfa, 0xff, 0xae, 0xae, 0x2f, 0xd7, 0x39, 0x6d, 0xcc, 0x90, 0x94, 0xb8,
- 0x8f, 0xe9, 0x34, 0x2e, 0xaf, 0xd9, 0xa3, 0xfd, 0x0e, 0xc5, 0x34, 0xee,
- 0x63, 0x70, 0x9e, 0x3e, 0x6f, 0xf7, 0x31, 0x4e, 0x7d, 0x0e, 0xb3, 0x72,
- 0x6c, 0xf1, 0x88, 0xea, 0x11, 0xd3, 0xaa, 0xd7, 0xbe, 0x4d, 0x75, 0xcd,
- 0x2e, 0xf4, 0xc6, 0x74, 0x0c, 0x67, 0xd5, 0xee, 0xdb, 0xa0, 0x25, 0x37,
- 0x0b, 0x9a, 0xa8, 0xe8, 0x11, 0x8e, 0x91, 0xb9, 0x7b, 0xba, 0x49, 0xb5,
- 0x5a, 0x19, 0x55, 0x14, 0x9b, 0x9c, 0x9a, 0x22, 0xa3, 0x18, 0x90, 0x9d,
- 0xc5, 0xa0, 0xec, 0x2e, 0x36, 0xca, 0x55, 0x34, 0xce, 0x37, 0xa2, 0xce,
- 0xde, 0x86, 0x5d, 0x98, 0x6d, 0xf3, 0x9a, 0x0d, 0x86, 0xaa, 0x34, 0x38,
- 0x76, 0x61, 0x4f, 0x8c, 0x9f, 0xed, 0xa0, 0x9a, 0x0d, 0xa2, 0x2e, 0x43,
- 0xc8, 0xd8, 0x10, 0xd8, 0xdb, 0xae, 0x0e, 0x2c, 0x95, 0xb4, 0xce, 0x5f,
- 0x09, 0xa7, 0xec, 0x29, 0x42, 0xf8, 0x33, 0x12, 0x8e, 0xb4, 0xc3, 0xe3,
- 0x59, 0xa5, 0xf6, 0x9d, 0x16, 0x03, 0x78, 0x2a, 0x16, 0xe9, 0xde, 0x26,
- 0x42, 0xb2, 0x97, 0xee, 0xb9, 0x32, 0x14, 0x7f, 0x33, 0xa6, 0xc7, 0xb5,
- 0x4a, 0x0d, 0x4a, 0x22, 0x89, 0x5e, 0x4d, 0xd3, 0x47, 0x20, 0xd3, 0x9a,
- 0x10, 0x55, 0x19, 0x75, 0xf6, 0x4d, 0xc2, 0x54, 0x9f, 0x2c, 0x1b, 0x40,
- 0x6b, 0x5b, 0x64, 0x7f, 0x8f, 0xa4, 0xc9, 0x84, 0xf5, 0x84, 0x33, 0xe3,
- 0xc3, 0xca, 0xc3, 0xf3, 0x7d, 0x1d, 0xcb, 0xfa, 0x30, 0x56, 0x26, 0xbd,
- 0x40, 0xae, 0x29, 0x46, 0x65, 0x1f, 0xe1, 0xfa, 0xe6, 0xc3, 0x8c, 0xb3,
- 0x2c, 0x6b, 0x47, 0xac, 0xfc, 0x75, 0x2f, 0x5a, 0x88, 0xc7, 0x6e, 0x4c,
- 0xa5, 0x19, 0x77, 0x19, 0x98, 0xa4, 0x9a, 0x48, 0x1b, 0x6a, 0xc4, 0x71,
- 0x8a, 0x43, 0x33, 0x69, 0xee, 0xff, 0xf4, 0x91, 0x8c, 0x7b, 0x88, 0xfe,
- 0x2d, 0x54, 0x0f, 0xa7, 0x28, 0x7e, 0xb1, 0x8c, 0x7b, 0xc9, 0xee, 0x21,
- 0x7b, 0x8d, 0x3a, 0xe3, 0xe6, 0x61, 0xc8, 0x1e, 0xc3, 0x6b, 0x5c, 0x77,
- 0x18, 0x75, 0x94, 0xf7, 0x0d, 0xaa, 0x78, 0x10, 0x8d, 0x44, 0xf4, 0x8b,
- 0x88, 0x04, 0x5f, 0x24, 0x7d, 0x0c, 0x6a, 0xc0, 0x6e, 0xbb, 0xd6, 0x76,
- 0xc2, 0xcc, 0x73, 0x0d, 0x0d, 0x4f, 0x55, 0x7b, 0x1d, 0xde, 0xc9, 0x45,
- 0xed, 0x1e, 0x92, 0x49, 0xf5, 0xcf, 0x0b, 0xba, 0x9a, 0x9a, 0xa0, 0xe7,
- 0xb6, 0x2a, 0xff, 0x65, 0x5f, 0x75, 0x1c, 0x32, 0xc5, 0x34, 0xb2, 0xbd,
- 0x3f, 0xf5, 0xbe, 0x49, 0x36, 0x7a, 0xfb, 0xd8, 0x9f, 0x79, 0xaf, 0xc4,
- 0x27, 0xbc, 0x1f, 0xc4, 0x2d, 0x2b, 0x41, 0x78, 0xb4, 0x87, 0xea, 0xed,
- 0x0f, 0x87, 0x4c, 0xef, 0xc5, 0x38, 0xf7, 0x81, 0x9d, 0xf8, 0x3d, 0xfa,
- 0xfd, 0xe4, 0x90, 0x8c, 0x4d, 0x85, 0x06, 0xb8, 0x86, 0x1d, 0x98, 0xd2,
- 0x6f, 0x44, 0xaf, 0x22, 0xe1, 0xee, 0xe8, 0x49, 0xb2, 0x49, 0x89, 0xc6,
- 0x1c, 0xa2, 0xdf, 0xdc, 0xd3, 0x7a, 0x0c, 0xdb, 0x94, 0x69, 0xef, 0x3b,
- 0x71, 0xa6, 0x17, 0x4c, 0xaf, 0x2c, 0x69, 0xb7, 0x62, 0xeb, 0x6d, 0x5c,
- 0x5b, 0xd9, 0xff, 0x9e, 0x17, 0xdb, 0xeb, 0x71, 0x3c, 0xd7, 0x80, 0xe7,
- 0x73, 0xa6, 0xe7, 0xb5, 0xf6, 0x28, 0xfa, 0x86, 0x2c, 0xbc, 0xac, 0x9b,
- 0x03, 0x55, 0x64, 0xe7, 0x09, 0xaa, 0xaf, 0xc2, 0x6d, 0xdc, 0x4b, 0x40,
- 0xc4, 0x81, 0x48, 0x3f, 0x81, 0xcc, 0x3b, 0x28, 0x74, 0xa5, 0x6a, 0xa8,
- 0x4e, 0x3b, 0x27, 0x2c, 0xf7, 0xf6, 0x76, 0x27, 0xd1, 0x00, 0x6c, 0x28,
- 0xb4, 0x90, 0xdc, 0xa2, 0xd8, 0x14, 0x91, 0xb1, 0xb1, 0xa0, 0xe3, 0xf9,
- 0xb4, 0x0f, 0xb7, 0x17, 0xe2, 0x84, 0xbd, 0x15, 0xa2, 0x3d, 0x81, 0x52,
- 0x3a, 0x80, 0x6f, 0x14, 0x1a, 0x49, 0xde, 0x41, 0xdc, 0x58, 0x08, 0xe1,
- 0x44, 0x9a, 0xf3, 0xb7, 0xe1, 0xd9, 0x1a, 0x6f, 0x44, 0x67, 0x41, 0xc3,
- 0x74, 0x1a, 0x9e, 0x07, 0xe2, 0x21, 0x74, 0x14, 0xa2, 0x28, 0x10, 0x86,
- 0xbb, 0x95, 0xe6, 0xbc, 0x9d, 0x74, 0xd2, 0x52, 0x08, 0x60, 0x69, 0x84,
- 0x22, 0x72, 0xc1, 0x27, 0x06, 0x08, 0x5b, 0x25, 0x0a, 0xf5, 0xb8, 0x38,
- 0xcc, 0x76, 0xae, 0x18, 0x7b, 0x72, 0x0a, 0x42, 0x05, 0xac, 0x94, 0x01,
- 0x0a, 0xd6, 0x91, 0x54, 0x81, 0xe8, 0x3d, 0xd8, 0x5e, 0xe9, 0xe1, 0x2e,
- 0x2f, 0x7c, 0xc6, 0x6f, 0x2d, 0xe9, 0xe9, 0xca, 0xe1, 0x69, 0xef, 0x27,
- 0x71, 0x8e, 0x4d, 0x9f, 0xae, 0x79, 0xfd, 0x30, 0x10, 0x1d, 0x67, 0xde,
- 0xec, 0xd8, 0xc8, 0xf1, 0xb0, 0x45, 0xc6, 0xaf, 0x2c, 0xaa, 0x41, 0x43,
- 0x53, 0xbc, 0x57, 0xa0, 0xf9, 0x88, 0x0e, 0x05, 0x49, 0x5a, 0xfb, 0x96,
- 0xc2, 0x0f, 0xad, 0xad, 0x0b, 0x83, 0xb8, 0x39, 0x52, 0x91, 0xd5, 0x39,
- 0xd2, 0xe1, 0xe4, 0x70, 0x03, 0x66, 0x88, 0x06, 0x97, 0xe1, 0x36, 0x8e,
- 0x8d, 0x59, 0xd8, 0xa0, 0x9b, 0xde, 0xd7, 0xda, 0x97, 0xe3, 0xfe, 0xc3,
- 0x83, 0x67, 0xdd, 0xa4, 0xd7, 0x59, 0xfd, 0x0e, 0x3c, 0x3a, 0x8e, 0xaf,
- 0x35, 0x00, 0x8f, 0x04, 0xc1, 0x3d, 0x6b, 0x35, 0x74, 0x02, 0x91, 0xce,
- 0x07, 0x10, 0x51, 0x34, 0xa1, 0xea, 0x2f, 0x0b, 0x24, 0xab, 0x8d, 0xc8,
- 0xd9, 0x5b, 0x80, 0x33, 0x6e, 0xf2, 0xe0, 0xdb, 0x0b, 0x4e, 0x92, 0x51,
- 0x10, 0xa5, 0x61, 0x37, 0x1c, 0xe4, 0x27, 0x97, 0x34, 0x6c, 0xa8, 0x25,
- 0x59, 0x3b, 0x84, 0x4c, 0x7a, 0x6e, 0xc1, 0xb1, 0xa1, 0x79, 0x59, 0xf9,
- 0x70, 0x13, 0xc9, 0xf0, 0xa9, 0x21, 0x6b, 0x97, 0x16, 0x0b, 0x90, 0xac,
- 0x15, 0xa2, 0x6f, 0x5e, 0x4e, 0x2c, 0xbf, 0x79, 0x39, 0xdd, 0x81, 0x3d,
- 0x33, 0x2c, 0xb7, 0xff, 0x1b, 0x79, 0x4d, 0xdb, 0x76, 0xb7, 0x61, 0x2c,
- 0x8a, 0x86, 0xc3, 0x57, 0x65, 0xc7, 0xf4, 0x3d, 0x42, 0x7c, 0x7c, 0xcf,
- 0xbf, 0x3a, 0xd2, 0xf7, 0xbe, 0xf0, 0x11, 0x3d, 0x0a, 0xe9, 0xe6, 0x03,
- 0x17, 0x63, 0x77, 0x92, 0xc9, 0x55, 0x19, 0x07, 0x49, 0xc6, 0xc1, 0x71,
- 0x96, 0xf5, 0xa7, 0x6b, 0xae, 0x90, 0x7c, 0x5f, 0x27, 0x5c, 0x76, 0x43,
- 0x2c, 0x8a, 0x9a, 0xc3, 0x6a, 0xb2, 0xc1, 0x11, 0x4e, 0xd4, 0x0a, 0x50,
- 0x55, 0x82, 0x96, 0x1a, 0x7c, 0xc8, 0x72, 0xd6, 0x49, 0xce, 0xdf, 0x1b,
- 0x24, 0x7e, 0xd6, 0xd3, 0x7c, 0x1b, 0x48, 0xce, 0x49, 0xe2, 0xff, 0x16,
- 0x7b, 0xde, 0x46, 0x9a, 0x77, 0x0b, 0xd5, 0x1e, 0xd3, 0xde, 0x4b, 0x44,
- 0x4f, 0xf4, 0x33, 0x5a, 0x08, 0x8d, 0x47, 0x82, 0xef, 0x53, 0x8d, 0x7d,
- 0xa3, 0x3d, 0x4e, 0xa1, 0x71, 0x4c, 0xfb, 0xcf, 0xab, 0x24, 0xed, 0xcb,
- 0xfa, 0xcd, 0xdf, 0x02, 0xf7, 0x1c, 0x4c, 0xf4, 0x50, 0x1d, 0xb1, 0x85,
- 0x6a, 0x25, 0x99, 0x72, 0x9b, 0x89, 0x1f, 0xc4, 0xd5, 0x68, 0x9d, 0xe0,
- 0xf8, 0x67, 0x92, 0x1f, 0x96, 0xa9, 0x4e, 0x0a, 0x87, 0x66, 0x10, 0x94,
- 0xa5, 0xa2, 0x4c, 0x78, 0xb0, 0x51, 0x76, 0x14, 0xc9, 0x5f, 0x83, 0x3d,
- 0x84, 0xa7, 0x9d, 0x78, 0x31, 0xef, 0xc4, 0x2b, 0xe9, 0x2d, 0x38, 0x50,
- 0xf2, 0x10, 0x6e, 0x36, 0x3d, 0xce, 0x55, 0x13, 0xee, 0x4a, 0x4c, 0x5e,
- 0x86, 0xae, 0x91, 0x87, 0x51, 0x9d, 0x71, 0x76, 0x53, 0x3e, 0xd5, 0x6f,
- 0x21, 0xb9, 0x6c, 0x28, 0xf2, 0xfd, 0x46, 0x64, 0xd2, 0x29, 0xc2, 0x40,
- 0x61, 0xaa, 0x81, 0x9c, 0x98, 0x68, 0x68, 0xb4, 0xfb, 0xba, 0x39, 0xba,
- 0x96, 0x2b, 0x7d, 0xb1, 0xdf, 0x7c, 0xc7, 0x5c, 0x9f, 0xb9, 0x0f, 0xfb,
- 0xb2, 0x3d, 0x84, 0x4d, 0xb7, 0x50, 0x7c, 0xaf, 0xd0, 0x38, 0x1d, 0xef,
- 0xc6, 0xbe, 0xbc, 0x71, 0x35, 0x7e, 0x4c, 0xda, 0xf1, 0xa3, 0x1f, 0x55,
- 0xed, 0xbc, 0x7f, 0xb5, 0x05, 0x77, 0xa5, 0x81, 0xf7, 0xd2, 0xdc, 0x4f,
- 0x24, 0x4c, 0x41, 0xf9, 0xe0, 0x90, 0xce, 0x39, 0x74, 0x0b, 0x96, 0xe6,
- 0x2d, 0xe4, 0x75, 0x0b, 0x67, 0x75, 0x8d, 0x72, 0x34, 0xe7, 0xea, 0x01,
- 0xa1, 0x51, 0x7e, 0x36, 0x9d, 0xfd, 0x88, 0xb4, 0xb3, 0x8e, 0x1e, 0x9e,
- 0xdb, 0x87, 0xea, 0xb7, 0xf7, 0xa1, 0x66, 0xd2, 0x0e, 0x3c, 0x45, 0x8a,
- 0x78, 0x3e, 0x1b, 0x0e, 0xbd, 0x07, 0x6b, 0x97, 0xc3, 0x50, 0x13, 0x4e,
- 0x07, 0xef, 0xcf, 0xf0, 0xfe, 0x94, 0xd6, 0xbd, 0xd4, 0xa1, 0xea, 0x45,
- 0xd1, 0xdc, 0xf3, 0x16, 0xca, 0x1b, 0x65, 0xa8, 0xa1, 0xd7, 0x10, 0x89,
- 0x76, 0xf2, 0x1e, 0x44, 0xa9, 0x92, 0xbb, 0x97, 0xcd, 0xe5, 0x6e, 0x2d,
- 0xef, 0x15, 0xe1, 0x61, 0x09, 0x13, 0x53, 0x96, 0x29, 0x91, 0xfd, 0x4e,
- 0xd1, 0x9c, 0x3f, 0xce, 0xee, 0x42, 0x36, 0x66, 0x59, 0xb7, 0xc7, 0xb5,
- 0xbe, 0x06, 0x07, 0xfe, 0x90, 0x32, 0x39, 0xc8, 0xe6, 0x53, 0xe4, 0x6b,
- 0xa1, 0x1d, 0xed, 0xa6, 0xe5, 0xb6, 0xeb, 0x0a, 0xee, 0x4f, 0x76, 0x89,
- 0x96, 0xc2, 0x16, 0xb1, 0x9c, 0xb0, 0x5b, 0xe8, 0xd8, 0x66, 0xd1, 0x74,
- 0xb4, 0x82, 0xdd, 0x22, 0x85, 0xcf, 0x7a, 0xa8, 0x37, 0xa7, 0x2d, 0xa4,
- 0x89, 0xaf, 0xa7, 0xfe, 0x0e, 0x5f, 0xac, 0x8b, 0x7e, 0x5c, 0xd7, 0xce,
- 0xbe, 0xf8, 0x30, 0x8e, 0xa5, 0xd9, 0xce, 0xfb, 0xb1, 0x87, 0xe4, 0xb3,
- 0x62, 0x88, 0xf7, 0xc3, 0xd4, 0xb3, 0x83, 0x08, 0xf7, 0xbd, 0x2a, 0xd4,
- 0x72, 0x01, 0xcd, 0x7a, 0x8d, 0x83, 0xe3, 0xab, 0x3a, 0xd0, 0xe4, 0xa8,
- 0xd0, 0x9f, 0xc8, 0x83, 0xe2, 0x69, 0x85, 0x87, 0x95, 0xf9, 0xa5, 0x64,
- 0xab, 0xa6, 0xe7, 0x52, 0xbc, 0xb9, 0xbf, 0x1a, 0x1b, 0xc4, 0x07, 0xd3,
- 0x21, 0x78, 0x0f, 0x27, 0x17, 0xfa, 0xd1, 0x21, 0xde, 0xb3, 0xeb, 0xc5,
- 0x4e, 0xf1, 0x4e, 0xbe, 0x5b, 0x5c, 0x9e, 0xe8, 0x42, 0x64, 0xf8, 0x3e,
- 0xf1, 0xf6, 0x04, 0xd3, 0xd9, 0x23, 0xce, 0x4f, 0x73, 0x9f, 0xd4, 0xc2,
- 0x1e, 0x9d, 0xfb, 0xa2, 0x8b, 0xab, 0xe0, 0xb7, 0x70, 0x4c, 0x67, 0x7d,
- 0x72, 0x9f, 0xb0, 0xd2, 0x5f, 0xda, 0x10, 0xcf, 0x59, 0x4e, 0x8d, 0x7b,
- 0xc5, 0x41, 0x9b, 0xdf, 0x29, 0xc2, 0xd1, 0xd3, 0x13, 0x5b, 0xc4, 0xf1,
- 0x7c, 0x85, 0xd7, 0xc9, 0x3c, 0xdb, 0xaf, 0x4c, 0x3a, 0xfe, 0x62, 0x9e,
- 0x36, 0xa1, 0xb4, 0x07, 0xe1, 0xb6, 0xfb, 0x51, 0x16, 0x46, 0xf4, 0x48,
- 0xe8, 0x65, 0x04, 0xe1, 0x2c, 0xb2, 0x6d, 0x5b, 0x78, 0x5a, 0x77, 0xc1,
- 0x31, 0x22, 0x93, 0x8c, 0xc8, 0x96, 0xfc, 0x2e, 0x48, 0x93, 0x5c, 0x1b,
- 0x7c, 0xbd, 0x8a, 0xfb, 0x14, 0x21, 0x89, 0xbf, 0x7f, 0xd1, 0xe6, 0x5c,
- 0x94, 0x0f, 0xb8, 0xbf, 0xfe, 0x57, 0xee, 0x8a, 0xed, 0xb1, 0x5d, 0xcd,
- 0xf7, 0xc4, 0x29, 0xd7, 0xb6, 0x73, 0x2f, 0xdc, 0x83, 0x99, 0x9c, 0x9b,
- 0x5b, 0x14, 0x1e, 0x77, 0xbb, 0x85, 0x0b, 0xba, 0x93, 0xea, 0x97, 0x87,
- 0x28, 0x47, 0x49, 0x90, 0xb5, 0x3b, 0x50, 0x1c, 0x73, 0x4a, 0xbc, 0x5f,
- 0xf5, 0xb3, 0x18, 0xf7, 0x10, 0x80, 0x43, 0xc4, 0xc3, 0xf7, 0x73, 0x21,
- 0x6c, 0xa2, 0xba, 0x2b, 0x64, 0xd7, 0x18, 0xbf, 0x87, 0x53, 0x39, 0x87,
- 0xa0, 0xba, 0xc2, 0x91, 0x58, 0x6d, 0xe1, 0x4a, 0x5b, 0x24, 0xca, 0x7d,
- 0x68, 0x85, 0x72, 0xd6, 0xde, 0x7c, 0x1d, 0x7e, 0x96, 0xab, 0xc3, 0x2b,
- 0x39, 0x0b, 0x07, 0x63, 0x83, 0x3d, 0x5e, 0x8a, 0x95, 0xcb, 0x62, 0x2e,
- 0xec, 0x88, 0x98, 0x8a, 0x17, 0x51, 0x5c, 0x48, 0x5c, 0x87, 0x54, 0x20,
- 0xdc, 0x39, 0x88, 0x7a, 0xbc, 0x91, 0x03, 0x61, 0x09, 0x78, 0x96, 0xd2,
- 0x1c, 0x6f, 0xc7, 0xcc, 0x7e, 0x17, 0xe1, 0xd8, 0x9f, 0x0b, 0xc4, 0x6b,
- 0x60, 0xb9, 0xcf, 0xc4, 0x29, 0x57, 0x17, 0xea, 0xd0, 0x95, 0xab, 0x47,
- 0x0f, 0xe5, 0xac, 0x75, 0xab, 0xe3, 0x78, 0x2b, 0xeb, 0x13, 0x2b, 0xb3,
- 0x83, 0x3d, 0x0a, 0xcd, 0xe9, 0x6a, 0x53, 0xfb, 0x9f, 0x22, 0xe0, 0x26,
- 0x23, 0x4c, 0xe6, 0x8e, 0x07, 0xfc, 0x14, 0x77, 0x8f, 0x8b, 0x4f, 0xf1,
- 0x04, 0xd9, 0xe3, 0x3d, 0xba, 0x5a, 0xbe, 0xe4, 0x88, 0x9c, 0xdd, 0x08,
- 0x75, 0xe0, 0x16, 0x61, 0x46, 0x6b, 0x29, 0x9e, 0x34, 0x54, 0x62, 0x85,
- 0x19, 0x11, 0x32, 0x61, 0x73, 0x27, 0x3c, 0x9a, 0x89, 0xce, 0x76, 0x96,
- 0xa9, 0x07, 0x9e, 0xa3, 0x64, 0x47, 0xd2, 0x17, 0xfb, 0xfb, 0x75, 0x78,
- 0x9d, 0xf2, 0xe5, 0xb9, 0x1c, 0xf7, 0xe6, 0xdd, 0xc6, 0xbb, 0x94, 0x03,
- 0x5e, 0x8a, 0x0d, 0x86, 0x38, 0xf6, 0xe7, 0x63, 0xf8, 0xe7, 0x64, 0x96,
- 0x8d, 0x3e, 0x5a, 0xf3, 0x2e, 0xc1, 0xeb, 0x20, 0xb9, 0xc4, 0xe0, 0xbe,
- 0x9c, 0xcd, 0x0f, 0xc5, 0x63, 0xe6, 0xe9, 0xff, 0x27, 0xed, 0x8f, 0x54,
- 0xc1, 0x5b, 0x4f, 0xba, 0x9c, 0xef, 0x69, 0x5e, 0xdb, 0xcf, 0xe4, 0x7a,
- 0xa6, 0x82, 0x0f, 0xdd, 0x46, 0xb5, 0x78, 0x21, 0xc7, 0x36, 0x67, 0xe1,
- 0x19, 0x5d, 0xa7, 0xda, 0x85, 0x6b, 0xf2, 0x7e, 0xaa, 0x5f, 0xb8, 0xcf,
- 0x64, 0x7a, 0xce, 0x10, 0x85, 0xfb, 0x73, 0x58, 0x2b, 0xc3, 0xb1, 0xa2,
- 0x0a, 0xe3, 0x98, 0x70, 0x3a, 0x09, 0x73, 0x70, 0xac, 0x65, 0x7f, 0x52,
- 0x0c, 0x6d, 0x82, 0xeb, 0xcf, 0x4e, 0x98, 0xb6, 0x1f, 0x57, 0x8b, 0xfb,
- 0xc9, 0x46, 0x5e, 0x8c, 0x55, 0x61, 0x82, 0xea, 0x1f, 0xc9, 0x30, 0x3d,
- 0xdf, 0xa5, 0xe7, 0x13, 0xa3, 0xd8, 0x17, 0x84, 0xe3, 0x4f, 0x14, 0xfc,
- 0x19, 0xde, 0x74, 0xc9, 0x74, 0x1d, 0x9e, 0xee, 0xb8, 0xe9, 0xdd, 0x18,
- 0xaf, 0x16, 0xb7, 0xe6, 0x5a, 0xf0, 0xfe, 0x58, 0x1d, 0xd9, 0x77, 0x3d,
- 0x96, 0x8c, 0x04, 0xf1, 0x36, 0xd1, 0x32, 0x40, 0xb4, 0x7c, 0xd2, 0x66,
- 0x0e, 0x34, 0x40, 0xed, 0xa7, 0xba, 0xa8, 0x9b, 0xfb, 0xcd, 0x4f, 0xeb,
- 0x6a, 0xe7, 0x6d, 0xc2, 0x0b, 0x2d, 0x92, 0x24, 0xd9, 0x5b, 0xd6, 0xb0,
- 0xde, 0xac, 0xfb, 0xc0, 0xfd, 0xa3, 0x3b, 0x70, 0x68, 0x86, 0x69, 0x71,
- 0x1b, 0xcb, 0xa7, 0xf9, 0x53, 0x36, 0xae, 0xb3, 0x3f, 0xbd, 0x73, 0x9f,
- 0x30, 0x42, 0xf6, 0xe7, 0xa7, 0x6b, 0x42, 0xd3, 0xdc, 0xa7, 0x0e, 0x9b,
- 0x6e, 0xf1, 0x53, 0x17, 0xf7, 0xab, 0x93, 0xe0, 0xff, 0x57, 0x5d, 0x95,
- 0x7e, 0xdf, 0x1d, 0x30, 0xed, 0x1e, 0xca, 0x15, 0xbb, 0x97, 0x1d, 0x22,
- 0x37, 0x90, 0x89, 0x3f, 0x99, 0x30, 0x57, 0x20, 0x46, 0x05, 0x7c, 0xbd,
- 0x6c, 0x2e, 0x31, 0x7a, 0xa8, 0x46, 0x90, 0x89, 0x5f, 0x13, 0xfb, 0xda,
- 0x05, 0x0e, 0x69, 0x06, 0x5e, 0xcb, 0x73, 0x2c, 0x77, 0xe2, 0xfb, 0x69,
- 0x35, 0x94, 0x12, 0xe1, 0xce, 0x5b, 0x84, 0x84, 0x50, 0x43, 0x0f, 0x0e,
- 0x51, 0x5e, 0x99, 0x4e, 0x73, 0x1e, 0x71, 0xda, 0xe7, 0x05, 0x6a, 0x29,
- 0x0e, 0x7d, 0x38, 0x54, 0x89, 0xfb, 0x85, 0xb8, 0xba, 0xff, 0xf7, 0x48,
- 0xa7, 0x4f, 0x17, 0x78, 0x4e, 0x13, 0x9f, 0xac, 0x66, 0x1f, 0x56, 0xa3,
- 0x29, 0xe9, 0x5e, 0x84, 0xa6, 0x38, 0xb6, 0xd0, 0x72, 0xb4, 0xd6, 0x91,
- 0xac, 0x1b, 0xdd, 0xf1, 0x2e, 0xd1, 0x53, 0xfc, 0x67, 0xbc, 0x27, 0xa1,
- 0x2c, 0x30, 0x36, 0x8b, 0xf5, 0x93, 0xdc, 0x53, 0xdc, 0x22, 0xba, 0x8b,
- 0xdc, 0x57, 0x1c, 0x10, 0xbf, 0x5f, 0x64, 0x9f, 0x9f, 0xef, 0x2f, 0xce,
- 0xeb, 0x9f, 0xfb, 0x8a, 0xa6, 0xe7, 0x05, 0x92, 0xfd, 0x03, 0x39, 0x8e,
- 0xc9, 0x8e, 0xfb, 0xfd, 0x68, 0xc3, 0x84, 0x0b, 0x9e, 0xd3, 0xf1, 0xaf,
- 0xe0, 0x76, 0xc2, 0x07, 0x4b, 0xb4, 0x8a, 0xfe, 0xd6, 0x4d, 0x48, 0x48,
- 0xb4, 0x91, 0xd0, 0x17, 0xb0, 0x4e, 0x7b, 0x29, 0x9e, 0x65, 0xac, 0xbe,
- 0x00, 0xeb, 0x92, 0xed, 0xcd, 0x2e, 0xf7, 0x28, 0x0e, 0x9b, 0x94, 0x57,
- 0x3c, 0x98, 0xce, 0x2d, 0xa2, 0xda, 0xc0, 0xc2, 0x7e, 0xbd, 0x06, 0x55,
- 0x76, 0x0c, 0xf0, 0x10, 0x9e, 0x84, 0xec, 0xa3, 0x79, 0xd2, 0xc3, 0x32,
- 0xbc, 0x74, 0xef, 0x8c, 0x4e, 0x72, 0x69, 0xaf, 0xcc, 0xdd, 0x3c, 0xb1,
- 0x12, 0x07, 0xc9, 0xe3, 0x6b, 0xb4, 0x28, 0x86, 0x14, 0x1f, 0xc5, 0x9a,
- 0x3b, 0xe6, 0xe6, 0xf4, 0xd0, 0x60, 0x5e, 0xaf, 0xbf, 0xaa, 0xa2, 0x87,
- 0x35, 0x72, 0xa5, 0x06, 0x93, 0xcd, 0x6a, 0x5a, 0x6b, 0x47, 0xfb, 0x16,
- 0x74, 0x0e, 0xf9, 0xc4, 0x2b, 0xe9, 0xbb, 0xad, 0x50, 0x1d, 0x8d, 0x23,
- 0x9b, 0x75, 0xcf, 0xd1, 0xdb, 0x34, 0x21, 0xf3, 0x58, 0xee, 0x79, 0xe0,
- 0xc1, 0x9c, 0x84, 0xc0, 0xdc, 0xf5, 0xf8, 0x44, 0x08, 0x7a, 0x6b, 0x35,
- 0x50, 0x2f, 0xe8, 0x1a, 0xcf, 0xcd, 0x6b, 0xc8, 0xa8, 0x23, 0x3f, 0xb9,
- 0x33, 0x9e, 0xc0, 0xbb, 0x59, 0x27, 0x36, 0x52, 0x9e, 0xbf, 0x31, 0x6d,
- 0xe0, 0x42, 0x29, 0x60, 0xcf, 0x21, 0x19, 0xf3, 0xe3, 0x9c, 0x34, 0xce,
- 0x83, 0xc9, 0x89, 0x2f, 0xd2, 0x17, 0x20, 0x9a, 0x7f, 0x42, 0xdf, 0xf9,
- 0xde, 0x45, 0xbb, 0x3f, 0x70, 0xea, 0x9a, 0xba, 0x4a, 0x1a, 0xe1, 0x9e,
- 0x52, 0x25, 0x17, 0x74, 0xe8, 0xac, 0x4b, 0x3f, 0x66, 0x47, 0x4d, 0x5c,
- 0x58, 0x5d, 0x8b, 0x4f, 0x46, 0x9b, 0x70, 0x7f, 0xce, 0x8b, 0x4b, 0xa3,
- 0x16, 0x56, 0xb6, 0xe1, 0xee, 0x20, 0x61, 0xb1, 0x5a, 0xf2, 0xfb, 0xd7,
- 0xa8, 0xf6, 0xa1, 0x78, 0x4a, 0x94, 0x46, 0x12, 0x1b, 0xc8, 0xae, 0xa3,
- 0x31, 0xa4, 0x6e, 0x8a, 0x47, 0x42, 0x17, 0xf1, 0x3d, 0x8b, 0x62, 0xb1,
- 0xe2, 0x30, 0xba, 0x84, 0xd3, 0xde, 0x67, 0xdc, 0x62, 0xef, 0x4b, 0x4a,
- 0x93, 0x03, 0xc2, 0x51, 0xbc, 0xd6, 0xaf, 0xbf, 0x2c, 0x0f, 0x71, 0xee,
- 0xe1, 0x1e, 0xc6, 0x88, 0xe5, 0xd2, 0xb8, 0x57, 0xb3, 0x59, 0xec, 0x9d,
- 0xb8, 0x9a, 0x9b, 0xae, 0xe6, 0xa3, 0xdd, 0x73, 0x79, 0x68, 0x30, 0xff,
- 0x8b, 0x2f, 0xe0, 0xa8, 0xd0, 0xdc, 0x7e, 0x07, 0xe7, 0x1f, 0x8f, 0x78,
- 0x93, 0xcc, 0x61, 0x1f, 0xf9, 0xe0, 0x49, 0xfd, 0x74, 0x90, 0x32, 0x04,
- 0x9c, 0xad, 0x02, 0x0f, 0xf2, 0x59, 0x93, 0x80, 0x85, 0xcd, 0x7a, 0xc5,
- 0x1e, 0xda, 0xda, 0x5d, 0xe8, 0xa3, 0x9c, 0xe4, 0x8a, 0xf9, 0xc8, 0xd7,
- 0x15, 0xbc, 0xaa, 0xb3, 0x0d, 0x6f, 0x9e, 0xcb, 0x49, 0xbc, 0x7f, 0x5e,
- 0xd9, 0xeb, 0xfe, 0x7c, 0xdf, 0x7b, 0xde, 0x36, 0x75, 0x24, 0x17, 0xc2,
- 0xfb, 0x76, 0x5c, 0xa3, 0xfa, 0x41, 0xa6, 0xda, 0x61, 0x23, 0x12, 0x0b,
- 0x54, 0x6e, 0x6d, 0x10, 0xf6, 0x36, 0xf1, 0xef, 0xdb, 0xfb, 0x70, 0xdf,
- 0x88, 0x84, 0x6a, 0x8d, 0xe3, 0xac, 0x89, 0x43, 0x75, 0x1c, 0xa7, 0xba,
- 0xb0, 0x6b, 0xc4, 0x23, 0xce, 0xe4, 0x9c, 0x78, 0xa2, 0xfb, 0x11, 0x2c,
- 0x68, 0xbd, 0x07, 0xb0, 0x6d, 0x90, 0xbf, 0x7f, 0x0b, 0xa9, 0x45, 0xbc,
- 0x3e, 0xf7, 0xda, 0x04, 0x7c, 0xad, 0xcc, 0x07, 0xbc, 0xef, 0xd3, 0xfc,
- 0xdb, 0x86, 0x9c, 0xe2, 0x62, 0xfa, 0x3f, 0x5b, 0x27, 0x02, 0x8c, 0x13,
- 0xf8, 0x5e, 0x0d, 0xcc, 0x3a, 0x1e, 0xcb, 0x3a, 0xf4, 0x51, 0x6d, 0xda,
- 0x87, 0x21, 0xa2, 0xeb, 0x9c, 0x3d, 0xd7, 0x95, 0x39, 0xfa, 0x7d, 0xa2,
- 0x36, 0x23, 0x9b, 0x41, 0xa2, 0x45, 0x59, 0xdd, 0x8d, 0xda, 0xe2, 0xb5,
- 0xf9, 0xb6, 0xc6, 0xc3, 0xfd, 0x4a, 0xd2, 0x15, 0xe5, 0x84, 0x5e, 0xbc,
- 0x9b, 0x16, 0x78, 0xc7, 0xb6, 0xc1, 0x5e, 0x34, 0xe5, 0x6b, 0x00, 0x3b,
- 0x86, 0xf0, 0xb8, 0xaf, 0x57, 0x6c, 0x5b, 0xea, 0xc3, 0x03, 0xc4, 0x4b,
- 0x0d, 0xf1, 0xf2, 0x61, 0x6c, 0x29, 0xad, 0xc3, 0xd7, 0xfe, 0x9d, 0x3c,
- 0x77, 0xd6, 0x68, 0x6e, 0x2e, 0x4a, 0x18, 0x7e, 0xae, 0xf7, 0x22, 0xd8,
- 0x39, 0x12, 0xe9, 0xf1, 0x49, 0x6c, 0x87, 0x11, 0xdc, 0x3b, 0x79, 0x2b,
- 0xdd, 0xe7, 0xb9, 0x82, 0xb8, 0x2b, 0xe3, 0x14, 0x6f, 0x51, 0xbd, 0x74,
- 0x2a, 0x2d, 0x2d, 0x72, 0xe0, 0x39, 0xeb, 0x89, 0xc0, 0x2e, 0xdc, 0xa4,
- 0x77, 0x61, 0x3b, 0xd9, 0x60, 0x47, 0xd3, 0x2e, 0x8c, 0x92, 0x0d, 0x6c,
- 0xab, 0xa7, 0x1a, 0x2e, 0x56, 0xb2, 0x7a, 0x03, 0x2c, 0x47, 0x81, 0x4e,
- 0xba, 0x5e, 0x47, 0x75, 0x9d, 0x14, 0x23, 0x6b, 0x23, 0xbf, 0x90, 0x35,
- 0x35, 0x97, 0xc4, 0xef, 0xd8, 0x6b, 0xd6, 0x51, 0x9e, 0x76, 0x31, 0x3e,
- 0xf0, 0x33, 0x4e, 0xf8, 0x22, 0x3d, 0xa6, 0x55, 0xa5, 0x69, 0xd1, 0x8d,
- 0x52, 0x53, 0x6e, 0x86, 0x6c, 0x76, 0x7d, 0xeb, 0xb5, 0xcf, 0xcd, 0xcb,
- 0x48, 0x87, 0xbb, 0x75, 0xca, 0x2a, 0x2b, 0x83, 0x50, 0x5a, 0xaf, 0xd5,
- 0xfd, 0xfc, 0x1c, 0x4c, 0x73, 0x25, 0xae, 0x85, 0xa4, 0x88, 0x72, 0x37,
- 0x2e, 0xd0, 0x1a, 0x41, 0x6c, 0x2d, 0x76, 0xa1, 0x77, 0xc4, 0xf1, 0x19,
- 0x3e, 0xf1, 0xb3, 0x2d, 0x7f, 0xc6, 0xff, 0x8e, 0x91, 0x48, 0xa7, 0x77,
- 0x8e, 0xff, 0xed, 0x93, 0x9f, 0xcd, 0x35, 0x90, 0xe1, 0xbc, 0xca, 0xf3,
- 0xf1, 0xb9, 0xa1, 0x79, 0xf9, 0x06, 0xf1, 0x80, 0x3d, 0xdf, 0x61, 0x0f,
- 0xfb, 0xb0, 0x8b, 0x7c, 0x7d, 0x43, 0xab, 0x89, 0x57, 0x13, 0xf7, 0x5b,
- 0x3b, 0x6c, 0x19, 0xdc, 0x6f, 0x3f, 0xdf, 0xd9, 0x74, 0x76, 0x0e, 0xfb,
- 0x54, 0xfa, 0xb0, 0xa7, 0x4a, 0x2d, 0xf6, 0x1e, 0xc3, 0x0f, 0x29, 0x0f,
- 0x3e, 0xf7, 0xb9, 0x3e, 0xdf, 0x76, 0x17, 0xef, 0x4d, 0x3c, 0x5d, 0x92,
- 0x85, 0x73, 0xa4, 0x5a, 0xb8, 0x46, 0x98, 0xb6, 0x8f, 0xe5, 0x8a, 0x8f,
- 0xfd, 0x57, 0x24, 0x03, 0xbc, 0xcf, 0x58, 0xb1, 0xff, 0x68, 0xfb, 0xbd,
- 0xc0, 0x51, 0xd3, 0x53, 0xb5, 0x0a, 0x54, 0xeb, 0x77, 0xdb, 0xf6, 0xb0,
- 0xd0, 0x08, 0xac, 0x7d, 0xae, 0x89, 0xeb, 0x7d, 0xee, 0x0d, 0x6a, 0x6b,
- 0xc7, 0x08, 0x80, 0x6e, 0x55, 0x78, 0x4d, 0xf5, 0x04, 0xf7, 0xeb, 0xb9,
- 0x8f, 0x4f, 0x71, 0xd7, 0x5b, 0xb7, 0xca, 0xf4, 0x2c, 0x58, 0xe5, 0x14,
- 0x8b, 0x33, 0x3d, 0x64, 0x7b, 0x1a, 0x12, 0x19, 0xd3, 0xdb, 0xb0, 0x2a,
- 0x84, 0x87, 0x32, 0xf3, 0x31, 0xb9, 0x05, 0x2d, 0xe3, 0xc0, 0x0f, 0x33,
- 0x41, 0x34, 0x8f, 0x86, 0xfb, 0x6f, 0x95, 0xc2, 0x03, 0xb3, 0x12, 0xdf,
- 0xbb, 0xbc, 0x66, 0xa5, 0x8d, 0xc5, 0x3f, 0x5a, 0xb3, 0xc2, 0xfe, 0x0c,
- 0x18, 0xd7, 0xe7, 0xef, 0x40, 0x7a, 0xc6, 0x33, 0x5b, 0x96, 0x2c, 0x3c,
- 0x14, 0x93, 0x70, 0xb3, 0xfe, 0x6f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab,
- 0x9c, 0x83, 0xed, 0x60, 0xb6, 0x64, 0x95, 0x86, 0x55, 0x99, 0x3a, 0x8a,
- 0x49, 0xf5, 0x14, 0x9f, 0xea, 0x70, 0x85, 0x62, 0xd2, 0x8a, 0x36, 0x0b,
- 0x8b, 0xdb, 0xcc, 0xbe, 0xc5, 0xe0, 0x3d, 0x68, 0xd5, 0x2c, 0x0a, 0xb5,
- 0xa7, 0x4b, 0x52, 0xbb, 0xeb, 0x25, 0x05, 0xdb, 0x23, 0x3c, 0x77, 0xd0,
- 0x58, 0x95, 0xaf, 0xe4, 0xd3, 0x4a, 0x5e, 0x75, 0xce, 0xe5, 0x53, 0xb7,
- 0xa1, 0x4f, 0xab, 0x3f, 0x4e, 0x49, 0xbc, 0x6f, 0xd2, 0x83, 0x91, 0x6c,
- 0x0a, 0x7b, 0xb3, 0x21, 0xfc, 0x3a, 0xe3, 0x26, 0xdb, 0x08, 0xeb, 0x3f,
- 0x00, 0x8f, 0xf1, 0x19, 0xb1, 0x7c, 0x38, 0xfa, 0x90, 0xf4, 0x13, 0x94,
- 0x9d, 0xea, 0x11, 0xaa, 0x12, 0x08, 0x37, 0x34, 0x87, 0x5e, 0xc4, 0x4f,
- 0xec, 0x7d, 0x36, 0xa0, 0xc2, 0x43, 0x53, 0x1e, 0xc8, 0x65, 0x3c, 0xb3,
- 0xb0, 0x7b, 0xb2, 0xbc, 0x6f, 0x2c, 0x61, 0xbd, 0x7e, 0x3f, 0xc9, 0x59,
- 0xa0, 0xa9, 0xb5, 0x0e, 0xe5, 0x2d, 0x4e, 0x8c, 0x64, 0x38, 0x0f, 0x7f,
- 0xbc, 0x46, 0x1e, 0x42, 0x79, 0x6e, 0x4f, 0x34, 0xe1, 0xa0, 0x0c, 0xfd,
- 0x72, 0x11, 0x38, 0x48, 0xb1, 0x63, 0x53, 0xec, 0x37, 0x56, 0x05, 0x8f,
- 0xca, 0xfe, 0xf4, 0x98, 0xc0, 0x02, 0x2d, 0x49, 0xf2, 0x70, 0xfa, 0x0f,
- 0xa5, 0xa3, 0x76, 0x0e, 0x1e, 0xa1, 0xf9, 0x93, 0xf6, 0xfc, 0x91, 0xfd,
- 0x4b, 0x25, 0x09, 0xd7, 0xb7, 0x1e, 0xc5, 0xc4, 0xc2, 0x0a, 0x0d, 0x41,
- 0xc2, 0x04, 0x5c, 0xcb, 0xd6, 0x13, 0x8f, 0x9b, 0x1f, 0xe3, 0xbe, 0xe6,
- 0x6f, 0xd7, 0xdc, 0x30, 0xce, 0x7e, 0xfd, 0xf1, 0x9a, 0x77, 0xd3, 0x6a,
- 0xb2, 0x9e, 0xea, 0x87, 0x6a, 0x92, 0xc3, 0xbd, 0x43, 0xdc, 0x4f, 0xa8,
- 0x37, 0x5e, 0x3f, 0xcc, 0x79, 0x59, 0x1d, 0x68, 0x10, 0x3e, 0x71, 0x73,
- 0x46, 0xed, 0x63, 0xc2, 0x2f, 0x47, 0xd4, 0x20, 0xc9, 0xae, 0xf3, 0x1e,
- 0xd1, 0xc7, 0x35, 0x8b, 0x2d, 0xb7, 0xeb, 0xf2, 0x15, 0xdc, 0x11, 0x9e,
- 0xc3, 0x21, 0x51, 0x1b, 0x77, 0x58, 0xd6, 0x9e, 0x18, 0xe7, 0x71, 0xfb,
- 0x4c, 0x00, 0x5d, 0xaf, 0x33, 0x96, 0x52, 0x6d, 0x31, 0xc8, 0xf4, 0xf1,
- 0x19, 0x0f, 0x89, 0x6a, 0xd1, 0xec, 0xab, 0x73, 0xb8, 0xc4, 0x87, 0x7d,
- 0x74, 0xbd, 0x6c, 0xe3, 0x13, 0x3e, 0xa7, 0xe8, 0x35, 0x94, 0xc7, 0xf8,
- 0x6c, 0xe3, 0x6f, 0xd7, 0xac, 0x1f, 0x53, 0x43, 0x12, 0xf1, 0xb1, 0x97,
- 0xf7, 0xe7, 0x69, 0xce, 0x69, 0x9d, 0xe9, 0xbe, 0xbc, 0x86, 0xfb, 0xb1,
- 0x4b, 0x88, 0x6e, 0x2b, 0x1b, 0x66, 0x0c, 0x6a, 0xdb, 0x4a, 0x22, 0x4f,
- 0x55, 0xfd, 0xe2, 0x0a, 0xaf, 0x2e, 0xd2, 0xc9, 0xb1, 0x74, 0x12, 0xa7,
- 0xe2, 0x15, 0xfd, 0xac, 0xcb, 0x7f, 0x03, 0xa9, 0xfa, 0x0e, 0xe4, 0xb2,
- 0x8a, 0x7f, 0x43, 0xa6, 0x03, 0xa3, 0xa4, 0xc3, 0xbb, 0x8b, 0x41, 0x7f,
- 0x47, 0x46, 0x43, 0x6f, 0x91, 0xeb, 0x2b, 0x18, 0x7b, 0xc6, 0x26, 0xe7,
- 0xea, 0xe0, 0x4a, 0x2e, 0x39, 0x90, 0xa9, 0xd8, 0x5c, 0x38, 0xef, 0x99,
- 0x0d, 0x89, 0xca, 0xbc, 0x32, 0xad, 0x23, 0x0f, 0xfd, 0x89, 0x85, 0x85,
- 0x6c, 0x0b, 0x77, 0x60, 0x6c, 0xdc, 0x6f, 0x2e, 0x36, 0x14, 0xac, 0x6a,
- 0xfd, 0x73, 0x7a, 0xb6, 0x05, 0x1f, 0x1f, 0xff, 0x3a, 0xca, 0xdf, 0x24,
- 0x7c, 0x94, 0x49, 0xa2, 0xb9, 0xf5, 0x16, 0xa4, 0xfe, 0x40, 0xc6, 0xd3,
- 0x19, 0x1f, 0x9e, 0xcf, 0x54, 0xf6, 0xec, 0x7f, 0x94, 0x25, 0x3f, 0x24,
- 0x1f, 0x78, 0xee, 0x4b, 0xf7, 0x49, 0x29, 0x9e, 0x3b, 0x78, 0x0f, 0xff,
- 0x1f, 0x1e, 0x77, 0xde, 0x1e, 0xe7, 0x11, 0x75, 0x23, 0xf3, 0xf3, 0x5a,
- 0xd0, 0x5a, 0xff, 0xbe, 0x67, 0x08, 0xf3, 0x81, 0x62, 0x48, 0xe5, 0x8c,
- 0x83, 0x90, 0x47, 0xec, 0x7d, 0x23, 0xc2, 0xb9, 0x11, 0xfd, 0x02, 0x4c,
- 0xb8, 0x09, 0x5f, 0x2d, 0x25, 0x59, 0x68, 0x99, 0x80, 0x5f, 0x2a, 0x2a,
- 0xf4, 0xdf, 0xe8, 0x77, 0x92, 0x7c, 0x9c, 0xc5, 0x8f, 0x28, 0xa6, 0xb0,
- 0x4f, 0x55, 0x72, 0x9c, 0x54, 0x7c, 0xc4, 0x4b, 0xc0, 0x87, 0x3e, 0x2b,
- 0x36, 0x1d, 0xca, 0x2f, 0xf6, 0x32, 0x96, 0xc9, 0x65, 0x2a, 0xbf, 0x23,
- 0x57, 0x7f, 0x93, 0x9e, 0x6d, 0x99, 0x8d, 0xd0, 0x6f, 0x96, 0xc5, 0x73,
- 0x56, 0x6a, 0x33, 0xcb, 0x2b, 0xe0, 0x7f, 0x83, 0xe4, 0x3f, 0x46, 0x34,
- 0x66, 0x69, 0x8d, 0xd7, 0x69, 0xcd, 0x4c, 0xf1, 0x10, 0x8d, 0xe1, 0x7b,
- 0x24, 0x67, 0xdb, 0x76, 0x0f, 0x7b, 0xf9, 0x7c, 0xc2, 0xf3, 0x19, 0x60,
- 0x30, 0x6b, 0xaa, 0xce, 0xb9, 0x73, 0x9d, 0x83, 0x94, 0x2f, 0xab, 0x28,
- 0x16, 0xbd, 0x19, 0xdf, 0x8e, 0x1b, 0x73, 0x6a, 0xd2, 0x24, 0x3c, 0x96,
- 0x52, 0x20, 0x48, 0x77, 0x64, 0xc3, 0x01, 0xe3, 0xdd, 0x74, 0x23, 0xf1,
- 0x14, 0x0e, 0x5d, 0xa0, 0xf1, 0xa6, 0x53, 0xc6, 0x81, 0x51, 0x07, 0x2e,
- 0xf0, 0x1e, 0xb2, 0xa8, 0x3c, 0x6f, 0x82, 0xc7, 0xce, 0x7f, 0xaf, 0xa6,
- 0xba, 0x2e, 0x9c, 0xa0, 0xac, 0x6a, 0xd6, 0x10, 0x6e, 0xcf, 0xb7, 0x3f,
- 0x82, 0x43, 0x54, 0xeb, 0xef, 0x88, 0x85, 0x90, 0xac, 0x8b, 0x53, 0xbd,
- 0xd1, 0xdc, 0x7f, 0x09, 0xff, 0xcd, 0x2a, 0xf3, 0x3e, 0xbc, 0x08, 0x27,
- 0x2e, 0xe1, 0x53, 0xcb, 0xa1, 0x69, 0x67, 0xa7, 0xa0, 0x95, 0x2f, 0xa0,
- 0x79, 0xe0, 0x13, 0xbc, 0x67, 0xf1, 0x1e, 0xbd, 0xec, 0x70, 0x10, 0x06,
- 0x0c, 0x2b, 0x4e, 0x04, 0x50, 0x0e, 0x38, 0xb0, 0x49, 0xe7, 0xde, 0xb4,
- 0x3a, 0xf0, 0x24, 0x61, 0xf9, 0x77, 0x44, 0x73, 0xdf, 0x87, 0x38, 0x6f,
- 0x4d, 0xd4, 0xf1, 0xba, 0x02, 0x89, 0xeb, 0x9b, 0xcf, 0xba, 0xa1, 0x76,
- 0xba, 0x84, 0x96, 0x68, 0x70, 0xfc, 0x95, 0x75, 0x3e, 0xf0, 0xa9, 0xa5,
- 0x45, 0x3e, 0x25, 0x1c, 0xa4, 0x05, 0x27, 0xc9, 0xf6, 0xfb, 0x30, 0x4f,
- 0x9b, 0xa8, 0x86, 0x57, 0x27, 0x1a, 0x18, 0xf7, 0x99, 0x9e, 0x7d, 0x44,
- 0xdb, 0x6b, 0x84, 0x03, 0x76, 0xc4, 0x2e, 0x59, 0xc9, 0x85, 0x7c, 0xfe,
- 0x4f, 0xa9, 0xae, 0xf4, 0xc0, 0xb9, 0x6f, 0x72, 0x07, 0xee, 0x4a, 0x3b,
- 0x49, 0x4e, 0xf3, 0x78, 0xcd, 0x45, 0x31, 0x98, 0x63, 0x7f, 0xf9, 0x3a,
- 0x2a, 0xcd, 0x24, 0x2a, 0xf1, 0xb1, 0x87, 0xe2, 0xc2, 0x6e, 0x3b, 0x17,
- 0xc0, 0xbb, 0x64, 0x55, 0x2b, 0x3e, 0x19, 0x7f, 0xd3, 0x4b, 0xbe, 0xb4,
- 0x4e, 0x6b, 0x83, 0x08, 0x66, 0x4c, 0x51, 0x6b, 0x38, 0xf0, 0x61, 0xbb,
- 0xda, 0x29, 0x39, 0x06, 0x70, 0x7d, 0xcc, 0xb4, 0x7c, 0x9a, 0xd6, 0xd3,
- 0x22, 0x22, 0xdd, 0x45, 0x11, 0x45, 0x75, 0xd1, 0x27, 0x57, 0x17, 0x5b,
- 0x64, 0x6f, 0xd1, 0xf4, 0x28, 0xab, 0xb6, 0x53, 0xdd, 0xb2, 0x8b, 0x6a,
- 0x5b, 0x1f, 0xd5, 0xd7, 0xaa, 0x7e, 0x11, 0x6e, 0x92, 0x7f, 0x08, 0xfb,
- 0x4a, 0x06, 0x9c, 0x99, 0x9d, 0x70, 0x65, 0xc2, 0xca, 0x5e, 0xec, 0x42,
- 0x32, 0x58, 0xc1, 0xb6, 0x32, 0xe9, 0xaa, 0xaa, 0x9d, 0xb1, 0xcc, 0x76,
- 0x9c, 0x9f, 0x60, 0x7c, 0x9e, 0xc0, 0xd6, 0x34, 0xff, 0x86, 0xf7, 0xc5,
- 0xb8, 0x81, 0x93, 0x54, 0x3b, 0x79, 0x5a, 0x1b, 0x48, 0x0f, 0x8d, 0x18,
- 0x2c, 0x09, 0x36, 0x2b, 0xd2, 0x05, 0xbc, 0x27, 0xdb, 0x65, 0x1c, 0x9c,
- 0xa2, 0x44, 0x42, 0xf9, 0xca, 0x99, 0x51, 0x28, 0x4e, 0xc8, 0xf0, 0x69,
- 0x3e, 0xfa, 0x1d, 0xe0, 0x73, 0x4b, 0x64, 0x67, 0xbf, 0x5d, 0xd3, 0x62,
- 0xc7, 0x9a, 0x7a, 0xaa, 0x75, 0xde, 0x21, 0x5e, 0x58, 0x16, 0x06, 0xaa,
- 0x47, 0xe6, 0x6b, 0xc2, 0xf5, 0xb7, 0x55, 0x23, 0x48, 0x73, 0x32, 0x0e,
- 0xac, 0x9c, 0x57, 0x5d, 0x1f, 0x6b, 0x45, 0x21, 0x27, 0xe6, 0x30, 0xd6,
- 0xa0, 0xea, 0xc3, 0x3a, 0x1c, 0xa2, 0xda, 0xdf, 0xaf, 0x6d, 0x45, 0x46,
- 0x29, 0x7b, 0x7f, 0x11, 0xe7, 0x1a, 0x00, 0xde, 0x5e, 0xc2, 0x50, 0x43,
- 0xe9, 0xaf, 0x72, 0xcc, 0xf4, 0xdc, 0x1d, 0xd7, 0x71, 0x24, 0x47, 0x21,
- 0x4a, 0x5b, 0x87, 0xda, 0xb6, 0x2e, 0x7c, 0x58, 0xc7, 0xf8, 0x97, 0x62,
- 0x15, 0xd1, 0xb3, 0x77, 0x2a, 0x60, 0x9f, 0xab, 0xd8, 0x57, 0x9a, 0xa7,
- 0xf9, 0x5a, 0x5a, 0xbf, 0x8c, 0x46, 0x96, 0xc9, 0x3f, 0x44, 0x23, 0xd9,
- 0x2c, 0x61, 0x9e, 0x5c, 0xba, 0x17, 0x2f, 0xa7, 0x79, 0xde, 0x70, 0x52,
- 0x17, 0x0a, 0xf7, 0xe6, 0x6d, 0x99, 0x98, 0x53, 0xbc, 0x06, 0xaf, 0x3f,
- 0xbf, 0x4e, 0x80, 0x6a, 0x85, 0x7f, 0xec, 0x5a, 0x14, 0x37, 0x72, 0xeb,
- 0xa8, 0xee, 0x8c, 0x42, 0xfb, 0xfd, 0x32, 0xe9, 0x83, 0x7b, 0xd5, 0x4b,
- 0x09, 0xf3, 0xc2, 0xf3, 0x4a, 0x9c, 0xcf, 0x30, 0x5b, 0xbb, 0x64, 0xc3,
- 0xb2, 0x5c, 0xed, 0x9a, 0xf2, 0x36, 0xd8, 0x0e, 0x7d, 0xbc, 0xe7, 0xe1,
- 0xd9, 0xdb, 0xee, 0xc3, 0x41, 0xca, 0x81, 0x4f, 0xa5, 0x9b, 0x4d, 0xae,
- 0xfd, 0xc0, 0x38, 0x54, 0xa4, 0xe8, 0xd9, 0x7f, 0x55, 0xcd, 0x3e, 0xbb,
- 0xa7, 0xb4, 0x13, 0x52, 0xa6, 0xa7, 0x9a, 0xeb, 0x0d, 0x37, 0xd5, 0xc9,
- 0x83, 0x69, 0xa6, 0xd7, 0xda, 0xe5, 0xa4, 0xb9, 0x76, 0xc7, 0xb5, 0xd9,
- 0x1b, 0xc9, 0x2e, 0x1a, 0x0c, 0x96, 0x63, 0x00, 0x4f, 0xd0, 0xd8, 0x50,
- 0x89, 0x65, 0x79, 0xa8, 0x9a, 0xfb, 0x9e, 0xfb, 0x48, 0xbf, 0xb5, 0xd9,
- 0xca, 0x3c, 0xd9, 0x52, 0x1f, 0x96, 0x0e, 0xbd, 0x58, 0x5d, 0xa9, 0x7d,
- 0xb8, 0x2e, 0xef, 0xc7, 0xbe, 0x74, 0x00, 0x53, 0xe9, 0x66, 0xe5, 0x05,
- 0xfb, 0xcc, 0x40, 0xa5, 0x47, 0x36, 0x98, 0x9e, 0x1f, 0x13, 0xc0, 0xe4,
- 0xd5, 0xef, 0x2c, 0x9f, 0x4a, 0xef, 0xf4, 0x94, 0x8d, 0xf9, 0x65, 0x4c,
- 0x04, 0x2a, 0x78, 0x88, 0x62, 0x85, 0xf7, 0x51, 0xd2, 0xeb, 0x3b, 0xa4,
- 0x57, 0x89, 0xf4, 0xfa, 0x82, 0xfe, 0x23, 0xc6, 0x2c, 0x9e, 0x3d, 0x71,
- 0x1f, 0xef, 0x13, 0x99, 0x04, 0x5a, 0xec, 0x31, 0x99, 0xb8, 0x13, 0xe7,
- 0x86, 0xf8, 0x6c, 0xe2, 0x47, 0x6b, 0x5e, 0x4a, 0x5b, 0xeb, 0x66, 0x62,
- 0xcd, 0xa9, 0x77, 0x08, 0x4f, 0x9b, 0x7f, 0xa0, 0xea, 0xe7, 0xc9, 0x4f,
- 0xb3, 0xa3, 0x7f, 0x88, 0xf3, 0x75, 0xcd, 0xca, 0xcf, 0x61, 0x7a, 0x1e,
- 0x8f, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0x6d, 0xff, 0x92, 0x9c, 0x2c,
- 0x0e, 0x87, 0xd6, 0x3c, 0xfb, 0x02, 0xfe, 0x23, 0xce, 0x2f, 0x0e, 0xeb,
- 0x2f, 0x80, 0xc7, 0x54, 0xea, 0xf1, 0xf0, 0xf4, 0x7d, 0x7c, 0x9e, 0x2a,
- 0x48, 0x69, 0xb4, 0xb2, 0x9f, 0x95, 0xe6, 0xfd, 0x37, 0x81, 0x89, 0x2d,
- 0x54, 0x4b, 0xdb, 0xe7, 0x58, 0xe1, 0x7d, 0x92, 0xfc, 0x22, 0x3a, 0xcc,
- 0xe3, 0x3f, 0x5e, 0xa3, 0xe5, 0x43, 0x70, 0x10, 0xc6, 0x49, 0x05, 0xd4,
- 0x4e, 0x20, 0xe8, 0x7f, 0x32, 0x1d, 0xa4, 0x1a, 0xad, 0xb9, 0x3b, 0x2a,
- 0xee, 0x9c, 0xdb, 0xf7, 0xe6, 0x3c, 0xf7, 0xf1, 0x9a, 0x63, 0x69, 0x35,
- 0xf5, 0x24, 0x9a, 0x7b, 0x7c, 0xe2, 0x0e, 0xa4, 0xea, 0x9a, 0xfb, 0x4e,
- 0x22, 0x9c, 0xf0, 0x08, 0x35, 0x7a, 0x1e, 0x95, 0x79, 0x96, 0xe5, 0x1d,
- 0x54, 0x27, 0x72, 0x9c, 0x49, 0xe3, 0xa4, 0xe2, 0xc0, 0xf2, 0x56, 0x6d,
- 0x76, 0x12, 0xf3, 0xf6, 0x52, 0x19, 0xb3, 0x2e, 0x4f, 0xe3, 0x1d, 0x0a,
- 0xd5, 0xfb, 0x6e, 0x38, 0xeb, 0x79, 0x4f, 0x71, 0x27, 0x76, 0xa4, 0x39,
- 0x4f, 0x93, 0x5c, 0xc8, 0x37, 0xbb, 0x23, 0x3b, 0xd1, 0x9f, 0x0f, 0xe0,
- 0x50, 0x36, 0xbc, 0x7f, 0x2f, 0xe1, 0xba, 0xe1, 0x52, 0x38, 0xb4, 0x4d,
- 0x04, 0x48, 0xdf, 0x54, 0xff, 0xd7, 0x07, 0xa9, 0x4e, 0x56, 0xe8, 0xbf,
- 0x52, 0xcf, 0xbc, 0x44, 0xf5, 0xcc, 0x39, 0xf2, 0x35, 0xdf, 0x5c, 0xad,
- 0xba, 0x6c, 0xc2, 0xc2, 0x4c, 0x6c, 0x23, 0x2e, 0xdb, 0x3a, 0x0b, 0x92,
- 0x8d, 0x71, 0x2e, 0xe2, 0xb3, 0x35, 0x1e, 0xb1, 0x6d, 0xd8, 0xf4, 0x3c,
- 0xd8, 0x1e, 0x44, 0x38, 0xc3, 0x98, 0x53, 0xfa, 0xa6, 0x83, 0xe4, 0x31,
- 0xa5, 0xed, 0xc2, 0x86, 0xd8, 0x2e, 0xf4, 0xeb, 0x7f, 0x02, 0x77, 0x3d,
- 0xc7, 0x23, 0xd9, 0xac, 0xa5, 0x79, 0x2f, 0xb5, 0x77, 0x21, 0x7c, 0x94,
- 0x73, 0x30, 0x55, 0xc3, 0x43, 0xec, 0xbb, 0x3c, 0xff, 0x6d, 0xc6, 0x0a,
- 0xc2, 0x15, 0x35, 0xed, 0x95, 0x3c, 0x7f, 0x7d, 0x9e, 0xcf, 0x74, 0x82,
- 0x6a, 0x53, 0x78, 0xdf, 0x5a, 0x6d, 0xe0, 0x71, 0x8a, 0x31, 0x89, 0x36,
- 0x17, 0xb0, 0x80, 0xcf, 0x2e, 0x57, 0xea, 0x18, 0xe6, 0x77, 0x69, 0x5e,
- 0x60, 0x3a, 0x4e, 0xf6, 0xf1, 0x77, 0xce, 0x28, 0x85, 0xe6, 0xce, 0x96,
- 0x72, 0xff, 0xe4, 0xb0, 0x95, 0xe4, 0xf7, 0x0d, 0xa4, 0xa0, 0x8f, 0xe2,
- 0x6d, 0xb0, 0x0c, 0x2a, 0xea, 0x29, 0x2e, 0x3b, 0xb4, 0x79, 0xb9, 0xb3,
- 0xac, 0x4f, 0x58, 0x13, 0x73, 0xba, 0x70, 0xd2, 0x33, 0x7b, 0xc6, 0xd4,
- 0x81, 0xbd, 0x68, 0xee, 0x7f, 0x57, 0x54, 0xd9, 0x3b, 0x98, 0x93, 0x2d,
- 0x48, 0x2d, 0x31, 0x9c, 0x5b, 0x3e, 0xc9, 0xae, 0x23, 0x3a, 0x2e, 0x10,
- 0x08, 0x5d, 0x6f, 0xef, 0x73, 0x4d, 0xb6, 0xfc, 0x29, 0xcd, 0xcd, 0xdf,
- 0xff, 0xd8, 0xc7, 0x67, 0x2e, 0x4f, 0x65, 0x9f, 0xb7, 0xa2, 0x0b, 0x2b,
- 0xf2, 0x39, 0x4d, 0xbe, 0x1f, 0x34, 0x24, 0x34, 0x68, 0x91, 0xd9, 0x1e,
- 0xfa, 0xfd, 0xd7, 0x79, 0x42, 0xfb, 0xab, 0xfb, 0xf0, 0xcb, 0x09, 0x03,
- 0x07, 0x28, 0x0f, 0xd4, 0x6a, 0xaa, 0x32, 0x81, 0x10, 0xd7, 0xd2, 0x36,
- 0xff, 0x2b, 0x27, 0xc8, 0x0f, 0xeb, 0x14, 0xbb, 0xc6, 0xa8, 0xf0, 0x77,
- 0x99, 0xf8, 0x7b, 0xd0, 0xc7, 0xbe, 0xb0, 0x84, 0xfc, 0x62, 0x3f, 0xf9,
- 0xeb, 0x01, 0xb2, 0x35, 0xaa, 0xe0, 0xc9, 0x0f, 0xd4, 0xfd, 0x20, 0x7f,
- 0x1d, 0x4e, 0xb3, 0xfc, 0x83, 0xfe, 0x5e, 0x3e, 0xde, 0xac, 0xd9, 0x7d,
- 0x55, 0x3d, 0x24, 0x71, 0xdc, 0xb5, 0xe3, 0xa9, 0x19, 0x92, 0xac, 0x6a,
- 0xa6, 0x6b, 0xb0, 0x14, 0x0e, 0x7a, 0xf9, 0x5d, 0x00, 0x02, 0x87, 0xbd,
- 0x7a, 0x25, 0x57, 0xce, 0x50, 0x3e, 0xba, 0x4c, 0x74, 0x1c, 0x8a, 0x35,
- 0x20, 0x45, 0xf9, 0x28, 0xa3, 0x55, 0x6c, 0x49, 0x9b, 0x66, 0x8c, 0x59,
- 0x6f, 0x04, 0xc7, 0xd5, 0x90, 0xcb, 0xd1, 0x3c, 0x70, 0x06, 0x3b, 0xad,
- 0xf3, 0x75, 0x6c, 0x53, 0x2e, 0x1c, 0x6f, 0x99, 0xb6, 0xca, 0x01, 0xe6,
- 0xd7, 0x81, 0xe7, 0x75, 0xb2, 0x99, 0xc5, 0xe1, 0xe0, 0xf3, 0x94, 0x53,
- 0xa7, 0xe6, 0xf4, 0x11, 0xce, 0xcf, 0xdb, 0xe3, 0x5a, 0x96, 0x75, 0x34,
- 0x05, 0x2d, 0x91, 0x47, 0x2f, 0x7d, 0x6f, 0x0a, 0x5e, 0x9e, 0xb3, 0xd5,
- 0x15, 0xd3, 0xaf, 0xfb, 0xe6, 0xde, 0xcb, 0xb1, 0x9f, 0x09, 0xe5, 0xff,
- 0x88, 0x7e, 0xf3, 0x9c, 0x01, 0xc6, 0x32, 0x7c, 0x56, 0xcb, 0xbb, 0xa3,
- 0xdd, 0xcd, 0xfe, 0xa2, 0xf0, 0x3b, 0x09, 0x1b, 0x86, 0xb9, 0x2f, 0xcc,
- 0x3d, 0x1a, 0x07, 0xf6, 0x5e, 0x7d, 0x67, 0x82, 0x3f, 0x3b, 0xb1, 0x69,
- 0x98, 0x7b, 0x11, 0xa7, 0x6f, 0x90, 0xf1, 0x37, 0x94, 0x87, 0x65, 0xf6,
- 0x79, 0xf2, 0xf5, 0x4f, 0xd7, 0xbc, 0x34, 0xc6, 0x39, 0x35, 0x60, 0xdc,
- 0x95, 0x9e, 0xd7, 0xf1, 0x55, 0x9e, 0xce, 0xde, 0x4d, 0x71, 0x27, 0x93,
- 0x56, 0x07, 0x22, 0x0e, 0x7b, 0x7f, 0x2d, 0x55, 0x14, 0x5f, 0xa5, 0x22,
- 0x8d, 0xe7, 0x53, 0xfc, 0x03, 0x87, 0x43, 0xc8, 0x64, 0xbb, 0xf0, 0x8d,
- 0x61, 0xcb, 0x72, 0xb7, 0x39, 0xf1, 0xca, 0x90, 0x85, 0x0f, 0x62, 0xc0,
- 0xcb, 0x43, 0xe1, 0x81, 0x73, 0xc0, 0xb7, 0x6b, 0xa9, 0x46, 0x6e, 0x11,
- 0x6a, 0x37, 0x61, 0x83, 0xd0, 0x7b, 0x68, 0x0e, 0xe6, 0xa1, 0x9e, 0xdd,
- 0x4d, 0xf3, 0xbd, 0x58, 0x00, 0x7e, 0x59, 0xf0, 0xe2, 0x17, 0xc3, 0x3c,
- 0xa7, 0x17, 0xe7, 0x8e, 0xd6, 0xfb, 0x77, 0xd2, 0x5c, 0x07, 0x29, 0xbe,
- 0x77, 0x1d, 0x4b, 0x60, 0xd3, 0x61, 0x81, 0x68, 0x24, 0x81, 0xce, 0x63,
- 0x35, 0xd8, 0x38, 0x2c, 0xe3, 0xfd, 0x78, 0x0d, 0x6e, 0x39, 0x3a, 0xcf,
- 0x47, 0xa5, 0xaf, 0xc1, 0x67, 0x35, 0xf9, 0x1c, 0xdc, 0xc9, 0x2c, 0xc7,
- 0x6c, 0xca, 0x17, 0x59, 0x8e, 0x81, 0x96, 0x15, 0x6c, 0xaf, 0xf4, 0x39,
- 0x9e, 0xa6, 0xfc, 0xf1, 0x78, 0xbb, 0x16, 0x0c, 0x4a, 0x06, 0x96, 0x8f,
- 0x96, 0xef, 0xac, 0x85, 0x75, 0x8a, 0xf7, 0x33, 0x3e, 0x6a, 0xb1, 0xac,
- 0x4d, 0xf1, 0xc8, 0xec, 0xbd, 0x36, 0xae, 0x0d, 0x90, 0x4f, 0x35, 0xe2,
- 0xf1, 0xec, 0xfc, 0x9e, 0x97, 0xd6, 0x73, 0xc9, 0x61, 0xee, 0x52, 0x60,
- 0x5d, 0xa9, 0x32, 0xac, 0x8f, 0x5c, 0x46, 0x24, 0xf8, 0x80, 0xe0, 0xb3,
- 0x22, 0xdc, 0x13, 0xb7, 0xac, 0x37, 0xe3, 0x96, 0x55, 0x88, 0x9b, 0x9e,
- 0x15, 0xab, 0x14, 0x1c, 0x5b, 0xc6, 0xef, 0x2a, 0x84, 0x93, 0x0d, 0x64,
- 0x5f, 0xde, 0x65, 0x5a, 0x70, 0x2b, 0x54, 0xd3, 0xa4, 0x20, 0x17, 0x5a,
- 0xa8, 0xf6, 0x00, 0x8d, 0xfe, 0x43, 0x43, 0xf5, 0xf8, 0xfe, 0xcc, 0xef,
- 0xf2, 0xf1, 0x1d, 0xbb, 0x9f, 0x76, 0x45, 0xc7, 0xba, 0x5a, 0x44, 0x92,
- 0xf7, 0x80, 0x7b, 0xa3, 0x7c, 0xa6, 0xd5, 0xc4, 0x2d, 0xf1, 0x3e, 0xec,
- 0x18, 0xe6, 0x7d, 0xb6, 0x3a, 0xe3, 0xca, 0xb0, 0xf5, 0xd7, 0x1e, 0xa2,
- 0x7f, 0x5d, 0x7b, 0x73, 0xca, 0x6b, 0xbf, 0xe3, 0xe4, 0x34, 0xd6, 0x8f,
- 0xd5, 0xa1, 0x34, 0xa5, 0x95, 0x97, 0x88, 0xe4, 0x1b, 0x3e, 0x44, 0x82,
- 0x0d, 0x14, 0xab, 0x66, 0xc8, 0x77, 0xa7, 0x4a, 0x5c, 0x07, 0x2c, 0x30,
- 0xac, 0xd1, 0x45, 0x98, 0x9c, 0xa1, 0xb9, 0xb2, 0x5a, 0xe7, 0x07, 0x84,
- 0xf3, 0xaa, 0x0d, 0xab, 0xd6, 0x6b, 0x44, 0xce, 0x36, 0x0b, 0x07, 0x66,
- 0xdb, 0x2c, 0xab, 0xab, 0x5d, 0x1b, 0xa8, 0x11, 0xe8, 0x97, 0x0c, 0x2d,
- 0xd1, 0xe2, 0xc0, 0xd7, 0x82, 0x88, 0x74, 0xbe, 0x89, 0x48, 0xcf, 0x05,
- 0x8a, 0x61, 0x4f, 0x95, 0xf8, 0x9c, 0xf0, 0x23, 0xf8, 0xeb, 0xe1, 0x85,
- 0x38, 0x35, 0xd5, 0x3f, 0xd7, 0x13, 0x83, 0xf7, 0xfa, 0x55, 0x06, 0x8e,
- 0x0f, 0x87, 0xc8, 0x7e, 0xdc, 0x14, 0xd7, 0x65, 0x48, 0x4d, 0x90, 0xeb,
- 0xa8, 0x4e, 0x88, 0x3d, 0x66, 0x59, 0x2b, 0x9a, 0x2a, 0x35, 0xcf, 0x8a,
- 0xe9, 0x6b, 0xdf, 0x71, 0x98, 0xef, 0xf7, 0x04, 0x49, 0x7f, 0xcd, 0xa9,
- 0x1d, 0xe2, 0x8c, 0x65, 0xfe, 0x81, 0x20, 0x9e, 0x7b, 0x6a, 0xe0, 0x65,
- 0xbe, 0x65, 0xec, 0x1e, 0xe5, 0x3e, 0x1c, 0xeb, 0x0d, 0xde, 0xce, 0x38,
- 0xef, 0x97, 0xb3, 0x8e, 0xca, 0xde, 0x0d, 0x71, 0x8a, 0x89, 0xc2, 0x4f,
- 0x78, 0xca, 0xf4, 0x74, 0x50, 0x7e, 0xaa, 0x1a, 0xe6, 0xf7, 0x2d, 0x7c,
- 0x38, 0x40, 0x71, 0xe3, 0xb2, 0x5e, 0x8d, 0x43, 0x75, 0x6a, 0x82, 0xeb,
- 0xe9, 0x27, 0x4b, 0xdc, 0x33, 0xdc, 0x89, 0xed, 0xfc, 0xbe, 0x4a, 0x69,
- 0xb5, 0x7d, 0xb6, 0x90, 0xae, 0x11, 0x36, 0x60, 0x3a, 0xe6, 0xd7, 0xef,
- 0xc4, 0x92, 0x21, 0xd6, 0xe3, 0xc7, 0x6b, 0x82, 0x24, 0xa3, 0xc7, 0xc9,
- 0x2e, 0x24, 0xa3, 0x03, 0xf2, 0x90, 0x65, 0xdd, 0x18, 0xbf, 0x76, 0x0e,
- 0xad, 0xff, 0x82, 0x83, 0xea, 0x3b, 0x07, 0xef, 0xeb, 0xa9, 0x89, 0x13,
- 0xe2, 0xda, 0x39, 0x0b, 0x35, 0xdc, 0x4f, 0x34, 0xa7, 0x2a, 0x79, 0xe9,
- 0x38, 0xe5, 0xa5, 0x97, 0x73, 0xec, 0x23, 0xf5, 0x06, 0xfb, 0x88, 0x44,
- 0xb1, 0x76, 0x7d, 0x3a, 0x84, 0x0b, 0x3a, 0x34, 0x37, 0x62, 0x44, 0x77,
- 0xa4, 0xbb, 0x63, 0x0e, 0xf3, 0xb9, 0x28, 0xfe, 0x4f, 0xe5, 0x78, 0xaf,
- 0x4d, 0xa0, 0x46, 0x63, 0x1b, 0xb0, 0x73, 0x01, 0xc5, 0xb4, 0x7e, 0xd4,
- 0xae, 0x06, 0x2e, 0x0d, 0xf1, 0xfe, 0x8c, 0x86, 0x03, 0xa5, 0x01, 0xd1,
- 0x30, 0xf4, 0x5b, 0x2b, 0x54, 0x35, 0xbf, 0x07, 0xf8, 0x30, 0xef, 0x01,
- 0x92, 0x0d, 0xf4, 0xdb, 0xe7, 0x7c, 0xde, 0x4c, 0xf3, 0x39, 0x9f, 0x70,
- 0x68, 0x13, 0xf9, 0x4e, 0x2f, 0x9a, 0xf5, 0x69, 0xc2, 0xce, 0xb3, 0x44,
- 0x67, 0x93, 0xa8, 0xec, 0x73, 0x45, 0xe6, 0xf6, 0xe9, 0x96, 0xe5, 0x3b,
- 0x45, 0x4d, 0x81, 0x69, 0x0a, 0x10, 0x4d, 0x1d, 0xa2, 0xfa, 0xd8, 0x06,
- 0xe1, 0x3b, 0xd6, 0x25, 0xa4, 0x02, 0xc7, 0xe4, 0x3a, 0x63, 0x4f, 0x8e,
- 0xf3, 0xd9, 0x66, 0xe1, 0x3c, 0xba, 0x45, 0x78, 0x0b, 0x3d, 0xc2, 0x7f,
- 0xcc, 0xc4, 0xfd, 0xf1, 0x2e, 0x9c, 0x1b, 0xe6, 0xb3, 0x6c, 0xf7, 0x89,
- 0x9a, 0xb9, 0xbd, 0x39, 0x6f, 0xa1, 0xd1, 0x5f, 0x48, 0x73, 0x7f, 0xf7,
- 0xe3, 0x35, 0xe9, 0xa1, 0x45, 0xfe, 0xa7, 0xc6, 0x02, 0xfe, 0x27, 0xc7,
- 0xd4, 0xfe, 0x7d, 0xc2, 0xb2, 0x76, 0xc6, 0xfe, 0x03, 0xeb, 0xd0, 0x6a,
- 0x8e, 0x55, 0xf0, 0xc1, 0x6e, 0x92, 0xc7, 0x36, 0xca, 0x2d, 0x93, 0x7a,
- 0xf3, 0x1c, 0x16, 0x51, 0x53, 0xfc, 0xee, 0x1b, 0xfd, 0x77, 0x73, 0x6e,
- 0xe3, 0x7d, 0x4d, 0x67, 0x3b, 0x28, 0xee, 0x7e, 0xc6, 0x6b, 0xcd, 0x10,
- 0x9f, 0x51, 0xeb, 0x87, 0xff, 0x4b, 0xf6, 0xf5, 0xce, 0x7d, 0xb6, 0xaf,
- 0x97, 0x78, 0x52, 0xa8, 0xe5, 0x19, 0xe2, 0xb7, 0xca, 0xf1, 0xb9, 0x3d,
- 0xbd, 0xb9, 0xfd, 0xbc, 0x4e, 0xe1, 0x2b, 0x70, 0x7d, 0x1e, 0x30, 0x5e,
- 0x1f, 0xea, 0x10, 0xde, 0x63, 0xc3, 0x94, 0x1f, 0x37, 0x10, 0xcf, 0x7c,
- 0x76, 0xac, 0x4b, 0xf8, 0x0b, 0x9b, 0x85, 0x8f, 0xf8, 0xac, 0x26, 0x3e,
- 0x71, 0xcc, 0x23, 0xbc, 0xc4, 0xa3, 0x87, 0x78, 0xf4, 0xce, 0xf1, 0xe8,
- 0x29, 0x04, 0xfd, 0xe9, 0x74, 0xbd, 0xff, 0xd1, 0x31, 0xc5, 0xbf, 0x6f,
- 0xcc, 0xb2, 0xde, 0xd7, 0x15, 0x3f, 0xf3, 0xf5, 0xaa, 0xfe, 0x45, 0xbe,
- 0x6e, 0x20, 0xbe, 0x2a, 0x7b, 0xb1, 0xa4, 0xc3, 0x14, 0xeb, 0x90, 0xcf,
- 0x71, 0xcc, 0xf3, 0x75, 0x30, 0xcd, 0xfb, 0x95, 0xbc, 0x6f, 0x39, 0x20,
- 0x56, 0x10, 0x5f, 0x65, 0xe2, 0x6b, 0xe5, 0x97, 0xf0, 0xf5, 0xe1, 0x35,
- 0x7c, 0xbd, 0xfa, 0xf7, 0xf2, 0xe5, 0x11, 0xcb, 0x87, 0x39, 0x0e, 0xdd,
- 0x66, 0xc8, 0xc3, 0x16, 0x61, 0x47, 0x07, 0xbe, 0x3f, 0x05, 0x14, 0xb3,
- 0xbb, 0x20, 0x53, 0xbc, 0x39, 0x1d, 0x8f, 0x84, 0x5e, 0xa1, 0x7a, 0x72,
- 0xba, 0xe4, 0x15, 0xcb, 0xec, 0x3d, 0x59, 0xac, 0x90, 0x89, 0xa6, 0x19,
- 0xfb, 0x5d, 0x33, 0xe8, 0xb5, 0x1a, 0xeb, 0x52, 0x3b, 0xbb, 0x15, 0x91,
- 0x72, 0xc4, 0xd1, 0x25, 0x12, 0x05, 0xde, 0x83, 0xdd, 0x22, 0x56, 0xda,
- 0xfb, 0xaf, 0x9d, 0xe2, 0xfa, 0x42, 0x87, 0x68, 0x21, 0xbb, 0x68, 0x3e,
- 0xc6, 0xe7, 0xc1, 0x36, 0x8b, 0xe6, 0x39, 0x79, 0x2c, 0x27, 0x79, 0x0c,
- 0x7d, 0x4e, 0x1e, 0x1b, 0x6c, 0x79, 0xfc, 0x4c, 0xbf, 0x78, 0x4d, 0x0f,
- 0x8d, 0xeb, 0x2a, 0xca, 0x86, 0x54, 0x3b, 0xd5, 0xce, 0xd5, 0x4e, 0x6f,
- 0xc5, 0xf8, 0x9c, 0x8f, 0x69, 0xd5, 0x68, 0x08, 0x39, 0x0d, 0xb5, 0xe7,
- 0xb4, 0xd0, 0x52, 0xf7, 0x89, 0xe4, 0x26, 0x1f, 0xd5, 0x3f, 0x3b, 0x62,
- 0x91, 0xe4, 0x72, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, 0x5d, 0xae, 0x2a,
- 0x9a, 0xd8, 0x47, 0xf1, 0xed, 0xc5, 0x9c, 0x44, 0xd8, 0x81, 0xdf, 0x3f,
- 0x73, 0xe2, 0x46, 0x82, 0x12, 0x4f, 0x10, 0xee, 0x78, 0x3c, 0xdb, 0x87,
- 0x27, 0xf2, 0xbd, 0x78, 0x3c, 0xff, 0x77, 0xde, 0xb5, 0x91, 0xbd, 0x46,
- 0x63, 0xa2, 0x72, 0x16, 0xe1, 0xe3, 0xc4, 0x75, 0x11, 0x96, 0xcd, 0x89,
- 0x16, 0x39, 0xc2, 0xb5, 0xae, 0xf3, 0x77, 0xdf, 0xd5, 0xd8, 0x17, 0x7b,
- 0x56, 0xbd, 0x64, 0x63, 0x91, 0x93, 0x6d, 0xc7, 0xec, 0x33, 0x52, 0xe5,
- 0x95, 0x7b, 0xec, 0x77, 0x41, 0x7d, 0xab, 0xef, 0xd2, 0xd8, 0x1f, 0x4e,
- 0xc4, 0xd7, 0xdb, 0xf9, 0xb5, 0x71, 0x6d, 0xe5, 0x3d, 0x99, 0xe0, 0xda,
- 0x4a, 0xaf, 0x26, 0xb0, 0x36, 0x6a, 0x7f, 0x86, 0xd6, 0x56, 0xf6, 0xba,
- 0xf5, 0xb5, 0x4d, 0xf6, 0x67, 0x74, 0x6d, 0xc5, 0xa7, 0xb4, 0xb5, 0x9a,
- 0xfd, 0x19, 0x5f, 0x5b, 0xc9, 0xcb, 0x2d, 0x6b, 0x97, 0x5e, 0x7d, 0xbf,
- 0x86, 0xff, 0xfe, 0x17, 0x9f, 0xed, 0x4e, 0xb2, 0x20, 0x3b, 0x00, 0x00,
- 0x00 };
+ 0xc5, 0x7b, 0x7d, 0x70, 0x1b, 0xe7, 0x79, 0xe7, 0xef, 0xc5, 0x02, 0xe4,
+ 0x02, 0x04, 0x41, 0x90, 0x82, 0x64, 0xf0, 0xca, 0x44, 0x58, 0x61, 0x41,
+ 0xc1, 0x26, 0x2d, 0x2f, 0x28, 0x50, 0x82, 0xcb, 0x55, 0x85, 0x4a, 0xb4,
+ 0x44, 0xc7, 0x74, 0x43, 0x3b, 0x6a, 0x4b, 0x67, 0x3c, 0x09, 0x2a, 0x51,
+ 0x16, 0x2d, 0xcb, 0x16, 0xed, 0xf8, 0x7a, 0xec, 0x9c, 0x27, 0xda, 0x50,
+ 0x1f, 0x96, 0x25, 0x10, 0x00, 0x3f, 0x64, 0xca, 0x9d, 0xce, 0x19, 0x26,
+ 0x29, 0x51, 0xb6, 0xf1, 0x21, 0xc7, 0x4a, 0x6a, 0xcf, 0x24, 0x11, 0x4e,
+ 0x96, 0x65, 0xd9, 0x89, 0x3f, 0x92, 0xf8, 0x7a, 0x4e, 0xa7, 0x37, 0xd5,
+ 0x48, 0xfe, 0x90, 0x2c, 0xf9, 0xa3, 0x69, 0x6f, 0x2a, 0xb5, 0x4e, 0xf7,
+ 0x9e, 0x67, 0x17, 0x94, 0x15, 0xd7, 0x9d, 0x9b, 0xf6, 0xfe, 0x38, 0xce,
+ 0x70, 0x00, 0xec, 0xbe, 0xfb, 0xbe, 0xcf, 0xf7, 0xf3, 0x7b, 0x9e, 0xf7,
+ 0xdd, 0x56, 0xc0, 0x83, 0xea, 0x5f, 0x3d, 0xfd, 0xc7, 0x87, 0x86, 0x1f,
+ 0x8e, 0x2d, 0x5b, 0xb1, 0x8c, 0xbe, 0x76, 0xa2, 0xa1, 0xc6, 0xc9, 0x37,
+ 0x57, 0x08, 0x20, 0xf5, 0x21, 0xfe, 0x43, 0x7f, 0x5f, 0xf9, 0x8f, 0x3d,
+ 0x66, 0xfd, 0x49, 0x80, 0x7f, 0x9e, 0x2e, 0xfe, 0x87, 0xec, 0xd0, 0x93,
+ 0x5d, 0x6b, 0x54, 0xc8, 0x92, 0x7e, 0x79, 0xd5, 0x26, 0x15, 0x48, 0x16,
+ 0xda, 0x42, 0x6b, 0xf1, 0x1b, 0xd3, 0x08, 0x38, 0xc1, 0xd7, 0xbf, 0xa2,
+ 0x7f, 0xb6, 0xe3, 0xc7, 0x2b, 0x95, 0x4f, 0xf3, 0x12, 0x64, 0xbf, 0x7e,
+ 0x10, 0xfe, 0x56, 0xc8, 0x2d, 0xf4, 0xcc, 0x5f, 0x2c, 0x2d, 0x39, 0xe1,
+ 0x9b, 0x9f, 0x0b, 0x86, 0x4b, 0xd7, 0xb0, 0x33, 0x3b, 0x84, 0x23, 0x71,
+ 0xa0, 0x76, 0x34, 0xa2, 0xed, 0x04, 0x72, 0x0e, 0x3d, 0x12, 0x3a, 0x81,
+ 0x10, 0x66, 0x0b, 0x2a, 0x1e, 0x2d, 0xc3, 0x70, 0xea, 0x21, 0x3c, 0x96,
+ 0xfe, 0x17, 0x33, 0xe4, 0xe2, 0x47, 0x86, 0xb0, 0x8b, 0xc6, 0xee, 0x4e,
+ 0x43, 0x0e, 0xea, 0x8f, 0x20, 0x98, 0x85, 0x5c, 0xaf, 0x0f, 0xa3, 0x38,
+ 0x1a, 0x3e, 0x3d, 0x07, 0xa5, 0xaf, 0x59, 0x52, 0x86, 0x80, 0xb6, 0xd4,
+ 0x5d, 0x42, 0xe9, 0x2f, 0x09, 0x25, 0xb1, 0x4d, 0x40, 0x16, 0x34, 0xee,
+ 0x86, 0x02, 0x7f, 0x0e, 0x63, 0x69, 0x41, 0xc6, 0x19, 0x89, 0xe7, 0x59,
+ 0x45, 0xf2, 0x16, 0x70, 0xaa, 0x1a, 0x76, 0x67, 0x79, 0x0d, 0x81, 0x9d,
+ 0xf1, 0x88, 0x7f, 0x06, 0x7c, 0x3f, 0x84, 0x11, 0x6b, 0x9c, 0x42, 0x5c,
+ 0x9b, 0xe6, 0x2e, 0xcd, 0x34, 0x0f, 0x69, 0xb5, 0x30, 0xfc, 0x4a, 0x10,
+ 0x10, 0x18, 0xd1, 0x1c, 0x48, 0xfa, 0xd7, 0x84, 0x9c, 0x50, 0x82, 0x9b,
+ 0xf1, 0xcf, 0xc4, 0x73, 0x32, 0xea, 0x82, 0x3d, 0x3e, 0x85, 0x5a, 0x54,
+ 0xfc, 0xb6, 0xd4, 0xa6, 0xd3, 0xa6, 0x79, 0x4a, 0x75, 0xe2, 0x10, 0xc9,
+ 0x67, 0xa4, 0xf0, 0xcf, 0x66, 0x85, 0x64, 0xb3, 0x4b, 0x9d, 0x5f, 0x5f,
+ 0x46, 0xde, 0x6f, 0x9a, 0x33, 0x74, 0x6f, 0x4f, 0x61, 0x5e, 0xce, 0xa6,
+ 0xe9, 0x50, 0x4d, 0x73, 0x93, 0xfa, 0x4f, 0xe6, 0xc6, 0xdf, 0x1a, 0x1b,
+ 0xc3, 0x33, 0x39, 0x3f, 0x9e, 0xcd, 0x26, 0x51, 0x48, 0x9b, 0x90, 0x74,
+ 0x27, 0x06, 0x47, 0x43, 0xd8, 0x56, 0xec, 0x46, 0x31, 0xad, 0xa4, 0xce,
+ 0xd0, 0x73, 0x1b, 0xe3, 0x2a, 0xee, 0x2f, 0xf6, 0x60, 0x2e, 0x0d, 0xd3,
+ 0xad, 0xab, 0x15, 0xb7, 0x88, 0x62, 0x4b, 0xb1, 0x17, 0xa5, 0xb4, 0x7a,
+ 0x7a, 0x44, 0x44, 0x86, 0x9b, 0x25, 0x27, 0xb6, 0x17, 0xdb, 0xf1, 0x40,
+ 0x31, 0x41, 0xcf, 0x98, 0xf8, 0x5a, 0xac, 0x85, 0xc6, 0x77, 0xe0, 0xe9,
+ 0x49, 0xd3, 0x8c, 0xc6, 0xfc, 0x18, 0x2c, 0x6a, 0x98, 0xcb, 0x39, 0x90,
+ 0x3a, 0xe4, 0x44, 0xea, 0x29, 0x60, 0xcb, 0x53, 0x1d, 0x98, 0xc9, 0x99,
+ 0xd8, 0xa8, 0x8d, 0x34, 0x3b, 0xe0, 0x42, 0xca, 0x2f, 0xe0, 0x52, 0x7d,
+ 0xd8, 0xec, 0xb7, 0x69, 0x3f, 0x23, 0x09, 0x6c, 0x7d, 0x2a, 0x8a, 0x77,
+ 0xd2, 0x06, 0xbe, 0xd6, 0x19, 0xc4, 0x70, 0x31, 0x80, 0x37, 0xd3, 0x01,
+ 0x5a, 0x43, 0xc3, 0x1b, 0x69, 0x99, 0xd6, 0x69, 0xc7, 0xc9, 0x34, 0x8f,
+ 0xe1, 0xb1, 0x5e, 0x0c, 0x14, 0x5b, 0xf0, 0x7a, 0x3a, 0x48, 0x6b, 0x06,
+ 0xf0, 0x2a, 0x8d, 0xbb, 0xb7, 0xa8, 0xe2, 0x34, 0x8d, 0x1b, 0x2c, 0x86,
+ 0xf0, 0x4a, 0xda, 0x4b, 0xb4, 0x06, 0x70, 0x22, 0x3d, 0x84, 0x9d, 0xe9,
+ 0xb6, 0xd3, 0x6b, 0x49, 0x86, 0xa1, 0x05, 0xbc, 0x0e, 0x5f, 0x7b, 0xd7,
+ 0xec, 0x0d, 0x58, 0xa6, 0x42, 0xeb, 0xcc, 0xaf, 0x3b, 0x84, 0x91, 0xf4,
+ 0xa9, 0xaa, 0xbf, 0x68, 0x78, 0x2c, 0x77, 0xd9, 0xfc, 0xf1, 0xd2, 0x16,
+ 0x1c, 0xc9, 0x02, 0x4f, 0xcf, 0x00, 0x33, 0x59, 0xc3, 0xac, 0xd7, 0x4d,
+ 0x73, 0xba, 0xb3, 0x9d, 0xe4, 0xa5, 0xf6, 0x6f, 0xa4, 0x51, 0xcf, 0x96,
+ 0x9d, 0xc0, 0x53, 0x4a, 0x7f, 0x05, 0x0e, 0xe4, 0xe7, 0x9c, 0xa8, 0x19,
+ 0x55, 0x7a, 0xf2, 0x50, 0x4e, 0x6f, 0x21, 0x8f, 0x3a, 0x94, 0x55, 0xfa,
+ 0x0c, 0xec, 0x30, 0x83, 0x7a, 0x6b, 0xa8, 0x5d, 0x32, 0xe1, 0x23, 0x5b,
+ 0x48, 0xb7, 0x9b, 0x66, 0xc3, 0x4a, 0xd3, 0x7c, 0xbd, 0x13, 0xa6, 0x43,
+ 0x57, 0x4f, 0x97, 0xa1, 0x56, 0x3e, 0x82, 0x3a, 0x7c, 0x02, 0x95, 0xaf,
+ 0x78, 0x11, 0x19, 0x0c, 0x4b, 0x91, 0xa1, 0xcb, 0xf4, 0x6c, 0x7d, 0x91,
+ 0xcc, 0x99, 0x78, 0x51, 0x47, 0x81, 0x62, 0x59, 0x86, 0x93, 0xf8, 0x69,
+ 0x1f, 0x35, 0x4d, 0xa7, 0xea, 0x85, 0x97, 0xe4, 0xbb, 0xfe, 0x80, 0x69,
+ 0xbe, 0xaf, 0xf9, 0x51, 0x43, 0xba, 0xb9, 0x65, 0xcc, 0xc4, 0xb4, 0x76,
+ 0x82, 0xe4, 0x29, 0x90, 0xea, 0x8b, 0xd3, 0x33, 0x01, 0x1a, 0x9f, 0xc0,
+ 0xfa, 0xd1, 0x20, 0x9e, 0xc9, 0xca, 0xf8, 0xf1, 0xd2, 0x28, 0xea, 0x68,
+ 0x2e, 0x0f, 0xc9, 0xaa, 0x96, 0xe4, 0x87, 0x22, 0x99, 0x5b, 0xd1, 0xb6,
+ 0x47, 0x14, 0xcf, 0x10, 0x8f, 0x41, 0x7c, 0xbf, 0x1c, 0xc0, 0x73, 0x65,
+ 0x3f, 0x8e, 0x96, 0x5b, 0x70, 0xbc, 0xac, 0xe1, 0x60, 0x4e, 0xd9, 0x5b,
+ 0x81, 0x89, 0x7a, 0x7d, 0x07, 0x1a, 0x96, 0x03, 0x6f, 0xe6, 0x63, 0xc8,
+ 0xe4, 0x4c, 0xb3, 0x40, 0x74, 0x7b, 0x88, 0x8f, 0x37, 0xf2, 0x5f, 0xc5,
+ 0xe1, 0x49, 0x27, 0x42, 0xd3, 0x01, 0x3c, 0x9b, 0x76, 0xe2, 0xfa, 0x8c,
+ 0x62, 0xe4, 0xa1, 0x46, 0xb7, 0x09, 0x35, 0x79, 0x83, 0x50, 0x72, 0x06,
+ 0x22, 0x21, 0x97, 0x70, 0xa0, 0xf5, 0xb0, 0x13, 0x6a, 0x29, 0x04, 0x57,
+ 0xab, 0x0c, 0xb5, 0xf5, 0x21, 0xc0, 0xe7, 0x40, 0x0d, 0xf9, 0xc6, 0xfa,
+ 0xf1, 0x28, 0x5d, 0x0b, 0xd0, 0x35, 0x7c, 0xb5, 0x16, 0xd2, 0x22, 0x09,
+ 0x24, 0x3b, 0x55, 0x42, 0xd2, 0x69, 0x9a, 0x92, 0xda, 0x81, 0xbb, 0x1e,
+ 0x37, 0xcd, 0xf0, 0x72, 0x1e, 0xef, 0x47, 0xb8, 0x44, 0x72, 0x68, 0x25,
+ 0xba, 0xb2, 0x44, 0x67, 0x96, 0xe8, 0xcc, 0x12, 0x9d, 0x59, 0x89, 0xec,
+ 0x46, 0xd1, 0x80, 0x47, 0x48, 0x5f, 0x21, 0xe2, 0xf1, 0x1d, 0x4b, 0x57,
+ 0xcf, 0x95, 0x83, 0xc4, 0x43, 0xc8, 0xe2, 0xe1, 0xe9, 0x9c, 0x80, 0x43,
+ 0x55, 0xfa, 0xce, 0x60, 0x35, 0xc2, 0x31, 0x25, 0x99, 0x47, 0x92, 0x9e,
+ 0x53, 0xf6, 0x1a, 0x50, 0x7a, 0x2a, 0x64, 0x03, 0x1b, 0xfd, 0x09, 0xcc,
+ 0x65, 0x5d, 0xa8, 0x53, 0x95, 0x10, 0xe9, 0x2c, 0x5a, 0xc1, 0x02, 0xdc,
+ 0xe7, 0xa7, 0x39, 0x1d, 0xb2, 0xb0, 0x63, 0xc9, 0x23, 0x88, 0x8c, 0x3b,
+ 0x30, 0xab, 0x49, 0xe4, 0xa3, 0x1a, 0xa4, 0x56, 0x5a, 0xae, 0x14, 0xa7,
+ 0x4f, 0x9a, 0x3f, 0x4b, 0x6b, 0x11, 0x3d, 0x34, 0x1f, 0xf9, 0x26, 0xcb,
+ 0x32, 0x4a, 0x34, 0x3c, 0x6a, 0xd1, 0x7b, 0xb4, 0xfc, 0x75, 0x61, 0xdb,
+ 0x90, 0x4e, 0x36, 0xa3, 0x84, 0x20, 0x94, 0x68, 0x48, 0x28, 0x5a, 0x52,
+ 0xf8, 0x31, 0x53, 0x7e, 0x83, 0xc6, 0x04, 0xae, 0x19, 0xd3, 0x87, 0x91,
+ 0xac, 0xc0, 0x5a, 0xd5, 0xc4, 0x1a, 0xad, 0x0f, 0x3b, 0xcb, 0xf3, 0xbe,
+ 0xc9, 0x31, 0xcc, 0xef, 0x9b, 0x49, 0x77, 0x63, 0x57, 0x36, 0x84, 0x9d,
+ 0x85, 0xa0, 0x6f, 0x3a, 0xcd, 0xf7, 0x54, 0xf2, 0x79, 0xbe, 0x17, 0xb8,
+ 0xe6, 0x5e, 0xcb, 0x35, 0xf7, 0x12, 0x18, 0x99, 0xf8, 0x1d, 0x8a, 0x23,
+ 0x0d, 0xd8, 0xa9, 0x7e, 0x4a, 0xf6, 0xa2, 0x26, 0x06, 0xd0, 0x8c, 0x33,
+ 0xfe, 0x76, 0xec, 0x9f, 0xea, 0xc5, 0xae, 0xa9, 0x65, 0x78, 0x6c, 0xa2,
+ 0x25, 0xe5, 0xd1, 0x49, 0x38, 0x9e, 0x70, 0x72, 0x40, 0x28, 0x43, 0x92,
+ 0x08, 0x47, 0x07, 0xc8, 0x7e, 0x5b, 0x1b, 0x4d, 0xf3, 0x44, 0x8c, 0xec,
+ 0x5b, 0x6b, 0xd3, 0xd6, 0x93, 0x00, 0x2a, 0x7d, 0x4a, 0xcf, 0xbb, 0xf0,
+ 0xe2, 0x76, 0xb2, 0xbb, 0x99, 0x18, 0x06, 0x24, 0x48, 0xed, 0x5e, 0xfc,
+ 0xbd, 0xf9, 0x94, 0x93, 0xe5, 0x6e, 0xee, 0xd8, 0xa4, 0xed, 0x15, 0x1c,
+ 0xeb, 0x6a, 0xae, 0xc6, 0x13, 0x9e, 0x9f, 0x9f, 0x21, 0xdd, 0xd1, 0x3c,
+ 0x83, 0xb1, 0xb6, 0xc4, 0x20, 0x2e, 0x9b, 0x67, 0x36, 0xf4, 0x62, 0xe7,
+ 0xdc, 0x32, 0xec, 0x9b, 0x70, 0x21, 0xd9, 0x28, 0xd0, 0xa0, 0x86, 0x2b,
+ 0xf7, 0x61, 0x19, 0x8c, 0x19, 0x7e, 0xae, 0x17, 0x07, 0xe7, 0xec, 0xdf,
+ 0xd9, 0xab, 0xbf, 0xe7, 0xe7, 0x3b, 0x4f, 0x3a, 0x65, 0x79, 0x72, 0xac,
+ 0x24, 0x15, 0xe8, 0x6d, 0x38, 0x32, 0x11, 0x20, 0xdd, 0x76, 0x0b, 0xe7,
+ 0xe1, 0x45, 0x3e, 0xcf, 0xe3, 0x26, 0x4e, 0x69, 0xa4, 0xe7, 0xec, 0x3a,
+ 0xe1, 0x39, 0xdc, 0x23, 0x5c, 0xa5, 0x3b, 0x45, 0xcd, 0xf4, 0x37, 0x85,
+ 0x7c, 0x38, 0x25, 0x6a, 0x4b, 0xed, 0x24, 0xfb, 0x7e, 0xe1, 0x3e, 0xac,
+ 0x84, 0x42, 0xe2, 0x11, 0xd2, 0xe7, 0x06, 0x21, 0x95, 0xe0, 0x77, 0xe8,
+ 0xc3, 0xc2, 0x51, 0xa2, 0x39, 0x2c, 0x1b, 0xe2, 0x75, 0x82, 0xa4, 0x37,
+ 0x18, 0x92, 0x3e, 0x84, 0x8d, 0x14, 0xff, 0x6f, 0x4d, 0xeb, 0x78, 0x34,
+ 0x5b, 0x4b, 0x31, 0x92, 0x7d, 0xff, 0x32, 0xad, 0xab, 0xe2, 0x31, 0xca,
+ 0x15, 0xb2, 0xbe, 0x0f, 0x3e, 0xf2, 0xb9, 0xd7, 0x63, 0xec, 0x8f, 0x40,
+ 0x21, 0x1b, 0xee, 0x7f, 0x54, 0x98, 0xe6, 0xd6, 0x88, 0xb9, 0x78, 0x5d,
+ 0xac, 0x2d, 0x7a, 0x12, 0xff, 0x68, 0xe6, 0x03, 0x43, 0xa8, 0xef, 0xa4,
+ 0x7b, 0xa3, 0x90, 0x5d, 0xfa, 0x2e, 0x1c, 0xa2, 0x5c, 0xe2, 0xd1, 0x29,
+ 0xbe, 0x8c, 0x86, 0xfb, 0x1f, 0x13, 0x1c, 0xf3, 0x95, 0xca, 0xb3, 0x18,
+ 0x39, 0x5d, 0x0b, 0x25, 0xb4, 0x46, 0xb4, 0x69, 0x75, 0x92, 0x91, 0x68,
+ 0xa6, 0x14, 0xe7, 0xee, 0x54, 0x86, 0xf7, 0x40, 0xf1, 0x5f, 0x00, 0xfb,
+ 0x2a, 0xe7, 0x93, 0x5d, 0x48, 0x58, 0x79, 0xc5, 0xc0, 0x4d, 0x57, 0xf3,
+ 0x8a, 0x4e, 0x76, 0x52, 0x8b, 0x3d, 0x44, 0xd7, 0xcb, 0x9a, 0x12, 0x9c,
+ 0x86, 0xb9, 0x78, 0x40, 0xe3, 0x7b, 0x3a, 0x76, 0x95, 0xcd, 0x90, 0xa4,
+ 0xb3, 0xac, 0x90, 0xaa, 0xd5, 0x99, 0x56, 0x3f, 0xf9, 0xc6, 0x6f, 0xcc,
+ 0x81, 0xb8, 0xac, 0xbd, 0x57, 0xf0, 0x93, 0xbc, 0xe0, 0x73, 0x16, 0xbf,
+ 0x2c, 0xff, 0x9a, 0x70, 0xe8, 0xbf, 0x31, 0xbf, 0x1d, 0x87, 0x6f, 0x71,
+ 0xd1, 0x99, 0xaa, 0xd3, 0xd1, 0x37, 0x3c, 0xba, 0xc3, 0x6c, 0x56, 0x1d,
+ 0x14, 0xab, 0x54, 0x8a, 0xed, 0xde, 0xc4, 0xa5, 0x4e, 0xb7, 0x78, 0xbd,
+ 0x33, 0xd8, 0xfb, 0x51, 0xc1, 0x4d, 0x7a, 0x46, 0xdf, 0xb6, 0x62, 0xc2,
+ 0xf9, 0x21, 0xd9, 0x5a, 0x0d, 0xc5, 0x55, 0x14, 0x5b, 0x7a, 0x2f, 0x50,
+ 0x2e, 0xba, 0x25, 0xe6, 0xfe, 0xe3, 0x1a, 0xdd, 0xf1, 0x55, 0x37, 0x1e,
+ 0xbc, 0x69, 0x36, 0xd1, 0x40, 0xb1, 0xdd, 0x8f, 0xd3, 0xf1, 0x1e, 0x8c,
+ 0x94, 0x6b, 0xc9, 0x0e, 0x9f, 0xaf, 0xec, 0x56, 0x5b, 0x7a, 0x2f, 0xa6,
+ 0x17, 0x53, 0x2c, 0xc1, 0x67, 0x85, 0x4e, 0xb5, 0x6f, 0x9b, 0x38, 0x71,
+ 0xab, 0x07, 0x71, 0x92, 0xab, 0x2c, 0x5f, 0x49, 0xe3, 0xd3, 0xc5, 0xaa,
+ 0x5a, 0x59, 0x2d, 0xb5, 0x0e, 0xc9, 0x52, 0xeb, 0x70, 0x0d, 0xc5, 0xe1,
+ 0xf3, 0x37, 0x0a, 0x9c, 0xba, 0x31, 0x92, 0xa8, 0x11, 0x6e, 0x9c, 0xe9,
+ 0x4b, 0x90, 0x9d, 0xb4, 0xa4, 0xdc, 0x3a, 0xc5, 0x8f, 0x51, 0x01, 0x49,
+ 0x4d, 0x60, 0xe7, 0x0c, 0x1e, 0x19, 0xd1, 0x7a, 0x61, 0xcc, 0xb1, 0x0d,
+ 0xb5, 0x63, 0x64, 0xae, 0x0f, 0x46, 0x59, 0x42, 0x3e, 0x40, 0xcc, 0x97,
+ 0x91, 0x72, 0xe9, 0xed, 0xdd, 0xf9, 0xc2, 0x5d, 0x2e, 0xdb, 0x87, 0x89,
+ 0xff, 0xec, 0xa4, 0x0f, 0x1e, 0xd6, 0xf3, 0x69, 0x92, 0x51, 0x3b, 0x9e,
+ 0x2f, 0x47, 0x29, 0xde, 0x69, 0x24, 0x17, 0x95, 0xe2, 0x45, 0x88, 0xec,
+ 0x4b, 0xc6, 0xc6, 0x09, 0xe5, 0x20, 0xc5, 0x85, 0x5c, 0x9e, 0x40, 0x51,
+ 0x32, 0xe0, 0xa7, 0xfc, 0xfd, 0x6a, 0x35, 0x06, 0x0c, 0xd2, 0xa7, 0x62,
+ 0x24, 0x81, 0x93, 0x0e, 0xa0, 0xa3, 0x59, 0x8f, 0xec, 0x6d, 0x26, 0x7d,
+ 0x34, 0x96, 0xdc, 0xd8, 0x3e, 0xd1, 0x84, 0x07, 0xa6, 0x3c, 0xd8, 0x3a,
+ 0x61, 0xe2, 0x52, 0x8c, 0x6d, 0x43, 0xe9, 0x27, 0x12, 0xbb, 0xeb, 0x48,
+ 0xae, 0xb7, 0xc6, 0x22, 0x09, 0xb7, 0x70, 0xa2, 0xb6, 0xd4, 0x47, 0x38,
+ 0x20, 0xc9, 0x7e, 0xa1, 0xd1, 0x1c, 0xa1, 0x9d, 0xda, 0xed, 0x48, 0x05,
+ 0x64, 0xb8, 0x4a, 0x5e, 0x8a, 0x25, 0xec, 0xc7, 0x7c, 0xef, 0xeb, 0xd8,
+ 0x58, 0xe3, 0x85, 0x94, 0x91, 0x91, 0x23, 0x0c, 0x80, 0x45, 0x35, 0xe8,
+ 0x69, 0x75, 0xd0, 0x7f, 0xc0, 0x37, 0x3b, 0xd9, 0xe2, 0x3b, 0x44, 0xf1,
+ 0x75, 0x4b, 0xd6, 0xc1, 0xeb, 0x30, 0x66, 0xa0, 0xb9, 0xfd, 0x78, 0x9a,
+ 0xe2, 0xf5, 0x43, 0x14, 0x7f, 0x8e, 0x94, 0xcb, 0x82, 0xe3, 0x89, 0xc5,
+ 0x4f, 0x96, 0x78, 0xcb, 0x12, 0x6f, 0x59, 0xe2, 0x8b, 0xe2, 0xc2, 0xd1,
+ 0x2c, 0xf3, 0xf1, 0x6b, 0xf2, 0xd1, 0x04, 0xf1, 0xee, 0xc6, 0x66, 0xa2,
+ 0xf7, 0xc1, 0xa9, 0x3a, 0x6c, 0x23, 0x7a, 0x8b, 0x9a, 0xa2, 0x3d, 0x27,
+ 0x4c, 0xec, 0x8f, 0x29, 0xc6, 0x4f, 0x29, 0x10, 0x39, 0x5a, 0x4d, 0xb3,
+ 0x4f, 0x63, 0x9e, 0x29, 0x5e, 0x39, 0x2c, 0x9e, 0xf7, 0x26, 0xe1, 0xc6,
+ 0x20, 0x3d, 0x33, 0x30, 0x85, 0xcf, 0x1c, 0xc4, 0x93, 0x9b, 0x78, 0xdc,
+ 0xa7, 0x29, 0x89, 0x1b, 0x28, 0xae, 0x9f, 0x53, 0x23, 0x95, 0x73, 0x12,
+ 0x7e, 0x9f, 0xe4, 0x31, 0xcc, 0xf2, 0xb8, 0x89, 0xf8, 0x79, 0x80, 0xf0,
+ 0x4e, 0x3d, 0xc5, 0xa5, 0xc2, 0x81, 0x48, 0xf4, 0x97, 0xc4, 0x7b, 0xa4,
+ 0x44, 0xb4, 0x8f, 0xda, 0xb4, 0xdf, 0xc7, 0xb4, 0xc7, 0x4c, 0xdc, 0x43,
+ 0xb4, 0x1f, 0x26, 0xda, 0x07, 0xb3, 0x2c, 0x0f, 0xce, 0x3b, 0x36, 0xfd,
+ 0x47, 0xca, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x13, 0x36, 0x4e,
+ 0xcd, 0xcb, 0xcb, 0x34, 0xbf, 0xad, 0x1d, 0x33, 0xff, 0x84, 0x64, 0xb6,
+ 0xb8, 0xc4, 0x72, 0x83, 0x51, 0xab, 0x47, 0x0e, 0x6e, 0xc1, 0x7d, 0x0e,
+ 0x78, 0xbc, 0x58, 0x50, 0xe2, 0x5c, 0x10, 0xc2, 0x31, 0xd2, 0xef, 0x71,
+ 0xca, 0x67, 0xcf, 0x97, 0xaf, 0xcd, 0x6f, 0xac, 0xeb, 0x49, 0xd2, 0xb1,
+ 0x92, 0x37, 0x28, 0xb6, 0xa5, 0xca, 0x49, 0xec, 0x9e, 0x42, 0x72, 0x56,
+ 0xfb, 0x6f, 0x14, 0x60, 0x16, 0x91, 0x7d, 0xd5, 0x26, 0xfd, 0xaa, 0x07,
+ 0x9b, 0x66, 0x02, 0x18, 0x2a, 0xaf, 0x41, 0x96, 0xe2, 0xcd, 0x36, 0x8a,
+ 0xcf, 0x1f, 0xc7, 0x92, 0x5b, 0x7d, 0x88, 0x90, 0x7e, 0x03, 0xb8, 0x8f,
+ 0x9e, 0xd9, 0x37, 0xc5, 0x3c, 0xf8, 0xab, 0x7a, 0x0e, 0x60, 0x0b, 0x5d,
+ 0xdb, 0x33, 0x25, 0xe3, 0x25, 0xed, 0x49, 0xc2, 0x34, 0x36, 0xc6, 0xb8,
+ 0x27, 0x0b, 0x3f, 0xb9, 0x27, 0x61, 0xc0, 0x48, 0xf4, 0x25, 0xfa, 0xbd,
+ 0xb9, 0xec, 0xf1, 0x8d, 0x4c, 0xe2, 0x7b, 0x8b, 0x75, 0x1f, 0x16, 0x10,
+ 0x1e, 0xbb, 0x4b, 0x8b, 0x90, 0xdd, 0x3b, 0x31, 0x5c, 0x76, 0xe0, 0x3b,
+ 0x33, 0x1e, 0x3c, 0x34, 0xf1, 0x99, 0x59, 0x13, 0x77, 0xe2, 0x8e, 0x56,
+ 0x0f, 0x1e, 0x9c, 0x49, 0x62, 0xef, 0x14, 0x42, 0xb5, 0xb1, 0x31, 0x8a,
+ 0xdd, 0x76, 0x3e, 0xa8, 0x23, 0xde, 0x1f, 0x9b, 0xf2, 0xfa, 0x06, 0x0f,
+ 0xb0, 0x0c, 0xd6, 0x04, 0xdd, 0x40, 0xa5, 0x36, 0x26, 0x61, 0xb3, 0x26,
+ 0x2d, 0xa8, 0x25, 0x43, 0x7f, 0x92, 0xe6, 0x9b, 0x86, 0xf4, 0xda, 0x62,
+ 0x44, 0x0e, 0x36, 0x4b, 0x95, 0xdc, 0x02, 0x34, 0xe1, 0xa1, 0xb9, 0x24,
+ 0xc6, 0xc8, 0x46, 0xb7, 0x4f, 0x8c, 0x7c, 0xaf, 0x91, 0x62, 0x88, 0xaf,
+ 0x43, 0x19, 0x7c, 0x53, 0xe8, 0x28, 0x44, 0xdc, 0xd8, 0x36, 0xe3, 0xf5,
+ 0x6d, 0x3d, 0x60, 0xae, 0x66, 0x7b, 0xba, 0x77, 0xae, 0x09, 0xf7, 0x4f,
+ 0xd1, 0xb5, 0x09, 0xb6, 0x61, 0xb2, 0xb5, 0x48, 0x2d, 0xf1, 0x16, 0x4e,
+ 0xba, 0x09, 0x33, 0x49, 0xb1, 0x3a, 0x92, 0x87, 0x1b, 0x5b, 0x2c, 0x5b,
+ 0xf0, 0x63, 0xf3, 0x94, 0x89, 0xb3, 0x5a, 0x14, 0x39, 0xb2, 0xeb, 0x83,
+ 0x53, 0xca, 0xe5, 0x6e, 0xc2, 0x3b, 0xef, 0x49, 0xca, 0xc1, 0x56, 0x29,
+ 0x89, 0xa6, 0xe5, 0x14, 0xe3, 0x9b, 0x4c, 0xf3, 0x9e, 0x8e, 0xb6, 0xa1,
+ 0xb7, 0x88, 0xe6, 0x46, 0x7d, 0x11, 0x2a, 0x8d, 0x4a, 0x8e, 0xb0, 0xf3,
+ 0x70, 0x8d, 0xe3, 0x46, 0x9c, 0x59, 0x48, 0x7a, 0x06, 0xc7, 0xf2, 0x80,
+ 0xaf, 0x29, 0x63, 0xe7, 0xb8, 0x26, 0xb2, 0x93, 0xc6, 0x4c, 0xd0, 0xd7,
+ 0x58, 0x82, 0xaf, 0xa6, 0x04, 0xbc, 0x40, 0xf1, 0x65, 0xc1, 0xf2, 0xdf,
+ 0x98, 0xa9, 0x26, 0x0b, 0x13, 0xfa, 0x5e, 0x9c, 0x54, 0x8c, 0x0a, 0x94,
+ 0xbd, 0x14, 0x2a, 0xf1, 0xc4, 0x9c, 0xd3, 0x77, 0x98, 0xf0, 0x5f, 0x93,
+ 0x1a, 0xc5, 0x1e, 0xd2, 0xe7, 0x0e, 0xb2, 0x85, 0xbf, 0x27, 0x7c, 0xf2,
+ 0x58, 0x26, 0x1c, 0xd2, 0x44, 0x3f, 0x4d, 0x0c, 0xec, 0x2a, 0x51, 0xcc,
+ 0x77, 0xac, 0xa5, 0x20, 0xa6, 0x44, 0x29, 0xad, 0x21, 0x9d, 0x71, 0xc1,
+ 0x58, 0x68, 0xeb, 0xe4, 0xfe, 0xec, 0x71, 0xd3, 0xa7, 0xaa, 0xf9, 0x12,
+ 0xe9, 0xec, 0xe1, 0xb2, 0x17, 0xc3, 0x84, 0x07, 0x16, 0x10, 0x8e, 0x7c,
+ 0x90, 0xec, 0x62, 0xfb, 0x84, 0x44, 0xf4, 0xf1, 0xb8, 0x24, 0x92, 0x8b,
+ 0x6c, 0x3c, 0xfa, 0xd0, 0x0c, 0xdb, 0x25, 0xd9, 0x11, 0xd9, 0xe2, 0x31,
+ 0xca, 0xf9, 0xcf, 0xff, 0x16, 0x06, 0x51, 0xfc, 0xc6, 0xd5, 0xdc, 0x6f,
+ 0xcb, 0x63, 0x64, 0x8a, 0x79, 0x56, 0x0e, 0xc2, 0x91, 0xc4, 0x2d, 0xda,
+ 0xaf, 0x28, 0x27, 0x30, 0xef, 0x84, 0x83, 0xa7, 0xa2, 0x94, 0x57, 0x08,
+ 0xdb, 0xc4, 0x2e, 0x99, 0x5b, 0x02, 0x2c, 0x03, 0xe6, 0xe7, 0x66, 0x89,
+ 0xf3, 0x67, 0x13, 0xe1, 0xdf, 0xff, 0x77, 0xbb, 0xdb, 0x64, 0xa6, 0x2c,
+ 0x3c, 0x4b, 0x38, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0x34, 0xcf,
+ 0x04, 0x38, 0x5f, 0x37, 0x21, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x58,
+ 0xeb, 0xd8, 0xf9, 0xa0, 0x1f, 0x6c, 0x0f, 0xd1, 0x6b, 0xec, 0xc1, 0x43,
+ 0x34, 0xf9, 0xb1, 0x75, 0x8e, 0xed, 0xd7, 0xfc, 0x64, 0xb1, 0xfe, 0x2f,
+ 0xe6, 0x95, 0x95, 0xea, 0xc1, 0x5f, 0xe1, 0xeb, 0x74, 0x3d, 0x80, 0xef,
+ 0x90, 0x1f, 0xdd, 0x47, 0x7c, 0x6e, 0xed, 0x7c, 0xc0, 0xf2, 0xdb, 0xad,
+ 0xe5, 0xdf, 0xa3, 0xeb, 0x2c, 0xef, 0x6e, 0x8a, 0x73, 0x1a, 0xf6, 0x65,
+ 0x2b, 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x4b, 0x8a, 0xb3, 0xc7, 0xca,
+ 0x8c, 0xc9, 0x12, 0x16, 0x1e, 0xfb, 0x61, 0xb9, 0x1d, 0x3f, 0x20, 0x9f,
+ 0x7c, 0x9e, 0x62, 0xee, 0xf7, 0x2d, 0x9c, 0xe6, 0x14, 0x8f, 0xa6, 0x55,
+ 0x3c, 0x4d, 0x58, 0x7f, 0x5f, 0x21, 0x84, 0x23, 0xe9, 0xf0, 0xde, 0x0b,
+ 0x50, 0x5e, 0x20, 0x79, 0xf9, 0xf6, 0x52, 0x8d, 0x76, 0x38, 0xad, 0xe4,
+ 0x81, 0xa0, 0x6f, 0x4f, 0xc1, 0xef, 0x1b, 0x49, 0x07, 0x7c, 0x23, 0x84,
+ 0x81, 0x76, 0xa6, 0x5b, 0x7c, 0x3b, 0x0b, 0xcb, 0x11, 0x6a, 0x82, 0xb1,
+ 0x88, 0x72, 0xc2, 0x7d, 0x13, 0x1b, 0x90, 0x6a, 0xb4, 0xe3, 0xfc, 0x03,
+ 0x53, 0x1c, 0x83, 0xdb, 0x52, 0x37, 0x3a, 0xbe, 0x5e, 0xd5, 0xb7, 0x1f,
+ 0x43, 0x74, 0xad, 0xa1, 0x03, 0xbe, 0x37, 0xad, 0x58, 0x0b, 0x3c, 0x4f,
+ 0xb6, 0xf5, 0x50, 0xc7, 0x6f, 0xcc, 0x64, 0xd5, 0xb6, 0x7e, 0x30, 0xe9,
+ 0xa4, 0xf8, 0x6a, 0x9a, 0x47, 0x3b, 0x04, 0x02, 0x1d, 0xdd, 0x30, 0x9a,
+ 0xe6, 0x6b, 0xc8, 0x64, 0xbe, 0xb9, 0x83, 0x22, 0x94, 0x7a, 0x0b, 0x12,
+ 0x0b, 0x28, 0xb5, 0x74, 0xac, 0xae, 0xde, 0x93, 0xf1, 0x9d, 0x09, 0x37,
+ 0x52, 0x4d, 0x7e, 0xcc, 0x12, 0x36, 0xd9, 0x68, 0xc5, 0xa2, 0xb6, 0xd3,
+ 0xc7, 0xa9, 0x96, 0x09, 0x7d, 0xc3, 0x4f, 0xbc, 0x26, 0x21, 0x77, 0x10,
+ 0x90, 0xa8, 0xd2, 0xc4, 0xbf, 0x73, 0x73, 0x51, 0xec, 0x2e, 0xff, 0xd8,
+ 0x61, 0xe7, 0x13, 0x25, 0x9f, 0xc4, 0x4f, 0x28, 0x2f, 0xd2, 0xbd, 0xec,
+ 0x9b, 0x66, 0xc8, 0xb2, 0x33, 0x81, 0xc7, 0x97, 0x45, 0xf6, 0xfe, 0x4f,
+ 0xc7, 0x75, 0xc4, 0x17, 0xc9, 0x2a, 0x6b, 0xd5, 0x8e, 0x0d, 0xd7, 0xa9,
+ 0x0f, 0xe2, 0x2f, 0xfd, 0x2c, 0xcb, 0x61, 0x91, 0xa5, 0x3a, 0xf5, 0x8c,
+ 0x0b, 0x0d, 0x41, 0x35, 0x8b, 0x17, 0xfa, 0xf8, 0x5a, 0xc0, 0xf7, 0x44,
+ 0x3a, 0xe9, 0x08, 0xa8, 0xf0, 0xbb, 0xf4, 0x6e, 0xf1, 0x04, 0x61, 0xc0,
+ 0x89, 0x74, 0x8f, 0x98, 0x28, 0xdc, 0x29, 0x8c, 0xfc, 0x37, 0x85, 0x31,
+ 0x9b, 0x12, 0x46, 0xa1, 0x9f, 0x3e, 0x37, 0x88, 0xc9, 0xc2, 0xb0, 0xd8,
+ 0x5d, 0xe0, 0x79, 0x49, 0x27, 0x34, 0xf7, 0x0f, 0x29, 0xc6, 0xfe, 0x80,
+ 0x62, 0xec, 0x31, 0x8a, 0xb1, 0xcf, 0x93, 0x5d, 0x7f, 0xff, 0x2a, 0x96,
+ 0x65, 0x5b, 0x4e, 0x32, 0x06, 0xf1, 0xfd, 0xbc, 0xf4, 0x12, 0xe9, 0x95,
+ 0x65, 0xf6, 0x13, 0xb2, 0x61, 0x96, 0xc5, 0x7f, 0xe6, 0x9c, 0x40, 0xfa,
+ 0xf8, 0xd0, 0xb2, 0xd9, 0xc7, 0x97, 0x31, 0x66, 0x1a, 0x16, 0x3b, 0x98,
+ 0xae, 0x5a, 0xaa, 0xdb, 0x55, 0xc2, 0x21, 0xd9, 0x61, 0xb1, 0xb1, 0xc0,
+ 0xd7, 0xf7, 0xe1, 0x3e, 0xaa, 0xff, 0xb6, 0xc6, 0xc2, 0x89, 0x6e, 0xc2,
+ 0x48, 0x17, 0x54, 0x73, 0x71, 0x34, 0x46, 0x98, 0xe1, 0xc6, 0x2b, 0x54,
+ 0xab, 0x22, 0xb9, 0x2d, 0xae, 0xe4, 0xf3, 0x76, 0x5e, 0xcd, 0xa5, 0xc1,
+ 0x75, 0x3a, 0x1a, 0x9c, 0xaa, 0x72, 0x24, 0x89, 0xf0, 0xde, 0xb8, 0x03,
+ 0x46, 0x8d, 0xee, 0xc2, 0x80, 0x55, 0x17, 0xae, 0x41, 0x66, 0x42, 0xe0,
+ 0x65, 0xf2, 0x01, 0x17, 0xc9, 0xe8, 0x50, 0x27, 0x3e, 0x23, 0xb5, 0x0a,
+ 0xaa, 0xe3, 0x4f, 0x9f, 0xa5, 0x9c, 0x73, 0x17, 0xe5, 0xd6, 0x89, 0xec,
+ 0x0a, 0x04, 0x3b, 0x64, 0x34, 0x74, 0x38, 0xf1, 0x8d, 0xd2, 0xef, 0xe3,
+ 0x4c, 0x63, 0xe4, 0xe0, 0x0b, 0xf0, 0xf8, 0x5e, 0x9a, 0x64, 0x7a, 0xf0,
+ 0xbd, 0x3a, 0xaa, 0xd7, 0xb6, 0x12, 0x4e, 0x1a, 0x27, 0x1a, 0x7a, 0x3a,
+ 0x22, 0x3d, 0xb7, 0x09, 0xf8, 0x6b, 0xf5, 0x1a, 0x8c, 0xb7, 0xfa, 0xe0,
+ 0x57, 0x53, 0xe2, 0xd5, 0x02, 0xe5, 0x0d, 0xc7, 0x37, 0xc5, 0x5b, 0xb3,
+ 0x3a, 0xf6, 0x96, 0xfb, 0xc5, 0x2f, 0x66, 0x65, 0x90, 0x4e, 0x28, 0x3e,
+ 0x69, 0xc8, 0x10, 0x5d, 0x2e, 0xc2, 0x42, 0x2f, 0xdf, 0x21, 0x70, 0x9d,
+ 0x9a, 0xc4, 0x77, 0x56, 0xb0, 0xcd, 0xdb, 0xb1, 0x2b, 0x98, 0x51, 0x42,
+ 0x49, 0x47, 0xb7, 0x08, 0x52, 0xec, 0x6a, 0xc8, 0xf4, 0x88, 0x06, 0xc2,
+ 0x9e, 0x0b, 0xa7, 0x37, 0x88, 0x05, 0x25, 0xc6, 0x9a, 0xf0, 0x2f, 0x24,
+ 0xd9, 0x2c, 0x2c, 0x7d, 0x20, 0xd9, 0x18, 0xdf, 0xc5, 0xb6, 0x43, 0x39,
+ 0x4a, 0xf6, 0xfd, 0x7a, 0x32, 0x89, 0x5b, 0x3b, 0xd6, 0x20, 0x64, 0xd9,
+ 0xc7, 0xb0, 0xd8, 0x47, 0xf2, 0x4b, 0x5a, 0xfd, 0x07, 0xbf, 0xef, 0xc0,
+ 0x24, 0x5c, 0x7e, 0x1d, 0x21, 0x89, 0x72, 0x43, 0xa9, 0x23, 0x32, 0xf8,
+ 0x96, 0xe8, 0x15, 0xa3, 0x85, 0x80, 0x2f, 0x9d, 0x86, 0xbf, 0x8e, 0x74,
+ 0x9c, 0x26, 0x1d, 0xef, 0x21, 0x1d, 0xef, 0xf9, 0x12, 0x1d, 0xef, 0x24,
+ 0x1d, 0xef, 0x2f, 0xfc, 0x9d, 0xa5, 0x33, 0xa7, 0xae, 0x63, 0x94, 0x72,
+ 0xee, 0x78, 0xab, 0xcd, 0x4f, 0x81, 0x30, 0xea, 0x9e, 0x58, 0xaf, 0x13,
+ 0x1e, 0x9d, 0x62, 0x66, 0x2f, 0x3d, 0xd3, 0x5c, 0xb5, 0x65, 0xbf, 0xef,
+ 0xc9, 0x74, 0xb7, 0x78, 0xd2, 0xf2, 0x2b, 0xc6, 0x8d, 0x49, 0x34, 0xaa,
+ 0x3d, 0x34, 0x17, 0xdb, 0xca, 0x9d, 0x02, 0x4f, 0xb1, 0xbd, 0x7c, 0x93,
+ 0x04, 0xcf, 0x36, 0x93, 0x12, 0x28, 0xb2, 0xdd, 0xf4, 0xd3, 0x6f, 0xb6,
+ 0x9d, 0x0d, 0xa2, 0xb1, 0xf8, 0x45, 0xfb, 0x81, 0xdf, 0xa9, 0xb3, 0xfd,
+ 0xb0, 0x1d, 0x0d, 0x0b, 0x67, 0x91, 0x7c, 0x96, 0xe6, 0x1f, 0x21, 0xba,
+ 0x77, 0xa6, 0xf7, 0x3b, 0x99, 0x36, 0x59, 0x67, 0x3b, 0x62, 0xfb, 0xb9,
+ 0x48, 0xb4, 0xb2, 0xcd, 0x5f, 0xed, 0xd9, 0xd0, 0xdf, 0xef, 0x4a, 0x50,
+ 0xb7, 0x38, 0x6d, 0x1e, 0x38, 0x87, 0x73, 0xce, 0xe6, 0x78, 0xea, 0xb7,
+ 0x6a, 0xba, 0x63, 0x57, 0x73, 0x39, 0xe7, 0x75, 0xc8, 0x0b, 0xf4, 0x80,
+ 0xfe, 0x9d, 0xd6, 0x2b, 0x34, 0xdf, 0x10, 0xb4, 0x15, 0x90, 0x03, 0xfa,
+ 0xa4, 0x3e, 0xd9, 0x4a, 0xf1, 0x96, 0xe6, 0x94, 0x33, 0x80, 0x9a, 0x11,
+ 0xd8, 0x99, 0x10, 0x84, 0x47, 0x17, 0x91, 0xbf, 0xc1, 0xf0, 0xe8, 0x4a,
+ 0x4f, 0x92, 0xee, 0x2d, 0x25, 0x7c, 0xbe, 0x58, 0xdf, 0x06, 0x33, 0x0b,
+ 0xb9, 0x41, 0x1f, 0xc4, 0x27, 0xa3, 0x61, 0xff, 0x79, 0x28, 0xa9, 0xb3,
+ 0x92, 0x52, 0xa1, 0x3c, 0x35, 0x34, 0x22, 0x94, 0xc1, 0xcb, 0x42, 0x49,
+ 0x96, 0xac, 0x1e, 0xcf, 0x36, 0xb4, 0x5b, 0x58, 0x7c, 0x10, 0xd1, 0x02,
+ 0x70, 0x1b, 0x01, 0xbc, 0x7b, 0x6e, 0x26, 0x9b, 0xd4, 0x3e, 0xe2, 0xd8,
+ 0x9e, 0x3c, 0x43, 0x54, 0x2f, 0xce, 0x70, 0xcf, 0x68, 0x5b, 0xb5, 0x67,
+ 0x34, 0x68, 0xf5, 0x8c, 0xce, 0x4b, 0x4a, 0x62, 0xbe, 0x67, 0x74, 0x05,
+ 0x3c, 0x97, 0xd2, 0xef, 0xad, 0xce, 0xb7, 0xb4, 0x3a, 0x5f, 0x5b, 0x01,
+ 0x22, 0x9a, 0x31, 0xcc, 0x1a, 0xd5, 0x43, 0xfc, 0x26, 0x1d, 0xae, 0x88,
+ 0xda, 0x73, 0x18, 0x21, 0x44, 0xa9, 0xde, 0xbd, 0x9e, 0xf2, 0xa0, 0x3b,
+ 0xb3, 0x03, 0x33, 0x9a, 0xd2, 0x37, 0x00, 0xb6, 0x9d, 0x6e, 0xec, 0xa3,
+ 0x18, 0xba, 0xb7, 0xcc, 0xf5, 0xc8, 0xb0, 0x38, 0xcb, 0x76, 0xe3, 0xb4,
+ 0xa5, 0x66, 0xaf, 0xff, 0x70, 0x75, 0xfd, 0x21, 0x6b, 0xfd, 0x0b, 0x92,
+ 0xd2, 0x5f, 0x5d, 0x5f, 0xfb, 0x33, 0xa1, 0xa4, 0x68, 0xfd, 0x9e, 0x3d,
+ 0xb4, 0xbe, 0x4b, 0xe5, 0xb5, 0x1f, 0xe6, 0xb5, 0xe9, 0x73, 0x08, 0xd7,
+ 0x93, 0xdd, 0xbc, 0x57, 0x90, 0xc5, 0xbb, 0xb9, 0x35, 0xd8, 0x35, 0xb3,
+ 0x06, 0x3b, 0xc9, 0xdf, 0xb6, 0x6a, 0x0d, 0x54, 0xa7, 0xa1, 0xde, 0xa7,
+ 0xe2, 0xb2, 0x23, 0x22, 0xa4, 0xf5, 0xed, 0x2d, 0x84, 0x41, 0x4e, 0x34,
+ 0xcb, 0xf8, 0xd4, 0x1c, 0x50, 0xd7, 0xf4, 0x39, 0x91, 0xfc, 0x7d, 0x0f,
+ 0xfe, 0x5c, 0x22, 0xff, 0x7d, 0x67, 0x81, 0x40, 0xd2, 0x63, 0xd5, 0x1c,
+ 0x09, 0xe1, 0x29, 0xfe, 0xd8, 0x69, 0xdb, 0x7b, 0x2b, 0x7c, 0x8d, 0x68,
+ 0x68, 0x50, 0x6f, 0x40, 0x43, 0xa3, 0x6c, 0x38, 0xa8, 0x8e, 0x59, 0x4f,
+ 0x21, 0xd1, 0xcc, 0xf5, 0x51, 0x3c, 0x35, 0x71, 0x65, 0xf9, 0xdf, 0x9b,
+ 0x89, 0xeb, 0xf8, 0x39, 0x02, 0x15, 0x56, 0x4c, 0xfc, 0xb2, 0x39, 0xe2,
+ 0xe4, 0xbf, 0x6d, 0x54, 0x97, 0xd6, 0x51, 0xf0, 0xed, 0xc1, 0x9e, 0xac,
+ 0x92, 0xda, 0x43, 0x75, 0xe5, 0xfe, 0x48, 0x5b, 0xcf, 0x26, 0x51, 0x83,
+ 0xd0, 0xc2, 0xf0, 0xe0, 0x00, 0x92, 0xcd, 0xf5, 0x55, 0x3a, 0x1e, 0x46,
+ 0xb3, 0x8b, 0x9e, 0xe3, 0x79, 0xae, 0xb1, 0xa7, 0x22, 0xd9, 0x13, 0xdf,
+ 0xe7, 0xef, 0x57, 0xef, 0xcb, 0xbf, 0xa3, 0x4f, 0xae, 0xfa, 0xaf, 0x4b,
+ 0xbf, 0xec, 0xfa, 0xb1, 0x2f, 0xb9, 0xfe, 0x6f, 0xd5, 0xe7, 0x95, 0x46,
+ 0xa7, 0x95, 0xfb, 0x93, 0x0e, 0xee, 0x4b, 0x3a, 0xf5, 0x42, 0xd7, 0x2e,
+ 0xf5, 0x3f, 0x51, 0xcc, 0xe2, 0x7e, 0x04, 0xe7, 0xdb, 0x33, 0x56, 0x3f,
+ 0xe2, 0xf8, 0x6f, 0x61, 0x4f, 0x8e, 0x1d, 0x6e, 0x51, 0x37, 0x6e, 0x98,
+ 0x4d, 0xea, 0x1f, 0x51, 0x7d, 0xb2, 0x03, 0x03, 0x31, 0x0d, 0x63, 0x59,
+ 0xa5, 0xef, 0x0e, 0xa8, 0xc9, 0x3b, 0x05, 0x4d, 0x54, 0x72, 0x0b, 0x69,
+ 0xbc, 0x7a, 0x4f, 0x33, 0xa8, 0xe6, 0xaa, 0xa0, 0x96, 0x62, 0x8f, 0x53,
+ 0xf5, 0xcb, 0x28, 0x05, 0x64, 0x67, 0x29, 0x28, 0xd7, 0x94, 0x5a, 0xe4,
+ 0x5a, 0x1a, 0xe7, 0x1d, 0x57, 0x2e, 0xdf, 0x81, 0x1d, 0xb8, 0xbc, 0xdc,
+ 0x63, 0x34, 0xeb, 0x8a, 0xbf, 0x59, 0xda, 0x81, 0x5d, 0x31, 0x7e, 0xb6,
+ 0x9b, 0x6a, 0x2f, 0x88, 0xc6, 0x0c, 0x21, 0x5c, 0x5d, 0x60, 0x37, 0xd5,
+ 0x97, 0x4b, 0x1c, 0x6a, 0xcf, 0xaf, 0x85, 0x53, 0x76, 0x97, 0x20, 0x7c,
+ 0x19, 0x07, 0x0e, 0x76, 0xc2, 0xed, 0x5e, 0xa1, 0x0c, 0x9e, 0x10, 0xc3,
+ 0x78, 0x36, 0x16, 0xe9, 0xdb, 0x2c, 0x42, 0xb2, 0x87, 0xee, 0xb9, 0x32,
+ 0x10, 0x72, 0xc6, 0x70, 0xbb, 0x56, 0x28, 0x41, 0x87, 0x48, 0x62, 0x40,
+ 0x55, 0xb5, 0x71, 0xc8, 0xb4, 0x26, 0x44, 0x6d, 0x46, 0xb9, 0x7c, 0x96,
+ 0xb0, 0xd1, 0x95, 0xa5, 0xc3, 0xe8, 0x58, 0x1e, 0xd9, 0xdb, 0xef, 0x50,
+ 0x65, 0xc2, 0x6c, 0xc2, 0x99, 0xf1, 0xe2, 0xa6, 0x03, 0xf3, 0xfd, 0x19,
+ 0xd3, 0xfc, 0x38, 0x56, 0xb9, 0x97, 0x44, 0x28, 0xd7, 0x97, 0xa2, 0xb2,
+ 0x97, 0xf0, 0x79, 0xdb, 0x01, 0xc6, 0x4b, 0x9c, 0x0f, 0x2a, 0x64, 0x37,
+ 0xed, 0xc4, 0x63, 0x1f, 0x66, 0xd2, 0x8c, 0x9f, 0x74, 0x4c, 0x53, 0x6d,
+ 0xa3, 0x8e, 0xb6, 0x50, 0xae, 0x4f, 0x60, 0x2e, 0xcd, 0x7d, 0x9c, 0x41,
+ 0x92, 0x71, 0x3f, 0xd1, 0xbf, 0x81, 0xea, 0xda, 0x14, 0xc5, 0x2b, 0x96,
+ 0xf1, 0x00, 0xf7, 0x6b, 0xa9, 0x96, 0xfe, 0x79, 0xd7, 0xd7, 0xc6, 0x20,
+ 0xbb, 0xf5, 0xd7, 0xba, 0xae, 0x3f, 0x80, 0x46, 0xca, 0xe7, 0x3a, 0x55,
+ 0x2e, 0x88, 0x46, 0x22, 0xda, 0x79, 0x44, 0x82, 0x2f, 0x93, 0x3e, 0x46,
+ 0x54, 0x60, 0xa7, 0x55, 0x33, 0x3b, 0x61, 0x14, 0xd8, 0xa6, 0xe0, 0xae,
+ 0xed, 0x6c, 0xc4, 0xfb, 0xb9, 0xa8, 0xd5, 0x0b, 0x32, 0xa8, 0x8e, 0x79,
+ 0x49, 0x53, 0x52, 0x79, 0x7a, 0x6e, 0xa3, 0xff, 0x7f, 0xed, 0xa9, 0x8b,
+ 0x43, 0xae, 0x53, 0xd9, 0xbf, 0xfe, 0xdc, 0x73, 0x96, 0x6c, 0xf4, 0xae,
+ 0xc9, 0xbf, 0xf0, 0x7c, 0x12, 0xcf, 0x7b, 0x3e, 0x8a, 0x9b, 0x66, 0x82,
+ 0x70, 0x65, 0x3f, 0xd5, 0xcd, 0x1f, 0x8f, 0x1a, 0x9e, 0xf3, 0x71, 0xee,
+ 0xe9, 0x3a, 0xf1, 0x07, 0xf4, 0xfb, 0xe9, 0x51, 0x19, 0xb7, 0x16, 0x9b,
+ 0xe1, 0x1a, 0x93, 0xc8, 0x3f, 0xd7, 0x52, 0xae, 0x72, 0xe0, 0x9e, 0xe8,
+ 0x51, 0x54, 0x02, 0x0e, 0x1a, 0xb3, 0x9f, 0x7e, 0x73, 0x6f, 0xea, 0x71,
+ 0x6c, 0xf6, 0xcf, 0x7a, 0xde, 0x8f, 0x33, 0xbd, 0x15, 0xa6, 0x97, 0x72,
+ 0xe4, 0xed, 0xd8, 0x78, 0x07, 0x0c, 0x9f, 0x6e, 0xfd, 0xbb, 0x5f, 0xee,
+ 0x6c, 0xc2, 0xe1, 0x5c, 0x33, 0x5e, 0xcc, 0x19, 0xee, 0x9f, 0x76, 0x46,
+ 0x31, 0x38, 0x6a, 0xe2, 0x15, 0xcd, 0x18, 0xae, 0x25, 0x3b, 0x4f, 0x50,
+ 0xad, 0x14, 0x5e, 0xae, 0xf8, 0x2f, 0x0b, 0x44, 0x24, 0x44, 0x86, 0x08,
+ 0x2c, 0xde, 0x4d, 0xa1, 0x2b, 0x55, 0xaf, 0x47, 0xb4, 0xd7, 0x85, 0x59,
+ 0x73, 0x6f, 0xa7, 0x93, 0x68, 0x00, 0xd6, 0x51, 0x4c, 0x9e, 0x4b, 0x47,
+ 0x71, 0x6b, 0x44, 0xc6, 0xfa, 0xa2, 0x86, 0x17, 0xd3, 0x5e, 0xdc, 0x55,
+ 0x8c, 0x13, 0x86, 0xf6, 0x13, 0xed, 0x09, 0x94, 0xd3, 0x01, 0x7c, 0xbd,
+ 0xd8, 0x42, 0xf2, 0x0e, 0x62, 0x6d, 0x91, 0x31, 0x16, 0xe7, 0x67, 0xdd,
+ 0xbd, 0x31, 0xde, 0x82, 0x1e, 0x8a, 0xdf, 0xb3, 0x69, 0xb8, 0xb7, 0xc7,
+ 0x43, 0xe8, 0x2e, 0x46, 0x51, 0x24, 0x2c, 0x76, 0x3b, 0xcd, 0x79, 0x17,
+ 0xe9, 0xa4, 0x9d, 0xea, 0xfb, 0x25, 0x11, 0x42, 0xa8, 0x45, 0xaf, 0x18,
+ 0x26, 0xcc, 0x94, 0x28, 0x36, 0xe1, 0xfc, 0x18, 0xdb, 0xf9, 0x5b, 0x5d,
+ 0xbb, 0x72, 0x7e, 0x84, 0x8a, 0xb8, 0x49, 0x06, 0xb6, 0x51, 0x95, 0x97,
+ 0x2a, 0x12, 0xbd, 0xfb, 0x3a, 0xed, 0x7e, 0xec, 0x0d, 0xc5, 0xcf, 0xf9,
+ 0x6d, 0x20, 0x3d, 0x7d, 0x72, 0x60, 0xd6, 0x73, 0x85, 0x64, 0xe0, 0xd3,
+ 0x7f, 0xd4, 0xf5, 0xc6, 0x01, 0x20, 0x3a, 0xc5, 0xbc, 0x71, 0x7c, 0x0d,
+ 0x27, 0x28, 0xbe, 0xb6, 0xcb, 0xf8, 0xb5, 0x49, 0xb5, 0x64, 0x68, 0x86,
+ 0x7b, 0xff, 0xaa, 0x97, 0xe8, 0xf0, 0x23, 0x49, 0x6b, 0xdf, 0x56, 0xfc,
+ 0xa1, 0xb9, 0x71, 0x61, 0x10, 0x5f, 0x8b, 0xd8, 0xb2, 0x7a, 0x9d, 0x74,
+ 0x38, 0x3d, 0xd6, 0x8c, 0xb9, 0x31, 0xee, 0xad, 0x9c, 0xea, 0x3a, 0x34,
+ 0x69, 0x62, 0x9d, 0x66, 0x78, 0x7e, 0xda, 0x79, 0x03, 0x1e, 0x38, 0x30,
+ 0x72, 0xba, 0x86, 0xf4, 0x7a, 0x59, 0xbb, 0x1b, 0x8f, 0x4e, 0xe1, 0xab,
+ 0xcd, 0xc0, 0x23, 0x41, 0x70, 0xff, 0x59, 0x09, 0x1d, 0x41, 0xa4, 0x67,
+ 0x3b, 0x22, 0x7e, 0x55, 0x28, 0xda, 0x2b, 0x14, 0xab, 0xea, 0x08, 0x3b,
+ 0xdc, 0x46, 0xb5, 0x7c, 0x0d, 0x79, 0xf0, 0x5d, 0x45, 0x27, 0xc9, 0x28,
+ 0x88, 0xf2, 0x58, 0x0d, 0x24, 0xf2, 0x93, 0x0b, 0x2a, 0xd6, 0x35, 0x90,
+ 0xac, 0x25, 0x21, 0x93, 0x9e, 0xdb, 0x71, 0x68, 0x74, 0x5e, 0x56, 0x5e,
+ 0xdc, 0x42, 0x32, 0x7c, 0x76, 0xd4, 0xdc, 0xa1, 0xc6, 0x02, 0x24, 0x6b,
+ 0x3f, 0xd1, 0x37, 0x2f, 0x27, 0x96, 0xdf, 0xbc, 0x9c, 0xee, 0xc6, 0xae,
+ 0x39, 0x96, 0xdb, 0xbf, 0x47, 0x5e, 0xb3, 0x96, 0xdd, 0xad, 0x9b, 0x8c,
+ 0xa2, 0xf9, 0xc0, 0x55, 0xd9, 0x31, 0x7d, 0x8f, 0x10, 0x1f, 0xdf, 0xf3,
+ 0xad, 0x8c, 0x0c, 0x5e, 0x14, 0x5e, 0xa2, 0xc7, 0x4f, 0xba, 0x39, 0xeb,
+ 0x62, 0x0c, 0x4e, 0x32, 0xb9, 0x2a, 0xe3, 0x20, 0xc9, 0x38, 0x38, 0xc5,
+ 0xb2, 0xfe, 0x11, 0xc9, 0x1a, 0x78, 0x83, 0x70, 0xd7, 0xcd, 0xb1, 0x28,
+ 0xea, 0x0f, 0x28, 0xc9, 0x66, 0x29, 0x9c, 0x68, 0x10, 0xa0, 0xea, 0x02,
+ 0xed, 0xf5, 0xf8, 0x98, 0xe5, 0xac, 0x91, 0x9c, 0xbf, 0x37, 0x42, 0xfc,
+ 0xac, 0xa1, 0xf9, 0xd6, 0x91, 0x9c, 0x93, 0xc4, 0xff, 0x6d, 0xd6, 0xbc,
+ 0x2d, 0x34, 0xef, 0x06, 0xaa, 0x21, 0x66, 0x3d, 0x17, 0x88, 0x9e, 0xe8,
+ 0xe7, 0xb4, 0x10, 0xca, 0x8e, 0x04, 0x2f, 0x52, 0xad, 0xbc, 0xd6, 0x1a,
+ 0xe7, 0xa7, 0x71, 0x4c, 0xfb, 0x5b, 0xb5, 0x0e, 0xf5, 0xcb, 0x7a, 0xc7,
+ 0x77, 0x83, 0x7b, 0x07, 0x06, 0xfa, 0xb1, 0x37, 0xbb, 0x81, 0x6a, 0x1e,
+ 0x99, 0x30, 0xa4, 0x81, 0xef, 0xc7, 0x95, 0x68, 0xa3, 0xe0, 0xf8, 0x67,
+ 0x90, 0x1f, 0x56, 0xa8, 0xde, 0x09, 0x87, 0xe6, 0x10, 0x94, 0x1d, 0x25,
+ 0x99, 0xf0, 0x5e, 0x8b, 0x2c, 0x95, 0xc8, 0x5f, 0x83, 0xfd, 0x84, 0x93,
+ 0x9d, 0x78, 0xb9, 0xe0, 0xc4, 0xab, 0xe9, 0x0d, 0x94, 0xe7, 0xdc, 0x84,
+ 0x87, 0x0d, 0xb7, 0x73, 0xc5, 0x81, 0x1a, 0x3b, 0x26, 0x2f, 0x45, 0xef,
+ 0xf8, 0xc3, 0xa8, 0xcb, 0x38, 0xfb, 0x28, 0x47, 0x6b, 0xb7, 0x91, 0x5c,
+ 0xd6, 0x95, 0xf8, 0x7e, 0x0b, 0x32, 0xe9, 0x14, 0xb2, 0xd9, 0x30, 0xd5,
+ 0x32, 0x4e, 0xe4, 0x9b, 0x5b, 0xac, 0xfe, 0x6c, 0x8e, 0xae, 0xe5, 0xca,
+ 0x5f, 0xec, 0x1b, 0x7f, 0xab, 0xda, 0x2f, 0x1e, 0xa4, 0x9c, 0xd2, 0x4f,
+ 0xd8, 0x73, 0x03, 0xc5, 0x77, 0x9b, 0xc6, 0xd9, 0x78, 0x1f, 0xf6, 0x14,
+ 0xf4, 0xab, 0xf1, 0x63, 0xba, 0x60, 0xf7, 0x05, 0xb7, 0x90, 0x3c, 0xce,
+ 0xa5, 0x4d, 0x3c, 0xaa, 0xb1, 0x3e, 0x29, 0x2e, 0xa5, 0xb9, 0x37, 0x68,
+ 0xe2, 0x19, 0x4d, 0x70, 0xbc, 0xa1, 0x3c, 0xba, 0x01, 0x4b, 0x0a, 0x26,
+ 0x4e, 0x6b, 0x2a, 0xc5, 0x2e, 0x18, 0x6e, 0xc2, 0x7e, 0x91, 0xd1, 0x7f,
+ 0x31, 0xf3, 0xce, 0x21, 0xb4, 0x75, 0x02, 0x9b, 0x47, 0x25, 0xcc, 0xcd,
+ 0x5c, 0xcd, 0xd1, 0x78, 0xf1, 0xf3, 0x3c, 0x9d, 0x98, 0x81, 0xb9, 0xc3,
+ 0xa9, 0x2b, 0xc3, 0xbc, 0xd7, 0x32, 0x12, 0x57, 0x12, 0xb5, 0x56, 0xce,
+ 0x56, 0xfb, 0x97, 0x48, 0x8a, 0x56, 0x12, 0x6d, 0xa9, 0x4f, 0x50, 0x59,
+ 0x2f, 0x43, 0x09, 0xfe, 0x0c, 0x91, 0xe8, 0x20, 0xef, 0x29, 0x94, 0xed,
+ 0xfc, 0xbd, 0xb4, 0x9a, 0xbf, 0xc3, 0x05, 0x8f, 0x50, 0xc7, 0x1c, 0xc8,
+ 0xcf, 0x98, 0x94, 0x67, 0x05, 0x66, 0x49, 0xc1, 0x2f, 0x64, 0x77, 0xe0,
+ 0xeb, 0x31, 0xd3, 0xbc, 0x2b, 0xae, 0x0e, 0x36, 0x4b, 0xf8, 0xd3, 0x06,
+ 0xc2, 0x14, 0x64, 0xf7, 0x84, 0x01, 0x10, 0xda, 0xda, 0x69, 0x98, 0x32,
+ 0xd5, 0x0c, 0x35, 0x3a, 0xf7, 0x1a, 0x7b, 0x45, 0x7b, 0x71, 0x83, 0xb8,
+ 0xa1, 0xd8, 0x2f, 0x42, 0x87, 0xee, 0x14, 0xd1, 0xa7, 0x6c, 0xdc, 0xd6,
+ 0x5a, 0xfc, 0xbc, 0x1f, 0xda, 0x43, 0x7c, 0xef, 0xd3, 0x4c, 0x3c, 0x4d,
+ 0xbc, 0xed, 0x2d, 0xdb, 0xb5, 0xc8, 0xee, 0xb4, 0xcd, 0xdb, 0xa3, 0x74,
+ 0xff, 0x62, 0x9a, 0xfd, 0xf1, 0x61, 0xab, 0xd7, 0xd9, 0x4c, 0xcf, 0xdc,
+ 0x9c, 0x0d, 0x87, 0x06, 0x85, 0x32, 0x34, 0x0b, 0xee, 0x77, 0xb6, 0x55,
+ 0x4e, 0x0a, 0xca, 0x3d, 0x12, 0xc7, 0x57, 0xf6, 0x79, 0x9b, 0xf6, 0x65,
+ 0x05, 0x58, 0x71, 0x91, 0xe9, 0xbf, 0x91, 0xea, 0xbe, 0x9f, 0xa5, 0xdb,
+ 0xfa, 0xdd, 0x24, 0xb6, 0xf3, 0xf1, 0x6e, 0x71, 0x89, 0xea, 0xbe, 0x57,
+ 0xd3, 0xc9, 0x85, 0x75, 0xe8, 0x11, 0x17, 0x0a, 0x7d, 0xe2, 0xc3, 0x7c,
+ 0x2f, 0x9c, 0x63, 0xf7, 0x8b, 0x77, 0xf3, 0x4c, 0x5b, 0xbf, 0x38, 0x33,
+ 0x7b, 0xde, 0x92, 0xfd, 0x2e, 0x8d, 0xfb, 0x9a, 0xf5, 0xb5, 0xf0, 0x99,
+ 0x04, 0x4f, 0x59, 0x8f, 0xdc, 0xe7, 0xb3, 0xfb, 0x43, 0xeb, 0xe2, 0x39,
+ 0xd3, 0xa9, 0x72, 0xaf, 0x37, 0x68, 0xf1, 0x38, 0x43, 0x78, 0x79, 0x36,
+ 0xbf, 0x41, 0x1c, 0x2e, 0xd8, 0xfc, 0x4d, 0x17, 0xd8, 0x6e, 0x65, 0xca,
+ 0x0d, 0x5f, 0xcc, 0xcf, 0x06, 0xfc, 0x9d, 0x41, 0xd4, 0x58, 0xfd, 0x24,
+ 0x13, 0xe3, 0x5a, 0x24, 0xf4, 0x0a, 0x82, 0x70, 0x96, 0xd8, 0xa6, 0x4d,
+ 0x3c, 0xa7, 0xb9, 0x20, 0x8d, 0xcb, 0x24, 0x17, 0xb2, 0x21, 0x9f, 0x0b,
+ 0x8e, 0x69, 0xae, 0x01, 0xe2, 0xb5, 0xdc, 0x67, 0x08, 0x39, 0xf8, 0xfb,
+ 0x17, 0x6d, 0xcd, 0x45, 0x79, 0x80, 0xfb, 0xe3, 0x6f, 0xd6, 0xd8, 0x36,
+ 0xc7, 0xf9, 0x68, 0xbe, 0xa7, 0x4d, 0x39, 0xb6, 0x93, 0x7b, 0xd9, 0x6e,
+ 0xcc, 0xe5, 0x6a, 0xb8, 0xc5, 0xe0, 0xae, 0xe9, 0x34, 0x71, 0x4e, 0x73,
+ 0x52, 0x5d, 0xf2, 0x10, 0xe5, 0x26, 0x07, 0x64, 0xf5, 0x6e, 0x94, 0x26,
+ 0x9d, 0x0e, 0xde, 0x73, 0xfa, 0x59, 0x8c, 0x7b, 0x00, 0xc0, 0x7e, 0xe2,
+ 0xe1, 0x99, 0x5c, 0x88, 0xea, 0x7f, 0xb9, 0x5a, 0x43, 0xfc, 0x01, 0x8e,
+ 0xe7, 0x24, 0xd1, 0xac, 0x43, 0x4a, 0xac, 0x34, 0xf1, 0xc9, 0xf2, 0x48,
+ 0xf4, 0x32, 0xc5, 0x2f, 0x3f, 0xe5, 0xaa, 0xdd, 0x85, 0x46, 0xfc, 0x2c,
+ 0xd7, 0x88, 0x57, 0x73, 0xa4, 0xc3, 0xd8, 0x48, 0xbf, 0x87, 0x62, 0xe4,
+ 0xd2, 0x98, 0x0b, 0x5b, 0x23, 0x86, 0xdf, 0x83, 0x28, 0xce, 0x25, 0xae,
+ 0x47, 0x2a, 0x10, 0xee, 0x19, 0x41, 0x13, 0xde, 0xcc, 0x81, 0x30, 0x04,
+ 0xdc, 0x4b, 0x68, 0x8e, 0xf7, 0x62, 0xc6, 0x90, 0x0b, 0x0a, 0xd5, 0x1f,
+ 0x88, 0xd7, 0xc3, 0xac, 0x39, 0x19, 0xa7, 0x1c, 0x5d, 0x6c, 0x44, 0x6f,
+ 0xae, 0x09, 0xfd, 0x94, 0xab, 0x56, 0xaf, 0x8c, 0xe3, 0xdd, 0xac, 0x57,
+ 0xdc, 0x94, 0x1d, 0xe9, 0xf7, 0xd3, 0x9c, 0xae, 0xe5, 0xca, 0xd0, 0xb3,
+ 0x04, 0xd8, 0x64, 0x84, 0xd9, 0xbc, 0xb7, 0xfb, 0x28, 0xde, 0x1e, 0x16,
+ 0x9f, 0xe1, 0x49, 0xb2, 0xc1, 0x2d, 0x9a, 0x52, 0xb9, 0x20, 0x45, 0x4e,
+ 0xaf, 0x87, 0x32, 0x7c, 0x9b, 0x30, 0xa2, 0x0d, 0x14, 0x47, 0x9a, 0xed,
+ 0x18, 0x61, 0x44, 0x84, 0x4c, 0x98, 0xdc, 0x09, 0xb7, 0x6a, 0xa0, 0xa7,
+ 0x93, 0x65, 0xea, 0x86, 0xfb, 0x29, 0xb2, 0x1b, 0xc7, 0x17, 0xfb, 0xf3,
+ 0x8d, 0x78, 0x83, 0xf2, 0xe4, 0xeb, 0x39, 0xc8, 0xb5, 0x14, 0xfb, 0x3f,
+ 0xa0, 0xd8, 0x7f, 0x2a, 0x36, 0x12, 0xe2, 0x98, 0x5f, 0x88, 0xe1, 0x5b,
+ 0x04, 0x83, 0x5b, 0xbc, 0xb4, 0xe6, 0x26, 0xc1, 0xeb, 0x20, 0xb9, 0x58,
+ 0xe7, 0xbe, 0x9a, 0xc5, 0x0f, 0xc5, 0x61, 0xe6, 0xe9, 0xff, 0x27, 0xed,
+ 0xdb, 0x6b, 0xe1, 0x69, 0x22, 0x5d, 0xce, 0xf7, 0x24, 0xaf, 0xed, 0x47,
+ 0x72, 0x1d, 0x63, 0xe3, 0xc2, 0x1a, 0xbd, 0x4e, 0xbc, 0x94, 0x63, 0x9b,
+ 0x33, 0xf1, 0xbc, 0xa6, 0x51, 0xcd, 0xc2, 0xb5, 0xf6, 0x10, 0xd5, 0x2d,
+ 0xdc, 0x27, 0x32, 0xdc, 0x27, 0x89, 0xc2, 0xbd, 0x39, 0xfc, 0x9e, 0x0c,
+ 0x69, 0x59, 0x2d, 0xa6, 0x90, 0x77, 0x3a, 0x09, 0x6b, 0x70, 0x8c, 0x65,
+ 0x3f, 0x7a, 0xab, 0x4b, 0xcd, 0xc3, 0xf0, 0xea, 0x3d, 0x30, 0x2c, 0xdf,
+ 0xad, 0x13, 0x0f, 0x90, 0x8d, 0xbc, 0x1c, 0xab, 0x45, 0x9e, 0xea, 0x1e,
+ 0xc2, 0xdf, 0xee, 0x3f, 0xa3, 0xe7, 0x13, 0x13, 0xd8, 0x13, 0x84, 0xf4,
+ 0x5d, 0x3f, 0xfe, 0x02, 0x67, 0x5d, 0x8c, 0xcb, 0xe1, 0xee, 0x8b, 0x1b,
+ 0x9e, 0xf5, 0xf1, 0x3a, 0x71, 0x7b, 0xae, 0x1d, 0x17, 0x27, 0x1b, 0xc9,
+ 0xbe, 0x9b, 0xb0, 0x78, 0x3c, 0x88, 0xf7, 0x88, 0x96, 0x61, 0x8d, 0xb1,
+ 0xba, 0x31, 0xdc, 0x0c, 0x65, 0x88, 0xea, 0xa1, 0xbe, 0x9f, 0x0b, 0xf6,
+ 0x01, 0xa5, 0xe7, 0x0e, 0xe1, 0x81, 0x1a, 0x49, 0x92, 0xec, 0x4d, 0x73,
+ 0x4c, 0x6b, 0xd3, 0xbc, 0xe0, 0xfe, 0xcf, 0xdd, 0xd8, 0x3f, 0xc7, 0xb4,
+ 0x9c, 0xea, 0xba, 0x61, 0x96, 0x3f, 0x4f, 0x77, 0x5d, 0x6f, 0x7d, 0xbe,
+ 0x56, 0xfd, 0xac, 0x74, 0x85, 0xac, 0xcf, 0x1f, 0xd1, 0x27, 0xf7, 0x99,
+ 0xc3, 0x46, 0x8d, 0xf8, 0xbe, 0x8b, 0xfb, 0xcd, 0x49, 0xf0, 0xff, 0x71,
+ 0x97, 0xdd, 0xaf, 0xbb, 0x1b, 0x86, 0xd5, 0x13, 0xf9, 0xb5, 0xd5, 0x8b,
+ 0x0e, 0x91, 0x1b, 0xc8, 0xc4, 0x9f, 0x4c, 0x58, 0x2b, 0x10, 0xa3, 0xc2,
+ 0xbc, 0x49, 0x36, 0x16, 0xeb, 0xfd, 0x54, 0x1b, 0xc8, 0xc4, 0xaf, 0x81,
+ 0x3d, 0x9d, 0x02, 0xfb, 0x55, 0x1d, 0x3f, 0x2d, 0x70, 0x0c, 0x77, 0xe2,
+ 0x99, 0xb4, 0x12, 0x4a, 0x89, 0x30, 0xd5, 0xf9, 0x0e, 0x84, 0x9a, 0xfb,
+ 0xb1, 0x9f, 0xf2, 0xc9, 0x6c, 0x9a, 0xf3, 0x07, 0x7d, 0x52, 0x3c, 0x6f,
+ 0xa0, 0xf8, 0xf3, 0xf1, 0xa8, 0x1d, 0xef, 0x8b, 0x71, 0x65, 0xef, 0x1f,
+ 0x90, 0x4e, 0x9f, 0x2b, 0xf2, 0x9c, 0x06, 0xae, 0xac, 0x64, 0x1f, 0x56,
+ 0xa2, 0x29, 0xc7, 0x7d, 0x08, 0xcd, 0x70, 0x6c, 0xa1, 0xe5, 0x68, 0xad,
+ 0x83, 0xd9, 0x1a, 0xf4, 0xc5, 0x7b, 0x45, 0x7f, 0xa9, 0x8f, 0xf7, 0x14,
+ 0xfc, 0x0b, 0xf4, 0x3b, 0xc5, 0x9a, 0x69, 0xee, 0x09, 0x6e, 0x10, 0x7d,
+ 0x25, 0xee, 0x0b, 0x0e, 0x8b, 0x6f, 0x94, 0xd8, 0xe7, 0xe7, 0xfb, 0x83,
+ 0xf3, 0xfa, 0xe7, 0xbe, 0xa0, 0xe1, 0x7e, 0x89, 0x64, 0xbf, 0x3d, 0xc7,
+ 0x71, 0x58, 0x7a, 0xc0, 0x87, 0xe5, 0xc8, 0xbb, 0xe0, 0x3e, 0x11, 0xff,
+ 0x1d, 0xdc, 0x45, 0xb8, 0x60, 0xb1, 0x6a, 0xeb, 0x6f, 0x75, 0xde, 0x81,
+ 0xc4, 0x72, 0x12, 0xfa, 0x02, 0xd6, 0xe9, 0x00, 0xc5, 0xb3, 0x8c, 0x39,
+ 0x18, 0x60, 0x5d, 0xb2, 0xbd, 0x59, 0x7d, 0x27, 0xca, 0x2b, 0x06, 0x22,
+ 0x9d, 0x6e, 0xcc, 0xe6, 0x16, 0x51, 0x4d, 0x60, 0x62, 0xaf, 0x56, 0x8f,
+ 0x5a, 0x2b, 0x06, 0xb8, 0x09, 0x47, 0x42, 0xf6, 0xd2, 0x3c, 0xe9, 0x31,
+ 0x19, 0x1e, 0xba, 0x77, 0x92, 0x72, 0xd3, 0xfe, 0x4e, 0x7b, 0xee, 0xb6,
+ 0xfc, 0x4d, 0xd8, 0x47, 0x1e, 0x5f, 0xaf, 0x46, 0x31, 0xea, 0xf7, 0x52,
+ 0xac, 0xf9, 0x56, 0x75, 0xce, 0xcf, 0xc8, 0x36, 0x79, 0xbd, 0x4d, 0xb5,
+ 0xb6, 0x1e, 0x96, 0xc9, 0x76, 0xed, 0x25, 0x1b, 0x75, 0xb4, 0xd6, 0xd6,
+ 0xce, 0x0d, 0xe8, 0x19, 0xf5, 0x8a, 0x57, 0xd3, 0xf7, 0x98, 0xa1, 0x46,
+ 0x1a, 0x47, 0x36, 0x5b, 0x53, 0xa5, 0xb7, 0x35, 0xff, 0xcf, 0xb5, 0x5c,
+ 0xa7, 0x7b, 0x29, 0x8f, 0x3c, 0x98, 0x73, 0x20, 0x50, 0xbd, 0x1e, 0xcf,
+ 0x87, 0xa0, 0x75, 0xd4, 0x01, 0x4d, 0x82, 0xae, 0xf1, 0xdc, 0xbc, 0x86,
+ 0x8c, 0x46, 0xf2, 0x93, 0x6f, 0xc7, 0x13, 0xf8, 0x20, 0xeb, 0xc4, 0x7a,
+ 0xca, 0xef, 0x6b, 0xd3, 0x3a, 0xce, 0x95, 0x6b, 0x79, 0x3d, 0xb2, 0xc3,
+ 0xf9, 0x71, 0x4e, 0x1a, 0xe7, 0xc6, 0x74, 0xfe, 0x8b, 0xf4, 0x05, 0x88,
+ 0xe6, 0x22, 0x8d, 0xe5, 0x7b, 0xe7, 0xad, 0xbe, 0xc0, 0xf1, 0x6b, 0xea,
+ 0x29, 0xc7, 0x38, 0xf7, 0x8a, 0xec, 0x5c, 0xd0, 0xad, 0xb1, 0x2e, 0x7d,
+ 0xb8, 0x3c, 0x61, 0xe0, 0xdc, 0xca, 0x06, 0x5c, 0x99, 0x68, 0xc5, 0x03,
+ 0x39, 0x0f, 0x2e, 0x4c, 0x98, 0xb8, 0x69, 0x39, 0xee, 0x09, 0x12, 0x06,
+ 0x6b, 0x20, 0xbf, 0xff, 0x29, 0xd5, 0x3c, 0x14, 0x4f, 0x89, 0xd2, 0x48,
+ 0x62, 0x1d, 0xd9, 0x75, 0x34, 0x86, 0xd4, 0x2d, 0xf1, 0x48, 0xe8, 0x3c,
+ 0xbe, 0x67, 0x52, 0x2c, 0xf6, 0x4b, 0x7a, 0xaf, 0x70, 0x5a, 0xfb, 0x84,
+ 0x1b, 0xac, 0x7d, 0x45, 0xc7, 0xf4, 0xb0, 0x90, 0x4a, 0xd7, 0xfa, 0xf5,
+ 0x97, 0xe5, 0x21, 0xce, 0x3d, 0x9c, 0x23, 0xc7, 0x4d, 0x97, 0xba, 0xc1,
+ 0xea, 0xd3, 0xec, 0xce, 0x5f, 0xcd, 0x4d, 0x57, 0xf3, 0xd1, 0xce, 0x6a,
+ 0x1e, 0x1a, 0x29, 0xbc, 0xf3, 0x05, 0xfc, 0x14, 0xaa, 0xee, 0x57, 0x70,
+ 0xfe, 0x71, 0x8b, 0xb3, 0x64, 0x0e, 0x7b, 0xc8, 0x07, 0x8f, 0x6a, 0x27,
+ 0x82, 0x94, 0x21, 0xe0, 0xec, 0x10, 0x78, 0x90, 0xcf, 0x8b, 0x04, 0x4c,
+ 0xdc, 0xa9, 0xd9, 0xf6, 0xb0, 0xbc, 0xd3, 0x85, 0x41, 0xca, 0x49, 0xae,
+ 0x98, 0x97, 0x7c, 0xdd, 0x8f, 0xd7, 0x34, 0xb6, 0xe1, 0x5b, 0xaa, 0x39,
+ 0x89, 0xf7, 0xbf, 0xed, 0xbd, 0xea, 0xdf, 0xee, 0x5b, 0xcf, 0xdb, 0xa6,
+ 0x86, 0xe4, 0x42, 0x78, 0xde, 0x8b, 0xab, 0x54, 0x37, 0xc8, 0x54, 0x33,
+ 0xac, 0x47, 0x62, 0x81, 0x92, 0x64, 0xfd, 0xfb, 0x68, 0xee, 0x5f, 0x76,
+ 0x0e, 0xe2, 0xfe, 0x71, 0x07, 0xea, 0x54, 0x8e, 0xb3, 0x06, 0xf6, 0x37,
+ 0x72, 0x9c, 0xea, 0xc5, 0x8e, 0x71, 0xb7, 0x38, 0x99, 0x73, 0xe2, 0xc9,
+ 0xbe, 0x47, 0xb0, 0xa0, 0x63, 0x4b, 0xb5, 0xd7, 0xc9, 0xdf, 0xbf, 0x89,
+ 0xd4, 0x22, 0x5e, 0x9f, 0x7b, 0x68, 0x02, 0xde, 0x0e, 0xe6, 0x03, 0x9e,
+ 0x8b, 0x34, 0xff, 0xe6, 0x51, 0xa7, 0x38, 0x9f, 0xfe, 0x1b, 0xf3, 0x48,
+ 0x80, 0x71, 0x01, 0xdf, 0xab, 0x87, 0xd1, 0xc8, 0x63, 0x59, 0x87, 0x5e,
+ 0xaa, 0x49, 0x07, 0x31, 0x4a, 0x74, 0xbd, 0x6e, 0xcd, 0x75, 0xb6, 0x4a,
+ 0xbf, 0x57, 0x34, 0x64, 0x64, 0x23, 0x48, 0xb4, 0xf8, 0x57, 0xf6, 0xa1,
+ 0xa1, 0x74, 0x6d, 0xbe, 0x25, 0xa3, 0xf7, 0x30, 0x7f, 0x9c, 0x13, 0x06,
+ 0xf0, 0x41, 0x5a, 0xe0, 0x7d, 0xcb, 0x06, 0x07, 0xd0, 0x5a, 0xa0, 0xfa,
+ 0xdf, 0x8a, 0x21, 0x3c, 0x2e, 0x6e, 0xdb, 0xb6, 0x63, 0x10, 0xdb, 0x89,
+ 0x97, 0x7a, 0xe2, 0xe5, 0xe3, 0xd8, 0x12, 0x5a, 0x87, 0xaf, 0x1d, 0x93,
+ 0xab, 0xfd, 0x87, 0xea, 0x5c, 0xab, 0xc0, 0xbd, 0x29, 0xa7, 0x1a, 0xc1,
+ 0xb6, 0xf1, 0x48, 0xbf, 0xd7, 0xc1, 0x76, 0x18, 0xc1, 0x7d, 0xd3, 0x49,
+ 0xba, 0xcf, 0x73, 0x05, 0xb1, 0x29, 0xe3, 0x14, 0xef, 0x52, 0x9d, 0x74,
+ 0x3c, 0xed, 0x58, 0x24, 0xe1, 0x07, 0xe6, 0x93, 0x81, 0x1d, 0xb8, 0x45,
+ 0xeb, 0xc5, 0xbd, 0x64, 0x83, 0xdd, 0xad, 0x3b, 0x30, 0x41, 0x36, 0xb0,
+ 0xb9, 0x89, 0x6a, 0xb7, 0x58, 0xd9, 0x1c, 0x08, 0xb0, 0x1c, 0x05, 0x7a,
+ 0xe8, 0x7a, 0x23, 0xd5, 0x73, 0x8e, 0x18, 0x59, 0x1b, 0xf9, 0x85, 0xac,
+ 0x2a, 0xb9, 0x24, 0xea, 0xad, 0x35, 0x1b, 0x29, 0x4f, 0xbb, 0x18, 0x1f,
+ 0xf8, 0x18, 0x27, 0x7c, 0x91, 0x1e, 0xc3, 0xac, 0x55, 0xd5, 0xe8, 0x7a,
+ 0x47, 0x6b, 0x6e, 0x8e, 0x6c, 0x76, 0x4d, 0xc7, 0xb5, 0xcf, 0xcd, 0xcb,
+ 0x48, 0x43, 0x4d, 0xc7, 0x8c, 0x59, 0xf1, 0x8f, 0xc0, 0xdf, 0x71, 0xad,
+ 0xee, 0xe7, 0xe7, 0x60, 0x9a, 0xed, 0xb8, 0x16, 0x72, 0x44, 0xfc, 0xf7,
+ 0xe0, 0xaf, 0x68, 0x8d, 0x20, 0x36, 0x96, 0x7a, 0x31, 0x30, 0x2e, 0x7d,
+ 0x8e, 0x4f, 0x7c, 0x6c, 0xcb, 0x9f, 0xf3, 0xbf, 0x75, 0x3c, 0xd2, 0xe3,
+ 0xa9, 0xf2, 0x7f, 0xef, 0xf4, 0xe7, 0x73, 0x0d, 0x67, 0x38, 0xaf, 0xf2,
+ 0x7c, 0xbc, 0xef, 0x37, 0x2f, 0xdf, 0x20, 0xb6, 0x5b, 0xf3, 0xed, 0x75,
+ 0xb3, 0x0f, 0xbb, 0xc8, 0xd7, 0xd7, 0x75, 0x18, 0x78, 0x2d, 0xf1, 0x80,
+ 0xb9, 0xd5, 0x92, 0xc1, 0x9f, 0x58, 0xcf, 0xf7, 0xb4, 0x56, 0x2c, 0x7b,
+ 0xb7, 0xfd, 0x96, 0xf7, 0x04, 0x78, 0x8f, 0x60, 0x7e, 0x5f, 0x20, 0x6a,
+ 0xed, 0xd7, 0xd9, 0x7b, 0x03, 0xdf, 0xa2, 0x38, 0xcb, 0xfb, 0x06, 0xb2,
+ 0x70, 0x8e, 0xd7, 0x09, 0xd7, 0x38, 0xd3, 0xf6, 0x81, 0x6c, 0xfb, 0xd8,
+ 0x5f, 0x21, 0x19, 0xe0, 0xfe, 0xa4, 0x6d, 0xff, 0xd1, 0xce, 0xfb, 0x80,
+ 0xa7, 0x0c, 0x77, 0xed, 0x0a, 0x50, 0x8d, 0xdf, 0x67, 0xd9, 0xc3, 0x75,
+ 0xfa, 0xdb, 0xab, 0xfe, 0xb1, 0x95, 0xeb, 0x7c, 0xee, 0x09, 0xbe, 0xbb,
+ 0x6a, 0xb2, 0x55, 0x22, 0x3c, 0xc5, 0x6b, 0xf2, 0xde, 0x02, 0xe7, 0x55,
+ 0x2b, 0xee, 0x7a, 0x1a, 0x57, 0x18, 0xee, 0x05, 0x2b, 0x9c, 0x62, 0x51,
+ 0xa6, 0x9f, 0x6c, 0x4f, 0x45, 0x22, 0x63, 0x78, 0x9a, 0x57, 0x84, 0xf0,
+ 0x50, 0x66, 0x3e, 0x26, 0xb7, 0xa3, 0x7d, 0x0a, 0xf8, 0xdf, 0x99, 0x20,
+ 0xda, 0x26, 0xc2, 0x43, 0xb7, 0x3b, 0xc2, 0xc3, 0xef, 0x38, 0xf8, 0x5e,
+ 0xa1, 0xeb, 0x26, 0x0b, 0x7f, 0x1f, 0xed, 0x5a, 0x66, 0x7d, 0xbe, 0xdd,
+ 0x75, 0x63, 0xe1, 0x6e, 0xa4, 0xe7, 0xdc, 0x97, 0xf3, 0x0e, 0x13, 0x0f,
+ 0xc5, 0x1c, 0xf8, 0x9a, 0xf6, 0xd7, 0xe4, 0x5b, 0x82, 0x6c, 0xe3, 0x18,
+ 0xe7, 0x60, 0x4b, 0xa7, 0xae, 0x15, 0x2a, 0xda, 0x32, 0x8d, 0x84, 0xd7,
+ 0x9a, 0xa8, 0xe6, 0x6f, 0xc4, 0x0f, 0x73, 0x8c, 0xd7, 0x4c, 0x8a, 0xfb,
+ 0x26, 0x5e, 0xef, 0x30, 0x86, 0x82, 0x50, 0x8c, 0x37, 0x85, 0x92, 0xba,
+ 0xdd, 0xa1, 0x1c, 0x69, 0x72, 0xf8, 0xb1, 0x2f, 0x62, 0xe7, 0xd1, 0x4e,
+ 0x2b, 0x6f, 0xbe, 0xd3, 0x65, 0xf7, 0xec, 0x4e, 0x56, 0xf3, 0xeb, 0xa9,
+ 0x2e, 0x6d, 0x56, 0x39, 0x9a, 0x22, 0xff, 0x59, 0x48, 0xf1, 0x73, 0x3c,
+ 0x9b, 0xb2, 0xce, 0x82, 0xfc, 0x32, 0x53, 0x43, 0xb6, 0x11, 0xd6, 0xc6,
+ 0x11, 0x8e, 0x3e, 0x64, 0xd1, 0xfa, 0xb3, 0xae, 0x58, 0xa1, 0x8c, 0x8a,
+ 0x53, 0x39, 0x08, 0x14, 0x09, 0x37, 0xb4, 0xf9, 0x5f, 0x46, 0x99, 0xfb,
+ 0xa1, 0x56, 0xa0, 0x67, 0x1e, 0x5a, 0x0b, 0x40, 0x2e, 0xe3, 0xbe, 0x0c,
+ 0xab, 0x17, 0xeb, 0xc0, 0x5a, 0x6d, 0x3b, 0xe1, 0x42, 0xde, 0xff, 0x15,
+ 0x54, 0x63, 0x37, 0xa2, 0xb2, 0xc1, 0x89, 0xf1, 0x0c, 0xe7, 0xe1, 0x63,
+ 0x5d, 0xf2, 0x28, 0x2a, 0x6e, 0x7b, 0x4f, 0x33, 0xe1, 0xa6, 0x0c, 0x3d,
+ 0x57, 0x22, 0x4c, 0x4a, 0xb1, 0x63, 0x6b, 0xec, 0x37, 0x66, 0xb2, 0xd1,
+ 0xde, 0x53, 0x19, 0x9d, 0x14, 0x58, 0xa0, 0x26, 0x31, 0x3a, 0xe7, 0xf4,
+ 0xa5, 0xd3, 0x51, 0xa4, 0xcb, 0xfc, 0xbc, 0xfb, 0x72, 0xd2, 0x9a, 0x3f,
+ 0xb2, 0x77, 0x89, 0xc3, 0x81, 0x65, 0x1d, 0x87, 0x50, 0x59, 0x68, 0xd3,
+ 0x10, 0x24, 0x4c, 0xc0, 0x35, 0x6c, 0x13, 0xf1, 0x7a, 0xe7, 0xe3, 0x5c,
+ 0x47, 0xfc, 0xa4, 0xeb, 0xe6, 0x29, 0xf6, 0xeb, 0x63, 0x5d, 0x1f, 0xa4,
+ 0x95, 0x64, 0x93, 0x04, 0xb9, 0x8e, 0xf8, 0xbf, 0x6f, 0x94, 0xfb, 0x08,
+ 0xbf, 0xe0, 0x3e, 0x02, 0xe5, 0x65, 0x65, 0xb8, 0x59, 0x78, 0xc5, 0xba,
+ 0x0c, 0xd5, 0x15, 0x44, 0xf3, 0xa5, 0x88, 0xd2, 0x53, 0x22, 0x8c, 0xb2,
+ 0x45, 0x50, 0x5d, 0x57, 0xb6, 0xe5, 0x65, 0x9f, 0xcd, 0xab, 0x5c, 0xc5,
+ 0x21, 0x51, 0x0b, 0x77, 0xf0, 0x3e, 0x34, 0xe7, 0x71, 0x6b, 0x4f, 0x9f,
+ 0xae, 0xff, 0xbc, 0x6b, 0x09, 0xd5, 0x16, 0x23, 0x4c, 0x1f, 0x78, 0xaf,
+ 0x8f, 0x6a, 0xd0, 0xec, 0xf1, 0x2a, 0x2e, 0xf1, 0x56, 0xe5, 0xc2, 0xdf,
+ 0xf9, 0x4c, 0xe2, 0x6b, 0x5d, 0x9b, 0x26, 0xf9, 0x8c, 0xe2, 0x4f, 0xba,
+ 0xd6, 0x4c, 0x2a, 0xa1, 0x8d, 0xb4, 0xee, 0x6e, 0xde, 0x5f, 0xa7, 0x39,
+ 0x67, 0x35, 0xa6, 0xbb, 0xd0, 0x75, 0x73, 0x96, 0x7b, 0xcb, 0xc7, 0xba,
+ 0xcc, 0x6c, 0x98, 0x31, 0xa8, 0x65, 0x2b, 0x89, 0x02, 0x55, 0xf3, 0xd7,
+ 0xd9, 0xbc, 0xba, 0x48, 0x1f, 0x87, 0xd2, 0x84, 0x76, 0xe2, 0xb6, 0x6e,
+ 0x56, 0x17, 0xd6, 0x20, 0xd5, 0xd4, 0x4d, 0x35, 0xa8, 0xdf, 0xb7, 0x36,
+ 0xd3, 0x8d, 0x09, 0xd2, 0xe1, 0xa6, 0x52, 0xd0, 0xd7, 0x9d, 0x51, 0x31,
+ 0x50, 0xe2, 0x7a, 0xb3, 0xd2, 0xb5, 0x6b, 0x72, 0xaa, 0x5a, 0xff, 0xf6,
+ 0x53, 0xcd, 0x4a, 0x76, 0x91, 0xb1, 0x6d, 0xae, 0xb5, 0x40, 0x34, 0x0b,
+ 0x7b, 0x5e, 0x37, 0xad, 0x73, 0xfd, 0xe8, 0x77, 0xcd, 0xd0, 0x42, 0xb6,
+ 0x85, 0xbb, 0xf1, 0xf8, 0x94, 0xcf, 0x08, 0xe8, 0x7e, 0x74, 0x76, 0x9c,
+ 0xa2, 0x67, 0xdb, 0xf1, 0xf8, 0xe1, 0x5b, 0x90, 0xff, 0x23, 0x27, 0x2e,
+ 0x66, 0x92, 0x58, 0xda, 0xf1, 0x55, 0x9c, 0xd9, 0x20, 0xe3, 0xef, 0x32,
+ 0x5e, 0x5c, 0x22, 0xfe, 0x0c, 0x6b, 0x8e, 0x7f, 0xcf, 0xfe, 0x90, 0x5b,
+ 0xb8, 0xc7, 0x35, 0xc6, 0x9e, 0xbf, 0xe7, 0x06, 0xf7, 0xde, 0x0c, 0xd4,
+ 0x10, 0x0e, 0x0a, 0x13, 0xcd, 0x6a, 0x86, 0xcf, 0x38, 0x05, 0x7c, 0x9c,
+ 0x2b, 0xa7, 0x89, 0x27, 0x47, 0xa9, 0xc5, 0xe7, 0x24, 0x7e, 0x9c, 0xa5,
+ 0x73, 0x14, 0x03, 0xd8, 0x07, 0xdc, 0x97, 0x43, 0x96, 0x1d, 0x5c, 0xbb,
+ 0xf6, 0x7e, 0x0f, 0xef, 0xf1, 0x1f, 0xcf, 0x72, 0x6c, 0x14, 0x54, 0xbb,
+ 0x84, 0x90, 0x9c, 0x5d, 0x82, 0x9e, 0xd9, 0xed, 0x74, 0x5d, 0x45, 0x5f,
+ 0xd5, 0xd7, 0x42, 0x05, 0x8f, 0x87, 0xf1, 0x49, 0x2e, 0x63, 0xff, 0x8e,
+ 0x5c, 0xfd, 0xed, 0x16, 0x8d, 0xe3, 0x84, 0x1d, 0x11, 0xb7, 0xf2, 0xb0,
+ 0xda, 0xf1, 0xef, 0xe2, 0xe5, 0x72, 0xca, 0xa2, 0x61, 0x37, 0xcd, 0xc5,
+ 0xb2, 0x79, 0xce, 0x4c, 0xdd, 0xc9, 0xf2, 0x0b, 0xf8, 0x7e, 0x48, 0xfa,
+ 0x98, 0xa4, 0x67, 0x1e, 0x27, 0x1e, 0xca, 0xc4, 0x5b, 0xb6, 0xf4, 0x5d,
+ 0x1a, 0xc3, 0xf7, 0x40, 0xfa, 0x32, 0x14, 0x67, 0xf5, 0x6c, 0xe6, 0x08,
+ 0xe5, 0xcb, 0x5a, 0x8a, 0x45, 0x67, 0xe3, 0xf7, 0x62, 0x6d, 0x4e, 0x49,
+ 0x1a, 0x14, 0x2e, 0x53, 0x7e, 0x08, 0xa7, 0xce, 0x36, 0xfc, 0x36, 0xd9,
+ 0x70, 0x0b, 0x61, 0x80, 0x70, 0xe8, 0x1c, 0x8d, 0x37, 0x9c, 0x32, 0x1e,
+ 0x9b, 0x90, 0x70, 0x8e, 0xf7, 0x80, 0x85, 0xfd, 0xbc, 0x01, 0x1e, 0x3b,
+ 0xff, 0xbd, 0x8e, 0xea, 0xba, 0x70, 0x82, 0xb2, 0xaa, 0x51, 0x4f, 0xb8,
+ 0xbd, 0xd0, 0xf9, 0x08, 0xf6, 0x53, 0x7d, 0xbf, 0x35, 0x46, 0x32, 0x69,
+ 0x8c, 0x53, 0xbd, 0xd1, 0x36, 0x74, 0x01, 0x7f, 0x67, 0x56, 0x78, 0x1f,
+ 0x5d, 0x84, 0x13, 0x17, 0xf0, 0x99, 0x29, 0xa9, 0xea, 0xe9, 0x19, 0xa8,
+ 0x95, 0x73, 0x68, 0x1b, 0xbe, 0x82, 0x0f, 0x4d, 0xde, 0x63, 0x97, 0x25,
+ 0x89, 0x30, 0x60, 0xd8, 0xef, 0x44, 0x00, 0x95, 0x80, 0x84, 0x5b, 0x35,
+ 0xee, 0x49, 0x2b, 0xc3, 0x4f, 0x13, 0x96, 0x7f, 0x5f, 0xb4, 0x0d, 0x7e,
+ 0x8c, 0x33, 0x66, 0xbe, 0x91, 0xd7, 0x15, 0x48, 0xdc, 0xd8, 0x76, 0xba,
+ 0x06, 0x4a, 0x8f, 0x4b, 0xa8, 0x89, 0x66, 0xe9, 0xaf, 0xcd, 0x33, 0x81,
+ 0xcf, 0x4c, 0x35, 0xf2, 0x19, 0xe1, 0x20, 0x35, 0x38, 0x4d, 0x3e, 0x31,
+ 0x88, 0x79, 0xda, 0xfe, 0x81, 0xf8, 0xd7, 0x88, 0x06, 0xc6, 0x7d, 0x86,
+ 0x7b, 0x0f, 0xd1, 0xf6, 0x53, 0xc2, 0x01, 0x5b, 0x63, 0x17, 0xcc, 0xe4,
+ 0x42, 0xeb, 0xfc, 0x5e, 0x9d, 0xdd, 0xfb, 0x66, 0x5f, 0xb9, 0x1b, 0x9b,
+ 0xd2, 0x4e, 0x92, 0xd3, 0x3c, 0x5e, 0x73, 0x51, 0x0c, 0x66, 0x8c, 0x53,
+ 0xb9, 0x9e, 0x4a, 0x33, 0xc7, 0xac, 0x0a, 0xec, 0xa2, 0xb8, 0xb0, 0xd3,
+ 0xca, 0x05, 0xf0, 0x2c, 0x5e, 0xd1, 0x81, 0x2b, 0x53, 0xff, 0xc3, 0x43,
+ 0xfa, 0x5b, 0xad, 0x2e, 0x87, 0x08, 0x66, 0x0c, 0xd1, 0xa0, 0x4b, 0xf8,
+ 0xb8, 0x53, 0xe9, 0x71, 0x48, 0xc3, 0xb8, 0x31, 0x66, 0x98, 0x5e, 0x55,
+ 0xed, 0x6f, 0x17, 0x91, 0xbe, 0x92, 0x88, 0xa2, 0xae, 0xe4, 0x95, 0xeb,
+ 0x4a, 0xed, 0xb2, 0xa7, 0x64, 0xb8, 0xfd, 0x2b, 0xee, 0xa5, 0xba, 0x65,
+ 0x07, 0xd5, 0xb6, 0x5e, 0xaa, 0xaf, 0x15, 0xb2, 0xc7, 0x1a, 0x92, 0x7f,
+ 0x88, 0xe2, 0x80, 0x0e, 0x67, 0x66, 0x1b, 0x5c, 0x99, 0xb0, 0x7f, 0x37,
+ 0x76, 0x20, 0x19, 0xb4, 0xb1, 0xad, 0x4c, 0xba, 0xaa, 0xed, 0x64, 0x2c,
+ 0x73, 0x2f, 0xce, 0xe4, 0x19, 0x9f, 0x27, 0xb0, 0x31, 0xcd, 0xbf, 0xe1,
+ 0x79, 0x39, 0xae, 0xe3, 0x28, 0xd5, 0x4e, 0xee, 0x8e, 0x66, 0xd2, 0x43,
+ 0x0b, 0x46, 0xca, 0x82, 0x4d, 0x90, 0x74, 0x01, 0xcf, 0xd1, 0x4e, 0x19,
+ 0xfb, 0x66, 0x28, 0x91, 0x50, 0x9e, 0x72, 0x92, 0x9d, 0xef, 0x26, 0x1b,
+ 0xf2, 0xaa, 0x5e, 0xfa, 0x1d, 0xe0, 0x73, 0x47, 0x64, 0x93, 0x3f, 0xe9,
+ 0x6a, 0xb7, 0x62, 0xcd, 0x2f, 0xa8, 0xc6, 0xf9, 0x15, 0xf1, 0xc2, 0xb2,
+ 0xd0, 0x51, 0x37, 0x3e, 0x5f, 0x13, 0xae, 0xb9, 0xa3, 0x0e, 0x41, 0x9a,
+ 0x33, 0x58, 0xdd, 0x23, 0x13, 0x58, 0x13, 0xeb, 0x40, 0x31, 0x27, 0xaa,
+ 0x18, 0x6b, 0x44, 0xf1, 0x62, 0x35, 0xf6, 0x53, 0xed, 0xef, 0x53, 0x37,
+ 0x22, 0xe3, 0xaf, 0x78, 0xde, 0x89, 0x73, 0x0d, 0x00, 0xcf, 0x00, 0x61,
+ 0xa8, 0xd1, 0xf4, 0x57, 0x90, 0x5f, 0x08, 0xf7, 0x3d, 0x71, 0x3e, 0x9f,
+ 0x49, 0x21, 0x4a, 0x5d, 0x8d, 0x86, 0xe5, 0xbd, 0xf8, 0xb8, 0x91, 0xf1,
+ 0xaf, 0x97, 0x62, 0x83, 0x8c, 0xdd, 0x33, 0x01, 0xeb, 0x5c, 0x04, 0xc5,
+ 0xc0, 0x2a, 0xcd, 0xd7, 0xd2, 0xfa, 0x65, 0x34, 0xb2, 0x4c, 0xfe, 0x6f,
+ 0x34, 0x92, 0xcd, 0x12, 0xe6, 0xc9, 0xa5, 0x07, 0xf0, 0x4a, 0x9a, 0xe7,
+ 0x0d, 0x27, 0x35, 0xe1, 0xe7, 0x9e, 0xbc, 0x25, 0x13, 0x63, 0x86, 0xd7,
+ 0xf0, 0x5a, 0xb1, 0xc9, 0x5e, 0x27, 0xc0, 0xbd, 0xa2, 0xff, 0xe0, 0x5a,
+ 0x1a, 0xe5, 0xc7, 0xd5, 0x54, 0x77, 0x46, 0xa1, 0x7e, 0xa3, 0x42, 0xfa,
+ 0xe0, 0x1e, 0xf5, 0x12, 0xc2, 0xbc, 0x70, 0xbf, 0x1a, 0xe7, 0x73, 0xc8,
+ 0xe6, 0x0e, 0x59, 0x37, 0x4d, 0x57, 0xa7, 0xea, 0x7f, 0x0f, 0x6c, 0x87,
+ 0x5e, 0xde, 0xeb, 0x70, 0xef, 0xee, 0xf4, 0x62, 0x1f, 0xe5, 0xc0, 0x67,
+ 0xd3, 0x6d, 0x06, 0xd7, 0x7e, 0x60, 0x1c, 0x2a, 0x52, 0xf4, 0xec, 0x50,
+ 0x1d, 0x9f, 0x09, 0xda, 0x55, 0xde, 0x06, 0x47, 0xe6, 0xb6, 0x3a, 0xae,
+ 0x37, 0x6a, 0xa8, 0x4e, 0x1e, 0x49, 0x33, 0xbd, 0xdc, 0x7b, 0x33, 0xcd,
+ 0x9d, 0x71, 0xf5, 0xf2, 0x5a, 0xb2, 0x8b, 0x66, 0x9d, 0xe5, 0x18, 0xc0,
+ 0x93, 0x34, 0x36, 0x54, 0x66, 0x59, 0x7e, 0xb7, 0x8e, 0xfb, 0x9d, 0x7b,
+ 0x48, 0xbf, 0x0d, 0x59, 0x7b, 0x9e, 0x6c, 0x79, 0x10, 0x4b, 0x46, 0x5f,
+ 0xa8, 0xb3, 0x6b, 0x1f, 0xae, 0xcb, 0x87, 0xb0, 0x27, 0x1d, 0xc0, 0x4c,
+ 0xba, 0xcd, 0xff, 0x12, 0x9c, 0xd5, 0xbc, 0xca, 0xe7, 0x88, 0xe7, 0xc7,
+ 0x04, 0x30, 0x7d, 0xf5, 0x3b, 0xcb, 0xc7, 0xee, 0x99, 0x1e, 0xb7, 0x30,
+ 0xbf, 0x8c, 0x7c, 0xc0, 0xae, 0x63, 0x28, 0x56, 0x78, 0x1e, 0x25, 0xbd,
+ 0xbe, 0x4f, 0x7a, 0x75, 0x90, 0x5e, 0x5f, 0xd2, 0xfe, 0x92, 0x31, 0x8b,
+ 0x7b, 0x57, 0xdc, 0xcb, 0xfb, 0x43, 0x06, 0x81, 0x16, 0x6b, 0x4c, 0x26,
+ 0xee, 0xc4, 0xeb, 0x94, 0x07, 0x6b, 0x28, 0xfe, 0x9d, 0x4a, 0x9b, 0xab,
+ 0xe7, 0x62, 0x6d, 0xa9, 0xf7, 0x29, 0x4f, 0x1b, 0x7f, 0xa8, 0x68, 0x67,
+ 0xc8, 0x4f, 0xb3, 0x13, 0x7f, 0x8a, 0x33, 0x8d, 0x6d, 0xfe, 0xb7, 0x60,
+ 0xb8, 0x9f, 0x88, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0xcb, 0xff, 0x0b,
+ 0x39, 0x59, 0x1c, 0x92, 0xda, 0x76, 0xf9, 0x25, 0xfc, 0x15, 0xce, 0x5c,
+ 0x17, 0xd6, 0x5e, 0x02, 0x8f, 0xb1, 0xeb, 0xf1, 0xf0, 0xec, 0xfd, 0x7c,
+ 0x1e, 0x2a, 0x48, 0xe9, 0xcc, 0xde, 0xc7, 0x4a, 0xf3, 0xbe, 0x9b, 0x40,
+ 0x7e, 0x03, 0xd5, 0xd2, 0xd6, 0x39, 0x54, 0x78, 0x9e, 0x26, 0xbf, 0x88,
+ 0x8e, 0xf1, 0xf8, 0x63, 0x5d, 0x6a, 0x21, 0x04, 0x89, 0x30, 0x0e, 0x61,
+ 0x84, 0x1e, 0x3e, 0x9f, 0xf1, 0x74, 0x3a, 0x48, 0xb9, 0xa0, 0xad, 0x2f,
+ 0x2a, 0xbe, 0x0d, 0x1b, 0x03, 0x70, 0x9e, 0x3b, 0x46, 0x79, 0x4e, 0x49,
+ 0x3d, 0x8d, 0xb6, 0x7e, 0xaf, 0xb8, 0x1b, 0xa9, 0xc6, 0xb6, 0xc1, 0xa3,
+ 0x08, 0x13, 0x66, 0x50, 0xa2, 0x67, 0x60, 0xcf, 0xb3, 0xb4, 0x20, 0x51,
+ 0x9d, 0xc8, 0x71, 0x26, 0x8d, 0xa3, 0x7e, 0x09, 0x37, 0x74, 0xa8, 0x97,
+ 0xa7, 0x31, 0x6f, 0x2f, 0xf6, 0x98, 0xd5, 0x05, 0x1a, 0x2f, 0xf9, 0x09,
+ 0xdb, 0xd4, 0xc0, 0x49, 0xb5, 0xbf, 0xa4, 0x6f, 0xc3, 0xd6, 0x34, 0xe7,
+ 0x69, 0x92, 0x0b, 0xf9, 0x66, 0x5f, 0x64, 0x1b, 0x86, 0x0a, 0x01, 0xec,
+ 0xcf, 0x86, 0xf7, 0xee, 0x26, 0x5c, 0x37, 0x56, 0x0e, 0x87, 0x36, 0x8b,
+ 0x00, 0xe9, 0x9b, 0xea, 0xff, 0xa6, 0x20, 0xd5, 0xc9, 0x7e, 0xfa, 0xb7,
+ 0xeb, 0x99, 0x53, 0x54, 0xcf, 0xbc, 0x4e, 0xbe, 0xe6, 0xad, 0xd6, 0xaa,
+ 0x4b, 0xf3, 0x26, 0xe6, 0x62, 0xeb, 0x71, 0xc9, 0xd2, 0x59, 0x90, 0x6c,
+ 0x8c, 0x73, 0x08, 0x9f, 0x8d, 0x71, 0x8b, 0xcd, 0x63, 0x86, 0xfb, 0xc1,
+ 0xce, 0x20, 0xe5, 0x34, 0xc6, 0x9c, 0x8e, 0x3f, 0x92, 0x48, 0x1e, 0x33,
+ 0xea, 0x0e, 0xac, 0x8b, 0xed, 0xc0, 0x90, 0xf6, 0x5d, 0xd4, 0x34, 0x71,
+ 0x3c, 0x92, 0x8d, 0x06, 0x9a, 0xf7, 0x42, 0x67, 0x2f, 0xc2, 0x4f, 0x31,
+ 0x3e, 0xfa, 0x19, 0xe1, 0x23, 0xf6, 0x5d, 0x9e, 0xbf, 0x51, 0x5f, 0x46,
+ 0xb8, 0xa2, 0xbe, 0xd3, 0xce, 0xf3, 0x37, 0x16, 0xf8, 0x4c, 0x26, 0xa8,
+ 0x36, 0x85, 0xe7, 0xdd, 0x95, 0x3a, 0x9e, 0xa0, 0x18, 0x93, 0x58, 0xee,
+ 0x02, 0x16, 0xf0, 0xd9, 0x63, 0xbb, 0x8e, 0x61, 0x7e, 0x97, 0x14, 0x04,
+ 0x66, 0xe3, 0x64, 0x1f, 0xff, 0xea, 0x8c, 0x51, 0xa8, 0x7a, 0x36, 0x94,
+ 0xfb, 0x27, 0x07, 0xcc, 0x24, 0xbf, 0x33, 0xe0, 0xa8, 0xf3, 0x52, 0xbc,
+ 0x0d, 0x56, 0x20, 0x79, 0x39, 0x2e, 0x4b, 0xea, 0xbc, 0xdc, 0x59, 0xd6,
+ 0x47, 0x38, 0xbe, 0x5b, 0xba, 0x70, 0xd2, 0x33, 0xbb, 0x26, 0x95, 0xe1,
+ 0xdd, 0x68, 0x1b, 0xfa, 0x40, 0xd4, 0x5a, 0x3b, 0x97, 0xd3, 0xed, 0x48,
+ 0x2d, 0xd6, 0x9d, 0x1b, 0xae, 0x64, 0x57, 0x13, 0x1d, 0xe7, 0x4c, 0x5c,
+ 0xb7, 0xc6, 0xda, 0xdf, 0x9a, 0x6e, 0xff, 0x73, 0x9a, 0x9b, 0xbf, 0x3f,
+ 0xe0, 0xe5, 0x33, 0x93, 0xc7, 0xb3, 0x2f, 0x9a, 0xd1, 0x85, 0xb6, 0x7c,
+ 0x4e, 0x90, 0xef, 0x07, 0x75, 0x07, 0x9a, 0xd5, 0xc8, 0xe5, 0x7e, 0xfa,
+ 0xfd, 0xb7, 0x05, 0x42, 0xfb, 0x2b, 0x07, 0xf1, 0xab, 0xbc, 0x8e, 0xc7,
+ 0x28, 0x0f, 0x34, 0xa8, 0x8a, 0x3f, 0xcf, 0xfb, 0xd7, 0x31, 0x9b, 0xff,
+ 0x9b, 0xf2, 0xe4, 0x87, 0x8d, 0x7e, 0xab, 0xc6, 0xb0, 0xf9, 0x2b, 0x10,
+ 0x7f, 0x03, 0x5e, 0xf6, 0x85, 0xc5, 0xe4, 0x17, 0x7b, 0xc9, 0x5f, 0x1f,
+ 0x23, 0x5b, 0xa3, 0x0a, 0x9e, 0xfc, 0x40, 0xd9, 0x0b, 0xf2, 0xd7, 0xb1,
+ 0x34, 0xcb, 0x3f, 0xe8, 0x1b, 0x18, 0xe5, 0xb8, 0x6b, 0xf5, 0x55, 0xb5,
+ 0x90, 0x83, 0xe3, 0xae, 0x15, 0x4f, 0x8d, 0x90, 0xe3, 0xd7, 0x75, 0x4c,
+ 0xd7, 0x48, 0x39, 0x1c, 0xf4, 0xf0, 0x79, 0x7e, 0x02, 0x87, 0x03, 0x9a,
+ 0x9d, 0x2b, 0xe7, 0x28, 0x1f, 0x5d, 0x22, 0x3a, 0xf6, 0xc7, 0x9a, 0x91,
+ 0xa2, 0x7c, 0x94, 0x51, 0x6d, 0x5b, 0x52, 0x67, 0x19, 0x63, 0xfe, 0x82,
+ 0x30, 0xa6, 0x12, 0x72, 0x49, 0x6d, 0xc3, 0x27, 0xb1, 0xcd, 0x3c, 0xd3,
+ 0xc8, 0x36, 0xe5, 0xc2, 0xe1, 0xf6, 0x59, 0xb3, 0x12, 0x60, 0x7e, 0x25,
+ 0xbc, 0xa8, 0x91, 0xcd, 0x5c, 0x17, 0x0e, 0xbe, 0x48, 0x39, 0x75, 0xa6,
+ 0xaa, 0x8f, 0x70, 0x61, 0xde, 0x1e, 0x63, 0x2c, 0xeb, 0x68, 0x0a, 0x6a,
+ 0xa2, 0x80, 0x3f, 0xa6, 0xef, 0xad, 0xc1, 0x4b, 0x55, 0x5b, 0x5d, 0x36,
+ 0xfb, 0xdf, 0xbd, 0xd5, 0x77, 0x6c, 0xac, 0x67, 0x42, 0x85, 0xfb, 0xe9,
+ 0x37, 0xcf, 0x19, 0xe0, 0xb3, 0x2d, 0x7c, 0xd6, 0xca, 0xb3, 0xb5, 0xb3,
+ 0x86, 0xfd, 0xc5, 0xcf, 0xef, 0x15, 0xac, 0x1b, 0xe3, 0xbe, 0x30, 0xf7,
+ 0x68, 0x24, 0xec, 0xbe, 0xfa, 0xde, 0x03, 0x7f, 0xf6, 0xe0, 0xd6, 0x31,
+ 0xee, 0x45, 0x9c, 0xb8, 0x59, 0xc6, 0x3f, 0x51, 0x1e, 0x96, 0xd9, 0xe7,
+ 0xc9, 0xd7, 0x7f, 0xd4, 0x75, 0x6a, 0x92, 0x73, 0xea, 0xdb, 0x5d, 0x9b,
+ 0xd2, 0xf3, 0x3a, 0xbe, 0xca, 0xd3, 0xe9, 0x7b, 0x28, 0xee, 0x64, 0xd2,
+ 0xca, 0x70, 0x44, 0xb2, 0xf6, 0xd5, 0x52, 0x25, 0xf1, 0x15, 0x2a, 0xd2,
+ 0x78, 0xbe, 0x5e, 0xf4, 0x8f, 0x85, 0xa8, 0xb6, 0xf1, 0xfb, 0x1e, 0x38,
+ 0x60, 0x52, 0xae, 0x70, 0xe2, 0xe9, 0xd1, 0xb0, 0xf6, 0x26, 0xe1, 0x9d,
+ 0x67, 0x46, 0x4d, 0xf3, 0x4d, 0x0d, 0x7f, 0xd2, 0x40, 0x35, 0x72, 0xbb,
+ 0x50, 0x12, 0x84, 0x0d, 0x42, 0xeb, 0x45, 0x5b, 0xb0, 0x00, 0xe5, 0xf4,
+ 0x4e, 0x9a, 0xef, 0x50, 0x11, 0x78, 0xb1, 0xe8, 0xc1, 0x0b, 0x63, 0xdc,
+ 0xfb, 0xf3, 0xa0, 0xf4, 0x54, 0x93, 0x6f, 0xdb, 0x81, 0x10, 0xc5, 0x58,
+ 0x19, 0xbd, 0x87, 0x12, 0xb8, 0xf5, 0x80, 0x40, 0x34, 0x92, 0x40, 0xcf,
+ 0xa1, 0x7a, 0xac, 0x1f, 0x93, 0x71, 0x31, 0x5e, 0x8f, 0xdb, 0x9e, 0x9a,
+ 0xe7, 0xe3, 0x9d, 0x6a, 0x9d, 0x27, 0x5b, 0xe7, 0xd8, 0x8e, 0x66, 0x39,
+ 0x66, 0x53, 0xbe, 0xc8, 0x72, 0x0c, 0x34, 0xcd, 0x60, 0xa7, 0xdd, 0xe7,
+ 0x78, 0x8e, 0xf2, 0xc7, 0x13, 0x9d, 0x6a, 0x30, 0xe8, 0xd0, 0x71, 0xc3,
+ 0x44, 0xe5, 0xdb, 0x0d, 0x30, 0x8f, 0xf3, 0x1e, 0xc6, 0xa7, 0xed, 0xa6,
+ 0x79, 0x6b, 0x3c, 0x72, 0x99, 0x2a, 0x3b, 0xf2, 0xa9, 0xb7, 0xc9, 0xa7,
+ 0x5a, 0xf0, 0x44, 0x76, 0x7e, 0xaf, 0x4b, 0xed, 0xbf, 0x20, 0x19, 0x3b,
+ 0xfc, 0x30, 0x3f, 0xa9, 0xd5, 0xcd, 0x4f, 0x5d, 0x7a, 0x24, 0xb8, 0x5d,
+ 0xf0, 0x19, 0x11, 0xee, 0x89, 0x9b, 0xe6, 0xd9, 0xb8, 0x69, 0x16, 0xe3,
+ 0x86, 0x7b, 0xd9, 0x0a, 0x3f, 0x0e, 0x2d, 0xe5, 0x77, 0x0d, 0xc2, 0xc9,
+ 0x66, 0xb2, 0x2f, 0xcf, 0x52, 0x35, 0xb8, 0x91, 0xea, 0x2b, 0x83, 0x82,
+ 0x5c, 0x68, 0xa1, 0xd2, 0x0f, 0xb4, 0xf8, 0xf6, 0x8f, 0x36, 0xe1, 0x99,
+ 0xb9, 0xdf, 0xe5, 0xe3, 0x39, 0x56, 0x3f, 0xed, 0x13, 0x0d, 0xab, 0x1b,
+ 0x10, 0x49, 0x6e, 0x01, 0xf7, 0x46, 0xf9, 0x4c, 0xaa, 0x81, 0xdb, 0xe2,
+ 0x83, 0xd8, 0x3a, 0xc6, 0xfb, 0x6b, 0x3f, 0xef, 0xfa, 0x64, 0xcc, 0xfc,
+ 0x5b, 0x37, 0xd1, 0xbf, 0xba, 0xb3, 0x2d, 0xe5, 0xb1, 0xde, 0x55, 0x3a,
+ 0x49, 0x75, 0x40, 0x23, 0xca, 0x33, 0x6a, 0x65, 0xb1, 0x48, 0xbe, 0xe9,
+ 0x45, 0x24, 0xd8, 0x4c, 0xb1, 0x6a, 0x8e, 0x7c, 0x77, 0xa6, 0xcc, 0x75,
+ 0xc0, 0x2f, 0xbb, 0xcc, 0x89, 0x45, 0x98, 0x9e, 0xa3, 0xb9, 0xb2, 0x6a,
+ 0xcf, 0x47, 0x84, 0xf3, 0xea, 0x74, 0xb3, 0xc1, 0xa3, 0x47, 0x4e, 0xb7,
+ 0x09, 0x09, 0x97, 0x97, 0x9b, 0x66, 0x6f, 0xa7, 0x3a, 0x5c, 0x2f, 0x30,
+ 0xe4, 0xd0, 0xd5, 0x44, 0xbb, 0x84, 0xaf, 0x06, 0x11, 0xe9, 0x39, 0x8b,
+ 0x48, 0xff, 0x39, 0x8a, 0x61, 0xcf, 0x96, 0xf9, 0x9c, 0xef, 0x23, 0xf8,
+ 0xdb, 0xb1, 0x85, 0x38, 0x3e, 0xf3, 0x50, 0xb5, 0x27, 0x06, 0xcf, 0x8d,
+ 0x2b, 0x74, 0x1c, 0x26, 0xbd, 0x9e, 0xd4, 0x6a, 0x28, 0xae, 0xcb, 0x70,
+ 0xb4, 0x42, 0x6e, 0xa4, 0x3a, 0x21, 0xf6, 0xb8, 0x69, 0x2e, 0x6b, 0xb5,
+ 0x6b, 0x9e, 0x65, 0xb3, 0xd7, 0xbe, 0xa3, 0x30, 0xdf, 0xef, 0x09, 0x92,
+ 0xfe, 0xda, 0x52, 0x5b, 0xc5, 0x49, 0xd3, 0xf8, 0x43, 0x41, 0x3c, 0xdf,
+ 0x56, 0x0f, 0x0f, 0xf3, 0x2d, 0x63, 0xe7, 0x04, 0xf7, 0xe1, 0x58, 0x6f,
+ 0xf0, 0xf4, 0xc4, 0x79, 0x9f, 0x9c, 0x75, 0x54, 0xf1, 0xac, 0x8b, 0x53,
+ 0x4c, 0x14, 0x3e, 0xc2, 0x53, 0x86, 0xbb, 0x9b, 0xf2, 0x53, 0xed, 0x18,
+ 0xbf, 0x2f, 0xe1, 0xc5, 0x63, 0x14, 0x37, 0x2e, 0x69, 0x75, 0xd8, 0xdf,
+ 0xc8, 0xb6, 0xc3, 0x74, 0x72, 0xcf, 0x70, 0x1b, 0xee, 0xe5, 0x77, 0x4e,
+ 0xca, 0xbf, 0x6b, 0x9d, 0x0d, 0xa4, 0x6b, 0x84, 0x0d, 0x98, 0x8e, 0xf9,
+ 0xf5, 0x7b, 0xb0, 0x78, 0x94, 0xf5, 0x78, 0xac, 0x2b, 0x48, 0x32, 0x7a,
+ 0x82, 0xec, 0xc2, 0xa1, 0x77, 0x43, 0x26, 0x5b, 0x5c, 0x1b, 0xbf, 0x76,
+ 0x0e, 0x75, 0xe8, 0x9c, 0x44, 0xf5, 0x9d, 0xc4, 0xfb, 0x79, 0x4a, 0xe2,
+ 0x88, 0xb8, 0x76, 0xce, 0x7c, 0x3d, 0xf7, 0x13, 0x8d, 0x19, 0x3b, 0x2f,
+ 0x1d, 0xa6, 0xbc, 0xf4, 0x4a, 0x8e, 0x7d, 0xe4, 0x17, 0x96, 0x8f, 0x38,
+ 0x28, 0xd6, 0xae, 0x49, 0x87, 0x70, 0x4e, 0x83, 0x5a, 0x83, 0x18, 0xd1,
+ 0x1d, 0xe9, 0xe9, 0xae, 0x62, 0x3e, 0x17, 0xc5, 0xff, 0x99, 0x9c, 0x32,
+ 0x68, 0xf5, 0x9f, 0x54, 0xa5, 0x8f, 0x3f, 0x79, 0xef, 0x3f, 0xa8, 0x0f,
+ 0xa1, 0x61, 0x25, 0x70, 0x7e, 0x94, 0xfb, 0x55, 0xbc, 0xcf, 0x35, 0x2c,
+ 0xae, 0xf0, 0x7b, 0x61, 0xb5, 0x43, 0x78, 0x2f, 0xce, 0xef, 0x5b, 0xb1,
+ 0xef, 0x3d, 0x0c, 0xf6, 0xbd, 0x06, 0x1a, 0xfb, 0xc9, 0x68, 0x38, 0xd4,
+ 0x43, 0x7e, 0x33, 0x00, 0xeb, 0xbc, 0x90, 0x36, 0x6b, 0xf7, 0xc7, 0x93,
+ 0xa7, 0xaa, 0xfb, 0x5b, 0x91, 0xea, 0xde, 0x5c, 0xb4, 0xd0, 0x23, 0x2e,
+ 0x15, 0x98, 0xa6, 0xb7, 0x89, 0xa6, 0x6e, 0xf1, 0xe1, 0xec, 0x3a, 0x71,
+ 0x71, 0xb6, 0x57, 0x9c, 0x2d, 0x70, 0x4c, 0xfe, 0x79, 0xd7, 0xae, 0x1c,
+ 0xe7, 0xb3, 0x3b, 0xc5, 0xbb, 0xf9, 0x0d, 0xe2, 0x42, 0xa1, 0x5f, 0x7c,
+ 0x34, 0x6b, 0xe0, 0xfe, 0x78, 0x2f, 0x0a, 0x63, 0xf0, 0xbb, 0xf5, 0xfb,
+ 0xc5, 0xa5, 0xbc, 0xdd, 0x27, 0xbc, 0x50, 0x68, 0xf1, 0x15, 0xd2, 0x5c,
+ 0x03, 0x1f, 0xa3, 0x1a, 0x78, 0x91, 0xef, 0x99, 0xc9, 0x80, 0xaf, 0x34,
+ 0xa9, 0x0c, 0xde, 0x23, 0x4c, 0xf3, 0xb6, 0xd8, 0x69, 0xd6, 0xa1, 0xf9,
+ 0x5a, 0xcc, 0xc6, 0x07, 0x3b, 0x49, 0x1e, 0x9b, 0x29, 0xb7, 0x4c, 0x6b,
+ 0x6d, 0x55, 0x2c, 0xc2, 0xb6, 0xce, 0xbc, 0x72, 0xae, 0xe6, 0xfd, 0xa7,
+ 0x21, 0x38, 0x3b, 0x81, 0xbd, 0xe9, 0xcf, 0x79, 0xbd, 0x44, 0xbc, 0x1a,
+ 0xae, 0x21, 0x7c, 0x4c, 0xbc, 0xbe, 0x3e, 0xfa, 0xf9, 0x7e, 0x9e, 0x93,
+ 0xc6, 0xee, 0x4a, 0x87, 0x53, 0x47, 0x84, 0x52, 0x29, 0xd8, 0xfb, 0x79,
+ 0x9a, 0x57, 0x52, 0x4e, 0x8f, 0x50, 0x1d, 0xd1, 0x2a, 0xd9, 0xbc, 0x26,
+ 0xaa, 0xbc, 0xde, 0x44, 0xbc, 0x5e, 0x2c, 0x70, 0x7d, 0xfe, 0x76, 0xd7,
+ 0x1b, 0xa3, 0x63, 0x66, 0x3d, 0xd5, 0xff, 0x75, 0x6a, 0xb7, 0xb8, 0x40,
+ 0x3c, 0x7f, 0x48, 0x3c, 0x7f, 0x5c, 0xb8, 0x53, 0x7c, 0x44, 0x7c, 0x5e,
+ 0x2c, 0xf0, 0x1e, 0x9e, 0x5b, 0x7c, 0x98, 0xb3, 0x79, 0xfc, 0xf0, 0x2a,
+ 0x8f, 0x41, 0xdf, 0xfe, 0x74, 0x93, 0xef, 0xd1, 0x49, 0xbf, 0x6f, 0xcf,
+ 0xa4, 0x69, 0x7e, 0xa8, 0x49, 0x3e, 0xe6, 0xeb, 0x55, 0xed, 0x8b, 0x7c,
+ 0xdd, 0x4c, 0x7c, 0xf1, 0xfe, 0xeb, 0x6f, 0xeb, 0x70, 0x9e, 0xaf, 0xc7,
+ 0xac, 0x73, 0x6c, 0xf6, 0x19, 0xa9, 0x7a, 0xde, 0x83, 0x25, 0xbe, 0x7c,
+ 0x74, 0xfd, 0x95, 0x7f, 0xcd, 0xd7, 0xe0, 0x05, 0xd2, 0x5f, 0xb1, 0xca,
+ 0x57, 0xfd, 0xbf, 0xc9, 0x17, 0xd5, 0xba, 0x63, 0xcc, 0x57, 0xa3, 0xfe,
+ 0xc6, 0x98, 0x49, 0xfa, 0x92, 0xac, 0x77, 0xc1, 0x8a, 0xd9, 0x1d, 0x78,
+ 0x25, 0xc6, 0xef, 0xc7, 0x45, 0x42, 0x47, 0x28, 0x9e, 0xce, 0x96, 0x3d,
+ 0xa2, 0xc6, 0xda, 0x87, 0xc5, 0x1b, 0xb5, 0x44, 0xd3, 0xe1, 0x19, 0x7e,
+ 0xff, 0x0b, 0x1a, 0x61, 0x01, 0x3f, 0xbf, 0x37, 0x37, 0x0d, 0xee, 0x97,
+ 0xf5, 0x8a, 0x86, 0x22, 0xef, 0xbb, 0x6e, 0x10, 0xbe, 0x22, 0x9f, 0xa3,
+ 0xeb, 0x11, 0xde, 0x62, 0xb7, 0xf0, 0x1c, 0x32, 0x4c, 0x8f, 0xba, 0x4e,
+ 0xd4, 0x1d, 0xba, 0x53, 0x78, 0xaa, 0x7b, 0xb0, 0xee, 0x62, 0xd0, 0x97,
+ 0xbe, 0x46, 0x1e, 0x17, 0xb5, 0x9b, 0x2d, 0x79, 0xbc, 0xa6, 0xcd, 0xef,
+ 0x1f, 0x5a, 0xe7, 0x10, 0xf9, 0x1c, 0x9c, 0x27, 0x48, 0xb5, 0x53, 0x43,
+ 0xb5, 0x76, 0x7a, 0x37, 0xc6, 0xe7, 0x7b, 0x0c, 0x92, 0x3f, 0x42, 0x4e,
+ 0x5d, 0xe9, 0x3f, 0x21, 0xd4, 0xd4, 0xfd, 0x22, 0x79, 0xab, 0x97, 0xea,
+ 0x9f, 0xad, 0xb1, 0x48, 0xf2, 0x06, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15,
+ 0x4d, 0xae, 0x2d, 0x19, 0xd8, 0x43, 0xf1, 0xed, 0xe5, 0x9c, 0x83, 0xb0,
+ 0x03, 0xbf, 0x43, 0xe6, 0xc4, 0x5a, 0xbf, 0x17, 0x4f, 0x12, 0xee, 0x78,
+ 0x22, 0x3b, 0x88, 0x27, 0x0b, 0x03, 0x78, 0xa2, 0xf0, 0xaf, 0xde, 0x95,
+ 0x91, 0x3d, 0xfa, 0xf9, 0x95, 0xd5, 0x33, 0x08, 0x89, 0xeb, 0x23, 0x1c,
+ 0xa3, 0x1f, 0x6e, 0x97, 0x23, 0x5c, 0xeb, 0xbe, 0x75, 0xf3, 0x07, 0x2a,
+ 0xfb, 0xa2, 0xba, 0xe2, 0x94, 0x85, 0x45, 0x1e, 0x59, 0x7e, 0xc8, 0x3a,
+ 0x1b, 0x95, 0xbe, 0x69, 0x97, 0xf5, 0x4e, 0xe7, 0x3b, 0x2b, 0x36, 0xa9,
+ 0xec, 0x0f, 0x0f, 0xc7, 0xd7, 0x58, 0xf9, 0xf5, 0x6f, 0x56, 0xd9, 0x3d,
+ 0x9a, 0x77, 0x56, 0x5d, 0x6f, 0xf7, 0xd1, 0x56, 0x45, 0xad, 0xcf, 0x33,
+ 0xab, 0xec, 0xfd, 0xed, 0x4f, 0x57, 0xb5, 0x5a, 0x9f, 0xe7, 0x57, 0xd9,
+ 0x3e, 0xf5, 0xee, 0x2a, 0xd5, 0xfa, 0xfc, 0x87, 0x55, 0x76, 0x5e, 0xbe,
+ 0xb4, 0x6a, 0xc9, 0xd5, 0xf7, 0x63, 0xf8, 0xef, 0xff, 0x00, 0x88, 0xf4,
+ 0x23, 0x6f, 0xec, 0x3a, 0x00, 0x00, 0x00 };
static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
@@ -4582,15 +4513,15 @@ static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
0x00000000 };
static struct fw_info bnx2_txp_fw_09 = {
- /* Firmware version: 4.4.23 */
+ /* Firmware version: 4.6.15 */
.ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
+ .ver_minor = 0x6,
+ .ver_fix = 0xf,
- .start_addr = 0x08000094,
+ .start_addr = 0x08000098,
.text_addr = 0x08000000,
- .text_len = 0x3b1c,
+ .text_len = 0x3ae8,
.text_index = 0x0,
.gz_text = bnx2_TXP_b09FwText,
.gz_text_len = sizeof(bnx2_TXP_b09FwText),
@@ -4600,15 +4531,15 @@ static struct fw_info bnx2_txp_fw_09 = {
.data_index = 0x0,
.data = bnx2_TXP_b09FwData,
- .sbss_addr = 0x08003b80,
+ .sbss_addr = 0x08003b40,
.sbss_len = 0x6c,
.sbss_index = 0x0,
- .bss_addr = 0x08003bec,
+ .bss_addr = 0x08003bac,
.bss_len = 0x24c,
.bss_index = 0x0,
- .rodata_addr = 0x08003b1c,
+ .rodata_addr = 0x08003ae8,
.rodata_len = 0x30,
.rodata_index = 0x0,
.rodata = bnx2_TXP_b09FwRodata,
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 6fcccef4cf3d..15a5cf0f676b 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -1,6 +1,6 @@
/* bnx2x.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 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
@@ -271,14 +271,7 @@ struct bnx2x_fastpath {
#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
-#define BNX2X_HAS_TX_WORK(fp) \
- ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \
- (fp->tx_pkt_prod != fp->tx_pkt_cons))
-
-#define BNX2X_HAS_RX_WORK(fp) \
- (fp->rx_comp_cons != rx_cons_sb)
-
-#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
+#define BNX2X_HAS_WORK(fp) (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))
/* MC hsi */
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index fefa6ab13064..aea26b4dc453 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -1,4 +1,4 @@
-/* Copyright 2008 Broadcom Corporation
+/* Copyright 2008-2009 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params,
val &= ~0x810;
EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
+ /* enable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+
/* enable emac for jumbo packets */
EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
(EMAC_RX_MTU_SIZE_JUMBO_ENA |
@@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
u32 gp_status)
{
struct bnx2x *bp = params->bp;
-
+ u16 new_line_speed;
u8 rc = 0;
vars->link_status = 0;
@@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
switch (gp_status & GP_STATUS_SPEED_MASK) {
case GP_STATUS_10M:
- vars->line_speed = SPEED_10;
+ new_line_speed = SPEED_10;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_10TFD;
else
@@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
case GP_STATUS_100M:
- vars->line_speed = SPEED_100;
+ new_line_speed = SPEED_100;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_100TXFD;
else
@@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_1G:
case GP_STATUS_1G_KX:
- vars->line_speed = SPEED_1000;
+ new_line_speed = SPEED_1000;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_1000TFD;
else
@@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
case GP_STATUS_2_5G:
- vars->line_speed = SPEED_2500;
+ new_line_speed = SPEED_2500;
if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_2500TFD;
else
@@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_10G_KX4:
case GP_STATUS_10G_HIG:
case GP_STATUS_10G_CX4:
- vars->line_speed = SPEED_10000;
+ new_line_speed = SPEED_10000;
vars->link_status |= LINK_10GTFD;
break;
case GP_STATUS_12G_HIG:
- vars->line_speed = SPEED_12000;
+ new_line_speed = SPEED_12000;
vars->link_status |= LINK_12GTFD;
break;
case GP_STATUS_12_5G:
- vars->line_speed = SPEED_12500;
+ new_line_speed = SPEED_12500;
vars->link_status |= LINK_12_5GTFD;
break;
case GP_STATUS_13G:
- vars->line_speed = SPEED_13000;
+ new_line_speed = SPEED_13000;
vars->link_status |= LINK_13GTFD;
break;
case GP_STATUS_15G:
- vars->line_speed = SPEED_15000;
+ new_line_speed = SPEED_15000;
vars->link_status |= LINK_15GTFD;
break;
case GP_STATUS_16G:
- vars->line_speed = SPEED_16000;
+ new_line_speed = SPEED_16000;
vars->link_status |= LINK_16GTFD;
break;
@@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break;
}
+ /* Upon link speed change set the NIG into drain mode.
+ Comes to deals with possible FIFO glitch due to clk change
+ when speed is decreased without link down indicator */
+ if (new_line_speed != vars->line_speed) {
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ + params->port*4, 0);
+ msleep(1);
+ }
+ vars->line_speed = new_line_speed;
vars->link_status |= LINK_STATUS_SERDES_LINK;
if ((params->req_line_speed == SPEED_AUTO_NEG) &&
@@ -3571,7 +3583,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params,
(MDIO_REG_BANK_CL73_IEEEB0 +
(MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
0x6041);
-
+ msleep(200);
/* set aer mmd back */
bnx2x_set_aer_mmd(params, vars);
@@ -3870,9 +3882,15 @@ static u8 bnx2x_link_initialize(struct link_params *params,
}
if (vars->phy_flags & PHY_XGXS_FLAG) {
- if (params->req_line_speed &&
+ if ((params->req_line_speed &&
((params->req_line_speed == SPEED_100) ||
- (params->req_line_speed == SPEED_10))) {
+ (params->req_line_speed == SPEED_10))) ||
+ (!params->req_line_speed &&
+ (params->speed_cap_mask >=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
+ (params->speed_cap_mask <
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ )) {
vars->phy_flags |= PHY_SGMII_FLAG;
} else {
vars->phy_flags &= ~PHY_SGMII_FLAG;
@@ -4194,6 +4212,11 @@ static u8 bnx2x_update_link_down(struct link_params *params,
/* activate nig drain */
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+
/* reset BigMac */
bnx2x_bmac_rx_disable(bp, params->port);
REG_WR(bp, GRCBASE_MISC +
@@ -4238,6 +4261,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
/* update shared memory */
bnx2x_update_mng(params, vars->link_status);
+ msleep(20);
return rc;
}
/* This function should called upon link interrupt */
@@ -4276,6 +4300,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Check external link change only for non-direct */
@@ -4377,10 +4404,11 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
ext_phy_addr[port],
MDIO_PMA_DEVAD,
MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- if (fw_ver1 == 0) {
+ if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
DP(NETIF_MSG_LINK,
- "bnx2x_8073_common_init_phy port %x "
- "fw Download failed\n", port);
+ "bnx2x_8073_common_init_phy port %x:"
+ "Download failed. fw version = 0x%x\n",
+ port, fw_ver1);
return -EINVAL;
}
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 7c533797c064..d3e7775a9ccf 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1,6 +1,6 @@
/* bnx2x_main.c: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 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
@@ -57,8 +57,8 @@
#include "bnx2x.h"
#include "bnx2x_init.h"
-#define DRV_MODULE_VERSION "1.45.23"
-#define DRV_MODULE_RELDATE "2008/11/03"
+#define DRV_MODULE_VERSION "1.45.26"
+#define DRV_MODULE_RELDATE "2009/01/26"
#define BNX2X_BC_VER 0x040200
/* Time in jiffies before concluding the transmitter is hung */
@@ -69,7 +69,7 @@ static char version[] __devinitdata =
DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Eliezer Tamir");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
@@ -733,6 +733,24 @@ static u16 bnx2x_ack_int(struct bnx2x *bp)
* fast path service functions
*/
+static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
+{
+ u16 tx_cons_sb;
+
+ /* Tell compiler that status block fields can change */
+ barrier();
+ tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb);
+ return (fp->tx_pkt_cons != tx_cons_sb);
+}
+
+static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
+{
+ /* Tell compiler that consumer and producer can change */
+ barrier();
+ return (fp->tx_pkt_prod != fp->tx_pkt_cons);
+
+}
+
/* free skb in the packet ring at pos idx
* return idx of last bd freed
*/
@@ -5137,12 +5155,21 @@ static void enable_blocks_attention(struct bnx2x *bp)
}
+static void bnx2x_reset_common(struct bnx2x *bp)
+{
+ /* reset_common */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+ 0xd3ffff7f);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
+}
+
static int bnx2x_init_common(struct bnx2x *bp)
{
u32 val, i;
DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp));
+ bnx2x_reset_common(bp);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
@@ -6123,8 +6150,8 @@ static void bnx2x_netif_start(struct bnx2x *bp)
static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
{
bnx2x_int_disable_sync(bp, disable_hw);
+ bnx2x_napi_disable(bp);
if (netif_running(bp->dev)) {
- bnx2x_napi_disable(bp);
netif_tx_disable(bp->dev);
bp->dev->trans_start = jiffies; /* prevent tx timeout */
}
@@ -6144,7 +6171,7 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
* multicast 64-127:port0 128-191:port1
*/
config->hdr.length_6b = 2;
- config->hdr.offset = port ? 31 : 0;
+ config->hdr.offset = port ? 32 : 0;
config->hdr.client_id = BP_CL_ID(bp);
config->hdr.reserved1 = 0;
@@ -6308,7 +6335,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
u32 load_code;
- int i, rc;
+ int i, rc = 0;
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
return -EPERM;
@@ -6316,48 +6343,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
- /* Send LOAD_REQUEST command to MCP
- Returns the type of LOAD command:
- if it is the first port to be initialized
- common blocks should be initialized, otherwise - not
- */
- if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
- if (!load_code) {
- BNX2X_ERR("MCP response failure, aborting\n");
- return -EBUSY;
- }
- if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
- return -EBUSY; /* other port in diagnostic mode */
-
- } else {
- int port = BP_PORT(bp);
-
- DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- load_count[0]++;
- load_count[1 + port]++;
- DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- if (load_count[0] == 1)
- load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
- else if (load_count[1 + port] == 1)
- load_code = FW_MSG_CODE_DRV_LOAD_PORT;
- else
- load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
- }
-
- if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
- (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
- bp->port.pmf = 1;
- else
- bp->port.pmf = 0;
- DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
-
- /* if we can't use MSI-X we only need one fp,
- * so try to enable MSI-X with the requested number of fp's
- * and fallback to inta with one fp
- */
if (use_inta) {
bp->num_queues = 1;
@@ -6372,7 +6357,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
else
bp->num_queues = 1;
- if (bnx2x_enable_msix(bp)) {
+ DP(NETIF_MSG_IFUP,
+ "set number of queues to %d\n", bp->num_queues);
+
+ /* if we can't use MSI-X we only need one fp,
+ * so try to enable MSI-X with the requested number of fp's
+ * and fallback to MSI or legacy INTx with one fp
+ */
+ rc = bnx2x_enable_msix(bp);
+ if (rc) {
/* failed to enable MSI-X */
bp->num_queues = 1;
if (use_multi)
@@ -6380,8 +6373,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
" to enable MSI-X\n");
}
}
- DP(NETIF_MSG_IFUP,
- "set number of queues to %d\n", bp->num_queues);
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
@@ -6390,30 +6381,85 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_fp(bp, i, disable_tpa) =
((bp->flags & TPA_ENABLE_FLAG) == 0);
+ for_each_queue(bp, i)
+ netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+ bnx2x_poll, 128);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ fp->poll_no_work = 0;
+ fp->poll_calls = 0;
+ fp->poll_max_calls = 0;
+ fp->poll_complete = 0;
+ fp->poll_exit = 0;
+ }
+#endif
+ bnx2x_napi_enable(bp);
+
if (bp->flags & USING_MSIX_FLAG) {
rc = bnx2x_req_msix_irqs(bp);
if (rc) {
pci_disable_msix(bp->pdev);
- goto load_error;
+ goto load_error1;
}
+ printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
} else {
bnx2x_ack_int(bp);
rc = bnx2x_req_irq(bp);
if (rc) {
- BNX2X_ERR("IRQ request failed, aborting\n");
- goto load_error;
+ BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
+ goto load_error1;
}
}
- for_each_queue(bp, i)
- netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
- bnx2x_poll, 128);
+ /* Send LOAD_REQUEST command to MCP
+ Returns the type of LOAD command:
+ if it is the first port to be initialized
+ common blocks should be initialized, otherwise - not
+ */
+ if (!BP_NOMCP(bp)) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+ if (!load_code) {
+ BNX2X_ERR("MCP response failure, aborting\n");
+ rc = -EBUSY;
+ goto load_error2;
+ }
+ if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ rc = -EBUSY; /* other port in diagnostic mode */
+ goto load_error2;
+ }
+
+ } else {
+ int port = BP_PORT(bp);
+
+ DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ load_count[0]++;
+ load_count[1 + port]++;
+ DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ if (load_count[0] == 1)
+ load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
+ else if (load_count[1 + port] == 1)
+ load_code = FW_MSG_CODE_DRV_LOAD_PORT;
+ else
+ load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
+ }
+
+ if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
+ bp->port.pmf = 1;
+ else
+ bp->port.pmf = 0;
+ DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
/* Initialize HW */
rc = bnx2x_init_hw(bp, load_code);
if (rc) {
BNX2X_ERR("HW init failed, aborting\n");
- goto load_int_disable;
+ goto load_error2;
}
/* Setup NIC internals and enable interrupts */
@@ -6425,7 +6471,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (!load_code) {
BNX2X_ERR("MCP response failure, aborting\n");
rc = -EBUSY;
- goto load_rings_free;
+ goto load_error3;
}
}
@@ -6434,7 +6480,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
rc = bnx2x_setup_leading(bp);
if (rc) {
BNX2X_ERR("Setup leading failed!\n");
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1H(bp))
@@ -6447,7 +6493,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
for_each_nondefault_queue(bp, i) {
rc = bnx2x_setup_multi(bp, i);
if (rc)
- goto load_netif_stop;
+ goto load_error3;
}
if (CHIP_IS_E1(bp))
@@ -6463,18 +6509,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
case LOAD_NORMAL:
/* Tx queue should be only reenabled */
netif_wake_queue(bp->dev);
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_OPEN:
netif_start_queue(bp->dev);
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
- if (bp->flags & USING_MSIX_FLAG)
- printk(KERN_INFO PFX "%s: using MSI-X\n",
- bp->dev->name);
break;
case LOAD_DIAG:
+ /* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
bp->state = BNX2X_STATE_DIAG;
break;
@@ -6492,20 +6538,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
return 0;
-load_netif_stop:
- bnx2x_napi_disable(bp);
-load_rings_free:
+load_error3:
+ bnx2x_int_disable_sync(bp, 1);
+ if (!BP_NOMCP(bp)) {
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+ }
+ bp->port.pmf = 0;
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-load_int_disable:
- bnx2x_int_disable_sync(bp, 1);
+load_error2:
/* Release IRQs */
bnx2x_free_irq(bp);
-load_error:
+load_error1:
+ bnx2x_napi_disable(bp);
+ for_each_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
- bp->port.pmf = 0;
/* TBD we really need to reset the chip
if we want to recover from this */
@@ -6578,6 +6629,7 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
}
cnt--;
msleep(1);
+ rmb(); /* Refresh the dsb_sp_prod */
}
bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
@@ -6629,14 +6681,6 @@ static void bnx2x_reset_port(struct bnx2x *bp)
/* TODO: Close Doorbell port? */
}
-static void bnx2x_reset_common(struct bnx2x *bp)
-{
- /* reset_common */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0xd3ffff7f);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
-}
-
static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
{
DP(BNX2X_MSG_MCP, "function %d reset_code %x\n",
@@ -6677,20 +6721,22 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bnx2x_set_storm_rx_mode(bp);
bnx2x_netif_stop(bp, 1);
- if (!netif_running(bp->dev))
- bnx2x_napi_disable(bp);
+
del_timer_sync(&bp->timer);
SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
(DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+
/* Wait until tx fast path tasks complete */
for_each_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
cnt = 1000;
smp_rmb();
- while (BNX2X_HAS_TX_WORK(fp)) {
+ while (bnx2x_has_tx_work_unload(fp)) {
bnx2x_tx_int(fp, 1000);
if (!cnt) {
@@ -6711,9 +6757,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
/* Give HW time to discard old tx messages */
msleep(1);
- /* Release IRQs */
- bnx2x_free_irq(bp);
-
if (CHIP_IS_E1(bp)) {
struct mac_configuration_cmd *config =
bnx2x_sp(bp, mcast_config);
@@ -6822,6 +6865,8 @@ unload_error:
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+ for_each_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
@@ -6874,10 +6919,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
*/
bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
- if (val == 0x7)
- REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
-
if (val == 0x7) {
u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
/* save our func */
@@ -6885,6 +6926,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
u32 swap_en;
u32 swap_val;
+ /* clear the UNDI indication */
+ REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
+
BNX2X_DEV_INFO("UNDI is active! reset device\n");
/* try unload UNDI on port 0 */
@@ -6910,6 +6954,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
bnx2x_fw_command(bp, reset_code);
}
+ /* now it's safe to release the lock */
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
+
REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
HC_REG_CONFIG_0), 0x1000);
@@ -6954,7 +7001,9 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
bp->fw_seq =
(SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
DRV_MSG_SEQ_NUMBER_MASK);
- }
+
+ } else
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
}
}
@@ -6971,7 +7020,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
id |= ((val & 0xf) << 12);
val = REG_RD(bp, MISC_REG_CHIP_METAL);
id |= ((val & 0xff) << 4);
- REG_RD(bp, MISC_REG_BOND_ID);
+ val = REG_RD(bp, MISC_REG_BOND_ID);
id |= (val & 0xf);
bp->common.chip_id = id;
bp->link_params.chip_id = bp->common.chip_id;
@@ -8103,6 +8152,9 @@ static int bnx2x_get_eeprom(struct net_device *dev,
struct bnx2x *bp = netdev_priv(dev);
int rc;
+ if (!netif_running(dev))
+ return -EAGAIN;
+
DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
@@ -8705,18 +8757,17 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
if (loopback_mode == BNX2X_MAC_LOOPBACK) {
bp->link_params.loopback_mode = LOOPBACK_BMAC;
- bnx2x_acquire_phy_lock(bp);
bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
} else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
+ u16 cnt = 1000;
bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
- bnx2x_acquire_phy_lock(bp);
bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
/* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
-
+ if (link_up)
+ while (cnt-- && bnx2x_test_link(&bp->link_params,
+ &bp->link_vars))
+ msleep(10);
} else
return -EINVAL;
@@ -8822,6 +8873,7 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
return BNX2X_LOOPBACK_FAILED;
bnx2x_netif_stop(bp, 1);
+ bnx2x_acquire_phy_lock(bp);
if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
@@ -8833,6 +8885,7 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
rc |= BNX2X_PHY_LOOPBACK_FAILED;
}
+ bnx2x_release_phy_lock(bp);
bnx2x_netif_start(bp);
return rc;
@@ -8906,7 +8959,10 @@ static int bnx2x_test_intr(struct bnx2x *bp)
return -ENODEV;
config->hdr.length_6b = 0;
- config->hdr.offset = 0;
+ if (CHIP_IS_E1(bp))
+ config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
+ else
+ config->hdr.offset = BP_FUNC(bp);
config->hdr.client_id = BP_CL_ID(bp);
config->hdr.reserved1 = 0;
@@ -9271,6 +9327,18 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
return 0;
}
+static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
+{
+ u16 rx_cons_sb;
+
+ /* Tell compiler that status block fields can change */
+ barrier();
+ rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+ if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+ rx_cons_sb++;
+ return (fp->rx_comp_cons != rx_cons_sb);
+}
+
/*
* net_device service functions
*/
@@ -9281,7 +9349,6 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
napi);
struct bnx2x *bp = fp->bp;
int work_done = 0;
- u16 rx_cons_sb;
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -9294,19 +9361,12 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
bnx2x_update_fpsb_idx(fp);
- if (BNX2X_HAS_TX_WORK(fp))
+ if (bnx2x_has_tx_work(fp))
bnx2x_tx_int(fp, budget);
- rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
- if (BNX2X_HAS_RX_WORK(fp))
+ if (bnx2x_has_rx_work(fp))
work_done = bnx2x_rx_int(fp, budget);
-
rmb(); /* BNX2X_HAS_WORK() reads the status block */
- rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
/* must not complete if we consumed full budget */
if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
@@ -9417,6 +9477,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
return rc;
}
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
/* check if packet requires linearization (packet is too fragmented) */
static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
u32 xmit_type)
@@ -9494,6 +9555,7 @@ exit_lbl:
return to_copy;
}
+#endif
/* called with netif_tx_lock
* bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
@@ -9534,6 +9596,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
/* First, check if we need to linearize the skb
(due to FW restrictions) */
if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
@@ -9546,6 +9609,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
}
+#endif
/*
Please read carefully. First we use one BD which we mark as start,
@@ -9776,6 +9840,8 @@ static int bnx2x_open(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
+ netif_carrier_off(dev);
+
bnx2x_set_power_state(bp, PCI_D0);
return bnx2x_nic_load(bp, LOAD_OPEN);
@@ -9859,7 +9925,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
for (; i < old; i++) {
if (CAM_IS_INVALID(config->
config_table[i])) {
- i--; /* already invalidated */
+ /* already invalidated */
break;
}
/* invalidate */
@@ -10269,22 +10335,18 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
return rc;
}
- rc = register_netdev(dev);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register net device\n");
- goto init_one_exit;
- }
-
pci_set_drvdata(pdev, dev);
rc = bnx2x_init_bp(bp);
+ if (rc)
+ goto init_one_exit;
+
+ rc = register_netdev(dev);
if (rc) {
- unregister_netdev(dev);
+ dev_err(&pdev->dev, "Cannot register net device\n");
goto init_one_exit;
}
- netif_carrier_off(dev);
-
bp->common.name = board_info[ent->driver_data].name;
printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
" IRQ %d, ", dev->name, bp->common.name,
@@ -10432,6 +10494,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
bnx2x_free_skbs(bp);
for_each_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+ for_each_queue(bp, i)
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
bp->state = BNX2X_STATE_CLOSED;
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index a67b0c358ae4..d084e5fc4b51 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -1,6 +1,6 @@
/* bnx2x_reg.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 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
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 840b3d1a22f5..bbbc3bb08aa5 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -806,7 +806,7 @@ static int cas_reset_mii_phy(struct cas *cp)
cas_phy_write(cp, MII_BMCR, BMCR_RESET);
udelay(100);
- while (limit--) {
+ while (--limit) {
val = cas_phy_read(cp, MII_BMCR);
if ((val & BMCR_RESET) == 0)
break;
@@ -979,7 +979,7 @@ static void cas_phy_init(struct cas *cp)
writel(val, cp->regs + REG_PCS_MII_CTRL);
limit = STOP_TRIES;
- while (limit-- > 0) {
+ while (--limit > 0) {
udelay(10);
if ((readl(cp->regs + REG_PCS_MII_CTRL) &
PCS_MII_RESET) == 0)
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index f66548751c38..79741c5f9fe7 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -1161,7 +1161,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
- priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id,
+ priv->phy = phy_connect(dev, dev_name(&cpmac_mii->phy_map[phy_id]->dev),
&cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv))
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 0089746b8d02..bab8a934c33d 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -90,6 +90,7 @@ static const struct pci_device_id cxgb3_pci_tbl[] = {
CH_DEVICE(0x30, 2), /* T3B10 */
CH_DEVICE(0x31, 3), /* T3B20 */
CH_DEVICE(0x32, 1), /* T3B02 */
+ CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */
{0,}
};
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 14f9fb3e8795..d31791f60292 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2104,6 +2104,7 @@ static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
{
lro_mgr->dev = qs->netdev;
lro_mgr->features = LRO_F_NAPI;
+ lro_mgr->frag_align_pad = NET_IP_ALIGN;
lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
lro_mgr->max_desc = T3_MAX_LRO_SES;
@@ -2275,8 +2276,7 @@ no_mem:
} else if ((len = ntohl(r->len_cq)) != 0) {
struct sge_fl *fl;
- if (eth)
- lro = qs->lro_enabled && is_eth_tcp(rss_hi);
+ lro &= eth && is_eth_tcp(rss_hi);
fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
if (fl->use_pages) {
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 2d1433077a8e..ac2a974dfe37 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -512,6 +512,13 @@ static const struct adapter_info t3_adap_info[] = {
F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
{ S_GPIO9, S_GPIO3 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T320"},
+ {},
+ {},
+ {1, 0,
+ F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
+ F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
+ { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
+ &mi1_mdio_ext_ops, "Chelsio T310" },
};
/*
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 7ce3053530f9..861c867fca87 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1027,7 +1027,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
printk(version);
if (bdev)
- snprintf(name, sizeof(name), "%s", bdev->bus_id);
+ snprintf(name, sizeof(name), "%s", dev_name(bdev));
else {
i = 0;
dev = root_lance_dev;
@@ -1105,10 +1105,10 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
start = to_tc_dev(bdev)->resource.start;
len = to_tc_dev(bdev)->resource.end - start + 1;
- if (!request_mem_region(start, len, bdev->bus_id)) {
+ if (!request_mem_region(start, len, dev_name(bdev))) {
printk(KERN_ERR
"%s: Unable to reserve MMIO resource\n",
- bdev->bus_id);
+ dev_name(bdev));
ret = -EBUSY;
goto err_out_dev;
}
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index e4cef491dc73..55625dbbae5a 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -606,8 +606,8 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
return -ENXIO;
- printk ("%s: %s at 0x%04lx",
- device->bus_id, depca_signature[lp->adapter], ioaddr);
+ printk("%s: %s at 0x%04lx",
+ dev_name(device), depca_signature[lp->adapter], ioaddr);
switch (lp->depca_bus) {
#ifdef CONFIG_MCA
@@ -669,7 +669,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
spin_lock_init(&lp->lock);
sprintf(lp->adapter_name, "%s (%s)",
- depca_signature[lp->adapter], device->bus_id);
+ depca_signature[lp->adapter], dev_name(device));
status = -EBUSY;
/* Initialisation Block */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 26474c92193f..6bd63cc67b3e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -31,7 +31,7 @@
char e1000_driver_name[] = "e1000";
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-#define DRV_VERSION "7.3.20-k3-NAPI"
+#define DRV_VERSION "7.3.21-k3-NAPI"
const char e1000_driver_version[] = DRV_VERSION;
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@@ -940,7 +940,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
err = pci_enable_device(pdev);
} else {
bars = pci_select_bars(pdev, IORESOURCE_MEM);
- err = pci_enable_device(pdev);
+ err = pci_enable_device_mem(pdev);
}
if (err)
return err;
@@ -3712,7 +3712,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
struct e1000_hw *hw = &adapter->hw;
u32 rctl, icr = er32(ICR);
- if (unlikely(!icr))
+ if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags)))
return IRQ_NONE; /* Not our interrupt */
/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index cf43ee743b3c..0890162953e9 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -981,11 +981,15 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
ew32(PBA_ECC, reg);
}
- /* PCI-Ex Control Register */
+ /* PCI-Ex Control Registers */
if (hw->mac.type == e1000_82574) {
reg = er32(GCR);
reg |= (1 << 22);
ew32(GCR, reg);
+
+ reg = er32(GCR2);
+ reg |= 1;
+ ew32(GCR2, reg);
}
return;
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index f25e961c6b3b..2d4ce0492df0 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -206,6 +206,7 @@ enum e1e_registers {
E1000_MANC2H = 0x05860, /* Management Control To Host - RW */
E1000_SW_FW_SYNC = 0x05B5C, /* Software-Firmware Synchronization - RW */
E1000_GCR = 0x05B00, /* PCI-Ex Control */
+ E1000_GCR2 = 0x05B64, /* PCI-Ex Control #2 */
E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
E1000_SWSM = 0x05B50, /* SW Semaphore */
E1000_FWSM = 0x05B54, /* FW Semaphore */
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index dfe92264e825..8e7c16535ad7 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3040,7 +3040,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
port->ofdev.dev.parent = &port->adapter->ofdev->dev;
port->ofdev.dev.bus = &ibmebus_bus_type;
- sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
+ dev_set_name(&port->ofdev.dev, "port%d", port_name_cnt++);
port->ofdev.dev.release = logical_port_release;
ret = of_device_register(&port->ofdev);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 7e33c129d51c..2769083bfe83 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1698,7 +1698,7 @@ static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_priva
/*
* Set MII speed to 2.5 MHz
*/
- fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
+ fep->phy_speed = (MCF_CLK / 3) / (2500000 * 2 ) * 2;
fecp->fec_mii_speed = fep->phy_speed;
fec_restart(dev, 0);
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index cd8e98b45ec5..049b0a7e01f3 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -1123,9 +1123,9 @@ static int mpc52xx_fec_of_resume(struct of_device *op)
#endif
static struct of_device_id mpc52xx_fec_match[] = {
- { .type = "network", .compatible = "fsl,mpc5200b-fec", },
- { .type = "network", .compatible = "fsl,mpc5200-fec", },
- { .type = "network", .compatible = "mpc5200-fec", },
+ { .compatible = "fsl,mpc5200b-fec", },
+ { .compatible = "fsl,mpc5200-fec", },
+ { .compatible = "mpc5200-fec", },
{ }
};
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 5b910cf63740..b8251e827059 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -6011,9 +6011,20 @@ static void nv_shutdown(struct pci_dev *pdev)
if (netif_running(dev))
nv_close(dev);
- nv_restore_mac_addr(pdev);
+ /*
+ * Restore the MAC so a kernel started by kexec won't get confused.
+ * If we really go for poweroff, we must not restore the MAC,
+ * otherwise the MAC for WOL will be reversed at least on some boards.
+ */
+ if (system_state != SYSTEM_POWER_OFF) {
+ nv_restore_mac_addr(pdev);
+ }
pci_disable_device(pdev);
+ /*
+ * Apparently it is not possible to reinitialise from D3 hot,
+ * only put the device into D3 if we really go for poweroff.
+ */
if (system_state == SYSTEM_POWER_OFF) {
if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled))
pci_enable_wake(pdev, PCI_D3hot, np->wolenabled);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index ea530673236e..9b12a13a640f 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -351,6 +351,9 @@ static int gfar_probe(struct of_device *ofdev,
/* Reset MAC layer */
gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
+ /* We need to delay at least 3 TX clocks */
+ udelay(2);
+
tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW);
gfar_write(&priv->regs->maccfg1, tempval);
@@ -1423,15 +1426,11 @@ static void gfar_vlan_rx_register(struct net_device *dev,
{
struct gfar_private *priv = netdev_priv(dev);
unsigned long flags;
- struct vlan_group *old_grp;
u32 tempval;
spin_lock_irqsave(&priv->rxlock, flags);
- old_grp = priv->vlgrp;
-
- if (old_grp == grp)
- return;
+ priv->vlgrp = grp;
if (grp) {
/* Enable VLAN tag insertion */
@@ -1630,6 +1629,12 @@ static void gfar_schedule_cleanup(struct net_device *dev)
if (netif_rx_schedule_prep(&priv->napi)) {
gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED);
__netif_rx_schedule(&priv->napi);
+ } else {
+ /*
+ * Clear IEVENT, so interrupts aren't called again
+ * because of the packets that have already arrived.
+ */
+ gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
}
spin_unlock(&priv->rxlock);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index b1a83344acc7..eaa86897f5c3 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -312,7 +312,7 @@ extern const char gfar_driver_version[];
#define ATTRELI_EI(x) (x)
#define BD_LFLAG(flags) ((flags) << 16)
-#define BD_LENGTH_MASK 0x00ff
+#define BD_LENGTH_MASK 0x0000ffff
/* TxBD status field bits */
#define TXBD_READY 0x8000
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index f3706e415b45..f49a426ad681 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -234,6 +234,8 @@ static int gfar_mdio_probe(struct of_device *ofdev,
if (NULL == new_bus)
return -ENOMEM;
+ device_init_wakeup(&ofdev->dev, 1);
+
new_bus->name = "Gianfar MII Bus",
new_bus->read = &gfar_mdio_read,
new_bus->write = &gfar_mdio_write,
diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c
index c40cd8df2212..ac9d964e59ec 100644
--- a/drivers/net/ibm_newemac/phy.c
+++ b/drivers/net/ibm_newemac/phy.c
@@ -60,7 +60,7 @@ int emac_mii_reset_phy(struct mii_phy *phy)
udelay(300);
- while (limit--) {
+ while (--limit) {
val = phy_read(phy, MII_BMCR);
if (val >= 0 && (val & BMCR_RESET) == 0)
break;
@@ -84,7 +84,7 @@ int emac_mii_reset_gpcs(struct mii_phy *phy)
udelay(300);
- while (limit--) {
+ while (--limit) {
val = gpcs_phy_read(phy, MII_BMCR);
if (val >= 0 && (val & BMCR_RESET) == 0)
break;
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index f5e2e7235fcb..13ca73f96ec6 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -699,11 +699,18 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
/* SGMII link check is done through the PCS register. */
if ((hw->phy.media_type != e1000_media_type_copper) ||
- (igb_sgmii_active_82575(hw)))
+ (igb_sgmii_active_82575(hw))) {
ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
&duplex);
- else
+ /*
+ * Use this flag to determine if link needs to be checked or
+ * not. If we have link clear the flag so that we do not
+ * continue to check for link.
+ */
+ hw->mac.get_link_status = !hw->mac.serdes_has_link;
+ } else {
ret_val = igb_check_for_copper_link(hw);
+ }
return ret_val;
}
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 5a27825cc48a..aebef8e48e76 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -300,11 +300,10 @@ struct igb_adapter {
#define IGB_FLAG_HAS_MSI (1 << 0)
#define IGB_FLAG_MSI_ENABLE (1 << 1)
-#define IGB_FLAG_HAS_DCA (1 << 2)
-#define IGB_FLAG_DCA_ENABLED (1 << 3)
-#define IGB_FLAG_IN_NETPOLL (1 << 5)
-#define IGB_FLAG_QUAD_PORT_A (1 << 6)
-#define IGB_FLAG_NEED_CTX_IDX (1 << 7)
+#define IGB_FLAG_DCA_ENABLED (1 << 2)
+#define IGB_FLAG_IN_NETPOLL (1 << 3)
+#define IGB_FLAG_QUAD_PORT_A (1 << 4)
+#define IGB_FLAG_NEED_CTX_IDX (1 << 5)
enum e1000_state_t {
__IGB_TESTING,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index b82b0fb2056c..a50db5398fa5 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -206,10 +206,11 @@ static int __init igb_init_module(void)
global_quad_port_a = 0;
- ret = pci_register_driver(&igb_driver);
#ifdef CONFIG_IGB_DCA
dca_register_notify(&dca_notifier);
#endif
+
+ ret = pci_register_driver(&igb_driver);
return ret;
}
@@ -1156,11 +1157,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* set flags */
switch (hw->mac.type) {
- case e1000_82576:
case e1000_82575:
- adapter->flags |= IGB_FLAG_HAS_DCA;
adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
break;
+ case e1000_82576:
default:
break;
}
@@ -1310,8 +1310,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
goto err_register;
#ifdef CONFIG_IGB_DCA
- if ((adapter->flags & IGB_FLAG_HAS_DCA) &&
- (dca_add_requester(&pdev->dev) == 0)) {
+ if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IGB_FLAG_DCA_ENABLED;
dev_info(&pdev->dev, "DCA enabled\n");
/* Always use CB2 mode, difference is masked
@@ -1835,11 +1834,11 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
rctl |= E1000_RCTL_SECRC;
/*
- * disable store bad packets, long packet enable, and clear size bits.
+ * disable store bad packets and clear size bits.
*/
- rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256);
+ rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_SZ_256);
- if (adapter->netdev->mtu > ETH_DATA_LEN)
+ /* enable LPE when to prevent packets larger than max_frame_size */
rctl |= E1000_RCTL_LPE;
/* Setup buffer sizes */
@@ -1865,7 +1864,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
*/
/* allocations using alloc_page take too long for regular MTU
* so only enable packet split for jumbo frames */
- if (rctl & E1000_RCTL_LPE) {
+ if (adapter->netdev->mtu > ETH_DATA_LEN) {
adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
srrctl |= adapter->rx_ps_hdr_size <<
E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
@@ -3473,19 +3472,16 @@ static int __igb_notify_dca(struct device *dev, void *data)
struct e1000_hw *hw = &adapter->hw;
unsigned long event = *(unsigned long *)data;
- if (!(adapter->flags & IGB_FLAG_HAS_DCA))
- goto out;
-
switch (event) {
case DCA_PROVIDER_ADD:
/* if already enabled, don't do it again */
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
break;
- adapter->flags |= IGB_FLAG_DCA_ENABLED;
/* Always use CB2 mode, difference is masked
* in the CB driver. */
wr32(E1000_DCA_CTRL, 2);
if (dca_add_requester(dev) == 0) {
+ adapter->flags |= IGB_FLAG_DCA_ENABLED;
dev_info(&adapter->pdev->dev, "DCA enabled\n");
igb_setup_dca(adapter);
break;
@@ -3502,7 +3498,7 @@ static int __igb_notify_dca(struct device *dev, void *data)
}
break;
}
-out:
+
return 0;
}
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 7eafdca19f34..85e88daab21a 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -585,7 +585,7 @@ static int mcs_speed_change(struct mcs_cb *mcs)
mcs_get_reg(mcs, MCS_RESV_REG, &rval);
} while(cnt++ < 100 && (rval & MCS_IRINTX));
- if(cnt >= 100) {
+ if (cnt > 100) {
IRDA_ERROR("unable to change speed\n");
ret = -EIO;
goto error;
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 31794c2363ec..e775338b525f 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -24,9 +24,8 @@
#include <mach/dma.h>
#include <mach/irda.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/regs-uart.h>
+#include <mach/regs-ost.h>
#define FICP __REG(0x40800000) /* Start of FICP area */
#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index acef3c65cd2c..d2f4d5f508b7 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -318,6 +318,9 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
+ rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
+ rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
rx_ring->cpu = cpu;
}
@@ -1741,6 +1744,32 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
}
+static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ /* add VID to filter table */
+ hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
+}
+
+static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_disable(adapter);
+
+ vlan_group_set_device(adapter->vlgrp, vid, NULL);
+
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_enable(adapter);
+
+ /* remove VID from filter table */
+ hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
+}
+
static void ixgbe_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp)
{
@@ -1760,6 +1789,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
ctrl |= IXGBE_VLNCTRL_VME;
ctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+ ixgbe_vlan_rx_add_vid(netdev, 0);
if (grp) {
/* enable VLAN tag insert/strip */
@@ -1773,32 +1803,6 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
ixgbe_irq_enable(adapter);
}
-static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
-
- /* add VID to filter table */
- hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
-}
-
-static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_disable(adapter);
-
- vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
-
- /* remove VID from filter table */
- hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
-}
-
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
{
ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp);
@@ -2074,6 +2078,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
ixgbe_irq_enable(adapter);
+ /* enable transmits */
+ netif_tx_start_all_queues(netdev);
+
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
@@ -3475,7 +3482,6 @@ static void ixgbe_watchdog_task(struct work_struct *work)
(FLOW_TX ? "TX" : "None"))));
netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
} else {
/* Force detection of hung controller */
adapter->detect_tx_hung = true;
@@ -3487,7 +3493,6 @@ static void ixgbe_watchdog_task(struct work_struct *work)
printk(KERN_INFO "ixgbe: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
}
}
@@ -4218,7 +4223,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
}
netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 83a11ff9ffd1..f011c57c9205 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -404,6 +404,9 @@
#define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
#define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
#define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
+#define IXGBE_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx rd Desc Relax Order */
+#define IXGBE_DCA_RXCTRL_DESC_WRO_EN (1 << 13) /* DCA Rx wr Desc Relax Order */
+#define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */
#define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 334ff9e12cdd..14248cfc3dfd 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -131,7 +131,8 @@ static int __init sonic_probe1(struct net_device *dev)
if (sonic_debug && version_printed++ == 0)
printk(version);
- printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr);
+ printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ",
+ dev_name(lp->device), dev->base_addr);
/*
* Put the sonic into software reset, then
@@ -156,7 +157,8 @@ static int __init sonic_probe1(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
goto out;
}
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 1d6e48e13366..75010cac76ac 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -416,6 +416,9 @@ static int korina_rx(struct net_device *dev, int limit)
if (devcs & ETH_RX_MP)
dev->stats.multicast++;
+ /* 16 bit align */
+ skb_reserve(skb_new, 2);
+
lp->rx_skb[lp->rx_next_done] = skb_new;
}
@@ -740,6 +743,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
static void korina_alloc_ring(struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
+ struct sk_buff *skb;
int i;
/* Initialize the transmit descriptors */
@@ -755,8 +759,6 @@ static void korina_alloc_ring(struct net_device *dev)
/* Initialize the receive descriptors */
for (i = 0; i < KORINA_NUM_RDS; i++) {
- struct sk_buff *skb = lp->rx_skb[i];
-
skb = dev_alloc_skb(KORINA_RBSIZE + 2);
if (!skb)
break;
@@ -769,11 +771,12 @@ static void korina_alloc_ring(struct net_device *dev)
lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]);
}
- /* loop back */
- lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[0]);
- lp->rx_next_done = 0;
+ /* loop back receive descriptors, so the last
+ * descriptor points to the first one */
+ lp->rd_ring[i - 1].link = CPHYSADDR(&lp->rd_ring[0]);
+ lp->rd_ring[i - 1].control |= DMA_DESC_COD;
- lp->rd_ring[i].control |= DMA_DESC_COD;
+ lp->rx_next_done = 0;
lp->rx_chain_head = 0;
lp->rx_chain_tail = 0;
lp->rx_chain_status = desc_empty;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index a04da4ecaa88..f4086542c358 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -211,10 +211,10 @@ static int macb_mii_probe(struct net_device *dev)
/* attach the mac to the phy */
if (pdata && pdata->is_rmii) {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
} else {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
}
@@ -321,6 +321,10 @@ static void macb_tx(struct macb *bp)
printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
bp->dev->name);
+ /* Transfer ongoing, disable transmitter, to avoid confusion */
+ if (status & MACB_BIT(TGO))
+ macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE));
+
head = bp->tx_head;
/*Mark all the buffer as used to avoid sending a lost buffer*/
@@ -343,6 +347,10 @@ static void macb_tx(struct macb *bp)
}
bp->tx_head = bp->tx_tail = 0;
+
+ /* Enable the transmitter again */
+ if (status & MACB_BIT(TGO))
+ macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
}
if (!(status & MACB_BIT(COMP)))
@@ -1069,7 +1077,7 @@ static void macb_get_drvinfo(struct net_device *dev,
strcpy(info->driver, bp->pdev->dev.driver->name);
strcpy(info->version, "$Revision: 1.14 $");
- strcpy(info->bus_info, bp->pdev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->pdev->dev));
}
static struct ethtool_ops macb_ethtool_ops = {
@@ -1226,8 +1234,8 @@ static int __init macb_probe(struct platform_device *pdev)
phydev = bp->phy_dev;
printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
return 0;
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 205bb05c25d6..527166e35d56 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -176,7 +176,8 @@ static int __init macsonic_init(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
return -ENOMEM;
}
@@ -337,7 +338,7 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n",
- lp->device->bus_id, dev->base_addr);
+ dev_name(lp->device), dev->base_addr);
/* The PowerBook's SONIC is 16 bit always. */
if (macintosh_config->ident == MAC_MODEL_PB520) {
@@ -370,10 +371,10 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
}
printk(KERN_INFO
"%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+ dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset);
#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif
@@ -525,12 +526,12 @@ static int __init mac_nubus_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: %s in slot %X\n",
- lp->device->bus_id, ndev->board->name, ndev->board->slot);
+ dev_name(lp->device), ndev->board->name, ndev->board->slot);
printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
+ dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 4e7a5faf0351..664835b822fb 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -237,7 +237,7 @@ static void mipsnet_set_mclist(struct net_device *dev)
{
}
-static int __init mipsnet_probe(struct device *dev)
+static int __init mipsnet_probe(struct platform_device *dev)
{
struct net_device *netdev;
int err;
@@ -248,7 +248,7 @@ static int __init mipsnet_probe(struct device *dev)
goto out;
}
- dev_set_drvdata(dev, netdev);
+ platform_set_drvdata(dev, netdev);
netdev->open = mipsnet_open;
netdev->stop = mipsnet_close;
@@ -293,23 +293,25 @@ out:
return err;
}
-static int __devexit mipsnet_device_remove(struct device *device)
+static int __devexit mipsnet_device_remove(struct platform_device *device)
{
- struct net_device *dev = dev_get_drvdata(device);
+ struct net_device *dev = platform_get_drvdata(device);
unregister_netdev(dev);
release_region(dev->base_addr, sizeof(struct mipsnet_regs));
free_netdev(dev);
- dev_set_drvdata(device, NULL);
+ platform_set_drvdata(device, NULL);
return 0;
}
-static struct device_driver mipsnet_driver = {
- .name = mipsnet_string,
- .bus = &platform_bus_type,
- .probe = mipsnet_probe,
- .remove = __devexit_p(mipsnet_device_remove),
+static struct platform_driver mipsnet_driver = {
+ .driver = {
+ .name = mipsnet_string,
+ .owner = THIS_MODULE,
+ },
+ .probe = mipsnet_probe,
+ .remove = __devexit_p(mipsnet_device_remove),
};
static int __init mipsnet_init_module(void)
@@ -319,7 +321,7 @@ static int __init mipsnet_init_module(void)
printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
"(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
- err = driver_register(&mipsnet_driver);
+ err = platform_driver_register(&mipsnet_driver);
if (err)
printk(KERN_ERR "Driver registration failed\n");
@@ -328,7 +330,7 @@ static int __init mipsnet_init_module(void)
static void __exit mipsnet_exit_module(void)
{
- driver_unregister(&mipsnet_driver);
+ platform_driver_unregister(&mipsnet_driver);
}
module_init(mipsnet_init_module);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 7253a499d9c8..65bbfec4d638 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -136,21 +136,23 @@ static char mv643xx_eth_driver_version[] = "1.4";
/*
* SDMA configuration register.
*/
+#define RX_BURST_SIZE_4_64BIT (2 << 1)
#define RX_BURST_SIZE_16_64BIT (4 << 1)
#define BLM_RX_NO_SWAP (1 << 4)
#define BLM_TX_NO_SWAP (1 << 5)
+#define TX_BURST_SIZE_4_64BIT (2 << 22)
#define TX_BURST_SIZE_16_64BIT (4 << 22)
#if defined(__BIG_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
- (RX_BURST_SIZE_16_64BIT | \
- TX_BURST_SIZE_16_64BIT)
+ (RX_BURST_SIZE_4_64BIT | \
+ TX_BURST_SIZE_4_64BIT)
#elif defined(__LITTLE_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
- (RX_BURST_SIZE_16_64BIT | \
- BLM_RX_NO_SWAP | \
- BLM_TX_NO_SWAP | \
- TX_BURST_SIZE_16_64BIT)
+ (RX_BURST_SIZE_4_64BIT | \
+ BLM_RX_NO_SWAP | \
+ BLM_TX_NO_SWAP | \
+ TX_BURST_SIZE_4_64BIT)
#else
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif
@@ -1173,7 +1175,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
{
struct mib_counters *p = &mp->mib_counters;
- spin_lock(&mp->mib_counters_lock);
+ spin_lock_bh(&mp->mib_counters_lock);
p->good_octets_received += mib_read(mp, 0x00);
p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
p->bad_octets_received += mib_read(mp, 0x08);
@@ -1206,7 +1208,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
p->bad_crc_event += mib_read(mp, 0x74);
p->collision += mib_read(mp, 0x78);
p->late_collision += mib_read(mp, 0x7c);
- spin_unlock(&mp->mib_counters_lock);
+ spin_unlock_bh(&mp->mib_counters_lock);
mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ);
}
@@ -1573,7 +1575,7 @@ oom:
return;
}
- mc_spec = kmalloc(0x200, GFP_KERNEL);
+ mc_spec = kmalloc(0x200, GFP_ATOMIC);
if (mc_spec == NULL)
goto oom;
mc_other = mc_spec + (0x100 >> 2);
@@ -1594,7 +1596,7 @@ oom:
entry = addr_crc(a);
}
- table[entry >> 2] |= 1 << (entry & 3);
+ table[entry >> 2] |= 1 << (8 * (entry & 3));
}
for (i = 0; i < 0x100; i += 4) {
@@ -2210,11 +2212,10 @@ static int mv643xx_eth_stop(struct net_device *dev)
struct mv643xx_eth_private *mp = netdev_priv(dev);
int i;
+ wrlp(mp, INT_MASK_EXT, 0x00000000);
wrlp(mp, INT_MASK, 0x00000000);
rdlp(mp, INT_MASK);
- del_timer_sync(&mp->mib_counters_timer);
-
napi_disable(&mp->napi);
del_timer_sync(&mp->rx_oom);
@@ -2226,6 +2227,7 @@ static int mv643xx_eth_stop(struct net_device *dev)
port_reset(mp);
mv643xx_eth_get_stats(dev);
mib_counters_update(mp);
+ del_timer_sync(&mp->mib_counters_timer);
skb_queue_purge(&mp->rx_recycle);
@@ -2586,7 +2588,7 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
phy_reset(mp);
- phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);
+ phy_attach(mp->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_GMII);
if (speed == 0) {
phy->autoneg = AUTONEG_ENABLE;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 6bb71b687f7b..e9c1296b267e 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1,7 +1,7 @@
/*************************************************************************
* myri10ge.c: Myricom Myri-10G Ethernet driver.
*
- * Copyright (C) 2005 - 2007 Myricom, Inc.
+ * Copyright (C) 2005 - 2009 Myricom, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.4.4-1.398"
+#define MYRI10GE_VERSION_STR "1.4.4-1.401"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -3786,7 +3786,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (status != 0) {
dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n",
status);
- goto abort_with_netdev;
+ goto abort_with_enabled;
}
pci_set_master(pdev);
@@ -3801,13 +3801,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
if (status != 0) {
dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
- goto abort_with_netdev;
+ goto abort_with_enabled;
}
(void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
&mgp->cmd_bus, GFP_KERNEL);
if (mgp->cmd == NULL)
- goto abort_with_netdev;
+ goto abort_with_enabled;
mgp->board_span = pci_resource_len(pdev, 0);
mgp->iomem_base = pci_resource_start(pdev, 0);
@@ -3943,8 +3943,10 @@ abort_with_mtrr:
dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
mgp->cmd, mgp->cmd_bus);
-abort_with_netdev:
+abort_with_enabled:
+ pci_disable_device(pdev);
+abort_with_netdev:
free_netdev(netdev);
return status;
}
@@ -3990,6 +3992,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
mgp->cmd, mgp->cmd_bus);
free_netdev(netdev);
+ pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
}
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index fac43fd6fc87..6a843f7350ab 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -150,7 +150,8 @@ static int __init ne3210_eisa_probe (struct device *device)
if (phys_mem < virt_to_phys(high_memory)) {
printk(KERN_CRIT "ne3210.c: Card RAM overlaps with normal memory!!!\n");
printk(KERN_CRIT "ne3210.c: Use EISA SCU to set card memory below 1MB,\n");
- printk(KERN_CRIT "ne3210.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
+ printk(KERN_CRIT "ne3210.c: or to an address above 0x%llx.\n",
+ (u64)virt_to_phys(high_memory));
printk(KERN_CRIT "ne3210.c: Driver NOT installed.\n");
retval = -EINVAL;
goto out3;
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index c11c568fd7db..f4dd9acb6877 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -146,7 +146,7 @@
#define MAX_RX_BUFFER_LENGTH 1760
#define MAX_RX_JUMBO_BUFFER_LENGTH 8062
-#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512)
+#define MAX_RX_LRO_BUFFER_LENGTH (8062)
#define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2)
#define RX_JUMBO_DMA_MAP_LEN \
(MAX_RX_JUMBO_BUFFER_LENGTH - 2)
@@ -207,11 +207,11 @@
#define MAX_CMD_DESCRIPTORS 4096
#define MAX_RCV_DESCRIPTORS 16384
-#define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4)
-#define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4)
-#define MAX_RCV_DESCRIPTORS_10G 8192
+#define MAX_CMD_DESCRIPTORS_HOST 1024
+#define MAX_RCV_DESCRIPTORS_1G 2048
+#define MAX_RCV_DESCRIPTORS_10G 4096
#define MAX_JUMBO_RCV_DESCRIPTORS 1024
-#define MAX_LRO_RCV_DESCRIPTORS 64
+#define MAX_LRO_RCV_DESCRIPTORS 8
#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS
#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS
#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS
@@ -1203,7 +1203,7 @@ typedef struct {
#define NETXEN_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
-#define MSIX_ENTRIES_PER_ADAPTER 8
+#define MSIX_ENTRIES_PER_ADAPTER 1
#define NETXEN_MSIX_TBL_SPACE 8192
#define NETXEN_PCI_REG_MSIX_TBL 0x44
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index c0bd40fcf708..0894a7be0225 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -561,7 +561,10 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
}
ring->tx_pending = adapter->max_tx_desc_count;
- ring->rx_max_pending = MAX_RCV_DESCRIPTORS;
+ if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+ ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
+ else
+ ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST;
ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS;
ring->rx_mini_max_pending = 0;
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index ca7c8d8050c9..ffd37bea1628 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -947,8 +947,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
}
for (i = 0; i < n; i++) {
if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
- netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0)
+ netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
+ kfree(buf);
return -EIO;
+ }
buf[i].addr = addr;
buf[i].data = val;
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index d854f07ef4d3..13087782ac40 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -76,6 +76,7 @@ static void netxen_nic_poll_controller(struct net_device *netdev);
#endif
static irqreturn_t netxen_intr(int irq, void *data);
static irqreturn_t netxen_msi_intr(int irq, void *data);
+static irqreturn_t netxen_msix_intr(int irq, void *data);
/* PCI Device ID Table */
#define ENTRY(device) \
@@ -200,9 +201,9 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
adapter->pci_using_dac = 1;
return 0;
}
+set_32_bit_mask:
#endif /* CONFIG_IA64 */
-set_32_bit_mask:
err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (!err)
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
@@ -371,67 +372,6 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
}
}
-#define PCI_CAP_ID_GEN 0x10
-
-static void netxen_pcie_strap_init(struct netxen_adapter *adapter)
-{
- u32 pdevfuncsave;
- u32 c8c9value = 0;
- u32 chicken = 0;
- u32 control = 0;
- int i, pos;
- struct pci_dev *pdev;
-
- pdev = adapter->pdev;
-
- adapter->hw_read_wx(adapter,
- NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4);
- /* clear chicken3.25:24 */
- chicken &= 0xFCFFFFFF;
- /*
- * if gen1 and B0, set F1020 - if gen 2, do nothing
- * if gen2 set to F1000
- */
- pos = pci_find_capability(pdev, PCI_CAP_ID_GEN);
- if (pos == 0xC0) {
- pci_read_config_dword(pdev, pos + 0x10, &control);
- if ((control & 0x000F0000) != 0x00020000) {
- /* set chicken3.24 if gen1 */
- chicken |= 0x01000000;
- }
- printk(KERN_INFO "%s Gen2 strapping detected\n",
- netxen_nic_driver_name);
- c8c9value = 0xF1000;
- } else {
- /* set chicken3.24 if gen1 */
- chicken |= 0x01000000;
- printk(KERN_INFO "%s Gen1 strapping detected\n",
- netxen_nic_driver_name);
- if (adapter->ahw.revision_id == NX_P3_B0)
- c8c9value = 0xF1020;
- else
- c8c9value = 0;
-
- }
- adapter->hw_write_wx(adapter,
- NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4);
-
- if (!c8c9value)
- return;
-
- pdevfuncsave = pdev->devfn;
- if (pdevfuncsave & 0x07)
- return;
-
- for (i = 0; i < 8; i++) {
- pci_read_config_dword(pdev, pos + 8, &control);
- pci_read_config_dword(pdev, pos + 8, &control);
- pci_write_config_dword(pdev, pos + 8, c8c9value);
- pdev->devfn++;
- }
- pdev->devfn = pdevfuncsave;
-}
-
static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
{
u32 control;
@@ -648,7 +588,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
- mem_ptr0 = ioremap(mem_base, mem_len);
+ mem_ptr0 = pci_ioremap_bar(pdev, 0);
+ if (mem_ptr0 == NULL) {
+ dev_err(&pdev->dev, "failed to map PCI bar 0\n");
+ return -EIO;
+ }
+
pci_len0 = mem_len;
first_page_group_start = 0;
first_page_group_end = 0;
@@ -735,17 +680,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
- /* ScatterGather support */
- netdev->features = NETIF_F_SG;
- netdev->features |= NETIF_F_IP_CSUM;
- netdev->features |= NETIF_F_TSO;
+ netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+ netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
if (NX_IS_REVISION_P3(revision_id)) {
- netdev->features |= NETIF_F_IPV6_CSUM;
- netdev->features |= NETIF_F_TSO6;
+ netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+ netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
}
- if (adapter->pci_using_dac)
+ if (adapter->pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
+ netdev->vlan_features |= NETIF_F_HIGHDMA;
+ }
/*
* Set the CRB window to invalid. If any register in window 0 is
@@ -810,9 +756,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
netxen_load_firmware(adapter);
- if (NX_IS_REVISION_P3(revision_id))
- netxen_pcie_strap_init(adapter);
-
if (NX_IS_REVISION_P2(revision_id)) {
/* Initialize multicast addr pool owners */
@@ -857,9 +800,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* See if the firmware gave us a virtual-physical port mapping.
*/
adapter->physical_port = adapter->portnum;
- i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum));
- if (i != 0x55555555)
- adapter->physical_port = i;
+ if (adapter->fw_major < 4) {
+ i = adapter->pci_read_normalize(adapter,
+ CRB_V2P(adapter->portnum));
+ if (i != 0x55555555)
+ adapter->physical_port = i;
+ }
adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
@@ -1083,7 +1029,9 @@ static int netxen_nic_open(struct net_device *netdev)
for (ring = 0; ring < adapter->max_rds_rings; ring++)
netxen_post_rx_buffers(adapter, ctx, ring);
}
- if (NETXEN_IS_MSI_FAMILY(adapter))
+ if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+ handler = netxen_msix_intr;
+ else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
handler = netxen_msi_intr;
else {
flags |= IRQF_SHARED;
@@ -1166,6 +1114,14 @@ static bool netxen_tso_check(struct net_device *netdev,
{
bool tso = false;
u8 opcode = TX_ETHER_PKT;
+ __be16 protocol = skb->protocol;
+ u16 flags = 0;
+
+ if (protocol == __constant_htons(ETH_P_8021Q)) {
+ struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
+ protocol = vh->h_vlan_encapsulated_proto;
+ flags = FLAGS_VLAN_TAGGED;
+ }
if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
skb_shinfo(skb)->gso_size > 0) {
@@ -1174,21 +1130,21 @@ static bool netxen_tso_check(struct net_device *netdev,
desc->total_hdr_length =
skb_transport_offset(skb) + tcp_hdrlen(skb);
- opcode = (skb->protocol == htons(ETH_P_IPV6)) ?
+ opcode = (protocol == __constant_htons(ETH_P_IPV6)) ?
TX_TCP_LSO6 : TX_TCP_LSO;
tso = true;
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
u8 l4proto;
- if (skb->protocol == htons(ETH_P_IP)) {
+ if (protocol == __constant_htons(ETH_P_IP)) {
l4proto = ip_hdr(skb)->protocol;
if (l4proto == IPPROTO_TCP)
opcode = TX_TCP_PKT;
else if(l4proto == IPPROTO_UDP)
opcode = TX_UDP_PKT;
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ } else if (protocol == __constant_htons(ETH_P_IPV6)) {
l4proto = ipv6_hdr(skb)->nexthdr;
if (l4proto == IPPROTO_TCP)
@@ -1199,7 +1155,7 @@ static bool netxen_tso_check(struct net_device *netdev,
}
desc->tcp_hdr_offset = skb_transport_offset(skb);
desc->ip_hdr_offset = skb_network_offset(skb);
- netxen_set_tx_flags_opcode(desc, 0, opcode);
+ netxen_set_tx_flags_opcode(desc, flags, opcode);
return tso;
}
@@ -1603,6 +1559,14 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
return IRQ_HANDLED;
}
+static irqreturn_t netxen_msix_intr(int irq, void *data)
+{
+ struct netxen_adapter *adapter = data;
+
+ napi_schedule(&adapter->napi);
+ return IRQ_HANDLED;
+}
+
static int netxen_nic_poll(struct napi_struct *napi, int budget)
{
struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index c38ed777f0a8..a6999403f37b 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -586,7 +586,7 @@ static int pcnet_config(struct pcmcia_device *link)
}
if ((link->conf.ConfigBase == 0x03c0)
- && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) {
+ && (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
goto failed;
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index a439ebeb4319..af28ff7ae176 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -125,6 +125,8 @@ static int __devinit mdio_gpio_bus_init(struct device *dev,
if (gpio_request(bitbang->mdio, "mdio"))
goto out_free_mdc;
+ gpio_direction_output(bitbang->mdc, 0);
+
dev_set_drvdata(dev, new_bus);
ret = mdiobus_register(new_bus);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 11adf6ed4628..811a637695ca 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -296,9 +296,8 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state)
struct phy_driver *phydrv = to_phy_driver(drv);
struct phy_device *phydev = to_phy_device(dev);
- if ((!device_may_wakeup(phydev->dev.parent)) &&
- (phydrv && phydrv->suspend))
- ret = phydrv->suspend(phydev);
+ if (drv && phydrv->suspend && !device_may_wakeup(phydev->dev.parent))
+ ret = phydrv->suspend(phydev);
return ret;
}
@@ -310,8 +309,7 @@ static int mdio_bus_resume(struct device * dev)
struct phy_driver *phydrv = to_phy_driver(drv);
struct phy_device *phydev = to_phy_device(dev);
- if ((!device_may_wakeup(phydev->dev.parent)) &&
- (phydrv && phydrv->resume))
+ if (drv && phydrv->resume && !device_may_wakeup(phydev->dev.parent))
ret = phydrv->resume(phydev);
return ret;
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index c05d38d46350..1387187543e4 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -81,6 +81,9 @@ static struct phy_driver lan83c185_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
@@ -102,6 +105,9 @@ static struct phy_driver lan8187_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
@@ -123,6 +129,9 @@ static struct phy_driver lan8700_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
@@ -144,6 +153,9 @@ static struct phy_driver lan911x_int_driver = {
.ack_interrupt = smsc_phy_ack_interrupt,
.config_intr = smsc_phy_config_intr,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
.driver = { .owner = THIS_MODULE, }
};
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index ec2314246682..335da4831ab3 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2168,7 +2168,7 @@ static void gelic_wl_connected_event(struct gelic_wl_info *wl,
complete(&wl->assoc_done);
netif_carrier_on(port_to_netdev(wl_port(wl)));
} else
- pr_debug("%s: event %#lx under wpa\n",
+ pr_debug("%s: event %#llx under wpa\n",
__func__, event);
}
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index c1dadadfab18..e6fdce9206cc 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -787,12 +787,12 @@ struct mbox_params {
struct flash_params {
u8 dev_id_str[4];
- u16 size;
- u16 csum;
- u16 ver;
- u16 sub_dev_id;
+ __le16 size;
+ __le16 csum;
+ __le16 ver;
+ __le16 sub_dev_id;
u8 mac_addr[6];
- u16 res;
+ __le16 res;
};
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 45421c8b6010..8ea72dc60f79 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -641,7 +641,7 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)
}
-static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
+static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
{
int status = 0;
/* wait for reg to come ready */
@@ -656,8 +656,11 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
FLASH_ADDR, FLASH_ADDR_RDY, FLASH_ADDR_ERR);
if (status)
goto exit;
- /* get the data */
- *data = ql_read32(qdev, FLASH_DATA);
+ /* This data is stored on flash as an array of
+ * __le32. Since ql_read32() returns cpu endian
+ * we need to swap it back.
+ */
+ *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA));
exit:
return status;
}
@@ -666,13 +669,20 @@ static int ql_get_flash_params(struct ql_adapter *qdev)
{
int i;
int status;
- u32 *p = (u32 *)&qdev->flash;
+ __le32 *p = (__le32 *)&qdev->flash;
+ u32 offset = 0;
+
+ /* Second function's parameters follow the first
+ * function's.
+ */
+ if (qdev->func)
+ offset = sizeof(qdev->flash) / sizeof(u32);
if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
return -ETIMEDOUT;
for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) {
- status = ql_read_flash_word(qdev, i, p);
+ status = ql_read_flash_word(qdev, i+offset, p);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
goto exit;
@@ -888,6 +898,7 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
lbq_desc->index);
lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
if (lbq_desc->p.lbq_page == NULL) {
+ rx_ring->lbq_clean_idx = clean_idx;
QPRINTK(qdev, RX_STATUS, ERR,
"Couldn't get a page.\n");
return;
@@ -897,6 +908,9 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
0, PAGE_SIZE,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(qdev->pdev, map)) {
+ rx_ring->lbq_clean_idx = clean_idx;
+ put_page(lbq_desc->p.lbq_page);
+ lbq_desc->p.lbq_page = NULL;
QPRINTK(qdev, RX_STATUS, ERR,
"PCI mapping failed.\n");
return;
@@ -958,6 +972,8 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
if (pci_dma_mapping_error(qdev->pdev, map)) {
QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
rx_ring->sbq_clean_idx = clean_idx;
+ dev_kfree_skb_any(sbq_desc->p.skb);
+ sbq_desc->p.skb = NULL;
return;
}
pci_unmap_addr_set(sbq_desc, mapaddr, map);
@@ -1439,12 +1455,12 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"Passing a VLAN packet upstream.\n");
- vlan_hwaccel_rx(skb, qdev->vlgrp,
+ vlan_hwaccel_receive_skb(skb, qdev->vlgrp,
le16_to_cpu(ib_mac_rsp->vlan_id));
} else {
QPRINTK(qdev, RX_STATUS, DEBUG,
"Passing a normal packet upstream.\n");
- netif_rx(skb);
+ netif_receive_skb(skb);
}
}
@@ -1501,6 +1517,11 @@ void ql_queue_asic_error(struct ql_adapter *qdev)
netif_stop_queue(qdev->ndev);
netif_carrier_off(qdev->ndev);
ql_disable_interrupts(qdev);
+ /* Clear adapter up bit to signal the recovery
+ * process that it shouldn't kill the reset worker
+ * thread
+ */
+ clear_bit(QL_ADAPTER_UP, &qdev->flags);
queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
}
@@ -1917,10 +1938,6 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
tx_ring_desc = &tx_ring->q[tx_ring->prod_idx];
mac_iocb_ptr = tx_ring_desc->queue_entry;
memset((void *)mac_iocb_ptr, 0, sizeof(mac_iocb_ptr));
- if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) != NETDEV_TX_OK) {
- QPRINTK(qdev, TX_QUEUED, ERR, "Could not map the segments.\n");
- return NETDEV_TX_BUSY;
- }
mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB;
mac_iocb_ptr->tid = tx_ring_desc->index;
@@ -1946,6 +1963,12 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
ql_hw_csum_setup(skb,
(struct ob_mac_tso_iocb_req *)mac_iocb_ptr);
}
+ if (ql_map_send(qdev, mac_iocb_ptr, skb, tx_ring_desc) !=
+ NETDEV_TX_OK) {
+ QPRINTK(qdev, TX_QUEUED, ERR,
+ "Could not map the segments.\n");
+ return NETDEV_TX_BUSY;
+ }
QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr);
tx_ring->prod_idx++;
if (tx_ring->prod_idx == tx_ring->wq_len)
@@ -2863,8 +2886,8 @@ static int ql_start_rss(struct ql_adapter *qdev)
/*
* Fill out the Indirection Table.
*/
- for (i = 0; i < 32; i++)
- hash_id[i] = i & 1;
+ for (i = 0; i < 256; i++)
+ hash_id[i] = i & (qdev->rss_ring_count - 1);
/*
* Random values for the IPv6 and IPv4 Hash Keys.
@@ -3090,7 +3113,11 @@ static int ql_adapter_down(struct ql_adapter *qdev)
netif_stop_queue(ndev);
netif_carrier_off(ndev);
- cancel_delayed_work_sync(&qdev->asic_reset_work);
+ /* Don't kill the reset worker thread if we
+ * are in the process of recovery.
+ */
+ if (test_bit(QL_ADAPTER_UP, &qdev->flags))
+ cancel_delayed_work_sync(&qdev->asic_reset_work);
cancel_delayed_work_sync(&qdev->mpi_reset_work);
cancel_delayed_work_sync(&qdev->mpi_work);
@@ -3491,7 +3518,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
static void qlge_tx_timeout(struct net_device *ndev)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
- queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
+ ql_queue_asic_error(qdev);
}
static void ql_asic_reset_work(struct work_struct *work)
@@ -3826,7 +3853,7 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *ndev = pci_get_drvdata(pdev);
struct ql_adapter *qdev = netdev_priv(ndev);
- int err;
+ int err, i;
netif_device_detach(ndev);
@@ -3836,6 +3863,9 @@ static int qlge_suspend(struct pci_dev *pdev, pm_message_t state)
return err;
}
+ for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++)
+ netif_napi_del(&qdev->rx_ring[i].napi);
+
err = pci_save_state(pdev);
if (err)
return err;
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 72fd9e97c190..b2dcdb5ed8bd 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -438,7 +438,6 @@ static void r6040_down(struct net_device *dev)
{
struct r6040_private *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->base;
- struct pci_dev *pdev = lp->pdev;
int limit = 2048;
u16 *adrp;
u16 cmd;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2c73ca606b35..0771eb6fc6eb 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -437,6 +437,22 @@ enum features {
RTL_FEATURE_GMII = (1 << 2),
};
+struct rtl8169_counters {
+ __le64 tx_packets;
+ __le64 rx_packets;
+ __le64 tx_errors;
+ __le32 rx_errors;
+ __le16 rx_missed;
+ __le16 align_errors;
+ __le32 tx_one_collision;
+ __le32 tx_multi_collision;
+ __le64 rx_unicast;
+ __le64 rx_broadcast;
+ __le32 rx_multicast;
+ __le16 tx_aborted;
+ __le16 tx_underun;
+};
+
struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
@@ -480,6 +496,7 @@ struct rtl8169_private {
unsigned features;
struct mii_if_info mii;
+ struct rtl8169_counters counters;
};
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -1100,22 +1117,6 @@ static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
"tx_underrun",
};
-struct rtl8169_counters {
- __le64 tx_packets;
- __le64 rx_packets;
- __le64 tx_errors;
- __le32 rx_errors;
- __le16 rx_missed;
- __le16 align_errors;
- __le32 tx_one_collision;
- __le32 tx_multi_collision;
- __le64 rx_unicast;
- __le64 rx_broadcast;
- __le32 rx_multicast;
- __le16 tx_aborted;
- __le16 tx_underun;
-};
-
static int rtl8169_get_sset_count(struct net_device *dev, int sset)
{
switch (sset) {
@@ -1126,16 +1127,21 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
}
}
-static void rtl8169_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
+static void rtl8169_update_counters(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct rtl8169_counters *counters;
dma_addr_t paddr;
u32 cmd;
+ int wait = 1000;
- ASSERT_RTNL();
+ /*
+ * Some chips are unable to dump tally counters when the receiver
+ * is disabled.
+ */
+ if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0)
+ return;
counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
if (!counters)
@@ -1146,31 +1152,45 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev,
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
- while (RTL_R32(CounterAddrLow) & CounterDump) {
- if (msleep_interruptible(1))
+ while (wait--) {
+ if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
+ /* copy updated counters */
+ memcpy(&tp->counters, counters, sizeof(*counters));
break;
+ }
+ udelay(10);
}
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
- data[0] = le64_to_cpu(counters->tx_packets);
- data[1] = le64_to_cpu(counters->rx_packets);
- data[2] = le64_to_cpu(counters->tx_errors);
- data[3] = le32_to_cpu(counters->rx_errors);
- data[4] = le16_to_cpu(counters->rx_missed);
- data[5] = le16_to_cpu(counters->align_errors);
- data[6] = le32_to_cpu(counters->tx_one_collision);
- data[7] = le32_to_cpu(counters->tx_multi_collision);
- data[8] = le64_to_cpu(counters->rx_unicast);
- data[9] = le64_to_cpu(counters->rx_broadcast);
- data[10] = le32_to_cpu(counters->rx_multicast);
- data[11] = le16_to_cpu(counters->tx_aborted);
- data[12] = le16_to_cpu(counters->tx_underun);
-
pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
}
+static void rtl8169_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ ASSERT_RTNL();
+
+ rtl8169_update_counters(dev);
+
+ data[0] = le64_to_cpu(tp->counters.tx_packets);
+ data[1] = le64_to_cpu(tp->counters.rx_packets);
+ data[2] = le64_to_cpu(tp->counters.tx_errors);
+ data[3] = le32_to_cpu(tp->counters.rx_errors);
+ data[4] = le16_to_cpu(tp->counters.rx_missed);
+ data[5] = le16_to_cpu(tp->counters.align_errors);
+ data[6] = le32_to_cpu(tp->counters.tx_one_collision);
+ data[7] = le32_to_cpu(tp->counters.tx_multi_collision);
+ data[8] = le64_to_cpu(tp->counters.rx_unicast);
+ data[9] = le64_to_cpu(tp->counters.rx_broadcast);
+ data[10] = le32_to_cpu(tp->counters.rx_multicast);
+ data[11] = le16_to_cpu(tp->counters.tx_aborted);
+ data[12] = le16_to_cpu(tp->counters.tx_underun);
+}
+
static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
switch(stringset) {
@@ -3682,6 +3702,9 @@ static int rtl8169_close(struct net_device *dev)
struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
+ /* update counters before going down */
+ rtl8169_update_counters(dev);
+
rtl8169_down(dev);
free_irq(dev->irq, dev);
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 31e38fae017f..845431c186ac 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2478,7 +2478,7 @@ static int sbmac_mii_probe(struct net_device *dev)
return -ENXIO;
}
- phy_dev = phy_connect(dev, phy_dev->dev.bus_id, &sbmac_mii_poll, 0,
+ phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll, 0,
PHY_INTERFACE_MODE_GMII);
if (IS_ERR(phy_dev)) {
printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
@@ -2500,7 +2500,7 @@ static int sbmac_mii_probe(struct net_device *dev)
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
dev->name, phy_dev->drv->name,
- phy_dev->dev.bus_id, phy_dev->irq);
+ dev_name(&phy_dev->dev), phy_dev->irq);
sc->phy_dev = phy_dev;
@@ -2697,7 +2697,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
sbm_base = ioremap_nocache(res->start, res->end - res->start + 1);
if (!sbm_base) {
printk(KERN_ERR "%s: unable to map device registers\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_out;
}
@@ -2708,7 +2708,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
* If we find a zero, skip this MAC.
*/
sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR);
- pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", pldev->dev.bus_id,
+ pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", dev_name(&pldev->dev),
sbmac_orig_hwaddr ? "" : "not ", (long long)res->start);
if (sbmac_orig_hwaddr == 0) {
err = 0;
@@ -2721,7 +2721,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
dev = alloc_etherdev(sizeof(struct sbmac_softc));
if (!dev) {
printk(KERN_ERR "%s: unable to allocate etherdev\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_unmap;
}
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7673fd92eaf5..847e9bb0098f 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -676,9 +676,8 @@ static int efx_init_port(struct efx_nic *efx)
rc = efx->phy_op->init(efx);
if (rc)
return rc;
- efx->phy_op->reconfigure(efx);
-
mutex_lock(&efx->mac_lock);
+ efx->phy_op->reconfigure(efx);
rc = falcon_switch_mac(efx);
mutex_unlock(&efx->mac_lock);
if (rc)
@@ -686,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx)
efx->mac_op->reconfigure(efx);
efx->port_initialized = true;
- efx->stats_enabled = true;
+ efx_stats_enable(efx);
return 0;
fail:
@@ -735,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx)
if (!efx->port_initialized)
return;
+ efx_stats_disable(efx);
efx->phy_op->fini(efx);
efx->port_initialized = false;
@@ -854,20 +854,27 @@ static void efx_fini_io(struct efx_nic *efx)
* interrupts across them. */
static int efx_wanted_rx_queues(void)
{
- cpumask_t core_mask;
+ cpumask_var_t core_mask;
int count;
int cpu;
- cpus_clear(core_mask);
+ if (!alloc_cpumask_var(&core_mask, GFP_KERNEL)) {
+ printk(KERN_WARNING
+ "efx.c: allocation failure, irq balancing hobbled\n");
+ return 1;
+ }
+
+ cpumask_clear(core_mask);
count = 0;
for_each_online_cpu(cpu) {
- if (!cpu_isset(cpu, core_mask)) {
+ if (!cpumask_test_cpu(cpu, core_mask)) {
++count;
- cpus_or(core_mask, core_mask,
- topology_core_siblings(cpu));
+ cpumask_or(core_mask, core_mask,
+ topology_core_cpumask(cpu));
}
}
+ free_cpumask_var(core_mask);
return count;
}
@@ -1361,6 +1368,20 @@ static int efx_net_stop(struct net_device *net_dev)
return 0;
}
+void efx_stats_disable(struct efx_nic *efx)
+{
+ spin_lock(&efx->stats_lock);
+ ++efx->stats_disable_count;
+ spin_unlock(&efx->stats_lock);
+}
+
+void efx_stats_enable(struct efx_nic *efx)
+{
+ spin_lock(&efx->stats_lock);
+ --efx->stats_disable_count;
+ spin_unlock(&efx->stats_lock);
+}
+
/* Context: process, dev_base_lock or RTNL held, non-blocking. */
static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
{
@@ -1369,12 +1390,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev)
struct net_device_stats *stats = &net_dev->stats;
/* Update stats if possible, but do not wait if another thread
- * is updating them (or resetting the NIC); slightly stale
- * stats are acceptable.
+ * is updating them or if MAC stats fetches are temporarily
+ * disabled; slightly stale stats are acceptable.
*/
if (!spin_trylock(&efx->stats_lock))
return stats;
- if (efx->stats_enabled) {
+ if (!efx->stats_disable_count) {
efx->mac_op->update_stats(efx);
falcon_update_nic_stats(efx);
}
@@ -1622,16 +1643,12 @@ static void efx_unregister_netdev(struct efx_nic *efx)
/* Tears down the entire software state and most of the hardware state
* before reset. */
-void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd)
{
EFX_ASSERT_RESET_SERIALISED(efx);
- /* The net_dev->get_stats handler is quite slow, and will fail
- * if a fetch is pending over reset. Serialise against it. */
- spin_lock(&efx->stats_lock);
- efx->stats_enabled = false;
- spin_unlock(&efx->stats_lock);
-
+ efx_stats_disable(efx);
efx_stop_all(efx);
mutex_lock(&efx->mac_lock);
mutex_lock(&efx->spi_lock);
@@ -1639,6 +1656,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
efx->phy_op->get_settings(efx, ecmd);
efx_fini_channels(efx);
+ if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
+ efx->phy_op->fini(efx);
}
/* This function will always ensure that the locks acquired in
@@ -1646,7 +1665,8 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
* that we were unable to reinitialise the hardware, and the
* driver should be disabled. If ok is false, then the rx and tx
* engines are not restarted, pending a RESET_DISABLE. */
-int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
+int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok)
{
int rc;
@@ -1658,6 +1678,15 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
ok = false;
}
+ if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) {
+ if (ok) {
+ rc = efx->phy_op->init(efx);
+ if (rc)
+ ok = false;
+ } else
+ efx->port_initialized = false;
+ }
+
if (ok) {
efx_init_channels(efx);
@@ -1670,7 +1699,7 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
if (ok) {
efx_start_all(efx);
- efx->stats_enabled = true;
+ efx_stats_enable(efx);
}
return rc;
}
@@ -1702,7 +1731,7 @@ static int efx_reset(struct efx_nic *efx)
EFX_INFO(efx, "resetting (%d)\n", method);
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, method, &ecmd);
rc = falcon_reset_hw(efx, method);
if (rc) {
@@ -1721,10 +1750,10 @@ static int efx_reset(struct efx_nic *efx)
/* Leave device stopped if necessary */
if (method == RESET_TYPE_DISABLE) {
- efx_reset_up(efx, &ecmd, false);
+ efx_reset_up(efx, method, &ecmd, false);
rc = -EIO;
} else {
- rc = efx_reset_up(efx, &ecmd, true);
+ rc = efx_reset_up(efx, method, &ecmd, true);
}
out_disable:
@@ -1876,6 +1905,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
efx->rx_checksum_enabled = true;
spin_lock_init(&efx->netif_stop_lock);
spin_lock_init(&efx->stats_lock);
+ efx->stats_disable_count = 1;
mutex_init(&efx->mac_lock);
efx->mac_op = &efx_dummy_mac_operations;
efx->phy_op = &efx_dummy_phy_operations;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 0dd7a532c78a..55d0f131b0e9 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -36,13 +36,16 @@ extern void efx_process_channel_now(struct efx_channel *channel);
extern void efx_flush_queues(struct efx_nic *efx);
/* Ports */
+extern void efx_stats_disable(struct efx_nic *efx);
+extern void efx_stats_enable(struct efx_nic *efx);
extern void efx_reconfigure_port(struct efx_nic *efx);
extern void __efx_reconfigure_port(struct efx_nic *efx);
/* Reset handling */
-extern void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd);
-extern int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd,
- bool ok);
+extern void efx_reset_down(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd);
+extern int efx_reset_up(struct efx_nic *efx, enum reset_type method,
+ struct ethtool_cmd *ecmd, bool ok);
/* Global */
extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 53d259e90187..7b5924c039b3 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
int rc;
- if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg)
- return -EINVAL;
-
/* Falcon GMAC does not support 1000Mbps HD */
if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
EFX_LOG(efx, "rejecting unsupported 1000Mbps HD"
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 5b9f2d9cc4ed..064307c2277e 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -338,10 +338,10 @@ static int falcon_alloc_special_buffer(struct efx_nic *efx,
nic_data->next_buffer_table += buffer->entries;
EFX_LOG(efx, "allocating special buffers %d-%d at %llx+%x "
- "(virt %p phys %lx)\n", buffer->index,
+ "(virt %p phys %llx)\n", buffer->index,
buffer->index + buffer->entries - 1,
- (unsigned long long)buffer->dma_addr, len,
- buffer->addr, virt_to_phys(buffer->addr));
+ (u64)buffer->dma_addr, len,
+ buffer->addr, (u64)virt_to_phys(buffer->addr));
return 0;
}
@@ -353,10 +353,10 @@ static void falcon_free_special_buffer(struct efx_nic *efx,
return;
EFX_LOG(efx, "deallocating special buffers %d-%d at %llx+%x "
- "(virt %p phys %lx)\n", buffer->index,
+ "(virt %p phys %llx)\n", buffer->index,
buffer->index + buffer->entries - 1,
- (unsigned long long)buffer->dma_addr, buffer->len,
- buffer->addr, virt_to_phys(buffer->addr));
+ (u64)buffer->dma_addr, buffer->len,
+ buffer->addr, (u64)virt_to_phys(buffer->addr));
pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr,
buffer->dma_addr);
@@ -824,10 +824,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
rx_ev_pause_frm ? " [PAUSE]" : "");
}
#endif
-
- if (unlikely(rx_ev_eth_crc_err && EFX_WORKAROUND_10750(efx) &&
- efx->phy_type == PHY_TYPE_SFX7101))
- tenxpress_crc_err(efx);
}
/* Handle receive events that are not in-order. */
@@ -1887,7 +1883,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
/* MAC stats will fail whilst the TX fifo is draining. Serialise
* the drain sequence with the statistics fetch */
- spin_lock(&efx->stats_lock);
+ efx_stats_disable(efx);
falcon_read(efx, &reg, MAC0_CTRL_REG_KER);
EFX_SET_OWORD_FIELD(reg, TXFIFO_DRAIN_EN_B0, 1);
@@ -1917,7 +1913,7 @@ static int falcon_reset_macs(struct efx_nic *efx)
udelay(10);
}
- spin_unlock(&efx->stats_lock);
+ efx_stats_enable(efx);
/* If we've reset the EM block and the link is up, then
* we'll have to kick the XAUI link so the PHY can recover */
@@ -2277,6 +2273,10 @@ int falcon_switch_mac(struct efx_nic *efx)
struct efx_mac_operations *old_mac_op = efx->mac_op;
efx_oword_t nic_stat;
unsigned strap_val;
+ int rc = 0;
+
+ /* Don't try to fetch MAC stats while we're switching MACs */
+ efx_stats_disable(efx);
/* Internal loopbacks override the phy speed setting */
if (efx->loopback_mode == LOOPBACK_GMAC) {
@@ -2287,16 +2287,12 @@ int falcon_switch_mac(struct efx_nic *efx)
efx->link_fd = true;
}
+ WARN_ON(!mutex_is_locked(&efx->mac_lock));
efx->mac_op = (EFX_IS10G(efx) ?
&falcon_xmac_operations : &falcon_gmac_operations);
- if (old_mac_op == efx->mac_op)
- return 0;
-
- WARN_ON(!mutex_is_locked(&efx->mac_lock));
-
- /* Not all macs support a mac-level link state */
- efx->mac_up = true;
+ /* Always push the NIC_STAT_REG setting even if the mac hasn't
+ * changed, because this function is run post online reset */
falcon_read(efx, &nic_stat, NIC_STAT_REG);
strap_val = EFX_IS10G(efx) ? 5 : 3;
if (falcon_rev(efx) >= FALCON_REV_B0) {
@@ -2309,9 +2305,17 @@ int falcon_switch_mac(struct efx_nic *efx)
BUG_ON(EFX_OWORD_FIELD(nic_stat, STRAP_PINS) != strap_val);
}
+ if (old_mac_op == efx->mac_op)
+ goto out;
EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
- return falcon_reset_macs(efx);
+ /* Not all macs support a mac-level link state */
+ efx->mac_up = true;
+
+ rc = falcon_reset_macs(efx);
+out:
+ efx_stats_enable(efx);
+ return rc;
}
/* This call is responsible for hooking in the MAC and PHY operations */
@@ -2339,10 +2343,10 @@ int falcon_probe_port(struct efx_nic *efx)
FALCON_MAC_STATS_SIZE);
if (rc)
return rc;
- EFX_LOG(efx, "stats buffer at %llx (virt %p phys %lx)\n",
- (unsigned long long)efx->stats_buffer.dma_addr,
+ EFX_LOG(efx, "stats buffer at %llx (virt %p phys %llx)\n",
+ (u64)efx->stats_buffer.dma_addr,
efx->stats_buffer.addr,
- virt_to_phys(efx->stats_buffer.addr));
+ (u64)virt_to_phys(efx->stats_buffer.addr));
return 0;
}
@@ -2917,9 +2921,9 @@ int falcon_probe_nic(struct efx_nic *efx)
goto fail4;
BUG_ON(efx->irq_status.dma_addr & 0x0f);
- EFX_LOG(efx, "INT_KER at %llx (virt %p phys %lx)\n",
- (unsigned long long)efx->irq_status.dma_addr,
- efx->irq_status.addr, virt_to_phys(efx->irq_status.addr));
+ EFX_LOG(efx, "INT_KER at %llx (virt %p phys %llx)\n",
+ (u64)efx->irq_status.dma_addr,
+ efx->irq_status.addr, (u64)virt_to_phys(efx->irq_status.addr));
falcon_probe_spi_devices(efx);
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index f6a16428113d..f9e2f95c3b48 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -15,6 +15,7 @@
#include "net_driver.h"
#include "mdio_10g.h"
#include "boards.h"
+#include "workarounds.h"
int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
int spins, int spintime)
@@ -179,17 +180,12 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
return false;
else if (efx_phy_mode_disabled(efx->phy_mode))
return false;
- else if (efx->loopback_mode == LOOPBACK_PHYXS) {
+ else if (efx->loopback_mode == LOOPBACK_PHYXS)
mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
MDIO_MMDREG_DEVS_PCS |
MDIO_MMDREG_DEVS_PMAPMD |
MDIO_MMDREG_DEVS_AN);
- if (!mmd_mask) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
- MDIO_PHYXS_STATUS2);
- return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
- }
- } else if (efx->loopback_mode == LOOPBACK_PCS)
+ else if (efx->loopback_mode == LOOPBACK_PCS)
mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
MDIO_MMDREG_DEVS_PMAPMD |
MDIO_MMDREG_DEVS_AN);
@@ -197,6 +193,13 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
MDIO_MMDREG_DEVS_AN);
+ if (!mmd_mask) {
+ /* Use presence of XGMII faults in leui of link state */
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
+ MDIO_PHYXS_STATUS2);
+ return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
+ }
+
while (mmd_mask) {
if (mmd_mask & 1) {
/* Double reads because link state is latched, and a
@@ -263,7 +266,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
}
}
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
+static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
{
int phy_id = efx->mii.phy_id;
u32 result = 0;
@@ -278,9 +281,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp)
result |= ADVERTISED_100baseT_Half;
if (reg & ADVERTISE_100FULL)
result |= ADVERTISED_100baseT_Full;
- if (reg & LPA_RESV)
- result |= xnp;
-
return result;
}
@@ -310,7 +310,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx,
*/
void mdio_clause45_get_settings_ext(struct efx_nic *efx,
struct ethtool_cmd *ecmd,
- u32 xnp, u32 xnp_lpa)
+ u32 npage_adv, u32 npage_lpa)
{
int phy_id = efx->mii.phy_id;
int reg;
@@ -361,8 +361,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->advertising |=
ADVERTISED_Autoneg |
- mdio_clause45_get_an(efx,
- MDIO_AN_ADVERTISE, xnp);
+ mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
+ npage_adv;
} else
ecmd->autoneg = AUTONEG_DISABLE;
} else
@@ -371,27 +371,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx,
if (ecmd->autoneg) {
/* If AN is complete, report best common mode,
* otherwise report best advertised mode. */
- u32 common = ecmd->advertising;
+ u32 modes = 0;
if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_STAT1) &
- (1 << MDIO_AN_STATUS_AN_DONE_LBN)) {
- common &= mdio_clause45_get_an(efx, MDIO_AN_LPA,
- xnp_lpa);
- }
- if (common & ADVERTISED_10000baseT_Full) {
+ (1 << MDIO_AN_STATUS_AN_DONE_LBN))
+ modes = (ecmd->advertising &
+ (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
+ npage_lpa));
+ if (modes == 0)
+ modes = ecmd->advertising;
+
+ if (modes & ADVERTISED_10000baseT_Full) {
ecmd->speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL;
- } else if (common & (ADVERTISED_1000baseT_Full |
- ADVERTISED_1000baseT_Half)) {
+ } else if (modes & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseT_Half)) {
ecmd->speed = SPEED_1000;
- ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full);
- } else if (common & (ADVERTISED_100baseT_Full |
- ADVERTISED_100baseT_Half)) {
+ ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
+ } else if (modes & (ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half)) {
ecmd->speed = SPEED_100;
- ecmd->duplex = !!(common & ADVERTISED_100baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
} else {
ecmd->speed = SPEED_10;
- ecmd->duplex = !!(common & ADVERTISED_10baseT_Full);
+ ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
}
} else {
/* Report forced settings */
@@ -415,7 +418,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
int phy_id = efx->mii.phy_id;
struct ethtool_cmd prev;
u32 required;
- int ctrl1_bits, reg;
+ int reg;
efx->phy_op->get_settings(efx, &prev);
@@ -430,99 +433,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
if (prev.port != PORT_TP || ecmd->port != PORT_TP)
return -EINVAL;
- /* Check that PHY supports these settings and work out the
- * basic control bits */
- if (ecmd->duplex) {
+ /* Check that PHY supports these settings */
+ if (ecmd->autoneg) {
+ required = SUPPORTED_Autoneg;
+ } else if (ecmd->duplex) {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = BMCR_FULLDPLX;
- required = SUPPORTED_10baseT_Full;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX;
- required = SUPPORTED_100baseT_Full;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX;
- required = SUPPORTED_1000baseT_Full;
- break;
- case SPEED_10000:
- ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 |
- BMCR_FULLDPLX);
- required = SUPPORTED_10000baseT_Full;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Full; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Full; break;
+ default: return -EINVAL;
}
} else {
switch (ecmd->speed) {
- case SPEED_10:
- ctrl1_bits = 0;
- required = SUPPORTED_10baseT_Half;
- break;
- case SPEED_100:
- ctrl1_bits = BMCR_SPEED100;
- required = SUPPORTED_100baseT_Half;
- break;
- case SPEED_1000:
- ctrl1_bits = BMCR_SPEED1000;
- required = SUPPORTED_1000baseT_Half;
- break;
- default:
- return -EINVAL;
+ case SPEED_10: required = SUPPORTED_10baseT_Half; break;
+ case SPEED_100: required = SUPPORTED_100baseT_Half; break;
+ default: return -EINVAL;
}
}
- if (ecmd->autoneg)
- required |= SUPPORTED_Autoneg;
required |= ecmd->advertising;
if (required & ~prev.supported)
return -EINVAL;
- /* Set the basic control bits */
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- MDIO_MMDREG_CTRL1);
- reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c);
- reg |= ctrl1_bits;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1,
- reg);
-
- /* Set the AN registers */
- if (ecmd->autoneg != prev.autoneg ||
- ecmd->advertising != prev.advertising) {
- bool xnp = false;
-
- if (efx->phy_op->set_xnp_advertise)
- xnp = efx->phy_op->set_xnp_advertise(efx,
- ecmd->advertising);
-
- if (ecmd->autoneg) {
- reg = 0;
- if (ecmd->advertising & ADVERTISED_10baseT_Half)
- reg |= ADVERTISE_10HALF;
- if (ecmd->advertising & ADVERTISED_10baseT_Full)
- reg |= ADVERTISE_10FULL;
- if (ecmd->advertising & ADVERTISED_100baseT_Half)
- reg |= ADVERTISE_100HALF;
- if (ecmd->advertising & ADVERTISED_100baseT_Full)
- reg |= ADVERTISE_100FULL;
- if (xnp)
- reg |= ADVERTISE_RESV;
- mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
- MDIO_AN_ADVERTISE, reg);
- }
+ if (ecmd->autoneg) {
+ bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full
+ || EFX_WORKAROUND_13204(efx));
+
+ /* Set up the base page */
+ reg = ADVERTISE_CSMA;
+ if (ecmd->advertising & ADVERTISED_10baseT_Half)
+ reg |= ADVERTISE_10HALF;
+ if (ecmd->advertising & ADVERTISED_10baseT_Full)
+ reg |= ADVERTISE_10FULL;
+ if (ecmd->advertising & ADVERTISED_100baseT_Half)
+ reg |= ADVERTISE_100HALF;
+ if (ecmd->advertising & ADVERTISED_100baseT_Full)
+ reg |= ADVERTISE_100FULL;
+ if (xnp)
+ reg |= ADVERTISE_RESV;
+ else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full))
+ reg |= ADVERTISE_NPAGE;
+ reg |= efx_fc_advertise(efx->wanted_fc);
+ mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_ADVERTISE, reg);
+
+ /* Set up the (extended) next page if necessary */
+ if (efx->phy_op->set_npage_adv)
+ efx->phy_op->set_npage_adv(efx, ecmd->advertising);
+ /* Enable and restart AN */
reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_CTRL1);
- if (ecmd->autoneg)
- reg |= BMCR_ANENABLE | BMCR_ANRESTART;
- else
- reg &= ~BMCR_ANENABLE;
+ reg |= BMCR_ANENABLE;
+ if (!(EFX_WORKAROUND_15195(efx) &&
+ LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
+ reg |= BMCR_ANRESTART;
if (xnp)
reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
else
reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
MDIO_MMDREG_CTRL1, reg);
+ } else {
+ /* Disable AN */
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+ MDIO_MMDREG_CTRL1,
+ __ffs(BMCR_ANENABLE), false);
+
+ /* Set the basic control bits */
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
+ MDIO_MMDREG_CTRL1);
+ reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
+ 0x003c);
+ if (ecmd->speed == SPEED_100)
+ reg |= BMCR_SPEED100;
+ if (ecmd->duplex)
+ reg |= BMCR_FULLDPLX;
+ mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
+ MDIO_MMDREG_CTRL1, reg);
}
return 0;
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 09bf801d0569..8ba49773ce7e 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -155,7 +155,8 @@
#define MDIO_AN_XNP 22
#define MDIO_AN_LPA_XNP 25
-#define MDIO_AN_10GBT_ADVERTISE 32
+#define MDIO_AN_10GBT_CTRL 32
+#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12
#define MDIO_AN_10GBT_STATUS (33)
#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5f255f75754e..e019ad1fb9a0 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -566,7 +566,7 @@ struct efx_mac_operations {
* @poll: Poll for hardware state. Serialised by the mac_lock.
* @get_settings: Get ethtool settings. Serialised by the mac_lock.
* @set_settings: Set ethtool settings. Serialised by the mac_lock.
- * @set_xnp_advertise: Set abilities advertised in Extended Next Page
+ * @set_npage_adv: Set abilities advertised in (Extended) Next Page
* (only needed where AN bit is set in mmds)
* @num_tests: Number of PHY-specific tests/results
* @test_names: Names of the tests/results
@@ -586,7 +586,7 @@ struct efx_phy_operations {
struct ethtool_cmd *ecmd);
int (*set_settings) (struct efx_nic *efx,
struct ethtool_cmd *ecmd);
- bool (*set_xnp_advertise) (struct efx_nic *efx, u32);
+ void (*set_npage_adv) (struct efx_nic *efx, u32);
u32 num_tests;
const char *const *test_names;
int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
@@ -754,8 +754,7 @@ union efx_multicast_hash {
* &struct net_device_stats.
* @stats_buffer: DMA buffer for statistics
* @stats_lock: Statistics update lock. Serialises statistics fetches
- * @stats_enabled: Temporarily disable statistics fetches.
- * Serialised by @stats_lock
+ * @stats_disable_count: Nest count for disabling statistics fetches
* @mac_op: MAC interface
* @mac_address: Permanent MAC address
* @phy_type: PHY type
@@ -837,7 +836,7 @@ struct efx_nic {
struct efx_mac_stats mac_stats;
struct efx_buffer stats_buffer;
spinlock_t stats_lock;
- bool stats_enabled;
+ unsigned int stats_disable_count;
struct efx_mac_operations *mac_op;
unsigned char mac_address[ETH_ALEN];
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 58c493ef81bb..07e855c148bc 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -17,7 +17,6 @@ extern struct efx_phy_operations falcon_sfx7101_phy_ops;
extern struct efx_phy_operations falcon_sft9001_phy_ops;
extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
-extern void tenxpress_crc_err(struct efx_nic *efx);
/****************************************************************************
* Exported functions from the driver for XFP optical PHYs
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index dba0d64d50cd..0a598084c513 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -665,6 +665,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
{
enum efx_loopback_mode loopback_mode = efx->loopback_mode;
int phy_mode = efx->phy_mode;
+ enum reset_type reset_method = RESET_TYPE_INVISIBLE;
struct ethtool_cmd ecmd;
struct efx_channel *channel;
int rc_test = 0, rc_reset = 0, rc;
@@ -718,21 +719,21 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
mutex_unlock(&efx->mac_lock);
/* free up all consumers of SRAM (including all the queues) */
- efx_reset_down(efx, &ecmd);
+ efx_reset_down(efx, reset_method, &ecmd);
rc = efx_test_chip(efx, tests);
if (rc && !rc_test)
rc_test = rc;
/* reset the chip to recover from the register test */
- rc_reset = falcon_reset_hw(efx, RESET_TYPE_ALL);
+ rc_reset = falcon_reset_hw(efx, reset_method);
/* Ensure that the phy is powered and out of loopback
* for the bist and loopback tests */
efx->phy_mode &= ~PHY_MODE_LOW_POWER;
efx->loopback_mode = LOOPBACK_NONE;
- rc = efx_reset_up(efx, &ecmd, rc_reset == 0);
+ rc = efx_reset_up(efx, reset_method, &ecmd, rc_reset == 0);
if (rc && !rc_reset)
rc_reset = rc;
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 16b80acb9992..cb25ae5b257a 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -186,19 +186,22 @@ static int sfn4111t_reset(struct efx_nic *efx)
{
efx_oword_t reg;
- /* GPIO pins are also used for I2C, so block that temporarily */
+ /* GPIO 3 and the GPIO register are shared with I2C, so block that */
mutex_lock(&efx->i2c_adap.bus_lock);
+ /* Pull RST_N (GPIO 2) low then let it up again, setting the
+ * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the
+ * output enables; the output levels should always be 0 (low)
+ * and we rely on external pull-ups. */
falcon_read(efx, &reg, GPIO_CTL_REG_KER);
EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, true);
- EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, false);
falcon_write(efx, &reg, GPIO_CTL_REG_KER);
msleep(1000);
- EFX_SET_OWORD_FIELD(reg, GPIO2_OUT, true);
- EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, true);
- EFX_SET_OWORD_FIELD(reg, GPIO3_OUT,
- !(efx->phy_mode & PHY_MODE_SPECIAL));
+ EFX_SET_OWORD_FIELD(reg, GPIO2_OEN, false);
+ EFX_SET_OWORD_FIELD(reg, GPIO3_OEN,
+ !!(efx->phy_mode & PHY_MODE_SPECIAL));
falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+ msleep(1);
mutex_unlock(&efx->i2c_adap.bus_lock);
@@ -232,12 +235,18 @@ static ssize_t set_phy_flash_cfg(struct device *dev,
} else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) {
err = -EBUSY;
} else {
+ /* Reset the PHY, reconfigure the MAC and enable/disable
+ * MAC stats accordingly. */
efx->phy_mode = new_mode;
+ if (new_mode & PHY_MODE_SPECIAL)
+ efx_stats_disable(efx);
if (efx->board_info.type == EFX_BOARD_SFE4001)
err = sfe4001_poweron(efx);
else
err = sfn4111t_reset(efx);
efx_reconfigure_port(efx);
+ if (!(new_mode & PHY_MODE_SPECIAL))
+ efx_stats_enable(efx);
}
rtnl_unlock();
@@ -326,6 +335,11 @@ int sfe4001_init(struct efx_nic *efx)
efx->board_info.monitor = sfe4001_check_hw;
efx->board_info.fini = sfe4001_fini;
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
+ * will fail. */
+ efx_stats_disable(efx);
+ }
rc = sfe4001_poweron(efx);
if (rc)
goto fail_ioexp;
@@ -372,17 +386,25 @@ static void sfn4111t_fini(struct efx_nic *efx)
i2c_unregister_device(efx->board_info.hwmon_client);
}
-static struct i2c_board_info sfn4111t_hwmon_info = {
+static struct i2c_board_info sfn4111t_a0_hwmon_info = {
I2C_BOARD_INFO("max6647", 0x4e),
.irq = -1,
};
+static struct i2c_board_info sfn4111t_r5_hwmon_info = {
+ I2C_BOARD_INFO("max6646", 0x4d),
+ .irq = -1,
+};
+
int sfn4111t_init(struct efx_nic *efx)
{
int rc;
efx->board_info.hwmon_client =
- i2c_new_device(&efx->i2c_adap, &sfn4111t_hwmon_info);
+ i2c_new_device(&efx->i2c_adap,
+ (efx->board_info.minor < 5) ?
+ &sfn4111t_a0_hwmon_info :
+ &sfn4111t_r5_hwmon_info);
if (!efx->board_info.hwmon_client)
return -EIO;
@@ -394,8 +416,10 @@ int sfn4111t_init(struct efx_nic *efx)
if (rc)
goto fail_hwmon;
- if (efx->phy_mode & PHY_MODE_SPECIAL)
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ efx_stats_disable(efx);
sfn4111t_reset(efx);
+ }
return 0;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 9ecb77da9545..f0efd246962c 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -67,6 +67,8 @@
#define PMA_PMD_EXT_CLK312_WIDTH 1
#define PMA_PMD_EXT_LPOWER_LBN 12
#define PMA_PMD_EXT_LPOWER_WIDTH 1
+#define PMA_PMD_EXT_ROBUST_LBN 14
+#define PMA_PMD_EXT_ROBUST_WIDTH 1
#define PMA_PMD_EXT_SSR_LBN 15
#define PMA_PMD_EXT_SSR_WIDTH 1
@@ -177,35 +179,24 @@
#define C22EXT_STATUS_LINK_LBN 2
#define C22EXT_STATUS_LINK_WIDTH 1
-#define C22EXT_MSTSLV_REG 49162
-#define C22EXT_MSTSLV_1000_HD_LBN 10
-#define C22EXT_MSTSLV_1000_HD_WIDTH 1
-#define C22EXT_MSTSLV_1000_FD_LBN 11
-#define C22EXT_MSTSLV_1000_FD_WIDTH 1
+#define C22EXT_MSTSLV_CTRL 49161
+#define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8
+#define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9
+
+#define C22EXT_MSTSLV_STATUS 49162
+#define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10
+#define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11
/* Time to wait between powering down the LNPGA and turning off the power
* rails */
#define LNPGA_PDOWN_WAIT (HZ / 5)
-static int crc_error_reset_threshold = 100;
-module_param(crc_error_reset_threshold, int, 0644);
-MODULE_PARM_DESC(crc_error_reset_threshold,
- "Max number of CRC errors before XAUI reset");
-
struct tenxpress_phy_data {
enum efx_loopback_mode loopback_mode;
- atomic_t bad_crc_count;
enum efx_phy_mode phy_mode;
int bad_lp_tries;
};
-void tenxpress_crc_err(struct efx_nic *efx)
-{
- struct tenxpress_phy_data *phy_data = efx->phy_data;
- if (phy_data != NULL)
- atomic_inc(&phy_data->bad_crc_count);
-}
-
static ssize_t show_phy_short_reach(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -284,7 +275,9 @@ static int tenxpress_init(struct efx_nic *efx)
PMA_PMD_XCONTROL_REG);
reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
(1 << PMA_PMD_EXT_CLK_OUT_LBN) |
- (1 << PMA_PMD_EXT_CLK312_LBN));
+ (1 << PMA_PMD_EXT_CLK312_LBN) |
+ (1 << PMA_PMD_EXT_ROBUST_LBN));
+
mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
PMA_PMD_XCONTROL_REG, reg);
mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
@@ -346,6 +339,7 @@ static int tenxpress_phy_init(struct efx_nic *efx)
rc = tenxpress_init(efx);
if (rc < 0)
goto fail;
+ mdio_clause45_set_pause(efx);
if (efx->phy_type == PHY_TYPE_SFT9001B) {
rc = device_create_file(&efx->pci_dev->dev,
@@ -376,8 +370,8 @@ static int tenxpress_special_reset(struct efx_nic *efx)
/* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
* a special software reset can glitch the XGMAC sufficiently for stats
- * requests to fail. Since we don't often special_reset, just lock. */
- spin_lock(&efx->stats_lock);
+ * requests to fail. */
+ efx_stats_disable(efx);
/* Initiate reset */
reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -392,17 +386,17 @@ static int tenxpress_special_reset(struct efx_nic *efx)
rc = mdio_clause45_wait_reset_mmds(efx,
TENXPRESS_REQUIRED_DEVS);
if (rc < 0)
- goto unlock;
+ goto out;
/* Try and reconfigure the device */
rc = tenxpress_init(efx);
if (rc < 0)
- goto unlock;
+ goto out;
/* Wait for the XGXS state machine to churn */
mdelay(10);
-unlock:
- spin_unlock(&efx->stats_lock);
+out:
+ efx_stats_enable(efx);
return rc;
}
@@ -520,7 +514,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
struct ethtool_cmd ecmd;
- bool phy_mode_change, loop_reset, loop_toggle, loopback;
+ bool phy_mode_change, loop_reset;
if (efx->phy_mode & (PHY_MODE_OFF | PHY_MODE_SPECIAL)) {
phy_data->phy_mode = efx->phy_mode;
@@ -531,12 +525,10 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
phy_mode_change = (efx->phy_mode == PHY_MODE_NORMAL &&
phy_data->phy_mode != PHY_MODE_NORMAL);
- loopback = LOOPBACK_MASK(efx) & efx->phy_op->loopbacks;
- loop_toggle = LOOPBACK_CHANGED(phy_data, efx, efx->phy_op->loopbacks);
loop_reset = (LOOPBACK_OUT_OF(phy_data, efx, efx->phy_op->loopbacks) ||
LOOPBACK_CHANGED(phy_data, efx, 1 << LOOPBACK_GPHY));
- if (loop_reset || loop_toggle || loopback || phy_mode_change) {
+ if (loop_reset || phy_mode_change) {
int rc;
efx->phy_op->get_settings(efx, &ecmd);
@@ -551,20 +543,6 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
falcon_reset_xaui(efx);
}
- if (efx->phy_type != PHY_TYPE_SFX7101) {
- /* Only change autoneg once, on coming out or
- * going into loopback */
- if (loop_toggle)
- ecmd.autoneg = !loopback;
- if (loopback) {
- ecmd.duplex = DUPLEX_FULL;
- if (efx->loopback_mode == LOOPBACK_GPHY)
- ecmd.speed = SPEED_1000;
- else
- ecmd.speed = SPEED_10000;
- }
- }
-
rc = efx->phy_op->set_settings(efx, &ecmd);
WARN_ON(rc);
}
@@ -623,13 +601,6 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
if (phy_data->phy_mode != PHY_MODE_NORMAL)
return;
-
- if (EFX_WORKAROUND_10750(efx) &&
- atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) {
- EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n");
- falcon_reset_xaui(efx);
- atomic_set(&phy_data->bad_crc_count, 0);
- }
}
static void tenxpress_phy_fini(struct efx_nic *efx)
@@ -772,107 +743,76 @@ reset:
return rc;
}
-static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx)
+static void
+tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy = efx->mii.phy_id;
- u32 lpa = 0;
+ int phy_id = efx->mii.phy_id;
+ u32 adv = 0, lpa = 0;
int reg;
if (efx->phy_type != PHY_TYPE_SFX7101) {
- reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT,
- C22EXT_MSTSLV_REG);
- if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN))
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_CTRL);
+ if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
+ adv |= ADVERTISED_1000baseT_Full;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_STATUS);
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
lpa |= ADVERTISED_1000baseT_Half;
- if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN))
+ if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
lpa |= ADVERTISED_1000baseT_Full;
}
- reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS);
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL);
+ if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+ adv |= ADVERTISED_10000baseT_Full;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_STATUS);
if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
lpa |= ADVERTISED_10000baseT_Full;
- return lpa;
-}
-static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
-{
- mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full,
- tenxpress_get_xnp_lpa(efx));
- ecmd->supported |= SUPPORTED_10000baseT_Full;
- ecmd->advertising |= ADVERTISED_10000baseT_Full;
+ mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
+
+ if (efx->phy_type != PHY_TYPE_SFX7101)
+ ecmd->supported |= (SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full);
+
+ /* In loopback, the PHY automatically brings up the correct interface,
+ * but doesn't advertise the correct speed. So override it */
+ if (efx->loopback_mode == LOOPBACK_GPHY)
+ ecmd->speed = SPEED_1000;
+ else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)
+ ecmd->speed = SPEED_10000;
}
-static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- int phy_id = efx->mii.phy_id;
- u32 xnp_adv = 0;
- int reg;
-
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN)))
- xnp_adv |= ADVERTISED_100baseT_Full;
- if (reg & (1 << PMA_PMD_1000T_ADV_LBN))
- xnp_adv |= ADVERTISED_1000baseT_Full;
- if (reg & (1 << PMA_PMD_10000T_ADV_LBN))
- xnp_adv |= ADVERTISED_10000baseT_Full;
-
- mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv,
- tenxpress_get_xnp_lpa(efx));
-
- ecmd->supported |= (SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full);
+ if (!ecmd->autoneg)
+ return -EINVAL;
- /* Use the vendor defined C22ext register for duplex settings */
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) {
- reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG);
- ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ?
- DUPLEX_FULL : DUPLEX_HALF);
- }
+ return mdio_clause45_set_settings(efx, ecmd);
}
-static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy_id = efx->mii.phy_id;
- int rc;
-
- rc = mdio_clause45_set_settings(efx, ecmd);
- if (rc)
- return rc;
-
- if (ecmd->speed != SPEED_10000 && !ecmd->autoneg)
- mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
- GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN,
- ecmd->duplex == DUPLEX_FULL);
-
- return rc;
+ mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+ advertising & ADVERTISED_10000baseT_Full);
}
-static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising)
+static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
{
- int phy = efx->mii.phy_id;
- int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG);
- bool enabled;
-
- reg &= ~((1 << 2) | (1 << 3));
- if (EFX_WORKAROUND_13204(efx) &&
- (advertising & ADVERTISED_100baseT_Full))
- reg |= 1 << PMA_PMD_100TX_ADV_LBN;
- if (advertising & ADVERTISED_1000baseT_Full)
- reg |= 1 << PMA_PMD_1000T_ADV_LBN;
- if (advertising & ADVERTISED_10000baseT_Full)
- reg |= 1 << PMA_PMD_10000T_ADV_LBN;
- mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD,
- PMA_PMD_SPEED_ENABLE_REG, reg);
-
- enabled = (advertising &
- (ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_10000baseT_Full));
- if (EFX_WORKAROUND_13204(efx))
- enabled |= (advertising & ADVERTISED_100baseT_Full);
- return enabled;
+ int phy_id = efx->mii.phy_id;
+
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
+ C22EXT_MSTSLV_CTRL,
+ C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+ advertising & ADVERTISED_1000baseT_Full);
+ mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
+ MDIO_AN_10GBT_CTRL,
+ MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
+ advertising & ADVERTISED_10000baseT_Full);
}
struct efx_phy_operations falcon_sfx7101_phy_ops = {
@@ -882,8 +822,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sfx7101_get_settings,
- .set_settings = mdio_clause45_set_settings,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sfx7101_set_npage_adv,
.num_tests = ARRAY_SIZE(sfx7101_test_names),
.test_names = sfx7101_test_names,
.run_tests = sfx7101_run_tests,
@@ -898,9 +839,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = {
.poll = tenxpress_phy_poll,
.fini = tenxpress_phy_fini,
.clear_interrupt = efx_port_dummy_op_void,
- .get_settings = sft9001_get_settings,
- .set_settings = sft9001_set_settings,
- .set_xnp_advertise = sft9001_set_xnp_advertise,
+ .get_settings = tenxpress_get_settings,
+ .set_settings = tenxpress_set_settings,
+ .set_npage_adv = sft9001_set_npage_adv,
.num_tests = ARRAY_SIZE(sft9001_test_names),
.test_names = sft9001_test_names,
.run_tests = sft9001_run_tests,
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 82e03e1d7371..78de68f4a95b 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -18,8 +18,8 @@
#define EFX_WORKAROUND_ALWAYS(efx) 1
#define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1)
#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx)
-#define EFX_WORKAROUND_SFX7101(efx) ((efx)->phy_type == PHY_TYPE_SFX7101)
-#define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A)
+#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \
+ (efx)->phy_type == PHY_TYPE_SFT9001B)
/* XAUI resets if link not detected */
#define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
@@ -29,8 +29,6 @@
#define EFX_WORKAROUND_7884 EFX_WORKAROUND_10G
/* TX pkt parser problem with <= 16 byte TXes */
#define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* Low rate CRC errors require XAUI reset */
-#define EFX_WORKAROUND_10750 EFX_WORKAROUND_SFX7101
/* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
* or a PCIe error (bug 11028) */
#define EFX_WORKAROUND_10727 EFX_WORKAROUND_ALWAYS
@@ -55,8 +53,8 @@
#define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A
/* Need to send XNP pages for 100BaseT */
-#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001A
-/* Need to keep AN enabled */
-#define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A
+#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001
+/* Don't restart AN in near-side loopback */
+#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001
#endif /* EFX_WORKAROUNDS_H */
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 607efeaf0bc5..9a00e5566af7 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -1003,9 +1003,9 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
break;
case SKFP_CLR_STATS: /* Zero out the driver statistics */
if (!capable(CAP_NET_ADMIN)) {
- memset(&lp->MacStat, 0, sizeof(lp->MacStat));
- } else {
status = -EPERM;
+ } else {
+ memset(&lp->MacStat, 0, sizeof(lp->MacStat));
}
break;
default:
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 3668e81e474d..994703cc0db3 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1403,9 +1403,6 @@ static int sky2_up(struct net_device *dev)
}
- if (netif_msg_ifup(sky2))
- printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
-
netif_carrier_off(dev);
/* must be power of 2 */
@@ -1484,6 +1481,9 @@ static int sky2_up(struct net_device *dev)
sky2_write32(hw, B0_IMSK, imask);
sky2_set_multicast(dev);
+
+ if (netif_msg_ifup(sky2))
+ printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
return 0;
err_out:
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index bf3aa2a1effe..293610334a77 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -220,9 +220,9 @@ static void smc911x_reset(struct net_device *dev)
/* make sure EEPROM has finished loading before setting GPIO_CFG */
timeout=1000;
- while ( timeout-- && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) {
+ while (--timeout && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_))
udelay(10);
- }
+
if (timeout == 0){
PRINTK("%s: smc911x_reset timeout waiting for EEPROM busy\n", dev->name);
return;
@@ -1545,7 +1545,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}
static int smc911x_ethtool_nwayreset(struct net_device *dev)
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 870b4c33f108..611584ee7a01 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -226,8 +226,7 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
* Use a DMA for RX and TX packets.
*/
#include <linux/dma-mapping.h>
-#include <asm/dma.h>
-#include <mach/pxa-regs.h>
+#include <mach/dma.h>
static dma_addr_t rx_dmabuf, tx_dmabuf;
static int rx_dmalen, tx_dmalen;
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index b215a8d85e62..0b6da9501444 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1614,7 +1614,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}
static int smc_ethtool_nwayreset(struct net_device *dev)
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index c4ccd121bc9c..1083e2c5dec6 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -44,6 +44,7 @@
defined(CONFIG_MACH_MAINSTONE) ||\
defined(CONFIG_MACH_ZYLONITE) ||\
defined(CONFIG_MACH_LITTLETON) ||\
+ defined(CONFIG_MACH_ZYLONITE2) ||\
defined(CONFIG_ARCH_VIPER)
#include <asm/mach-types.h>
@@ -494,8 +495,6 @@ struct smc_local {
*/
#include <linux/dma-mapping.h>
#include <mach/dma.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#ifdef SMC_insl
#undef SMC_insl
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index f513bdf1c887..9b85961aeb34 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -769,7 +769,7 @@ static int smsc911x_mii_probe(struct net_device *dev)
return -ENODEV;
}
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc911x_phy_adjust_link, 0, pdata->config.phy_interface);
if (IS_ERR(phydev)) {
@@ -778,7 +778,8 @@ static int smsc911x_mii_probe(struct net_device *dev)
}
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name,
+ dev_name(&phydev->dev), phydev->irq);
/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -953,7 +954,7 @@ smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
do {
udelay(1);
val = smsc911x_reg_read(pdata, RX_DP_CTRL);
- } while (timeout-- && (val & RX_DP_CTRL_RX_FFWD_));
+ } while (--timeout && (val & RX_DP_CTRL_RX_FFWD_));
if (unlikely(timeout == 0))
SMSC_WARNING(HW, "Timed out waiting for "
@@ -1545,7 +1546,7 @@ static void smsc911x_ethtool_getdrvinfo(struct net_device *dev,
{
strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver));
strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, dev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(dev->dev.parent),
sizeof(info->bus_info));
}
@@ -1624,7 +1625,7 @@ static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op)
do {
msleep(1);
e2cmd = smsc911x_reg_read(pdata, E2P_CMD);
- } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--));
+ } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout));
if (!timeout) {
SMSC_TRACE(DRV, "TIMED OUT");
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index c14a4c6452c7..72f1348eb809 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -341,7 +341,7 @@ static int smsc9420_eeprom_send_cmd(struct smsc9420_pdata *pd, u32 op)
do {
msleep(1);
e2cmd = smsc9420_reg_read(pd, E2P_CMD);
- } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--));
+ } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout));
if (!timeout) {
smsc_info(HW, "TIMED OUT");
@@ -413,6 +413,7 @@ static int smsc9420_ethtool_get_eeprom(struct net_device *dev,
}
memcpy(data, &eeprom_data[eeprom->offset], len);
+ eeprom->magic = SMSC9420_EEPROM_MAGIC;
eeprom->len = len;
return 0;
}
@@ -423,6 +424,9 @@ static int smsc9420_ethtool_set_eeprom(struct net_device *dev,
struct smsc9420_pdata *pd = netdev_priv(dev);
int ret;
+ if (eeprom->magic != SMSC9420_EEPROM_MAGIC)
+ return -EINVAL;
+
smsc9420_eeprom_enable_access(pd);
smsc9420_eeprom_send_cmd(pd, E2P_CMD_EPC_CMD_EWEN_);
ret = smsc9420_eeprom_write_location(pd, eeprom->offset, *data);
@@ -498,7 +502,7 @@ static void smsc9420_check_mac_address(struct net_device *dev)
static void smsc9420_stop_tx(struct smsc9420_pdata *pd)
{
u32 dmac_control, mac_cr, dma_intr_ena;
- int timeOut = 1000;
+ int timeout = 1000;
/* disable TX DMAC */
dmac_control = smsc9420_reg_read(pd, DMAC_CONTROL);
@@ -506,13 +510,13 @@ static void smsc9420_stop_tx(struct smsc9420_pdata *pd)
smsc9420_reg_write(pd, DMAC_CONTROL, dmac_control);
/* Wait max 10ms for transmit process to stop */
- while (timeOut--) {
+ while (--timeout) {
if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_TS_)
break;
udelay(10);
}
- if (!timeOut)
+ if (!timeout)
smsc_warn(IFDOWN, "TX DMAC failed to stop");
/* ACK Tx DMAC stop bit */
@@ -596,7 +600,7 @@ static void smsc9420_free_rx_ring(struct smsc9420_pdata *pd)
static void smsc9420_stop_rx(struct smsc9420_pdata *pd)
{
- int timeOut = 1000;
+ int timeout = 1000;
u32 mac_cr, dmac_control, dma_intr_ena;
/* mask RX DMAC interrupts */
@@ -617,13 +621,13 @@ static void smsc9420_stop_rx(struct smsc9420_pdata *pd)
smsc9420_pci_flush_write(pd);
/* wait up to 10ms for receive to stop */
- while (timeOut--) {
+ while (--timeout) {
if (smsc9420_reg_read(pd, DMAC_STATUS) & DMAC_STS_RS_)
break;
udelay(10);
}
- if (!timeOut)
+ if (!timeout)
smsc_warn(IFDOWN, "RX DMAC did not stop! timeout.");
/* ACK the Rx DMAC stop bit */
@@ -1156,7 +1160,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr,
phydev->phy_id);
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
@@ -1165,7 +1169,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
}
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -1378,6 +1382,7 @@ static int smsc9420_open(struct net_device *dev)
/* test the IRQ connection to the ISR */
smsc_dbg(IFUP, "Testing ISR using IRQ %d", dev->irq);
+ pd->software_irq_signal = false;
spin_lock_irqsave(&pd->int_lock, flags);
/* configure interrupt deassertion timer and enable interrupts */
@@ -1393,8 +1398,6 @@ static int smsc9420_open(struct net_device *dev)
smsc9420_pci_flush_write(pd);
timeout = 1000;
- pd->software_irq_signal = false;
- smp_wmb();
while (timeout--) {
if (pd->software_irq_signal)
break;
diff --git a/drivers/net/smsc9420.h b/drivers/net/smsc9420.h
index 69c351f93f86..e441402f77a2 100644
--- a/drivers/net/smsc9420.h
+++ b/drivers/net/smsc9420.h
@@ -44,6 +44,7 @@
#define LAN_REGISTER_EXTENT (0x400)
#define SMSC9420_EEPROM_SIZE ((u32)11)
+#define SMSC9420_EEPROM_MAGIC (0x9420)
#define PKT_BUF_SZ (VLAN_ETH_FRAME_LEN + NET_IP_ALIGN + 4)
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 4bb8f72c65cc..e5beb299cbd0 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -428,7 +428,7 @@ static int lance_open( struct net_device *dev )
while (--i > 0)
if (DREG & CSR0_IDON)
break;
- if (i < 0 || (DREG & CSR0_ERR)) {
+ if (i <= 0 || (DREG & CSR0_ERR)) {
DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
dev->name, i, DREG ));
DREG = CSR0_STOP;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index feaf0e0577d7..43695b76606f 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -909,7 +909,7 @@ static void check_duplex(struct net_device *dev)
printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
"negotiated capability %4.4x.\n", dev->name,
duplex ? "full" : "half", np->phys[0], negotiated);
- iowrite16(ioread16(ioaddr + MACCtrl0) | duplex ? 0x20 : 0, ioaddr + MACCtrl0);
+ iowrite16(ioread16(ioaddr + MACCtrl0) | (duplex ? 0x20 : 0), ioaddr + MACCtrl0);
}
}
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 86c765d83de1..8d64b1da0465 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -148,7 +148,7 @@ static u16 __phy_read(struct gem *gp, int phy_addr, int reg)
cmd |= (MIF_FRAME_TAMSB);
writel(cmd, gp->regs + MIF_FRAME);
- while (limit--) {
+ while (--limit) {
cmd = readl(gp->regs + MIF_FRAME);
if (cmd & MIF_FRAME_TALSB)
break;
@@ -1157,7 +1157,7 @@ static void gem_pcs_reset(struct gem *gp)
if (limit-- <= 0)
break;
}
- if (limit <= 0)
+ if (limit < 0)
printk(KERN_WARNING "%s: PCS reset bit would not clear.\n",
gp->dev->name);
}
@@ -2221,6 +2221,8 @@ static int gem_do_start(struct net_device *dev)
gp->running = 1;
+ napi_enable(&gp->napi);
+
if (gp->lstate == link_up) {
netif_carrier_on(gp->dev);
gem_set_link_modes(gp);
@@ -2238,6 +2240,8 @@ static int gem_do_start(struct net_device *dev)
spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
+ napi_disable(&gp->napi);
+
gp->running = 0;
gem_reset(gp);
gem_clean_rings(gp);
@@ -2338,8 +2342,6 @@ static int gem_open(struct net_device *dev)
if (!gp->asleep)
rc = gem_do_start(dev);
gp->opened = (rc == 0);
- if (gp->opened)
- napi_enable(&gp->napi);
mutex_unlock(&gp->pm_mutex);
@@ -2476,8 +2478,6 @@ static int gem_resume(struct pci_dev *pdev)
/* Re-attach net device */
netif_device_attach(dev);
-
- napi_enable(&gp->napi);
}
spin_lock_irqsave(&gp->lock, flags);
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 61843fd57525..78f8cee5fd74 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -79,7 +79,7 @@ static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
udelay(100);
- while (limit--) {
+ while (--limit) {
val = __phy_read(phy, phy_id, MII_BMCR);
if ((val & BMCR_RESET) == 0)
break;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 7a72a3112f0a..d4fb4acdbebd 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2543,25 +2543,36 @@ static struct quattro * __devinit quattro_sbus_find(struct of_device *child)
}
/* After all quattro cards have been probed, we call these functions
- * to register the IRQ handlers.
+ * to register the IRQ handlers for the cards that have been
+ * successfully probed and skip the cards that failed to initialize
*/
-static void __init quattro_sbus_register_irqs(void)
+static int __init quattro_sbus_register_irqs(void)
{
struct quattro *qp;
for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
struct of_device *op = qp->quattro_dev;
- int err;
+ int err, qfe_slot, skip = 0;
+
+ for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
+ if (!qp->happy_meals[qfe_slot])
+ skip = 1;
+ }
+ if (skip)
+ continue;
err = request_irq(op->irqs[0],
quattro_sbus_interrupt,
IRQF_SHARED, "Quattro",
qp);
if (err != 0) {
- printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err);
- panic("QFE request irq");
+ printk(KERN_ERR "Quattro HME: IRQ registration "
+ "error %d.\n", err);
+ return err;
}
}
+
+ return 0;
}
static void quattro_sbus_free_irqs(void)
@@ -2570,6 +2581,14 @@ static void quattro_sbus_free_irqs(void)
for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
struct of_device *op = qp->quattro_dev;
+ int qfe_slot, skip = 0;
+
+ for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
+ if (!qp->happy_meals[qfe_slot])
+ skip = 1;
+ }
+ if (skip)
+ continue;
free_irq(op->irqs[0], qp);
}
@@ -2629,6 +2648,14 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
int i, qfe_slot = -1;
int err = -ENODEV;
+ sbus_dp = to_of_device(op->dev.parent)->node;
+ if (is_qfe)
+ sbus_dp = to_of_device(op->dev.parent->parent)->node;
+
+ /* We can match PCI devices too, do not accept those here. */
+ if (strcmp(sbus_dp->name, "sbus"))
+ return err;
+
if (is_qfe) {
qp = quattro_sbus_find(op);
if (qp == NULL)
@@ -2734,10 +2761,6 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
if (qp != NULL)
hp->happy_flags |= HFLAG_QUATTRO;
- sbus_dp = to_of_device(op->dev.parent)->node;
- if (is_qfe)
- sbus_dp = to_of_device(op->dev.parent->parent)->node;
-
/* Get the supported DVMA burst sizes from our Happy SBUS. */
hp->happy_bursts = of_getintprop_default(sbus_dp,
"burst-sizes", 0x00);
@@ -2824,6 +2847,9 @@ err_out_iounmap:
if (hp->tcvregs)
of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
+ if (qp)
+ qp->happy_meals[qfe_slot] = NULL;
+
err_out_free_netdev:
free_netdev(dev);
@@ -3281,7 +3307,7 @@ static int __init happy_meal_sbus_init(void)
err = of_register_driver(&hme_sbus_driver, &of_bus_type);
if (!err)
- quattro_sbus_register_irqs();
+ err = quattro_sbus_register_irqs();
return err;
}
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 281373281756..16c528db7251 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -343,7 +343,7 @@ static void lance_init_ring_dvma(struct net_device *dev)
ib->phys_addr [5] = dev->dev_addr [4];
/* Setup the Tx ring entries */
- for (i = 0; i <= TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i));
ib->btx_ring [i].tmd0 = leptr;
ib->btx_ring [i].tmd1_hadr = leptr >> 16;
@@ -399,7 +399,7 @@ static void lance_init_ring_pio(struct net_device *dev)
sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]);
/* Setup the Tx ring entries */
- for (i = 0; i <= TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
leptr = libbuff_offset(tx_buf, i);
sbus_writew(leptr, &ib->btx_ring [i].tmd0);
sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr);
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 6e8f377355fe..fe0c3f244562 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -227,7 +227,7 @@ static int qe_init(struct sunqe *qep, int from_irq)
if (!(sbus_readb(mregs + MREGS_PHYCONFIG) & MREGS_PHYCONFIG_LTESTDIS)) {
int tries = 50;
- while (tries--) {
+ while (--tries) {
u8 tmp;
mdelay(5);
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index bcd0e60cbda9..e1f8eb96a45c 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -725,7 +725,7 @@ static int tc_mii_probe(struct net_device *dev)
}
/* attach the mac to the phy */
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&tc_handle_link_change, 0,
lp->chiptype == TC35815_TX4939 ?
PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII);
@@ -735,7 +735,7 @@ static int tc_mii_probe(struct net_device *dev)
}
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, id=%x)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id,
+ dev->name, phydev->drv->name, dev_name(&phydev->dev),
phydev->phy_id);
/* mask with MAC supported features */
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5e2dbaee125b..b080f9493d83 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -852,7 +852,7 @@ static int tg3_bmcr_reset(struct tg3 *tp)
}
udelay(10);
}
- if (limit <= 0)
+ if (limit < 0)
return -EBUSY;
return 0;
@@ -1603,7 +1603,7 @@ static int tg3_wait_macro_done(struct tg3 *tp)
break;
}
}
- if (limit <= 0)
+ if (limit < 0)
return -EBUSY;
return 0;
@@ -2237,8 +2237,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
if (phyid != TG3_PHY_ID_BCMAC131) {
phyid &= TG3_PHY_OUI_MASK;
- if (phyid == TG3_PHY_OUI_1 &&
- phyid == TG3_PHY_OUI_2 &&
+ if (phyid == TG3_PHY_OUI_1 ||
+ phyid == TG3_PHY_OUI_2 ||
phyid == TG3_PHY_OUI_3)
do_low_power = true;
}
@@ -7535,11 +7535,58 @@ static int tg3_test_msi(struct tg3 *tp)
return err;
}
+static int tg3_request_firmware(struct tg3 *tp)
+{
+ const __be32 *fw_data;
+
+ if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) {
+ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+ tp->dev->name, tp->fw_needed);
+ return -ENOENT;
+ }
+
+ fw_data = (void *)tp->fw->data;
+
+ /* Firmware blob starts with version numbers, followed by
+ * start address and _full_ length including BSS sections
+ * (which must be longer than the actual data, of course
+ */
+
+ tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */
+ if (tp->fw_len < (tp->fw->size - 12)) {
+ printk(KERN_ERR "%s: bogus length %d in \"%s\"\n",
+ tp->dev->name, tp->fw_len, tp->fw_needed);
+ release_firmware(tp->fw);
+ tp->fw = NULL;
+ return -EINVAL;
+ }
+
+ /* We no longer need firmware; we have it. */
+ tp->fw_needed = NULL;
+ return 0;
+}
+
static int tg3_open(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
int err;
+ if (tp->fw_needed) {
+ err = tg3_request_firmware(tp);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
+ if (err)
+ return err;
+ } else if (err) {
+ printk(KERN_WARNING "%s: TSO capability disabled.\n",
+ tp->dev->name);
+ tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+ } else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+ printk(KERN_NOTICE "%s: TSO capability restored.\n",
+ tp->dev->name);
+ tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+ }
+ }
+
netif_carrier_off(tp->dev);
err = tg3_set_power_state(tp, PCI_D0);
@@ -12934,7 +12981,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
struct net_device *dev;
struct tg3 *tp;
int err, pm_cap;
- const char *fw_name = NULL;
char str[40];
u64 dma_mask, persist_dma_mask;
@@ -13091,7 +13137,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tg3_init_bufmgr_config(tp);
if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
- fw_name = FIRMWARE_TG3;
+ tp->fw_needed = FIRMWARE_TG3;
if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
@@ -13104,37 +13150,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
} else {
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
- }
- if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
- fw_name = FIRMWARE_TG3TSO5;
+ tp->fw_needed = FIRMWARE_TG3TSO5;
else
- fw_name = FIRMWARE_TG3TSO;
- }
-
- if (fw_name) {
- const __be32 *fw_data;
-
- err = request_firmware(&tp->fw, fw_name, &tp->pdev->dev);
- if (err) {
- printk(KERN_ERR "tg3: Failed to load firmware \"%s\"\n",
- fw_name);
- goto err_out_iounmap;
- }
-
- fw_data = (void *)tp->fw->data;
-
- /* Firmware blob starts with version numbers, followed by
- start address and _full_ length including BSS sections
- (which must be longer than the actual data, of course */
-
- tp->fw_len = be32_to_cpu(fw_data[2]); /* includes bss */
- if (tp->fw_len < (tp->fw->size - 12)) {
- printk(KERN_ERR "tg3: bogus length %d in \"%s\"\n",
- tp->fw_len, fw_name);
- err = -EINVAL;
- goto err_out_fw;
- }
+ tp->fw_needed = FIRMWARE_TG3TSO;
}
/* TSO is on by default on chips that support hardware TSO.
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index ae5da603c6af..508def3e077f 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2764,6 +2764,7 @@ struct tg3 {
struct ethtool_coalesce coal;
/* firmware info */
+ const char *fw_needed;
const struct firmware *fw;
u32 fw_len; /* includes BSS */
};
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 75461dbd4876..a9fd2b2ccaf6 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -1237,7 +1237,7 @@ static void tsi108_init_phy(struct net_device *dev)
spin_lock_irqsave(&phy_lock, flags);
tsi108_write_mii(data, MII_BMCR, BMCR_RESET);
- while (i--){
+ while (--i) {
if(!(tsi108_read_mii(data, MII_BMCR) & BMCR_RESET))
break;
udelay(10);
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 1210fb3748a7..db7d5e11855d 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -9,6 +9,11 @@
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
for more information on this driver.
+
+ DC21143 manual "21143 PCI/CardBus 10/100Mb/s Ethernet LAN Controller
+ Hardware Reference Manual" is currently available at :
+ http://developer.intel.com/design/network/manuals/278074.htm
+
Please submit bugs to http://bugzilla.kernel.org/ .
*/
@@ -32,7 +37,11 @@ void t21142_media_task(struct work_struct *work)
int csr12 = ioread32(ioaddr + CSR12);
int next_tick = 60*HZ;
int new_csr6 = 0;
+ int csr14 = ioread32(ioaddr + CSR14);
+ /* CSR12[LS10,LS100] are not reliable during autonegotiation */
+ if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
+ csr12 |= 6;
if (tulip_debug > 2)
printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
dev->name, csr12, medianame[dev->if_port]);
@@ -76,7 +85,7 @@ void t21142_media_task(struct work_struct *work)
new_csr6 = 0x83860000;
dev->if_port = 3;
iowrite32(0, ioaddr + CSR13);
- iowrite32(0x0003FF7F, ioaddr + CSR14);
+ iowrite32(0x0003FFFF, ioaddr + CSR14);
iowrite16(8, ioaddr + CSR15);
iowrite32(1, ioaddr + CSR13);
}
@@ -132,10 +141,14 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
struct tulip_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->base_addr;
int csr12 = ioread32(ioaddr + CSR12);
+ int csr14 = ioread32(ioaddr + CSR14);
+ /* CSR12[LS10,LS100] are not reliable during autonegotiation */
+ if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
+ csr12 |= 6;
if (tulip_debug > 1)
printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, "
- "%8.8x.\n", dev->name, csr12, csr5, ioread32(ioaddr + CSR14));
+ "%8.8x.\n", dev->name, csr12, csr5, csr14);
/* If NWay finished and we have a negotiated partner capability. */
if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) {
@@ -143,7 +156,9 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
int negotiated = tp->sym_advertise & (csr12 >> 16);
tp->lpar = csr12 >> 16;
tp->nwayset = 1;
- if (negotiated & 0x0100) dev->if_port = 5;
+ /* If partner cannot negotiate, it is 10Mbps Half Duplex */
+ if (!(csr12 & 0x8000)) dev->if_port = 0;
+ else if (negotiated & 0x0100) dev->if_port = 5;
else if (negotiated & 0x0080) dev->if_port = 3;
else if (negotiated & 0x0040) dev->if_port = 4;
else if (negotiated & 0x0020) dev->if_port = 0;
@@ -214,7 +229,7 @@ void t21142_lnk_change(struct net_device *dev, int csr5)
tp->timer.expires = RUN_AT(3*HZ);
add_timer(&tp->timer);
} else if (dev->if_port == 5)
- iowrite32(ioread32(ioaddr + CSR14) & ~0x080, ioaddr + CSR14);
+ iowrite32(csr14 & ~0x080, ioaddr + CSR14);
} else if (dev->if_port == 0 || dev->if_port == 4) {
if ((csr12 & 4) == 0)
printk(KERN_INFO"%s: 21143 10baseT link beat good.\n",
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index d5d53b633cf8..d4c5ecc51f77 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -392,7 +392,7 @@ static void de_rx (struct de_private *de)
unsigned drop = 0;
int rc;
- while (rx_work--) {
+ while (--rx_work) {
u32 status, len;
dma_addr_t mapping;
struct sk_buff *skb, *copy_skb;
@@ -464,13 +464,14 @@ static void de_rx (struct de_private *de)
drop = 1;
rx_next:
- de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn);
if (rx_tail == (DE_RX_RING_SIZE - 1))
de->rx_ring[rx_tail].opts2 =
cpu_to_le32(RingEnd | de->rx_buf_sz);
else
de->rx_ring[rx_tail].opts2 = cpu_to_le32(de->rx_buf_sz);
de->rx_ring[rx_tail].addr1 = cpu_to_le32(mapping);
+ wmb();
+ de->rx_ring[rx_tail].opts1 = cpu_to_le32(DescOwn);
rx_tail = NEXT_RX(rx_tail);
}
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index d7b81e4fdd56..09fea31d3e36 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -157,10 +157,16 @@ static int update_filter(struct tap_filter *filter, void __user *arg)
nexact = n;
- /* The rest is hashed */
+ /* Remaining multicast addresses are hashed,
+ * unicast will leave the filter disabled. */
memset(filter->mask, 0, sizeof(filter->mask));
- for (; n < uf.count; n++)
+ for (; n < uf.count; n++) {
+ if (!is_multicast_ether_addr(addr[n].u)) {
+ err = 0; /* no filter */
+ goto done;
+ }
addr_hash_set(filter->mask, addr[n].u);
+ }
/* For ALLMULTI just set the mask to all ones.
* This overrides the mask populated above. */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 11441225bf41..e87986867ba5 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1536,6 +1536,11 @@ static void adjust_link(struct net_device *dev)
static int init_phy(struct net_device *dev)
{
struct ucc_geth_private *priv = netdev_priv(dev);
+ struct device_node *np = priv->node;
+ struct device_node *phy, *mdio;
+ const phandle *ph;
+ char bus_name[MII_BUS_ID_SIZE];
+ const unsigned int *id;
struct phy_device *phydev;
char phy_id[BUS_ID_SIZE];
@@ -1543,8 +1548,18 @@ static int init_phy(struct net_device *dev)
priv->oldspeed = 0;
priv->oldduplex = -1;
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->ug_info->mdio_bus,
- priv->ug_info->phy_address);
+ ph = of_get_property(np, "phy-handle", NULL);
+ phy = of_find_node_by_phandle(*ph);
+ mdio = of_get_parent(phy);
+
+ id = of_get_property(phy, "reg", NULL);
+
+ of_node_put(phy);
+ of_node_put(mdio);
+
+ uec_mdio_bus_name(bus_name, mdio);
+ snprintf(phy_id, sizeof(phy_id), "%s:%02x",
+ bus_name, *id);
phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
@@ -3748,6 +3763,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ugeth->ug_info = ug_info;
ugeth->dev = dev;
+ ugeth->node = np;
return 0;
}
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 8f699cb773ee..16cbe42ba43c 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -1186,6 +1186,8 @@ struct ucc_geth_private {
int oldspeed;
int oldduplex;
int oldlink;
+
+ struct device_node *node;
};
void uec_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index c001d261366b..54635911305c 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -156,7 +156,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
if (err)
goto reg_map_fail;
- snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+ uec_mdio_bus_name(new_bus->id, np);
new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL);
@@ -283,3 +283,13 @@ void uec_mdio_exit(void)
{
of_unregister_platform_driver(&uec_mdio_driver);
}
+
+void uec_mdio_bus_name(char *name, struct device_node *np)
+{
+ const u32 *reg;
+
+ reg = of_get_property(np, "reg", NULL);
+
+ snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0);
+}
+
diff --git a/drivers/net/ucc_geth_mii.h b/drivers/net/ucc_geth_mii.h
index 1e45b2028a50..840cf80235b7 100644
--- a/drivers/net/ucc_geth_mii.h
+++ b/drivers/net/ucc_geth_mii.h
@@ -97,4 +97,5 @@ int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int __init uec_mdio_init(void);
void uec_mdio_exit(void);
+void uec_mdio_bus_name(char *name, struct device_node *np);
#endif /* __UEC_MII_H */
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index e009481c606c..396f821b5ff0 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1451,6 +1451,14 @@ static const struct usb_device_id products [] = {
// Cables-to-Go USB Ethernet Adapter
USB_DEVICE(0x0b95, 0x772a),
.driver_info = (unsigned long) &ax88772_info,
+}, {
+ // ABOCOM for pci
+ USB_DEVICE(0x14ea, 0xab11),
+ .driver_info = (unsigned long) &ax88178_info,
+}, {
+ // ASIX 88772a
+ USB_DEVICE(0x0db0, 0xa877),
+ .driver_info = (unsigned long) &ax88772_info,
},
{ }, // END
};
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 0d0fa91c0251..fe98acaead97 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -455,6 +455,7 @@ static const struct usb_device_id hso_ids[] = {
{icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */
{USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */
{USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */
+ {USB_DEVICE(0x0af0, 0x7381)}, /* GE40x */
{USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */
{USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */
{USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */
@@ -462,7 +463,8 @@ static const struct usb_device_id hso_ids[] = {
{USB_DEVICE(0x0af0, 0x7801)},
{USB_DEVICE(0x0af0, 0x7901)},
{USB_DEVICE(0x0af0, 0x7361)},
- {icon321_port_device(0x0af0, 0xd051)},
+ {USB_DEVICE(0x0af0, 0xd057)},
+ {USB_DEVICE(0x0af0, 0xd055)},
{}
};
MODULE_DEVICE_TABLE(usb, hso_ids);
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 5385d66b306e..ced8f36ebd01 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -94,10 +94,18 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data)
{
struct usb_device *xdev = dev->udev;
int ret;
+ void *buffer;
+
+ buffer = kmalloc(size, GFP_NOIO);
+ if (buffer == NULL)
+ return -ENOMEM;
ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
- MCS7830_RD_BMREQ, 0x0000, index, data,
+ MCS7830_RD_BMREQ, 0x0000, index, buffer,
size, MCS7830_CTRL_TIMEOUT);
+ memcpy(data, buffer, size);
+ kfree(buffer);
+
return ret;
}
@@ -105,10 +113,18 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data)
{
struct usb_device *xdev = dev->udev;
int ret;
+ void *buffer;
+
+ buffer = kmalloc(size, GFP_NOIO);
+ if (buffer == NULL)
+ return -ENOMEM;
+
+ memcpy(buffer, data, size);
ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
- MCS7830_WR_BMREQ, 0x0000, index, data,
+ MCS7830_WR_BMREQ, 0x0000, index, buffer,
size, MCS7830_CTRL_TIMEOUT);
+ kfree(buffer);
return ret;
}
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 852d0e7c4e62..108bbbeacfb6 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -263,10 +263,11 @@ static void veth_dev_free(struct net_device *dev)
}
static const struct net_device_ops veth_netdev_ops = {
- .ndo_init = veth_dev_init,
- .ndo_open = veth_open,
- .ndo_start_xmit = veth_xmit,
- .ndo_get_stats = veth_get_stats,
+ .ndo_init = veth_dev_init,
+ .ndo_open = veth_open,
+ .ndo_start_xmit = veth_xmit,
+ .ndo_get_stats = veth_get_stats,
+ .ndo_set_mac_address = eth_mac_addr,
};
static void veth_setup(struct net_device *dev)
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index a75f91dc3153..c5691fdb7079 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1302,7 +1302,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
static int velocity_init_td_ring(struct velocity_info *vptr)
{
dma_addr_t curr;
- unsigned int j;
+ int j;
/* Init the TD ring entries */
for (j = 0; j < vptr->tx.numq; j++) {
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 43f6523c40be..c68808336c8c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -24,6 +24,7 @@
#include <linux/virtio.h>
#include <linux/virtio_net.h>
#include <linux/scatterlist.h>
+#include <linux/if_vlan.h>
static int napi_weight = 128;
module_param(napi_weight, int, 0444);
@@ -33,7 +34,7 @@ module_param(csum, bool, 0444);
module_param(gso, bool, 0444);
/* FIXME: MTU in config. */
-#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
+#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
#define GOOD_COPY_LEN 128
struct virtnet_info
@@ -286,7 +287,7 @@ static void try_fill_recv_maxbufs(struct virtnet_info *vi)
skb_put(skb, MAX_PACKET_LEN);
hdr = skb_vnet_hdr(skb);
- sg_init_one(sg, hdr, sizeof(*hdr));
+ sg_set_buf(sg, hdr, sizeof(*hdr));
if (vi->big_packets) {
for (i = 0; i < MAX_SKB_FRAGS; i++) {
@@ -487,9 +488,9 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
/* Encode metadata header at front. */
if (vi->mergeable_rx_bufs)
- sg_init_one(sg, mhdr, sizeof(*mhdr));
+ sg_set_buf(sg, mhdr, sizeof(*mhdr));
else
- sg_init_one(sg, hdr, sizeof(*hdr));
+ sg_set_buf(sg, hdr, sizeof(*hdr));
num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index d3d37fed6893..15d9f51b292c 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -609,7 +609,7 @@ void i2400m_msg_to_dev_cancel_wait(struct i2400m *i2400m, int code)
spin_lock_irqsave(&i2400m->rx_lock, flags);
ack_skb = i2400m->ack_skb;
if (ack_skb && !IS_ERR(ack_skb))
- kfree(ack_skb);
+ kfree_skb(ack_skb);
i2400m->ack_skb = ERR_PTR(code);
spin_unlock_irqrestore(&i2400m->rx_lock, flags);
}
diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c
index 626632985977..9b81af3f80a9 100644
--- a/drivers/net/wimax/i2400m/debugfs.c
+++ b/drivers/net/wimax/i2400m/debugfs.c
@@ -234,20 +234,6 @@ struct dentry *debugfs_create_i2400m_reset(
&fops_i2400m_reset);
}
-/*
- * Debug levels control; see debug.h
- */
-struct d_level D_LEVEL[] = {
- D_SUBMODULE_DEFINE(control),
- D_SUBMODULE_DEFINE(driver),
- D_SUBMODULE_DEFINE(debugfs),
- D_SUBMODULE_DEFINE(fw),
- D_SUBMODULE_DEFINE(netdev),
- D_SUBMODULE_DEFINE(rfkill),
- D_SUBMODULE_DEFINE(rx),
- D_SUBMODULE_DEFINE(tx),
-};
-size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
#define __debugfs_register(prefix, name, parent) \
do { \
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 5f98047e18cf..d58b971faa64 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -613,7 +613,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
snprintf(wimax_dev->name, sizeof(wimax_dev->name),
- "i2400m-%s:%s", dev->bus->name, dev->bus_id);
+ "i2400m-%s:%s", dev->bus->name, dev_name(dev));
i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
if (i2400m->bm_cmd_buf == NULL) {
@@ -707,6 +707,22 @@ void i2400m_release(struct i2400m *i2400m)
EXPORT_SYMBOL_GPL(i2400m_release);
+/*
+ * Debug levels control; see debug.h
+ */
+struct d_level D_LEVEL[] = {
+ D_SUBMODULE_DEFINE(control),
+ D_SUBMODULE_DEFINE(driver),
+ D_SUBMODULE_DEFINE(debugfs),
+ D_SUBMODULE_DEFINE(fw),
+ D_SUBMODULE_DEFINE(netdev),
+ D_SUBMODULE_DEFINE(rfkill),
+ D_SUBMODULE_DEFINE(rx),
+ D_SUBMODULE_DEFINE(tx),
+};
+size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
+
+
static
int __init i2400m_driver_init(void)
{
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 067c871cc226..3b9d27ea2950 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -157,7 +157,7 @@ enum {
/* Firmware version we request when pulling the fw image file */
-#define I2400M_FW_VERSION "1.3"
+#define I2400M_FW_VERSION "1.4"
/**
diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c
index 9702c22b2497..0528879f6d39 100644
--- a/drivers/net/wimax/i2400m/usb-notif.c
+++ b/drivers/net/wimax/i2400m/usb-notif.c
@@ -102,7 +102,7 @@ int i2400mu_notification_grok(struct i2400mu *i2400mu, const void *buf,
dev_err(dev, "HW BUG? Unknown/unexpected data in notification "
"message (%zu bytes)\n", buf_len);
snprintf(prefix, sizeof(prefix), "%s %s: ",
- dev_driver_string(dev) , dev->bus_id);
+ dev_driver_string(dev) , dev_name(dev));
if (buf_len > 64) {
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
8, 4, buf, 64, 0);
diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c
index 074cc1f89853..a314799967cf 100644
--- a/drivers/net/wimax/i2400m/usb-rx.c
+++ b/drivers/net/wimax/i2400m/usb-rx.c
@@ -184,6 +184,8 @@ void i2400mu_rx_size_maybe_shrink(struct i2400mu *i2400mu)
* NOTE: this function might realloc the skb (if it is too small),
* so always update with the one returned.
* ERR_PTR() is < 0 on error.
+ * Will return NULL if it cannot reallocate -- this can be
+ * considered a transient retryable error.
*/
static
struct sk_buff *i2400mu_rx(struct i2400mu *i2400mu, struct sk_buff *rx_skb)
@@ -243,8 +245,8 @@ retry:
if (printk_ratelimit())
dev_err(dev, "RX: Can't reallocate skb to %d; "
"RX dropped\n", rx_size);
- kfree(rx_skb);
- result = 0;
+ kfree_skb(rx_skb);
+ rx_skb = NULL;
goto out; /* drop it...*/
}
kfree_skb(rx_skb);
@@ -344,7 +346,8 @@ int i2400mu_rxd(void *_i2400mu)
if (IS_ERR(rx_skb))
goto out;
atomic_dec(&i2400mu->rx_pending_count);
- if (rx_skb->len == 0) { /* some ignorable condition */
+ if (rx_skb == NULL || rx_skb->len == 0) {
+ /* some "ignorable" condition */
kfree_skb(rx_skb);
continue;
}
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
index bfca15da6f0f..14c11656e82c 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -1082,8 +1082,8 @@ static int __init arlan_probe_here(struct net_device *dev,
if (arlan_check_fingerprint(memaddr))
return -ENODEV;
- printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name,
- (int) virt_to_phys((void*)memaddr));
+ printk(KERN_NOTICE "%s: Arlan found at %llx, \n ", dev->name,
+ (u64) virt_to_phys((void*)memaddr));
ap->card = (void *) memaddr;
dev->mem_start = memaddr;
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 8ef87356e083..1d77ee9d6e99 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1028,6 +1028,8 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
* it's done by reseting the chip. To accomplish this we must
* first cleanup any pending DMA, then restart stuff after a la
* ath5k_init.
+ *
+ * Called with sc->lock.
*/
static int
ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
@@ -1096,6 +1098,42 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
* Buffers setup *
\***************/
+static
+struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
+{
+ struct sk_buff *skb;
+ unsigned int off;
+
+ /*
+ * Allocate buffer with headroom_needed space for the
+ * fake physical layer header at the start.
+ */
+ skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
+
+ if (!skb) {
+ ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
+ sc->rxbufsize + sc->cachelsz - 1);
+ return NULL;
+ }
+ /*
+ * Cache-line-align. This is important (for the
+ * 5210 at least) as not doing so causes bogus data
+ * in rx'd frames.
+ */
+ off = ((unsigned long)skb->data) % sc->cachelsz;
+ if (off != 0)
+ skb_reserve(skb, sc->cachelsz - off);
+
+ *skb_addr = pci_map_single(sc->pdev,
+ skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
+ ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
+ dev_kfree_skb(skb);
+ return NULL;
+ }
+ return skb;
+}
+
static int
ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
{
@@ -1103,37 +1141,11 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct sk_buff *skb = bf->skb;
struct ath5k_desc *ds;
- if (likely(skb == NULL)) {
- unsigned int off;
-
- /*
- * Allocate buffer with headroom_needed space for the
- * fake physical layer header at the start.
- */
- skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
- if (unlikely(skb == NULL)) {
- ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
- sc->rxbufsize + sc->cachelsz - 1);
+ if (!skb) {
+ skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
+ if (!skb)
return -ENOMEM;
- }
- /*
- * Cache-line-align. This is important (for the
- * 5210 at least) as not doing so causes bogus data
- * in rx'd frames.
- */
- off = ((unsigned long)skb->data) % sc->cachelsz;
- if (off != 0)
- skb_reserve(skb, sc->cachelsz - off);
-
bf->skb = skb;
- bf->skbaddr = pci_map_single(sc->pdev,
- skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) {
- ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
- dev_kfree_skb(skb);
- bf->skb = NULL;
- return -ENOMEM;
- }
}
/*
@@ -1662,7 +1674,8 @@ ath5k_tasklet_rx(unsigned long data)
{
struct ieee80211_rx_status rxs = {};
struct ath5k_rx_status rs = {};
- struct sk_buff *skb;
+ struct sk_buff *skb, *next_skb;
+ dma_addr_t next_skb_addr;
struct ath5k_softc *sc = (void *)data;
struct ath5k_buf *bf, *bf_last;
struct ath5k_desc *ds;
@@ -1747,10 +1760,17 @@ ath5k_tasklet_rx(unsigned long data)
goto next;
}
accept:
+ next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
+
+ /*
+ * If we can't replace bf->skb with a new skb under memory
+ * pressure, just skip this packet
+ */
+ if (!next_skb)
+ goto next;
+
pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
PCI_DMA_FROMDEVICE);
- bf->skb = NULL;
-
skb_put(skb, rs.rs_datalen);
/* The MAC header is padded to have 32-bit boundary if the
@@ -1823,6 +1843,9 @@ accept:
ath5k_check_ibss_tsf(sc, skb, &rxs);
__ieee80211_rx(sc->hw, skb, &rxs);
+
+ bf->skb = next_skb;
+ bf->skbaddr = next_skb_addr;
next:
list_move_tail(&bf->list, &sc->rxbuf);
} while (ath5k_rxbuf_setup(sc, bf) == 0);
@@ -2814,11 +2837,17 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath5k_softc *sc = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
+ int ret;
+
+ mutex_lock(&sc->lock);
sc->bintval = conf->beacon_int;
sc->power_level = conf->power_level;
- return ath5k_chan_set(sc, conf->channel);
+ ret = ath5k_chan_set(sc, conf->channel);
+
+ mutex_unlock(&sc->lock);
+ return ret;
}
static int
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 727f067aca4f..0e80990d8e84 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1538,6 +1538,7 @@ bad2:
bad:
if (ah)
ath9k_hw_detach(ah);
+ ath9k_exit_debug(sc);
return error;
}
@@ -1545,7 +1546,7 @@ bad:
static int ath_attach(u16 devid, struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
- int error = 0;
+ int error = 0, i;
DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
@@ -1589,11 +1590,11 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
/* initialize tx/rx engine */
error = ath_tx_init(sc, ATH_TXBUF);
if (error != 0)
- goto detach;
+ goto error_attach;
error = ath_rx_init(sc, ATH_RXBUF);
if (error != 0)
- goto detach;
+ goto error_attach;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
/* Initialze h/w Rfkill */
@@ -1601,8 +1602,9 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
/* Initialize s/w rfkill */
- if (ath_init_sw_rfkill(sc))
- goto detach;
+ error = ath_init_sw_rfkill(sc);
+ if (error)
+ goto error_attach;
#endif
error = ieee80211_register_hw(hw);
@@ -1611,8 +1613,16 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
ath_init_leds(sc);
return 0;
-detach:
- ath_detach(sc);
+
+error_attach:
+ /* cleanup tx queues */
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+ if (ATH_TXQ_SETUP(sc, i))
+ ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+ ath9k_hw_detach(sc->sc_ah);
+ ath9k_exit_debug(sc);
+
return error;
}
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 04ab457a8faa..1b71b934bb5e 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -490,7 +490,7 @@ static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
{
- if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG))
+ if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
return 0;
if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
return 0;
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
index 9112c030b1e8..6df1b3b77c25 100644
--- a/drivers/net/wireless/ath9k/regd_common.h
+++ b/drivers/net/wireless/ath9k/regd_common.h
@@ -228,7 +228,7 @@ enum {
};
#define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \
- (!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
+ (~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
#define REG_DOMAIN_5GHZ_MASK REQ_MASK
static struct reg_dmn_pair_mapping regDomainPairs[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 9b60a0c5de5f..21c841847d88 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -638,12 +638,16 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
s8 scale_action = 0;
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc, rate_mask;
+ u16 fc;
+ u16 rate_mask = 0;
struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
IWL_DEBUG_RATE("enter\n");
+ if (sta)
+ rate_mask = sta->supp_rates[sband->band];
+
/* Send management frames and broadcast/multicast data using lowest
* rate. */
fc = le16_to_cpu(hdr->frame_control);
@@ -651,11 +655,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
is_multicast_ether_addr(hdr->addr1) ||
!sta || !priv_sta) {
IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
- info->control.rates[0].idx = rate_lowest_index(sband, sta);
+ if (!rate_mask)
+ info->control.rates[0].idx =
+ rate_lowest_index(sband, NULL);
+ else
+ info->control.rates[0].idx =
+ rate_lowest_index(sband, sta);
return;
}
- rate_mask = sta->supp_rates[sband->band];
index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
if (sband->band == IEEE80211_BAND_5GHZ)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index f3f17929ca0b..27f50471aed8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -944,7 +944,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
}
/* See if there's a better rate or modulation mode to try. */
- rs_rate_scale_perform(priv, hdr, sta, lq_sta);
+ if (sta && sta->supp_rates[sband->band])
+ rs_rate_scale_perform(priv, hdr, sta, lq_sta);
out:
return;
}
@@ -2101,14 +2102,23 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl_lq_sta *lq_sta = priv_sta;
int rate_idx;
+ u64 mask_bit = 0;
IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
+ if (sta)
+ mask_bit = sta->supp_rates[sband->band];
+
/* Send management frames and broadcast/multicast data using lowest
* rate. */
if (!ieee80211_is_data(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
- info->control.rates[0].idx = rate_lowest_index(sband, sta);
+ if (!mask_bit)
+ info->control.rates[0].idx =
+ rate_lowest_index(sband, NULL);
+ else
+ info->control.rates[0].idx =
+ rate_lowest_index(sband, sta);
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5da6b35cd26d..36bafeb353ce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1719,6 +1719,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
priv->ucode_data_backup.len = data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
+ if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
+ !priv->ucode_data_backup.v_addr)
+ goto err_pci_alloc;
+
/* Initialization instructions and data */
if (init_size && init_data_size) {
priv->ucode_init.len = init_size;
@@ -2482,7 +2486,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb_any(skb);
IWL_DEBUG_MACDUMP("leave\n");
- return 0;
+ return NETDEV_TX_OK;
}
static int iwl_mac_add_interface(struct ieee80211_hw *hw,
@@ -4038,6 +4042,19 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
priv->is_open = 1;
}
+ /* pci driver assumes state will be saved in this function.
+ * pci state is saved and device disabled when interface is
+ * stopped, so at this time pci device will always be disabled -
+ * whether interface was started or not. saving pci state now will
+ * cause saved state be that of a disabled device, which will cause
+ * problems during resume in that we will end up with a disabled device.
+ *
+ * indicate that the current saved state (from when interface was
+ * stopped) is valid. if interface was never up at time of suspend
+ * then the saved state will still be valid as it was saved during
+ * .probe. */
+ pdev->state_saved = true;
+
pci_set_power_state(pdev, PCI_D3hot);
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 8c71ad4f88c5..4b35b30e493e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -224,7 +224,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
IWL_ERROR("Error: Response NULL in '%s'\n",
get_cmd_string(cmd->id));
ret = -EIO;
- goto out;
+ goto cancel;
}
ret = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 412f66bac1af..70a8b21ca39b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -480,6 +480,9 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
+ /* clean ucode key table bit map */
+ priv->ucode_key_table = 0;
+
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
EXPORT_SYMBOL(iwl_clear_stations_table);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index b0ee86c62685..ab13ff22a8c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -148,7 +148,7 @@ static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
pci_unmap_single(dev,
pci_unmap_addr(&txq->cmd[index]->meta, mapping),
pci_unmap_len(&txq->cmd[index]->meta, len),
- PCI_DMA_TODEVICE);
+ PCI_DMA_BIDIRECTIONAL);
/* Unmap chunks, if any. */
for (i = 1; i < num_tbs; i++) {
@@ -964,7 +964,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
* within command buffer array. */
txcmd_phys = pci_map_single(priv->pci_dev,
out_cmd, sizeof(struct iwl_cmd),
- PCI_DMA_TODEVICE);
+ PCI_DMA_BIDIRECTIONAL);
pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
/* Add buffer containing Tx command and MAC(!) header to TFD's
@@ -1115,7 +1115,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
phys_addr = pci_map_single(priv->pci_dev, out_cmd,
- len, PCI_DMA_TODEVICE);
+ len, PCI_DMA_BIDIRECTIONAL);
pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
pci_unmap_len_set(&out_cmd->meta, len, len);
phys_addr += offsetof(struct iwl_cmd, hdr);
@@ -1212,7 +1212,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
pci_unmap_single(priv->pci_dev,
pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping),
pci_unmap_len(&txq->cmd[cmd_idx]->meta, len),
- PCI_DMA_TODEVICE);
+ PCI_DMA_BIDIRECTIONAL);
for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d64580805d6e..93be74a1f139 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -745,7 +745,7 @@ static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_
IWL_ERROR("Error: Response NULL in '%s'\n",
get_cmd_string(cmd->id));
ret = -EIO;
- goto out;
+ goto cancel;
}
ret = 0;
@@ -6538,7 +6538,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb_any(skb);
IWL_DEBUG_MAC80211("leave\n");
- return 0;
+ return NETDEV_TX_OK;
}
static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
@@ -8143,6 +8143,19 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
priv->is_open = 1;
}
+ /* pci driver assumes state will be saved in this function.
+ * pci state is saved and device disabled when interface is
+ * stopped, so at this time pci device will always be disabled -
+ * whether interface was started or not. saving pci state now will
+ * cause saved state be that of a disabled device, which will cause
+ * problems during resume in that we will end up with a disabled device.
+ *
+ * indicate that the current saved state (from when interface was
+ * stopped) is valid. if interface was never up at time of suspend
+ * then the saved state will still be valid as it was saved during
+ * .probe. */
+ pdev->state_saved = true;
+
pci_set_power_state(pdev, PCI_D3hot);
return 0;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 61d2f50470c8..b118a35ec605 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -23,7 +23,7 @@ static const char * mesh_stat_strings[]= {
static void lbs_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
snprintf(info->fw_version, 32, "%u.%u.%u.p%u",
priv->fwrelease >> 24 & 0xff,
@@ -47,7 +47,7 @@ static int lbs_ethtool_get_eeprom_len(struct net_device *dev)
static int lbs_ethtool_get_eeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 * bytes)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct cmd_ds_802_11_eeprom_access cmd;
int ret;
@@ -76,7 +76,7 @@ out:
static void lbs_ethtool_get_stats(struct net_device *dev,
struct ethtool_stats *stats, uint64_t *data)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
@@ -113,7 +113,7 @@ static void lbs_ethtool_get_stats(struct net_device *dev,
static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
return MESH_STATS_NUM;
@@ -143,7 +143,7 @@ static void lbs_ethtool_get_strings(struct net_device *dev,
static void lbs_ethtool_get_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
if (priv->wol_criteria == 0xffffffff) {
/* Interface driver didn't configure wake */
@@ -166,7 +166,7 @@ static void lbs_ethtool_get_wol(struct net_device *dev,
static int lbs_ethtool_set_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
uint32_t criteria = 0;
if (priv->wol_criteria == 0xffffffff && wol->wolopts)
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index e173b1b46c23..f6a79a653b7b 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -32,7 +32,7 @@ struct txpd {
u8 pktdelay_2ms;
/* reserved */
u8 reserved1;
-};
+} __attribute__ ((packed));
/* RxPD Descriptor */
struct rxpd {
@@ -63,7 +63,7 @@ struct rxpd {
/* Pkt Priority */
u8 priority;
u8 reserved[3];
-};
+} __attribute__ ((packed));
struct cmd_header {
__le16 command;
@@ -97,7 +97,7 @@ struct enc_key {
struct lbs_offset_value {
u32 offset;
u32 value;
-};
+} __attribute__ ((packed));
/* Define general data structure */
/* cmd_DS_GEN */
@@ -107,7 +107,7 @@ struct cmd_ds_gen {
__le16 seqnum;
__le16 result;
void *cmdresp[0];
-};
+} __attribute__ ((packed));
#define S_DS_GEN sizeof(struct cmd_ds_gen)
@@ -163,7 +163,7 @@ struct cmd_ds_802_11_subscribe_event {
* bump this up a bit.
*/
uint8_t tlv[128];
-};
+} __attribute__ ((packed));
/*
* This scan handle Country Information IE(802.11d compliant)
@@ -180,7 +180,7 @@ struct cmd_ds_802_11_scan {
mrvlietypes_chanlistparamset_t ChanListParamSet;
mrvlietypes_ratesparamset_t OpRateSet;
#endif
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_scan_rsp {
struct cmd_header hdr;
@@ -188,7 +188,7 @@ struct cmd_ds_802_11_scan_rsp {
__le16 bssdescriptsize;
uint8_t nr_sets;
uint8_t bssdesc_and_tlvbuffer[0];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_get_log {
struct cmd_header hdr;
@@ -206,33 +206,33 @@ struct cmd_ds_802_11_get_log {
__le32 fcserror;
__le32 txframe;
__le32 wepundecryptable;
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_control {
struct cmd_header hdr;
__le16 action;
u16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_multicast_adr {
struct cmd_header hdr;
__le16 action;
__le16 nr_of_adrs;
u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_authenticate {
u8 macaddr[ETH_ALEN];
u8 authtype;
u8 reserved[10];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_deauthenticate {
struct cmd_header hdr;
u8 macaddr[ETH_ALEN];
__le16 reasoncode;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_associate {
u8 peerstaaddr[6];
@@ -251,7 +251,7 @@ struct cmd_ds_802_11_associate {
struct cmd_ds_802_11_associate_rsp {
struct ieeetypes_assocrsp assocRsp;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_set_wep {
struct cmd_header hdr;
@@ -265,7 +265,7 @@ struct cmd_ds_802_11_set_wep {
/* 40, 128bit or TXWEP */
uint8_t keytype[4];
uint8_t keymaterial[4][16];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_3_get_stat {
__le32 xmitok;
@@ -274,7 +274,7 @@ struct cmd_ds_802_3_get_stat {
__le32 rcverror;
__le32 rcvnobuffer;
__le32 rcvcrcerror;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_get_stat {
__le32 txfragmentcnt;
@@ -294,7 +294,7 @@ struct cmd_ds_802_11_get_stat {
__le32 txbeacon;
__le32 rxbeacon;
__le32 wepundecryptable;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_snmp_mib {
struct cmd_header hdr;
@@ -303,58 +303,58 @@ struct cmd_ds_802_11_snmp_mib {
__le16 oid;
__le16 bufsize;
u8 value[128];
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_reg_map {
__le16 buffersize;
u8 regmap[128];
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_bbp_reg_map {
__le16 buffersize;
u8 regmap[128];
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_rf_reg_map {
__le16 buffersize;
u8 regmap[64];
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_mac_reg_access {
__le16 action;
__le16 offset;
__le32 value;
-};
+} __attribute__ ((packed));
struct cmd_ds_bbp_reg_access {
__le16 action;
__le16 offset;
u8 value;
u8 reserved[3];
-};
+} __attribute__ ((packed));
struct cmd_ds_rf_reg_access {
__le16 action;
__le16 offset;
u8 value;
u8 reserved[3];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_radio_control {
struct cmd_header hdr;
__le16 action;
__le16 control;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_beacon_control {
__le16 action;
__le16 beacon_enable;
__le16 beacon_period;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_sleep_params {
struct cmd_header hdr;
@@ -379,7 +379,7 @@ struct cmd_ds_802_11_sleep_params {
/* reserved field, should be set to zero */
__le16 reserved;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_inactivity_timeout {
struct cmd_header hdr;
@@ -389,7 +389,7 @@ struct cmd_ds_802_11_inactivity_timeout {
/* Inactivity timeout in msec */
__le16 timeout;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rf_channel {
struct cmd_header hdr;
@@ -399,7 +399,7 @@ struct cmd_ds_802_11_rf_channel {
__le16 rftype; /* unused */
__le16 reserved; /* unused */
u8 channellist[32]; /* unused */
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rssi {
/* weighting factor */
@@ -408,21 +408,21 @@ struct cmd_ds_802_11_rssi {
__le16 reserved_0;
__le16 reserved_1;
__le16 reserved_2;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rssi_rsp {
__le16 SNR;
__le16 noisefloor;
__le16 avgSNR;
__le16 avgnoisefloor;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_mac_address {
struct cmd_header hdr;
__le16 action;
u8 macadd[ETH_ALEN];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rf_tx_power {
struct cmd_header hdr;
@@ -431,7 +431,7 @@ struct cmd_ds_802_11_rf_tx_power {
__le16 curlevel;
s8 maxlevel;
s8 minlevel;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rf_antenna {
__le16 action;
@@ -439,33 +439,33 @@ struct cmd_ds_802_11_rf_antenna {
/* Number of antennas or 0xffff(diversity) */
__le16 antennamode;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_monitor_mode {
__le16 action;
__le16 mode;
-};
+} __attribute__ ((packed));
struct cmd_ds_set_boot2_ver {
struct cmd_header hdr;
__le16 action;
__le16 version;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_fw_wake_method {
struct cmd_header hdr;
__le16 action;
__le16 method;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_sleep_period {
struct cmd_header hdr;
__le16 action;
__le16 period;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_ps_mode {
__le16 action;
@@ -473,7 +473,7 @@ struct cmd_ds_802_11_ps_mode {
__le16 multipledtim;
__le16 reserved;
__le16 locallisteninterval;
-};
+} __attribute__ ((packed));
struct cmd_confirm_sleep {
struct cmd_header hdr;
@@ -483,7 +483,7 @@ struct cmd_confirm_sleep {
__le16 multipledtim;
__le16 reserved;
__le16 locallisteninterval;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_data_rate {
struct cmd_header hdr;
@@ -491,14 +491,14 @@ struct cmd_ds_802_11_data_rate {
__le16 action;
__le16 reserved;
u8 rates[MAX_RATES];
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_rate_adapt_rateset {
struct cmd_header hdr;
__le16 action;
__le16 enablehwauto;
__le16 bitmap;
-};
+} __attribute__ ((packed));
struct cmd_ds_802_11_ad_hoc_start {
struct cmd_header hdr;
@@ -520,7 +520,7 @@ struct cmd_ds_802_11_ad_hoc_result {
u8 pad[3];
u8 bssid[ETH_ALEN];
-};
+} __attribute__ ((packed));
struct adhoc_bssdesc {
u8 bssid[ETH_ALEN];
@@ -578,7 +578,7 @@ struct MrvlIEtype_keyParamSet {
/* key material of size keylen */
u8 key[32];
-};
+} __attribute__ ((packed));
#define MAX_WOL_RULES 16
@@ -590,7 +590,7 @@ struct host_wol_rule {
__le16 reserve;
__be32 sig_mask;
__be32 signature;
-};
+} __attribute__ ((packed));
struct wol_config {
uint8_t action;
@@ -598,8 +598,7 @@ struct wol_config {
uint8_t no_rules_in_cmd;
uint8_t result;
struct host_wol_rule rule[MAX_WOL_RULES];
-};
-
+} __attribute__ ((packed));
struct cmd_ds_host_sleep {
struct cmd_header hdr;
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 2fc637ad85c7..ea3dc038be76 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -59,7 +59,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
static ssize_t if_usb_firmware_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct if_usb_card *cardp = priv->card;
char fwname[FIRMWARE_NAME_MAX];
int ret;
@@ -86,7 +86,7 @@ static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
static ssize_t if_usb_boot2_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct if_usb_card *cardp = priv->card;
char fwname[FIRMWARE_NAME_MAX];
int ret;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 4e0007d20030..f76623e0ff9a 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -222,7 +222,7 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
static ssize_t lbs_anycast_get(struct device *dev,
struct device_attribute *attr, char * buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
@@ -241,7 +241,7 @@ static ssize_t lbs_anycast_get(struct device *dev,
static ssize_t lbs_anycast_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
uint32_t datum;
int ret;
@@ -263,7 +263,7 @@ static ssize_t lbs_anycast_set(struct device *dev,
static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
u32 retry_limit;
@@ -286,7 +286,7 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_access mesh_access;
int ret;
unsigned long retry_limit;
@@ -321,7 +321,7 @@ static void lbs_remove_mesh(struct lbs_private *priv);
static ssize_t lbs_rtap_get(struct device *dev,
struct device_attribute *attr, char * buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
return snprintf(buf, 5, "0x%X\n", priv->monitormode);
}
@@ -332,7 +332,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
{
int monitor_mode;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
sscanf(buf, "%x", &monitor_mode);
if (monitor_mode) {
@@ -383,7 +383,7 @@ static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
static ssize_t lbs_mesh_get(struct device *dev,
struct device_attribute *attr, char * buf)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
}
@@ -393,7 +393,7 @@ static ssize_t lbs_mesh_get(struct device *dev,
static ssize_t lbs_mesh_set(struct device *dev,
struct device_attribute *attr, const char * buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
int enable;
int ret, action = CMD_ACT_MESH_CONFIG_STOP;
@@ -452,7 +452,7 @@ static struct attribute_group lbs_mesh_attr_group = {
*/
static int lbs_dev_open(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev) ;
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
lbs_deb_enter(LBS_DEB_NET);
@@ -521,7 +521,7 @@ static int lbs_mesh_stop(struct net_device *dev)
*/
static int lbs_eth_stop(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_NET);
@@ -538,7 +538,7 @@ static int lbs_eth_stop(struct net_device *dev)
static void lbs_tx_timeout(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_TX);
@@ -590,7 +590,7 @@ EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
*/
static struct net_device_stats *lbs_get_stats(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_NET);
return &priv->stats;
@@ -599,7 +599,7 @@ static struct net_device_stats *lbs_get_stats(struct net_device *dev)
static int lbs_set_mac_address(struct net_device *dev, void *addr)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct sockaddr *phwaddr = addr;
struct cmd_ds_802_11_mac_address cmd;
@@ -732,7 +732,7 @@ static void lbs_set_mcast_worker(struct work_struct *work)
static void lbs_set_multicast_list(struct net_device *dev)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
schedule_work(&priv->mcast_work);
}
@@ -748,7 +748,7 @@ static void lbs_set_multicast_list(struct net_device *dev)
static int lbs_thread(void *data)
{
struct net_device *dev = data;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
wait_queue_t wait;
lbs_deb_enter(LBS_DEB_THREAD);
@@ -1184,6 +1184,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
goto done;
}
priv = netdev_priv(dev);
+ dev->ml_priv = priv;
if (lbs_init_adapter(priv)) {
lbs_pr_err("failed to initialize adapter structure.\n");
diff --git a/drivers/net/wireless/libertas/persistcfg.c b/drivers/net/wireless/libertas/persistcfg.c
index d42b7a5a1b3f..18fe29faf99b 100644
--- a/drivers/net/wireless/libertas/persistcfg.c
+++ b/drivers/net/wireless/libertas/persistcfg.c
@@ -18,7 +18,7 @@
static int mesh_get_default_parameters(struct device *dev,
struct mrvl_mesh_defaults *defs)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
int ret;
@@ -57,7 +57,7 @@ static ssize_t bootflag_get(struct device *dev,
static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
uint32_t datum;
int ret;
@@ -100,7 +100,7 @@ static ssize_t boottime_get(struct device *dev,
static ssize_t boottime_set(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
uint32_t datum;
int ret;
@@ -152,7 +152,7 @@ static ssize_t channel_get(struct device *dev,
static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
struct cmd_ds_mesh_config cmd;
uint32_t datum;
int ret;
@@ -210,7 +210,7 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
int len;
int ret;
@@ -269,7 +269,7 @@ static ssize_t protocol_id_set(struct device *dev,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
uint32_t datum;
int ret;
@@ -323,7 +323,7 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
uint32_t datum;
int ret;
@@ -377,7 +377,7 @@ static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
struct cmd_ds_mesh_config cmd;
struct mrvl_mesh_defaults defs;
struct mrvl_meshie *ie;
- struct lbs_private *priv = netdev_priv(to_net_dev(dev));
+ struct lbs_private *priv = to_net_dev(dev)->ml_priv;
uint32_t datum;
int ret;
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 57f6c12cda20..9014950f4328 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -945,7 +945,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
DECLARE_SSID_BUF(ssid);
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1008,7 +1008,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
#define SCAN_ITEM_SIZE 128
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int err = 0;
char *ev = extra;
char *stop = ev + dwrq->length;
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index dac462641170..68bec31ae03b 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -60,7 +60,7 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned long flags;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct txpd *txpd;
char *p802x_hdr;
uint16_t pkt_len;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index c6102e08179e..f16d136ab4bb 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -163,7 +163,7 @@ static int lbs_get_name(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct chan_freq_power *cfp;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -189,7 +189,7 @@ static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
struct sockaddr *awrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -207,7 +207,7 @@ static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -231,7 +231,7 @@ static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -248,7 +248,7 @@ static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -273,7 +273,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
u32 val = vwrq->value;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -293,7 +293,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 val = 0;
@@ -315,7 +315,7 @@ out:
static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u32 val = vwrq->value;
@@ -336,7 +336,7 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 val = 0;
@@ -359,7 +359,7 @@ out:
static int lbs_get_mode(struct net_device *dev,
struct iw_request_info *info, u32 * uwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -385,7 +385,7 @@ static int lbs_get_txpow(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
s16 curlevel = 0;
int ret = 0;
@@ -418,7 +418,7 @@ out:
static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 slimit = 0, llimit = 0;
@@ -466,7 +466,7 @@ out:
static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u16 val = 0;
@@ -542,7 +542,7 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
int i, j;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct iw_range *range = (struct iw_range *)extra;
struct chan_freq_power *cfp;
u8 rates[MAX_RATES + 1];
@@ -708,7 +708,7 @@ out:
static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -758,7 +758,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
static int lbs_get_power(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -781,7 +781,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
EXCELLENT = 95,
PERFECT = 100
};
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
u32 rssi_qual;
u32 tx_qual;
u32 quality = 0;
@@ -886,7 +886,7 @@ static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
int ret = -EINVAL;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct chan_freq_power *cfp;
struct assoc_request * assoc_req;
@@ -943,7 +943,7 @@ static int lbs_mesh_set_freq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct chan_freq_power *cfp;
int ret = -EINVAL;
@@ -994,7 +994,7 @@ out:
static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
u8 new_rate = 0;
int ret = -EINVAL;
u8 rates[MAX_RATES + 1];
@@ -1054,7 +1054,7 @@ out:
static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1079,7 +1079,7 @@ static int lbs_set_mode(struct net_device *dev,
struct iw_request_info *info, u32 * uwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1124,7 +1124,7 @@ static int lbs_get_encode(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *dwrq, u8 * extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1319,7 +1319,7 @@ static int lbs_set_encode(struct net_device *dev,
struct iw_point *dwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
u16 is_default = 0, index = 0, set_tx_key = 0;
@@ -1395,7 +1395,7 @@ static int lbs_get_encodeext(struct net_device *dev,
char *extra)
{
int ret = -EINVAL;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int index, max_key_len;
@@ -1501,7 +1501,7 @@ static int lbs_set_encodeext(struct net_device *dev,
char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int alg = ext->alg;
struct assoc_request * assoc_req;
@@ -1639,7 +1639,7 @@ static int lbs_set_genie(struct net_device *dev,
struct iw_point *dwrq,
char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
struct assoc_request * assoc_req;
@@ -1685,7 +1685,7 @@ static int lbs_get_genie(struct net_device *dev,
char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1713,7 +1713,7 @@ static int lbs_set_auth(struct net_device *dev,
struct iw_param *dwrq,
char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
int ret = 0;
int updated = 0;
@@ -1816,7 +1816,7 @@ static int lbs_get_auth(struct net_device *dev,
char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1857,7 +1857,7 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
s16 dbm = (s16) vwrq->value;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1936,7 +1936,7 @@ out:
static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -1971,7 +1971,7 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
u8 ssid[IW_ESSID_MAX_SIZE];
u8 ssid_len = 0;
@@ -2040,7 +2040,7 @@ static int lbs_mesh_get_essid(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -2058,7 +2058,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
int ret = 0;
lbs_deb_enter(LBS_DEB_WEXT);
@@ -2102,7 +2102,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
struct sockaddr *awrq, char *extra)
{
- struct lbs_private *priv = netdev_priv(dev);
+ struct lbs_private *priv = dev->ml_priv;
struct assoc_request * assoc_req;
int ret = 0;
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
index c3bb85e0251e..067d1a9c728b 100644
--- a/drivers/net/wireless/orinoco/orinoco.c
+++ b/drivers/net/wireless/orinoco/orinoco.c
@@ -1673,7 +1673,7 @@ static void print_linkstatus(struct net_device *dev, u16 status)
s = "UNKNOWN";
}
- printk(KERN_INFO "%s: New link status: %s (%04x)\n",
+ printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
dev->name, s, status);
}
@@ -3157,8 +3157,20 @@ static int orinoco_pm_notifier(struct notifier_block *notifier,
return NOTIFY_DONE;
}
+
+static void orinoco_register_pm_notifier(struct orinoco_private *priv)
+{
+ priv->pm_notifier.notifier_call = orinoco_pm_notifier;
+ register_pm_notifier(&priv->pm_notifier);
+}
+
+static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
+{
+ unregister_pm_notifier(&priv->pm_notifier);
+}
#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
-#define orinoco_pm_notifier NULL
+#define orinoco_register_pm_notifier(priv) do { } while(0)
+#define orinoco_unregister_pm_notifier(priv) do { } while(0)
#endif
/********************************************************************/
@@ -3648,8 +3660,7 @@ struct net_device
priv->cached_fw = NULL;
/* Register PM notifiers */
- priv->pm_notifier.notifier_call = orinoco_pm_notifier;
- register_pm_notifier(&priv->pm_notifier);
+ orinoco_register_pm_notifier(priv);
return dev;
}
@@ -3673,7 +3684,7 @@ void free_orinocodev(struct net_device *dev)
kfree(rx_data);
}
- unregister_pm_notifier(&priv->pm_notifier);
+ orinoco_unregister_pm_notifier(priv);
orinoco_uncache_fw(priv);
priv->wpa_ie_len = 0;
@@ -5068,33 +5079,30 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
struct orinoco_private *priv = netdev_priv(dev);
u8 *buf;
unsigned long flags;
- int err = 0;
/* cut off at IEEE80211_MAX_DATA_LEN */
if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
(wrqu->data.length && (extra == NULL)))
return -EINVAL;
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
if (wrqu->data.length) {
buf = kmalloc(wrqu->data.length, GFP_KERNEL);
- if (buf == NULL) {
- err = -ENOMEM;
- goto out;
- }
+ if (buf == NULL)
+ return -ENOMEM;
memcpy(buf, extra, wrqu->data.length);
- kfree(priv->wpa_ie);
- priv->wpa_ie = buf;
- priv->wpa_ie_len = wrqu->data.length;
- } else {
- kfree(priv->wpa_ie);
- priv->wpa_ie = NULL;
- priv->wpa_ie_len = 0;
+ } else
+ buf = NULL;
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ kfree(buf);
+ return -EBUSY;
}
+ kfree(priv->wpa_ie);
+ priv->wpa_ie = buf;
+ priv->wpa_ie_len = wrqu->data.length;
+
if (priv->wpa_ie) {
/* Looks like wl_lkm wants to check the auth alg, and
* somehow pass it to the firmware.
@@ -5103,9 +5111,8 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
*/
}
-out:
orinoco_unlock(priv, &flags);
- return err;
+ return 0;
}
static int orinoco_ioctl_get_genie(struct net_device *dev,
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index c6a370fa9bcb..34561e6e816b 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -451,8 +451,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
if (err)
goto err;
-
- }
+ }
+ break;
case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
if (!priv->iq_autocal) {
@@ -745,7 +745,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
struct p54_hdr *entry_hdr;
struct p54_tx_data *entry_data;
- int pad = 0;
+ unsigned int pad = 0, frame_len;
range = (void *)info->rate_driver_data;
if (range->start_addr != addr) {
@@ -768,6 +768,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
__skb_unlink(entry, &priv->tx_queue);
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+ frame_len = entry->len;
entry_hdr = (struct p54_hdr *) entry->data;
entry_data = (struct p54_tx_data *) entry_hdr->data;
priv->tx_stats[entry_data->hw_queue].len--;
@@ -814,15 +815,28 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
info->status.ack_signal = p54_rssi_to_dbm(dev,
(int)payload->ack_rssi);
- if (entry_data->key_type == P54_CRYPTO_TKIPMICHAEL) {
+ /* Undo all changes to the frame. */
+ switch (entry_data->key_type) {
+ case P54_CRYPTO_TKIPMICHAEL: {
u8 *iv = (u8 *)(entry_data->align + pad +
- entry_data->crypt_offset);
+ entry_data->crypt_offset);
/* Restore the original TKIP IV. */
iv[2] = iv[0];
iv[0] = iv[1];
iv[1] = (iv[0] | 0x20) & 0x7f; /* WEPSeed - 8.3.2.2 */
+
+ frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */
+ break;
+ }
+ case P54_CRYPTO_AESCCMP:
+ frame_len -= 8; /* remove CCMP_MIC */
+ break;
+ case P54_CRYPTO_WEP:
+ frame_len -= 4; /* remove WEP_ICV */
+ break;
}
+ skb_trim(entry, frame_len);
skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
ieee80211_tx_status_irqsafe(dev, entry);
goto out;
@@ -1147,7 +1161,7 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
sizeof(struct p54_hdr) + sizeof(*tim),
- P54_CONTROL_TYPE_TIM, GFP_KERNEL);
+ P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1610,7 +1624,7 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
err:
printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
- kfree_skb(skb);
+ p54_free_skb(dev, skb);
return -EINVAL;
}
@@ -2077,7 +2091,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
algo = P54_CRYPTO_AESCCMP;
break;
default:
- return -EINVAL;
+ return -EOPNOTSUPP;
}
}
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 6a6a72f6f82c..5de2ebfb28c7 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -144,11 +144,8 @@ static void p54u_tx_cb(struct urb *urb)
struct sk_buff *skb = urb->context;
struct ieee80211_hw *dev = (struct ieee80211_hw *)
usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
- struct p54u_priv *priv = dev->priv;
- skb_pull(skb, priv->common.tx_hdr_len);
- if (FREE_AFTER_TX(skb))
- p54_free_skb(dev, skb);
+ p54_free_skb(dev, skb);
}
static void p54u_tx_dummy_cb(struct urb *urb) { }
@@ -230,7 +227,10 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
p54u_tx_dummy_cb, dev);
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ skb->data, skb->len, FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
+ addr_urb->transfer_flags |= URB_ZERO_PACKET;
+ data_urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(addr_urb, &priv->submitted);
err = usb_submit_urb(addr_urb, GFP_ATOMIC);
@@ -239,7 +239,7 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
goto out;
}
- usb_anchor_urb(addr_urb, &priv->submitted);
+ usb_anchor_urb(data_urb, &priv->submitted);
err = usb_submit_urb(data_urb, GFP_ATOMIC);
if (err)
usb_unanchor_urb(data_urb);
@@ -269,28 +269,24 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54u_priv *priv = dev->priv;
struct urb *data_urb;
- struct lm87_tx_hdr *hdr;
- __le32 checksum;
- __le32 addr = ((struct p54_hdr *)skb->data)->req_id;
+ struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
data_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!data_urb)
return;
- checksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
- hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr));
- hdr->chksum = checksum;
- hdr->device_addr = addr;
+ hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
+ hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
data_urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(data_urb, &priv->submitted);
if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
usb_unanchor_urb(data_urb);
- skb_pull(skb, sizeof(*hdr));
p54_free_skb(dev, skb);
}
usb_free_urb(data_urb);
@@ -300,11 +296,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54u_priv *priv = dev->priv;
struct urb *int_urb, *data_urb;
- struct net2280_tx_hdr *hdr;
+ struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
struct net2280_reg_write *reg;
int err = 0;
- __le32 addr = ((struct p54_hdr *) skb->data)->req_id;
- __le16 len = cpu_to_le16(skb->len);
reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
if (!reg)
@@ -327,10 +321,9 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
reg->addr = cpu_to_le32(P54U_DEV_BASE);
reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
- hdr = (void *)skb_push(skb, sizeof(*hdr));
memset(hdr, 0, sizeof(*hdr));
- hdr->len = len;
- hdr->device_addr = addr;
+ hdr->len = cpu_to_le16(skb->len);
+ hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
usb_fill_bulk_urb(int_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
@@ -341,11 +334,13 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
* free what's inside the transfer_buffer after the callback routine
* has completed.
*/
- int_urb->transfer_flags |= URB_FREE_BUFFER;
+ int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
usb_fill_bulk_urb(data_urb, priv->udev,
usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
- skb->data, skb->len, p54u_tx_cb, skb);
+ hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
+ p54u_tx_cb : p54u_tx_dummy_cb, skb);
+ data_urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(int_urb, &priv->submitted);
err = usb_submit_urb(int_urb, GFP_ATOMIC);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 607ce9f61b54..ed93ac41297f 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1649,9 +1649,7 @@ static char *rndis_translate_scan(struct net_device *dev,
char *end_buf,
struct ndis_80211_bssid_ex *bssid)
{
-#ifdef DEBUG
struct usbnet *usbdev = netdev_priv(dev);
-#endif
u8 *ie;
char *current_val;
int bssid_len, ie_len, i;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 746a8f36b931..0709decec9c2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -154,6 +154,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+ struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
struct ieee80211_rate *rate =
ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
const struct rt2x00_rate *hwrate;
@@ -313,7 +314,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* When preamble is enabled we should set the
* preamble bit for the signal.
*/
- if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
txdesc->signal |= 0x08;
}
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index c3f53a92180a..3298cae1e12d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -162,7 +162,7 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->flags))
+ if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
return;
cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 6ad6bac37706..f4747a1134ba 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -48,6 +48,10 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
{USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
{USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
{USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
+ /* Surecom */
+ {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187},
+ /* Logitech */
+ {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187},
/* Netgear */
{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
@@ -57,8 +61,16 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
/* Sitecom */
{USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
+ /* Sphairon Access Systems GmbH */
+ {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
+ /* Dick Smith Electronics */
+ {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187},
/* Abocom */
{USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
+ /* Qcom */
+ {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187},
+ /* AirLive */
+ {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187},
{}
};
@@ -273,6 +285,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
buf, skb->len, rtl8187_tx_cb, skb);
+ urb->transfer_flags |= URB_ZERO_PACKET;
usb_anchor_urb(urb, &priv->anchored);
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
index 4e75e8e7fa90..78df281b297a 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
@@ -285,7 +285,10 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
ofdm_power = priv->channels[channel - 1].hw_value >> 4;
cck_power = min(cck_power, (u8)11);
- ofdm_power = min(ofdm_power, (u8)35);
+ if (ofdm_power > (u8)15)
+ ofdm_power = 25;
+ else
+ ofdm_power += 10;
rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
@@ -536,7 +539,10 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
cck_power += priv->txpwr_base & 0xF;
cck_power = min(cck_power, (u8)35);
- ofdm_power = min(ofdm_power, (u8)15);
+ if (ofdm_power > (u8)15)
+ ofdm_power = 25;
+ else
+ ofdm_power += 10;
ofdm_power += priv->txpwr_base >> 4;
ofdm_power = min(ofdm_power, (u8)35);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index 7207bfd2e6cd..c875ee05e22e 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -86,6 +86,7 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type)
case AL7230B_RF:
r = zd_rf_init_al7230b(rf);
break;
+ case MAXIM_NEW_RF:
case UW2453_RF:
r = zd_rf_init_uw2453(rf);
break;
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index b5db57d2fcf5..f0e5e943f6e3 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -37,6 +37,7 @@
static struct usb_device_id usb_ids[] = {
/* ZD1211 */
{ USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 },
+ { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 },
{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
@@ -84,6 +85,7 @@ static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B },
/* "Driverless" devices that need ejecting */
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index 03a3f34e9039..a12a7211c982 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -183,7 +183,7 @@ static int __init sonic_probe1(struct net_device *dev)
if (lp->descriptors == NULL) {
printk(KERN_ERR "%s: couldn't alloc DMA memory for "
- " descriptors.\n", lp->device->bus_id);
+ " descriptors.\n", dev_name(lp->device));
goto out;
}
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 9da5a4b81133..8574622e36a5 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -38,7 +38,7 @@
static LIST_HEAD(dying_tasks);
static LIST_HEAD(dead_tasks);
-static cpumask_t marked_cpus = CPU_MASK_NONE;
+static cpumask_var_t marked_cpus;
static DEFINE_SPINLOCK(task_mortuary);
static void process_task_mortuary(void);
@@ -154,6 +154,10 @@ int sync_start(void)
{
int err;
+ if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+ return -ENOMEM;
+ cpumask_clear(marked_cpus);
+
start_cpu_work();
err = task_handoff_register(&task_free_nb);
@@ -179,6 +183,7 @@ out2:
task_handoff_unregister(&task_free_nb);
out1:
end_sync();
+ free_cpumask_var(marked_cpus);
goto out;
}
@@ -190,6 +195,7 @@ void sync_stop(void)
profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
task_handoff_unregister(&task_free_nb);
end_sync();
+ free_cpumask_var(marked_cpus);
}
@@ -456,10 +462,10 @@ static void mark_done(int cpu)
{
int i;
- cpu_set(cpu, marked_cpus);
+ cpumask_set_cpu(cpu, marked_cpus);
for_each_online_cpu(i) {
- if (!cpu_isset(i, marked_cpus))
+ if (!cpumask_test_cpu(i, marked_cpus))
return;
}
@@ -468,7 +474,7 @@ static void mark_done(int cpu)
*/
process_task_mortuary();
- cpus_clear(marked_cpus);
+ cpumask_clear(marked_cpus);
}
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 2e03b6d796d3..f0e99d4c066b 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -161,7 +161,7 @@ struct op_sample
{
entry->event = ring_buffer_lock_reserve
(op_ring_buffer_write, sizeof(struct op_sample) +
- size * sizeof(entry->sample->data[0]), &entry->irq_flags);
+ size * sizeof(entry->sample->data[0]));
if (entry->event)
entry->sample = ring_buffer_event_data(entry->event);
else
@@ -178,8 +178,7 @@ struct op_sample
int op_cpu_buffer_write_commit(struct op_entry *entry)
{
- return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event,
- entry->irq_flags);
+ return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event);
}
struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
@@ -393,16 +392,21 @@ oprofile_write_reserve(struct op_entry *entry, struct pt_regs * const regs,
return;
fail:
+ entry->event = NULL;
cpu_buf->sample_lost_overflow++;
}
int oprofile_add_data(struct op_entry *entry, unsigned long val)
{
+ if (!entry->event)
+ return 0;
return op_cpu_buffer_add_data(entry, val);
}
int oprofile_write_commit(struct op_entry *entry)
{
+ if (!entry->event)
+ return -EINVAL;
return op_cpu_buffer_write_commit(entry);
}
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
index 63f81c44846a..272995d20293 100644
--- a/drivers/oprofile/cpu_buffer.h
+++ b/drivers/oprofile/cpu_buffer.h
@@ -66,6 +66,13 @@ static inline void op_cpu_buffer_reset(int cpu)
cpu_buf->last_task = NULL;
}
+/*
+ * op_cpu_buffer_add_data() and op_cpu_buffer_write_commit() may be
+ * called only if op_cpu_buffer_write_reserve() did not return NULL or
+ * entry->event != NULL, otherwise entry->size or entry->event will be
+ * used uninitialized.
+ */
+
struct op_sample
*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size);
int op_cpu_buffer_write_commit(struct op_entry *entry);
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index d539d9df88e7..e16c38a70836 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -479,7 +479,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
res = &dino_dev->hba.lmmio_space;
res->flags = IORESOURCE_MEM;
size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)",
- bus->bridge->bus_id);
+ dev_name(bus->bridge));
res->name = kmalloc(size+1, GFP_KERNEL);
if(res->name)
strcpy((char *)res->name, name);
@@ -493,7 +493,7 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
struct list_head *ln, *tmp_ln;
printk(KERN_ERR "Dino: cannot attach bus %s\n",
- bus->bridge->bus_id);
+ dev_name(bus->bridge));
/* kill the bus, we can't do anything with it */
list_for_each_safe(ln, tmp_ln, &bus->devices) {
struct pci_dev *dev = pci_dev_b(ln);
@@ -611,12 +611,12 @@ dino_fixup_bus(struct pci_bus *bus)
}
DBG("DEBUG %s assigning %d [0x%lx,0x%lx]\n",
- bus->self->dev.bus_id, i,
+ dev_name(&bus->self->dev), i,
bus->self->resource[i].start,
bus->self->resource[i].end);
pci_assign_resource(bus->self, i);
DBG("DEBUG %s after assign %d [0x%lx,0x%lx]\n",
- bus->self->dev.bus_id, i,
+ dev_name(&bus->self->dev), i,
bus->self->resource[i].start,
bus->self->resource[i].end);
}
@@ -1026,7 +1026,8 @@ static int __init dino_probe(struct parisc_device *dev)
dino_current_bus = bus->subordinate + 1;
pci_bus_assign_resources(bus);
} else {
- printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n", dev->dev.bus_id, dino_current_bus);
+ printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (probably duplicate bus number %d)\n",
+ dev_name(&dev->dev), dino_current_bus);
/* increment the bus number in case of duplicates */
dino_current_bus++;
}
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 3fac8f81d59d..a70cf16ee1ad 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -668,7 +668,7 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
* @dev: instance of PCI owned by the driver that's asking
* @mask: number of address bits this PCI device can handle
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static int sba_dma_supported( struct device *dev, u64 mask)
{
@@ -680,8 +680,8 @@ static int sba_dma_supported( struct device *dev, u64 mask)
return(0);
}
- /* Documentation/DMA-mapping.txt tells drivers to try 64-bit first,
- * then fall back to 32-bit if that fails.
+ /* Documentation/PCI/PCI-DMA-mapping.txt tells drivers to try 64-bit
+ * first, then fall back to 32-bit if that fails.
* We are just "encouraging" 32-bit DMA masks here since we can
* never allow IOMMU bypass unless we add special support for ZX1.
*/
@@ -706,7 +706,7 @@ static int sba_dma_supported( struct device *dev, u64 mask)
* @size: number of bytes to map in driver buffer.
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static dma_addr_t
sba_map_single(struct device *dev, void *addr, size_t size,
@@ -785,7 +785,7 @@ sba_map_single(struct device *dev, void *addr, size_t size,
* @size: number of bytes mapped in driver buffer.
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void
sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
@@ -861,7 +861,7 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
* @size: number of bytes mapped in driver buffer.
* @dma_handle: IOVA of new buffer.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void *sba_alloc_consistent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
@@ -892,7 +892,7 @@ static void *sba_alloc_consistent(struct device *hwdev, size_t size,
* @vaddr: virtual address IOVA of "consistent" buffer.
* @dma_handler: IO virtual address of "consistent" buffer.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void
sba_free_consistent(struct device *hwdev, size_t size, void *vaddr,
@@ -927,7 +927,7 @@ int dump_run_sg = 0;
* @nents: number of entries in list
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static int
sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
@@ -1011,7 +1011,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
* @nents: number of entries in list
* @direction: R/W or both.
*
- * See Documentation/DMA-mapping.txt
+ * See Documentation/PCI/PCI-DMA-mapping.txt
*/
static void
sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
diff --git a/drivers/parport/parport_atari.c b/drivers/parport/parport_atari.c
index ad4cdd256137..0b28fccec03f 100644
--- a/drivers/parport/parport_atari.c
+++ b/drivers/parport/parport_atari.c
@@ -84,7 +84,7 @@ parport_atari_frob_control(struct parport *p, unsigned char mask,
static unsigned char
parport_atari_read_status(struct parport *p)
{
- return ((mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) |
+ return ((st_mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) |
PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR);
}
@@ -193,9 +193,9 @@ static int __init parport_atari_init(void)
sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
local_irq_restore(flags);
/* MFP port I0 as input. */
- mfp.data_dir &= ~1;
+ st_mfp.data_dir &= ~1;
/* MFP port I0 interrupt on high->low edge. */
- mfp.active_edge &= ~1;
+ st_mfp.active_edge &= ~1;
p = parport_register_port((unsigned long)&sound_ym.wd_data,
IRQ_MFP_BUSY, PARPORT_DMA_NONE,
&parport_atari_ops);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 101ed49a2d15..032db815b0f9 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -64,6 +64,11 @@ struct parport_pc_pci {
static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma)
{
+ /* the rule described below doesn't hold for this device */
+ if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
+ dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+ dev->subsystem_device == 0x0299)
+ return -ENODEV;
/*
* Netmos uses the subdevice ID to indicate the number of parallel
* and serial ports. The form is 0x00PS, where <P> is the number of
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 52b54f053be0..118c77778d29 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -133,7 +133,7 @@ int pci_bus_add_child(struct pci_bus *bus)
*
* Call hotplug for each new devices.
*/
-void pci_bus_add_devices(struct pci_bus *bus)
+void pci_bus_add_devices(const struct pci_bus *bus)
{
struct pci_dev *dev;
struct pci_bus *child;
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index f5a662a50acb..5f333403c2ea 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -42,6 +42,7 @@
LIST_HEAD(dmar_drhd_units);
static struct acpi_table_header * __initdata dmar_tbl;
+static acpi_size dmar_tbl_size;
static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
{
@@ -288,8 +289,9 @@ static int __init dmar_table_detect(void)
acpi_status status = AE_OK;
/* if we could find DMAR table, then there are DMAR devices */
- status = acpi_get_table(ACPI_SIG_DMAR, 0,
- (struct acpi_table_header **)&dmar_tbl);
+ status = acpi_get_table_with_size(ACPI_SIG_DMAR, 0,
+ (struct acpi_table_header **)&dmar_tbl,
+ &dmar_tbl_size);
if (ACPI_SUCCESS(status) && !dmar_tbl) {
printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
@@ -330,6 +332,14 @@ parse_dmar_table(void)
entry_header = (struct acpi_dmar_header *)(dmar + 1);
while (((unsigned long)entry_header) <
(((unsigned long)dmar) + dmar_tbl->length)) {
+ /* Avoid looping forever on bad ACPI tables */
+ if (entry_header->length == 0) {
+ printk(KERN_WARNING PREFIX
+ "Invalid 0-length structure\n");
+ ret = -EINVAL;
+ break;
+ }
+
dmar_table_print_dmar_entry(entry_header);
switch (entry_header->type) {
@@ -481,6 +491,7 @@ void __init detect_intel_iommu(void)
iommu_detected = 1;
#endif
}
+ early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
dmar_tbl = NULL;
}
@@ -491,7 +502,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
int map_size;
u32 ver;
static int iommu_allocated = 0;
- int agaw;
+ int agaw = 0;
iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
@@ -507,6 +518,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
+#ifdef CONFIG_DMAR
agaw = iommu_calculate_agaw(iommu);
if (agaw < 0) {
printk(KERN_ERR
@@ -514,6 +526,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
iommu->seq_id);
goto error;
}
+#endif
iommu->agaw = agaw;
/* the registers might be more than one page */
@@ -571,19 +584,49 @@ static inline void reclaim_free_desc(struct q_inval *qi)
}
}
+static int qi_check_fault(struct intel_iommu *iommu, int index)
+{
+ u32 fault;
+ int head;
+ struct q_inval *qi = iommu->qi;
+ int wait_index = (index + 1) % QI_LENGTH;
+
+ fault = readl(iommu->reg + DMAR_FSTS_REG);
+
+ /*
+ * If IQE happens, the head points to the descriptor associated
+ * with the error. No new descriptors are fetched until the IQE
+ * is cleared.
+ */
+ if (fault & DMA_FSTS_IQE) {
+ head = readl(iommu->reg + DMAR_IQH_REG);
+ if ((head >> 4) == index) {
+ memcpy(&qi->desc[index], &qi->desc[wait_index],
+ sizeof(struct qi_desc));
+ __iommu_flush_cache(iommu, &qi->desc[index],
+ sizeof(struct qi_desc));
+ writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
/*
* Submit the queued invalidation descriptor to the remapping
* hardware unit and wait for its completion.
*/
-void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
+int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
{
+ int rc = 0;
struct q_inval *qi = iommu->qi;
struct qi_desc *hw, wait_desc;
int wait_index, index;
unsigned long flags;
if (!qi)
- return;
+ return 0;
hw = qi->desc;
@@ -601,7 +644,8 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
hw[index] = *desc;
- wait_desc.low = QI_IWD_STATUS_DATA(2) | QI_IWD_STATUS_WRITE | QI_IWD_TYPE;
+ wait_desc.low = QI_IWD_STATUS_DATA(QI_DONE) |
+ QI_IWD_STATUS_WRITE | QI_IWD_TYPE;
wait_desc.high = virt_to_phys(&qi->desc_status[wait_index]);
hw[wait_index] = wait_desc;
@@ -612,13 +656,11 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
qi->free_head = (qi->free_head + 2) % QI_LENGTH;
qi->free_cnt -= 2;
- spin_lock(&iommu->register_lock);
/*
* update the HW tail register indicating the presence of
* new descriptors.
*/
writel(qi->free_head << 4, iommu->reg + DMAR_IQT_REG);
- spin_unlock(&iommu->register_lock);
while (qi->desc_status[wait_index] != QI_DONE) {
/*
@@ -628,15 +670,21 @@ void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
* a deadlock where the interrupt context can wait indefinitely
* for free slots in the queue.
*/
+ rc = qi_check_fault(iommu, index);
+ if (rc)
+ goto out;
+
spin_unlock(&qi->q_lock);
cpu_relax();
spin_lock(&qi->q_lock);
}
-
- qi->desc_status[index] = QI_DONE;
+out:
+ qi->desc_status[index] = qi->desc_status[wait_index] = QI_DONE;
reclaim_free_desc(qi);
spin_unlock_irqrestore(&qi->q_lock, flags);
+
+ return rc;
}
/*
@@ -649,13 +697,13 @@ void qi_global_iec(struct intel_iommu *iommu)
desc.low = QI_IEC_TYPE;
desc.high = 0;
+ /* should never fail */
qi_submit_sync(&desc, iommu);
}
int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
u64 type, int non_present_entry_flush)
{
-
struct qi_desc desc;
if (non_present_entry_flush) {
@@ -669,10 +717,7 @@ int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm,
| QI_CC_GRAN(type) | QI_CC_TYPE;
desc.high = 0;
- qi_submit_sync(&desc, iommu);
-
- return 0;
-
+ return qi_submit_sync(&desc, iommu);
}
int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
@@ -702,10 +747,7 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
desc.high = QI_IOTLB_ADDR(addr) | QI_IOTLB_IH(ih)
| QI_IOTLB_AM(size_order);
- qi_submit_sync(&desc, iommu);
-
- return 0;
-
+ return qi_submit_sync(&desc, iommu);
}
/*
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index e31fb91652ce..2aa117c8cd87 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -5,11 +5,15 @@
obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
+
+# pciehp should be linked before acpiphp in order to allow the native driver
+# to attempt to bind first. We can then fall back to generic support.
+
+obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
-obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o
obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 1c1141801060..f47bc74be567 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -30,9 +30,8 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
+#include <linux/acpi.h>
#include <linux/pci-acpi.h>
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
#define MY_NAME "acpi_pcihp"
@@ -408,7 +407,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
dbg("Trying to get hotplug control for %s\n",
(char *)string.pointer);
- status = pci_osc_control_set(handle, flags);
+ status = acpi_pci_osc_control_set(handle, flags);
if (ACPI_SUCCESS(status))
goto got_one;
kfree(string.pointer);
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index a13abf55d784..8450f4a6568a 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -225,7 +225,8 @@ void cpqhp_shutdown_debugfs(void)
void cpqhp_create_debugfs_files(struct controller *ctrl)
{
- ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops);
+ ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev),
+ S_IRUGO, root, ctrl, &debug_ops);
}
void cpqhp_remove_debugfs_files(struct controller *ctrl)
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index b0e7de9e536d..d8649e127298 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -195,13 +195,13 @@ static void remove_slot_worker(struct work_struct *work)
* Tries hard not to re-enable already existing devices;
* also handles scanning of subfunctions.
*/
-static void pci_rescan_slot(struct pci_dev *temp)
+static int pci_rescan_slot(struct pci_dev *temp)
{
struct pci_bus *bus = temp->bus;
struct pci_dev *dev;
int func;
- int retval;
u8 hdr_type;
+ int count = 0;
if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
temp->hdr_type = hdr_type & 0x7f;
@@ -213,17 +213,12 @@ static void pci_rescan_slot(struct pci_dev *temp)
dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3,
temp->devfn & 7);
- retval = pci_bus_add_device(dev);
- if (retval)
- dev_err(&dev->dev, "error adding "
- "device, continuing.\n");
- else
- add_slot(dev);
+ count++;
}
}
/* multifunction device? */
if (!(hdr_type & 0x80))
- return;
+ return count;
/* continue scanning for other functions */
for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
@@ -239,16 +234,13 @@ static void pci_rescan_slot(struct pci_dev *temp)
dbg("New device on %s function %x:%x\n",
bus->name, temp->devfn >> 3,
temp->devfn & 7);
- retval = pci_bus_add_device(dev);
- if (retval)
- dev_err(&dev->dev, "error adding "
- "device, continuing.\n");
- else
- add_slot(dev);
+ count++;
}
}
}
}
+
+ return count;
}
@@ -262,6 +254,8 @@ static void pci_rescan_bus(const struct pci_bus *bus)
{
unsigned int devfn;
struct pci_dev *dev;
+ int retval;
+ int found = 0;
dev = alloc_pci_dev();
if (!dev)
return;
@@ -270,7 +264,23 @@ static void pci_rescan_bus(const struct pci_bus *bus)
dev->sysdata = bus->sysdata;
for (devfn = 0; devfn < 0x100; devfn += 8) {
dev->devfn = devfn;
- pci_rescan_slot(dev);
+ found += pci_rescan_slot(dev);
+ }
+
+ if (found) {
+ pci_bus_assign_resources(bus);
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ /* Skip already-added devices */
+ if (dev->is_added)
+ continue;
+ retval = pci_bus_add_device(dev);
+ if (retval)
+ dev_err(&dev->dev,
+ "Error adding device, continuing\n");
+ else
+ add_slot(dev);
+ }
+ pci_bus_add_devices(bus);
}
kfree(dev);
}
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index db85284ffb62..0a368547e633 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -46,10 +46,10 @@ extern int pciehp_force;
extern struct workqueue_struct *pciehp_wq;
#define dbg(format, arg...) \
- do { \
- if (pciehp_debug) \
- printk("%s: " format, MY_NAME , ## arg); \
- } while (0)
+do { \
+ if (pciehp_debug) \
+ printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \
+} while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
@@ -60,7 +60,7 @@ extern struct workqueue_struct *pciehp_wq;
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (pciehp_debug) \
- dev_printk(, &ctrl->pcie->device, \
+ dev_printk(KERN_DEBUG, &ctrl->pcie->device, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
@@ -108,9 +108,11 @@ struct controller {
u32 slot_cap;
u8 cap_base;
struct timer_list poll_timer;
- int cmd_busy;
+ unsigned int cmd_busy:1;
unsigned int no_cmd_complete:1;
unsigned int link_active_reporting:1;
+ unsigned int notification_enabled:1;
+ unsigned int power_fault_detected;
};
#define INT_BUTTON_IGNORE 0
@@ -170,6 +172,7 @@ extern int pciehp_configure_device(struct slot *p_slot);
extern int pciehp_unconfigure_device(struct slot *p_slot);
extern void pciehp_queue_pushbutton_work(struct work_struct *work);
struct controller *pcie_init(struct pcie_device *dev);
+int pcie_init_notification(struct controller *ctrl);
int pciehp_enable_slot(struct slot *p_slot);
int pciehp_disable_slot(struct slot *p_slot);
int pcie_enable_notification(struct controller *ctrl);
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 438d795f9fe3..96048010e7d9 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -67,37 +67,27 @@ static int __init parse_detect_mode(void)
return PCIEHP_DETECT_DEFAULT;
}
-static struct pcie_port_service_id __initdata port_pci_ids[] = {
- {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_ANY_PORT,
- .service_type = PCIE_PORT_SERVICE_HP,
- .driver_data = 0,
- }, { /* end: all zeroes */ }
-};
-
static int __initdata dup_slot_id;
static int __initdata acpi_slot_detected;
static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
/* Dummy driver for dumplicate name detection */
-static int __init dummy_probe(struct pcie_device *dev,
- const struct pcie_port_service_id *id)
+static int __init dummy_probe(struct pcie_device *dev)
{
int pos;
u32 slot_cap;
struct slot *slot, *tmp;
struct pci_dev *pdev = dev->port;
struct pci_bus *pbus = pdev->subordinate;
- if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL)))
- return -ENOMEM;
/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
if (pciehp_get_hp_hw_control_from_firmware(pdev))
return -ENODEV;
if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP)))
return -ENODEV;
pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
+ slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+ if (!slot)
+ return -ENOMEM;
slot->number = slot_cap >> 19;
list_for_each_entry(tmp, &dummy_slots, slot_list) {
if (tmp->number == slot->number)
@@ -111,7 +101,8 @@ static int __init dummy_probe(struct pcie_device *dev,
static struct pcie_port_service_driver __initdata dummy_driver = {
.name = "pciehp_dummy",
- .id_table = port_pci_ids,
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_HP,
.probe = dummy_probe,
};
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 5482d4ed8256..fb254b2454de 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -126,8 +126,10 @@ static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status)
mutex_lock(&slot->ctrl->crit_sect);
/* has it been >1 sec since our last toggle? */
- if ((get_seconds() - slot->last_emi_toggle) < 1)
+ if ((get_seconds() - slot->last_emi_toggle) < 1) {
+ mutex_unlock(&slot->ctrl->crit_sect);
return -EINVAL;
+ }
/* see what our current state is */
retval = get_lock_status(hotplug_slot, &value);
@@ -399,7 +401,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
return 0;
}
-static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
+static int pciehp_probe(struct pcie_device *dev)
{
int rc;
struct controller *ctrl;
@@ -432,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
goto err_out_release_ctlr;
}
+ /* Enable events after we have setup the data structures */
+ rc = pcie_init_notification(ctrl);
+ if (rc) {
+ ctrl_err(ctrl, "Notification initialization failed\n");
+ goto err_out_release_ctlr;
+ }
+
/* Check if slot is occupied */
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
t_slot->hpc_ops->get_adapter_status(t_slot, &value);
@@ -466,7 +475,7 @@ static void pciehp_remove (struct pcie_device *dev)
}
#ifdef CONFIG_PM
-static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
+static int pciehp_suspend (struct pcie_device *dev)
{
dev_info(&dev->device, "%s ENTRY\n", __func__);
return 0;
@@ -494,20 +503,12 @@ static int pciehp_resume (struct pcie_device *dev)
}
return 0;
}
-#endif
-
-static struct pcie_port_service_id port_pci_ids[] = { {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_ANY_PORT,
- .service_type = PCIE_PORT_SERVICE_HP,
- .driver_data = 0,
- }, { /* end: all zeroes */ }
-};
+#endif /* PM */
static struct pcie_port_service_driver hpdriver_portdrv = {
.name = PCIE_MODULE_NAME,
- .id_table = &port_pci_ids[0],
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_HP,
.probe = pciehp_probe,
.remove = pciehp_remove,
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 71a8012886b0..07bd32151146 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -548,23 +548,21 @@ static int hpc_power_on_slot(struct slot * slot)
slot_cmd = POWER_ON;
cmd_mask = PCI_EXP_SLTCTL_PCC;
- /* Enable detection that we turned off at slot power-off time */
if (!pciehp_poll_mode) {
- slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
+ /* Enable power fault detection turned off at power off time */
+ slot_cmd |= PCI_EXP_SLTCTL_PFDE;
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
}
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-
if (retval) {
ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
- return -1;
+ return retval;
}
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+ ctrl->power_fault_detected = 0;
return retval;
}
@@ -621,18 +619,10 @@ static int hpc_power_off_slot(struct slot * slot)
slot_cmd = POWER_OFF;
cmd_mask = PCI_EXP_SLTCTL_PCC;
- /*
- * If we get MRL or presence detect interrupts now, the isr
- * will notice the sticky power-fault bit too and issue power
- * indicator change commands. This will lead to an endless loop
- * of command completions, since the power-fault bit remains on
- * till the slot is powered on again.
- */
if (!pciehp_poll_mode) {
- slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
+ /* Disable power fault detection */
+ slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
}
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
@@ -672,10 +662,11 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
PCI_EXP_SLTSTA_CC);
+ detected &= ~intr_loc;
intr_loc |= detected;
if (!intr_loc)
return IRQ_NONE;
- if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, detected)) {
+ if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, intr_loc)) {
ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
__func__);
return IRQ_NONE;
@@ -709,9 +700,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
pciehp_handle_presence_change(p_slot);
/* Check Power Fault Detected */
- if (intr_loc & PCI_EXP_SLTSTA_PFD)
+ if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
+ ctrl->power_fault_detected = 1;
pciehp_handle_power_fault(p_slot);
-
+ }
return IRQ_HANDLED;
}
@@ -934,7 +926,7 @@ static void pcie_disable_notification(struct controller *ctrl)
ctrl_warn(ctrl, "Cannot disable software notification\n");
}
-static int pcie_init_notification(struct controller *ctrl)
+int pcie_init_notification(struct controller *ctrl)
{
if (pciehp_request_irq(ctrl))
return -1;
@@ -942,13 +934,17 @@ static int pcie_init_notification(struct controller *ctrl)
pciehp_free_irq(ctrl);
return -1;
}
+ ctrl->notification_enabled = 1;
return 0;
}
static void pcie_shutdown_notification(struct controller *ctrl)
{
- pcie_disable_notification(ctrl);
- pciehp_free_irq(ctrl);
+ if (ctrl->notification_enabled) {
+ pcie_disable_notification(ctrl);
+ pciehp_free_irq(ctrl);
+ ctrl->notification_enabled = 0;
+ }
}
static int pcie_init_slot(struct controller *ctrl)
@@ -1110,13 +1106,8 @@ struct controller *pcie_init(struct pcie_device *dev)
if (pcie_init_slot(ctrl))
goto abort_ctrl;
- if (pcie_init_notification(ctrl))
- goto abort_slot;
-
return ctrl;
-abort_slot:
- pcie_cleanup_slot(ctrl);
abort_ctrl:
kfree(ctrl);
abort:
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 6aba0b6cf2e0..974e924ca96d 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -48,10 +48,10 @@ extern int shpchp_debug;
extern struct workqueue_struct *shpchp_wq;
#define dbg(format, arg...) \
- do { \
- if (shpchp_debug) \
- printk("%s: " format, MY_NAME , ## arg); \
- } while (0)
+do { \
+ if (shpchp_debug) \
+ printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \
+} while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
@@ -62,7 +62,7 @@ extern struct workqueue_struct *shpchp_wq;
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (shpchp_debug) \
- dev_printk(, &ctrl->pci_dev->dev, \
+ dev_printk(KERN_DEBUG, &ctrl->pci_dev->dev, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 138f161becc0..aa315e52529b 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -137,7 +137,7 @@ int __ref shpchp_configure_device(struct slot *p_slot)
busnr))
break;
}
- if (busnr >= end) {
+ if (busnr > end) {
ctrl_err(ctrl,
"No free bus for hot-added bridge\n");
pci_dev_put(dev);
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 3dfecb20d5e7..b548937d4746 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -61,6 +61,8 @@
/* global iommu list, set NULL for ignored DMAR units */
static struct intel_iommu **g_iommus;
+static int rwbf_quirk;
+
/*
* 0: Present
* 1-11: Reserved
@@ -268,7 +270,12 @@ static long list_size;
static void domain_remove_dev_info(struct dmar_domain *domain);
-int dmar_disabled;
+#ifdef CONFIG_DMAR_DEFAULT_ON
+int dmar_disabled = 0;
+#else
+int dmar_disabled = 1;
+#endif /*CONFIG_DMAR_DEFAULT_ON*/
+
static int __initdata dmar_map_gfx = 1;
static int dmar_forcedac;
static int intel_iommu_strict;
@@ -284,9 +291,12 @@ static int __init intel_iommu_setup(char *str)
if (!str)
return -EINVAL;
while (*str) {
- if (!strncmp(str, "off", 3)) {
+ if (!strncmp(str, "on", 2)) {
+ dmar_disabled = 0;
+ printk(KERN_INFO "Intel-IOMMU: enabled\n");
+ } else if (!strncmp(str, "off", 3)) {
dmar_disabled = 1;
- printk(KERN_INFO"Intel-IOMMU: disabled\n");
+ printk(KERN_INFO "Intel-IOMMU: disabled\n");
} else if (!strncmp(str, "igfx_off", 8)) {
dmar_map_gfx = 0;
printk(KERN_INFO
@@ -777,7 +787,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu)
u32 val;
unsigned long flag;
- if (!cap_rwbf(iommu->cap))
+ if (!rwbf_quirk && !cap_rwbf(iommu->cap))
return;
val = iommu->gcmd | DMA_GCMD_WBF;
@@ -1960,7 +1970,7 @@ static inline void iommu_prepare_isa(void)
ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
if (ret)
- printk("IOMMU: Failed to create 0-64M identity map, "
+ printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, "
"floppy might not work\n");
}
@@ -3129,3 +3139,15 @@ static struct iommu_ops intel_iommu_ops = {
.unmap = intel_iommu_unmap_range,
.iova_to_phys = intel_iommu_iova_to_phys,
};
+
+static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
+{
+ /*
+ * Mobile 4 Series Chipset neglects to set RWBF capability,
+ * but needs it:
+ */
+ printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n");
+ rwbf_quirk = 1;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index f78371b22529..9d07a05d26f1 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -6,6 +6,7 @@
#include <linux/irq.h>
#include <asm/io_apic.h>
#include <asm/smp.h>
+#include <asm/cpu.h>
#include <linux/intel-iommu.h>
#include "intr_remapping.h"
@@ -20,7 +21,7 @@ struct irq_2_iommu {
u8 irte_mask;
};
-#ifdef CONFIG_SPARSE_IRQ
+#ifdef CONFIG_GENERIC_HARDIRQS
static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
{
struct irq_2_iommu *iommu;
@@ -207,7 +208,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
return index;
}
-static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
+static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
{
struct qi_desc desc;
@@ -215,7 +216,7 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
| QI_IEC_SELECTIVE;
desc.high = 0;
- qi_submit_sync(&desc, iommu);
+ return qi_submit_sync(&desc, iommu);
}
int map_irq_to_irte_handle(int irq, u16 *sub_handle)
@@ -283,6 +284,7 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
int modify_irte(int irq, struct irte *irte_modified)
{
+ int rc;
int index;
struct irte *irte;
struct intel_iommu *iommu;
@@ -303,14 +305,15 @@ int modify_irte(int irq, struct irte *irte_modified)
set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
__iommu_flush_cache(iommu, irte, sizeof(*irte));
- qi_flush_iec(iommu, index, 0);
-
+ rc = qi_flush_iec(iommu, index, 0);
spin_unlock(&irq_2_ir_lock);
- return 0;
+
+ return rc;
}
int flush_irte(int irq)
{
+ int rc;
int index;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
@@ -326,10 +329,10 @@ int flush_irte(int irq)
index = irq_iommu->irte_index + irq_iommu->sub_handle;
- qi_flush_iec(iommu, index, irq_iommu->irte_mask);
+ rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
spin_unlock(&irq_2_ir_lock);
- return 0;
+ return rc;
}
struct intel_iommu *map_ioapic_to_ir(int apic)
@@ -355,6 +358,7 @@ struct intel_iommu *map_dev_to_ir(struct pci_dev *dev)
int free_irte(int irq)
{
+ int rc = 0;
int index, i;
struct irte *irte;
struct intel_iommu *iommu;
@@ -375,7 +379,7 @@ int free_irte(int irq)
if (!irq_iommu->sub_handle) {
for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
set_64bit((unsigned long *)irte, 0);
- qi_flush_iec(iommu, index, irq_iommu->irte_mask);
+ rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
}
irq_iommu->iommu = NULL;
@@ -385,7 +389,7 @@ int free_irte(int irq)
spin_unlock(&irq_2_ir_lock);
- return 0;
+ return rc;
}
static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index b4a90badd0a6..dceea56f7342 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -27,40 +27,33 @@ static int pci_msi_enable = 1;
/* Arch hooks */
-int __attribute__ ((weak))
-arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+#ifndef arch_msi_check_device
+int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
{
return 0;
}
+#endif
-int __attribute__ ((weak))
-arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
-{
- return 0;
-}
-
-int __attribute__ ((weak))
-arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+#ifndef arch_setup_msi_irqs
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
list_for_each_entry(entry, &dev->msi_list, list) {
ret = arch_setup_msi_irq(dev, entry);
- if (ret)
+ if (ret < 0)
return ret;
+ if (ret > 0)
+ return -ENOSPC;
}
return 0;
}
+#endif
-void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
-{
- return;
-}
-
-void __attribute__ ((weak))
-arch_teardown_msi_irqs(struct pci_dev *dev)
+#ifndef arch_teardown_msi_irqs
+void arch_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
@@ -69,6 +62,7 @@ arch_teardown_msi_irqs(struct pci_dev *dev)
arch_teardown_msi_irq(entry->irq);
}
}
+#endif
static void __msi_set_enable(struct pci_dev *dev, int pos, int enable)
{
@@ -103,6 +97,14 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
}
}
+static inline __attribute_const__ u32 msi_mask(unsigned x)
+{
+ /* Don't shift by >= width of type */
+ if (x >= 5)
+ return 0xffffffff;
+ return (1 << (1 << x)) - 1;
+}
+
static void msix_flush_writes(struct irq_desc *desc)
{
struct msi_desc *entry;
@@ -398,21 +400,18 @@ static int msi_capability_init(struct pci_dev *dev)
entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
- if (entry->msi_attrib.maskbit) {
- entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
- entry->msi_attrib.is_64);
- }
entry->dev = dev;
if (entry->msi_attrib.maskbit) {
- unsigned int maskbits, temp;
+ unsigned int base, maskbits, temp;
+
+ base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+ entry->mask_base = (void __iomem *)(long)base;
+
/* All MSIs are unmasked by default, Mask them all */
- pci_read_config_dword(dev,
- msi_mask_bits_reg(pos, entry->msi_attrib.is_64),
- &maskbits);
- temp = (1 << multi_msi_capable(control));
- temp = ((temp - 1) & ~temp);
+ pci_read_config_dword(dev, base, &maskbits);
+ temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
maskbits |= temp;
- pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits);
+ pci_write_config_dword(dev, base, maskbits);
entry->msi_attrib.maskbits_mask = temp;
}
list_add_tail(&entry->list, &dev->msi_list);
@@ -490,7 +489,9 @@ static int msix_capability_init(struct pci_dev *dev,
}
ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
- if (ret) {
+ if (ret < 0) {
+ /* If we had some success report the number of irqs
+ * we succeeded in setting up. */
int avail = 0;
list_for_each_entry(entry, &dev->msi_list, list) {
if (entry->irq != 0) {
@@ -498,14 +499,13 @@ static int msix_capability_init(struct pci_dev *dev,
}
}
- msi_free_irqs(dev);
+ if (avail != 0)
+ ret = avail;
+ }
- /* If we had some success report the number of irqs
- * we succeeded in setting up.
- */
- if (avail == 0)
- avail = ret;
- return avail;
+ if (ret) {
+ msi_free_irqs(dev);
+ return ret;
}
i = 0;
@@ -670,6 +670,23 @@ static int msi_free_irqs(struct pci_dev* dev)
}
/**
+ * pci_msix_table_size - return the number of device's MSI-X table entries
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ */
+int pci_msix_table_size(struct pci_dev *dev)
+{
+ int pos;
+ u16 control;
+
+ pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+ if (!pos)
+ return 0;
+
+ pci_read_config_word(dev, msi_control_reg(pos), &control);
+ return multi_msix_capable(control);
+}
+
+/**
* pci_enable_msix - configure device's MSI-X capability structure
* @dev: pointer to the pci_dev data structure of MSI-X device function
* @entries: pointer to an array of MSI-X entries
@@ -686,9 +703,8 @@ static int msi_free_irqs(struct pci_dev* dev)
**/
int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
{
- int status, pos, nr_entries;
+ int status, nr_entries;
int i, j;
- u16 control;
if (!entries)
return -EINVAL;
@@ -697,9 +713,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
if (status)
return status;
- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
- pci_read_config_word(dev, msi_control_reg(pos), &control);
- nr_entries = multi_msix_capable(control);
+ nr_entries = pci_msix_table_size(dev);
if (nvec > nr_entries)
return -EINVAL;
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index deea8a187eb8..fac5eddcefd2 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -18,221 +18,6 @@
#include <linux/pci-acpi.h>
#include "pci.h"
-struct acpi_osc_data {
- acpi_handle handle;
- u32 support_set;
- u32 control_set;
- u32 control_query;
- int is_queried;
- struct list_head sibiling;
-};
-static LIST_HEAD(acpi_osc_data_list);
-
-struct acpi_osc_args {
- u32 capbuf[3];
-};
-
-static DEFINE_MUTEX(pci_acpi_lock);
-
-static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
-{
- struct acpi_osc_data *data;
-
- list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
- if (data->handle == handle)
- return data;
- }
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
- return NULL;
- INIT_LIST_HEAD(&data->sibiling);
- data->handle = handle;
- list_add_tail(&data->sibiling, &acpi_osc_data_list);
- return data;
-}
-
-static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
- 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
-
-static acpi_status acpi_run_osc(acpi_handle handle,
- struct acpi_osc_args *osc_args, u32 *retval)
-{
- acpi_status status;
- struct acpi_object_list input;
- union acpi_object in_params[4];
- struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *out_obj;
- u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE];
-
- /* Setting up input parameters */
- input.count = 4;
- input.pointer = in_params;
- in_params[0].type = ACPI_TYPE_BUFFER;
- in_params[0].buffer.length = 16;
- in_params[0].buffer.pointer = OSC_UUID;
- in_params[1].type = ACPI_TYPE_INTEGER;
- in_params[1].integer.value = 1;
- in_params[2].type = ACPI_TYPE_INTEGER;
- in_params[2].integer.value = 3;
- in_params[3].type = ACPI_TYPE_BUFFER;
- in_params[3].buffer.length = 12;
- in_params[3].buffer.pointer = (u8 *)osc_args->capbuf;
-
- status = acpi_evaluate_object(handle, "_OSC", &input, &output);
- if (ACPI_FAILURE(status))
- return status;
-
- if (!output.length)
- return AE_NULL_OBJECT;
-
- out_obj = output.pointer;
- if (out_obj->type != ACPI_TYPE_BUFFER) {
- printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n");
- status = AE_TYPE;
- goto out_kfree;
- }
- /* Need to ignore the bit0 in result code */
- errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
- if (errors) {
- if (errors & OSC_REQUEST_ERROR)
- printk(KERN_DEBUG "_OSC request fails\n");
- if (errors & OSC_INVALID_UUID_ERROR)
- printk(KERN_DEBUG "_OSC invalid UUID\n");
- if (errors & OSC_INVALID_REVISION_ERROR)
- printk(KERN_DEBUG "_OSC invalid revision\n");
- if (errors & OSC_CAPABILITIES_MASK_ERROR) {
- if (flags & OSC_QUERY_ENABLE)
- goto out_success;
- printk(KERN_DEBUG "_OSC FW not grant req. control\n");
- status = AE_SUPPORT;
- goto out_kfree;
- }
- status = AE_ERROR;
- goto out_kfree;
- }
-out_success:
- *retval = *((u32 *)(out_obj->buffer.pointer + 8));
- status = AE_OK;
-
-out_kfree:
- kfree(output.pointer);
- return status;
-}
-
-static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data)
-{
- acpi_status status;
- u32 support_set, result;
- struct acpi_osc_args osc_args;
-
- /* do _OSC query for all possible controls */
- support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS);
- osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
- osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set;
- osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
-
- status = acpi_run_osc(osc_data->handle, &osc_args, &result);
- if (ACPI_SUCCESS(status)) {
- osc_data->support_set = support_set;
- osc_data->control_query = result;
- osc_data->is_queried = 1;
- }
-
- return status;
-}
-
-/*
- * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature
- * @flags: Bitmask of flags to support
- *
- * See the ACPI spec for the definition of the flags
- */
-int pci_acpi_osc_support(acpi_handle handle, u32 flags)
-{
- acpi_status status;
- acpi_handle tmp;
- struct acpi_osc_data *osc_data;
- int rc = 0;
-
- status = acpi_get_handle(handle, "_OSC", &tmp);
- if (ACPI_FAILURE(status))
- return -ENOTTY;
-
- mutex_lock(&pci_acpi_lock);
- osc_data = acpi_get_osc_data(handle);
- if (!osc_data) {
- printk(KERN_ERR "acpi osc data array is full\n");
- rc = -ENOMEM;
- goto out;
- }
-
- __acpi_query_osc(flags, osc_data);
-out:
- mutex_unlock(&pci_acpi_lock);
- return rc;
-}
-
-/**
- * pci_osc_control_set - commit requested control to Firmware
- * @handle: acpi_handle for the target ACPI object
- * @flags: driver's requested control bits
- *
- * Attempt to take control from Firmware on requested control bits.
- **/
-acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
-{
- acpi_status status;
- u32 control_req, control_set, result;
- acpi_handle tmp;
- struct acpi_osc_data *osc_data;
- struct acpi_osc_args osc_args;
-
- status = acpi_get_handle(handle, "_OSC", &tmp);
- if (ACPI_FAILURE(status))
- return status;
-
- mutex_lock(&pci_acpi_lock);
- osc_data = acpi_get_osc_data(handle);
- if (!osc_data) {
- printk(KERN_ERR "acpi osc data array is full\n");
- status = AE_ERROR;
- goto out;
- }
-
- control_req = (flags & OSC_CONTROL_MASKS);
- if (!control_req) {
- status = AE_TYPE;
- goto out;
- }
-
- /* No need to evaluate _OSC if the control was already granted. */
- if ((osc_data->control_set & control_req) == control_req)
- goto out;
-
- if (!osc_data->is_queried) {
- status = __acpi_query_osc(osc_data->support_set, osc_data);
- if (ACPI_FAILURE(status))
- goto out;
- }
-
- if ((osc_data->control_query & control_req) != control_req) {
- status = AE_SUPPORT;
- goto out;
- }
-
- control_set = osc_data->control_set | control_req;
- osc_args.capbuf[OSC_QUERY_TYPE] = 0;
- osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set;
- osc_args.capbuf[OSC_CONTROL_TYPE] = control_set;
- status = acpi_run_osc(handle, &osc_args, &result);
- if (ACPI_SUCCESS(status))
- osc_data->control_set = result;
-out:
- mutex_unlock(&pci_acpi_lock);
- return status;
-}
-EXPORT_SYMBOL(pci_osc_control_set);
-
/*
* _SxD returns the D-state with the highest power
* (lowest D-state number) supported in the S-state "x".
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index c697f2680856..a5f11ad975b2 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -352,142 +352,98 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- int i = 0;
+ int error = 0;
if (drv && drv->suspend) {
- i = drv->suspend(pci_dev, state);
- suspend_report_result(drv->suspend, i);
- } else {
- pci_save_state(pci_dev);
- /*
- * This is for compatibility with existing code with legacy PM
- * support.
- */
- pci_pm_set_unknown_state(pci_dev);
+ pci_power_t prev = pci_dev->current_state;
+
+ pci_dev->state_saved = false;
+
+ error = drv->suspend(pci_dev, state);
+ suspend_report_result(drv->suspend, error);
+ if (error)
+ return error;
+
+ if (pci_dev->state_saved)
+ goto Fixup;
+
+ if (pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: Device state not saved by %pF\n",
+ drv->suspend);
+ goto Fixup;
+ }
}
+ pci_save_state(pci_dev);
+ /*
+ * This is for compatibility with existing code with legacy PM support.
+ */
+ pci_pm_set_unknown_state(pci_dev);
+
+ Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
- return i;
+ return error;
}
static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- int i = 0;
+ int error = 0;
if (drv && drv->suspend_late) {
- i = drv->suspend_late(pci_dev, state);
- suspend_report_result(drv->suspend_late, i);
+ error = drv->suspend_late(pci_dev, state);
+ suspend_report_result(drv->suspend_late, error);
}
- return i;
+ return error;
}
static int pci_legacy_resume_early(struct device *dev)
{
- int error = 0;
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
-
- if (drv && drv->resume_early)
- error = drv->resume_early(pci_dev);
- return error;
+ return drv && drv->resume_early ?
+ drv->resume_early(pci_dev) : 0;
}
static int pci_legacy_resume(struct device *dev)
{
- int error;
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
pci_fixup_device(pci_fixup_resume, pci_dev);
- if (drv && drv->resume) {
- error = drv->resume(pci_dev);
- } else {
- /* restore the PCI config space */
- pci_restore_state(pci_dev);
- error = pci_pm_reenable_device(pci_dev);
- }
- return error;
+ return drv && drv->resume ?
+ drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev);
}
/* Auxiliary functions used by the new power management framework */
-static int pci_restore_standard_config(struct pci_dev *pci_dev)
-{
- struct pci_dev *parent = pci_dev->bus->self;
- int error = 0;
-
- /* Check if the device's bus is operational */
- if (!parent || parent->current_state == PCI_D0) {
- pci_restore_state(pci_dev);
- pci_update_current_state(pci_dev, PCI_D0);
- } else {
- dev_warn(&pci_dev->dev, "unable to restore config, "
- "bridge %s in low power state D%d\n", pci_name(parent),
- parent->current_state);
- pci_dev->current_state = PCI_UNKNOWN;
- error = -EAGAIN;
- }
-
- return error;
-}
-
-static bool pci_is_bridge(struct pci_dev *pci_dev)
-{
- return !!(pci_dev->subordinate);
-}
-
static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
{
- if (pci_restore_standard_config(pci_dev))
- pci_fixup_device(pci_fixup_resume_early, pci_dev);
+ pci_restore_standard_config(pci_dev);
+ pci_dev->state_saved = false;
+ pci_fixup_device(pci_fixup_resume_early, pci_dev);
}
-static int pci_pm_default_resume(struct pci_dev *pci_dev)
+static void pci_pm_default_resume(struct pci_dev *pci_dev)
{
- /*
- * pci_restore_standard_config() should have been called once already,
- * but it would have failed if the device's parent bridge had not been
- * in power state D0 at that time. Check it and try again if necessary.
- */
- if (pci_dev->current_state == PCI_UNKNOWN) {
- int error = pci_restore_standard_config(pci_dev);
- if (error)
- return error;
- }
-
pci_fixup_device(pci_fixup_resume, pci_dev);
if (!pci_is_bridge(pci_dev))
pci_enable_wake(pci_dev, PCI_D0, false);
-
- return pci_pm_reenable_device(pci_dev);
-}
-
-static void pci_pm_default_suspend_generic(struct pci_dev *pci_dev)
-{
- /* If device is enabled at this point, disable it */
- pci_disable_enabled_device(pci_dev);
- /*
- * Save state with interrupts enabled, because in principle the bus the
- * device is on may be put into a low power state after this code runs.
- */
- pci_save_state(pci_dev);
}
static void pci_pm_default_suspend(struct pci_dev *pci_dev)
{
- pci_pm_default_suspend_generic(pci_dev);
-
+ /* Disable non-bridge devices without PM support */
if (!pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
-
- pci_fixup_device(pci_fixup_suspend, pci_dev);
+ pci_disable_enabled_device(pci_dev);
+ pci_save_state(pci_dev);
}
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -532,21 +488,49 @@ static void pci_pm_complete(struct device *dev)
static int pci_pm_suspend(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_SUSPEND);
- if (drv && drv->pm && drv->pm->suspend) {
- error = drv->pm->suspend(dev);
- suspend_report_result(drv->pm->suspend, error);
+ if (!pm) {
+ pci_pm_default_suspend(pci_dev);
+ goto Fixup;
}
- if (!error)
- pci_pm_default_suspend(pci_dev);
+ pci_dev->state_saved = false;
- return error;
+ if (pm->suspend) {
+ pci_power_t prev = pci_dev->current_state;
+ int error;
+
+ error = pm->suspend(dev);
+ suspend_report_result(pm->suspend, error);
+ if (error)
+ return error;
+
+ if (pci_dev->state_saved)
+ goto Fixup;
+
+ if (pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: State of device not saved by %pF\n",
+ pm->suspend);
+ goto Fixup;
+ }
+ }
+
+ if (!pci_dev->state_saved) {
+ pci_save_state(pci_dev);
+ if (!pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+ }
+
+ Fixup:
+ pci_fixup_device(pci_fixup_suspend, pci_dev);
+
+ return 0;
}
static int pci_pm_suspend_noirq(struct device *dev)
@@ -575,11 +559,11 @@ static int pci_pm_resume_noirq(struct device *dev)
struct device_driver *drv = dev->driver;
int error = 0;
+ pci_pm_default_resume_noirq(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev);
- pci_pm_default_resume_noirq(pci_dev);
-
if (drv && drv->pm && drv->pm->resume_noirq)
error = drv->pm->resume_noirq(dev);
@@ -589,18 +573,29 @@ static int pci_pm_resume_noirq(struct device *dev)
static int pci_pm_resume(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
+ /*
+ * This is necessary for the suspend error path in which resume is
+ * called without restoring the standard config registers of the device.
+ */
+ if (pci_dev->state_saved)
+ pci_restore_standard_config(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- error = pci_pm_default_resume(pci_dev);
+ pci_pm_default_resume(pci_dev);
- if (!error && drv && drv->pm && drv->pm->resume)
- error = drv->pm->resume(dev);
+ if (pm) {
+ if (pm->resume)
+ error = pm->resume(dev);
+ } else {
+ pci_pm_reenable_device(pci_dev);
+ }
- return error;
+ return 0;
}
#else /* !CONFIG_SUSPEND */
@@ -617,21 +612,31 @@ static int pci_pm_resume(struct device *dev)
static int pci_pm_freeze(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_FREEZE);
- if (drv && drv->pm && drv->pm->freeze) {
- error = drv->pm->freeze(dev);
- suspend_report_result(drv->pm->freeze, error);
+ if (!pm) {
+ pci_pm_default_suspend(pci_dev);
+ return 0;
}
- if (!error)
- pci_pm_default_suspend_generic(pci_dev);
+ pci_dev->state_saved = false;
- return error;
+ if (pm->freeze) {
+ int error;
+
+ error = pm->freeze(dev);
+ suspend_report_result(pm->freeze, error);
+ if (error)
+ return error;
+ }
+
+ if (!pci_dev->state_saved)
+ pci_save_state(pci_dev);
+
+ return 0;
}
static int pci_pm_freeze_noirq(struct device *dev)
@@ -674,16 +679,18 @@ static int pci_pm_thaw_noirq(struct device *dev)
static int pci_pm_thaw(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- pci_pm_reenable_device(pci_dev);
-
- if (drv && drv->pm && drv->pm->thaw)
- error = drv->pm->thaw(dev);
+ if (pm) {
+ if (pm->thaw)
+ error = pm->thaw(dev);
+ } else {
+ pci_pm_reenable_device(pci_dev);
+ }
return error;
}
@@ -691,19 +698,29 @@ static int pci_pm_thaw(struct device *dev)
static int pci_pm_poweroff(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_HIBERNATE);
- if (drv && drv->pm && drv->pm->poweroff) {
- error = drv->pm->poweroff(dev);
- suspend_report_result(drv->pm->poweroff, error);
+ if (!pm) {
+ pci_pm_default_suspend(pci_dev);
+ goto Fixup;
}
- if (!error)
- pci_pm_default_suspend(pci_dev);
+ pci_dev->state_saved = false;
+
+ if (pm->poweroff) {
+ error = pm->poweroff(dev);
+ suspend_report_result(pm->poweroff, error);
+ }
+
+ if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+
+ Fixup:
+ pci_fixup_device(pci_fixup_suspend, pci_dev);
return error;
}
@@ -730,11 +747,11 @@ static int pci_pm_restore_noirq(struct device *dev)
struct device_driver *drv = dev->driver;
int error = 0;
+ pci_pm_default_resume_noirq(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume_early(dev);
- pci_pm_default_resume_noirq(pci_dev);
-
if (drv && drv->pm && drv->pm->restore_noirq)
error = drv->pm->restore_noirq(dev);
@@ -744,16 +761,27 @@ static int pci_pm_restore_noirq(struct device *dev)
static int pci_pm_restore(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
int error = 0;
+ /*
+ * This is necessary for the hibernation error path in which restore is
+ * called without restoring the standard config registers of the device.
+ */
+ if (pci_dev->state_saved)
+ pci_restore_standard_config(pci_dev);
+
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_resume(dev);
- error = pci_pm_default_resume(pci_dev);
+ pci_pm_default_resume(pci_dev);
- if (!error && drv && drv->pm && drv->pm->restore)
- error = drv->pm->restore(dev);
+ if (pm) {
+ if (pm->restore)
+ error = pm->restore(dev);
+ } else {
+ pci_pm_reenable_device(pci_dev);
+ }
return error;
}
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index db7ec14fa719..1c8929801400 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -493,6 +493,19 @@ pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr,
}
/**
+ * pci_adjust_legacy_attr - adjustment of legacy file attributes
+ * @b: bus to create files under
+ * @mmap_type: I/O port or memory
+ *
+ * Stub implementation. Can be overridden by arch if necessary.
+ */
+void __weak
+pci_adjust_legacy_attr(struct pci_bus *b, enum pci_mmap_state mmap_type)
+{
+ return;
+}
+
+/**
* pci_create_legacy_files - create legacy I/O port and memory files
* @b: bus to create files under
*
@@ -518,6 +531,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_io->read = pci_read_legacy_io;
b->legacy_io->write = pci_write_legacy_io;
b->legacy_io->mmap = pci_mmap_legacy_io;
+ pci_adjust_legacy_attr(b, pci_mmap_io);
error = device_create_bin_file(&b->dev, b->legacy_io);
if (error)
goto legacy_io_err;
@@ -528,6 +542,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_mem->mmap = pci_mmap_legacy_mem;
+ pci_adjust_legacy_attr(b, pci_mmap_mem);
error = device_create_bin_file(&b->dev, b->legacy_mem);
if (error)
goto legacy_mem_err;
@@ -719,8 +734,8 @@ static int pci_create_resource_files(struct pci_dev *pdev)
return 0;
}
#else /* !HAVE_PCI_MMAP */
-static inline int pci_create_resource_files(struct pci_dev *dev) { return 0; }
-static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
+int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
+void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
#endif /* HAVE_PCI_MMAP */
/**
@@ -768,8 +783,8 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
return -EINVAL;
rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */
- if (!rom)
- return 0;
+ if (!rom || !size)
+ return -EIO;
if (off >= size)
count = 0;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e491fdedf705..0b3e20f1b6f7 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -22,7 +22,7 @@
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h"
-unsigned int pci_pm_d3_delay = 10;
+unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
#ifdef CONFIG_PCI_DOMAINS
int pci_domains_supported = 1;
@@ -426,6 +426,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* given PCI device
* @dev: PCI device to handle.
* @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
+ * @wait: If 'true', wait for the device to change its power state
*
* RETURN VALUE:
* -EINVAL if the requested state is invalid.
@@ -435,7 +436,7 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* 0 if device's power state has been successfully changed.
*/
static int
-pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
+pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
{
u16 pmcsr;
bool need_restore = false;
@@ -480,8 +481,10 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
break;
case PCI_UNKNOWN: /* Boot-up */
if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
- && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+ && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) {
need_restore = true;
+ wait = true;
+ }
/* Fall-through: force to D0 */
default:
pmcsr = 0;
@@ -491,12 +494,15 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
/* enter specified state */
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
+ if (!wait)
+ return 0;
+
/* Mandatory power management transition delays */
/* see PCI PM 1.1 5.6.1 table 18 */
if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
msleep(pci_pm_d3_delay);
else if (state == PCI_D2 || dev->current_state == PCI_D2)
- udelay(200);
+ udelay(PCI_PM_D2_DELAY);
dev->current_state = state;
@@ -515,7 +521,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
if (need_restore)
pci_restore_bars(dev);
- if (dev->bus->self)
+ if (wait && dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self);
return 0;
@@ -585,7 +591,7 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
return 0;
- error = pci_raw_set_power_state(dev, state);
+ error = pci_raw_set_power_state(dev, state, true);
if (state > PCI_D0 && platform_pci_power_manageable(dev)) {
/* Allow the platform to finalize the transition */
@@ -651,7 +657,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+ dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
cap = (u16 *)&save_state->data[0];
@@ -694,7 +700,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+ dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
@@ -730,6 +736,7 @@ pci_save_state(struct pci_dev *dev)
/* XXX: 100% dword access ok here? */
for (i = 0; i < 16; i++)
pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
+ dev->state_saved = true;
if ((i = pci_save_pcie_state(dev)) != 0)
return i;
if ((i = pci_save_pcix_state(dev)) != 0)
@@ -1374,6 +1381,50 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
}
/**
+ * pci_restore_standard_config - restore standard config registers of PCI device
+ * @dev: PCI device to handle
+ *
+ * This function assumes that the device's configuration space is accessible.
+ * If the device needs to be powered up, the function will wait for it to
+ * change the state.
+ */
+int pci_restore_standard_config(struct pci_dev *dev)
+{
+ pci_power_t prev_state;
+ int error;
+
+ pci_update_current_state(dev, PCI_D0);
+
+ prev_state = dev->current_state;
+ if (prev_state == PCI_D0)
+ goto Restore;
+
+ error = pci_raw_set_power_state(dev, PCI_D0, false);
+ if (error)
+ return error;
+
+ /*
+ * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
+ * we've made this assumption forever and it appears to be universally
+ * satisfied.
+ */
+ switch(prev_state) {
+ case PCI_D3cold:
+ case PCI_D3hot:
+ mdelay(pci_pm_d3_delay);
+ break;
+ case PCI_D2:
+ udelay(PCI_PM_D2_DELAY);
+ break;
+ }
+
+ pci_update_current_state(dev, PCI_D0);
+
+ Restore:
+ return dev->state_saved ? pci_restore_state(dev) : 0;
+}
+
+/**
* pci_enable_ari - enable ARI forwarding if hardware support it
* @dev: the PCI device
*/
@@ -1489,16 +1540,21 @@ void pci_release_region(struct pci_dev *pdev, int bar)
}
/**
- * pci_request_region - Reserved PCI I/O and memory resource
+ * __pci_request_region - Reserved PCI I/O and memory resource
* @pdev: PCI device whose resources are to be reserved
* @bar: BAR to be reserved
* @res_name: Name to be associated with resource.
+ * @exclusive: whether the region access is exclusive or not
*
* Mark the PCI region associated with PCI device @pdev BR @bar as
* being reserved by owner @res_name. Do not access any
* address inside the PCI regions unless this call returns
* successfully.
*
+ * If @exclusive is set, then the region is marked so that userspace
+ * is explicitly not allowed to map the resource via /dev/mem or
+ * sysfs MMIO access.
+ *
* Returns 0 on success, or %EBUSY on error. A warning
* message is also printed on failure.
*/
@@ -1537,12 +1593,12 @@ err_out:
}
/**
- * pci_request_region - Reserved PCI I/O and memory resource
+ * pci_request_region - Reserve PCI I/O and memory resource
* @pdev: PCI device whose resources are to be reserved
* @bar: BAR to be reserved
- * @res_name: Name to be associated with resource.
+ * @res_name: Name to be associated with resource
*
- * Mark the PCI region associated with PCI device @pdev BR @bar as
+ * Mark the PCI region associated with PCI device @pdev BAR @bar as
* being reserved by owner @res_name. Do not access any
* address inside the PCI regions unless this call returns
* successfully.
@@ -1972,18 +2028,24 @@ static int __pcie_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */
+ pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto transaction_done;
+
msleep(100);
pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND) {
- dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto transaction_done;
+
+ dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
"sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND)
- dev_info(&dev->dev, "Still busy after 1s; "
+ ssleep(1);
+ pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+ if (status & PCI_EXP_DEVSTA_TRPND)
+ dev_info(&dev->dev, "Still busy after 1s; "
"proceeding with reset anyway\n");
- }
+transaction_done:
pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_BCR_FLR);
mdelay(100);
@@ -2010,18 +2072,24 @@ static int __pci_af_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */
+ pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+ if (!(status & PCI_AF_STATUS_TP))
+ goto transaction_done;
+
msleep(100);
pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP) {
- dev_info(&dev->dev, "Busy after 100ms while trying to"
- " reset; sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_byte(dev,
- cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP)
- dev_info(&dev->dev, "Still busy after 1s; "
- "proceeding with reset anyway\n");
- }
+ if (!(status & PCI_AF_STATUS_TP))
+ goto transaction_done;
+
+ dev_info(&dev->dev, "Busy after 100ms while trying to"
+ " reset; sleeping for 1 second\n");
+ ssleep(1);
+ pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+ if (status & PCI_AF_STATUS_TP)
+ dev_info(&dev->dev, "Still busy after 1s; "
+ "proceeding with reset anyway\n");
+
+transaction_done:
pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
mdelay(100);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1351bb4addde..07c0aa5275e6 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -16,21 +16,21 @@ extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
#endif
/**
- * Firmware PM callbacks
+ * struct pci_platform_pm_ops - Firmware PM callbacks
*
- * @is_manageable - returns 'true' if given device is power manageable by the
- * platform firmware
+ * @is_manageable: returns 'true' if given device is power manageable by the
+ * platform firmware
*
- * @set_state - invokes the platform firmware to set the device's power state
+ * @set_state: invokes the platform firmware to set the device's power state
*
- * @choose_state - returns PCI power state of given device preferred by the
- * platform; to be used during system-wide transitions from a
- * sleeping state to the working state and vice versa
+ * @choose_state: returns PCI power state of given device preferred by the
+ * platform; to be used during system-wide transitions from a
+ * sleeping state to the working state and vice versa
*
- * @can_wakeup - returns 'true' if given device is capable of waking up the
- * system from a sleeping state
+ * @can_wakeup: returns 'true' if given device is capable of waking up the
+ * system from a sleeping state
*
- * @sleep_wake - enables/disables the system wake up capability of given device
+ * @sleep_wake: enables/disables the system wake up capability of given device
*
* If given platform is generally capable of power managing PCI devices, all of
* these callbacks are mandatory.
@@ -49,6 +49,12 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
extern void pci_pm_init(struct pci_dev *dev);
extern void platform_pci_wakeup_init(struct pci_dev *dev);
extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
+extern int pci_restore_standard_config(struct pci_dev *dev);
+
+static inline bool pci_is_bridge(struct pci_dev *pci_dev)
+{
+ return !!(pci_dev->subordinate);
+}
extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index e390707661dd..32ade5af927e 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -38,30 +38,13 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-static int __devinit aer_probe (struct pcie_device *dev,
- const struct pcie_port_service_id *id );
+static int __devinit aer_probe (struct pcie_device *dev);
static void aer_remove(struct pcie_device *dev);
-static int aer_suspend(struct pcie_device *dev, pm_message_t state)
-{return 0;}
-static int aer_resume(struct pcie_device *dev) {return 0;}
static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
enum pci_channel_state error);
static void aer_error_resume(struct pci_dev *dev);
static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
-/*
- * PCI Express bus's AER Root service driver data structure
- */
-static struct pcie_port_service_id aer_id[] = {
- {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_RC_PORT,
- .service_type = PCIE_PORT_SERVICE_AER,
- },
- { /* end: all zeroes */ }
-};
-
static struct pci_error_handlers aer_error_handlers = {
.error_detected = aer_error_detected,
.resume = aer_error_resume,
@@ -69,14 +52,12 @@ static struct pci_error_handlers aer_error_handlers = {
static struct pcie_port_service_driver aerdriver = {
.name = "aer",
- .id_table = &aer_id[0],
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_AER,
.probe = aer_probe,
.remove = aer_remove,
- .suspend = aer_suspend,
- .resume = aer_resume,
-
.err_handler = &aer_error_handlers,
.reset_link = aer_root_reset,
@@ -207,8 +188,7 @@ static void aer_remove(struct pcie_device *dev)
*
* Invoked when PCI Express bus loads AER service driver.
**/
-static int __devinit aer_probe (struct pcie_device *dev,
- const struct pcie_port_service_id *id )
+static int __devinit aer_probe (struct pcie_device *dev)
{
int status;
struct aer_rpc *rpc;
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index ebce26c37049..8edb2f300e8f 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -38,7 +38,7 @@ int aer_osc_setup(struct pcie_device *pciedev)
handle = acpi_find_root_bridge_handle(pdev);
if (handle) {
- status = pci_osc_control_set(handle,
+ status = acpi_pci_osc_control_set(handle,
OSC_PCI_EXPRESS_AER_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
}
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index aac7006949f1..aebb5f666ddf 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -108,6 +108,34 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
}
#endif /* 0 */
+
+static void set_device_error_reporting(struct pci_dev *dev, void *data)
+{
+ bool enable = *((bool *)data);
+
+ if (dev->pcie_type != PCIE_RC_PORT &&
+ dev->pcie_type != PCIE_SW_UPSTREAM_PORT &&
+ dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT)
+ return;
+
+ if (enable)
+ pci_enable_pcie_error_reporting(dev);
+ else
+ pci_disable_pcie_error_reporting(dev);
+}
+
+/**
+ * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports.
+ * @dev: pointer to root port's pci_dev data structure
+ * @enable: true = enable error reporting, false = disable error reporting.
+ */
+static void set_downstream_devices_error_reporting(struct pci_dev *dev,
+ bool enable)
+{
+ set_device_error_reporting(dev, &enable);
+ pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable);
+}
+
static int find_device_iter(struct device *device, void *data)
{
struct pci_dev *dev;
@@ -320,21 +348,21 @@ static int find_aer_service_iter(struct device *device, void *data)
{
struct device_driver *driver;
struct pcie_port_service_driver *service_driver;
- struct pcie_device *pcie_dev;
struct find_aer_service_data *result;
result = (struct find_aer_service_data *) data;
if (device->bus == &pcie_port_bus_type) {
- pcie_dev = to_pcie_device(device);
- if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT)
+ struct pcie_port_data *port_data;
+
+ port_data = pci_get_drvdata(to_pcie_device(device)->port);
+ if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT)
result->is_downstream = 1;
driver = device->driver;
if (driver) {
service_driver = to_service_driver(driver);
- if (service_driver->id_table->service_type ==
- PCIE_PORT_SERVICE_AER) {
+ if (service_driver->service == PCIE_PORT_SERVICE_AER) {
result->aer_driver = service_driver;
return 1;
}
@@ -525,15 +553,11 @@ void aer_enable_rootport(struct aer_rpc *rpc)
pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);
- /* Enable Root Port device reporting error itself */
- pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, &reg16);
- reg16 = reg16 |
- PCI_EXP_DEVCTL_CERE |
- PCI_EXP_DEVCTL_NFERE |
- PCI_EXP_DEVCTL_FERE |
- PCI_EXP_DEVCTL_URRE;
- pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL,
- reg16);
+ /*
+ * Enable error reporting for the root port device and downstream port
+ * devices.
+ */
+ set_downstream_devices_error_reporting(pdev, true);
/* Enable Root Port's interrupt in response to error messages */
pci_write_config_dword(pdev,
@@ -553,6 +577,12 @@ static void disable_root_aer(struct aer_rpc *rpc)
u32 reg32;
int pos;
+ /*
+ * Disable error reporting for the root port device and downstream port
+ * devices.
+ */
+ set_downstream_devices_error_reporting(pdev, false);
+
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Disable Root's interrupt in response to error messages */
pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 586b6f75910d..b0367f168af4 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -718,9 +718,9 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
/*
* All PCIe functions are in one slot, remove one function will remove
- * the the whole slot, so just wait
+ * the whole slot, so just wait until we are the last function left.
*/
- if (!list_empty(&parent->subordinate->devices))
+ if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices))
goto out;
/* All functions are removed, so just disable ASPM for the link */
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 2529f3f2ea5a..17ad53868f9f 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -25,19 +25,21 @@
#define PCIE_CAPABILITIES_REG 0x2
#define PCIE_SLOT_CAPABILITIES_REG 0x14
#define PCIE_PORT_DEVICE_MAXSERVICES 4
+#define PCIE_PORT_MSI_VECTOR_MASK 0x1f
+/*
+ * According to the PCI Express Base Specification 2.0, the indices of the MSI-X
+ * table entires used by port services must not exceed 31
+ */
+#define PCIE_PORT_MAX_MSIX_ENTRIES 32
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
-struct pcie_port_device_ext {
- int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */
-};
-
extern struct bus_type pcie_port_bus_type;
extern int pcie_port_device_probe(struct pci_dev *dev);
extern int pcie_port_device_register(struct pci_dev *dev);
#ifdef CONFIG_PM
-extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state);
-extern int pcie_port_device_resume(struct pci_dev *dev);
+extern int pcie_port_device_suspend(struct device *dev);
+extern int pcie_port_device_resume(struct device *dev);
#endif
extern void pcie_port_device_remove(struct pci_dev *dev);
extern int __must_check pcie_port_bus_register(void);
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index eec89b767f9f..ef3a4eeaebb4 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -26,20 +26,22 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type);
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
{
struct pcie_device *pciedev;
+ struct pcie_port_data *port_data;
struct pcie_port_service_driver *driver;
if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
return 0;
-
+
pciedev = to_pcie_device(dev);
driver = to_service_driver(drv);
- if ( (driver->id_table->vendor != PCI_ANY_ID &&
- driver->id_table->vendor != pciedev->id.vendor) ||
- (driver->id_table->device != PCI_ANY_ID &&
- driver->id_table->device != pciedev->id.device) ||
- (driver->id_table->port_type != PCIE_ANY_PORT &&
- driver->id_table->port_type != pciedev->id.port_type) ||
- driver->id_table->service_type != pciedev->id.service_type )
+
+ if (driver->service != pciedev->service)
+ return 0;
+
+ port_data = pci_get_drvdata(pciedev->port);
+
+ if (driver->port_type != PCIE_ANY_PORT
+ && driver->port_type != port_data->port_type)
return 0;
return 1;
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 8b3f8c18032f..5a5bfe7cdf5f 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -15,10 +15,9 @@
#include <linux/slab.h>
#include <linux/pcieport_if.h>
+#include "../pci.h"
#include "portdrv.h"
-extern int pcie_mch_quirk; /* MSI-quirk Indicator */
-
/**
* release_pcie_device - free PCI Express port service device structure
* @dev: Port service device to release
@@ -31,26 +30,150 @@ static void release_pcie_device(struct device *dev)
kfree(to_pcie_device(dev));
}
-static int is_msi_quirked(struct pci_dev *dev)
+/**
+ * pcie_port_msix_add_entry - add entry to given array of MSI-X entries
+ * @entries: Array of MSI-X entries
+ * @new_entry: Index of the entry to add to the array
+ * @nr_entries: Number of entries aleady in the array
+ *
+ * Return value: Position of the added entry in the array
+ */
+static int pcie_port_msix_add_entry(
+ struct msix_entry *entries, int new_entry, int nr_entries)
{
- int port_type, quirk = 0;
+ int j;
+
+ for (j = 0; j < nr_entries; j++)
+ if (entries[j].entry == new_entry)
+ return j;
+
+ entries[j].entry = new_entry;
+ return j;
+}
+
+/**
+ * pcie_port_enable_msix - try to set up MSI-X as interrupt mode for given port
+ * @dev: PCI Express port to handle
+ * @vectors: Array of interrupt vectors to populate
+ * @mask: Bitmask of port capabilities returned by get_port_device_capability()
+ *
+ * Return value: 0 on success, error code on failure
+ */
+static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
+{
+ struct msix_entry *msix_entries;
+ int idx[PCIE_PORT_DEVICE_MAXSERVICES];
+ int nr_entries, status, pos, i, nvec;
u16 reg16;
+ u32 reg32;
- pci_read_config_word(dev,
- pci_find_capability(dev, PCI_CAP_ID_EXP) +
- PCIE_CAPABILITIES_REG, &reg16);
- port_type = (reg16 >> 4) & PORT_TYPE_MASK;
- switch(port_type) {
- case PCIE_RC_PORT:
- if (pcie_mch_quirk == 1)
- quirk = 1;
- break;
- case PCIE_SW_UPSTREAM_PORT:
- case PCIE_SW_DOWNSTREAM_PORT:
- default:
- break;
+ nr_entries = pci_msix_table_size(dev);
+ if (!nr_entries)
+ return -EINVAL;
+ if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
+ nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES;
+
+ msix_entries = kzalloc(sizeof(*msix_entries) * nr_entries, GFP_KERNEL);
+ if (!msix_entries)
+ return -ENOMEM;
+
+ /*
+ * Allocate as many entries as the port wants, so that we can check
+ * which of them will be useful. Moreover, if nr_entries is correctly
+ * equal to the number of entries this port actually uses, we'll happily
+ * go through without any tricks.
+ */
+ for (i = 0; i < nr_entries; i++)
+ msix_entries[i].entry = i;
+
+ status = pci_enable_msix(dev, msix_entries, nr_entries);
+ if (status)
+ goto Exit;
+
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ idx[i] = -1;
+ status = -EIO;
+ nvec = 0;
+
+ if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP)) {
+ int entry;
+
+ /*
+ * The code below follows the PCI Express Base Specification 2.0
+ * stating in Section 6.1.6 that "PME and Hot-Plug Event
+ * interrupts (when both are implemented) always share the same
+ * MSI or MSI-X vector, as indicated by the Interrupt Message
+ * Number field in the PCI Express Capabilities register", where
+ * according to Section 7.8.2 of the specification "For MSI-X,
+ * the value in this field indicates which MSI-X Table entry is
+ * used to generate the interrupt message."
+ */
+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
+ entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK;
+ if (entry >= nr_entries)
+ goto Error;
+
+ i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+ if (i == nvec)
+ nvec++;
+
+ idx[PCIE_PORT_SERVICE_PME_SHIFT] = i;
+ idx[PCIE_PORT_SERVICE_HP_SHIFT] = i;
+ }
+
+ if (mask & PCIE_PORT_SERVICE_AER) {
+ int entry;
+
+ /*
+ * The code below follows Section 7.10.10 of the PCI Express
+ * Base Specification 2.0 stating that bits 31-27 of the Root
+ * Error Status Register contain a value indicating which of the
+ * MSI/MSI-X vectors assigned to the port is going to be used
+ * for AER, where "For MSI-X, the value in this register
+ * indicates which MSI-X Table entry is used to generate the
+ * interrupt message."
+ */
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
+ entry = reg32 >> 27;
+ if (entry >= nr_entries)
+ goto Error;
+
+ i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+ if (i == nvec)
+ nvec++;
+
+ idx[PCIE_PORT_SERVICE_AER_SHIFT] = i;
}
- return quirk;
+
+ /*
+ * If nvec is equal to the allocated number of entries, we can just use
+ * what we have. Otherwise, the port has some extra entries not for the
+ * services we know and we need to work around that.
+ */
+ if (nvec == nr_entries) {
+ status = 0;
+ } else {
+ /* Drop the temporary MSI-X setup */
+ pci_disable_msix(dev);
+
+ /* Now allocate the MSI-X vectors for real */
+ status = pci_enable_msix(dev, msix_entries, nvec);
+ if (status)
+ goto Exit;
+ }
+
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ vectors[i] = idx[i] >= 0 ? msix_entries[idx[i]].vector : -1;
+
+ Exit:
+ kfree(msix_entries);
+ return status;
+
+ Error:
+ pci_disable_msix(dev);
+ goto Exit;
}
/**
@@ -64,47 +187,32 @@ static int is_msi_quirked(struct pci_dev *dev)
*/
static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
{
- int i, pos, nvec, status = -EINVAL;
- int interrupt_mode = PCIE_PORT_INTx_MODE;
+ struct pcie_port_data *port_data = pci_get_drvdata(dev);
+ int irq, interrupt_mode = PCIE_PORT_NO_IRQ;
+ int i;
- /* Set INTx as default */
- for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
- if (mask & (1 << i))
- nvec++;
- vectors[i] = dev->irq;
- }
-
/* Check MSI quirk */
- if (is_msi_quirked(dev))
- return interrupt_mode;
-
- /* Select MSI-X over MSI if supported */
- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
- if (pos) {
- struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] =
- {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
- status = pci_enable_msix(dev, msix_entries, nvec);
- if (!status) {
- int j = 0;
-
- interrupt_mode = PCIE_PORT_MSIX_MODE;
- for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
- if (mask & (1 << i))
- vectors[i] = msix_entries[j++].vector;
- }
- }
- }
- if (status) {
- pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
- if (pos) {
- status = pci_enable_msi(dev);
- if (!status) {
- interrupt_mode = PCIE_PORT_MSI_MODE;
- for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
- vectors[i] = dev->irq;
- }
- }
- }
+ if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk)
+ goto Fallback;
+
+ /* Try to use MSI-X if supported */
+ if (!pcie_port_enable_msix(dev, vectors, mask))
+ return PCIE_PORT_MSIX_MODE;
+
+ /* We're not going to use MSI-X, so try MSI and fall back to INTx */
+ if (!pci_enable_msi(dev))
+ interrupt_mode = PCIE_PORT_MSI_MODE;
+
+ Fallback:
+ if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin)
+ interrupt_mode = PCIE_PORT_INTx_MODE;
+
+ irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1;
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ vectors[i] = irq;
+
+ vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
+
return interrupt_mode;
}
@@ -132,13 +240,11 @@ static int get_port_device_capability(struct pci_dev *dev)
pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
if (reg32 & SLOT_HP_CAPABLE_MASK)
services |= PCIE_PORT_SERVICE_HP;
- }
- /* PME Capable - root port capability */
- if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
- services |= PCIE_PORT_SERVICE_PME;
-
+ }
+ /* AER capable */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
services |= PCIE_PORT_SERVICE_AER;
+ /* VC support */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
services |= PCIE_PORT_SERVICE_VC;
@@ -152,20 +258,17 @@ static int get_port_device_capability(struct pci_dev *dev)
* @port_type: Type of the port
* @service_type: Type of service to associate with the service device
* @irq: Interrupt vector to associate with the service device
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
*/
static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
- int port_type, int service_type, int irq, int irq_mode)
+ int service_type, int irq)
{
+ struct pcie_port_data *port_data = pci_get_drvdata(parent);
struct device *device;
+ int port_type = port_data->port_type;
dev->port = parent;
- dev->interrupt_mode = irq_mode;
dev->irq = irq;
- dev->id.vendor = parent->vendor;
- dev->id.device = parent->device;
- dev->id.port_type = port_type;
- dev->id.service_type = (1 << service_type);
+ dev->service = service_type;
/* Initialize generic device interface */
device = &dev->device;
@@ -185,10 +288,9 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
* @port_type: Type of the port
* @service_type: Type of service to associate with the service device
* @irq: Interrupt vector to associate with the service device
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
*/
static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
- int port_type, int service_type, int irq, int irq_mode)
+ int service_type, int irq)
{
struct pcie_device *device;
@@ -196,7 +298,7 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
if (!device)
return NULL;
- pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
+ pcie_device_init(parent, device, service_type, irq);
return device;
}
@@ -230,63 +332,90 @@ int pcie_port_device_probe(struct pci_dev *dev)
*/
int pcie_port_device_register(struct pci_dev *dev)
{
- struct pcie_port_device_ext *p_ext;
- int status, type, capabilities, irq_mode, i;
+ struct pcie_port_data *port_data;
+ int status, capabilities, irq_mode, i, nr_serv;
int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
u16 reg16;
- /* Allocate port device extension */
- if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
+ port_data = kzalloc(sizeof(*port_data), GFP_KERNEL);
+ if (!port_data)
return -ENOMEM;
-
- pci_set_drvdata(dev, p_ext);
+ pci_set_drvdata(dev, port_data);
/* Get port type */
pci_read_config_word(dev,
pci_find_capability(dev, PCI_CAP_ID_EXP) +
PCIE_CAPABILITIES_REG, &reg16);
- type = (reg16 >> 4) & PORT_TYPE_MASK;
+ port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK;
- /* Now get port services */
capabilities = get_port_device_capability(dev);
+ /* Root ports are capable of generating PME too */
+ if (port_data->port_type == PCIE_RC_PORT)
+ capabilities |= PCIE_PORT_SERVICE_PME;
+
irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
- p_ext->interrupt_mode = irq_mode;
+ if (irq_mode == PCIE_PORT_NO_IRQ) {
+ /*
+ * Don't use service devices that require interrupts if there is
+ * no way to generate them.
+ */
+ if (!(capabilities & PCIE_PORT_SERVICE_VC)) {
+ status = -ENODEV;
+ goto Error;
+ }
+ capabilities = PCIE_PORT_SERVICE_VC;
+ }
+ port_data->port_irq_mode = irq_mode;
+
+ status = pci_enable_device(dev);
+ if (status)
+ goto Error;
+ pci_set_master(dev);
/* Allocate child services if any */
- for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+ for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
struct pcie_device *child;
+ int service = 1 << i;
+
+ if (!(capabilities & service))
+ continue;
- if (capabilities & (1 << i)) {
- child = alloc_pcie_device(
- dev, /* parent */
- type, /* port type */
- i, /* service type */
- vectors[i], /* irq */
- irq_mode /* interrupt mode */);
- if (child) {
- status = device_register(&child->device);
- if (status) {
- kfree(child);
- continue;
- }
- get_device(&child->device);
- }
+ child = alloc_pcie_device(dev, service, vectors[i]);
+ if (!child)
+ continue;
+
+ status = device_register(&child->device);
+ if (status) {
+ kfree(child);
+ continue;
}
+
+ get_device(&child->device);
+ nr_serv++;
+ }
+ if (!nr_serv) {
+ pci_disable_device(dev);
+ status = -ENODEV;
+ goto Error;
}
+
return 0;
+
+ Error:
+ kfree(port_data);
+ return status;
}
#ifdef CONFIG_PM
static int suspend_iter(struct device *dev, void *data)
{
struct pcie_port_service_driver *service_driver;
- pm_message_t state = * (pm_message_t *) data;
if ((dev->bus == &pcie_port_bus_type) &&
(dev->driver)) {
service_driver = to_service_driver(dev->driver);
if (service_driver->suspend)
- service_driver->suspend(to_pcie_device(dev), state);
+ service_driver->suspend(to_pcie_device(dev));
}
return 0;
}
@@ -294,11 +423,10 @@ static int suspend_iter(struct device *dev, void *data)
/**
* pcie_port_device_suspend - suspend port services associated with a PCIe port
* @dev: PCI Express port to handle
- * @state: Representation of system power management transition in progress
*/
-int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
+int pcie_port_device_suspend(struct device *dev)
{
- return device_for_each_child(&dev->dev, &state, suspend_iter);
+ return device_for_each_child(dev, NULL, suspend_iter);
}
static int resume_iter(struct device *dev, void *data)
@@ -318,24 +446,17 @@ static int resume_iter(struct device *dev, void *data)
* pcie_port_device_suspend - resume port services associated with a PCIe port
* @dev: PCI Express port to handle
*/
-int pcie_port_device_resume(struct pci_dev *dev)
+int pcie_port_device_resume(struct device *dev)
{
- return device_for_each_child(&dev->dev, NULL, resume_iter);
+ return device_for_each_child(dev, NULL, resume_iter);
}
-#endif
+#endif /* PM */
static int remove_iter(struct device *dev, void *data)
{
- struct pcie_port_service_driver *service_driver;
-
if (dev->bus == &pcie_port_bus_type) {
- if (dev->driver) {
- service_driver = to_service_driver(dev->driver);
- if (service_driver->remove)
- service_driver->remove(to_pcie_device(dev));
- }
- *(unsigned long*)data = (unsigned long)dev;
- return 1;
+ put_device(dev);
+ device_unregister(dev);
}
return 0;
}
@@ -349,25 +470,20 @@ static int remove_iter(struct device *dev, void *data)
*/
void pcie_port_device_remove(struct pci_dev *dev)
{
- struct device *device;
- unsigned long device_addr;
- int interrupt_mode = PCIE_PORT_INTx_MODE;
- int status;
+ struct pcie_port_data *port_data = pci_get_drvdata(dev);
- do {
- status = device_for_each_child(&dev->dev, &device_addr, remove_iter);
- if (status) {
- device = (struct device*)device_addr;
- interrupt_mode = (to_pcie_device(device))->interrupt_mode;
- put_device(device);
- device_unregister(device);
- }
- } while (status);
- /* Switch to INTx by default if MSI enabled */
- if (interrupt_mode == PCIE_PORT_MSIX_MODE)
+ device_for_each_child(&dev->dev, NULL, remove_iter);
+
+ switch (port_data->port_irq_mode) {
+ case PCIE_PORT_MSIX_MODE:
pci_disable_msix(dev);
- else if (interrupt_mode == PCIE_PORT_MSI_MODE)
+ break;
+ case PCIE_PORT_MSI_MODE:
pci_disable_msi(dev);
+ break;
+ }
+
+ kfree(port_data);
}
/**
@@ -392,7 +508,7 @@ static int pcie_port_probe_service(struct device *dev)
return -ENODEV;
pciedev = to_pcie_device(dev);
- status = driver->probe(pciedev, driver->id_table);
+ status = driver->probe(pciedev);
if (!status) {
dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n",
driver->name);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 99a914a027f8..a6fee6c52c77 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -32,11 +32,6 @@ MODULE_LICENSE("GPL");
/* global data */
static const char device_name[] = "pcieport-driver";
-static int pcie_portdrv_save_config(struct pci_dev *dev)
-{
- return pci_save_state(dev);
-}
-
static int pcie_portdrv_restore_config(struct pci_dev *dev)
{
int retval;
@@ -49,33 +44,21 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
}
#ifdef CONFIG_PM
-static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
-{
- return pcie_port_device_suspend(dev, state);
-
-}
+static struct dev_pm_ops pcie_portdrv_pm_ops = {
+ .suspend = pcie_port_device_suspend,
+ .resume = pcie_port_device_resume,
+ .freeze = pcie_port_device_suspend,
+ .thaw = pcie_port_device_resume,
+ .poweroff = pcie_port_device_suspend,
+ .restore = pcie_port_device_resume,
+};
-static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state)
-{
- return pci_save_state(dev);
-}
+#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)
-static int pcie_portdrv_resume_early(struct pci_dev *dev)
-{
- return pci_restore_state(dev);
-}
+#else /* !PM */
-static int pcie_portdrv_resume(struct pci_dev *dev)
-{
- pcie_portdrv_restore_config(dev);
- return pcie_port_device_resume(dev);
-}
-#else
-#define pcie_portdrv_suspend NULL
-#define pcie_portdrv_suspend_late NULL
-#define pcie_portdrv_resume_early NULL
-#define pcie_portdrv_resume NULL
-#endif
+#define PCIE_PORTDRV_PM_OPS NULL
+#endif /* !PM */
/*
* pcie_portdrv_probe - Probe PCI-Express port devices
@@ -94,22 +77,15 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
if (status)
return status;
- if (pci_enable_device(dev) < 0)
- return -ENODEV;
-
- pci_set_master(dev);
if (!dev->irq && dev->pin) {
dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
"check vendor BIOS\n", dev->vendor, dev->device);
}
- if (pcie_port_device_register(dev)) {
- pci_disable_device(dev);
- return -ENOMEM;
- }
-
- pcie_portdrv_save_config(dev);
+ status = pcie_port_device_register(dev);
+ if (status)
+ return status;
- pci_enable_pcie_error_reporting(dev);
+ pci_save_state(dev);
return 0;
}
@@ -291,12 +267,9 @@ static struct pci_driver pcie_portdriver = {
.probe = pcie_portdrv_probe,
.remove = pcie_portdrv_remove,
- .suspend = pcie_portdrv_suspend,
- .suspend_late = pcie_portdrv_suspend_late,
- .resume_early = pcie_portdrv_resume_early,
- .resume = pcie_portdrv_resume,
-
.err_handler = &pcie_portdrv_err_handler,
+
+ .driver.pm = PCIE_PORTDRV_PM_OPS,
};
static int __init pcie_portdrv_init(void)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index baad093aafe3..5e40e44c9980 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1660,9 +1660,13 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
* of parallel ports and <S> is the number of serial ports.
*/
switch (dev->device) {
+ case PCI_DEVICE_ID_NETMOS_9835:
+ /* Well, this rule doesn't hold for the following 9835 device */
+ if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+ dev->subsystem_device == 0x0299)
+ return;
case PCI_DEVICE_ID_NETMOS_9735:
case PCI_DEVICE_ID_NETMOS_9745:
- case PCI_DEVICE_ID_NETMOS_9835:
case PCI_DEVICE_ID_NETMOS_9845:
case PCI_DEVICE_ID_NETMOS_9855:
if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL &&
@@ -1981,7 +1985,6 @@ static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE,
quirk_msi_ht_cap);
-
/* The nVidia CK804 chipset may have 2 HT MSI mappings.
* MSI are supported if the MSI capability set in any of these mappings.
*/
@@ -2032,6 +2035,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
ht_enable_msi_mapping);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE,
+ ht_enable_msi_mapping);
+
/* The P5N32-SLI Premium motherboard from Asus has a problem with msi
* for the MCP55 NIC. It is not yet determined whether the msi problem
* also affects other devices. As for now, turn off msi for this device.
@@ -2048,10 +2054,100 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NVENET_15,
nvenet_msi_disable);
-static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
{
struct pci_dev *host_bridge;
+ int pos;
+ int i, dev_no;
+ int found = 0;
+
+ dev_no = dev->devfn >> 3;
+ for (i = dev_no; i >= 0; i--) {
+ host_bridge = pci_get_slot(dev->bus, PCI_DEVFN(i, 0));
+ if (!host_bridge)
+ continue;
+
+ pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
+ if (pos != 0) {
+ found = 1;
+ break;
+ }
+ pci_dev_put(host_bridge);
+ }
+
+ if (!found)
+ return;
+
+ /* root did that ! */
+ if (msi_ht_cap_enabled(host_bridge))
+ goto out;
+
+ ht_enable_msi_mapping(dev);
+
+out:
+ pci_dev_put(host_bridge);
+}
+
+static void __devinit ht_disable_msi_mapping(struct pci_dev *dev)
+{
+ int pos, ttl = 48;
+
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+ while (pos && ttl--) {
+ u8 flags;
+
+ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+ &flags) == 0) {
+ dev_info(&dev->dev, "Enabling HT MSI Mapping\n");
+
+ pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
+ flags & ~HT_MSI_FLAGS_ENABLE);
+ }
+ pos = pci_find_next_ht_capability(dev, pos,
+ HT_CAPTYPE_MSI_MAPPING);
+ }
+}
+
+static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
+{
int pos, ttl = 48;
+ int found = 0;
+
+ /* check if there is HT MSI cap or enabled on this device */
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+ while (pos && ttl--) {
+ u8 flags;
+
+ if (found < 1)
+ found = 1;
+ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+ &flags) == 0) {
+ if (flags & HT_MSI_FLAGS_ENABLE) {
+ if (found < 2) {
+ found = 2;
+ break;
+ }
+ }
+ }
+ pos = pci_find_next_ht_capability(dev, pos,
+ HT_CAPTYPE_MSI_MAPPING);
+ }
+
+ return found;
+}
+
+static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+{
+ struct pci_dev *host_bridge;
+ int pos;
+ int found;
+
+ /* check if there is HT MSI cap or enabled on this device */
+ found = ht_check_msi_mapping(dev);
+
+ /* no HT MSI CAP */
+ if (found == 0)
+ return;
/*
* HT MSI mapping should be disabled on devices that are below
@@ -2067,24 +2163,19 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
if (pos != 0) {
/* Host bridge is to HT */
- ht_enable_msi_mapping(dev);
+ if (found == 1) {
+ /* it is not enabled, try to enable it */
+ nv_ht_enable_msi_mapping(dev);
+ }
return;
}
- /* Host bridge is not to HT, disable HT MSI mapping on this device */
- pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
- while (pos && ttl--) {
- u8 flags;
+ /* HT MSI is not enabled */
+ if (found == 1)
+ return;
- if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
- &flags) == 0) {
- dev_info(&dev->dev, "Disabling HT MSI mapping");
- pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
- flags & ~HT_MSI_FLAGS_ENABLE);
- }
- pos = pci_find_next_ht_capability(dev, pos,
- HT_CAPTYPE_MSI_MAPPING);
- }
+ /* Host bridge is not to HT, disable HT MSI mapping on this device */
+ ht_disable_msi_mapping(dev);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 042e08924421..caf8e1eae45e 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -71,6 +71,9 @@ void pci_remove_bus(struct pci_bus *pci_bus)
down_write(&pci_bus_sem);
list_del(&pci_bus->node);
up_write(&pci_bus_sem);
+ if (!pci_bus->is_added)
+ return;
+
pci_remove_legacy_files(pci_bus);
device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 132a78159b60..36864a935d68 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -55,6 +55,7 @@ void pci_disable_rom(struct pci_dev *pdev)
/**
* pci_get_rom_size - obtain the actual size of the ROM image
+ * @pdev: target PCI device
* @rom: kernel virtual pointer to image of ROM
* @size: size of PCI window
* return: size of actual ROM image
@@ -63,7 +64,7 @@ void pci_disable_rom(struct pci_dev *pdev)
* The PCI window size could be much larger than the
* actual image size.
*/
-size_t pci_get_rom_size(void __iomem *rom, size_t size)
+size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
{
void __iomem *image;
int last_image;
@@ -72,8 +73,10 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size)
do {
void __iomem *pds;
/* Standard PCI ROMs start out with these bytes 55 AA */
- if (readb(image) != 0x55)
+ if (readb(image) != 0x55) {
+ dev_err(&pdev->dev, "Invalid ROM contents\n");
break;
+ }
if (readb(image + 1) != 0xAA)
break;
/* get the PCI data structure and check its signature */
@@ -159,7 +162,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
* size is much larger than the actual size of the ROM.
* True size is important if the ROM is going to be copied.
*/
- *size = pci_get_rom_size(rom, *size);
+ *size = pci_get_rom_size(pdev, rom, *size);
return rom;
}
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 704608945780..170a3eda9dd3 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -27,7 +27,7 @@
#include <linux/slab.h>
-static void pbus_assign_resources_sorted(struct pci_bus *bus)
+static void pbus_assign_resources_sorted(const struct pci_bus *bus)
{
struct pci_dev *dev;
struct resource *res;
@@ -495,7 +495,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_size_bridges);
-void __ref pci_bus_assign_resources(struct pci_bus *bus)
+void __ref pci_bus_assign_resources(const struct pci_bus *bus)
{
struct pci_bus *b;
struct pci_dev *dev;
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 5a8ccb4f604d..21189447e545 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -1,8 +1,8 @@
/*
* drivers/pci/slot.c
* Copyright (C) 2006 Matthew Wilcox <matthew@wil.cx>
- * Copyright (C) 2006-2008 Hewlett-Packard Development Company, L.P.
- * Alex Chiang <achiang@hp.com>
+ * Copyright (C) 2006-2009 Hewlett-Packard Development Company, L.P.
+ * Alex Chiang <achiang@hp.com>
*/
#include <linux/kobject.h>
@@ -52,8 +52,8 @@ static void pci_slot_release(struct kobject *kobj)
struct pci_dev *dev;
struct pci_slot *slot = to_pci_slot(kobj);
- pr_debug("%s: releasing pci_slot on %x:%d\n", __func__,
- slot->bus->number, slot->number);
+ dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
+ slot->number, pci_slot_name(slot));
list_for_each_entry(dev, &slot->bus->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot->number)
@@ -248,9 +248,8 @@ placeholder:
if (PCI_SLOT(dev->devfn) == slot_nr)
dev->slot = slot;
- /* Don't care if debug printk has a -1 for slot_nr */
- pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
- __func__, pci_domain_nr(parent), parent->number, slot_nr);
+ dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
+ slot_nr, pci_slot_name(slot));
out:
kfree(slot_name);
@@ -299,9 +298,8 @@ EXPORT_SYMBOL_GPL(pci_renumber_slot);
*/
void pci_destroy_slot(struct pci_slot *slot)
{
- pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__,
- atomic_read(&slot->kobj.kref.refcount) - 1,
- pci_domain_nr(slot->bus), slot->bus->number, slot->number);
+ dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
+ slot->number, atomic_read(&slot->kobj.kref.refcount) - 1);
down_write(&pci_bus_sem);
kobject_put(&slot->kobj);
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index fc1de46fd20a..90013341cd5f 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -468,13 +468,13 @@ out:
return ret;
}
-int au1x00_drv_pcmcia_remove(struct device *dev)
+int au1x00_drv_pcmcia_remove(struct platform_device *dev)
{
- struct skt_dev_info *sinfo = dev_get_drvdata(dev);
+ struct skt_dev_info *sinfo = platform_get_drvdata(dev);
int i;
mutex_lock(&pcmcia_sockets_lock);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
for (i = 0; i < sinfo->nskt; i++) {
struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
@@ -498,13 +498,13 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
* PCMCIA "Driver" API
*/
-static int au1x00_drv_pcmcia_probe(struct device *dev)
+static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;
mutex_lock(&pcmcia_sockets_lock);
for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
- ret = au1x00_pcmcia_hw_init[i](dev);
+ ret = au1x00_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -512,14 +512,26 @@ static int au1x00_drv_pcmcia_probe(struct device *dev)
return ret;
}
+static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
-static struct device_driver au1x00_pcmcia_driver = {
+static struct platform_driver au1x00_pcmcia_driver = {
+ .driver = {
+ .name = "au1x00-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = au1x00_drv_pcmcia_probe,
.remove = au1x00_drv_pcmcia_remove,
- .name = "au1x00-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .suspend = au1x00_drv_pcmcia_suspend,
+ .resume = au1x00_drv_pcmcia_resume,
};
@@ -533,8 +545,7 @@ static struct device_driver au1x00_pcmcia_driver = {
static int __init au1x00_pcmcia_init(void)
{
int error = 0;
- if ((error = driver_register(&au1x00_pcmcia_driver)))
- return error;
+ error = platform_driver_register(&au1x00_pcmcia_driver);
return error;
}
@@ -544,7 +555,7 @@ static int __init au1x00_pcmcia_init(void)
*/
static void __exit au1x00_pcmcia_exit(void)
{
- driver_unregister(&au1x00_pcmcia_driver);
+ platform_driver_unregister(&au1x00_pcmcia_driver);
}
module_init(au1x00_pcmcia_init);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 71653ab84890..40d4953e4b12 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1238,6 +1238,16 @@ static int pcic_init(struct pcmcia_socket *s)
return 0;
}
+static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int i82365_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
static struct pccard_operations pcic_operations = {
.init = pcic_init,
.get_status = pcic_get_status,
@@ -1248,11 +1258,13 @@ static struct pccard_operations pcic_operations = {
/*====================================================================*/
-static struct device_driver i82365_driver = {
- .name = "i82365",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver i82365_driver = {
+ .driver = {
+ .name = "i82365",
+ .owner = THIS_MODULE,
+ },
+ .suspend = i82365_drv_pcmcia_suspend,
+ .resume = i82365_drv_pcmcia_resume,
};
static struct platform_device *i82365_device;
@@ -1261,7 +1273,7 @@ static int __init init_i82365(void)
{
int i, ret;
- ret = driver_register(&i82365_driver);
+ ret = platform_driver_register(&i82365_driver);
if (ret)
goto err_out;
@@ -1337,7 +1349,7 @@ err_dev_unregister:
pnp_disable_dev(i82365_pnpdev);
#endif
err_driver_unregister:
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
err_out:
return ret;
} /* init_i82365 */
@@ -1365,7 +1377,7 @@ static void __exit exit_i82365(void)
if (i82365_pnpdev)
pnp_disable_dev(i82365_pnpdev);
#endif
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
} /* exit_i82365 */
module_init(init_i82365);
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 2ab4f22c21de..62b4ecc97c46 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -696,13 +696,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
+static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int cfc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver pcc_driver = {
- .name = "cfc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "cfc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = cfc_drv_pcmcia_suspend,
+ .resume = cfc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
@@ -716,13 +728,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;
- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;
ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}
@@ -754,7 +766,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}
@@ -802,7 +814,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */
module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 2f108c23dbd9..12034b41d196 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -672,13 +672,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
+static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int pcc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver pcc_driver = {
- .name = "pcc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "pcc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = pcc_drv_pcmcia_suspend,
+ .resume = pcc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
@@ -692,13 +704,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;
- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;
ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}
@@ -715,7 +727,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}
@@ -763,7 +775,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */
module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index bb9ddb9532e3..16f84aab6ab3 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -28,7 +28,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
#include <asm/mach-types.h>
@@ -39,6 +38,44 @@
#include "soc_common.h"
#include "pxa2xx_base.h"
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) sockets
+ */
+
+#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */
+#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
+#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
+#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
+#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
+
+#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
+#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
+#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
+#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
+
+#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */
+#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */
+#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */
+#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */
+
+#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ (0x20000000 + (Nb) * PCMCIASp)
+#define _PCMCIAIO(Nb) _PCMCIA(Nb) /* PCMCIA I/O [0..1] */
+#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \
+ (_PCMCIA(Nb) + 2 * PCMCIAPrtSp)
+#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
+ (_PCMCIA(Nb) + 3 * PCMCIAPrtSp)
+
+#define _PCMCIA0 _PCMCIA(0) /* PCMCIA 0 */
+#define _PCMCIA0IO _PCMCIAIO(0) /* PCMCIA 0 I/O */
+#define _PCMCIA0Attr _PCMCIAAttr(0) /* PCMCIA 0 Attribute */
+#define _PCMCIA0Mem _PCMCIAMem(0) /* PCMCIA 0 Memory */
+
+#define _PCMCIA1 _PCMCIA(1) /* PCMCIA 1 */
+#define _PCMCIA1IO _PCMCIAIO(1) /* PCMCIA 1 I/O */
+#define _PCMCIA1Attr _PCMCIAAttr(1) /* PCMCIA 1 Attribute */
+#define _PCMCIA1Mem _PCMCIAMem(1) /* PCMCIA 1 Memory */
+
#define MCXX_SETUP_MASK (0x7f)
#define MCXX_ASST_MASK (0x1f)
@@ -183,23 +220,67 @@ static void pxa2xx_configure_sockets(struct device *dev)
MECR &= ~MECR_NOS;
}
+static const char *skt_names[] = {
+ "PCMCIA socket 0",
+ "PCMCIA socket 1",
+};
+
+#define SKT_DEV_INFO_SIZE(n) \
+ (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
{
- int ret;
+ int i, ret;
struct pcmcia_low_level *ops;
+ struct skt_dev_info *sinfo;
+ struct soc_pcmcia_socket *skt;
if (!dev || !dev->platform_data)
return -ENODEV;
ops = (struct pcmcia_low_level *)dev->platform_data;
+ sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
+ if (!sinfo)
+ return -ENOMEM;
+
+ sinfo->nskt = ops->nr;
+
+ /* Initialize processor specific parameters */
+ for (i = 0; i < ops->nr; i++) {
+ skt = &sinfo->skt[i];
+
+ skt->nr = i;
+ skt->irq = NO_IRQ;
+
+ skt->res_skt.start = _PCMCIA(skt->nr);
+ skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+ skt->res_skt.name = skt_names[skt->nr];
+ skt->res_skt.flags = IORESOURCE_MEM;
+
+ skt->res_io.start = _PCMCIAIO(skt->nr);
+ skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+ skt->res_io.name = "io";
+ skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ skt->res_mem.start = _PCMCIAMem(skt->nr);
+ skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+ skt->res_mem.name = "memory";
+ skt->res_mem.flags = IORESOURCE_MEM;
+
+ skt->res_attr.start = _PCMCIAAttr(skt->nr);
+ skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+ skt->res_attr.name = "attribute";
+ skt->res_attr.flags = IORESOURCE_MEM;
+ }
+
/* Provide our PXA2xx specific timing routines. */
ops->set_timing = pxa2xx_pcmcia_set_timing;
#ifdef CONFIG_CPU_FREQ
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
#endif
- ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
+ ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo);
if (!ret)
pxa2xx_configure_sockets(dev);
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 7c8bcb476622..4ed64d8e95e7 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -16,7 +16,6 @@
#include <linux/gpio.h>
#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
#include "soc_common.h"
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index 6c3aac377126..a7b943d01e34 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -16,7 +16,6 @@
#include <linux/gpio.h>
#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
#include "soc_common.h"
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c
index f663a011bf4a..d09c0dc4a31a 100644
--- a/drivers/pcmcia/pxa2xx_e740.c
+++ b/drivers/pcmcia/pxa2xx_e740.c
@@ -16,8 +16,6 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/eseries-gpio.h>
#include <asm/irq.h>
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index 37ec55df086e..6cbb1b1f7cfd 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -24,7 +24,6 @@
#include <mach/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
#include <mach/lubbock.h>
#include "sa1111_generic.h"
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 877001db4916..1138551ba8f6 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -21,11 +21,10 @@
#include <pcmcia/ss.h>
-#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
#include <mach/mainstone.h>
#include "soc_common.h"
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
index 36c7a0b324d2..e0e5cb339b4a 100644
--- a/drivers/pcmcia/pxa2xx_trizeps4.c
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -22,8 +22,7 @@
#include <asm/mach-types.h>
#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
#include <mach/trizeps4.h>
#include "soc_common.h"
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
index dd10481be7bf..17871360fe99 100644
--- a/drivers/pcmcia/pxa2xx_viper.c
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -26,7 +26,6 @@
#include <asm/irq.h>
-#include <mach/pxa-regs.h>
#include <mach/viper.h>
#include <asm/mach-types.h>
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index c0e2afc79e3e..e592e0e0d7ed 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -153,7 +153,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num,
unsigned long align, struct pcmcia_socket *s)
{
struct resource *res = make_resource(0, num, IORESOURCE_IO,
- s->dev.bus_id);
+ dev_name(&s->dev));
struct pcmcia_align_data data;
unsigned long min = base;
int ret;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index c5b2a44b4c37..d8da5ac844e9 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -65,7 +65,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#endif
};
-static int sa11x0_drv_pcmcia_probe(struct device *dev)
+static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;
@@ -73,7 +73,7 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
* Initialise any "on-board" PCMCIA sockets.
*/
for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) {
- ret = sa11x0_pcmcia_hw_init[i](dev);
+ ret = sa11x0_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -81,13 +81,31 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
return ret;
}
-static struct device_driver sa11x0_pcmcia_driver = {
+static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+{
+ return soc_common_drv_pcmcia_remove(&dev->dev);
+}
+
+static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver sa11x0_pcmcia_driver = {
+ .driver = {
+ .name = "sa11x0-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = sa11x0_drv_pcmcia_probe,
- .remove = soc_common_drv_pcmcia_remove,
- .name = "sa11x0-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .remove = sa11x0_drv_pcmcia_remove,
+ .suspend = sa11x0_drv_pcmcia_suspend,
+ .resume = sa11x0_drv_pcmcia_resume,
};
/* sa11x0_pcmcia_init()
@@ -100,7 +118,7 @@ static struct device_driver sa11x0_pcmcia_driver = {
*/
static int __init sa11x0_pcmcia_init(void)
{
- return driver_register(&sa11x0_pcmcia_driver);
+ return platform_driver_register(&sa11x0_pcmcia_driver);
}
/* sa11x0_pcmcia_exit()
@@ -110,7 +128,7 @@ static int __init sa11x0_pcmcia_init(void)
*/
static void __exit sa11x0_pcmcia_exit(void)
{
- driver_unregister(&sa11x0_pcmcia_driver);
+ platform_driver_unregister(&sa11x0_pcmcia_driver);
}
MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 7cb1273202cc..810ac492a8c9 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -163,9 +163,55 @@ sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
return p - buf;
}
+static const char *skt_names[] = {
+ "PCMCIA socket 0",
+ "PCMCIA socket 1",
+};
+
+#define SKT_DEV_INFO_SIZE(n) \
+ (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
int first, int nr)
{
+ struct skt_dev_info *sinfo;
+ struct soc_pcmcia_socket *skt;
+ int i;
+
+ sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
+ if (!sinfo)
+ return -ENOMEM;
+
+ sinfo->nskt = nr;
+
+ /* Initiliaze processor specific parameters */
+ for (i = 0; i < nr; i++) {
+ skt = &sinfo->skt[i];
+
+ skt->nr = first + i;
+ skt->irq = NO_IRQ;
+
+ skt->res_skt.start = _PCMCIA(skt->nr);
+ skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+ skt->res_skt.name = skt_names[skt->nr];
+ skt->res_skt.flags = IORESOURCE_MEM;
+
+ skt->res_io.start = _PCMCIAIO(skt->nr);
+ skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+ skt->res_io.name = "io";
+ skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ skt->res_mem.start = _PCMCIAMem(skt->nr);
+ skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+ skt->res_mem.name = "memory";
+ skt->res_mem.flags = IORESOURCE_MEM;
+
+ skt->res_attr.start = _PCMCIAAttr(skt->nr);
+ skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+ skt->res_attr.name = "attribute";
+ skt->res_attr.flags = IORESOURCE_MEM;
+ }
+
/*
* set default MECR calculation if the board specific
* code did not specify one...
@@ -180,7 +226,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
ops->frequency_change = sa1100_pcmcia_frequency_change;
#endif
- return soc_common_drv_pcmcia_probe(dev, ops, first, nr);
+ return soc_common_drv_pcmcia_probe(dev, ops, sinfo);
}
EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index f49ac6666153..163cf98e2386 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -49,11 +49,6 @@
#include "soc_common.h"
-/* FIXME: platform dependent resource declaration has to move out of this file */
-#ifdef CONFIG_ARCH_PXA
-#include <mach/pxa-regs.h>
-#endif
-
#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
@@ -581,19 +576,6 @@ EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
LIST_HEAD(soc_pcmcia_sockets);
static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
-static const char *skt_names[] = {
- "PCMCIA socket 0",
- "PCMCIA socket 1",
-};
-
-struct skt_dev_info {
- int nskt;
- struct soc_pcmcia_socket skt[0];
-};
-
-#define SKT_DEV_INFO_SIZE(n) \
- (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
-
#ifdef CONFIG_CPU_FREQ
static int
soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
@@ -637,26 +619,18 @@ static int soc_pcmcia_cpufreq_register(void) { return 0; }
static void soc_pcmcia_cpufreq_unregister(void) {}
#endif
-int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
+int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
+ struct skt_dev_info *sinfo)
{
- struct skt_dev_info *sinfo;
struct soc_pcmcia_socket *skt;
int ret, i;
mutex_lock(&soc_pcmcia_sockets_lock);
- sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
- if (!sinfo) {
- ret = -ENOMEM;
- goto out;
- }
-
- sinfo->nskt = nr;
-
/*
* Initialise the per-socket structure.
*/
- for (i = 0; i < nr; i++) {
+ for (i = 0; i < sinfo->nskt; i++) {
skt = &sinfo->skt[i];
skt->socket.ops = &soc_common_pcmcia_operations;
@@ -668,43 +642,21 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
skt->poll_timer.data = (unsigned long)skt;
skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
- skt->nr = first + i;
- skt->irq = NO_IRQ;
skt->dev = dev;
skt->ops = ops;
- skt->res_skt.start = _PCMCIA(skt->nr);
- skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
- skt->res_skt.name = skt_names[skt->nr];
- skt->res_skt.flags = IORESOURCE_MEM;
-
ret = request_resource(&iomem_resource, &skt->res_skt);
if (ret)
goto out_err_1;
- skt->res_io.start = _PCMCIAIO(skt->nr);
- skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
- skt->res_io.name = "io";
- skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-
ret = request_resource(&skt->res_skt, &skt->res_io);
if (ret)
goto out_err_2;
- skt->res_mem.start = _PCMCIAMem(skt->nr);
- skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
- skt->res_mem.name = "memory";
- skt->res_mem.flags = IORESOURCE_MEM;
-
ret = request_resource(&skt->res_skt, &skt->res_mem);
if (ret)
goto out_err_3;
- skt->res_attr.start = _PCMCIAAttr(skt->nr);
- skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
- skt->res_attr.name = "attribute";
- skt->res_attr.flags = IORESOURCE_MEM;
-
ret = request_resource(&skt->res_skt, &skt->res_attr);
if (ret)
goto out_err_4;
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 38c67375f363..290e143839ee 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -58,6 +58,11 @@ struct soc_pcmcia_socket {
struct list_head node;
};
+struct skt_dev_info {
+ int nskt;
+ struct soc_pcmcia_socket skt[0];
+};
+
struct pcmcia_state {
unsigned detect: 1,
ready: 1,
@@ -132,7 +137,7 @@ extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_
extern struct list_head soc_pcmcia_sockets;
-extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
+extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo);
extern int soc_common_drv_pcmcia_remove(struct device *dev);
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 2a613e920fd4..9ad97ea836e8 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -363,13 +363,25 @@ static int __init get_tcic_id(void)
return id;
}
+static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int tcic_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver tcic_driver = {
- .name = "tcic-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver tcic_driver = {
+ .driver = {
+ .name = "tcic-pcmcia",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tcic_drv_pcmcia_suspend,
+ .resume = tcic_drv_pcmcia_resume,
};
static struct platform_device tcic_device = {
@@ -383,7 +395,7 @@ static int __init init_tcic(void)
int i, sock, ret = 0;
u_int mask, scan;
- if (driver_register(&tcic_driver))
+ if (platform_driver_register(&tcic_driver))
return -1;
printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
@@ -391,7 +403,7 @@ static int __init init_tcic(void)
if (!request_region(tcic_base, 16, "tcic-2")) {
printk("could not allocate ports,\n ");
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
else {
@@ -414,7 +426,7 @@ static int __init init_tcic(void)
if (sock == 0) {
printk("not found.\n");
release_region(tcic_base, 16);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
@@ -542,7 +554,7 @@ static void __exit exit_tcic(void)
}
platform_device_unregister(&tcic_device);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
} /* exit_tcic */
/*====================================================================*/
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index b2c412419059..659421d0ca46 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -704,24 +704,37 @@ static int __devinit vrc4171_card_setup(char *options)
__setup("vrc4171_card=", vrc4171_card_setup);
-static struct device_driver vrc4171_card_driver = {
- .name = vrc4171_card_name,
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static int vrc4171_card_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int vrc4171_card_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver vrc4171_card_driver = {
+ .driver = {
+ .name = vrc4171_card_name,
+ .owner = THIS_MODULE,
+ },
+ .suspend = vrc4171_card_suspend,
+ .resume = vrc4171_card_resume,
};
static int __devinit vrc4171_card_init(void)
{
int retval;
- retval = driver_register(&vrc4171_card_driver);
+ retval = platform_driver_register(&vrc4171_card_driver);
if (retval < 0)
return retval;
retval = platform_device_register(&vrc4171_card_device);
if (retval < 0) {
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}
@@ -735,11 +748,12 @@ static int __devinit vrc4171_card_init(void)
if (retval < 0) {
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}
- printk(KERN_INFO "%s, connected to IRQ %d\n", vrc4171_card_driver.name, vrc4171_irq);
+ printk(KERN_INFO "%s, connected to IRQ %d\n",
+ vrc4171_card_driver.driver.name, vrc4171_irq);
return 0;
}
@@ -749,7 +763,7 @@ static void __devexit vrc4171_card_exit(void)
free_irq(vrc4171_irq, vrc4171_sockets);
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
}
module_init(vrc4171_card_init);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 1a266d4ab5f1..b3866ad50227 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -42,6 +42,7 @@ config ASUS_LAPTOP
depends on LEDS_CLASS
depends on NEW_LEDS
depends on BACKLIGHT_CLASS_DEVICE
+ depends on INPUT
---help---
This is the new Linux driver for Asus laptops. It may also support some
MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
@@ -61,6 +62,7 @@ config DELL_LAPTOP
depends on EXPERIMENTAL
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL
+ depends on POWER_SUPPLY
default n
---help---
This driver adds support for rfkill and backlight control to Dell
@@ -300,6 +302,7 @@ config INTEL_MENLOW
config EEEPC_LAPTOP
tristate "Eee PC Hotkey Driver (EXPERIMENTAL)"
depends on ACPI
+ depends on INPUT
depends on EXPERIMENTAL
select BACKLIGHT_CLASS_DEVICE
select HWMON
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 8fb8b3591048..56af6cf385b0 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -46,6 +46,7 @@
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>
+#include <linux/input.h>
#define ASUS_LAPTOP_VERSION "0.42"
@@ -181,6 +182,8 @@ struct asus_hotk {
u8 light_level; //light sensor level
u8 light_switch; //light sensor switch value
u16 event_count[128]; //count for each event TODO make this better
+ struct input_dev *inputdev;
+ u16 *keycode_map;
};
/*
@@ -250,6 +253,37 @@ ASUS_LED(rled, "record");
ASUS_LED(pled, "phone");
ASUS_LED(gled, "gaming");
+struct key_entry {
+ char type;
+ u8 code;
+ u16 keycode;
+};
+
+enum { KE_KEY, KE_END };
+
+static struct key_entry asus_keymap[] = {
+ {KE_KEY, 0x30, KEY_VOLUMEUP},
+ {KE_KEY, 0x31, KEY_VOLUMEDOWN},
+ {KE_KEY, 0x32, KEY_MUTE},
+ {KE_KEY, 0x33, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x40, KEY_PREVIOUSSONG},
+ {KE_KEY, 0x41, KEY_NEXTSONG},
+ {KE_KEY, 0x43, KEY_STOP},
+ {KE_KEY, 0x45, KEY_PLAYPAUSE},
+ {KE_KEY, 0x50, KEY_EMAIL},
+ {KE_KEY, 0x51, KEY_WWW},
+ {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */
+ {KE_KEY, 0x5D, KEY_WLAN},
+ {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE},
+ {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */
+ {KE_KEY, 0x82, KEY_CAMERA},
+ {KE_KEY, 0x8A, KEY_TV},
+ {KE_KEY, 0x95, KEY_MEDIA},
+ {KE_KEY, 0x99, KEY_PHONE},
+ {KE_END, 0},
+};
+
/*
* This function evaluates an ACPI method, given an int as parameter, the
* method is searched within the scope of the handle, can be NULL. The output
@@ -720,8 +754,68 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
return store_status(buf, count, NULL, GPS_ON);
}
+/*
+ * Hotkey functions
+ */
+static struct key_entry *asus_get_entry_by_scancode(int code)
+{
+ struct key_entry *key;
+
+ for (key = asus_keymap; key->type != KE_END; key++)
+ if (code == key->code)
+ return key;
+
+ return NULL;
+}
+
+static struct key_entry *asus_get_entry_by_keycode(int code)
+{
+ struct key_entry *key;
+
+ for (key = asus_keymap; key->type != KE_END; key++)
+ if (code == key->keycode && key->type == KE_KEY)
+ return key;
+
+ return NULL;
+}
+
+static int asus_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+{
+ struct key_entry *key = asus_get_entry_by_scancode(scancode);
+
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+ struct key_entry *key;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ key = asus_get_entry_by_scancode(scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!asus_get_entry_by_keycode(old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
{
+ static struct key_entry *key;
+
/* TODO Find a better way to handle events count. */
if (!hotk)
return;
@@ -738,10 +832,24 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
lcd_blank(FB_BLANK_POWERDOWN);
}
- acpi_bus_generate_proc_event(hotk->device, event,
- hotk->event_count[event % 128]++);
-
- return;
+ acpi_bus_generate_netlink_event(hotk->device->pnp.device_class,
+ dev_name(&hotk->device->dev), event,
+ hotk->event_count[event % 128]++);
+
+ if (hotk->inputdev) {
+ key = asus_get_entry_by_scancode(event);
+ if (!key)
+ return ;
+
+ switch (key->type) {
+ case KE_KEY:
+ input_report_key(hotk->inputdev, key->keycode, 1);
+ input_sync(hotk->inputdev);
+ input_report_key(hotk->inputdev, key->keycode, 0);
+ input_sync(hotk->inputdev);
+ break;
+ }
+ }
}
#define ASUS_CREATE_DEVICE_ATTR(_name) \
@@ -959,6 +1067,38 @@ static int asus_hotk_get_info(void)
return AE_OK;
}
+static int asus_input_init(void)
+{
+ const struct key_entry *key;
+ int result;
+
+ hotk->inputdev = input_allocate_device();
+ if (!hotk->inputdev) {
+ printk(ASUS_INFO "Unable to allocate input device\n");
+ return 0;
+ }
+ hotk->inputdev->name = "Asus Laptop extra buttons";
+ hotk->inputdev->phys = ASUS_HOTK_FILE "/input0";
+ hotk->inputdev->id.bustype = BUS_HOST;
+ hotk->inputdev->getkeycode = asus_getkeycode;
+ hotk->inputdev->setkeycode = asus_setkeycode;
+
+ for (key = asus_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_KEY:
+ set_bit(EV_KEY, hotk->inputdev->evbit);
+ set_bit(key->keycode, hotk->inputdev->keybit);
+ break;
+ }
+ }
+ result = input_register_device(hotk->inputdev);
+ if (result) {
+ printk(ASUS_INFO "Unable to register input device\n");
+ input_free_device(hotk->inputdev);
+ }
+ return result;
+}
+
static int asus_hotk_check(void)
{
int result = 0;
@@ -1044,7 +1184,7 @@ static int asus_hotk_add(struct acpi_device *device)
/* GPS is on by default */
write_status(NULL, 1, GPS_ON);
- end:
+end:
if (result) {
kfree(hotk->name);
kfree(hotk);
@@ -1091,10 +1231,17 @@ static void asus_led_exit(void)
ASUS_LED_UNREGISTER(gled);
}
+static void asus_input_exit(void)
+{
+ if (hotk->inputdev)
+ input_unregister_device(hotk->inputdev);
+}
+
static void __exit asus_laptop_exit(void)
{
asus_backlight_exit();
asus_led_exit();
+ asus_input_exit();
acpi_bus_unregister_driver(&asus_hotk_driver);
sysfs_remove_group(&asuspf_device->dev.kobj, &asuspf_attribute_group);
@@ -1216,6 +1363,10 @@ static int __init asus_laptop_init(void)
printk(ASUS_INFO "Brightness ignored, must be controlled by "
"ACPI video driver\n");
+ result = asus_input_init();
+ if (result)
+ goto fail_input;
+
result = asus_led_init(dev);
if (result)
goto fail_led;
@@ -1242,22 +1393,25 @@ static int __init asus_laptop_init(void)
return 0;
- fail_sysfs:
+fail_sysfs:
platform_device_del(asuspf_device);
- fail_platform_device2:
+fail_platform_device2:
platform_device_put(asuspf_device);
- fail_platform_device1:
+fail_platform_device1:
platform_driver_unregister(&asuspf_driver);
- fail_platform_driver:
+fail_platform_driver:
asus_led_exit();
- fail_led:
+fail_led:
+ asus_input_exit();
+
+fail_input:
asus_backlight_exit();
- fail_backlight:
+fail_backlight:
return result;
}
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
index 1e74988c7b2d..d63f26e666a4 100644
--- a/drivers/platform/x86/asus_acpi.c
+++ b/drivers/platform/x86/asus_acpi.c
@@ -143,6 +143,7 @@ struct asus_hotk {
S1300N, S5200N*/
A4S, /* Z81sp */
F3Sa, /* (Centrino) */
+ R1F,
END_MODEL
} model; /* Models currently supported */
u16 event_count[128]; /* Count for each event TODO make this better */
@@ -420,7 +421,18 @@ static struct model_data model_conf[END_MODEL] = {
.display_get = "\\ADVG",
.display_set = "SDSP",
},
-
+ {
+ .name = "R1F",
+ .mt_bt_switch = "BLED",
+ .mt_mled = "MLED",
+ .mt_wled = "WLED",
+ .mt_lcd_switch = "\\Q10",
+ .lcd_status = "\\GP06",
+ .brightness_set = "SPLV",
+ .brightness_get = "GPLV",
+ .display_set = "SDSP",
+ .display_get = "\\INFB"
+ }
};
/* procdir we use */
@@ -1165,6 +1177,8 @@ static int asus_model_match(char *model)
return W3V;
else if (strncmp(model, "W5A", 3) == 0)
return W5A;
+ else if (strncmp(model, "R1F", 3) == 0)
+ return R1F;
else if (strncmp(model, "A4S", 3) == 0)
return A4S;
else if (strncmp(model, "F3Sa", 4) == 0)
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 9d93cb971e59..786ed8661cb0 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -30,6 +30,7 @@
#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/rfkill.h>
+#include <linux/pci.h>
#define EEEPC_LAPTOP_VERSION "0.1"
@@ -161,6 +162,10 @@ static struct key_entry eeepc_keymap[] = {
{KE_KEY, 0x13, KEY_MUTE },
{KE_KEY, 0x14, KEY_VOLUMEDOWN },
{KE_KEY, 0x15, KEY_VOLUMEUP },
+ {KE_KEY, 0x1a, KEY_COFFEE },
+ {KE_KEY, 0x1b, KEY_ZOOM },
+ {KE_KEY, 0x1c, KEY_PROG2 },
+ {KE_KEY, 0x1d, KEY_PROG3 },
{KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
{KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
@@ -510,7 +515,43 @@ static int eeepc_hotk_check(void)
static void notify_brn(void)
{
struct backlight_device *bd = eeepc_backlight_device;
- bd->props.brightness = read_brightness(bd);
+ if (bd)
+ bd->props.brightness = read_brightness(bd);
+}
+
+static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct pci_dev *dev;
+ struct pci_bus *bus = pci_find_bus(0, 1);
+
+ if (event != ACPI_NOTIFY_BUS_CHECK)
+ return;
+
+ if (!bus) {
+ printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
+ return;
+ }
+
+ if (get_acpi(CM_ASL_WLAN) == 1) {
+ dev = pci_get_slot(bus, 0);
+ if (dev) {
+ /* Device already present */
+ pci_dev_put(dev);
+ return;
+ }
+ dev = pci_scan_single_device(bus, 0);
+ if (dev) {
+ pci_bus_assign_resources(bus);
+ if (pci_bus_add_device(dev))
+ printk(EEEPC_ERR "Unable to hotplug wifi\n");
+ }
+ } else {
+ dev = pci_get_slot(bus, 0);
+ if (dev) {
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+ }
+ }
}
static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
@@ -520,8 +561,9 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
return;
if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
notify_brn();
- acpi_bus_generate_proc_event(ehotk->device, event,
- ehotk->event_count[event % 128]++);
+ acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class,
+ dev_name(&ehotk->device->dev), event,
+ ehotk->event_count[event % 128]++);
if (ehotk->inputdev) {
key = eepc_get_entry_by_scancode(event);
if (key) {
@@ -539,6 +581,45 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
}
}
+static int eeepc_register_rfkill_notifier(char *node)
+{
+ acpi_status status = AE_OK;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, node, &handle);
+
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_install_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ eeepc_rfkill_notify,
+ NULL);
+ if (ACPI_FAILURE(status))
+ printk(EEEPC_WARNING
+ "Failed to register notify on %s\n", node);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+static void eeepc_unregister_rfkill_notifier(char *node)
+{
+ acpi_status status = AE_OK;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, node, &handle);
+
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_remove_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ eeepc_rfkill_notify);
+ if (ACPI_FAILURE(status))
+ printk(EEEPC_ERR
+ "Error removing rfkill notify handler %s\n",
+ node);
+ }
+}
+
static int eeepc_hotk_add(struct acpi_device *device)
{
acpi_status status = AE_OK;
@@ -558,7 +639,7 @@ static int eeepc_hotk_add(struct acpi_device *device)
ehotk->device = device;
result = eeepc_hotk_check();
if (result)
- goto end;
+ goto ehotk_fail;
status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
eeepc_hotk_notify, ehotk);
if (ACPI_FAILURE(status))
@@ -569,18 +650,25 @@ static int eeepc_hotk_add(struct acpi_device *device)
RFKILL_TYPE_WLAN);
if (!ehotk->eeepc_wlan_rfkill)
- goto end;
+ goto wlan_fail;
ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
- if (get_acpi(CM_ASL_WLAN) == 1)
+ if (get_acpi(CM_ASL_WLAN) == 1) {
ehotk->eeepc_wlan_rfkill->state =
RFKILL_STATE_UNBLOCKED;
- else
+ rfkill_set_default(RFKILL_TYPE_WLAN,
+ RFKILL_STATE_UNBLOCKED);
+ } else {
ehotk->eeepc_wlan_rfkill->state =
RFKILL_STATE_SOFT_BLOCKED;
- rfkill_register(ehotk->eeepc_wlan_rfkill);
+ rfkill_set_default(RFKILL_TYPE_WLAN,
+ RFKILL_STATE_SOFT_BLOCKED);
+ }
+ result = rfkill_register(ehotk->eeepc_wlan_rfkill);
+ if (result)
+ goto wlan_fail;
}
if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
@@ -588,27 +676,47 @@ static int eeepc_hotk_add(struct acpi_device *device)
rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
if (!ehotk->eeepc_bluetooth_rfkill)
- goto end;
+ goto bluetooth_fail;
ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
ehotk->eeepc_bluetooth_rfkill->toggle_radio =
eeepc_bluetooth_rfkill_set;
ehotk->eeepc_bluetooth_rfkill->get_state =
eeepc_bluetooth_rfkill_state;
- if (get_acpi(CM_ASL_BLUETOOTH) == 1)
+ if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_UNBLOCKED;
- else
+ rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+ RFKILL_STATE_UNBLOCKED);
+ } else {
ehotk->eeepc_bluetooth_rfkill->state =
RFKILL_STATE_SOFT_BLOCKED;
- rfkill_register(ehotk->eeepc_bluetooth_rfkill);
- }
+ rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
+ RFKILL_STATE_SOFT_BLOCKED);
+ }
- end:
- if (result) {
- kfree(ehotk);
- ehotk = NULL;
+ result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
+ if (result)
+ goto bluetooth_fail;
}
+
+ eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
+ eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
+
+ return 0;
+
+ bluetooth_fail:
+ if (ehotk->eeepc_bluetooth_rfkill)
+ rfkill_free(ehotk->eeepc_bluetooth_rfkill);
+ rfkill_unregister(ehotk->eeepc_wlan_rfkill);
+ ehotk->eeepc_wlan_rfkill = NULL;
+ wlan_fail:
+ if (ehotk->eeepc_wlan_rfkill)
+ rfkill_free(ehotk->eeepc_wlan_rfkill);
+ ehotk_fail:
+ kfree(ehotk);
+ ehotk = NULL;
+
return result;
}
@@ -622,6 +730,10 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
eeepc_hotk_notify);
if (ACPI_FAILURE(status))
printk(EEEPC_ERR "Error removing notify handler\n");
+
+ eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
+ eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
+
kfree(ehotk);
return 0;
}
@@ -737,13 +849,21 @@ static void eeepc_backlight_exit(void)
{
if (eeepc_backlight_device)
backlight_device_unregister(eeepc_backlight_device);
- if (ehotk->inputdev)
- input_unregister_device(ehotk->inputdev);
+ eeepc_backlight_device = NULL;
+}
+
+static void eeepc_rfkill_exit(void)
+{
if (ehotk->eeepc_wlan_rfkill)
rfkill_unregister(ehotk->eeepc_wlan_rfkill);
if (ehotk->eeepc_bluetooth_rfkill)
rfkill_unregister(ehotk->eeepc_bluetooth_rfkill);
- eeepc_backlight_device = NULL;
+}
+
+static void eeepc_input_exit(void)
+{
+ if (ehotk->inputdev)
+ input_unregister_device(ehotk->inputdev);
}
static void eeepc_hwmon_exit(void)
@@ -762,6 +882,8 @@ static void eeepc_hwmon_exit(void)
static void __exit eeepc_laptop_exit(void)
{
eeepc_backlight_exit();
+ eeepc_rfkill_exit();
+ eeepc_input_exit();
eeepc_hwmon_exit();
acpi_bus_unregister_driver(&eeepc_hotk_driver);
sysfs_remove_group(&platform_device->dev.kobj,
@@ -865,6 +987,8 @@ fail_platform_driver:
fail_hwmon:
eeepc_backlight_exit();
fail_backlight:
+ eeepc_input_exit();
+ eeepc_rfkill_exit();
return result;
}
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 65dc41540c62..45940f31fe9e 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -166,6 +166,7 @@ struct fujitsu_hotkey_t {
struct platform_device *pf_device;
struct kfifo *fifo;
spinlock_t fifo_lock;
+ int rfkill_supported;
int rfkill_state;
int logolamp_registered;
int kblamps_registered;
@@ -526,7 +527,7 @@ static ssize_t
show_lid_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
- if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+ if (!(fujitsu_hotkey->rfkill_supported & 0x100))
return sprintf(buf, "unknown\n");
if (fujitsu_hotkey->rfkill_state & 0x100)
return sprintf(buf, "open\n");
@@ -538,7 +539,7 @@ static ssize_t
show_dock_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
- if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+ if (!(fujitsu_hotkey->rfkill_supported & 0x200))
return sprintf(buf, "unknown\n");
if (fujitsu_hotkey->rfkill_state & 0x200)
return sprintf(buf, "docked\n");
@@ -550,7 +551,7 @@ static ssize_t
show_radios_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
- if (fujitsu_hotkey->rfkill_state == UNSUPPORTED_CMD)
+ if (!(fujitsu_hotkey->rfkill_supported & 0x20))
return sprintf(buf, "unknown\n");
if (fujitsu_hotkey->rfkill_state & 0x20)
return sprintf(buf, "on\n");
@@ -928,8 +929,17 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
; /* No action, result is discarded */
vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);
- fujitsu_hotkey->rfkill_state =
- call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
+ fujitsu_hotkey->rfkill_supported =
+ call_fext_func(FUNC_RFKILL, 0x0, 0x0, 0x0);
+
+ /* Make sure our bitmask of supported functions is cleared if the
+ RFKILL function block is not implemented, like on the S7020. */
+ if (fujitsu_hotkey->rfkill_supported == UNSUPPORTED_CMD)
+ fujitsu_hotkey->rfkill_supported = 0;
+
+ if (fujitsu_hotkey->rfkill_supported)
+ fujitsu_hotkey->rfkill_state =
+ call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
/* Suspect this is a keymap of the application panel, print it */
printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n",
@@ -1005,8 +1015,9 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
input = fujitsu_hotkey->input;
- fujitsu_hotkey->rfkill_state =
- call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
+ if (fujitsu_hotkey->rfkill_supported)
+ fujitsu_hotkey->rfkill_state =
+ call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
switch (event) {
case ACPI_FUJITSU_NOTIFY_CODE1:
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 7c789f0a94d7..f41135f2fb29 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -382,6 +382,11 @@ static int __init hp_wmi_input_setup(void)
case KE_SW:
set_bit(EV_SW, hp_wmi_input_dev->evbit);
set_bit(key->keycode, hp_wmi_input_dev->swbit);
+
+ /* Set initial dock state */
+ input_report_switch(hp_wmi_input_dev, key->keycode,
+ hp_wmi_dock_state());
+ input_sync(hp_wmi_input_dev);
break;
}
}
@@ -441,6 +446,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set;
bluetooth_rfkill->user_claim_unsupported = 1;
err = rfkill_register(bluetooth_rfkill);
+ if (err)
goto register_bluetooth_error;
}
@@ -457,9 +463,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
return 0;
register_wwan_err:
- rfkill_unregister(bluetooth_rfkill);
+ if (bluetooth_rfkill)
+ rfkill_unregister(bluetooth_rfkill);
register_bluetooth_error:
- rfkill_unregister(wifi_rfkill);
+ if (wifi_rfkill)
+ rfkill_unregister(wifi_rfkill);
add_sysfs_error:
cleanup_sysfs(device);
return err;
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index f30db367c82e..c47a44dcb702 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -507,7 +507,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
hkey_num = result & 0xf;
- if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) {
+ if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"hotkey number out of range: %d\n",
hkey_num));
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
index e988ec130fcd..41aec2acbb91 100644
--- a/drivers/power/pcf50633-charger.c
+++ b/drivers/power/pcf50633-charger.c
@@ -199,7 +199,8 @@ static int adapter_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
- struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
+ struct pcf50633_mbc *mbc = container_of(psy,
+ struct pcf50633_mbc, adapter);
int ret = 0;
switch (psp) {
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index d30bb766fcef..b56a704409d2 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -20,7 +20,7 @@
static inline unsigned int get_irq_flags(struct resource *res)
{
- unsigned int flags = IRQF_DISABLED | IRQF_SHARED;
+ unsigned int flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED;
flags |= res->flags & IRQF_TRIGGER_MASK;
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index addb87cf44d9..3222fa3c808c 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -193,7 +193,7 @@ static int rio_match_bus(struct device *dev, struct device_driver *drv)
}
static struct device rio_bus = {
- .bus_id = "rapidio",
+ .init_name = "rapidio",
};
struct bus_type rio_bus_type = {
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index 366565aba865..c175e38a4cd5 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -152,11 +152,7 @@ static void __exit bq24022_exit(void)
platform_driver_unregister(&bq24022_driver);
}
-/*
- * make sure this is probed before gpio_vbus and pda_power,
- * but after asic3 or other GPIO expander drivers.
- */
-subsys_initcall(bq24022_init);
+module_init(bq24022_init);
module_exit(bq24022_exit);
MODULE_AUTHOR("Philipp Zabel");
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 7aa35248181b..5056e23e4414 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1435,7 +1435,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
struct platform_device *pdev;
int ret;
- if (lednum > ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
+ if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
dev_err(wm8350->dev, "Invalid LED index %d\n", lednum);
return -ENODEV;
}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index cced4d108319..81450fbd8b12 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -241,6 +241,12 @@ config RTC_DRV_M41T80_WDT
If you say Y here you will get support for the
watchdog timer in the ST M41T60 and M41T80 RTC chips series.
+config RTC_DRV_DM355EVM
+ tristate "TI DaVinci DM355 EVM RTC"
+ depends on MFD_DM355EVM_MSP
+ help
+ Supports the RTC firmware in the MSP430 on the DM355 EVM.
+
config RTC_DRV_TWL92330
boolean "TI TWL92330/Menelaus"
depends on MENELAUS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6e28021abb9d..0e697aa51caa 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
+obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o
obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index d5e4e637ddec..86c61f143515 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -351,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
/* register irq handler after we know what name we'll use */
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
IRQF_DISABLED | IRQF_SHARED,
- rtc->rtcdev->dev.bus_id, rtc);
+ dev_name(&rtc->rtcdev->dev), rtc);
if (ret) {
dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
rtc_device_unregister(rtc->rtcdev);
@@ -366,7 +366,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
if (gpbr_readl(rtc) == 0)
dev_warn(&pdev->dev, "%s: SET TIME!\n",
- rtc->rtcdev->dev.bus_id);
+ dev_name(&rtc->rtcdev->dev));
return 0;
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c
index 8906a688e6a6..979ed0406ce9 100644
--- a/drivers/rtc/rtc-au1xxx.c
+++ b/drivers/rtc/rtc-au1xxx.c
@@ -81,7 +81,7 @@ static int __devinit au1xtoy_rtc_probe(struct platform_device *pdev)
if (au_readl(SYS_TOYTRIM) != 32767) {
/* wait until hardware gives access to TRIM register */
t = 0x00100000;
- while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && t--)
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && --t)
msleep(1);
if (!t) {
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
new file mode 100644
index 000000000000..58d4e18530da
--- /dev/null
+++ b/drivers/rtc/rtc-dm355evm.c
@@ -0,0 +1,175 @@
+/*
+ * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware
+ *
+ * Copyright (c) 2008 by David Brownell
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c/dm355evm_msp.h>
+
+
+/*
+ * The MSP430 firmware on the DM355 EVM uses a watch crystal to feed
+ * a 1 Hz counter. When a backup battery is supplied, that makes a
+ * reasonable RTC for applications where alarms and non-NTP drift
+ * compensation aren't important.
+ *
+ * The only real glitch is the inability to read or write all four
+ * counter bytes atomically: the count may increment in the middle
+ * of an operation, causing trouble when the LSB rolls over.
+ *
+ * This driver was tested with firmware revision A4.
+ */
+union evm_time {
+ u8 bytes[4];
+ u32 value;
+};
+
+static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ union evm_time time;
+ int status;
+ int tries = 0;
+
+ do {
+ /*
+ * Read LSB(0) to MSB(3) bytes. Defend against the counter
+ * rolling over by re-reading until the value is stable,
+ * and assuming the four reads take at most a few seconds.
+ */
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_0);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[0] == status)
+ break;
+ time.bytes[0] = status;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_1);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[1] == status)
+ break;
+ time.bytes[1] = status;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_2);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[2] == status)
+ break;
+ time.bytes[2] = status;
+
+ status = dm355evm_msp_read(DM355EVM_MSP_RTC_3);
+ if (status < 0)
+ return status;
+ if (tries && time.bytes[3] == status)
+ break;
+ time.bytes[3] = status;
+
+ } while (++tries < 5);
+
+ dev_dbg(dev, "read timestamp %08x\n", time.value);
+
+ rtc_time_to_tm(le32_to_cpu(time.value), tm);
+ return 0;
+}
+
+static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ union evm_time time;
+ unsigned long value;
+ int status;
+
+ rtc_tm_to_time(tm, &value);
+ time.value = cpu_to_le32(value);
+
+ dev_dbg(dev, "write timestamp %08x\n", time.value);
+
+ /*
+ * REVISIT handle non-atomic writes ... maybe just retry until
+ * byte[1] sticks (no rollover)?
+ */
+ status = dm355evm_msp_write(time.bytes[0], DM355EVM_MSP_RTC_0);
+ if (status < 0)
+ return status;
+
+ status = dm355evm_msp_write(time.bytes[1], DM355EVM_MSP_RTC_1);
+ if (status < 0)
+ return status;
+
+ status = dm355evm_msp_write(time.bytes[2], DM355EVM_MSP_RTC_2);
+ if (status < 0)
+ return status;
+
+ status = dm355evm_msp_write(time.bytes[3], DM355EVM_MSP_RTC_3);
+ if (status < 0)
+ return status;
+
+ return 0;
+}
+
+static struct rtc_class_ops dm355evm_rtc_ops = {
+ .read_time = dm355evm_rtc_read_time,
+ .set_time = dm355evm_rtc_set_time,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit dm355evm_rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register(pdev->name,
+ &pdev->dev, &dm355evm_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+ PTR_ERR(rtc));
+ return PTR_ERR(rtc);
+ }
+ platform_set_drvdata(pdev, rtc);
+
+ return 0;
+}
+
+static int __devexit dm355evm_rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+ rtc_device_unregister(rtc);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+/*
+ * I2C is used to talk to the MSP430, but this platform device is
+ * exposed by an MFD driver that manages I2C communications.
+ */
+static struct platform_driver rtc_dm355evm_driver = {
+ .probe = dm355evm_rtc_probe,
+ .remove = __devexit_p(dm355evm_rtc_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "rtc-dm355evm",
+ },
+};
+
+static int __init dm355evm_rtc_init(void)
+{
+ return platform_driver_register(&rtc_dm355evm_driver);
+}
+module_init(dm355evm_rtc_init);
+
+static void __exit dm355evm_rtc_exit(void)
+{
+ platform_driver_unregister(&rtc_dm355evm_driver);
+}
+module_exit(dm355evm_rtc_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index e54b5c619bdf..e01b955db077 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -122,7 +122,6 @@ static const struct rtc_class_ops ds1390_rtc_ops = {
static int __devinit ds1390_probe(struct spi_device *spi)
{
- struct rtc_device *rtc;
unsigned char tmp;
struct ds1390 *chip;
int res;
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 2cbeb0794f14..bd1ce8e2bc18 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -377,13 +377,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
/* handle periodic and alarm irqs */
if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_timer);
goto fail0;
}
if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_alarm);
goto fail1;
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index bd56a033bfd0..bb8cc05605ac 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -485,7 +485,7 @@ static void __exit pxa_rtc_exit(void)
module_init(pxa_rtc_init);
module_exit(pxa_rtc_exit);
-MODULE_AUTHOR("Robert Jarzmik");
+MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
MODULE_DESCRIPTION("PXA27x/PXA3xx Realtime Clock Driver (RTC)");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pxa-rtc");
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index d26a5f82aaba..4f247e4dd3f9 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -35,7 +35,8 @@
#include <asm/irq.h>
#ifdef CONFIG_ARCH_PXA
-#include <mach/pxa-regs.h>
+#include <mach/regs-rtc.h>
+#include <mach/regs-ost.h>
#endif
#define RTC_DEF_DIVIDER 32768 - 1
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
index ad35f76c46b7..a6341e4f9a0f 100644
--- a/drivers/rtc/rtc-twl4030.c
+++ b/drivers/rtc/rtc-twl4030.c
@@ -426,7 +426,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
ret = request_irq(irq, twl4030_rtc_interrupt,
IRQF_TRIGGER_RISING,
- rtc->dev.bus_id, rtc);
+ dev_name(&rtc->dev), rtc);
if (ret < 0) {
dev_err(&pdev->dev, "IRQ is not free.\n");
goto out1;
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile
index d0eae59bc366..95bccfd3f169 100644
--- a/drivers/s390/Makefile
+++ b/drivers/s390/Makefile
@@ -2,9 +2,6 @@
# Makefile for the S/390 specific device drivers
#
-CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
-
-obj-y += s390mach.o sysinfo.o
obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
drivers-y += drivers/s390/built-in.o
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index bd5914994142..204b087bc800 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -9,6 +9,9 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -22,6 +25,7 @@
#include <asm/ebcdic.h>
#include <asm/idals.h>
#include <asm/todclk.h>
+#include <asm/itcw.h>
/* This is ugly... */
#define PRINTK_HEADER "dasd:"
@@ -57,6 +61,8 @@ static void dasd_device_tasklet(struct dasd_device *);
static void dasd_block_tasklet(struct dasd_block *);
static void do_kick_device(struct work_struct *);
static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
+static void dasd_device_timeout(unsigned long);
+static void dasd_block_timeout(unsigned long);
/*
* SECTION: Operations on the device structure.
@@ -99,6 +105,8 @@ struct dasd_device *dasd_alloc_device(void)
(unsigned long) device);
INIT_LIST_HEAD(&device->ccw_queue);
init_timer(&device->timer);
+ device->timer.function = dasd_device_timeout;
+ device->timer.data = (unsigned long) device;
INIT_WORK(&device->kick_work, do_kick_device);
device->state = DASD_STATE_NEW;
device->target = DASD_STATE_NEW;
@@ -138,6 +146,8 @@ struct dasd_block *dasd_alloc_block(void)
INIT_LIST_HEAD(&block->ccw_queue);
spin_lock_init(&block->queue_lock);
init_timer(&block->timer);
+ block->timer.function = dasd_block_timeout;
+ block->timer.data = (unsigned long) block;
return block;
}
@@ -215,7 +225,7 @@ static int dasd_state_known_to_basic(struct dasd_device *device)
return rc;
}
/* register 'device' debug area, used for all DBF_DEV_XXX calls */
- device->debug_area = debug_register(dev_name(&device->cdev->dev), 1, 1,
+ device->debug_area = debug_register(dev_name(&device->cdev->dev), 4, 1,
8 * sizeof(long));
debug_register_view(device->debug_area, &debug_sprintf_view);
debug_set_level(device->debug_area, DBF_WARNING);
@@ -756,7 +766,7 @@ static inline int dasd_check_cqr(struct dasd_ccw_req *cqr)
return -EINVAL;
device = cqr->startdev;
if (strncmp((char *) &cqr->magic, device->discipline->ebcname, 4)) {
- DEV_MESSAGE(KERN_WARNING, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
" dasd_ccw_req 0x%08x magic doesn't match"
" discipline 0x%08x",
cqr->magic,
@@ -776,6 +786,7 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
{
struct dasd_device *device;
int retries, rc;
+ char errorstring[ERRORLENGTH];
/* Check the cqr */
rc = dasd_check_cqr(cqr);
@@ -809,10 +820,10 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
"device busy, retry later");
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "line %d unknown RC=%d, please "
- "report to linux390@de.ibm.com",
- __LINE__, rc);
+ /* internal error 10 - unknown rc*/
+ snprintf(errorstring, ERRORLENGTH, "10 %d", rc);
+ dev_err(&device->cdev->dev, "An error occurred in the "
+ "DASD device driver, reason=%s\n", errorstring);
BUG();
break;
}
@@ -830,6 +841,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
{
struct dasd_device *device;
int rc;
+ char errorstring[ERRORLENGTH];
/* Check the cqr */
rc = dasd_check_cqr(cqr);
@@ -837,17 +849,21 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
return rc;
device = (struct dasd_device *) cqr->startdev;
if (cqr->retries < 0) {
- DEV_MESSAGE(KERN_DEBUG, device,
- "start_IO: request %p (%02x/%i) - no retry left.",
- cqr, cqr->status, cqr->retries);
+ dev_err(&device->cdev->dev, "start_IO run out of retries "
+ "and failed with request %s\n", cqr);
cqr->status = DASD_CQR_ERROR;
return -EIO;
}
cqr->startclk = get_clock();
cqr->starttime = jiffies;
cqr->retries--;
- rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
- cqr->lpm, 0);
+ if (cqr->cpmode == 1) {
+ rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
+ (long) cqr, cqr->lpm);
+ } else {
+ rc = ccw_device_start(device->cdev, cqr->cpaddr,
+ (long) cqr, cqr->lpm, 0);
+ }
switch (rc) {
case 0:
cqr->status = DASD_CQR_IN_IO;
@@ -856,11 +872,11 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr);
break;
case -EBUSY:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: device busy, retry later");
break;
case -ETIMEDOUT:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: request timeout, retry later");
break;
case -EACCES:
@@ -870,19 +886,24 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
* Do a retry with all available pathes.
*/
cqr->lpm = LPM_ANYPATH;
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: selected pathes gone,"
" retry on all pathes");
break;
case -ENODEV:
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ "start_IO: -ENODEV device gone, retry");
+ break;
case -EIO:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
- "start_IO: device gone, retry");
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ "start_IO: -EIO device gone, retry");
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "line %d unknown RC=%d, please report"
- " to linux390@de.ibm.com", __LINE__, rc);
+ /* internal error 11 - unknown rc */
+ snprintf(errorstring, ERRORLENGTH, "11 %d", rc);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
BUG();
break;
}
@@ -915,19 +936,10 @@ static void dasd_device_timeout(unsigned long ptr)
*/
void dasd_device_set_timer(struct dasd_device *device, int expires)
{
- if (expires == 0) {
- if (timer_pending(&device->timer))
- del_timer(&device->timer);
- return;
- }
- if (timer_pending(&device->timer)) {
- if (mod_timer(&device->timer, jiffies + expires))
- return;
- }
- device->timer.function = dasd_device_timeout;
- device->timer.data = (unsigned long) device;
- device->timer.expires = jiffies + expires;
- add_timer(&device->timer);
+ if (expires == 0)
+ del_timer(&device->timer);
+ else
+ mod_timer(&device->timer, jiffies + expires);
}
/*
@@ -935,8 +947,7 @@ void dasd_device_set_timer(struct dasd_device *device, int expires)
*/
void dasd_device_clear_timer(struct dasd_device *device)
{
- if (timer_pending(&device->timer))
- del_timer(&device->timer);
+ del_timer(&device->timer);
}
static void dasd_handle_killed_request(struct ccw_device *cdev,
@@ -1000,11 +1011,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
case -EIO:
break;
case -ETIMEDOUT:
- printk(KERN_WARNING"%s(%s): request timed out\n",
+ DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
__func__, dev_name(&cdev->dev));
break;
default:
- printk(KERN_WARNING"%s(%s): unknown error %ld\n",
+ DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
__func__, dev_name(&cdev->dev), PTR_ERR(irb));
}
dasd_handle_killed_request(cdev, intparm);
@@ -1013,15 +1024,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
now = get_clock();
- DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
- dev_name(&cdev->dev), ((irb->scsw.cmd.cstat << 8) |
- irb->scsw.cmd.dstat), (unsigned int) intparm);
-
/* check for unsolicited interrupts */
cqr = (struct dasd_ccw_req *) intparm;
- if (!cqr || ((irb->scsw.cmd.cc == 1) &&
- (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
- (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
+ if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
+ (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+ (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) {
if (cqr && cqr->status == DASD_CQR_IN_IO)
cqr->status = DASD_CQR_QUEUED;
device = dasd_device_from_cdev_locked(cdev);
@@ -1044,7 +1051,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
/* Check for clear pending */
if (cqr->status == DASD_CQR_CLEAR_PENDING &&
- irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
+ scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
cqr->status = DASD_CQR_CLEARED;
dasd_device_clear_timer(device);
wake_up(&dasd_flush_wq);
@@ -1052,19 +1059,18 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
return;
}
- /* check status - the request might have been killed by dyn detach */
+ /* check status - the request might have been killed by dyn detach */
if (cqr->status != DASD_CQR_IN_IO) {
MESSAGE(KERN_DEBUG,
"invalid status: bus_id %s, status %02x",
dev_name(&cdev->dev), cqr->status);
return;
}
- DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
- ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
+
next = NULL;
expires = 0;
- if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
- irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
+ if (scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
+ scsw_cstat(&irb->scsw) == 0) {
/* request was completed successfully */
cqr->status = DASD_CQR_SUCCESS;
cqr->stopclk = now;
@@ -1075,18 +1081,23 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
}
} else { /* error */
memcpy(&cqr->irb, irb, sizeof(struct irb));
+ /* log sense for every failed I/O to s390 debugfeature */
+ dasd_log_sense_dbf(cqr, irb);
if (device->features & DASD_FEATURE_ERPLOG) {
dasd_log_sense(cqr, irb);
}
+
/*
* If we don't want complex ERP for this request, then just
* reset this and retry it in the fastpath
*/
if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
cqr->retries > 0) {
- DEV_MESSAGE(KERN_DEBUG, device,
- "default ERP in fastpath (%i retries left)",
- cqr->retries);
+ if (cqr->lpm == LPM_ANYPATH)
+ DBF_DEV_EVENT(DBF_DEBUG, device,
+ "default ERP in fastpath "
+ "(%i retries left)",
+ cqr->retries);
cqr->lpm = LPM_ANYPATH;
cqr->status = DASD_CQR_QUEUED;
next = cqr;
@@ -1097,10 +1108,6 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
(!device->stopped)) {
if (device->discipline->start_IO(next) == 0)
expires = next->expires;
- else
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Interrupt fastpath "
- "failed!");
}
if (expires != 0)
dasd_device_set_timer(device, expires);
@@ -1173,6 +1180,7 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
struct dasd_block *block;
void (*callback)(struct dasd_ccw_req *, void *data);
void *callback_data;
+ char errorstring[ERRORLENGTH];
list_for_each_safe(l, n, final_queue) {
cqr = list_entry(l, struct dasd_ccw_req, devlist);
@@ -1193,10 +1201,11 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
cqr->status = DASD_CQR_TERMINATED;
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "wrong cqr status in __dasd_process_final_queue "
- "for cqr %p, status %x",
- cqr, cqr->status);
+ /* internal error 12 - wrong cqr status*/
+ snprintf(errorstring, ERRORLENGTH, "12 %p %x02", cqr, cqr->status);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
BUG();
}
if (cqr->callback != NULL)
@@ -1221,18 +1230,17 @@ static void __dasd_device_check_expire(struct dasd_device *device)
(time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
if (device->discipline->term_IO(cqr) != 0) {
/* Hmpf, try again in 5 sec */
- DEV_MESSAGE(KERN_ERR, device,
- "internal error - timeout (%is) expired "
- "for cqr %p, termination failed, "
- "retrying in 5s",
- (cqr->expires/HZ), cqr);
+ dev_err(&device->cdev->dev,
+ "cqr %p timed out (%is) but cannot be "
+ "ended, retrying in 5 s\n",
+ (cqr->expires/HZ), cqr);
cqr->expires += 5*HZ;
dasd_device_set_timer(device, 5*HZ);
} else {
- DEV_MESSAGE(KERN_ERR, device,
- "internal error - timeout (%is) expired "
- "for cqr %p (%i retries left)",
- (cqr->expires/HZ), cqr, cqr->retries);
+ dev_err(&device->cdev->dev,
+ "cqr %p timed out (%is), %i retries "
+ "remaining\n", (cqr->expires/HZ),
+ cqr, cqr->retries);
}
}
}
@@ -1294,10 +1302,9 @@ int dasd_flush_device_queue(struct dasd_device *device)
rc = device->discipline->term_IO(cqr);
if (rc) {
/* unable to terminate requeust */
- DEV_MESSAGE(KERN_ERR, device,
- "dasd flush ccw_queue is unable "
- " to terminate request %p",
- cqr);
+ dev_err(&device->cdev->dev,
+ "Flushing the DASD request queue "
+ "failed for request %p\n", cqr);
/* stop flush processing */
goto finished;
}
@@ -1541,10 +1548,9 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
/* request in IO - terminate IO and release again */
rc = device->discipline->term_IO(cqr);
if (rc) {
- DEV_MESSAGE(KERN_ERR, device,
- "dasd_cancel_req is unable "
- " to terminate request %p, rc = %d",
- cqr, rc);
+ dev_err(&device->cdev->dev,
+ "Cancelling request %p failed with rc=%d\n",
+ cqr, rc);
} else {
cqr->stopclk = get_clock();
rc = 1;
@@ -1586,19 +1592,10 @@ static void dasd_block_timeout(unsigned long ptr)
*/
void dasd_block_set_timer(struct dasd_block *block, int expires)
{
- if (expires == 0) {
- if (timer_pending(&block->timer))
- del_timer(&block->timer);
- return;
- }
- if (timer_pending(&block->timer)) {
- if (mod_timer(&block->timer, jiffies + expires))
- return;
- }
- block->timer.function = dasd_block_timeout;
- block->timer.data = (unsigned long) block;
- block->timer.expires = jiffies + expires;
- add_timer(&block->timer);
+ if (expires == 0)
+ del_timer(&block->timer);
+ else
+ mod_timer(&block->timer, jiffies + expires);
}
/*
@@ -1606,8 +1603,7 @@ void dasd_block_set_timer(struct dasd_block *block, int expires)
*/
void dasd_block_clear_timer(struct dasd_block *block)
{
- if (timer_pending(&block->timer))
- del_timer(&block->timer);
+ del_timer(&block->timer);
}
/*
@@ -1631,7 +1627,7 @@ static inline void __dasd_block_process_erp(struct dasd_block *block,
if (cqr->status == DASD_CQR_DONE)
DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful");
else
- DEV_MESSAGE(KERN_ERR, device, "%s", "ERP unsuccessful");
+ dev_err(&device->cdev->dev, "ERP failed for the DASD\n");
erp_fn = device->discipline->erp_postaction(cqr);
erp_fn(cqr);
}
@@ -2005,8 +2001,11 @@ static void dasd_setup_queue(struct dasd_block *block)
blk_queue_max_sectors(block->request_queue, max);
blk_queue_max_phys_segments(block->request_queue, -1L);
blk_queue_max_hw_segments(block->request_queue, -1L);
- blk_queue_max_segment_size(block->request_queue, -1L);
- blk_queue_segment_boundary(block->request_queue, -1L);
+ /* with page sized segments we can translate each segement into
+ * one idaw/tidaw
+ */
+ blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
+ blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL);
}
@@ -2057,8 +2056,9 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
}
if (dasd_probeonly) {
- DEV_MESSAGE(KERN_INFO, base, "%s",
- "No access to device due to probeonly mode");
+ dev_info(&base->cdev->dev,
+ "Accessing the DASD failed because it is in "
+ "probeonly mode\n");
rc = -EPERM;
goto out;
}
@@ -2115,7 +2115,8 @@ dasd_device_operations = {
.owner = THIS_MODULE,
.open = dasd_open,
.release = dasd_release,
- .locked_ioctl = dasd_ioctl,
+ .ioctl = dasd_ioctl,
+ .compat_ioctl = dasd_ioctl,
.getgeo = dasd_getgeo,
};
@@ -2157,14 +2158,14 @@ int dasd_generic_probe(struct ccw_device *cdev,
ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_generic_probe: could not set ccw-device options "
"for %s\n", dev_name(&cdev->dev));
return ret;
}
ret = dasd_add_sysfs_files(cdev);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_generic_probe: could not add sysfs entries "
"for %s\n", dev_name(&cdev->dev));
return ret;
@@ -2180,9 +2181,7 @@ int dasd_generic_probe(struct ccw_device *cdev,
(dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
ret = ccw_device_set_online(cdev);
if (ret)
- printk(KERN_WARNING
- "dasd_generic_probe: could not initially "
- "online ccw-device %s; return code: %d\n",
+ pr_warning("%s: Setting the DASD online failed with rc=%d\n",
dev_name(&cdev->dev), ret);
return 0;
}
@@ -2246,10 +2245,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
discipline = base_discipline;
if (device->features & DASD_FEATURE_USEDIAG) {
if (!dasd_diag_discipline_pointer) {
- printk (KERN_WARNING
- "dasd_generic couldn't online device %s "
- "- discipline DIAG not available\n",
- dev_name(&cdev->dev));
+ pr_warning("%s Setting the DASD online failed because "
+ "of missing DIAG discipline\n",
+ dev_name(&cdev->dev));
dasd_delete_device(device);
return -ENODEV;
}
@@ -2270,10 +2268,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
/* check_device will allocate block device if necessary */
rc = discipline->check_device(device);
if (rc) {
- printk (KERN_WARNING
- "dasd_generic couldn't online device %s "
- "with discipline %s rc=%i\n",
- dev_name(&cdev->dev), discipline->name, rc);
+ pr_warning("%s Setting the DASD online with discipline %s "
+ "failed with rc=%i\n",
+ dev_name(&cdev->dev), discipline->name, rc);
module_put(discipline->owner);
module_put(base_discipline->owner);
dasd_delete_device(device);
@@ -2282,9 +2279,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
dasd_set_target_state(device, DASD_STATE_ONLINE);
if (device->state <= DASD_STATE_KNOWN) {
- printk (KERN_WARNING
- "dasd_generic discipline not found for %s\n",
- dev_name(&cdev->dev));
+ pr_warning("%s Setting the DASD online failed because of a "
+ "missing discipline\n", dev_name(&cdev->dev));
rc = -ENODEV;
dasd_set_target_state(device, DASD_STATE_NEW);
if (device->block)
@@ -2328,13 +2324,13 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
open_count = atomic_read(&device->block->open_count);
if (open_count > max_count) {
if (open_count > 0)
- printk(KERN_WARNING "Can't offline dasd "
- "device with open count = %i.\n",
- open_count);
+ pr_warning("%s: The DASD cannot be set offline "
+ "with open count %i\n",
+ dev_name(&cdev->dev), open_count);
else
- printk(KERN_WARNING "%s",
- "Can't offline dasd device due "
- "to internal use\n");
+ pr_warning("%s: The DASD cannot be set offline "
+ "while it is in use\n",
+ dev_name(&cdev->dev));
clear_bit(DASD_FLAG_OFFLINE, &device->flags);
dasd_put_device(device);
return -EBUSY;
@@ -2407,8 +2403,10 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate RDC request");
+ /* internal error 13 - Allocating the RDC request failed*/
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "13");
return cqr;
}
@@ -2445,6 +2443,40 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
}
EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars);
+/*
+ * In command mode and transport mode we need to look for sense
+ * data in different places. The sense data itself is allways
+ * an array of 32 bytes, so we can unify the sense data access
+ * for both modes.
+ */
+char *dasd_get_sense(struct irb *irb)
+{
+ struct tsb *tsb = NULL;
+ char *sense = NULL;
+
+ if (scsw_is_tm(&irb->scsw) && (irb->scsw.tm.fcxs == 0x01)) {
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb((struct tcw *)(unsigned long)
+ irb->scsw.tm.tcw);
+ if (tsb && tsb->length == 64 && tsb->flags)
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ sense = tsb->tsa.iostat.sense;
+ break;
+ case 2: /* tsa_ddpc */
+ sense = tsb->tsa.ddpc.sense;
+ break;
+ default:
+ /* currently we don't use interrogate data */
+ break;
+ }
+ } else if (irb->esw.esw0.erw.cons) {
+ sense = irb->ecw;
+ }
+ return sense;
+}
+EXPORT_SYMBOL_GPL(dasd_get_sense);
+
static int __init dasd_init(void)
{
int rc;
@@ -2486,7 +2518,7 @@ static int __init dasd_init(void)
return 0;
failed:
- MESSAGE(KERN_INFO, "%s", "initialization not performed due to errors");
+ pr_info("The DASD device driver could not be initialized\n");
dasd_exit();
return rc;
}
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index d82aad5224f0..27991b692056 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -7,6 +7,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/timer.h>
#include <linux/slab.h>
#include <asm/idals.h>
@@ -75,7 +77,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
struct dasd_device *device = erp->startdev;
unsigned long flags;
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"blocking request queue for %is", expires/HZ);
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
@@ -114,9 +116,9 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ dev_err(&device->cdev->dev,
"is offline or not installed - "
- "INTERVENTION REQUIRED!!");
+ "INTERVENTION REQUIRED!!\n");
dasd_3990_erp_block_queue(erp, 60*HZ);
}
@@ -158,7 +160,7 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
if ((erp->lpm & opm) != 0x00) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"try alternate lpm=%x (lpum=%x / opm=%x)",
erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm);
@@ -166,10 +168,9 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
erp->status = DASD_CQR_FILLED;
erp->retries = 10;
} else {
- DEV_MESSAGE(KERN_ERR, device,
- "No alternate channel path left (lpum=%x / "
- "opm=%x) -> permanent error",
- erp->irb.esw.esw0.sublog.lpum, opm);
+ dev_err(&device->cdev->dev,
+ "The DASD cannot be reached on any path (lpum=%x"
+ "/opm=%x)\n", erp->irb.esw.esw0.sublog.lpum, opm);
/* post request with permanent error */
erp->status = DASD_CQR_FAILED;
@@ -204,8 +205,8 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
sizeof(struct DCTL_data),
device);
if (IS_ERR(dctl_cqr)) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Unable to allocate DCTL-CQR");
+ dev_err(&device->cdev->dev,
+ "Unable to allocate DCTL-CQR\n");
erp->status = DASD_CQR_FAILED;
return erp;
}
@@ -294,7 +295,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
/* interrupt (this enables easier enqueing of the cqr) */
if (erp->function != dasd_3990_erp_action_4) {
- DEV_MESSAGE(KERN_INFO, device, "%s",
+ DBF_DEV_EVENT(DBF_INFO, device, "%s",
"dasd_3990_erp_action_4: first time retry");
erp->retries = 256;
@@ -303,7 +304,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
} else {
if (sense && (sense[25] == 0x1D)) { /* state change pending */
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"waiting for state change pending "
"interrupt, %d retries left",
erp->retries);
@@ -311,15 +312,14 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
dasd_3990_erp_block_queue(erp, 30*HZ);
} else if (sense && (sense[25] == 0x1E)) { /* busy */
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"busy - redriving request later, "
"%d retries left",
erp->retries);
dasd_3990_erp_block_queue(erp, HZ);
} else {
-
/* no state change pending - retry */
- DEV_MESSAGE (KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"redriving request immediately, "
"%d retries left",
erp->retries);
@@ -384,6 +384,7 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
struct dasd_device *device = erp->startdev;
char msg_format = (sense[7] & 0xF0);
char msg_no = (sense[7] & 0x0F);
+ char errorstring[ERRORLENGTH];
switch (msg_format) {
case 0x00: /* Format 0 - Program or System Checks */
@@ -394,95 +395,97 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Command");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Command\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Command "
- "Sequence");
+ "Sequence\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - CCW Count less than "
- "required");
+ "required\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Parameter");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Parameter\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Diagnostic of Sepecial"
- " Command Violates File Mask");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Diagnostic of Special"
+ " Command Violates File Mask\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel Returned with "
- "Incorrect retry CCW");
+ "Incorrect retry CCW\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reset Notification");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reset Notification\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Storage Path Restart");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Storage Path Restart\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel requested "
- "... %02x", sense[8]);
+ "... %02x\n", sense[8]);
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Defective/"
- "Alternate Track Pointer");
+ "Alternate Track Pointer\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - DPS Installation "
- "Check");
+ "Check\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Command Invalid on "
- "Secondary Address");
+ "Secondary Address\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Status Not As "
- "Required: reason %02x", sense[8]);
+ "Required: reason %02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reseved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
} else {
switch (msg_no) {
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Device Error Source");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Device Error "
+ "Source\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Device Fenced - "
- "device = %02x", sense[4]);
+ "device = %02x\n", sense[4]);
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Data Pinned for "
- "Device");
+ "Device\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
}
break;
@@ -492,348 +495,352 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device Status 1 not as "
- "expected");
+ "expected\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Index missing");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Index missing\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Interruption cannot be reset");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Interruption cannot be "
+ "reset\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device did not respond to "
- "selection");
+ "selection\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device check-2 error or Set "
- "Sector is not complete");
+ "Sector is not complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Head address does not "
- "compare");
+ "compare\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device status 1 not valid");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device status 1 not valid\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device not ready");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device not ready\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Track physical address did "
- "not compare");
+ "not compare\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Missing device address bit");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Missing device address bit\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Drive motor switch is off");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Drive motor switch is off\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Seek incomplete");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Seek incomplete\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Offset active cannot be "
- "reset");
+ "reset\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Reserved\n");
}
break;
case 0x20: /* Format 2 - 3990 Equipment Checks */
switch (msg_no) {
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - 3990 check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - 3990 check-2 error\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Support facility errors");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Support facility errors\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
- "FORMAT 2 - Microcode detected error %02x",
- sense[8]);
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Microcode detected error "
+ "%02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Reserved\n");
}
break;
case 0x30: /* Format 3 - 3990 Control Checks */
switch (msg_no) {
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Allegiance terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Allegiance terminated\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Reserved\n");
}
break;
case 0x40: /* Format 4 - Data Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Home address area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Home address area error\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Count area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Count area error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Key area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Key area error\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Data area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Data area error\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home address "
- "area");
+ "area\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in count address "
- "area");
+ "area\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in key area\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in data area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Home address area error; "
- "offset active");
+ "offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Count area error; offset "
- "active");
+ "active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Key area error; offset "
- "active");
+ "active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Data area error; "
- "offset active");
+ "offset active\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in count "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Reserved\n");
}
break;
case 0x50: /* Format 5 - Data Check with displacement information */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area");
+ "home address area\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the count area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the count "
+ "area\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the key area\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the data "
+ "area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area; offset active");
+ "home address area; offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the count area; "
- "offset active");
+ "offset active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Reserved\n");
}
break;
case 0x60: /* Format 6 - Usage Statistics/Overrun Errors */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel A");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel A\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel B");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel B\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel C");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel C\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel D");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel D\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel E");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel E\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel F");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel F\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel G");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel G\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel H");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel H\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Reserved\n");
}
break;
case 0x70: /* Format 7 - Device Connection Control Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC initiated by a connection "
- "check alert");
+ "check alert\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 sequence not "
- "successful");
+ "successful\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 and RCC 2 sequences not "
- "successful");
+ "successful\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in during "
- "selection sequence");
+ "selection sequence\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - extra RCC required");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - extra RCC required\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid DCC selection "
- "response or timeout");
+ "response or timeout\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer complete");
+ "transfer complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer incomplete");
+ "transfer incomplete\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "immediate command sequence");
+ "immediate command sequence\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "extended command sequence");
+ "extended command sequence\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - 3990 microcode time out when "
- "stopping selection");
+ "stopping selection\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - No response to selection "
- "after a poll interruption");
+ "after a poll interruption\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Permanent path error (DASD "
- "controller not available)");
+ "controller not available)\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - DASD controller not available"
- " on disconnected command chain");
+ " on disconnected command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - Reserved\n");
}
break;
@@ -841,52 +848,52 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
switch (msg_no) {
case 0x00: /* No Message */
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Error correction code "
- "hardware fault");
+ "hardware fault\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Unexpected end operation "
- "response code");
+ "response code\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count not zero");
+ "count not zero\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count zero");
+ "count zero\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DPS checks after a system "
- "reset or selective reset");
+ "reset or selective reset\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - DPS cannot be filled");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - DPS cannot be filled\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Short busy time-out during "
- "device selection");
+ "device selection\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DASD controller failed to "
- "set or reset the long busy latch");
+ "set or reset the long busy latch\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - No interruption from device "
- "during a command chain");
+ "during a command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - Reserved\n");
}
break;
@@ -895,97 +902,100 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00:
break; /* No Message */
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Device check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Device check-2 error\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Head address did not compare");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Head address did not "
+ "compare\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Track physical address did "
- "not compare while oriented");
+ "not compare while oriented\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Reserved\n");
}
break;
case 0xF0: /* Format F - Cache Storage Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Operation Terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Operation Terminated\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem Processing Error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem Processing Error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache or nonvolatile storage "
- "equipment failure");
+ "equipment failure\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching terminated\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache fast write access not "
- "authorized");
+ "authorized\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Track format incorrect");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Track format incorrect\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching reinitiated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching reinitiated\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Nonvolatile storage "
- "terminated");
+ "terminated\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Volume is suspended duplex");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Volume is suspended duplex\n");
/* call extended error reporting (EER) */
dasd_eer_write(device, erp->refers,
DASD_EER_PPRCSUSPEND);
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem status connot be "
- "determined");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem status cannot be "
+ "determined\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Caching status reset to "
- "default");
+ "default\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - DASD Fast Write inhibited");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - DASD Fast Write inhibited\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT D - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT D - Reserved\n");
}
break;
- default: /* unknown message format - should not happen */
- DEV_MESSAGE (KERN_WARNING, device,
- "unknown message format %02x",
- msg_format);
+ default: /* unknown message format - should not happen
+ internal error 03 - unknown message format */
+ snprintf(errorstring, ERRORLENGTH, "03 %x02", msg_format);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
break;
} /* end switch message format */
@@ -1015,7 +1025,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
/* env data present (ACTION 10 - retry should work) */
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Command Reject - environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1023,9 +1033,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
erp->retries = 5;
} else {
- /* fatal error - set status to FAILED */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Command Reject - Fatal error");
+ /* fatal error - set status to FAILED
+ internal error 09 - Command Reject */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "09");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
@@ -1061,7 +1072,7 @@ dasd_3990_erp_bus_out(struct dasd_ccw_req * erp)
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"bus out parity error or BOPC requested by "
"channel");
@@ -1093,21 +1104,19 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_equip_check;
if (sense[1] & SNS1_WRITE_INHIBITED) {
+ dev_info(&device->cdev->dev,
+ "Write inhibited path encountered\n");
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Write inhibited path encountered");
-
- /* vary path offline */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Path should be varied off-line. "
- "This is not implemented yet \n - please report "
- "to linux390@de.ibm.com");
+ /* vary path offline
+ internal error 04 - Path should be varied off-line.*/
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "04");
erp = dasd_3990_erp_action_1(erp);
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - " "environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1116,7 +1125,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - retry exhausted or "
"undesirable");
@@ -1125,7 +1134,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
} else {
/* all other equipment checks - Action 5 */
/* rest is done when retries == 0 */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment check or processing error");
erp = dasd_3990_erp_action_5(erp);
@@ -1156,9 +1165,9 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
if (sense[2] & SNS2_CORRECTABLE) { /* correctable data check */
/* issue message that the data has been corrected */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic("No way to inform application about the possibly "
@@ -1166,7 +1175,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check recovered secondary "
"addr of duplex pair");
@@ -1174,7 +1183,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with internal "
"retry exhausted");
@@ -1182,7 +1191,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else {
/* all other data checks */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with retry count "
"exhausted...");
@@ -1212,7 +1221,7 @@ dasd_3990_erp_overrun(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_overrun;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Overrun - service overrun or overrun"
" error requested by channel");
@@ -1243,7 +1252,7 @@ dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Track format error when destaging or "
"staging data");
@@ -1252,8 +1261,10 @@ dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_action_4(erp, sense);
} else {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Invalid Track Format - Fatal error");
+ /* internal error 06 - The track format is not valid*/
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "06");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
@@ -1279,8 +1290,8 @@ dasd_3990_erp_EOC(struct dasd_ccw_req * default_erp, char *sense)
struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "End-of-Cylinder - must never happen");
+ dev_err(&device->cdev->dev,
+ "The cylinder data for accessing the DASD is inconsistent\n");
/* implement action 7 - BUG */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1306,7 +1317,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_env_data;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Environmental data present");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1339,8 +1350,8 @@ dasd_3990_erp_no_rec(struct dasd_ccw_req * default_erp, char *sense)
struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "No Record Found - Fatal error ");
+ dev_err(&device->cdev->dev,
+ "The specified record was not found\n");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1365,7 +1376,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
struct dasd_device *device = erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected");
+ dev_err(&device->cdev->dev, "Accessing the DASD failed because of "
+ "a hardware error\n");
return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
@@ -1394,7 +1406,7 @@ static struct dasd_ccw_req *dasd_3990_erp_inspect_alias(
if (cqr->block &&
(cqr->block->base != cqr->startdev)) {
if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
- DEV_MESSAGE(KERN_ERR, cqr->startdev,
+ DBF_DEV_EVENT(DBF_ERR, cqr->startdev,
"ERP on alias device for request %p,"
" recover on base device %s", cqr,
dev_name(&cqr->block->base->cdev->dev));
@@ -1511,7 +1523,7 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense)
erp->retries = 256;
erp->function = dasd_3990_erp_action_10_32;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Perform logging requested");
return erp;
@@ -1549,7 +1561,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
char *LO_data; /* LO_eckd_data_t */
struct ccw1 *ccw, *oldccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition");
default_erp->function = dasd_3990_erp_action_1B_32;
@@ -1561,10 +1573,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B is not defined"
+ " in transport mode - just retry");
+ return default_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
return default_erp;
@@ -1575,8 +1593,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
cpa = default_erp->refers->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Unable to determine address of the CCW "
"to be restarted");
@@ -1590,7 +1607,9 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
sizeof(struct LO_eckd_data), device);
if (IS_ERR(erp)) {
- DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");
+ /* internal error 01 - Unable to allocate ERP */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "01");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
@@ -1599,7 +1618,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
oldccw = cqr->cpaddr;
if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
PFX_data = cqr->data;
- memcpy(DE_data, &PFX_data->define_extend,
+ memcpy(DE_data, &PFX_data->define_extent,
sizeof(struct DE_eckd_data));
} else
memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
@@ -1608,10 +1627,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
@@ -1701,7 +1717,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
char *LO_data; /* struct LO_eckd_data */
struct ccw1 *ccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition"
" - follow on");
@@ -1712,10 +1728,16 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B, update,"
+ " in transport mode - just retry");
+ return previous_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
previous_erp->status = DASD_CQR_FILLED;
@@ -1728,10 +1750,10 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
cpa = previous_erp->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Unable to determine address of the CCW "
- "to be restarted");
+ /* internal error 02 -
+ Unable to determine address of the CCW to be restarted */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "02");
previous_erp->status = DASD_CQR_FAILED;
@@ -1744,10 +1766,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not happen */
previous_erp->status = DASD_CQR_FAILED;
return previous_erp;
@@ -1935,14 +1954,13 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense)
if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) {
- /* set to suspended duplex state then restart */
+ /* set to suspended duplex state then restart
+ internal error 05 - Set device to suspended duplex state
+ should be done */
struct dasd_device *device = erp->startdev;
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Set device to suspended duplex state should be "
- "done!\n"
- "This is not implemented yet (for compound ERP)"
- " - please report to linux390@de.ibm.com");
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "05");
}
@@ -2012,15 +2030,14 @@ dasd_3990_erp_handle_sim(struct dasd_device *device, char *sense)
{
/* print message according to log or message to operator mode */
if ((sense[24] & DASD_SIM_MSG_TO_OP) || (sense[1] & 0x10)) {
-
/* print SIM SRC from RefCode */
- DEV_MESSAGE(KERN_ERR, device, "SIM - SRC: "
- "%02x%02x%02x%02x", sense[22],
+ dev_err(&device->cdev->dev, "SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
sense[23], sense[11], sense[12]);
} else if (sense[24] & DASD_SIM_LOG) {
/* print SIM SRC Refcode */
- DEV_MESSAGE(KERN_WARNING, device, "SIM - SRC: "
- "%02x%02x%02x%02x", sense[22],
+ dev_warn(&device->cdev->dev, "log SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
sense[23], sense[11], sense[12]);
}
}
@@ -2063,14 +2080,14 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
switch (sense[25]) {
case 0x00: /* success - use default ERP for retries */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"ERP called for successful request"
" - just retry");
break;
case 0x01: /* fatal error */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Retry not recommended - Fatal error");
+ dev_err(&device->cdev->dev,
+ "ERP failed for the DASD\n");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2080,13 +2097,10 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_int_req(erp);
break;
- case 0x0F: /* length mismatch during update write command */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "update write command error - should not "
- "happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x0F: /* length mismatch during update write command
+ internal error 08 - update write command error*/
+ dev_err(&device->cdev->dev, "An error occurred in the "
+ "DASD device driver, reason=%s\n", "08");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2095,13 +2109,12 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_action_10_32(erp, sense);
break;
- case 0x15: /* next track outside defined extend */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "next track outside defined extend - "
- "should not happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x15: /* next track outside defined extend
+ internal error 07 - The next track is not
+ within the defined storage extent */
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "07");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2112,9 +2125,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1C: /* invalid data */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic
@@ -2123,7 +2136,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1D: /* state-change pending */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"A State change pending condition exists "
"for the subsystem or device");
@@ -2131,7 +2144,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1E: /* busy */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Busy condition exists "
"for the subsystem or device");
erp = dasd_3990_erp_action_4(erp, sense);
@@ -2171,9 +2184,9 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
{
struct dasd_device *device = erp->startdev;
- if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
+ if (scsw_cstat(&erp->refers->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK
| SCHN_STAT_CHN_CTRL_CHK)) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"channel or interface control check");
erp = dasd_3990_erp_action_4(erp, NULL);
}
@@ -2193,21 +2206,23 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
* erp_new contens was possibly modified
*/
static struct dasd_ccw_req *
-dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
+dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
{
struct dasd_ccw_req *erp_new = NULL;
- /* sense data are located in the refers record of the */
- /* already set up new ERP ! */
- char *sense = erp->refers->irb.ecw;
+ char *sense;
/* if this problem occured on an alias retry on base */
erp_new = dasd_3990_erp_inspect_alias(erp);
if (erp_new)
return erp_new;
- /* check if no concurrent sens is available */
- if (!erp->refers->irb.esw.esw0.erw.cons)
+ /* sense data are located in the refers record of the
+ * already set up new ERP !
+ * check if concurrent sens is available
+ */
+ sense = dasd_get_sense(&erp->refers->irb);
+ if (!sense)
erp_new = dasd_3990_erp_control_check(erp);
/* distinguish between 24 and 32 byte sense data */
else if (sense[27] & DASD_SENSE_BIT_0) {
@@ -2231,7 +2246,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
* DESCRIPTION
* This funtion adds an additional request block (ERP) to the head of
* the given cqr (or erp).
- * This erp is initialized as an default erp (retry TIC)
+ * For a command mode cqr the erp is initialized as an default erp
+ * (retry TIC).
+ * For transport mode we make a copy of the original TCW (points to
+ * the original TCCB, TIDALs, etc.) but give it a fresh
+ * TSB so the original sense data will not be changed.
*
* PARAMETER
* cqr head of the current ERP-chain (or single cqr if
@@ -2239,25 +2258,35 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
* RETURN VALUES
* erp pointer to new ERP-chain head
*/
-static struct dasd_ccw_req *
-dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
+static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
{
struct dasd_device *device = cqr->startdev;
struct ccw1 *ccw;
-
- /* allocate additional request block */
struct dasd_ccw_req *erp;
+ int cplength, datasize;
+ struct tcw *tcw;
+ struct tsb *tsb;
+
+ if (cqr->cpmode == 1) {
+ cplength = 0;
+ datasize = sizeof(struct tcw) + sizeof(struct tsb);
+ } else {
+ cplength = 2;
+ datasize = 0;
+ }
- erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device);
+ /* allocate additional request block */
+ erp = dasd_alloc_erp_request((char *) &cqr->magic,
+ cplength, datasize, device);
if (IS_ERR(erp)) {
if (cqr->retries <= 0) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"Unable to allocate ERP request");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock ();
} else {
- DEV_MESSAGE (KERN_ERR, device,
+ DBF_DEV_EVENT(DBF_ERR, device,
"Unable to allocate ERP request "
"(%i retries left)",
cqr->retries);
@@ -2266,13 +2295,24 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
return cqr;
}
- /* initialize request with default TIC to current ERP/CQR */
- ccw = erp->cpaddr;
- ccw->cmd_code = CCW_CMD_NOOP;
- ccw->flags = CCW_FLAG_CC;
- ccw++;
- ccw->cmd_code = CCW_CMD_TIC;
- ccw->cda = (long)(cqr->cpaddr);
+ if (cqr->cpmode == 1) {
+ /* make a shallow copy of the original tcw but set new tsb */
+ erp->cpmode = 1;
+ erp->cpaddr = erp->data;
+ tcw = erp->data;
+ tsb = (struct tsb *) &tcw[1];
+ *tcw = *((struct tcw *)cqr->cpaddr);
+ tcw->tsb = (long)tsb;
+ } else {
+ /* initialize request with default TIC to current ERP/CQR */
+ ccw = erp->cpaddr;
+ ccw->cmd_code = CCW_CMD_NOOP;
+ ccw->flags = CCW_FLAG_CC;
+ ccw++;
+ ccw->cmd_code = CCW_CMD_TIC;
+ ccw->cda = (long)(cqr->cpaddr);
+ }
+
erp->function = dasd_3990_erp_add_erp;
erp->refers = cqr;
erp->startdev = device;
@@ -2282,7 +2322,6 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
erp->expires = 0;
erp->retries = 256;
erp->buildclk = get_clock();
-
erp->status = DASD_CQR_FILLED;
return erp;
@@ -2340,28 +2379,33 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
* match 'boolean' for match found
* returns 1 if match found, otherwise 0.
*/
-static int
-dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
+static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1,
+ struct dasd_ccw_req *cqr2)
{
+ char *sense1, *sense2;
if (cqr1->startdev != cqr2->startdev)
return 0;
- if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
- return 0;
+ sense1 = dasd_get_sense(&cqr1->irb);
+ sense2 = dasd_get_sense(&cqr2->irb);
- if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
- (cqr2->irb.esw.esw0.erw.cons == 0)) {
- if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
- SCHN_STAT_CHN_CTRL_CHK)) ==
- (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
- SCHN_STAT_CHN_CTRL_CHK)))
+ /* one request has sense data, the other not -> no match, return 0 */
+ if (!sense1 != !sense2)
+ return 0;
+ /* no sense data in both cases -> check cstat for IFCC */
+ if (!sense1 && !sense2) {
+ if ((scsw_cstat(&cqr1->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)) ==
+ (scsw_cstat(&cqr2->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)))
return 1; /* match with ifcc*/
}
/* check sense data; byte 0-2,25,27 */
- if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
- (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
- (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) {
+ if (!(sense1 && sense2 &&
+ (memcmp(sense1, sense2, 3) == 0) &&
+ (sense1[27] == sense2[27]) &&
+ (sense1[25] == sense2[25]))) {
return 0; /* sense doesn't match */
}
@@ -2434,7 +2478,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
{
struct dasd_device *device = erp->startdev;
- char *sense = erp->irb.ecw;
+ char *sense = dasd_get_sense(&erp->irb);
/* check for 24 byte sense ERP */
if ((erp->function == dasd_3990_erp_bus_out) ||
@@ -2449,7 +2493,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
/* prepare erp for retry on different channel path */
erp = dasd_3990_erp_action_1(erp);
- if (!(sense[2] & DASD_SENSE_BIT_0)) {
+ if (sense && !(sense[2] & DASD_SENSE_BIT_0)) {
/* issue a Diagnostic Control command with an
* Inhibit Write subcommand */
@@ -2471,7 +2515,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
break;
}
default:
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"invalid subcommand modifier 0x%x "
"for Diagnostic Control Command",
sense[25]);
@@ -2479,19 +2523,21 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
}
/* check for 32 byte sense ERP */
- } else if ((erp->function == dasd_3990_erp_compound_retry) ||
- (erp->function == dasd_3990_erp_compound_path) ||
- (erp->function == dasd_3990_erp_compound_code) ||
- (erp->function == dasd_3990_erp_compound_config)) {
+ } else if (sense &&
+ ((erp->function == dasd_3990_erp_compound_retry) ||
+ (erp->function == dasd_3990_erp_compound_path) ||
+ (erp->function == dasd_3990_erp_compound_code) ||
+ (erp->function == dasd_3990_erp_compound_config))) {
erp = dasd_3990_erp_compound(erp, sense);
} else {
- /* No retry left and no additional special handling */
- /*necessary */
- DEV_MESSAGE(KERN_ERR, device,
- "no retries left for erp %p - "
- "set status to FAILED", erp);
+ /*
+ * No retry left and no additional special handling
+ * necessary
+ */
+ dev_err(&device->cdev->dev,
+ "ERP %p has run out of retries and failed\n", erp);
erp->status = DASD_CQR_FAILED;
}
@@ -2548,24 +2594,25 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,
if (erp->retries > 0) {
- char *sense = erp->refers->irb.ecw;
+ char *sense = dasd_get_sense(&erp->refers->irb);
/* check for special retries */
- if (erp->function == dasd_3990_erp_action_4) {
+ if (sense && erp->function == dasd_3990_erp_action_4) {
erp = dasd_3990_erp_action_4(erp, sense);
- } else if (erp->function == dasd_3990_erp_action_1B_32) {
+ } else if (sense &&
+ erp->function == dasd_3990_erp_action_1B_32) {
erp = dasd_3990_update_1B(erp, sense);
- } else if (erp->function == dasd_3990_erp_int_req) {
+ } else if (sense && erp->function == dasd_3990_erp_int_req) {
erp = dasd_3990_erp_int_req(erp);
} else {
/* simple retry */
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"%i retries left for erp %p",
erp->retries, erp);
@@ -2609,24 +2656,24 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at BEGINNING of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at BEGINNING of ERP-ACTION\n");
for (temp_erp = cqr;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
}
/* double-check if current erp/cqr was successful */
- if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
- (cqr->irb.scsw.cmd.dstat ==
+ if ((scsw_cstat(&cqr->irb.scsw) == 0x00) &&
+ (scsw_dstat(&cqr->irb.scsw) ==
(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"ERP called for successful request %p"
" - NO ERP necessary", cqr);
@@ -2648,13 +2695,13 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at END of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at END of ERP-ACTION\n");
for (temp_erp = erp;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
@@ -2667,6 +2714,8 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
list_add_tail(&erp->blocklist, &cqr->blocklist);
}
+
+
return erp;
} /* end dasd_3990_erp_action */
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 20676cdef4a5..29806967e533 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -503,7 +503,7 @@ static void lcu_update_work(struct work_struct *work)
*/
spin_lock_irqsave(&lcu->lock, flags);
if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
- DEV_MESSAGE(KERN_WARNING, device, "could not update"
+ DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
" alias data in lcu (rc = %d), retry later", rc);
schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
} else {
@@ -646,14 +646,16 @@ static int reset_summary_unit_check(struct alias_lcu *lcu,
{
struct dasd_ccw_req *cqr;
int rc = 0;
+ struct ccw1 *ccw;
cqr = lcu->rsu_cqr;
strncpy((char *) &cqr->magic, "ECKD", 4);
ASCEBC((char *) &cqr->magic, 4);
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK;
- cqr->cpaddr->flags = 0 ;
- cqr->cpaddr->count = 16;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RSCK;
+ ccw->flags = 0 ;
+ ccw->count = 16;
+ ccw->cda = (__u32)(addr_t) cqr->data;
((char *)cqr->data)[0] = reason;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -855,16 +857,25 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
struct alias_lcu *lcu;
char reason;
struct dasd_eckd_private *private;
+ char *sense;
private = (struct dasd_eckd_private *) device->private;
- reason = irb->ecw[8];
- DEV_MESSAGE(KERN_WARNING, device, "%s %x",
- "eckd handle summary unit check: reason", reason);
+ sense = dasd_get_sense(irb);
+ if (sense) {
+ reason = sense[8];
+ DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
+ "eckd handle summary unit check: reason", reason);
+ } else {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "eckd handle summary unit check:"
+ " no reason code available");
+ return;
+ }
lcu = private->lcu;
if (!lcu) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"device not ready to handle summary"
" unit check (no lcu structure)");
return;
@@ -877,7 +888,7 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
* the next interrupt on a different device
*/
if (list_empty(&device->alias_list)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"device is in offline processing,"
" don't do summary unit check handling");
spin_unlock(&lcu->lock);
@@ -885,7 +896,7 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
}
if (lcu->suc_data.device) {
/* already scheduled or running */
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"previous instance of summary unit check worker"
" still pending");
spin_unlock(&lcu->lock);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 300e28a531f8..da231a787cee 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -67,6 +67,8 @@ int dasd_probeonly = 0; /* is true, when probeonly mode is active */
int dasd_autodetect = 0; /* is true, when autodetection is active */
int dasd_nopav = 0; /* is true, when PAV is disabled */
EXPORT_SYMBOL_GPL(dasd_nopav);
+int dasd_nofcx; /* disable High Performance Ficon */
+EXPORT_SYMBOL_GPL(dasd_nofcx);
/*
* char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -272,6 +274,11 @@ dasd_parse_keyword( char *parsestring ) {
}
return residual_str;
}
+ if (strncmp("nofcx", parsestring, length) == 0) {
+ dasd_nofcx = 1;
+ MESSAGE(KERN_INFO, "%s", "disable High Performance Ficon");
+ return residual_str;
+ }
if (strncmp("fixedbuffers", parsestring, length) == 0) {
if (dasd_page_cache)
return residual_str;
@@ -677,7 +684,7 @@ static ssize_t dasd_ff_show(struct device *dev, struct device_attribute *attr,
struct dasd_devmap *devmap;
int ff_flag;
- devmap = dasd_find_busid(dev->bus_id);
+ devmap = dasd_find_busid(dev_name(dev));
if (!IS_ERR(devmap))
ff_flag = (devmap->features & DASD_FEATURE_FAILFAST) != 0;
else
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index ef2a56952054..fa33673e8ce4 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -8,6 +8,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -144,8 +146,8 @@ dasd_diag_erp(struct dasd_device *device)
mdsk_term_io(device);
rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
if (rc)
- DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, "
- "rc=%d", rc);
+ dev_warn(&device->cdev->dev, "DIAG ERP failed with "
+ "rc=%d\n", rc);
}
/* Start a given request at the device. Return zero on success, non-zero
@@ -160,7 +162,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
device = cqr->startdev;
if (cqr->retries < 0) {
- DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p "
+ DBF_DEV_EVENT(DBF_ERR, device, "DIAG start_IO: request %p "
"- no retry left)", cqr);
cqr->status = DASD_CQR_ERROR;
return -EIO;
@@ -195,7 +197,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
break;
default: /* Error condition */
cqr->status = DASD_CQR_QUEUED;
- DEV_MESSAGE(KERN_WARNING, device, "dia250 returned rc=%d", rc);
+ DBF_DEV_EVENT(DBF_WARNING, device, "dia250 returned rc=%d", rc);
dasd_diag_erp(device);
rc = -EIO;
break;
@@ -249,7 +251,7 @@ dasd_ext_handler(__u16 code)
cqr = (struct dasd_ccw_req *) ip;
device = (struct dasd_device *) cqr->startdev;
if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- DEV_MESSAGE(KERN_WARNING, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
" magic number of dasd_ccw_req 0x%08X doesn't"
" match discipline 0x%08X",
cqr->magic, *(int *) (&device->discipline->name));
@@ -281,15 +283,11 @@ dasd_ext_handler(__u16 code)
rc = dasd_start_diag(next);
if (rc == 0)
expires = next->expires;
- else if (rc != -EACCES)
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Interrupt fastpath "
- "failed!");
}
}
} else {
cqr->status = DASD_CQR_QUEUED;
- DEV_MESSAGE(KERN_WARNING, device, "interrupt status for "
+ DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
"request %p was %d (%d retries left)", cqr, status,
cqr->retries);
dasd_diag_erp(device);
@@ -322,8 +320,9 @@ dasd_diag_check_device(struct dasd_device *device)
if (private == NULL) {
private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private data");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "Allocating memory for private DASD data "
+ "failed\n");
return -ENOMEM;
}
ccw_device_get_id(device->cdev, &private->dev_id);
@@ -331,7 +330,7 @@ dasd_diag_check_device(struct dasd_device *device)
}
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"could not allocate dasd block structure");
device->private = NULL;
kfree(private);
@@ -347,7 +346,7 @@ dasd_diag_check_device(struct dasd_device *device)
rc = diag210((struct diag210 *) rdc_data);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device "
+ DBF_DEV_EVENT(DBF_WARNING, device, "failed to retrieve device "
"information (rc=%d)", rc);
rc = -EOPNOTSUPP;
goto out;
@@ -362,8 +361,8 @@ dasd_diag_check_device(struct dasd_device *device)
private->pt_block = 2;
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "unsupported device class "
- "(class=%d)", private->rdc_data.vdev_class);
+ dev_warn(&device->cdev->dev, "Device type %d is not supported "
+ "in DIAG mode\n", private->rdc_data.vdev_class);
rc = -EOPNOTSUPP;
goto out;
}
@@ -380,7 +379,7 @@ dasd_diag_check_device(struct dasd_device *device)
/* figure out blocksize of device */
label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
if (label == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"No memory to allocate initialization request");
rc = -ENOMEM;
goto out;
@@ -404,8 +403,8 @@ dasd_diag_check_device(struct dasd_device *device)
private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
rc = dia250(&private->iob, RW_BIO);
if (rc == 3) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "DIAG call failed");
+ dev_warn(&device->cdev->dev,
+ "A 64-bit DIAG call failed\n");
rc = -EOPNOTSUPP;
goto out_label;
}
@@ -414,8 +413,8 @@ dasd_diag_check_device(struct dasd_device *device)
break;
}
if (bsize > PAGE_SIZE) {
- DEV_MESSAGE(KERN_WARNING, device, "device access failed "
- "(rc=%d)", rc);
+ dev_warn(&device->cdev->dev, "Accessing the DASD failed because"
+ " of an incorrect format (rc=%d)\n", rc);
rc = -EIO;
goto out_label;
}
@@ -433,15 +432,15 @@ dasd_diag_check_device(struct dasd_device *device)
block->s2b_shift++;
rc = mdsk_init_io(device, block->bp_block, 0, NULL);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
- "failed (rc=%d)", rc);
+ dev_warn(&device->cdev->dev, "DIAG initialization "
+ "failed with rc=%d\n", rc);
rc = -EIO;
} else {
- DEV_MESSAGE(KERN_INFO, device,
- "(%ld B/blk): %ldkB",
- (unsigned long) block->bp_block,
- (unsigned long) (block->blocks <<
- block->s2b_shift) >> 1);
+ dev_info(&device->cdev->dev,
+ "New DASD with %ld byte/block, total size %ld KB\n",
+ (unsigned long) block->bp_block,
+ (unsigned long) (block->blocks <<
+ block->s2b_shift) >> 1);
}
out_label:
free_page((long) label);
@@ -595,7 +594,7 @@ static void
dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
struct irb *stat)
{
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"dump sense not available for DIAG data");
}
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index bdb87998f364..fb2ad37f092a 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -11,6 +11,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -27,9 +29,12 @@
#include <asm/uaccess.h>
#include <asm/cio.h>
#include <asm/ccwdev.h>
+#include <asm/itcw.h>
#include "dasd_int.h"
#include "dasd_eckd.h"
+#include "../cio/chsc.h"
+
#ifdef PRINTK_HEADER
#undef PRINTK_HEADER
@@ -84,7 +89,7 @@ dasd_eckd_probe (struct ccw_device *cdev)
/* set ECKD specific ccw-device options */
ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_eckd_probe: could not set ccw-device options "
"for %s\n", dev_name(&cdev->dev));
return ret;
@@ -159,6 +164,14 @@ recs_per_track(struct dasd_eckd_characteristics * rdc,
return 0;
}
+static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
+{
+ geo->cyl = (__u16) cyl;
+ geo->head = cyl >> 16;
+ geo->head <<= 4;
+ geo->head |= head;
+}
+
static int
check_XRC (struct ccw1 *de_ccw,
struct DE_eckd_data *data,
@@ -186,11 +199,12 @@ check_XRC (struct ccw1 *de_ccw,
}
static int
-define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
- int totrk, int cmd, struct dasd_device * device)
+define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
+ unsigned int totrk, int cmd, struct dasd_device *device)
{
struct dasd_eckd_private *private;
- struct ch_t geo, beg, end;
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
int rc = 0;
private = (struct dasd_eckd_private *) device->private;
@@ -236,7 +250,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
rc = check_XRC (ccw, data, device);
break;
default:
- DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
+ dev_err(&device->cdev->dev,
+ "0x%x is not a known command\n", cmd);
break;
}
@@ -248,27 +263,24 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
&& !(private->uses_cdl && trk < 2))
data->ga_extended |= 0x40; /* Regular Data Format Mode */
- geo.cyl = private->rdc_data.no_cyl;
- geo.head = private->rdc_data.trk_per_cyl;
- beg.cyl = trk / geo.head;
- beg.head = trk % geo.head;
- end.cyl = totrk / geo.head;
- end.head = totrk % geo.head;
+ heads = private->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
/* check for sequential prestage - enhance cylinder range */
if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
data->attributes.operation == DASD_SEQ_ACCESS) {
- if (end.cyl + private->attrib.nr_cyl < geo.cyl)
- end.cyl += private->attrib.nr_cyl;
+ if (endcyl + private->attrib.nr_cyl < private->real_cyl)
+ endcyl += private->attrib.nr_cyl;
else
- end.cyl = (geo.cyl - 1);
+ endcyl = (private->real_cyl - 1);
}
- data->beg_ext.cyl = beg.cyl;
- data->beg_ext.head = beg.head;
- data->end_ext.cyl = end.cyl;
- data->end_ext.head = end.head;
+ set_ch_t(&data->beg_ext, begcyl, beghead);
+ set_ch_t(&data->end_ext, endcyl, endhead);
return rc;
}
@@ -283,29 +295,145 @@ static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata,
return 0;
/* switch on System Time Stamp - needed for XRC Support */
- pfxdata->define_extend.ga_extended |= 0x08; /* 'Time Stamp Valid' */
- pfxdata->define_extend.ga_extended |= 0x02; /* 'Extended Parameter' */
+ pfxdata->define_extent.ga_extended |= 0x08; /* 'Time Stamp Valid' */
+ pfxdata->define_extent.ga_extended |= 0x02; /* 'Extended Parameter' */
pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */
- rc = get_sync_clock(&pfxdata->define_extend.ep_sys_time);
+ rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
/* Ignore return code if sync clock is switched off. */
if (rc == -ENOSYS || rc == -EACCES)
rc = 0;
return rc;
}
-static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
- int totrk, int cmd, struct dasd_device *basedev,
- struct dasd_device *startdev)
+static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
+ unsigned int rec_on_trk, int count, int cmd,
+ struct dasd_device *device, unsigned int reclen,
+ unsigned int tlf)
+{
+ struct dasd_eckd_private *private;
+ int sector;
+ int dn, d;
+
+ private = (struct dasd_eckd_private *) device->private;
+
+ memset(data, 0, sizeof(*data));
+ sector = 0;
+ if (rec_on_trk) {
+ switch (private->rdc_data.dev_type) {
+ case 0x3390:
+ dn = ceil_quot(reclen + 6, 232);
+ d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
+ sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+ break;
+ case 0x3380:
+ d = 7 + ceil_quot(reclen + 12, 32);
+ sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+ break;
+ }
+ }
+ data->sector = sector;
+ /* note: meaning of count depends on the operation
+ * for record based I/O it's the number of records, but for
+ * track based I/O it's the number of tracks
+ */
+ data->count = count;
+ switch (cmd) {
+ case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_READ_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
+ data->operation.orientation = 0x1;
+ data->operation.operation = 0x03;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_READ_RECORD_ZERO:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_WRITE:
+ case DASD_ECKD_CCW_WRITE_MT:
+ case DASD_ECKD_CCW_WRITE_KD:
+ case DASD_ECKD_CCW_WRITE_KD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x01;
+ break;
+ case DASD_ECKD_CCW_WRITE_CKD:
+ case DASD_ECKD_CCW_WRITE_CKD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen; /* not tlf, as one might think */
+ data->operation.operation = 0x3F;
+ data->extended_operation = 0x23;
+ break;
+ case DASD_ECKD_CCW_READ:
+ case DASD_ECKD_CCW_READ_MT:
+ case DASD_ECKD_CCW_READ_KD:
+ case DASD_ECKD_CCW_READ_KD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x06;
+ break;
+ case DASD_ECKD_CCW_READ_CKD:
+ case DASD_ECKD_CCW_READ_CKD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_READ_COUNT:
+ data->operation.operation = 0x06;
+ break;
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ data->auxiliary.length_valid = 0x1;
+ data->length = tlf;
+ data->operation.operation = 0x0C;
+ break;
+ case DASD_ECKD_CCW_ERASE:
+ data->length = reclen;
+ data->auxiliary.length_valid = 0x1;
+ data->operation.operation = 0x0b;
+ break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, device,
+ "fill LRE unknown opcode 0x%x", cmd);
+ BUG();
+ }
+ set_ch_t(&data->seek_addr,
+ trk / private->rdc_data.trk_per_cyl,
+ trk % private->rdc_data.trk_per_cyl);
+ data->search_arg.cyl = data->seek_addr.cyl;
+ data->search_arg.head = data->seek_addr.head;
+ data->search_arg.record = rec_on_trk;
+}
+
+static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev, struct dasd_device *startdev,
+ unsigned char format, unsigned int rec_on_trk, int count,
+ unsigned int blksize, unsigned int tlf)
{
struct dasd_eckd_private *basepriv, *startpriv;
- struct DE_eckd_data *data;
- struct ch_t geo, beg, end;
+ struct DE_eckd_data *dedata;
+ struct LRE_eckd_data *lredata;
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
int rc = 0;
basepriv = (struct dasd_eckd_private *) basedev->private;
startpriv = (struct dasd_eckd_private *) startdev->private;
- data = &pfxdata->define_extend;
+ dedata = &pfxdata->define_extent;
+ lredata = &pfxdata->locate_record;
ccw->cmd_code = DASD_ECKD_CCW_PFX;
ccw->flags = 0;
@@ -314,10 +442,16 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
memset(pfxdata, 0, sizeof(*pfxdata));
/* prefix data */
- pfxdata->format = 0;
+ if (format > 1) {
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "PFX LRE unknown format 0x%x", format);
+ BUG();
+ return -EINVAL;
+ }
+ pfxdata->format = format;
pfxdata->base_address = basepriv->ned->unit_addr;
pfxdata->base_lss = basepriv->ned->ID;
- pfxdata->validity.define_extend = 1;
+ pfxdata->validity.define_extent = 1;
/* private uid is kept up to date, conf_data may be outdated */
if (startpriv->uid.type != UA_BASE_DEVICE) {
@@ -337,70 +471,94 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
case DASD_ECKD_CCW_READ_KD:
case DASD_ECKD_CCW_READ_KD_MT:
case DASD_ECKD_CCW_READ_COUNT:
- data->mask.perm = 0x1;
- data->attributes.operation = basepriv->attrib.operation;
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ break;
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = 0;
break;
case DASD_ECKD_CCW_WRITE:
case DASD_ECKD_CCW_WRITE_MT:
case DASD_ECKD_CCW_WRITE_KD:
case DASD_ECKD_CCW_WRITE_KD_MT:
- data->mask.perm = 0x02;
- data->attributes.operation = basepriv->attrib.operation;
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
case DASD_ECKD_CCW_WRITE_CKD:
case DASD_ECKD_CCW_WRITE_CKD_MT:
- data->attributes.operation = DASD_BYPASS_CACHE;
+ dedata->attributes.operation = DASD_BYPASS_CACHE;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
case DASD_ECKD_CCW_ERASE:
case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
- data->mask.perm = 0x3;
- data->mask.auth = 0x1;
- data->attributes.operation = DASD_BYPASS_CACHE;
+ dedata->mask.perm = 0x3;
+ dedata->mask.auth = 0x1;
+ dedata->attributes.operation = DASD_BYPASS_CACHE;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
- default:
- DEV_MESSAGE(KERN_ERR, basedev, "unknown opcode 0x%x", cmd);
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ rc = check_XRC_on_prefix(pfxdata, basedev);
break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "PFX LRE unknown opcode 0x%x", cmd);
+ BUG();
+ return -EINVAL;
}
- data->attributes.mode = 0x3; /* ECKD */
+ dedata->attributes.mode = 0x3; /* ECKD */
if ((basepriv->rdc_data.cu_type == 0x2105 ||
basepriv->rdc_data.cu_type == 0x2107 ||
basepriv->rdc_data.cu_type == 0x1750)
&& !(basepriv->uses_cdl && trk < 2))
- data->ga_extended |= 0x40; /* Regular Data Format Mode */
+ dedata->ga_extended |= 0x40; /* Regular Data Format Mode */
- geo.cyl = basepriv->rdc_data.no_cyl;
- geo.head = basepriv->rdc_data.trk_per_cyl;
- beg.cyl = trk / geo.head;
- beg.head = trk % geo.head;
- end.cyl = totrk / geo.head;
- end.head = totrk % geo.head;
+ heads = basepriv->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
/* check for sequential prestage - enhance cylinder range */
- if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
- data->attributes.operation == DASD_SEQ_ACCESS) {
+ if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+ dedata->attributes.operation == DASD_SEQ_ACCESS) {
- if (end.cyl + basepriv->attrib.nr_cyl < geo.cyl)
- end.cyl += basepriv->attrib.nr_cyl;
+ if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+ endcyl += basepriv->attrib.nr_cyl;
else
- end.cyl = (geo.cyl - 1);
+ endcyl = (basepriv->real_cyl - 1);
+ }
+
+ set_ch_t(&dedata->beg_ext, begcyl, beghead);
+ set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+ if (format == 1) {
+ fill_LRE_data(lredata, trk, rec_on_trk, count, cmd,
+ basedev, blksize, tlf);
}
- data->beg_ext.cyl = beg.cyl;
- data->beg_ext.head = beg.head;
- data->end_ext.cyl = end.cyl;
- data->end_ext.head = end.head;
return rc;
}
+static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev, struct dasd_device *startdev)
+{
+ return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
+ 0, 0, 0, 0, 0);
+}
+
static void
-locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
- int rec_on_trk, int no_rec, int cmd,
+locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
+ unsigned int rec_on_trk, int no_rec, int cmd,
struct dasd_device * device, int reclen)
{
struct dasd_eckd_private *private;
@@ -491,12 +649,14 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
data->operation.operation = 0x0b;
break;
default:
- DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
- }
- data->seek_addr.cyl = data->search_arg.cyl =
- trk / private->rdc_data.trk_per_cyl;
- data->seek_addr.head = data->search_arg.head =
- trk % private->rdc_data.trk_per_cyl;
+ DBF_DEV_EVENT(DBF_ERR, device, "unknown locate record "
+ "opcode 0x%x", cmd);
+ }
+ set_ch_t(&data->seek_addr,
+ trk / private->rdc_data.trk_per_cyl,
+ trk % private->rdc_data.trk_per_cyl);
+ data->search_arg.cyl = data->seek_addr.cyl;
+ data->search_arg.head = data->seek_addr.head;
data->search_arg.record = rec_on_trk;
}
@@ -585,8 +745,8 @@ static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate RCD request");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "Could not allocate RCD request");
return cqr;
}
@@ -736,14 +896,16 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
rc = dasd_eckd_read_conf_lpm(device, &conf_data,
&conf_len, lpm);
if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
- MESSAGE(KERN_WARNING,
- "Read configuration data returned "
- "error %d", rc);
+ DBF_EVENT(DBF_WARNING,
+ "Read configuration data returned "
+ "error %d for device: %s", rc,
+ dev_name(&device->cdev->dev));
return rc;
}
if (conf_data == NULL) {
- MESSAGE(KERN_WARNING, "%s", "No configuration "
- "data retrieved");
+ DBF_EVENT(DBF_WARNING, "No configuration "
+ "data retrieved for device: %s",
+ dev_name(&device->cdev->dev));
continue; /* no error */
}
/* save first valid configuration data */
@@ -790,8 +952,9 @@ static int dasd_eckd_read_features(struct dasd_device *device)
sizeof(struct dasd_rssd_features)),
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate initialization request");
+ DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
+ "request for device: %s",
+ dev_name(&device->cdev->dev));
return PTR_ERR(cqr);
}
cqr->startdev = device;
@@ -840,7 +1003,8 @@ static int dasd_eckd_read_features(struct dasd_device *device)
/*
* Build CP for Perform Subsystem Function - SSC.
*/
-static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
+static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
+ int enable_pav)
{
struct dasd_ccw_req *cqr;
struct dasd_psf_ssc_data *psf_ssc_data;
@@ -851,15 +1015,17 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate PSF-SSC request");
return cqr;
}
psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
psf_ssc_data->order = PSF_ORDER_SSC;
- psf_ssc_data->suborder = 0x88;
- psf_ssc_data->reserved[0] = 0x88;
-
+ psf_ssc_data->suborder = 0x40;
+ if (enable_pav) {
+ psf_ssc_data->suborder |= 0x88;
+ psf_ssc_data->reserved[0] = 0x88;
+ }
ccw = cqr->cpaddr;
ccw->cmd_code = DASD_ECKD_CCW_PSF;
ccw->cda = (__u32)(addr_t)psf_ssc_data;
@@ -880,12 +1046,12 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
* call might change behaviour of DASD devices.
*/
static int
-dasd_eckd_psf_ssc(struct dasd_device *device)
+dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
{
struct dasd_ccw_req *cqr;
int rc;
- cqr = dasd_eckd_build_psf_ssc(device);
+ cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
if (IS_ERR(cqr))
return PTR_ERR(cqr);
@@ -904,19 +1070,20 @@ static int dasd_eckd_validate_server(struct dasd_device *device)
{
int rc;
struct dasd_eckd_private *private;
+ int enable_pav;
- /* Currently PAV is the only reason to 'validate' server on LPAR */
if (dasd_nopav || MACHINE_IS_VM)
- return 0;
-
- rc = dasd_eckd_psf_ssc(device);
+ enable_pav = 0;
+ else
+ enable_pav = 1;
+ rc = dasd_eckd_psf_ssc(device, enable_pav);
/* may be requested feature is not available on server,
* therefore just report error and go ahead */
private = (struct dasd_eckd_private *) device->private;
- DEV_MESSAGE(KERN_INFO, device,
- "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d",
- private->uid.vendor, private->uid.serial,
- private->uid.ssid, rc);
+ DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x "
+ "returned rc=%d for device: %s",
+ private->uid.vendor, private->uid.serial,
+ private->uid.ssid, rc, dev_name(&device->cdev->dev));
/* RE-Read Configuration Data */
return dasd_eckd_read_conf(device);
}
@@ -938,9 +1105,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
private = kzalloc(sizeof(struct dasd_eckd_private),
GFP_KERNEL | GFP_DMA);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private "
- "data");
+ dev_warn(&device->cdev->dev,
+ "Allocating memory for private DASD data "
+ "failed\n");
return -ENOMEM;
}
device->private = (void *) private;
@@ -965,8 +1132,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
if (private->uid.type == UA_BASE_DEVICE) {
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "could not allocate dasd block structure");
+ DBF_EVENT(DBF_WARNING, "could not allocate dasd "
+ "block structure for device: %s",
+ dev_name(&device->cdev->dev));
rc = PTR_ERR(block);
goto out_err1;
}
@@ -997,20 +1165,27 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
memset(rdc_data, 0, sizeof(rdc_data));
rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Read device characteristics returned "
- "rc=%d", rc);
+ DBF_EVENT(DBF_WARNING,
+ "Read device characteristics failed, rc=%d for "
+ "device: %s", rc, dev_name(&device->cdev->dev));
goto out_err3;
}
- DEV_MESSAGE(KERN_INFO, device,
- "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
- private->rdc_data.dev_type,
- private->rdc_data.dev_model,
- private->rdc_data.cu_type,
- private->rdc_data.cu_model.model,
- private->rdc_data.no_cyl,
- private->rdc_data.trk_per_cyl,
- private->rdc_data.sec_per_trk);
+ /* find the vaild cylinder size */
+ if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
+ private->rdc_data.long_no_cyl)
+ private->real_cyl = private->rdc_data.long_no_cyl;
+ else
+ private->real_cyl = private->rdc_data.no_cyl;
+
+ dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
+ "with %d cylinders, %d heads, %d sectors\n",
+ private->rdc_data.dev_type,
+ private->rdc_data.dev_model,
+ private->rdc_data.cu_type,
+ private->rdc_data.cu_model.model,
+ private->real_cyl,
+ private->rdc_data.trk_per_cyl,
+ private->rdc_data.sec_per_trk);
return 0;
out_err3:
@@ -1151,14 +1326,12 @@ dasd_eckd_end_analysis(struct dasd_block *block)
status = private->init_cqr_status;
private->init_cqr_status = -1;
if (status != DASD_CQR_DONE) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "volume analysis returned unformatted disk");
+ dev_warn(&device->cdev->dev,
+ "The DASD is not formatted\n");
return -EMEDIUMTYPE;
}
private->uses_cdl = 1;
- /* Calculate number of blocks/records per track. */
- blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
/* Check Track 0 for Compatible Disk Layout */
count_area = NULL;
for (i = 0; i < 3; i++) {
@@ -1182,8 +1355,8 @@ dasd_eckd_end_analysis(struct dasd_block *block)
count_area = &private->count_area[0];
} else {
if (private->count_area[3].record == 1)
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Trk 0: no records after VTOC!");
+ dev_warn(&device->cdev->dev,
+ "Track 0 has no records following the VTOC\n");
}
if (count_area != NULL && count_area->kl == 0) {
/* we found notthing violating our disk layout */
@@ -1191,8 +1364,8 @@ dasd_eckd_end_analysis(struct dasd_block *block)
block->bp_block = count_area->dl;
}
if (block->bp_block == 0) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Volume has incompatible disk layout");
+ dev_warn(&device->cdev->dev,
+ "The disk layout of the DASD is not supported\n");
return -EMEDIUMTYPE;
}
block->s2b_shift = 0; /* bits to shift 512 to get a block */
@@ -1200,19 +1373,19 @@ dasd_eckd_end_analysis(struct dasd_block *block)
block->s2b_shift++;
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
- block->blocks = (private->rdc_data.no_cyl *
+ block->blocks = (private->real_cyl *
private->rdc_data.trk_per_cyl *
blk_per_trk);
- DEV_MESSAGE(KERN_INFO, device,
- "(%dkB blks): %dkB at %dkB/trk %s",
- (block->bp_block >> 10),
- ((private->rdc_data.no_cyl *
- private->rdc_data.trk_per_cyl *
- blk_per_trk * (block->bp_block >> 9)) >> 1),
- ((blk_per_trk * block->bp_block) >> 10),
- private->uses_cdl ?
- "compatible disk layout" : "linux disk layout");
+ dev_info(&device->cdev->dev,
+ "DASD with %d KB/block, %d KB total size, %d KB/track, "
+ "%s\n", (block->bp_block >> 10),
+ ((private->real_cyl *
+ private->rdc_data.trk_per_cyl *
+ blk_per_trk * (block->bp_block >> 9)) >> 1),
+ ((blk_per_trk * block->bp_block) >> 10),
+ private->uses_cdl ?
+ "compatible disk layout" : "linux disk layout");
return 0;
}
@@ -1262,31 +1435,35 @@ dasd_eckd_format_device(struct dasd_device * device,
struct eckd_count *ect;
struct ccw1 *ccw;
void *data;
- int rpt, cyl, head;
+ int rpt;
+ struct ch_t address;
int cplength, datasize;
int i;
+ int intensity = 0;
+ int r0_perm;
private = (struct dasd_eckd_private *) device->private;
rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
- cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;
- head = fdata->start_unit % private->rdc_data.trk_per_cyl;
+ set_ch_t(&address,
+ fdata->start_unit / private->rdc_data.trk_per_cyl,
+ fdata->start_unit % private->rdc_data.trk_per_cyl);
/* Sanity checks. */
if (fdata->start_unit >=
- (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) {
- DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!",
- fdata->start_unit);
+ (private->real_cyl * private->rdc_data.trk_per_cyl)) {
+ dev_warn(&device->cdev->dev, "Start track number %d used in "
+ "formatting is too big\n", fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (fdata->start_unit > fdata->stop_unit) {
- DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.",
- fdata->start_unit);
+ dev_warn(&device->cdev->dev, "Start track %d used in "
+ "formatting exceeds end track\n", fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (dasd_check_blocksize(fdata->blksize) != 0) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Invalid blocksize %d...terminating!",
- fdata->blksize);
+ dev_warn(&device->cdev->dev,
+ "The DASD cannot be formatted with block size %d\n",
+ fdata->blksize);
return ERR_PTR(-EINVAL);
}
@@ -1296,9 +1473,17 @@ dasd_eckd_format_device(struct dasd_device * device,
* Bit 1: write home address, currently not supported
* Bit 2: invalidate tracks
* Bit 3: use OS/390 compatible disk layout (cdl)
+ * Bit 4: do not allow storage subsystem to modify record zero
* Only some bit combinations do make sense.
*/
- switch (fdata->intensity) {
+ if (fdata->intensity & 0x10) {
+ r0_perm = 0;
+ intensity = fdata->intensity & ~0x10;
+ } else {
+ r0_perm = 1;
+ intensity = fdata->intensity;
+ }
+ switch (intensity) {
case 0x00: /* Normal format */
case 0x08: /* Normal format, use cdl. */
cplength = 2 + rpt;
@@ -1322,8 +1507,8 @@ dasd_eckd_format_device(struct dasd_device * device,
sizeof(struct eckd_count);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
- fdata->intensity);
+ dev_warn(&device->cdev->dev, "An I/O control call used "
+ "incorrect flags 0x%x\n", fdata->intensity);
return ERR_PTR(-EINVAL);
}
/* Allocate the format ccw request. */
@@ -1335,11 +1520,14 @@ dasd_eckd_format_device(struct dasd_device * device,
data = fcp->data;
ccw = fcp->cpaddr;
- switch (fdata->intensity & ~0x08) {
+ switch (intensity & ~0x08) {
case 0x00: /* Normal format. */
define_extent(ccw++, (struct DE_eckd_data *) data,
fdata->start_unit, fdata->start_unit,
DASD_ECKD_CCW_WRITE_CKD, device);
+ /* grant subsystem permission to format R0 */
+ if (r0_perm)
+ ((struct DE_eckd_data *)data)->ga_extended |= 0x04;
data += sizeof(struct DE_eckd_data);
ccw[-1].flags |= CCW_FLAG_CC;
locate_record(ccw++, (struct LO_eckd_data *) data,
@@ -1373,11 +1561,11 @@ dasd_eckd_format_device(struct dasd_device * device,
data += sizeof(struct LO_eckd_data);
break;
}
- if (fdata->intensity & 0x01) { /* write record zero */
+ if (intensity & 0x01) { /* write record zero */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = 0;
ect->kl = 0;
ect->dl = 8;
@@ -1388,11 +1576,11 @@ dasd_eckd_format_device(struct dasd_device * device,
ccw->cda = (__u32)(addr_t) ect;
ccw++;
}
- if ((fdata->intensity & ~0x08) & 0x04) { /* erase track */
+ if ((intensity & ~0x08) & 0x04) { /* erase track */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = 1;
ect->kl = 0;
ect->dl = 0;
@@ -1405,20 +1593,20 @@ dasd_eckd_format_device(struct dasd_device * device,
for (i = 0; i < rpt; i++) {
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = i + 1;
ect->kl = 0;
ect->dl = fdata->blksize;
/* Check for special tracks 0-1 when formatting CDL */
- if ((fdata->intensity & 0x08) &&
+ if ((intensity & 0x08) &&
fdata->start_unit == 0) {
if (i < 3) {
ect->kl = 4;
ect->dl = sizes_trk0[i] - 4;
}
}
- if ((fdata->intensity & 0x08) &&
+ if ((intensity & 0x08) &&
fdata->start_unit == 1) {
ect->kl = 44;
ect->dl = LABEL_SIZE - 44;
@@ -1479,57 +1667,69 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
struct irb *irb)
{
char mask;
+ char *sense = NULL;
/* first of all check for state change pending interrupt */
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
- if ((irb->scsw.cmd.dstat & mask) == mask) {
+ if ((scsw_dstat(&irb->scsw) & mask) == mask) {
dasd_generic_handle_state_change(device);
return;
}
/* summary unit check */
- if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
+ if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
(irb->ecw[7] == 0x0D)) {
dasd_alias_handle_summary_unit_check(device, irb);
return;
}
-
+ sense = dasd_get_sense(irb);
/* service information message SIM */
- if (irb->esw.esw0.erw.cons && !(irb->ecw[27] & DASD_SENSE_BIT_0) &&
- ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
- dasd_3990_erp_handle_sim(device, irb->ecw);
+ if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
+ ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
+ dasd_3990_erp_handle_sim(device, sense);
dasd_schedule_device_bh(device);
return;
}
- if ((irb->scsw.cmd.cc == 1) &&
- (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
- (irb->scsw.cmd.actl & SCSW_ACTL_START_PEND) &&
- (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND)) {
+ if ((scsw_cc(&irb->scsw) == 1) &&
+ (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+ (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) &&
+ (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) {
/* fake irb do nothing, they are handled elsewhere */
dasd_schedule_device_bh(device);
return;
}
- if (!(irb->esw.esw0.erw.cons)) {
+ if (!sense) {
/* just report other unsolicited interrupts */
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"unsolicited interrupt received");
} else {
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"unsolicited interrupt received "
"(sense available)");
- device->discipline->dump_sense(device, NULL, irb);
+ device->discipline->dump_sense_dbf(device, NULL, irb,
+ "unsolicited");
}
dasd_schedule_device_bh(device);
return;
};
-static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
+ struct dasd_device *startdev,
struct dasd_block *block,
- struct request *req)
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
{
struct dasd_eckd_private *private;
unsigned long *idaws;
@@ -1539,11 +1739,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
struct req_iterator iter;
struct bio_vec *bv;
char *dst;
- unsigned int blksize, blk_per_trk, off;
+ unsigned int off;
int count, cidaw, cplength, datasize;
- sector_t recid, first_rec, last_rec;
- sector_t first_trk, last_trk;
- unsigned int first_offs, last_offs;
+ sector_t recid;
unsigned char cmd, rcmd;
int use_prefix;
struct dasd_device *basedev;
@@ -1556,15 +1754,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
cmd = DASD_ECKD_CCW_WRITE_MT;
else
return ERR_PTR(-EINVAL);
- /* Calculate number of blocks/records per track. */
- blksize = block->bp_block;
- blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
- /* Calculate record id of first and last block. */
- first_rec = first_trk = req->sector >> block->s2b_shift;
- first_offs = sector_div(first_trk, blk_per_trk);
- last_rec = last_trk =
- (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
- last_offs = sector_div(last_trk, blk_per_trk);
+
/* Check struct bio and count the number of blocks for the request. */
count = 0;
cidaw = 0;
@@ -1714,6 +1904,497 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
return cqr;
}
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
+ struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
+{
+ struct dasd_eckd_private *private;
+ unsigned long *idaws;
+ struct dasd_ccw_req *cqr;
+ struct ccw1 *ccw;
+ struct req_iterator iter;
+ struct bio_vec *bv;
+ char *dst, *idaw_dst;
+ unsigned int cidaw, cplength, datasize;
+ unsigned int tlf;
+ sector_t recid;
+ unsigned char cmd;
+ struct dasd_device *basedev;
+ unsigned int trkcount, count, count_to_trk_end;
+ unsigned int idaw_len, seg_len, part_len, len_to_track_end;
+ unsigned char new_track, end_idaw;
+ sector_t trkid;
+ unsigned int recoffs;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+ if (rq_data_dir(req) == READ)
+ cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+ else if (rq_data_dir(req) == WRITE)
+ cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+ else
+ return ERR_PTR(-EINVAL);
+
+ /* Track based I/O needs IDAWs for each page, and not just for
+ * 64 bit addresses. We need additional idals for pages
+ * that get filled from two tracks, so we use the number
+ * of records as upper limit.
+ */
+ cidaw = last_rec - first_rec + 1;
+ trkcount = last_trk - first_trk + 1;
+
+ /* 1x prefix + one read/write ccw per track */
+ cplength = 1 + trkcount;
+
+ /* on 31-bit we need space for two 32 bit addresses per page
+ * on 64-bit one 64 bit address
+ */
+ datasize = sizeof(struct PFX_eckd_data) +
+ cidaw * sizeof(unsigned long long);
+
+ /* Allocate the ccw request. */
+ cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+ cplength, datasize, startdev);
+ if (IS_ERR(cqr))
+ return cqr;
+ ccw = cqr->cpaddr;
+ /* transfer length factor: how many bytes to read from the last track */
+ if (first_trk == last_trk)
+ tlf = last_offs - first_offs + 1;
+ else
+ tlf = last_offs + 1;
+ tlf *= blksize;
+
+ if (prefix_LRE(ccw++, cqr->data, first_trk,
+ last_trk, cmd, basedev, startdev,
+ 1 /* format */, first_offs + 1,
+ trkcount, blksize,
+ tlf) == -EAGAIN) {
+ /* Clock not in sync and XRC is enabled.
+ * Try again later.
+ */
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-EAGAIN);
+ }
+
+ /*
+ * The translation of request into ccw programs must meet the
+ * following conditions:
+ * - all idaws but the first and the last must address full pages
+ * (or 2K blocks on 31-bit)
+ * - the scope of a ccw and it's idal ends with the track boundaries
+ */
+ idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
+ recid = first_rec;
+ new_track = 1;
+ end_idaw = 0;
+ len_to_track_end = 0;
+ idaw_dst = 0;
+ idaw_len = 0;
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ seg_len = bv->bv_len;
+ while (seg_len) {
+ if (new_track) {
+ trkid = recid;
+ recoffs = sector_div(trkid, blk_per_trk);
+ count_to_trk_end = blk_per_trk - recoffs;
+ count = min((last_rec - recid + 1),
+ (sector_t)count_to_trk_end);
+ len_to_track_end = count * blksize;
+ ccw[-1].flags |= CCW_FLAG_CC;
+ ccw->cmd_code = cmd;
+ ccw->count = len_to_track_end;
+ ccw->cda = (__u32)(addr_t)idaws;
+ ccw->flags = CCW_FLAG_IDA;
+ ccw++;
+ recid += count;
+ new_track = 0;
+ }
+ /* If we start a new idaw, everything is fine and the
+ * start of the new idaw is the start of this segment.
+ * If we continue an idaw, we must make sure that the
+ * current segment begins where the so far accumulated
+ * idaw ends
+ */
+ if (!idaw_dst)
+ idaw_dst = dst;
+ if ((idaw_dst + idaw_len) != dst) {
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-ERANGE);
+ }
+ part_len = min(seg_len, len_to_track_end);
+ seg_len -= part_len;
+ dst += part_len;
+ idaw_len += part_len;
+ len_to_track_end -= part_len;
+ /* collected memory area ends on an IDA_BLOCK border,
+ * -> create an idaw
+ * idal_create_words will handle cases where idaw_len
+ * is larger then IDA_BLOCK_SIZE
+ */
+ if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
+ end_idaw = 1;
+ /* We also need to end the idaw at track end */
+ if (!len_to_track_end) {
+ new_track = 1;
+ end_idaw = 1;
+ }
+ if (end_idaw) {
+ idaws = idal_create_words(idaws, idaw_dst,
+ idaw_len);
+ idaw_dst = 0;
+ idaw_len = 0;
+ end_idaw = 0;
+ }
+ }
+ }
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 5 * 60 * HZ; /* 5 minutes */
+ cqr->lpm = private->path_data.ppm;
+ cqr->retries = 256;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ return cqr;
+}
+
+static int prepare_itcw(struct itcw *itcw,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev,
+ struct dasd_device *startdev,
+ unsigned int rec_on_trk, int count,
+ unsigned int blksize,
+ unsigned int total_data_size,
+ unsigned int tlf,
+ unsigned int blk_per_trk)
+{
+ struct PFX_eckd_data pfxdata;
+ struct dasd_eckd_private *basepriv, *startpriv;
+ struct DE_eckd_data *dedata;
+ struct LRE_eckd_data *lredata;
+ struct dcw *dcw;
+
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
+ u8 pfx_cmd;
+
+ int rc = 0;
+ int sector = 0;
+ int dn, d;
+
+
+ /* setup prefix data */
+ basepriv = (struct dasd_eckd_private *) basedev->private;
+ startpriv = (struct dasd_eckd_private *) startdev->private;
+ dedata = &pfxdata.define_extent;
+ lredata = &pfxdata.locate_record;
+
+ memset(&pfxdata, 0, sizeof(pfxdata));
+ pfxdata.format = 1; /* PFX with LRE */
+ pfxdata.base_address = basepriv->ned->unit_addr;
+ pfxdata.base_lss = basepriv->ned->ID;
+ pfxdata.validity.define_extent = 1;
+
+ /* private uid is kept up to date, conf_data may be outdated */
+ if (startpriv->uid.type != UA_BASE_DEVICE) {
+ pfxdata.validity.verify_base = 1;
+ if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
+ pfxdata.validity.hyper_pav = 1;
+ }
+
+ switch (cmd) {
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ dedata->ga_extended |= 0x42;
+ lredata->operation.orientation = 0x0;
+ lredata->operation.operation = 0x0C;
+ lredata->auxiliary.check_bytes = 0x01;
+ pfx_cmd = DASD_ECKD_CCW_PFX_READ;
+ break;
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ rc = check_XRC_on_prefix(&pfxdata, basedev);
+ dedata->ga_extended |= 0x42;
+ lredata->operation.orientation = 0x0;
+ lredata->operation.operation = 0x3F;
+ lredata->extended_operation = 0x23;
+ lredata->auxiliary.check_bytes = 0x2;
+ pfx_cmd = DASD_ECKD_CCW_PFX;
+ break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "prepare itcw, unknown opcode 0x%x", cmd);
+ BUG();
+ break;
+ }
+ if (rc)
+ return rc;
+
+ dedata->attributes.mode = 0x3; /* ECKD */
+
+ heads = basepriv->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
+
+ /* check for sequential prestage - enhance cylinder range */
+ if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+ dedata->attributes.operation == DASD_SEQ_ACCESS) {
+
+ if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+ endcyl += basepriv->attrib.nr_cyl;
+ else
+ endcyl = (basepriv->real_cyl - 1);
+ }
+
+ set_ch_t(&dedata->beg_ext, begcyl, beghead);
+ set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+ dedata->ep_format = 0x20; /* records per track is valid */
+ dedata->ep_rec_per_track = blk_per_trk;
+
+ if (rec_on_trk) {
+ switch (basepriv->rdc_data.dev_type) {
+ case 0x3390:
+ dn = ceil_quot(blksize + 6, 232);
+ d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
+ sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+ break;
+ case 0x3380:
+ d = 7 + ceil_quot(blksize + 12, 32);
+ sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+ break;
+ }
+ }
+
+ lredata->auxiliary.length_valid = 1;
+ lredata->auxiliary.length_scope = 1;
+ lredata->auxiliary.imbedded_ccw_valid = 1;
+ lredata->length = tlf;
+ lredata->imbedded_ccw = cmd;
+ lredata->count = count;
+ lredata->sector = sector;
+ set_ch_t(&lredata->seek_addr, begcyl, beghead);
+ lredata->search_arg.cyl = lredata->seek_addr.cyl;
+ lredata->search_arg.head = lredata->seek_addr.head;
+ lredata->search_arg.record = rec_on_trk;
+
+ dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
+ &pfxdata, sizeof(pfxdata), total_data_size);
+
+ return rc;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
+ struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
+{
+ struct dasd_eckd_private *private;
+ struct dasd_ccw_req *cqr;
+ struct req_iterator iter;
+ struct bio_vec *bv;
+ char *dst;
+ unsigned int trkcount, ctidaw;
+ unsigned char cmd;
+ struct dasd_device *basedev;
+ unsigned int tlf;
+ struct itcw *itcw;
+ struct tidaw *last_tidaw = NULL;
+ int itcw_op;
+ size_t itcw_size;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+ if (rq_data_dir(req) == READ) {
+ cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+ itcw_op = ITCW_OP_READ;
+ } else if (rq_data_dir(req) == WRITE) {
+ cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+ itcw_op = ITCW_OP_WRITE;
+ } else
+ return ERR_PTR(-EINVAL);
+
+ /* trackbased I/O needs address all memory via TIDAWs,
+ * not just for 64 bit addresses. This allows us to map
+ * each segment directly to one tidaw.
+ */
+ trkcount = last_trk - first_trk + 1;
+ ctidaw = 0;
+ rq_for_each_segment(bv, req, iter) {
+ ++ctidaw;
+ }
+
+ /* Allocate the ccw request. */
+ itcw_size = itcw_calc_size(0, ctidaw, 0);
+ cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+ 0, itcw_size, startdev);
+ if (IS_ERR(cqr))
+ return cqr;
+
+ cqr->cpmode = 1;
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 100*HZ;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ cqr->retries = 10;
+
+ /* transfer length factor: how many bytes to read from the last track */
+ if (first_trk == last_trk)
+ tlf = last_offs - first_offs + 1;
+ else
+ tlf = last_offs + 1;
+ tlf *= blksize;
+
+ itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
+ cqr->cpaddr = itcw_get_tcw(itcw);
+
+ if (prepare_itcw(itcw, first_trk, last_trk,
+ cmd, basedev, startdev,
+ first_offs + 1,
+ trkcount, blksize,
+ (last_rec - first_rec + 1) * blksize,
+ tlf, blk_per_trk) == -EAGAIN) {
+ /* Clock not in sync and XRC is enabled.
+ * Try again later.
+ */
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-EAGAIN);
+ }
+
+ /*
+ * A tidaw can address 4k of memory, but must not cross page boundaries
+ * We can let the block layer handle this by setting
+ * blk_queue_segment_boundary to page boundaries and
+ * blk_max_segment_size to page size when setting up the request queue.
+ */
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
+ if (IS_ERR(last_tidaw))
+ return (struct dasd_ccw_req *)last_tidaw;
+ }
+
+ last_tidaw->flags |= 0x80;
+ itcw_finalize(itcw);
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 5 * 60 * HZ; /* 5 minutes */
+ cqr->lpm = private->path_data.ppm;
+ cqr->retries = 256;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ return cqr;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req)
+{
+ int tpm, cmdrtd, cmdwtd;
+ int use_prefix;
+
+ struct dasd_eckd_private *private;
+ int fcx_in_css, fcx_in_gneq, fcx_in_features;
+ struct dasd_device *basedev;
+ sector_t first_rec, last_rec;
+ sector_t first_trk, last_trk;
+ unsigned int first_offs, last_offs;
+ unsigned int blk_per_trk, blksize;
+ int cdlspecial;
+ struct dasd_ccw_req *cqr;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+
+ /* Calculate number of blocks/records per track. */
+ blksize = block->bp_block;
+ blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
+ /* Calculate record id of first and last block. */
+ first_rec = first_trk = req->sector >> block->s2b_shift;
+ first_offs = sector_div(first_trk, blk_per_trk);
+ last_rec = last_trk =
+ (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+ last_offs = sector_div(last_trk, blk_per_trk);
+ cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
+
+ /* is transport mode supported ? */
+ fcx_in_css = css_general_characteristics.fcx;
+ fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
+ fcx_in_features = private->features.feature[40] & 0x80;
+ tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
+
+ /* is read track data and write track data in command mode supported? */
+ cmdrtd = private->features.feature[9] & 0x20;
+ cmdwtd = private->features.feature[12] & 0x40;
+ use_prefix = private->features.feature[8] & 0x01;
+
+ cqr = NULL;
+ if (cdlspecial || dasd_page_cache) {
+ /* do nothing, just fall through to the cmd mode single case */
+ } else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
+ cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ cqr = NULL;
+ } else if (use_prefix &&
+ (((rq_data_dir(req) == READ) && cmdrtd) ||
+ ((rq_data_dir(req) == WRITE) && cmdwtd))) {
+ cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ cqr = NULL;
+ }
+ if (!cqr)
+ cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ return cqr;
+}
+
static int
dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
{
@@ -1767,7 +2448,7 @@ out:
}
/*
- * Modify ccw chain in cqr so it can be started on a base device.
+ * Modify ccw/tcw in cqr so it can be started on a base device.
*
* Note that this is not enough to restart the cqr!
* Either reset cqr->startdev as well (summary unit check handling)
@@ -1777,13 +2458,24 @@ void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr)
{
struct ccw1 *ccw;
struct PFX_eckd_data *pfxdata;
-
- ccw = cqr->cpaddr;
- pfxdata = cqr->data;
-
- if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+ struct tcw *tcw;
+ struct tccb *tccb;
+ struct dcw *dcw;
+
+ if (cqr->cpmode == 1) {
+ tcw = cqr->cpaddr;
+ tccb = tcw_get_tccb(tcw);
+ dcw = (struct dcw *)&tccb->tca[0];
+ pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
pfxdata->validity.verify_base = 0;
pfxdata->validity.hyper_pav = 0;
+ } else {
+ ccw = cqr->cpaddr;
+ pfxdata = cqr->data;
+ if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+ pfxdata->validity.verify_base = 0;
+ pfxdata->validity.hyper_pav = 0;
+ }
}
}
@@ -1861,6 +2553,7 @@ dasd_eckd_release(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1868,14 +2561,15 @@ dasd_eckd_release(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1902,6 +2596,7 @@ dasd_eckd_reserve(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1909,14 +2604,15 @@ dasd_eckd_reserve(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1942,6 +2638,7 @@ dasd_eckd_steal_lock(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1949,14 +2646,15 @@ dasd_eckd_steal_lock(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_SLCK;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1990,7 +2688,7 @@ dasd_eckd_performance(struct dasd_device *device, void __user *argp)
sizeof(struct dasd_rssd_perf_stats_t)),
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
@@ -2080,9 +2778,9 @@ dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
return -EFAULT;
private->attrib = attrib;
- DEV_MESSAGE(KERN_INFO, device,
- "cache operation mode set to %x (%i cylinder prestage)",
- private->attrib.operation, private->attrib.nr_cyl);
+ dev_info(&device->cdev->dev,
+ "The DASD cache mode was set to %x (%i cylinder prestage)\n",
+ private->attrib.operation, private->attrib.nr_cyl);
return 0;
}
@@ -2133,7 +2831,7 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
/* setup CCWs for PSF + RSSD */
cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
rc = PTR_ERR(cqr);
goto out_free;
@@ -2242,11 +2940,29 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
return len;
}
+static void
+dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+ struct irb *irb, char *reason)
+{
+ int sl;
+ if (irb->esw.esw0.erw.cons) {
+ for (sl = 0; sl < 4; sl++) {
+ DBF_DEV_EVENT(DBF_EMERG, device,
+ "%s: %08x %08x %08x %08x",
+ reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
+ irb->ecw[8 * 2], irb->ecw[8 * 3]);
+ }
+ } else {
+ DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+ "SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+}
+
/*
* Print sense data and related channel program.
* Parts are printed because printk buffer is only 1024 bytes.
*/
-static void dasd_eckd_dump_sense(struct dasd_device *device,
+static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
struct dasd_ccw_req *req, struct irb *irb)
{
char *page;
@@ -2255,8 +2971,8 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
page = (char *) get_zeroed_page(GFP_ATOMIC);
if (page == NULL) {
- DEV_MESSAGE(KERN_ERR, device, " %s",
- "No memory to dump sense data");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "No memory to dump sense data\n");
return;
}
/* dump the sense data */
@@ -2265,7 +2981,7 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
- irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
+ scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n",
dev_name(&device->cdev->dev),
@@ -2341,6 +3057,147 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
free_page((unsigned long) page);
}
+
+/*
+ * Print sense data from a tcw.
+ */
+static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
+ struct dasd_ccw_req *req, struct irb *irb)
+{
+ char *page;
+ int len, sl, sct, residual;
+
+ struct tsb *tsb;
+ u8 *sense;
+
+
+ page = (char *) get_zeroed_page(GFP_ATOMIC);
+ if (page == NULL) {
+ DEV_MESSAGE(KERN_ERR, device, " %s",
+ "No memory to dump sense data");
+ return;
+ }
+ /* dump the sense data */
+ len = sprintf(page, KERN_ERR PRINTK_HEADER
+ " I/O status report for device %s:\n",
+ dev_name(&device->cdev->dev));
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " in req: %p CS: 0x%02X DS: 0x%02X "
+ "fcxs: 0x%02X schxs: 0x%02X\n", req,
+ scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+ irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " device %s: Failing TCW: %p\n",
+ dev_name(&device->cdev->dev),
+ (void *) (addr_t) irb->scsw.tm.tcw);
+
+ tsb = NULL;
+ sense = NULL;
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb(
+ (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+
+ if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->length %d\n", tsb->length);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->flags %x\n", tsb->flags);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->dcw_offset %d\n", tsb->dcw_offset);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->count %d\n", tsb->count);
+ residual = tsb->count - 28;
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " residual %d\n", residual);
+
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_time %d\n",
+ tsb->tsa.iostat.dev_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.def_time %d\n",
+ tsb->tsa.iostat.def_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.queue_time %d\n",
+ tsb->tsa.iostat.queue_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_busy_time %d\n",
+ tsb->tsa.iostat.dev_busy_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_act_time %d\n",
+ tsb->tsa.iostat.dev_act_time);
+ sense = tsb->tsa.iostat.sense;
+ break;
+ case 2: /* ts_ddpc */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.ddpc.rcq: ");
+ for (sl = 0; sl < 16; sl++) {
+ for (sct = 0; sct < 8; sct++) {
+ len += sprintf(page + len, " %02x",
+ tsb->tsa.ddpc.rcq[sl]);
+ }
+ len += sprintf(page + len, "\n");
+ }
+ sense = tsb->tsa.ddpc.sense;
+ break;
+ case 3: /* tsa_intrg */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.intrg.: not supportet yet \n");
+ break;
+ }
+
+ if (sense) {
+ for (sl = 0; sl < 4; sl++) {
+ len += sprintf(page + len,
+ KERN_ERR PRINTK_HEADER
+ " Sense(hex) %2d-%2d:",
+ (8 * sl), ((8 * sl) + 7));
+ for (sct = 0; sct < 8; sct++) {
+ len += sprintf(page + len, " %02x",
+ sense[8 * sl + sct]);
+ }
+ len += sprintf(page + len, "\n");
+ }
+
+ if (sense[27] & DASD_SENSE_BIT_0) {
+ /* 24 Byte Sense Data */
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " 24 Byte: %x MSG %x, "
+ "%s MSGb to SYSOP\n",
+ sense[7] >> 4, sense[7] & 0x0f,
+ sense[1] & 0x10 ? "" : "no");
+ } else {
+ /* 32 Byte Sense Data */
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " 32 Byte: Format: %x "
+ "Exception class %x\n",
+ sense[6] & 0x0f, sense[22] >> 4);
+ }
+ } else {
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+ } else {
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " SORRY - NO TSB DATA AVAILABLE\n");
+ }
+ printk("%s", page);
+ free_page((unsigned long) page);
+}
+
+static void dasd_eckd_dump_sense(struct dasd_device *device,
+ struct dasd_ccw_req *req, struct irb *irb)
+{
+ if (req && scsw_is_tm(&req->irb.scsw))
+ dasd_eckd_dump_sense_tcw(device, req, irb);
+ else
+ dasd_eckd_dump_sense_ccw(device, req, irb);
+}
+
+
/*
* max_blocks is dependent on the amount of storage that is available
* in the static io buffer for each device. Currently each device has
@@ -2375,6 +3232,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
.build_cp = dasd_eckd_build_alias_cp,
.free_cp = dasd_eckd_free_alias_cp,
.dump_sense = dasd_eckd_dump_sense,
+ .dump_sense_dbf = dasd_eckd_dump_sense_dbf,
.fill_info = dasd_eckd_fill_info,
.ioctl = dasd_eckd_ioctl,
};
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 2476f87d21d0..ad45bcac3ce4 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -38,8 +38,11 @@
#define DASD_ECKD_CCW_RELEASE 0x94
#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
+#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5
+#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6
#define DASD_ECKD_CCW_RESERVE 0xB4
#define DASD_ECKD_CCW_PFX 0xE7
+#define DASD_ECKD_CCW_PFX_READ 0xEA
#define DASD_ECKD_CCW_RSCK 0xF9
/*
@@ -48,6 +51,11 @@
#define PSF_ORDER_PRSSD 0x18
#define PSF_ORDER_SSC 0x1D
+/*
+ * Size that is reportet for large volumes in the old 16-bit no_cyl field
+ */
+#define LV_COMPAT_CYL 0xFFFE
+
/*****************************************************************************
* SECTION: Type Definitions
****************************************************************************/
@@ -118,7 +126,9 @@ struct DE_eckd_data {
unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
__u8 ep_format; /* Extended Parameter format byte */
__u8 ep_prio; /* Extended Parameter priority I/O byte */
- __u8 ep_reserved[6]; /* Extended Parameter Reserved */
+ __u8 ep_reserved1; /* Extended Parameter Reserved */
+ __u8 ep_rec_per_track; /* Number of records on a track */
+ __u8 ep_reserved[4]; /* Extended Parameter Reserved */
} __attribute__ ((packed));
struct LO_eckd_data {
@@ -139,11 +149,37 @@ struct LO_eckd_data {
__u16 length;
} __attribute__ ((packed));
+struct LRE_eckd_data {
+ struct {
+ unsigned char orientation:2;
+ unsigned char operation:6;
+ } __attribute__ ((packed)) operation;
+ struct {
+ unsigned char length_valid:1;
+ unsigned char length_scope:1;
+ unsigned char imbedded_ccw_valid:1;
+ unsigned char check_bytes:2;
+ unsigned char imbedded_count_valid:1;
+ unsigned char reserved:1;
+ unsigned char read_count_suffix:1;
+ } __attribute__ ((packed)) auxiliary;
+ __u8 imbedded_ccw;
+ __u8 count;
+ struct ch_t seek_addr;
+ struct chr_t search_arg;
+ __u8 sector;
+ __u16 length;
+ __u8 imbedded_count;
+ __u8 extended_operation;
+ __u16 extended_parameter_length;
+ __u8 extended_parameter[0];
+} __attribute__ ((packed));
+
/* Prefix data for format 0x00 and 0x01 */
struct PFX_eckd_data {
unsigned char format;
struct {
- unsigned char define_extend:1;
+ unsigned char define_extent:1;
unsigned char time_stamp:1;
unsigned char verify_base:1;
unsigned char hyper_pav:1;
@@ -153,9 +189,8 @@ struct PFX_eckd_data {
__u8 aux;
__u8 base_lss;
__u8 reserved[7];
- struct DE_eckd_data define_extend;
- struct LO_eckd_data locate_record;
- __u8 LO_extended_data[4];
+ struct DE_eckd_data define_extent;
+ struct LRE_eckd_data locate_record;
} __attribute__ ((packed));
struct dasd_eckd_characteristics {
@@ -228,7 +263,8 @@ struct dasd_eckd_characteristics {
__u8 factor7;
__u8 factor8;
__u8 reserved2[3];
- __u8 reserved3[10];
+ __u8 reserved3[6];
+ __u32 long_no_cyl;
} __attribute__ ((packed));
/* elements of the configuration data */
@@ -406,6 +442,7 @@ struct dasd_eckd_private {
int uses_cdl;
struct attrib_data_t attrib; /* e.g. cache operations */
struct dasd_rssd_features features;
+ u32 real_cyl;
/* alias managemnet */
struct dasd_uid uid;
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index f8e05ce98621..9ce4209552ae 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -297,11 +297,12 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
struct dasd_eer_header header;
unsigned long flags;
struct eerbuffer *eerb;
+ char *sense;
/* go through cqr chain and count the valid sense data sets */
data_size = 0;
for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
+ if (dasd_get_sense(&temp_cqr->irb))
data_size += 32;
header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
@@ -316,9 +317,11 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
list_for_each_entry(eerb, &bufferlist, list) {
dasd_eer_start_record(eerb, header.total_size);
dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
- for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
- dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32);
+ for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
+ sense = dasd_get_sense(&temp_cqr->irb);
+ if (sense)
+ dasd_eer_write_buffer(eerb, sense, 32);
+ }
dasd_eer_write_buffer(eerb, "EOR", 4);
}
spin_unlock_irqrestore(&bufferlock, flags);
@@ -451,6 +454,7 @@ int dasd_eer_enable(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
unsigned long flags;
+ struct ccw1 *ccw;
if (device->eer_cqr)
return 0;
@@ -468,10 +472,11 @@ int dasd_eer_enable(struct dasd_device *device)
cqr->expires = 10 * HZ;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS;
- cqr->cpaddr->count = SNSS_DATA_SIZE;
- cqr->cpaddr->flags = 0;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_SNSS;
+ ccw->count = SNSS_DATA_SIZE;
+ ccw->flags = 0;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 8f10000851a3..5d4193571440 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -91,14 +91,14 @@ dasd_default_erp_action(struct dasd_ccw_req *cqr)
/* just retry - there is nothing to save ... I got no sense data.... */
if (cqr->retries > 0) {
- DEV_MESSAGE (KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"default ERP called (%i retries left)",
cqr->retries);
cqr->lpm = LPM_ANYPATH;
cqr->status = DASD_CQR_FILLED;
} else {
- DEV_MESSAGE (KERN_WARNING, device, "%s",
- "default ERP called (NO retry left)");
+ dev_warn(&device->cdev->dev,
+ "default ERP called (NO retry left)\n");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock();
}
@@ -162,8 +162,21 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
device->discipline->dump_sense(device, cqr, irb);
}
+void
+dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb)
+{
+ struct dasd_device *device;
+
+ device = cqr->startdev;
+ /* dump sense data to s390 debugfeature*/
+ if (device->discipline && device->discipline->dump_sense_dbf)
+ device->discipline->dump_sense_dbf(device, cqr, irb, "log");
+}
+EXPORT_SYMBOL(dasd_log_sense_dbf);
+
EXPORT_SYMBOL(dasd_default_erp_action);
EXPORT_SYMBOL(dasd_default_erp_postaction);
EXPORT_SYMBOL(dasd_alloc_erp_request);
EXPORT_SYMBOL(dasd_free_erp_request);
EXPORT_SYMBOL(dasd_log_sense);
+
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index f1d176021694..b8aff8c1b4a6 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -128,17 +128,17 @@ dasd_fba_check_characteristics(struct dasd_device *device)
private = kzalloc(sizeof(struct dasd_fba_private),
GFP_KERNEL | GFP_DMA);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private "
- "data");
+ dev_warn(&device->cdev->dev,
+ "memory allocation failed for private data");
return -ENOMEM;
}
device->private = (void *) private;
}
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "could not allocate dasd block structure");
+ DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
+ "structure for device: %s",
+ dev_name(&device->cdev->dev));
device->private = NULL;
kfree(private);
return PTR_ERR(block);
@@ -150,9 +150,9 @@ dasd_fba_check_characteristics(struct dasd_device *device)
rdc_data = (void *) &(private->rdc_data);
rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Read device characteristics returned error %d",
- rc);
+ DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
+ "error %d for device: %s",
+ rc, dev_name(&device->cdev->dev));
device->block = NULL;
dasd_free_block(block);
device->private = NULL;
@@ -160,7 +160,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
return rc;
}
- DEV_MESSAGE(KERN_INFO, device,
+ dev_info(&device->cdev->dev,
"%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)",
cdev->id.dev_type,
cdev->id.dev_model,
@@ -180,7 +180,7 @@ static int dasd_fba_do_analysis(struct dasd_block *block)
private = (struct dasd_fba_private *) block->base->private;
rc = dasd_check_blocksize(private->rdc_data.blk_size);
if (rc) {
- DEV_MESSAGE(KERN_INFO, block->base, "unknown blocksize %d",
+ DBF_DEV_EVENT(DBF_WARNING, block->base, "unknown blocksize %d",
private->rdc_data.blk_size);
return rc;
}
@@ -215,7 +215,7 @@ dasd_fba_erp_postaction(struct dasd_ccw_req * cqr)
if (cqr->function == dasd_default_erp_action)
return dasd_default_erp_postaction;
- DEV_MESSAGE(KERN_WARNING, cqr->startdev, "unknown ERP action %p",
+ DBF_DEV_EVENT(DBF_WARNING, cqr->startdev, "unknown ERP action %p",
cqr->function);
return NULL;
}
@@ -233,9 +233,9 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device,
}
/* check for unsolicited interrupts */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"unsolicited interrupt received");
- device->discipline->dump_sense(device, NULL, irb);
+ device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited");
dasd_schedule_device_bh(device);
return;
};
@@ -437,6 +437,25 @@ dasd_fba_fill_info(struct dasd_device * device,
}
static void
+dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+ struct irb *irb, char *reason)
+{
+ int sl;
+ if (irb->esw.esw0.erw.cons) {
+ for (sl = 0; sl < 4; sl++) {
+ DBF_DEV_EVENT(DBF_EMERG, device,
+ "%s: %08x %08x %08x %08x",
+ reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
+ irb->ecw[8 * 2], irb->ecw[8 * 3]);
+ }
+ } else {
+ DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+ "SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+}
+
+
+static void
dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
struct irb *irb)
{
@@ -446,7 +465,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
page = (char *) get_zeroed_page(GFP_ATOMIC);
if (page == NULL) {
- DEV_MESSAGE(KERN_ERR, device, " %s",
+ dev_err(&device->cdev->dev,
"No memory to dump sense data");
return;
}
@@ -576,6 +595,7 @@ static struct dasd_discipline dasd_fba_discipline = {
.build_cp = dasd_fba_build_cp,
.free_cp = dasd_fba_free_cp,
.dump_sense = dasd_fba_dump_sense,
+ .dump_sense_dbf = dasd_fba_dump_sense_dbf,
.fill_info = dasd_fba_fill_info,
};
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 4a39084d9c95..c1e487f774c6 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -112,6 +112,9 @@ do { \
d_data); \
} while(0)
+/* limit size for an errorstring */
+#define ERRORLENGTH 30
+
/* definition of dbf debug levels */
#define DBF_EMERG 0 /* system is unusable */
#define DBF_ALERT 1 /* action must be taken immediately */
@@ -157,7 +160,8 @@ struct dasd_ccw_req {
struct dasd_block *block; /* the originating block device */
struct dasd_device *memdev; /* the device used to allocate this */
struct dasd_device *startdev; /* device the request is started on */
- struct ccw1 *cpaddr; /* address of channel program */
+ void *cpaddr; /* address of ccw or tcw */
+ unsigned char cpmode; /* 0 = cmd mode, 1 = itcw */
char status; /* status of this request */
short retries; /* A retry counter */
unsigned long flags; /* flags of this request */
@@ -280,6 +284,8 @@ struct dasd_discipline {
dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
struct irb *);
+ void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *,
+ struct irb *, char *);
void (*handle_unsolicited_interrupt) (struct dasd_device *,
struct irb *);
@@ -378,7 +384,7 @@ struct dasd_block {
struct block_device *bdev;
atomic_t open_count;
- unsigned long blocks; /* size of volume in blocks */
+ unsigned long long blocks; /* size of volume in blocks */
unsigned int bp_block; /* bytes per block */
unsigned int s2b_shift; /* log2 (bp_block/512) */
@@ -573,12 +579,14 @@ int dasd_generic_notify(struct ccw_device *, int);
void dasd_generic_handle_state_change(struct dasd_device *);
int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
+char *dasd_get_sense(struct irb *);
/* externals in dasd_devmap.c */
extern int dasd_max_devindex;
extern int dasd_probeonly;
extern int dasd_autodetect;
extern int dasd_nopav;
+extern int dasd_nofcx;
int dasd_devmap_init(void);
void dasd_devmap_exit(void);
@@ -623,6 +631,7 @@ struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
struct dasd_device *);
void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
+void dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb);
/* externals in dasd_3990_erp.c */
struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *);
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index b82d816d9ef7..4ce3f72ee1c1 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -9,6 +9,9 @@
*
* i/o controls for the dasd driver.
*/
+
+#define KMSG_COMPONENT "dasd"
+
#include <linux/interrupt.h>
#include <linux/major.h>
#include <linux/fs.h>
@@ -94,7 +97,8 @@ static int dasd_ioctl_quiesce(struct dasd_block *block)
if (!capable (CAP_SYS_ADMIN))
return -EACCES;
- DEV_MESSAGE(KERN_DEBUG, base, "%s", "Quiesce IO on device");
+ dev_info(&base->cdev->dev, "The DASD has been put in the quiesce "
+ "state\n");
spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
base->stopped |= DASD_STOPPED_QUIESCE;
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -103,7 +107,7 @@ static int dasd_ioctl_quiesce(struct dasd_block *block)
/*
- * Quiesce device.
+ * Resume device.
*/
static int dasd_ioctl_resume(struct dasd_block *block)
{
@@ -114,7 +118,8 @@ static int dasd_ioctl_resume(struct dasd_block *block)
if (!capable (CAP_SYS_ADMIN))
return -EACCES;
- DEV_MESSAGE(KERN_DEBUG, base, "%s", "resume IO on device");
+ dev_info(&base->cdev->dev, "I/O operations have been resumed "
+ "on the DASD\n");
spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
base->stopped &= ~DASD_STOPPED_QUIESCE;
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -140,13 +145,13 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
return -EPERM;
if (base->state != DASD_STATE_BASIC) {
- DEV_MESSAGE(KERN_WARNING, base, "%s",
- "dasd_format: device is not disabled! ");
+ dev_warn(&base->cdev->dev,
+ "The DASD cannot be formatted while it is enabled\n");
return -EBUSY;
}
DBF_DEV_EVENT(DBF_NOTICE, base,
- "formatting units %d to %d (%d B blocks) flags %d",
+ "formatting units %u to %u (%u B blocks) flags %u",
fdata->start_unit,
fdata->stop_unit, fdata->blksize, fdata->intensity);
@@ -169,10 +174,9 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
dasd_sfree_request(cqr, cqr->memdev);
if (rc) {
if (rc != -ERESTARTSYS)
- DEV_MESSAGE(KERN_ERR, base,
- " Formatting of unit %d failed "
- "with rc = %d",
- fdata->start_unit, rc);
+ dev_err(&base->cdev->dev,
+ "Formatting unit %d failed with "
+ "rc=%d\n", fdata->start_unit, rc);
return rc;
}
fdata->start_unit++;
@@ -199,8 +203,9 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
return -EFAULT;
if (bdev != bdev->bd_contains) {
- DEV_MESSAGE(KERN_WARNING, block->base, "%s",
- "Cannot low-level format a partition");
+ dev_warn(&block->base->cdev->dev,
+ "The specified DASD is a partition and cannot be "
+ "formatted\n");
return -EINVAL;
}
return dasd_format(block, &fdata);
@@ -365,9 +370,9 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
return ret;
}
-int
-dasd_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
+static int
+dasd_do_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
{
struct dasd_block *block = bdev->bd_disk->private_data;
void __user *argp = (void __user *)arg;
@@ -420,3 +425,14 @@ dasd_ioctl(struct block_device *bdev, fmode_t mode,
return -EINVAL;
}
}
+
+int dasd_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ int rc;
+
+ lock_kernel();
+ rc = dasd_do_ioctl(bdev, mode, cmd, arg);
+ unlock_kernel();
+ return rc;
+}
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index bf6fd348f20e..0aa569419d57 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -112,7 +112,7 @@ dasd_devices_show(struct seq_file *m, void *v)
seq_printf(m, "n/f ");
else
seq_printf(m,
- "at blocksize: %d, %ld blocks, %ld MB",
+ "at blocksize: %d, %lld blocks, %lld MB",
block->bp_block, block->blocks,
((block->bp_block >> 9) *
block->blocks) >> 11);
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 1fd8f2193ed8..4377e93a43d7 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -280,8 +280,11 @@ sclp_dispatch_evbufs(struct sccb_header *sccb)
rc = 0;
for (offset = sizeof(struct sccb_header); offset < sccb->length;
offset += evbuf->length) {
- /* Search for event handler */
evbuf = (struct evbuf_header *) ((addr_t) sccb + offset);
+ /* Check for malformed hardware response */
+ if (evbuf->length == 0)
+ break;
+ /* Search for event handler */
reg = NULL;
list_for_each(l, &sclp_reg_list) {
reg = list_entry(l, struct sclp_register, list);
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 506390496416..77ab6e34a100 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -19,6 +19,7 @@
#include <linux/memory.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
+#include <asm/setup.h>
#include "sclp.h"
@@ -474,6 +475,10 @@ static void __init add_memory_merged(u16 rn)
goto skip_add;
if (start + size > VMEM_MAX_PHYS)
size = VMEM_MAX_PHYS - start;
+ if (memory_end_set && (start >= memory_end))
+ goto skip_add;
+ if (memory_end_set && (start + size > memory_end))
+ size = memory_end - start;
add_memory(0, start, size);
skip_add:
first_rn = rn;
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index d0d565a05dfe..c07809c8016a 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -324,8 +324,6 @@ static inline void tape_proc_cleanup (void) {;}
#endif
/* a function for dumping device sense info */
-extern void tape_dump_sense(struct tape_device *, struct tape_request *,
- struct irb *);
extern void tape_dump_sense_dbf(struct tape_device *, struct tape_request *,
struct irb *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 22ca34361ed7..807ded5eb049 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -8,6 +8,8 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
@@ -18,8 +20,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_34XX: "
-
/*
* Pointer to debug area.
*/
@@ -203,8 +203,7 @@ tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)
tape_34xx_schedule_work(device, TO_MSEN);
} else {
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
- PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
- tape_dump_sense(device, NULL, irb);
+ tape_dump_sense_dbf(device, NULL, irb);
}
return TAPE_IO_SUCCESS;
}
@@ -226,9 +225,7 @@ tape_34xx_erp_read_opposite(struct tape_device *device,
tape_std_read_backward(device, request);
return tape_34xx_erp_retry(request);
}
- if (request->op != TO_RBA)
- PRINT_ERR("read_opposite called with state:%s\n",
- tape_op_verbose[request->op]);
+
/*
* We tried to read forward and backward, but hat no
* success -> failed.
@@ -241,13 +238,9 @@ tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request,
struct irb *irb, int no)
{
if (request->op != TO_ASSIGN) {
- PRINT_WARN("An unexpected condition #%d was caught in "
- "tape error recovery.\n", no);
- PRINT_WARN("Please report this incident.\n");
- if (request)
- PRINT_WARN("Operation of tape:%s\n",
- tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ dev_err(&device->cdev->dev, "An unexpected condition %d "
+ "occurred in tape error recovery\n", no);
+ tape_dump_sense_dbf(device, request, irb);
}
return tape_34xx_erp_failed(request, -EIO);
}
@@ -261,9 +254,8 @@ tape_34xx_erp_overrun(struct tape_device *device, struct tape_request *request,
struct irb *irb)
{
if (irb->ecw[3] == 0x40) {
- PRINT_WARN ("Data overrun error between control-unit "
- "and drive. Use a faster channel connection, "
- "if possible! \n");
+ dev_warn (&device->cdev->dev, "A data overrun occurred between"
+ " the control unit and tape unit\n");
return tape_34xx_erp_failed(request, -EIO);
}
return tape_34xx_erp_bug(device, request, irb, -1);
@@ -280,7 +272,8 @@ tape_34xx_erp_sequence(struct tape_device *device,
/*
* cu detected incorrect block-id sequence on tape.
*/
- PRINT_WARN("Illegal block-id sequence found!\n");
+ dev_warn (&device->cdev->dev, "The block ID sequence on the "
+ "tape is incorrect\n");
return tape_34xx_erp_failed(request, -EIO);
}
/*
@@ -393,8 +386,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
/* Writing at physical end of volume */
return tape_34xx_erp_failed(request, -ENOSPC);
default:
- PRINT_ERR("Invalid op in %s:%i\n",
- __func__, __LINE__);
return tape_34xx_erp_failed(request, 0);
}
}
@@ -420,7 +411,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
irb, -4);
/* data check is permanent, CU recovery has failed */
- PRINT_WARN("Permanent read error\n");
+ dev_warn (&device->cdev->dev, "A read error occurred "
+ "that cannot be recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x25:
// a write data check occurred
@@ -433,22 +425,26 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
irb, -5);
// data check is permanent, cu-recovery has failed
- PRINT_WARN("Permanent write error\n");
+ dev_warn (&device->cdev->dev, "A write error on the "
+ "tape cannot be recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x26:
/* Data Check (read opposite) occurred. */
return tape_34xx_erp_read_opposite(device, request);
case 0x28:
/* ID-Mark at tape start couldn't be written */
- PRINT_WARN("ID-Mark could not be written.\n");
+ dev_warn (&device->cdev->dev, "Writing the ID-mark "
+ "failed\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x31:
/* Tape void. Tried to read beyond end of device. */
- PRINT_WARN("Read beyond end of recorded area.\n");
+ dev_warn (&device->cdev->dev, "Reading the tape beyond"
+ " the end of the recorded area failed\n");
return tape_34xx_erp_failed(request, -ENOSPC);
case 0x41:
/* Record sequence error. */
- PRINT_WARN("Invalid block-id sequence found.\n");
+ dev_warn (&device->cdev->dev, "The tape contains an "
+ "incorrect block ID sequence\n");
return tape_34xx_erp_failed(request, -EIO);
default:
/* all data checks for 3480 should result in one of
@@ -470,16 +466,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
switch (sense[3]) {
case 0x00:
/* Unit check with erpa code 0. Report and ignore. */
- PRINT_WARN("Non-error sense was found. "
- "Unit-check will be ignored.\n");
return TAPE_IO_SUCCESS;
case 0x21:
/*
* Data streaming not operational. CU will switch to
* interlock mode. Reissue the command.
*/
- PRINT_WARN("Data streaming not operational. "
- "Switching to interlock-mode.\n");
return tape_34xx_erp_retry(request);
case 0x22:
/*
@@ -487,11 +479,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* error on the lower interface, internal path not usable,
* or error during cartridge load.
*/
- PRINT_WARN("A path equipment check occurred. One of the "
- "following conditions occurred:\n");
- PRINT_WARN("drive adapter error, buffer error on the lower "
- "interface, internal path not usable, error "
- "during cartridge load.\n");
+ dev_warn (&device->cdev->dev, "A path equipment check occurred"
+ " for the tape device\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x24:
/*
@@ -514,7 +503,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* but the hardware isn't capable to do idrc, or a perform
* subsystem func is issued and the CU is not on-line.
*/
- PRINT_WARN ("Function incompatible. Try to switch off idrc\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x2a:
/*
@@ -552,23 +540,26 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* reading the format id mark or that that format specified
* is not supported by the drive.
*/
- PRINT_WARN("Drive not capable processing the tape format!\n");
+ dev_warn (&device->cdev->dev, "The tape unit cannot process "
+ "the tape format\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
case 0x30:
/* The medium is write protected. */
- PRINT_WARN("Medium is write protected!\n");
+ dev_warn (&device->cdev->dev, "The tape medium is write-"
+ "protected\n");
return tape_34xx_erp_failed(request, -EACCES);
case 0x32:
// Tension loss. We cannot recover this, it's an I/O error.
- PRINT_WARN("The drive lost tape tension.\n");
+ dev_warn (&device->cdev->dev, "The tape does not have the "
+ "required tape tension\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x33:
/*
* Load Failure. The cartridge was not inserted correctly or
* the tape is not threaded correctly.
*/
- PRINT_WARN("Cartridge load failure. Reload the cartridge "
- "and try again.\n");
+ dev_warn (&device->cdev->dev, "The tape unit failed to load"
+ " the cartridge\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x34:
@@ -576,8 +567,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Unload failure. The drive cannot maintain tape tension
* and control tape movement during an unload operation.
*/
- PRINT_WARN("Failure during cartridge unload. "
- "Please try manually.\n");
+ dev_warn (&device->cdev->dev, "Automatic unloading of the tape"
+ " cartridge failed\n");
if (request->op == TO_RUN)
return tape_34xx_erp_failed(request, -EIO);
return tape_34xx_erp_bug(device, request, irb, sense[3]);
@@ -589,8 +580,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* - the cartridge loader does not respond correctly
* - a failure occurs during an index, load, or unload cycle
*/
- PRINT_WARN("Equipment check! Please check the drive and "
- "the cartridge loader.\n");
+ dev_warn (&device->cdev->dev, "An equipment check has occurred"
+ " on the tape unit\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x36:
if (device->cdev->id.driver_info == tape_3490)
@@ -603,7 +594,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Tape length error. The tape is shorter than reported in
* the beginning-of-tape data.
*/
- PRINT_WARN("Tape length error.\n");
+ dev_warn (&device->cdev->dev, "The tape information states an"
+ " incorrect length\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x38:
/*
@@ -620,12 +612,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_failed(request, -EIO);
case 0x3a:
/* Drive switched to not ready. */
- PRINT_WARN("Drive not ready. Turn the ready/not ready switch "
- "to ready position and try again.\n");
+ dev_warn (&device->cdev->dev, "The tape unit is not ready\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x3b:
/* Manual rewind or unload. This causes an I/O error. */
- PRINT_WARN("Medium was rewound or unloaded manually.\n");
+ dev_warn (&device->cdev->dev, "The tape medium has been "
+ "rewound or unloaded manually\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x42:
@@ -633,7 +625,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Degraded mode. A condition that can cause degraded
* performance is detected.
*/
- PRINT_WARN("Subsystem is running in degraded mode.\n");
+ dev_warn (&device->cdev->dev, "The tape subsystem is running "
+ "in degraded mode\n");
return tape_34xx_erp_retry(request);
case 0x43:
/* Drive not ready. */
@@ -652,7 +645,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
break;
}
}
- PRINT_WARN("The drive is not ready.\n");
return tape_34xx_erp_failed(request, -ENOMEDIUM);
case 0x44:
/* Locate Block unsuccessful. */
@@ -663,7 +655,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_failed(request, -EIO);
case 0x45:
/* The drive is assigned to a different channel path. */
- PRINT_WARN("The drive is assigned elsewhere.\n");
+ dev_warn (&device->cdev->dev, "The tape unit is already "
+ "assigned\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x46:
/*
@@ -671,11 +664,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* the power supply may be switched off or
* the drive address may not be set correctly.
*/
- PRINT_WARN("The drive is not on-line.");
+ dev_warn (&device->cdev->dev, "The tape unit is not online\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x47:
/* Volume fenced. CU reports volume integrity is lost. */
- PRINT_WARN("Volume fenced. The volume integrity is lost.\n");
+ dev_warn (&device->cdev->dev, "The control unit has fenced "
+ "access to the tape volume\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x48:
@@ -683,20 +677,21 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_retry(request);
case 0x49:
/* Bus out check. A parity check error on the bus was found. */
- PRINT_WARN("Bus out check. A data transfer over the bus "
- "has been corrupted.\n");
+ dev_warn (&device->cdev->dev, "A parity error occurred on the "
+ "tape bus\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4a:
/* Control unit erp failed. */
- PRINT_WARN("The control unit I/O error recovery failed.\n");
+ dev_warn (&device->cdev->dev, "I/O error recovery failed on "
+ "the tape control unit\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4b:
/*
* CU and drive incompatible. The drive requests micro-program
* patches, which are not available on the CU.
*/
- PRINT_WARN("The drive needs microprogram patches from the "
- "control unit, which are not available.\n");
+ dev_warn (&device->cdev->dev, "The tape unit requires a "
+ "firmware update\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4c:
/*
@@ -721,8 +716,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* the block to be written is larger than allowed for
* buffered mode.
*/
- PRINT_WARN("Maximum block size for buffered "
- "mode exceeded.\n");
+ dev_warn (&device->cdev->dev, "The maximum block size"
+ " for buffered mode is exceeded\n");
return tape_34xx_erp_failed(request, -ENOBUFS);
}
/* This erpa is reserved for 3480. */
@@ -759,22 +754,20 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_retry(request);
case 0x55:
/* Channel interface recovery (permanent). */
- PRINT_WARN("A permanent channel interface error occurred.\n");
+ dev_warn (&device->cdev->dev, "A channel interface error cannot be"
+ " recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x56:
/* Channel protocol error. */
- PRINT_WARN("A channel protocol error occurred.\n");
+ dev_warn (&device->cdev->dev, "A channel protocol error "
+ "occurred\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x57:
if (device->cdev->id.driver_info == tape_3480) {
/* Attention intercept. */
- PRINT_WARN("An attention intercept occurred, "
- "which will be recovered.\n");
return tape_34xx_erp_retry(request);
} else {
/* Global status intercept. */
- PRINT_WARN("An global status intercept was received, "
- "which will be recovered.\n");
return tape_34xx_erp_retry(request);
}
case 0x5a:
@@ -782,42 +775,31 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Tape length incompatible. The tape inserted is too long,
* which could cause damage to the tape or the drive.
*/
- PRINT_WARN("Tape Length Incompatible\n");
- PRINT_WARN("Tape length exceeds IBM enhanced capacity "
- "cartdridge length or a medium\n");
- PRINT_WARN("with EC-CST identification mark has been mounted "
- "in a device that writes\n");
- PRINT_WARN("3480 or 3480 XF format.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support "
+ "the tape length\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5b:
/* Format 3480 XF incompatible */
if (sense[1] & SENSE_BEGINNING_OF_TAPE)
/* The tape will get overwritten. */
return tape_34xx_erp_retry(request);
- PRINT_WARN("Format 3480 XF Incompatible\n");
- PRINT_WARN("Medium has been created in 3480 format. "
- "To change the format writes\n");
- PRINT_WARN("must be issued at BOT.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " format 3480 XF\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5c:
/* Format 3480-2 XF incompatible */
- PRINT_WARN("Format 3480-2 XF Incompatible\n");
- PRINT_WARN("Device can only read 3480 or 3480 XF format.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support tape "
+ "format 3480-2 XF\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5d:
/* Tape length violation. */
- PRINT_WARN("Tape Length Violation\n");
- PRINT_WARN("The mounted tape exceeds IBM Enhanced Capacity "
- "Cartdridge System Tape length.\n");
- PRINT_WARN("This may cause damage to the drive or tape when "
- "processing to the EOV\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " the current tape length\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
case 0x5e:
/* Compaction algorithm incompatible. */
- PRINT_WARN("Compaction Algorithm Incompatible\n");
- PRINT_WARN("The volume is recorded using an incompatible "
- "compaction algorithm,\n");
- PRINT_WARN("which is not supported by the device.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " the compaction algorithm\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
/* The following erpas should have been covered earlier. */
@@ -848,7 +830,6 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request,
(irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
(request->op == TO_WRI)) {
/* Write at end of volume */
- PRINT_INFO("End of volume\n"); /* XXX */
return tape_34xx_erp_failed(request, -ENOSPC);
}
@@ -869,9 +850,7 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request,
}
DBF_EVENT(6, "xunknownirq\n");
- PRINT_ERR("Unexpected interrupt.\n");
- PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ tape_dump_sense_dbf(device, request, irb);
return TAPE_IO_STOP;
}
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 71605a179d65..5a5bb97a081a 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -8,12 +8,15 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
#include <asm/ebcdic.h>
#define TAPE_DBF_AREA tape_3590_dbf
+#define BUFSIZE 512 /* size of buffers for dynamic generated messages */
#include "tape.h"
#include "tape_std.h"
@@ -36,7 +39,7 @@ EXPORT_SYMBOL(TAPE_DBF_AREA);
* - Read Alternate: implemented
*******************************************************************/
-#define PRINTK_HEADER "TAPE_3590: "
+#define KMSG_COMPONENT "tape"
static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
[0x00] = "",
@@ -726,7 +729,7 @@ static void tape_3590_med_state_set(struct tape_device *device,
}
c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
if (sense->flags & MSENSE_CRYPT_MASK) {
- PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
+ DBF_EVENT(6, "Medium is encrypted (%04x)\n", sense->flags);
c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
} else {
DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
@@ -847,8 +850,7 @@ tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb)
tape_3590_schedule_work(device, TO_READ_ATTMSG);
} else {
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
- PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
- tape_dump_sense(device, NULL, irb);
+ tape_dump_sense_dbf(device, NULL, irb);
}
/* check medium state */
tape_3590_schedule_work(device, TO_MSEN);
@@ -876,8 +878,6 @@ tape_3590_erp_basic(struct tape_device *device, struct tape_request *request,
case SENSE_BRA_DRE:
return tape_3590_erp_failed(device, request, irb, rc);
default:
- PRINT_ERR("Unknown BRA %x - This should not happen!\n",
- sense->bra);
BUG();
return TAPE_IO_STOP;
}
@@ -910,7 +910,8 @@ tape_3590_erp_swap(struct tape_device *device, struct tape_request *request,
* should proceed with the new tape... this
* should probably be done in user space!
*/
- PRINT_WARN("(%s): Swap Tape Device!\n", dev_name(&device->cdev->dev));
+ dev_warn (&device->cdev->dev, "The tape medium must be loaded into a "
+ "different tape unit\n");
return tape_3590_erp_basic(device, request, irb, -EIO);
}
@@ -985,8 +986,6 @@ tape_3590_erp_read_opposite(struct tape_device *device,
return tape_3590_erp_failed(device, request, irb, -EIO);
break;
default:
- PRINT_WARN("read_opposite_recovery_called_with_op: %s\n",
- tape_op_verbose[request->op]);
return tape_3590_erp_failed(device, request, irb, -EIO);
}
}
@@ -998,50 +997,61 @@ static void
tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f70.emc) {
case 0x02:
- PRINT_WARN("(%s): Data degraded\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Data degraded");
break;
case 0x03:
- PRINT_WARN("(%s): Data degraded in partion %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+ snprintf(exception, BUFSIZE, "Data degraded in partion %i",
+ sense->fmt.f70.mp);
break;
case 0x04:
- PRINT_WARN("(%s): Medium degraded\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Medium degraded");
break;
case 0x05:
- PRINT_WARN("(%s): Medium degraded in partition %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+ snprintf(exception, BUFSIZE, "Medium degraded in partition %i",
+ sense->fmt.f70.mp);
break;
case 0x06:
- PRINT_WARN("(%s): Block 0 Error\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Block 0 Error");
break;
case 0x07:
- PRINT_WARN("(%s): Medium Exception 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.md);
+ snprintf(exception, BUFSIZE, "Medium Exception 0x%02x",
+ sense->fmt.f70.md);
break;
default:
- PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f70.emc);
break;
}
/* Service Message */
switch (sense->fmt.f70.smc) {
case 0x02:
- PRINT_WARN("(%s): Reference Media maintenance procedure %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.md);
+ snprintf(service, BUFSIZE, "Reference Media maintenance "
+ "procedure %i", sense->fmt.f70.md);
break;
default:
- PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f70.smc);
break;
}
+
+ dev_warn (&device->cdev->dev, "Tape media information: exception %s, "
+ "service %s\n", exception, service);
+
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1051,108 +1061,108 @@ static void
tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f71.emc) {
case 0x01:
- PRINT_WARN("(%s): Effect of failure is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Effect of failure is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): CU Exception - no performance impact\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "CU Exception - no performance "
+ "impact");
break;
case 0x03:
- PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on channel "
+ "interface 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x04:
- PRINT_WARN("(%s): CU Exception on device path 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on device path "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
case 0x05:
- PRINT_WARN("(%s): CU Exception on library path 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on library path "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
case 0x06:
- PRINT_WARN("(%s): CU Exception on node 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on node 0x%02x",
+ sense->fmt.f71.md[0]);
break;
case 0x07:
- PRINT_WARN("(%s): CU Exception on partition 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on partition "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
default:
- PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f71.emc);
}
/* Service Message */
switch (sense->fmt.f71.smc) {
case 0x01:
- PRINT_WARN("(%s): Repair impact is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair impact is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): Repair will not impact cu performance\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will not impact cu "
+ "performance");
break;
case 0x03:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable node "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable node "
+ "0x%x on CU", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable nodes "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "nodes (0x%x-0x%x) on CU", sense->fmt.f71.md[1],
+ sense->fmt.f71.md[2]);
break;
case 0x04:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable cannel path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path 0x%x on CU",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable cannel paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable cannel"
+ " paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x05:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable device path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable device"
+ " path 0x%x on CU", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable device paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable device"
+ " paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x06:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable library path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "library path 0x%x on CU",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable library paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "library paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x07:
- PRINT_WARN("(%s): Repair will disable access to CU\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will disable access to CU");
break;
default:
- PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f71.smc);
}
+
+ dev_warn (&device->cdev->dev, "I/O subsystem information: exception"
+ " %s, service %s\n", exception, service);
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1162,111 +1172,109 @@ static void
tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f71.emc) {
case 0x01:
- PRINT_WARN("(%s): Effect of failure is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Effect of failure is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): DV Exception - no performance impact\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception - no performance"
+ " impact");
break;
case 0x03:
- PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on channel "
+ "interface 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x04:
- PRINT_WARN("(%s): DV Exception on loader 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on loader 0x%02x",
+ sense->fmt.f71.md[0]);
break;
case 0x05:
- PRINT_WARN("(%s): DV Exception on message display 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on message display"
+ " 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x06:
- PRINT_WARN("(%s): DV Exception in tape path\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception in tape path");
break;
case 0x07:
- PRINT_WARN("(%s): DV Exception in drive\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception in drive");
break;
default:
- PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f71.emc);
}
/* Service Message */
switch (sense->fmt.f71.smc) {
case 0x01:
- PRINT_WARN("(%s): Repair impact is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair impact is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): Repair will not impact device performance\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will not impact device "
+ "performance");
break;
case 0x03:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable channel path "
- "0x%x on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path 0x%x on DV",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable channel path "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x04:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable interface 0x%x "
- "on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "interface 0x%x on DV", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable interfaces "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "interfaces (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x05:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable loader 0x%x "
- "on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable loader"
+ " 0x%x on DV", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable loader "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable loader"
+ " (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x07:
- PRINT_WARN("(%s): Repair will disable access to DV\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will disable access to DV");
break;
case 0x08:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable message "
- "display 0x%x on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "message display 0x%x on DV",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable message "
- "displays (0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "message displays (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x09:
- PRINT_WARN("(%s): Clean DV\n", dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Clean DV");
break;
default:
- PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f71.smc);
}
+
+ dev_warn (&device->cdev->dev, "Device subsystem information: exception"
+ " %s, service %s\n", exception, service);
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1282,46 +1290,44 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
return;
if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) {
if (tape_3590_msg[sense->mc] != NULL)
- PRINT_WARN("(%s): %s\n", dev_name(&device->cdev->dev),
- tape_3590_msg[sense->mc]);
- else {
- PRINT_WARN("(%s): Message Code 0x%x\n",
- dev_name(&device->cdev->dev), sense->mc);
- }
+ dev_warn (&device->cdev->dev, "The tape unit has "
+ "issued sense message %s\n",
+ tape_3590_msg[sense->mc]);
+ else
+ dev_warn (&device->cdev->dev, "The tape unit has "
+ "issued an unknown sense message code 0x%x\n",
+ sense->mc);
return;
}
if (sense->mc == 0xf0) {
/* Standard Media Information Message */
- PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, "
- "RC=%02x-%04x-%02x\n", dev_name(&device->cdev->dev),
- sense->fmt.f70.sev, sense->mc,
- sense->fmt.f70.emc, sense->fmt.f70.smc,
- sense->fmt.f70.refcode, sense->fmt.f70.mid,
- sense->fmt.f70.fid);
+ dev_warn (&device->cdev->dev, "MIM SEV=%i, MC=%02x, ES=%x/%x, "
+ "RC=%02x-%04x-%02x\n", sense->fmt.f70.sev, sense->mc,
+ sense->fmt.f70.emc, sense->fmt.f70.smc,
+ sense->fmt.f70.refcode, sense->fmt.f70.mid,
+ sense->fmt.f70.fid);
tape_3590_print_mim_msg_f0(device, irb);
return;
}
if (sense->mc == 0xf1) {
/* Standard I/O Subsystem Service Information Message */
- PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, "
- "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.sev,
- device->cdev->id.dev_model,
- sense->mc, sense->fmt.f71.emc,
- sense->fmt.f71.smc, sense->fmt.f71.refcode1,
- sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+ dev_warn (&device->cdev->dev, "IOSIM SEV=%i, DEVTYPE=3590/%02x,"
+ " MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+ sense->fmt.f71.sev, device->cdev->id.dev_model,
+ sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+ sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+ sense->fmt.f71.refcode3);
tape_3590_print_io_sim_msg_f1(device, irb);
return;
}
if (sense->mc == 0xf2) {
/* Standard Device Service Information Message */
- PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, "
- "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.sev,
- device->cdev->id.dev_model,
- sense->mc, sense->fmt.f71.emc,
- sense->fmt.f71.smc, sense->fmt.f71.refcode1,
- sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+ dev_warn (&device->cdev->dev, "DEVSIM SEV=%i, DEVTYPE=3590/%02x"
+ ", MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+ sense->fmt.f71.sev, device->cdev->id.dev_model,
+ sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+ sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+ sense->fmt.f71.refcode3);
tape_3590_print_dev_sim_msg_f2(device, irb);
return;
}
@@ -1329,8 +1335,8 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
/* Standard Library Service Information Message */
return;
}
- PRINT_WARN("(%s): Device Message(%x)\n",
- dev_name(&device->cdev->dev), sense->mc);
+ dev_warn (&device->cdev->dev, "The tape unit has issued an unknown "
+ "sense message code %x\n", sense->mc);
}
static int tape_3590_crypt_error(struct tape_device *device,
@@ -1355,9 +1361,8 @@ static int tape_3590_crypt_error(struct tape_device *device,
/* No connection to EKM */
return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
- PRINT_ERR("(%s): Unable to get encryption key from EKM\n", bus_id);
- PRINT_ERR("(%s): CU=%02X DRIVE=%06X EKM=%02X:%04X\n", bus_id, cu_rc,
- drv_rc, ekm_rc1, ekm_rc2);
+ dev_err (&device->cdev->dev, "The tape unit failed to obtain the "
+ "encryption key from EKM\n");
return tape_3590_erp_basic(device, request, irb, -ENOKEY);
}
@@ -1443,8 +1448,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
* print additional msg since default msg
* "device intervention" is not very meaningfull
*/
- PRINT_WARN("(%s): Tape operation when medium not loaded\n",
- dev_name(&device->cdev->dev));
tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF);
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
@@ -1490,19 +1493,13 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
case 0x6020:
- PRINT_WARN("(%s): Cartridge of wrong type ?\n",
- dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
case 0x8011:
- PRINT_WARN("(%s): Another host has reserved the tape device\n",
- dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EPERM);
case 0x8013:
- PRINT_WARN("(%s): Another host has privileged access to the "
- "tape device\n", dev_name(&device->cdev->dev));
- PRINT_WARN("(%s): To solve the problem unload the current "
- "cartridge!\n", dev_name(&device->cdev->dev));
+ dev_warn (&device->cdev->dev, "A different host has privileged"
+ " access to the tape unit\n");
return tape_3590_erp_basic(device, request, irb, -EPERM);
default:
return tape_3590_erp_basic(device, request, irb, -EIO);
@@ -1552,9 +1549,7 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request,
}
DBF_EVENT(6, "xunknownirq\n");
- PRINT_ERR("Unexpected interrupt.\n");
- PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ tape_dump_sense_dbf(device, request, irb);
return TAPE_IO_STOP;
}
@@ -1609,7 +1604,6 @@ tape_3590_setup_device(struct tape_device *device)
if (rc)
goto fail_rdc_data;
if (rdc_data->data[31] == 0x13) {
- PRINT_INFO("Device has crypto support\n");
data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
tape_3592_disable_crypt(device);
} else {
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index ae18baf59f06..f32e89e7c4f2 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -10,6 +10,8 @@
* Stefan Bader <shbader@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/blkdev.h>
@@ -23,8 +25,6 @@
#include "tape.h"
-#define PRINTK_HEADER "TAPE_BLOCK: "
-
#define TAPEBLOCK_MAX_SEC 100
#define TAPEBLOCK_MIN_REQUEUE 3
@@ -279,8 +279,6 @@ tapeblock_cleanup_device(struct tape_device *device)
tape_put_device(device);
if (!device->blk_data.disk) {
- PRINT_ERR("(%s): No gendisk to clean up!\n",
- dev_name(&device->cdev->dev));
goto cleanup_queue;
}
@@ -314,7 +312,8 @@ tapeblock_revalidate_disk(struct gendisk *disk)
if (!device->blk_data.medium_changed)
return 0;
- PRINT_INFO("Detecting media size...\n");
+ dev_info(&device->cdev->dev, "Determining the size of the recorded "
+ "area...\n");
rc = tape_mtop(device, MTFSFM, 1);
if (rc)
return rc;
@@ -341,7 +340,8 @@ tapeblock_revalidate_disk(struct gendisk *disk)
device->bof = rc;
nr_of_blks -= rc;
- PRINT_INFO("Found %i blocks on media\n", nr_of_blks);
+ dev_info(&device->cdev->dev, "The size of the recorded area is %i "
+ "blocks\n", nr_of_blks);
set_capacity(device->blk_data.disk,
nr_of_blks*(TAPEBLOCK_HSEC_SIZE/512));
@@ -376,8 +376,8 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)
if (device->required_tapemarks) {
DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
- PRINT_ERR("TBLOCK: Refusing to open tape with missing"
- " end of file marks.\n");
+ dev_warn(&device->cdev->dev, "Opening the tape failed because"
+ " of missing end-of-file marks\n");
rc = -EPERM;
goto put_device;
}
@@ -452,7 +452,6 @@ tapeblock_ioctl(
rc = -EINVAL;
break;
default:
- PRINT_WARN("invalid ioctl 0x%x\n", command);
rc = -EINVAL;
}
@@ -474,7 +473,6 @@ tapeblock_init(void)
if (tapeblock_major == 0)
tapeblock_major = rc;
- PRINT_INFO("tape gets major %d for block device\n", tapeblock_major);
return 0;
}
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index be0ce2215c8d..31566c55adfe 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -24,8 +24,6 @@
#include "tape_std.h"
#include "tape_class.h"
-#define PRINTK_HEADER "TAPE_CHAR: "
-
#define TAPECHAR_MAJOR 0 /* get dynamic major */
/*
@@ -102,8 +100,6 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
if (block_size > MAX_BLOCKSIZE) {
DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n",
block_size, MAX_BLOCKSIZE);
- PRINT_ERR("Invalid blocksize (%zd> %d)\n",
- block_size, MAX_BLOCKSIZE);
return -EINVAL;
}
@@ -485,7 +481,6 @@ tapechar_init (void)
return -1;
tapechar_major = MAJOR(dev);
- PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev));
return 0;
}
@@ -496,7 +491,5 @@ tapechar_init (void)
void
tapechar_exit(void)
{
- PRINT_INFO("tape releases major %d for character devices\n",
- tapechar_major);
unregister_chrdev_region(MKDEV(tapechar_major, 0), 256);
}
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index f9bb51fa7f5b..1b6a24412465 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -11,6 +11,7 @@
* Stefan Bader <shbader@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
#include <linux/module.h>
#include <linux/init.h> // for kernel parameters
#include <linux/kmod.h> // for requesting modules
@@ -25,7 +26,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_CORE: "
#define LONG_BUSY_TIMEOUT 180 /* seconds */
static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
@@ -214,13 +214,13 @@ tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
switch(newstate){
case MS_UNLOADED:
device->tape_generic_status |= GMT_DR_OPEN(~0);
- PRINT_INFO("(%s): Tape is unloaded\n",
- dev_name(&device->cdev->dev));
+ dev_info(&device->cdev->dev, "The tape cartridge has been "
+ "successfully unloaded\n");
break;
case MS_LOADED:
device->tape_generic_status &= ~GMT_DR_OPEN(~0);
- PRINT_INFO("(%s): Tape has been mounted\n",
- dev_name(&device->cdev->dev));
+ dev_info(&device->cdev->dev, "A tape cartridge has been "
+ "mounted\n");
break;
default:
// print nothing
@@ -333,7 +333,6 @@ tape_generic_online(struct tape_device *device,
/* Let the discipline have a go at the device. */
device->discipline = discipline;
if (!try_module_get(discipline->owner)) {
- PRINT_ERR("Cannot get module. Module gone.\n");
return -EINVAL;
}
@@ -391,7 +390,6 @@ int
tape_generic_offline(struct tape_device *device)
{
if (!device) {
- PRINT_ERR("tape_generic_offline: no such device\n");
return -ENODEV;
}
@@ -413,9 +411,6 @@ tape_generic_offline(struct tape_device *device)
DBF_EVENT(3, "(%08x): Set offline failed "
"- drive in use.\n",
device->cdev_id);
- PRINT_WARN("(%s): Set offline failed "
- "- drive in use.\n",
- dev_name(&device->cdev->dev));
spin_unlock_irq(get_ccwdev_lock(device->cdev));
return -EBUSY;
}
@@ -435,14 +430,11 @@ tape_alloc_device(void)
device = kzalloc(sizeof(struct tape_device), GFP_KERNEL);
if (device == NULL) {
DBF_EXCEPTION(2, "ti:no mem\n");
- PRINT_INFO ("can't allocate memory for "
- "tape info structure\n");
return ERR_PTR(-ENOMEM);
}
device->modeset_byte = kmalloc(1, GFP_KERNEL | GFP_DMA);
if (device->modeset_byte == NULL) {
DBF_EXCEPTION(2, "ti:no mem\n");
- PRINT_INFO("can't allocate memory for modeset byte\n");
kfree(device);
return ERR_PTR(-ENOMEM);
}
@@ -490,7 +482,6 @@ tape_put_device(struct tape_device *device)
} else {
if (remain < 0) {
DBF_EVENT(4, "put device without reference\n");
- PRINT_ERR("put device without reference\n");
} else {
DBF_EVENT(4, "tape_free_device(%p)\n", device);
kfree(device->modeset_byte);
@@ -538,8 +529,6 @@ tape_generic_probe(struct ccw_device *cdev)
ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
if (ret) {
tape_put_device(device);
- PRINT_ERR("probe failed for tape device %s\n",
- dev_name(&cdev->dev));
return ret;
}
cdev->dev.driver_data = device;
@@ -547,7 +536,6 @@ tape_generic_probe(struct ccw_device *cdev)
device->cdev = cdev;
ccw_device_get_id(cdev, &dev_id);
device->cdev_id = devid_to_int(&dev_id);
- PRINT_INFO("tape device %s found\n", dev_name(&cdev->dev));
return ret;
}
@@ -584,7 +572,6 @@ tape_generic_remove(struct ccw_device *cdev)
device = cdev->dev.driver_data;
if (!device) {
- PRINT_ERR("No device pointer in tape_generic_remove!\n");
return;
}
DBF_LH(3, "(%08x): tape_generic_remove(%p)\n", device->cdev_id, cdev);
@@ -615,10 +602,8 @@ tape_generic_remove(struct ccw_device *cdev)
*/
DBF_EVENT(3, "(%08x): Drive in use vanished!\n",
device->cdev_id);
- PRINT_WARN("(%s): Drive in use vanished - "
- "expect trouble!\n",
- dev_name(&device->cdev->dev));
- PRINT_WARN("State was %i\n", device->tape_state);
+ dev_warn(&device->cdev->dev, "A tape unit was detached"
+ " while in use\n");
tape_state_set(device, TS_NOT_OPER);
__tape_discard_requests(device);
spin_unlock_irq(get_ccwdev_lock(device->cdev));
@@ -830,30 +815,6 @@ __tape_end_request(
}
/*
- * Write sense data to console/dbf
- */
-void
-tape_dump_sense(struct tape_device* device, struct tape_request *request,
- struct irb *irb)
-{
- unsigned int *sptr;
-
- PRINT_INFO("-------------------------------------------------\n");
- PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\n",
- irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
- PRINT_INFO("DEVICE: %s\n", dev_name(&device->cdev->dev));
- if (request != NULL)
- PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]);
-
- sptr = (unsigned int *) irb->ecw;
- PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
- sptr[0], sptr[1], sptr[2], sptr[3]);
- PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
- sptr[4], sptr[5], sptr[6], sptr[7]);
- PRINT_INFO("--------------------------------------------------\n");
-}
-
-/*
* Write sense data to dbf
*/
void
@@ -1051,8 +1012,6 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
device = (struct tape_device *) cdev->dev.driver_data;
if (device == NULL) {
- PRINT_ERR("could not get device structure for %s "
- "in interrupt\n", dev_name(&cdev->dev));
return;
}
request = (struct tape_request *) intparm;
@@ -1064,13 +1023,13 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
/* FIXME: What to do with the request? */
switch (PTR_ERR(irb)) {
case -ETIMEDOUT:
- PRINT_WARN("(%s): Request timed out\n",
+ DBF_LH(1, "(%s): Request timed out\n",
dev_name(&cdev->dev));
case -EIO:
__tape_end_request(device, request, -EIO);
break;
default:
- PRINT_ERR("(%s): Unexpected i/o error %li\n",
+ DBF_LH(1, "(%s): Unexpected i/o error %li\n",
dev_name(&cdev->dev),
PTR_ERR(irb));
}
@@ -1182,8 +1141,6 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
default:
if (rc > 0) {
DBF_EVENT(6, "xunknownrc\n");
- PRINT_ERR("Invalid return code from discipline "
- "interrupt function.\n");
__tape_end_request(device, request, -EIO);
} else {
__tape_end_request(device, request, rc);
@@ -1323,7 +1280,6 @@ EXPORT_SYMBOL(tape_state_set);
EXPORT_SYMBOL(tape_med_state_set);
EXPORT_SYMBOL(tape_alloc_request);
EXPORT_SYMBOL(tape_free_request);
-EXPORT_SYMBOL(tape_dump_sense);
EXPORT_SYMBOL(tape_dump_sense_dbf);
EXPORT_SYMBOL(tape_do_io);
EXPORT_SYMBOL(tape_do_io_async);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index 8a376af926a7..202f42132939 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -20,8 +20,6 @@
#include "tape.h"
-#define PRINTK_HEADER "TAPE_PROC: "
-
static const char *tape_med_st_verbose[MS_SIZE] =
{
[MS_UNKNOWN] = "UNKNOWN ",
@@ -128,7 +126,6 @@ tape_proc_init(void)
proc_create("tapedevices", S_IFREG | S_IRUGO | S_IWUSR, NULL,
&tape_proc_ops);
if (tape_proc_devices == NULL) {
- PRINT_WARN("tape: Cannot register procfs entry tapedevices\n");
return;
}
}
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index 5bd573d144d6..44dd0f80c847 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -26,8 +26,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_STD: "
-
/*
* tape_std_assign
*/
@@ -46,9 +44,8 @@ tape_std_assign_timeout(unsigned long data)
device->cdev_id);
rc = tape_cancel_io(device, request);
if(rc)
- PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n",
+ DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n",
dev_name(&device->cdev->dev), rc);
-
}
int
@@ -82,8 +79,6 @@ tape_std_assign(struct tape_device *device)
del_timer(&timeout);
if (rc != 0) {
- PRINT_WARN("%s: assign failed - device might be busy\n",
- dev_name(&device->cdev->dev));
DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
device->cdev_id);
} else {
@@ -105,8 +100,6 @@ tape_std_unassign (struct tape_device *device)
if (device->tape_state == TS_NOT_OPER) {
DBF_EVENT(3, "(%08x): Can't unassign device\n",
device->cdev_id);
- PRINT_WARN("(%s): Can't unassign device - device gone\n",
- dev_name(&device->cdev->dev));
return -EIO;
}
@@ -120,8 +113,6 @@ tape_std_unassign (struct tape_device *device)
if ((rc = tape_do_io(device, request)) != 0) {
DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
- PRINT_WARN("%s: Unassign failed\n",
- dev_name(&device->cdev->dev));
} else {
DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
}
@@ -242,8 +233,6 @@ tape_std_mtsetblk(struct tape_device *device, int count)
if (count > MAX_BLOCKSIZE) {
DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
count, MAX_BLOCKSIZE);
- PRINT_ERR("Invalid block size (%d > %d) given.\n",
- count, MAX_BLOCKSIZE);
return -EINVAL;
}
@@ -633,14 +622,6 @@ tape_std_mtcompression(struct tape_device *device, int mt_count)
if (mt_count < 0 || mt_count > 1) {
DBF_EXCEPTION(6, "xcom parm\n");
- if (*device->modeset_byte & 0x08)
- PRINT_INFO("(%s) Compression is currently on\n",
- dev_name(&device->cdev->dev));
- else
- PRINT_INFO("(%s) Compression is currently off\n",
- dev_name(&device->cdev->dev));
- PRINT_INFO("Use 1 to switch compression on, 0 to "
- "switch it off\n");
return -EINVAL;
}
request = tape_alloc_request(2, 0);
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index eefc6611412e..cfe782ee6473 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -5,7 +5,7 @@
*
* For more information please refer to Documentation/s390/zfcpdump.txt
*
- * Copyright IBM Corp. 2003,2007
+ * Copyright IBM Corp. 2003,2008
* Author(s): Michael Holzheu
*/
@@ -48,12 +48,19 @@ struct sys_info {
union save_area lc_mask;
};
+struct ipib_info {
+ unsigned long ipib;
+ u32 checksum;
+} __attribute__((packed));
+
static struct sys_info sys_info;
static struct debug_info *zcore_dbf;
static int hsa_available;
static struct dentry *zcore_dir;
static struct dentry *zcore_file;
static struct dentry *zcore_memmap_file;
+static struct dentry *zcore_reipl_file;
+static struct ipl_parameter_block *ipl_block;
/*
* Copy memory from HSA to kernel or user memory (not reentrant):
@@ -527,6 +534,33 @@ static const struct file_operations zcore_memmap_fops = {
.release = zcore_memmap_release,
};
+static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (ipl_block) {
+ diag308(DIAG308_SET, ipl_block);
+ diag308(DIAG308_IPL, NULL);
+ }
+ return count;
+}
+
+static int zcore_reipl_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int zcore_reipl_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static const struct file_operations zcore_reipl_fops = {
+ .owner = THIS_MODULE,
+ .write = zcore_reipl_write,
+ .open = zcore_reipl_open,
+ .release = zcore_reipl_release,
+};
+
static void __init set_s390_lc_mask(union save_area *map)
{
@@ -645,6 +679,39 @@ static int __init zcore_header_init(int arch, struct zcore_header *hdr)
return 0;
}
+/*
+ * Provide IPL parameter information block from either HSA or memory
+ * for future reipl
+ */
+static int __init zcore_reipl_init(void)
+{
+ struct ipib_info ipib_info;
+ int rc;
+
+ rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
+ if (rc)
+ return rc;
+ if (ipib_info.ipib == 0)
+ return 0;
+ ipl_block = (void *) __get_free_page(GFP_KERNEL);
+ if (!ipl_block)
+ return -ENOMEM;
+ if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
+ rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
+ else
+ rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE);
+ if (rc) {
+ free_page((unsigned long) ipl_block);
+ return rc;
+ }
+ if (cksm(ipl_block, ipl_block->hdr.len) != ipib_info.checksum) {
+ TRACE("Checksum does not match\n");
+ free_page((unsigned long) ipl_block);
+ ipl_block = NULL;
+ }
+ return 0;
+}
+
static int __init zcore_init(void)
{
unsigned char arch;
@@ -690,6 +757,10 @@ static int __init zcore_init(void)
if (rc)
goto fail;
+ rc = zcore_reipl_init();
+ if (rc)
+ goto fail;
+
zcore_dir = debugfs_create_dir("zcore" , NULL);
if (!zcore_dir) {
rc = -ENOMEM;
@@ -707,9 +778,17 @@ static int __init zcore_init(void)
rc = -ENOMEM;
goto fail_file;
}
+ zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
+ NULL, &zcore_reipl_fops);
+ if (!zcore_reipl_file) {
+ rc = -ENOMEM;
+ goto fail_memmap_file;
+ }
hsa_available = 1;
return 0;
+fail_memmap_file:
+ debugfs_remove(zcore_memmap_file);
fail_file:
debugfs_remove(zcore_file);
fail_dir:
@@ -723,10 +802,15 @@ static void __exit zcore_exit(void)
{
debug_unregister(zcore_dbf);
sclp_sdias_exit();
+ free_page((unsigned long) ipl_block);
+ debugfs_remove(zcore_reipl_file);
+ debugfs_remove(zcore_memmap_file);
+ debugfs_remove(zcore_file);
+ debugfs_remove(zcore_dir);
diag308(DIAG308_REL_HSA, NULL);
}
-MODULE_AUTHOR("Copyright IBM Corp. 2003,2007");
+MODULE_AUTHOR("Copyright IBM Corp. 2003,2008");
MODULE_DESCRIPTION("zcore module for zfcpdump support");
MODULE_LICENSE("GPL");
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
index bd79bd165396..adb3dd301528 100644
--- a/drivers/s390/cio/Makefile
+++ b/drivers/s390/cio/Makefile
@@ -3,7 +3,7 @@
#
obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \
- fcx.o itcw.o
+ fcx.o itcw.o crw.o
ccw_device-objs += device.o device_fsm.o device_ops.o
ccw_device-objs += device_id.o device_pgid.o device_status.o
obj-y += ccw_device.o cmf.o
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index fe6cea15bbaf..d3850dc30e42 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -133,6 +133,8 @@ void do_adapter_IO(u8 isc)
while (word) {
if (word & INDICATOR_MASK) {
airq = airqs[isc][i];
+ /* Make sure gcc reads from airqs only once. */
+ barrier();
if (likely(airq))
airq->handler(&indicators[isc].byte[i],
airq->drv_data);
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 1246f61a5338..3e5f304ad88f 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -17,8 +17,8 @@
#include <linux/errno.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "cio.h"
#include "css.h"
#include "ioasm.h"
@@ -706,12 +706,12 @@ static int __init chp_init(void)
struct chp_id chpid;
int ret;
- ret = s390_register_crw_handler(CRW_RSC_CPATH, chp_process_crw);
+ ret = crw_register_handler(CRW_RSC_CPATH, chp_process_crw);
if (ret)
return ret;
chp_wq = create_singlethread_workqueue("cio_chp");
if (!chp_wq) {
- s390_unregister_crw_handler(CRW_RSC_CPATH);
+ crw_unregister_handler(CRW_RSC_CPATH);
return -ENOMEM;
}
INIT_WORK(&cfg_work, cfg_func);
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index ebab6ea4659b..7399b07a1aeb 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -19,8 +19,8 @@
#include <asm/cio.h>
#include <asm/chpid.h>
#include <asm/chsc.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "css.h"
#include "cio.h"
#include "cio_debug.h"
@@ -820,7 +820,7 @@ int __init chsc_alloc_sei_area(void)
"chsc machine checks!\n");
return -ENOMEM;
}
- ret = s390_register_crw_handler(CRW_RSC_CSS, chsc_process_crw);
+ ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw);
if (ret)
kfree(sei_page);
return ret;
@@ -828,7 +828,7 @@ int __init chsc_alloc_sei_area(void)
void __init chsc_free_sei_area(void)
{
- s390_unregister_crw_handler(CRW_RSC_CSS);
+ crw_unregister_handler(CRW_RSC_CSS);
kfree(sei_page);
}
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 659f8a791656..2aebb9823044 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -30,6 +30,8 @@
#include <asm/isc.h>
#include <asm/cpu.h>
#include <asm/fcx.h>
+#include <asm/nmi.h>
+#include <asm/crw.h>
#include "cio.h"
#include "css.h"
#include "chsc.h"
@@ -38,7 +40,6 @@
#include "blacklist.h"
#include "cio_debug.h"
#include "chp.h"
-#include "../s390mach.h"
debug_info_t *cio_debug_msg_id;
debug_info_t *cio_debug_trace_id;
@@ -471,6 +472,7 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel);
int cio_disable_subchannel(struct subchannel *sch)
{
char dbf_txt[15];
+ int retry;
int ret;
CIO_TRACE_EVENT (2, "dissch");
@@ -481,16 +483,17 @@ int cio_disable_subchannel(struct subchannel *sch)
if (cio_update_schib(sch))
return -ENODEV;
- if (scsw_actl(&sch->schib.scsw) != 0)
- /*
- * the disable function must not be called while there are
- * requests pending for completion !
- */
- return -EBUSY;
-
sch->config.ena = 0;
- ret = cio_commit_config(sch);
+ for (retry = 0; retry < 3; retry++) {
+ ret = cio_commit_config(sch);
+ if (ret == -EBUSY) {
+ struct irb irb;
+ if (tsch(sch->schid, &irb) != 0)
+ break;
+ } else
+ break;
+ }
sprintf (dbf_txt, "ret:%d", ret);
CIO_TRACE_EVENT (2, dbf_txt);
return ret;
diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c
new file mode 100644
index 000000000000..d157665d0e76
--- /dev/null
+++ b/drivers/s390/cio/crw.c
@@ -0,0 +1,159 @@
+/*
+ * Channel report handling code
+ *
+ * Copyright IBM Corp. 2000,2009
+ * Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ * Cornelia Huck <cornelia.huck@de.ibm.com>,
+ * Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#include <linux/semaphore.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/init.h>
+#include <asm/crw.h>
+
+static struct semaphore crw_semaphore;
+static DEFINE_MUTEX(crw_handler_mutex);
+static crw_handler_t crw_handlers[NR_RSCS];
+
+/**
+ * crw_register_handler() - register a channel report word handler
+ * @rsc: reporting source code to handle
+ * @handler: handler to be registered
+ *
+ * Returns %0 on success and a negative error value otherwise.
+ */
+int crw_register_handler(int rsc, crw_handler_t handler)
+{
+ int rc = 0;
+
+ if ((rsc < 0) || (rsc >= NR_RSCS))
+ return -EINVAL;
+ mutex_lock(&crw_handler_mutex);
+ if (crw_handlers[rsc])
+ rc = -EBUSY;
+ else
+ crw_handlers[rsc] = handler;
+ mutex_unlock(&crw_handler_mutex);
+ return rc;
+}
+
+/**
+ * crw_unregister_handler() - unregister a channel report word handler
+ * @rsc: reporting source code to handle
+ */
+void crw_unregister_handler(int rsc)
+{
+ if ((rsc < 0) || (rsc >= NR_RSCS))
+ return;
+ mutex_lock(&crw_handler_mutex);
+ crw_handlers[rsc] = NULL;
+ mutex_unlock(&crw_handler_mutex);
+}
+
+/*
+ * Retrieve CRWs and call function to handle event.
+ */
+static int crw_collect_info(void *unused)
+{
+ struct crw crw[2];
+ int ccode;
+ unsigned int chain;
+ int ignore;
+
+repeat:
+ ignore = down_interruptible(&crw_semaphore);
+ chain = 0;
+ while (1) {
+ crw_handler_t handler;
+
+ if (unlikely(chain > 1)) {
+ struct crw tmp_crw;
+
+ printk(KERN_WARNING"%s: Code does not support more "
+ "than two chained crws; please report to "
+ "linux390@de.ibm.com!\n", __func__);
+ ccode = stcrw(&tmp_crw);
+ printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
+ "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+ __func__, tmp_crw.slct, tmp_crw.oflw,
+ tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
+ tmp_crw.erc, tmp_crw.rsid);
+ printk(KERN_WARNING"%s: This was crw number %x in the "
+ "chain\n", __func__, chain);
+ if (ccode != 0)
+ break;
+ chain = tmp_crw.chn ? chain + 1 : 0;
+ continue;
+ }
+ ccode = stcrw(&crw[chain]);
+ if (ccode != 0)
+ break;
+ printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
+ "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+ crw[chain].slct, crw[chain].oflw, crw[chain].chn,
+ crw[chain].rsc, crw[chain].anc, crw[chain].erc,
+ crw[chain].rsid);
+ /* Check for overflows. */
+ if (crw[chain].oflw) {
+ int i;
+
+ pr_debug("%s: crw overflow detected!\n", __func__);
+ mutex_lock(&crw_handler_mutex);
+ for (i = 0; i < NR_RSCS; i++) {
+ if (crw_handlers[i])
+ crw_handlers[i](NULL, NULL, 1);
+ }
+ mutex_unlock(&crw_handler_mutex);
+ chain = 0;
+ continue;
+ }
+ if (crw[0].chn && !chain) {
+ chain++;
+ continue;
+ }
+ mutex_lock(&crw_handler_mutex);
+ handler = crw_handlers[crw[chain].rsc];
+ if (handler)
+ handler(&crw[0], chain ? &crw[1] : NULL, 0);
+ mutex_unlock(&crw_handler_mutex);
+ /* chain is always 0 or 1 here. */
+ chain = crw[chain].chn ? chain + 1 : 0;
+ }
+ goto repeat;
+ return 0;
+}
+
+void crw_handle_channel_report(void)
+{
+ up(&crw_semaphore);
+}
+
+/*
+ * Separate initcall needed for semaphore initialization since
+ * crw_handle_channel_report might be called before crw_machine_check_init.
+ */
+static int __init crw_init_semaphore(void)
+{
+ init_MUTEX_LOCKED(&crw_semaphore);
+ return 0;
+}
+pure_initcall(crw_init_semaphore);
+
+/*
+ * Machine checks for the channel subsystem must be enabled
+ * after the channel subsystem is initialized
+ */
+static int __init crw_machine_check_init(void)
+{
+ struct task_struct *task;
+
+ task = kthread_run(crw_collect_info, NULL, "kmcheck");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+ ctl_set_bit(14, 28); /* enable channel report MCH */
+ return 0;
+}
+device_initcall(crw_machine_check_init);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 8019288bc6de..1f2e424596af 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -18,8 +18,8 @@
#include <linux/list.h>
#include <linux/reboot.h>
#include <asm/isc.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "css.h"
#include "cio.h"
#include "cio_debug.h"
@@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct subchannel_id schid, void *data)
return rc;
}
+static int call_fn_all_sch(struct subchannel_id schid, void *data)
+{
+ struct cb_data *cb = data;
+ struct subchannel *sch;
+ int rc = 0;
+
+ sch = get_subchannel_by_schid(schid);
+ if (sch) {
+ if (cb->fn_known_sch)
+ rc = cb->fn_known_sch(sch, cb->data);
+ put_device(&sch->dev);
+ } else {
+ if (cb->fn_unknown_sch)
+ rc = cb->fn_unknown_sch(schid, cb->data);
+ }
+
+ return rc;
+}
+
int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
int (*fn_unknown)(struct subchannel_id,
void *), void *data)
@@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
struct cb_data cb;
int rc;
- cb.set = idset_sch_new();
- if (!cb.set)
- return -ENOMEM;
- idset_fill(cb.set);
cb.data = data;
cb.fn_known_sch = fn_known;
cb.fn_unknown_sch = fn_unknown;
+
+ cb.set = idset_sch_new();
+ if (!cb.set)
+ /* fall back to brute force scanning in case of oom */
+ return for_each_subchannel(call_fn_all_sch, &cb);
+
+ idset_fill(cb.set);
+
/* Process registered subchannels. */
rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
if (rc)
@@ -765,7 +788,7 @@ init_channel_subsystem (void)
if (ret)
goto out;
- ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw);
+ ret = crw_register_handler(CRW_RSC_SCH, css_process_crw);
if (ret)
goto out;
@@ -845,7 +868,7 @@ out_unregister:
out_bus:
bus_unregister(&css_bus_type);
out:
- s390_unregister_crw_handler(CRW_RSC_CSS);
+ crw_unregister_handler(CRW_RSC_CSS);
chsc_free_sei_area();
kfree(slow_subchannel_set);
pr_alert("The CSS device driver initialization failed with "
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 23d5752349b5..9be6dd5a5664 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -457,12 +457,13 @@ int ccw_device_set_online(struct ccw_device *cdev)
return (ret == 0) ? -ENODEV : ret;
}
-static void online_store_handle_offline(struct ccw_device *cdev)
+static int online_store_handle_offline(struct ccw_device *cdev)
{
if (cdev->private->state == DEV_STATE_DISCONNECTED)
ccw_device_remove_disconnected(cdev);
- else if (cdev->drv && cdev->drv->set_offline)
- ccw_device_set_offline(cdev);
+ else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+ return ccw_device_set_offline(cdev);
+ return 0;
}
static int online_store_recog_and_online(struct ccw_device *cdev)
@@ -530,13 +531,10 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
goto out;
switch (i) {
case 0:
- online_store_handle_offline(cdev);
- ret = count;
+ ret = online_store_handle_offline(cdev);
break;
case 1:
ret = online_store_handle_online(cdev, force);
- if (!ret)
- ret = count;
break;
default:
ret = -EINVAL;
@@ -545,7 +543,7 @@ out:
if (cdev->drv)
module_put(cdev->drv->owner);
atomic_set(&cdev->private->onoff, 0);
- return ret;
+ return (ret < 0) ? ret : count;
}
static ssize_t
@@ -681,35 +679,22 @@ get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css,
return dev ? to_ccwdev(dev) : NULL;
}
-static void
-ccw_device_add_changed(struct work_struct *work)
-{
- struct ccw_device_private *priv;
- struct ccw_device *cdev;
-
- priv = container_of(work, struct ccw_device_private, kick_work);
- cdev = priv->cdev;
- if (device_add(&cdev->dev)) {
- put_device(&cdev->dev);
- return;
- }
- set_bit(1, &cdev->private->registered);
-}
-
-void ccw_device_do_unreg_rereg(struct work_struct *work)
+void ccw_device_do_unbind_bind(struct work_struct *work)
{
struct ccw_device_private *priv;
struct ccw_device *cdev;
struct subchannel *sch;
+ int ret;
priv = container_of(work, struct ccw_device_private, kick_work);
cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
- ccw_device_unregister(cdev);
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_add_changed);
- queue_work(ccw_device_work, &cdev->private->kick_work);
+ if (test_bit(1, &cdev->private->registered)) {
+ device_release_driver(&cdev->dev);
+ ret = device_attach(&cdev->dev);
+ WARN_ON(ret == -ENODEV);
+ }
}
static void
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 0f2e63ea48de..85e01846ca65 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -80,7 +80,7 @@ void io_subchannel_init_config(struct subchannel *sch);
int ccw_device_cancel_halt_clear(struct ccw_device *);
-void ccw_device_do_unreg_rereg(struct work_struct *);
+void ccw_device_do_unbind_bind(struct work_struct *);
void ccw_device_move_to_orphanage(struct work_struct *);
int ccw_device_is_orphan(struct ccw_device *);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 8df5eaafc5ab..87b4bfca080f 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
cdev->id.dev_type != cdev->private->senseid.dev_type ||
cdev->id.dev_model != cdev->private->senseid.dev_model) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_do_unreg_rereg);
+ ccw_device_do_unbind_bind);
queue_work(ccw_device_work, &cdev->private->kick_work);
return 0;
}
@@ -366,7 +366,7 @@ static void ccw_device_oper_notify(struct ccw_device *cdev)
}
/* Driver doesn't want device back. */
ccw_device_set_notoper(cdev);
- PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg);
+ PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
@@ -728,7 +728,7 @@ static void ccw_device_generic_notoper(struct ccw_device *cdev,
{
struct subchannel *sch;
- cdev->private->state = DEV_STATE_NOT_OPER;
+ ccw_device_set_notoper(cdev);
sch = to_subchannel(cdev->dev.parent);
css_schedule_eval(sch->schid);
}
@@ -1052,7 +1052,7 @@ ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event)
sch = to_subchannel(cdev->dev.parent);
/*
* An interrupt in state offline means a previous disable was not
- * successful. Try again.
+ * successful - should not happen, but we try to disable again.
*/
cio_disable_subchannel(sch);
}
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 10cb0f8726e5..61ba765936a6 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -440,12 +440,16 @@ static inline void inbound_primed(struct qdio_q *q, int count)
/* reset the previous ACK but first set the new one */
set_buf_state(q, new, SLSB_P_INPUT_ACK);
set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
- }
- else {
+ } else {
q->u.in.polling = 1;
- set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK);
+ set_buf_state(q, new, SLSB_P_INPUT_ACK);
}
+ /*
+ * last_move_ftc points to the ACK'ed buffer and not to the last turns
+ * first_to_check like for qebsm. Since it is only used to check if
+ * the queue front moved in qdio_inbound_q_done this is not a problem.
+ */
q->last_move_ftc = new;
count--;
if (!count)
@@ -455,7 +459,7 @@ static inline void inbound_primed(struct qdio_q *q, int count)
* Need to change all PRIMED buffers to NOT_INIT, otherwise
* we're loosing initiative in the thinint code.
*/
- set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT,
+ set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT,
count);
}
@@ -778,21 +782,17 @@ static void __qdio_outbound_processing(struct qdio_q *q)
spin_unlock_irqrestore(&q->lock, flags);
- if (queue_type(q) == QDIO_ZFCP_QFMT) {
+ if (queue_type(q) == QDIO_ZFCP_QFMT)
if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
- tasklet_schedule(&q->tasklet);
- return;
- }
+ goto sched;
/* bail out for HiperSockets unicast queues */
if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
return;
if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
- (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
- tasklet_schedule(&q->tasklet);
- return;
- }
+ (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
+ goto sched;
if (q->u.out.pci_out_enabled)
return;
@@ -810,6 +810,12 @@ static void __qdio_outbound_processing(struct qdio_q *q)
qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
}
}
+ return;
+
+sched:
+ if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
+ tasklet_schedule(&q->tasklet);
}
/* outbound tasklet */
@@ -822,6 +828,9 @@ void qdio_outbound_processing(unsigned long data)
void qdio_outbound_timer(unsigned long data)
{
struct qdio_q *q = (struct qdio_q *)data;
+
+ if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
tasklet_schedule(&q->tasklet);
}
@@ -863,6 +872,9 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
int i;
struct qdio_q *q;
+ if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
+
qdio_perf_stat_inc(&perf_stats.pci_int);
for_each_input_queue(irq_ptr, q, i)
@@ -1065,8 +1077,9 @@ EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
* @cdev: associated ccw device
* @how: use halt or clear to shutdown
*
- * This function calls qdio_shutdown() for @cdev with method @how
- * and on success qdio_free() for @cdev.
+ * This function calls qdio_shutdown() for @cdev with method @how.
+ * and qdio_free(). The qdio_free() return value is ignored since
+ * !irq_ptr is already checked.
*/
int qdio_cleanup(struct ccw_device *cdev, int how)
{
@@ -1077,8 +1090,8 @@ int qdio_cleanup(struct ccw_device *cdev, int how)
return -ENODEV;
rc = qdio_shutdown(cdev, how);
- if (rc == 0)
- rc = qdio_free(cdev);
+
+ qdio_free(cdev);
return rc;
}
EXPORT_SYMBOL_GPL(qdio_cleanup);
@@ -1090,11 +1103,11 @@ static void qdio_shutdown_queues(struct ccw_device *cdev)
int i;
for_each_input_queue(irq_ptr, q, i)
- tasklet_disable(&q->tasklet);
+ tasklet_kill(&q->tasklet);
for_each_output_queue(irq_ptr, q, i) {
- tasklet_disable(&q->tasklet);
del_timer(&q->u.out.timer);
+ tasklet_kill(&q->tasklet);
}
}
@@ -1112,6 +1125,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
if (!irq_ptr)
return -ENODEV;
+ BUG_ON(irqs_disabled());
DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
mutex_lock(&irq_ptr->setup_mutex);
@@ -1124,6 +1138,12 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
return 0;
}
+ /*
+ * Indicate that the device is going down. Scheduling the queue
+ * tasklets is forbidden from here on.
+ */
+ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
+
tiqdio_remove_input_queues(irq_ptr);
qdio_shutdown_queues(cdev);
qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1403,9 +1423,8 @@ int qdio_activate(struct ccw_device *cdev)
switch (irq_ptr->state) {
case QDIO_IRQ_STATE_STOPPED:
case QDIO_IRQ_STATE_ERR:
- mutex_unlock(&irq_ptr->setup_mutex);
- qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
- return -EIO;
+ rc = -EIO;
+ break;
default:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE);
rc = 0;
@@ -1465,7 +1484,6 @@ static void handle_inbound(struct qdio_q *q, unsigned int callflags,
if (q->u.in.ack_count <= 0) {
q->u.in.polling = 0;
q->u.in.ack_count = 0;
- /* TODO: must we set last_move_ftc to something meaningful? */
goto set;
}
q->last_move_ftc = add_buf(q->last_move_ftc, diff);
@@ -1556,7 +1574,6 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
qdio_perf_stat_inc(&perf_stats.fast_requeue);
}
out:
- /* Fixme: could wait forever if called from process context */
tasklet_schedule(&q->tasklet);
}
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8e90e147b746..c7c5512a892e 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -31,6 +31,7 @@
/* list of thin interrupt input queues */
static LIST_HEAD(tiq_list);
+DEFINE_MUTEX(tiq_list_lock);
/* adapter local summary indicator */
static unsigned char *tiqdio_alsi;
@@ -95,12 +96,11 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
css_qdio_omit_svs = 1;
- for_each_input_queue(irq_ptr, q, i) {
+ mutex_lock(&tiq_list_lock);
+ for_each_input_queue(irq_ptr, q, i)
list_add_rcu(&q->entry, &tiq_list);
- synchronize_rcu();
- }
+ mutex_unlock(&tiq_list_lock);
xchg(irq_ptr->dsci, 1);
- tasklet_schedule(&tiqdio_tasklet);
}
/*
@@ -118,7 +118,10 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
/* if establish triggered an error */
if (!q || !q->entry.prev || !q->entry.next)
continue;
+
+ mutex_lock(&tiq_list_lock);
list_del_rcu(&q->entry);
+ mutex_unlock(&tiq_list_lock);
synchronize_rcu();
}
}
@@ -155,7 +158,6 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
*/
qdio_check_outbound_after_thinint(q);
-again:
if (!qdio_inbound_q_moved(q))
return;
@@ -163,7 +165,8 @@ again:
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
qdio_stop_polling(q);
@@ -173,7 +176,8 @@ again:
*/
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
}
diff --git a/drivers/s390/ebcdic.c b/drivers/s390/ebcdic.c
deleted file mode 100644
index 99c98da15473..000000000000
--- a/drivers/s390/ebcdic.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * arch/s390/kernel/ebcdic.c
- * ECBDIC -> ASCII, ASCII -> ECBDIC conversion tables.
- *
- * S390 version
- * Copyright (C) 1998 IBM Corporation
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <asm/types.h>
-
-/*
- * ASCII -> EBCDIC
- */
-__u8 _ascebc[256] =
-{
- /*00 NL SH SX EX ET NQ AK BL */
- 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08 BS HT LF VT FF CR SO SI */
- 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10 DL D1 D2 D3 D4 NK SN EB */
- 0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
- /*18 CN EM SB EC FS GS RS US */
- 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20 SP ! " # $ % & ' */
- 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28 ( ) * + , - . / */
- 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30 0 1 2 3 4 5 6 7 */
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38 8 9 : ; < = > ? */
- 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40 @ A B C D E F G */
- 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48 H I J K L M N O */
- 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50 P Q R S T U V W */
- 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58 X Y Z [ \ ] ^ _ */
- 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
- /*60 ` a b c d e f g */
- 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68 h i j k l m n o */
- 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70 p q r s t u v w */
- 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78 x y z { | } ~ DL */
- 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-/*
- * EBCDIC -> ASCII
- */
-__u8 _ebcasc[256] =
-{
- /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
- -ENP ->LF */
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
- -IUS */
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
- -INP */
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
- -SW */
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40 SP RSP ä ---- */
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48 . < ( + | */
- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50 & ---- */
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58 ß ! $ * ) ; */
- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60 - / ---- Ä ---- ---- ---- */
- 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68 ---- , % _ > ? */
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70 ---- ---- ---- ---- ---- ---- ---- */
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78 * ` : # @ ' = " */
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80 * a b c d e f g */
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88 h i ---- ---- ---- */
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90 ° j k l m n o p */
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98 q r ---- ---- */
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0 ~ s t u v w x */
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8 y z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0 ^ ---- § ---- */
- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8 ---- [ ] ---- ---- ---- ---- */
- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0 { A B C D E F G */
- 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8 H I ---- ö ---- */
- 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0 } J K L M N O P */
- 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8 Q R ---- ü */
- 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0 \ S T U V W X */
- 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8 Y Z ---- Ö ---- ---- ---- */
- 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0 0 1 2 3 4 5 6 7 */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
- 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
-
-/*
- * EBCDIC (capitals) -> ASCII (small case)
- */
-__u8 _ebcasc_reduce_case[256] =
-{
- /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
-
- /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-
- /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
- -ENP ->LF */
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
-
- /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
- -IUS */
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
- -INP */
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
-
- /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
- -SW */
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
-
- /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
-
- /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
-
- /* 0x40 SP RSP ä ---- */
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
-
- /* 0x48 . < ( + | */
- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
-
- /* 0x50 & ---- */
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
-
- /* 0x58 ß ! $ * ) ; */
- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
-
- /* 0x60 - / ---- Ä ---- ---- ---- */
- 0x2D, 0x2F, 0x07, 0x84, 0x07, 0x07, 0x07, 0x8F,
-
- /* 0x68 ---- , % _ > ? */
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
-
- /* 0x70 ---- ---- ---- ---- ---- ---- ---- */
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x78 * ` : # @ ' = " */
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
-
- /* 0x80 * a b c d e f g */
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0x88 h i ---- ---- ---- */
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
-
- /* 0x90 ° j k l m n o p */
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0x98 q r ---- ---- */
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
-
- /* 0xA0 ~ s t u v w x */
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xA8 y z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xB0 ^ ---- § ---- */
- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
-
- /* 0xB8 ---- [ ] ---- ---- ---- ---- */
- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xC0 { A B C D E F G */
- 0x7B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0xC8 H I ---- ö ---- */
- 0x68, 0x69, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
-
- /* 0xD0 } J K L M N O P */
- 0x7D, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0xD8 Q R ---- ü */
- 0x71, 0x72, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
-
- /* 0xE0 \ S T U V W X */
- 0x5C, 0xF6, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xE8 Y Z ---- Ö ---- ---- ---- */
- 0x79, 0x7A, 0xFD, 0x07, 0x94, 0x07, 0x07, 0x07,
-
- /* 0xF0 0 1 2 3 4 5 6 7 */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-
- /* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */
- 0x38, 0x39, 0x07, 0x07, 0x81, 0x07, 0x07, 0x07
-};
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index acca6678cb2b..49c3bfa1afd7 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -70,7 +70,9 @@ static char debug_buffer[255];
static void lcs_tasklet(unsigned long);
static void lcs_start_kernel_thread(struct work_struct *);
static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
+#ifdef CONFIG_IP_MULTICAST
static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *);
+#endif /* CONFIG_IP_MULTICAST */
static int lcs_recovery(void *ptr);
/**
@@ -1285,6 +1287,8 @@ out:
lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD);
return 0;
}
+#endif /* CONFIG_IP_MULTICAST */
+
/**
* function called by net device to
* handle multicast address relevant things
@@ -1292,6 +1296,7 @@ out:
static void
lcs_set_multicast_list(struct net_device *dev)
{
+#ifdef CONFIG_IP_MULTICAST
struct lcs_card *card;
LCS_DBF_TEXT(4, trace, "setmulti");
@@ -1299,9 +1304,8 @@ lcs_set_multicast_list(struct net_device *dev)
if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD))
schedule_work(&card->kernel_thread_starter);
-}
-
#endif /* CONFIG_IP_MULTICAST */
+}
static long
lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3d04920b9bb9..0dcc036d34aa 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1038,7 +1038,7 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card)
rc = qeth_query_setadapterparms(card);
if (rc) {
QETH_DBF_MESSAGE(2, "%s couldn't set adapter parameters: "
- "0x%x\n", card->gdev->dev.bus_id, rc);
+ "0x%x\n", dev_name(&card->gdev->dev), rc);
return rc;
}
if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) {
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
deleted file mode 100644
index 92b0417f8e12..000000000000
--- a/drivers/s390/s390mach.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * drivers/s390/s390mach.c
- * S/390 machine check handler
- *
- * Copyright IBM Corp. 2000,2008
- * Author(s): Ingo Adlung (adlung@de.ibm.com)
- * Martin Schwidefsky (schwidefsky@de.ibm.com)
- * Cornelia Huck <cornelia.huck@de.ibm.com>
- */
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/workqueue.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/kthread.h>
-#include <asm/etr.h>
-#include <asm/lowcore.h>
-#include <asm/cio.h>
-#include <asm/cpu.h>
-#include "s390mach.h"
-
-static struct semaphore m_sem;
-
-static NORET_TYPE void
-s390_handle_damage(char *msg)
-{
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- disabled_wait((unsigned long) __builtin_return_address(0));
- for(;;);
-}
-
-static crw_handler_t crw_handlers[NR_RSCS];
-
-/**
- * s390_register_crw_handler() - register a channel report word handler
- * @rsc: reporting source code to handle
- * @handler: handler to be registered
- *
- * Returns %0 on success and a negative error value otherwise.
- */
-int s390_register_crw_handler(int rsc, crw_handler_t handler)
-{
- if ((rsc < 0) || (rsc >= NR_RSCS))
- return -EINVAL;
- if (!cmpxchg(&crw_handlers[rsc], NULL, handler))
- return 0;
- return -EBUSY;
-}
-
-/**
- * s390_unregister_crw_handler() - unregister a channel report word handler
- * @rsc: reporting source code to handle
- */
-void s390_unregister_crw_handler(int rsc)
-{
- if ((rsc < 0) || (rsc >= NR_RSCS))
- return;
- xchg(&crw_handlers[rsc], NULL);
- synchronize_sched();
-}
-
-/*
- * Retrieve CRWs and call function to handle event.
- */
-static int s390_collect_crw_info(void *param)
-{
- struct crw crw[2];
- int ccode;
- struct semaphore *sem;
- unsigned int chain;
- int ignore;
-
- sem = (struct semaphore *)param;
-repeat:
- ignore = down_interruptible(sem);
- chain = 0;
- while (1) {
- if (unlikely(chain > 1)) {
- struct crw tmp_crw;
-
- printk(KERN_WARNING"%s: Code does not support more "
- "than two chained crws; please report to "
- "linux390@de.ibm.com!\n", __func__);
- ccode = stcrw(&tmp_crw);
- printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
- "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
- __func__, tmp_crw.slct, tmp_crw.oflw,
- tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
- tmp_crw.erc, tmp_crw.rsid);
- printk(KERN_WARNING"%s: This was crw number %x in the "
- "chain\n", __func__, chain);
- if (ccode != 0)
- break;
- chain = tmp_crw.chn ? chain + 1 : 0;
- continue;
- }
- ccode = stcrw(&crw[chain]);
- if (ccode != 0)
- break;
- printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
- "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
- crw[chain].slct, crw[chain].oflw, crw[chain].chn,
- crw[chain].rsc, crw[chain].anc, crw[chain].erc,
- crw[chain].rsid);
- /* Check for overflows. */
- if (crw[chain].oflw) {
- int i;
-
- pr_debug("%s: crw overflow detected!\n", __func__);
- for (i = 0; i < NR_RSCS; i++) {
- if (crw_handlers[i])
- crw_handlers[i](NULL, NULL, 1);
- }
- chain = 0;
- continue;
- }
- if (crw[0].chn && !chain) {
- chain++;
- continue;
- }
- if (crw_handlers[crw[chain].rsc])
- crw_handlers[crw[chain].rsc](&crw[0],
- chain ? &crw[1] : NULL,
- 0);
- /* chain is always 0 or 1 here. */
- chain = crw[chain].chn ? chain + 1 : 0;
- }
- goto repeat;
- return 0;
-}
-
-struct mcck_struct {
- int kill_task;
- int channel_report;
- int warning;
- unsigned long long mcck_code;
-};
-
-static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
-
-/*
- * Main machine check handler function. Will be called with interrupts enabled
- * or disabled and machine checks enabled or disabled.
- */
-void
-s390_handle_mcck(void)
-{
- unsigned long flags;
- struct mcck_struct mcck;
-
- /*
- * Disable machine checks and get the current state of accumulated
- * machine checks. Afterwards delete the old state and enable machine
- * checks again.
- */
- local_irq_save(flags);
- local_mcck_disable();
- mcck = __get_cpu_var(cpu_mcck);
- memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
- clear_thread_flag(TIF_MCCK_PENDING);
- local_mcck_enable();
- local_irq_restore(flags);
-
- if (mcck.channel_report)
- up(&m_sem);
-
-#ifdef CONFIG_MACHCHK_WARNING
-/*
- * The warning may remain for a prolonged period on the bare iron.
- * (actually till the machine is powered off, or until the problem is gone)
- * So we just stop listening for the WARNING MCH and prevent continuously
- * being interrupted. One caveat is however, that we must do this per
- * processor and cannot use the smp version of ctl_clear_bit().
- * On VM we only get one interrupt per virtally presented machinecheck.
- * Though one suffices, we may get one interrupt per (virtual) processor.
- */
- if (mcck.warning) { /* WARNING pending ? */
- static int mchchk_wng_posted = 0;
- /*
- * Use single machine clear, as we cannot handle smp right now
- */
- __ctl_clear_bit(14, 24); /* Disable WARNING MCH */
- if (xchg(&mchchk_wng_posted, 1) == 0)
- kill_cad_pid(SIGPWR, 1);
- }
-#endif
-
- if (mcck.kill_task) {
- local_irq_enable();
- printk(KERN_EMERG "mcck: Terminating task because of machine "
- "malfunction (code 0x%016llx).\n", mcck.mcck_code);
- printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
- current->comm, current->pid);
- do_exit(SIGSEGV);
- }
-}
-EXPORT_SYMBOL_GPL(s390_handle_mcck);
-
-/*
- * returns 0 if all registers could be validated
- * returns 1 otherwise
- */
-static int
-s390_revalidate_registers(struct mci *mci)
-{
- int kill_task;
- u64 tmpclock;
- u64 zero;
- void *fpt_save_area, *fpt_creg_save_area;
-
- kill_task = 0;
- zero = 0;
- /* General purpose registers */
- if (!mci->gr)
- /*
- * General purpose registers couldn't be restored and have
- * unknown contents. Process needs to be terminated.
- */
- kill_task = 1;
-
- /* Revalidate floating point registers */
- if (!mci->fp)
- /*
- * Floating point registers can't be restored and
- * therefore the process needs to be terminated.
- */
- kill_task = 1;
-
-#ifndef CONFIG_64BIT
- asm volatile(
- " ld 0,0(%0)\n"
- " ld 2,8(%0)\n"
- " ld 4,16(%0)\n"
- " ld 6,24(%0)"
- : : "a" (&S390_lowcore.floating_pt_save_area));
-#endif
-
- if (MACHINE_HAS_IEEE) {
-#ifdef CONFIG_64BIT
- fpt_save_area = &S390_lowcore.floating_pt_save_area;
- fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
-#else
- fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
- fpt_creg_save_area = fpt_save_area+128;
-#endif
- /* Floating point control register */
- if (!mci->fc) {
- /*
- * Floating point control register can't be restored.
- * Task will be terminated.
- */
- asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
- kill_task = 1;
-
- } else
- asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
-
- asm volatile(
- " ld 0,0(%0)\n"
- " ld 1,8(%0)\n"
- " ld 2,16(%0)\n"
- " ld 3,24(%0)\n"
- " ld 4,32(%0)\n"
- " ld 5,40(%0)\n"
- " ld 6,48(%0)\n"
- " ld 7,56(%0)\n"
- " ld 8,64(%0)\n"
- " ld 9,72(%0)\n"
- " ld 10,80(%0)\n"
- " ld 11,88(%0)\n"
- " ld 12,96(%0)\n"
- " ld 13,104(%0)\n"
- " ld 14,112(%0)\n"
- " ld 15,120(%0)\n"
- : : "a" (fpt_save_area));
- }
-
- /* Revalidate access registers */
- asm volatile(
- " lam 0,15,0(%0)"
- : : "a" (&S390_lowcore.access_regs_save_area));
- if (!mci->ar)
- /*
- * Access registers have unknown contents.
- * Terminating task.
- */
- kill_task = 1;
-
- /* Revalidate control registers */
- if (!mci->cr)
- /*
- * Control registers have unknown contents.
- * Can't recover and therefore stopping machine.
- */
- s390_handle_damage("invalid control registers.");
- else
-#ifdef CONFIG_64BIT
- asm volatile(
- " lctlg 0,15,0(%0)"
- : : "a" (&S390_lowcore.cregs_save_area));
-#else
- asm volatile(
- " lctl 0,15,0(%0)"
- : : "a" (&S390_lowcore.cregs_save_area));
-#endif
-
- /*
- * We don't even try to revalidate the TOD register, since we simply
- * can't write something sensible into that register.
- */
-
-#ifdef CONFIG_64BIT
- /*
- * See if we can revalidate the TOD programmable register with its
- * old contents (should be zero) otherwise set it to zero.
- */
- if (!mci->pr)
- asm volatile(
- " sr 0,0\n"
- " sckpf"
- : : : "0", "cc");
- else
- asm volatile(
- " l 0,0(%0)\n"
- " sckpf"
- : : "a" (&S390_lowcore.tod_progreg_save_area)
- : "0", "cc");
-#endif
-
- /* Revalidate clock comparator register */
- asm volatile(
- " stck 0(%1)\n"
- " sckc 0(%1)"
- : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
-
- /* Check if old PSW is valid */
- if (!mci->wp)
- /*
- * Can't tell if we come from user or kernel mode
- * -> stopping machine.
- */
- s390_handle_damage("old psw invalid.");
-
- if (!mci->ms || !mci->pm || !mci->ia)
- kill_task = 1;
-
- return kill_task;
-}
-
-#define MAX_IPD_COUNT 29
-#define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */
-
-/*
- * machine check handler.
- */
-void
-s390_do_machine_check(struct pt_regs *regs)
-{
- static DEFINE_SPINLOCK(ipd_lock);
- static unsigned long long last_ipd;
- static int ipd_count;
- unsigned long long tmp;
- struct mci *mci;
- struct mcck_struct *mcck;
- int umode;
-
- lockdep_off();
-
- s390_idle_check();
-
- mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
- mcck = &__get_cpu_var(cpu_mcck);
- umode = user_mode(regs);
-
- if (mci->sd)
- /* System damage -> stopping machine */
- s390_handle_damage("received system damage machine check.");
-
- if (mci->pd) {
- if (mci->b) {
- /* Processing backup -> verify if we can survive this */
- u64 z_mcic, o_mcic, t_mcic;
-#ifdef CONFIG_64BIT
- z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
- o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
- 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
- 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
- 1ULL<<16);
-#else
- z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
- 1ULL<<29);
- o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
- 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
- 1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
-#endif
- t_mcic = *(u64 *)mci;
-
- if (((t_mcic & z_mcic) != 0) ||
- ((t_mcic & o_mcic) != o_mcic)) {
- s390_handle_damage("processing backup machine "
- "check with damage.");
- }
-
- /*
- * Nullifying exigent condition, therefore we might
- * retry this instruction.
- */
-
- spin_lock(&ipd_lock);
-
- tmp = get_clock();
-
- if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
- ipd_count++;
- else
- ipd_count = 1;
-
- last_ipd = tmp;
-
- if (ipd_count == MAX_IPD_COUNT)
- s390_handle_damage("too many ipd retries.");
-
- spin_unlock(&ipd_lock);
- }
- else {
- /* Processing damage -> stopping machine */
- s390_handle_damage("received instruction processing "
- "damage machine check.");
- }
- }
- if (s390_revalidate_registers(mci)) {
- if (umode) {
- /*
- * Couldn't restore all register contents while in
- * user mode -> mark task for termination.
- */
- mcck->kill_task = 1;
- mcck->mcck_code = *(unsigned long long *) mci;
- set_thread_flag(TIF_MCCK_PENDING);
- }
- else
- /*
- * Couldn't restore all register contents while in
- * kernel mode -> stopping machine.
- */
- s390_handle_damage("unable to revalidate registers.");
- }
-
- if (mci->cd) {
- /* Timing facility damage */
- s390_handle_damage("TOD clock damaged");
- }
-
- if (mci->ed && mci->ec) {
- /* External damage */
- if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
- etr_sync_check();
- if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))
- etr_switch_to_local();
- if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))
- stp_sync_check();
- if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))
- stp_island_check();
- }
-
- if (mci->se)
- /* Storage error uncorrected */
- s390_handle_damage("received storage error uncorrected "
- "machine check.");
-
- if (mci->ke)
- /* Storage key-error uncorrected */
- s390_handle_damage("received storage key-error uncorrected "
- "machine check.");
-
- if (mci->ds && mci->fa)
- /* Storage degradation */
- s390_handle_damage("received storage degradation machine "
- "check.");
-
- if (mci->cp) {
- /* Channel report word pending */
- mcck->channel_report = 1;
- set_thread_flag(TIF_MCCK_PENDING);
- }
-
- if (mci->w) {
- /* Warning pending */
- mcck->warning = 1;
- set_thread_flag(TIF_MCCK_PENDING);
- }
- lockdep_on();
-}
-
-/*
- * s390_init_machine_check
- *
- * initialize machine check handling
- */
-static int
-machine_check_init(void)
-{
- init_MUTEX_LOCKED(&m_sem);
- ctl_set_bit(14, 25); /* enable external damage MCH */
- ctl_set_bit(14, 27); /* enable system recovery MCH */
-#ifdef CONFIG_MACHCHK_WARNING
- ctl_set_bit(14, 24); /* enable warning MCH */
-#endif
- return 0;
-}
-
-/*
- * Initialize the machine check handler really early to be able to
- * catch all machine checks that happen during boot
- */
-arch_initcall(machine_check_init);
-
-/*
- * Machine checks for the channel subsystem must be enabled
- * after the channel subsystem is initialized
- */
-static int __init
-machine_check_crw_init (void)
-{
- struct task_struct *task;
-
- task = kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
- if (IS_ERR(task))
- return PTR_ERR(task);
- ctl_set_bit(14, 28); /* enable channel report MCH */
- return 0;
-}
-
-device_initcall (machine_check_crw_init);
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
deleted file mode 100644
index d39f8b697d27..000000000000
--- a/drivers/s390/s390mach.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * drivers/s390/s390mach.h
- * S/390 data definitions for machine check processing
- *
- * S390 version
- * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390mach_h
-#define __s390mach_h
-
-#include <asm/types.h>
-
-struct mci {
- __u32 sd : 1; /* 00 system damage */
- __u32 pd : 1; /* 01 instruction-processing damage */
- __u32 sr : 1; /* 02 system recovery */
- __u32 to_be_defined_1 : 1; /* 03 */
- __u32 cd : 1; /* 04 timing-facility damage */
- __u32 ed : 1; /* 05 external damage */
- __u32 to_be_defined_2 : 1; /* 06 */
- __u32 dg : 1; /* 07 degradation */
- __u32 w : 1; /* 08 warning pending */
- __u32 cp : 1; /* 09 channel-report pending */
- __u32 sp : 1; /* 10 service-processor damage */
- __u32 ck : 1; /* 11 channel-subsystem damage */
- __u32 to_be_defined_3 : 2; /* 12-13 */
- __u32 b : 1; /* 14 backed up */
- __u32 to_be_defined_4 : 1; /* 15 */
- __u32 se : 1; /* 16 storage error uncorrected */
- __u32 sc : 1; /* 17 storage error corrected */
- __u32 ke : 1; /* 18 storage-key error uncorrected */
- __u32 ds : 1; /* 19 storage degradation */
- __u32 wp : 1; /* 20 psw mwp validity */
- __u32 ms : 1; /* 21 psw mask and key validity */
- __u32 pm : 1; /* 22 psw program mask and cc validity */
- __u32 ia : 1; /* 23 psw instruction address validity */
- __u32 fa : 1; /* 24 failing storage address validity */
- __u32 to_be_defined_5 : 1; /* 25 */
- __u32 ec : 1; /* 26 external damage code validity */
- __u32 fp : 1; /* 27 floating point register validity */
- __u32 gr : 1; /* 28 general register validity */
- __u32 cr : 1; /* 29 control register validity */
- __u32 to_be_defined_6 : 1; /* 30 */
- __u32 st : 1; /* 31 storage logical validity */
- __u32 ie : 1; /* 32 indirect storage error */
- __u32 ar : 1; /* 33 access register validity */
- __u32 da : 1; /* 34 delayed access exception */
- __u32 to_be_defined_7 : 7; /* 35-41 */
- __u32 pr : 1; /* 42 tod programmable register validity */
- __u32 fc : 1; /* 43 fp control register validity */
- __u32 ap : 1; /* 44 ancillary report */
- __u32 to_be_defined_8 : 1; /* 45 */
- __u32 ct : 1; /* 46 cpu timer validity */
- __u32 cc : 1; /* 47 clock comparator validity */
- __u32 to_be_defined_9 : 16; /* 47-63 */
-};
-
-/*
- * Channel Report Word
- */
-struct crw {
- __u32 res1 : 1; /* reserved zero */
- __u32 slct : 1; /* solicited */
- __u32 oflw : 1; /* overflow */
- __u32 chn : 1; /* chained */
- __u32 rsc : 4; /* reporting source code */
- __u32 anc : 1; /* ancillary report */
- __u32 res2 : 1; /* reserved zero */
- __u32 erc : 6; /* error-recovery code */
- __u32 rsid : 16; /* reporting-source ID */
-} __attribute__ ((packed));
-
-typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
-
-extern int s390_register_crw_handler(int rsc, crw_handler_t handler);
-extern void s390_unregister_crw_handler(int rsc);
-
-#define NR_RSCS 16
-
-#define CRW_RSC_MONITOR 0x2 /* monitoring facility */
-#define CRW_RSC_SCH 0x3 /* subchannel */
-#define CRW_RSC_CPATH 0x4 /* channel path */
-#define CRW_RSC_CONFIG 0x9 /* configuration-alert facility */
-#define CRW_RSC_CSS 0xB /* channel subsystem */
-
-#define CRW_ERC_EVENT 0x00 /* event information pending */
-#define CRW_ERC_AVAIL 0x01 /* available */
-#define CRW_ERC_INIT 0x02 /* initialized */
-#define CRW_ERC_TERROR 0x03 /* temporary error */
-#define CRW_ERC_IPARM 0x04 /* installed parm initialized */
-#define CRW_ERC_TERM 0x05 /* terminal */
-#define CRW_ERC_PERRN 0x06 /* perm. error, fac. not init */
-#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
-#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
-
-static inline int stcrw(struct crw *pcrw )
-{
- int ccode;
-
- __asm__ __volatile__(
- "stcrw 0(%2)\n\t"
- "ipm %0\n\t"
- "srl %0,28\n\t"
- : "=d" (ccode), "=m" (*pcrw)
- : "a" (pcrw)
- : "cc" );
- return ccode;
-}
-
-#define ED_ETR_SYNC 12 /* External damage ETR sync check */
-#define ED_ETR_SWITCH 13 /* External damage ETR switch to local */
-
-#define ED_STP_SYNC 7 /* External damage STP sync check */
-#define ED_STP_ISLAND 6 /* External damage STP island check */
-
-struct pt_regs;
-
-void s390_handle_mcck(void);
-void s390_do_machine_check(struct pt_regs *regs);
-#endif /* __s390mach */
diff --git a/drivers/s390/sysinfo.c b/drivers/s390/sysinfo.c
deleted file mode 100644
index 0eea90781385..000000000000
--- a/drivers/s390/sysinfo.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * drivers/s390/sysinfo.c
- *
- * Copyright IBM Corp. 2001, 2008
- * Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com)
- * Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <asm/ebcdic.h>
-#include <asm/sysinfo.h>
-#include <asm/cpcmd.h>
-
-/* Sigh, math-emu. Don't ask. */
-#include <asm/sfp-util.h>
-#include <math-emu/soft-fp.h>
-#include <math-emu/single.h>
-
-static inline int stsi_0(void)
-{
- int rc = stsi (NULL, 0, 0, 0);
- return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
-}
-
-static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
-{
- if (stsi(info, 1, 1, 1) == -ENOSYS)
- return len;
-
- EBCASC(info->manufacturer, sizeof(info->manufacturer));
- EBCASC(info->type, sizeof(info->type));
- EBCASC(info->model, sizeof(info->model));
- EBCASC(info->sequence, sizeof(info->sequence));
- EBCASC(info->plant, sizeof(info->plant));
- EBCASC(info->model_capacity, sizeof(info->model_capacity));
- EBCASC(info->model_perm_cap, sizeof(info->model_perm_cap));
- EBCASC(info->model_temp_cap, sizeof(info->model_temp_cap));
- len += sprintf(page + len, "Manufacturer: %-16.16s\n",
- info->manufacturer);
- len += sprintf(page + len, "Type: %-4.4s\n",
- info->type);
- if (info->model[0] != '\0')
- /*
- * Sigh: the model field has been renamed with System z9
- * to model_capacity and a new model field has been added
- * after the plant field. To avoid confusing older programs
- * the "Model:" prints "model_capacity model" or just
- * "model_capacity" if the model string is empty .
- */
- len += sprintf(page + len,
- "Model: %-16.16s %-16.16s\n",
- info->model_capacity, info->model);
- else
- len += sprintf(page + len, "Model: %-16.16s\n",
- info->model_capacity);
- len += sprintf(page + len, "Sequence Code: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant: %-4.4s\n",
- info->plant);
- len += sprintf(page + len, "Model Capacity: %-16.16s %08u\n",
- info->model_capacity, *(u32 *) info->model_cap_rating);
- if (info->model_perm_cap[0] != '\0')
- len += sprintf(page + len,
- "Model Perm. Capacity: %-16.16s %08u\n",
- info->model_perm_cap,
- *(u32 *) info->model_perm_cap_rating);
- if (info->model_temp_cap[0] != '\0')
- len += sprintf(page + len,
- "Model Temp. Capacity: %-16.16s %08u\n",
- info->model_temp_cap,
- *(u32 *) info->model_temp_cap_rating);
- return len;
-}
-
-#if 0 /* Currently unused */
-static int stsi_1_2_1(struct sysinfo_1_2_1 *info, char *page, int len)
-{
- if (stsi(info, 1, 2, 1) == -ENOSYS)
- return len;
-
- len += sprintf(page + len, "\n");
- EBCASC(info->sequence, sizeof(info->sequence));
- EBCASC(info->plant, sizeof(info->plant));
- len += sprintf(page + len, "Sequence Code of CPU: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant of CPU: %-16.16s\n",
- info->plant);
- return len;
-}
-#endif
-
-static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
-{
- struct sysinfo_1_2_2_extension *ext;
- int i;
-
- if (stsi(info, 1, 2, 2) == -ENOSYS)
- return len;
- ext = (struct sysinfo_1_2_2_extension *)
- ((unsigned long) info + info->acc_offset);
-
- len += sprintf(page + len, "\n");
- len += sprintf(page + len, "CPUs Total: %d\n",
- info->cpus_total);
- len += sprintf(page + len, "CPUs Configured: %d\n",
- info->cpus_configured);
- len += sprintf(page + len, "CPUs Standby: %d\n",
- info->cpus_standby);
- len += sprintf(page + len, "CPUs Reserved: %d\n",
- info->cpus_reserved);
-
- if (info->format == 1) {
- /*
- * Sigh 2. According to the specification the alternate
- * capability field is a 32 bit floating point number
- * if the higher order 8 bits are not zero. Printing
- * a floating point number in the kernel is a no-no,
- * always print the number as 32 bit unsigned integer.
- * The user-space needs to know about the strange
- * encoding of the alternate cpu capability.
- */
- len += sprintf(page + len, "Capability: %u %u\n",
- info->capability, ext->alt_capability);
- for (i = 2; i <= info->cpus_total; i++)
- len += sprintf(page + len,
- "Adjustment %02d-way: %u %u\n",
- i, info->adjustment[i-2],
- ext->alt_adjustment[i-2]);
-
- } else {
- len += sprintf(page + len, "Capability: %u\n",
- info->capability);
- for (i = 2; i <= info->cpus_total; i++)
- len += sprintf(page + len,
- "Adjustment %02d-way: %u\n",
- i, info->adjustment[i-2]);
- }
-
- if (info->secondary_capability != 0)
- len += sprintf(page + len, "Secondary Capability: %d\n",
- info->secondary_capability);
-
- return len;
-}
-
-#if 0 /* Currently unused */
-static int stsi_2_2_1(struct sysinfo_2_2_1 *info, char *page, int len)
-{
- if (stsi(info, 2, 2, 1) == -ENOSYS)
- return len;
-
- len += sprintf(page + len, "\n");
- EBCASC (info->sequence, sizeof(info->sequence));
- EBCASC (info->plant, sizeof(info->plant));
- len += sprintf(page + len, "Sequence Code of logical CPU: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant of logical CPU: %-16.16s\n",
- info->plant);
- return len;
-}
-#endif
-
-static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
-{
- if (stsi(info, 2, 2, 2) == -ENOSYS)
- return len;
-
- EBCASC (info->name, sizeof(info->name));
-
- len += sprintf(page + len, "\n");
- len += sprintf(page + len, "LPAR Number: %d\n",
- info->lpar_number);
-
- len += sprintf(page + len, "LPAR Characteristics: ");
- if (info->characteristics & LPAR_CHAR_DEDICATED)
- len += sprintf(page + len, "Dedicated ");
- if (info->characteristics & LPAR_CHAR_SHARED)
- len += sprintf(page + len, "Shared ");
- if (info->characteristics & LPAR_CHAR_LIMITED)
- len += sprintf(page + len, "Limited ");
- len += sprintf(page + len, "\n");
-
- len += sprintf(page + len, "LPAR Name: %-8.8s\n",
- info->name);
-
- len += sprintf(page + len, "LPAR Adjustment: %d\n",
- info->caf);
-
- len += sprintf(page + len, "LPAR CPUs Total: %d\n",
- info->cpus_total);
- len += sprintf(page + len, "LPAR CPUs Configured: %d\n",
- info->cpus_configured);
- len += sprintf(page + len, "LPAR CPUs Standby: %d\n",
- info->cpus_standby);
- len += sprintf(page + len, "LPAR CPUs Reserved: %d\n",
- info->cpus_reserved);
- len += sprintf(page + len, "LPAR CPUs Dedicated: %d\n",
- info->cpus_dedicated);
- len += sprintf(page + len, "LPAR CPUs Shared: %d\n",
- info->cpus_shared);
- return len;
-}
-
-static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
-{
- int i;
-
- if (stsi(info, 3, 2, 2) == -ENOSYS)
- return len;
- for (i = 0; i < info->count; i++) {
- EBCASC (info->vm[i].name, sizeof(info->vm[i].name));
- EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi));
- len += sprintf(page + len, "\n");
- len += sprintf(page + len, "VM%02d Name: %-8.8s\n",
- i, info->vm[i].name);
- len += sprintf(page + len, "VM%02d Control Program: %-16.16s\n",
- i, info->vm[i].cpi);
-
- len += sprintf(page + len, "VM%02d Adjustment: %d\n",
- i, info->vm[i].caf);
-
- len += sprintf(page + len, "VM%02d CPUs Total: %d\n",
- i, info->vm[i].cpus_total);
- len += sprintf(page + len, "VM%02d CPUs Configured: %d\n",
- i, info->vm[i].cpus_configured);
- len += sprintf(page + len, "VM%02d CPUs Standby: %d\n",
- i, info->vm[i].cpus_standby);
- len += sprintf(page + len, "VM%02d CPUs Reserved: %d\n",
- i, info->vm[i].cpus_reserved);
- }
- return len;
-}
-
-
-static int proc_read_sysinfo(char *page, char **start,
- off_t off, int count,
- int *eof, void *data)
-{
- unsigned long info = get_zeroed_page (GFP_KERNEL);
- int level, len;
-
- if (!info)
- return 0;
-
- len = 0;
- level = stsi_0();
- if (level >= 1)
- len = stsi_1_1_1((struct sysinfo_1_1_1 *) info, page, len);
-
- if (level >= 1)
- len = stsi_1_2_2((struct sysinfo_1_2_2 *) info, page, len);
-
- if (level >= 2)
- len = stsi_2_2_2((struct sysinfo_2_2_2 *) info, page, len);
-
- if (level >= 3)
- len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
-
- free_page (info);
- return len;
-}
-
-static __init int create_proc_sysinfo(void)
-{
- create_proc_read_entry("sysinfo", 0444, NULL,
- proc_read_sysinfo, NULL);
- return 0;
-}
-
-__initcall(create_proc_sysinfo);
-
-/*
- * Service levels interface.
- */
-
-static DECLARE_RWSEM(service_level_sem);
-static LIST_HEAD(service_level_list);
-
-int register_service_level(struct service_level *slr)
-{
- struct service_level *ptr;
-
- down_write(&service_level_sem);
- list_for_each_entry(ptr, &service_level_list, list)
- if (ptr == slr) {
- up_write(&service_level_sem);
- return -EEXIST;
- }
- list_add_tail(&slr->list, &service_level_list);
- up_write(&service_level_sem);
- return 0;
-}
-EXPORT_SYMBOL(register_service_level);
-
-int unregister_service_level(struct service_level *slr)
-{
- struct service_level *ptr, *next;
- int rc = -ENOENT;
-
- down_write(&service_level_sem);
- list_for_each_entry_safe(ptr, next, &service_level_list, list) {
- if (ptr != slr)
- continue;
- list_del(&ptr->list);
- rc = 0;
- break;
- }
- up_write(&service_level_sem);
- return rc;
-}
-EXPORT_SYMBOL(unregister_service_level);
-
-static void *service_level_start(struct seq_file *m, loff_t *pos)
-{
- down_read(&service_level_sem);
- return seq_list_start(&service_level_list, *pos);
-}
-
-static void *service_level_next(struct seq_file *m, void *p, loff_t *pos)
-{
- return seq_list_next(p, &service_level_list, pos);
-}
-
-static void service_level_stop(struct seq_file *m, void *p)
-{
- up_read(&service_level_sem);
-}
-
-static int service_level_show(struct seq_file *m, void *p)
-{
- struct service_level *slr;
-
- slr = list_entry(p, struct service_level, list);
- slr->seq_print(m, slr);
- return 0;
-}
-
-static const struct seq_operations service_level_seq_ops = {
- .start = service_level_start,
- .next = service_level_next,
- .stop = service_level_stop,
- .show = service_level_show
-};
-
-static int service_level_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &service_level_seq_ops);
-}
-
-static const struct file_operations service_level_ops = {
- .open = service_level_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release
-};
-
-static void service_level_vm_print(struct seq_file *m,
- struct service_level *slr)
-{
- char *query_buffer, *str;
-
- query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
- if (!query_buffer)
- return;
- cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
- str = strchr(query_buffer, '\n');
- if (str)
- *str = 0;
- seq_printf(m, "VM: %s\n", query_buffer);
- kfree(query_buffer);
-}
-
-static struct service_level service_level_vm = {
- .seq_print = service_level_vm_print
-};
-
-static __init int create_proc_service_level(void)
-{
- proc_create("service_levels", 0, NULL, &service_level_ops);
- if (MACHINE_IS_VM)
- register_service_level(&service_level_vm);
- return 0;
-}
-
-subsys_initcall(create_proc_service_level);
-
-/*
- * Bogomips calculation based on cpu capability.
- */
-
-int get_cpu_capability(unsigned int *capability)
-{
- struct sysinfo_1_2_2 *info;
- int rc;
-
- info = (void *) get_zeroed_page(GFP_KERNEL);
- if (!info)
- return -ENOMEM;
- rc = stsi(info, 1, 2, 2);
- if (rc == -ENOSYS)
- goto out;
- rc = 0;
- *capability = info->capability;
-out:
- free_page((unsigned long) info);
- return rc;
-}
-
-/*
- * CPU capability might have changed. Therefore recalculate loops_per_jiffy.
- */
-void s390_adjust_jiffies(void)
-{
- struct sysinfo_1_2_2 *info;
- const unsigned int fmil = 0x4b189680; /* 1e7 as 32-bit float. */
- FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
- FP_DECL_EX;
- unsigned int capability;
-
- info = (void *) get_zeroed_page(GFP_KERNEL);
- if (!info)
- return;
-
- if (stsi(info, 1, 2, 2) != -ENOSYS) {
- /*
- * Major sigh. The cpu capability encoding is "special".
- * If the first 9 bits of info->capability are 0 then it
- * is a 32 bit unsigned integer in the range 0 .. 2^23.
- * If the first 9 bits are != 0 then it is a 32 bit float.
- * In addition a lower value indicates a proportionally
- * higher cpu capacity. Bogomips are the other way round.
- * To get to a halfway suitable number we divide 1e7
- * by the cpu capability number. Yes, that means a floating
- * point division .. math-emu here we come :-)
- */
- FP_UNPACK_SP(SA, &fmil);
- if ((info->capability >> 23) == 0)
- FP_FROM_INT_S(SB, info->capability, 32, int);
- else
- FP_UNPACK_SP(SB, &info->capability);
- FP_DIV_S(SR, SA, SB);
- FP_TO_INT_S(capability, SR, 32, 0);
- } else
- /*
- * Really old machine without stsi block for basic
- * cpu information. Report 42.0 bogomips.
- */
- capability = 42;
- loops_per_jiffy = capability * (500000/HZ);
- free_page((unsigned long) info);
-}
-
-/*
- * calibrate the delay loop
- */
-void __cpuinit calibrate_delay(void)
-{
- s390_adjust_jiffies();
- /* Print the good old Bogomips line .. */
- printk(KERN_DEBUG "Calibrating delay loop (skipped)... "
- "%lu.%02lu BogoMIPS preset\n", loops_per_jiffy/(500000/HZ),
- (loops_per_jiffy/(5000/HZ)) % 100);
-}
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index d4bda2017746..6d25aca7b412 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -35,7 +35,7 @@ static struct platform_device *a4000t_scsi_device;
#define A4000T_SCSI_ADDR 0xdd0040
-static int __devinit a4000t_probe(struct device *dev)
+static int __devinit a4000t_probe(struct platform_device *dev)
{
struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata;
@@ -78,7 +78,7 @@ static int __devinit a4000t_probe(struct device *dev)
goto out_put_host;
}
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);
return 0;
@@ -93,9 +93,9 @@ static int __devinit a4000t_probe(struct device *dev)
return -ENODEV;
}
-static __devexit int a4000t_device_remove(struct device *dev)
+static __devexit int a4000t_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
scsi_remove_host(host);
@@ -108,25 +108,27 @@ static __devexit int a4000t_device_remove(struct device *dev)
return 0;
}
-static struct device_driver a4000t_scsi_driver = {
- .name = "a4000t-scsi",
- .bus = &platform_bus_type,
- .probe = a4000t_probe,
- .remove = __devexit_p(a4000t_device_remove),
+static struct platform_driver a4000t_scsi_driver = {
+ .driver = {
+ .name = "a4000t-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = a4000t_probe,
+ .remove = __devexit_p(a4000t_device_remove),
};
static int __init a4000t_scsi_init(void)
{
int err;
- err = driver_register(&a4000t_scsi_driver);
+ err = platform_driver_register(&a4000t_scsi_driver);
if (err)
return err;
a4000t_scsi_device = platform_device_register_simple("a4000t-scsi",
-1, NULL, 0);
if (IS_ERR(a4000t_scsi_device)) {
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_register(&a4000t_scsi_driver);
return PTR_ERR(a4000t_scsi_device);
}
@@ -136,7 +138,7 @@ static int __init a4000t_scsi_init(void)
static void __exit a4000t_scsi_exit(void)
{
platform_device_unregister(a4000t_scsi_device);
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_unregister(&a4000t_scsi_driver);
}
module_init(a4000t_scsi_init);
diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
index 68a64123af8f..8ee01b907332 100644
--- a/drivers/scsi/arm/cumana_2.c
+++ b/drivers/scsi/arm/cumana_2.c
@@ -390,7 +390,8 @@ static struct scsi_host_template cumanascsi2_template = {
.eh_abort_handler = fas216_eh_abort,
.can_queue = 1,
.this_id = 7,
- .sg_tablesize = SG_ALL,
+ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
+ .dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "cumanascsi2",
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index bb2477b3fb0b..d8435132f461 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -508,7 +508,8 @@ static struct scsi_host_template eesox_template = {
.eh_abort_handler = fas216_eh_abort,
.can_queue = 1,
.this_id = 7,
- .sg_tablesize = SG_ALL,
+ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
+ .dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "eesox",
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index d9a546d1917c..e2297b4c1b9e 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -302,7 +302,8 @@ static struct scsi_host_template powertecscsi_template = {
.can_queue = 8,
.this_id = 7,
- .sg_tablesize = SG_ALL,
+ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
+ .dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
.proc_name = "powertec",
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c
index d858f3d41274..9e9a82b03f2d 100644
--- a/drivers/scsi/bvme6000_scsi.c
+++ b/drivers/scsi/bvme6000_scsi.c
@@ -34,7 +34,7 @@ static struct scsi_host_template bvme6000_scsi_driver_template = {
static struct platform_device *bvme6000_scsi_device;
static __devinit int
-bvme6000_probe(struct device *dev)
+bvme6000_probe(struct platform_device *dev)
{
struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata;
@@ -73,7 +73,7 @@ bvme6000_probe(struct device *dev)
goto out_put_host;
}
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);
return 0;
@@ -87,9 +87,9 @@ bvme6000_probe(struct device *dev)
}
static __devexit int
-bvme6000_device_remove(struct device *dev)
+bvme6000_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
scsi_remove_host(host);
@@ -100,25 +100,27 @@ bvme6000_device_remove(struct device *dev)
return 0;
}
-static struct device_driver bvme6000_scsi_driver = {
- .name = "bvme6000-scsi",
- .bus = &platform_bus_type,
- .probe = bvme6000_probe,
- .remove = __devexit_p(bvme6000_device_remove),
+static struct platform_driver bvme6000_scsi_driver = {
+ .driver = {
+ .name = "bvme6000-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = bvme6000_probe,
+ .remove = __devexit_p(bvme6000_device_remove),
};
static int __init bvme6000_scsi_init(void)
{
int err;
- err = driver_register(&bvme6000_scsi_driver);
+ err = platform_driver_register(&bvme6000_scsi_driver);
if (err)
return err;
bvme6000_scsi_device = platform_device_register_simple("bvme6000-scsi",
-1, NULL, 0);
if (IS_ERR(bvme6000_scsi_device)) {
- driver_unregister(&bvme6000_scsi_driver);
+ platform_driver_unregister(&bvme6000_scsi_driver);
return PTR_ERR(bvme6000_scsi_device);
}
@@ -128,7 +130,7 @@ static int __init bvme6000_scsi_init(void)
static void __exit bvme6000_scsi_exit(void)
{
platform_device_unregister(bvme6000_scsi_device);
- driver_unregister(&bvme6000_scsi_driver);
+ platform_driver_unregister(&bvme6000_scsi_driver);
}
module_init(bvme6000_scsi_init);
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h
index fde6e4c634e7..a7cf550b9cca 100644
--- a/drivers/scsi/cxgb3i/cxgb3i.h
+++ b/drivers/scsi/cxgb3i/cxgb3i.h
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/scatterlist.h>
+#include <linux/skbuff.h>
#include <scsi/libiscsi_tcp.h>
/* from cxgb3 LLD */
@@ -113,6 +114,26 @@ struct cxgb3i_endpoint {
struct cxgb3i_conn *cconn;
};
+/**
+ * struct cxgb3i_task_data - private iscsi task data
+ *
+ * @nr_frags: # of coalesced page frags (from scsi sgl)
+ * @frags: coalesced page frags (from scsi sgl)
+ * @skb: tx pdu skb
+ * @offset: data offset for the next pdu
+ * @count: max. possible pdu payload
+ * @sgoffset: offset to the first sg entry for a given offset
+ */
+#define MAX_PDU_FRAGS ((ULP2_MAX_PDU_PAYLOAD + 512 - 1) / 512)
+struct cxgb3i_task_data {
+ unsigned short nr_frags;
+ skb_frag_t frags[MAX_PDU_FRAGS];
+ struct sk_buff *skb;
+ unsigned int offset;
+ unsigned int count;
+ unsigned int sgoffset;
+};
+
int cxgb3i_iscsi_init(void);
void cxgb3i_iscsi_cleanup(void);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
index 08f3a09d9233..a83d36e4926f 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
@@ -639,10 +639,11 @@ static int ddp_init(struct t3cdev *tdev)
write_unlock(&cxgb3i_ddp_rwlock);
ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x "
- "pkt %u,%u.\n",
+ "pkt %u/%u, %u/%u.\n",
ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits,
ddp->idx_mask, ddp->rsvd_tag_mask,
- ddp->max_txsz, ddp->max_rxsz);
+ ddp->max_txsz, uinfo.max_txsz,
+ ddp->max_rxsz, uinfo.max_rxsz);
return 0;
free_ddp_map:
@@ -654,8 +655,8 @@ free_ddp_map:
* cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource
* @tdev: t3cdev adapter
* @tformat: tag format
- * @txsz: max tx pkt size, filled in by this func.
- * @rxsz: max rx pkt size, filled in by this func.
+ * @txsz: max tx pdu payload size, filled in by this func.
+ * @rxsz: max rx pdu payload size, filled in by this func.
* initialize the ddp pagepod manager for a given adapter if needed and
* setup the tag format for a given iscsi entity
*/
@@ -685,10 +686,12 @@ int cxgb3i_adapter_ddp_init(struct t3cdev *tdev,
tformat->sw_bits, tformat->rsvd_bits,
tformat->rsvd_shift, tformat->rsvd_mask);
- *txsz = ddp->max_txsz;
- *rxsz = ddp->max_rxsz;
- ddp_log_info("ddp max pkt size: %u, %u.\n",
- ddp->max_txsz, ddp->max_rxsz);
+ *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ ddp_log_info("max payload size: %u/%u, %u/%u.\n",
+ *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
return 0;
}
EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
index 5c7c4d95c493..3faae7831c83 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
@@ -13,6 +13,8 @@
#ifndef __CXGB3I_ULP2_DDP_H__
#define __CXGB3I_ULP2_DDP_H__
+#include <linux/vmalloc.h>
+
/**
* struct cxgb3i_tag_format - cxgb3i ulp tag format for an iscsi entity
*
@@ -85,8 +87,9 @@ struct cxgb3i_ddp_info {
struct sk_buff **gl_skb;
};
+#define ISCSI_PDU_NONPAYLOAD_LEN 312 /* bhs(48) + ahs(256) + digest(8) */
#define ULP2_MAX_PKT_SIZE 16224
-#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_MAX)
+#define ULP2_MAX_PDU_PAYLOAD (ULP2_MAX_PKT_SIZE - ISCSI_PDU_NONPAYLOAD_LEN)
#define PPOD_PAGES_MAX 4
#define PPOD_PAGES_SHIFT 2 /* 4 pages per pod */
diff --git a/drivers/scsi/cxgb3i/cxgb3i_init.c b/drivers/scsi/cxgb3i/cxgb3i_init.c
index 091ecb4d9f3d..1ce9f244e46c 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_init.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_init.c
@@ -12,8 +12,8 @@
#include "cxgb3i.h"
#define DRV_MODULE_NAME "cxgb3i"
-#define DRV_MODULE_VERSION "1.0.0"
-#define DRV_MODULE_RELDATE "Jun. 1, 2008"
+#define DRV_MODULE_VERSION "1.0.1"
+#define DRV_MODULE_RELDATE "Jan. 2009"
static char version[] =
"Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index d83464b9b3f9..fa2a44f37b36 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -364,7 +364,8 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth,
cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost,
cmds_max,
- sizeof(struct iscsi_tcp_task),
+ sizeof(struct iscsi_tcp_task) +
+ sizeof(struct cxgb3i_task_data),
initial_cmdsn, ISCSI_MAX_TARGET);
if (!cls_session)
return NULL;
@@ -402,17 +403,15 @@ static inline int cxgb3i_conn_max_xmit_dlength(struct iscsi_conn *conn)
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- cconn->hba->snic->tx_max_size -
- ISCSI_PDU_NONPAYLOAD_MAX);
+ unsigned int max = max(512 * MAX_SKB_FRAGS, SKB_TX_HEADROOM);
+ max = min(cconn->hba->snic->tx_max_size, max);
if (conn->max_xmit_dlength)
- conn->max_xmit_dlength = min_t(unsigned int,
- conn->max_xmit_dlength, max);
+ conn->max_xmit_dlength = min(conn->max_xmit_dlength, max);
else
conn->max_xmit_dlength = max;
align_pdu_size(conn->max_xmit_dlength);
- cxgb3i_log_info("conn 0x%p, max xmit %u.\n",
+ cxgb3i_api_debug("conn 0x%p, max xmit %u.\n",
conn, conn->max_xmit_dlength);
return 0;
}
@@ -427,9 +426,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn)
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct cxgb3i_conn *cconn = tcp_conn->dd_data;
- unsigned int max = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- cconn->hba->snic->rx_max_size -
- ISCSI_PDU_NONPAYLOAD_MAX);
+ unsigned int max = cconn->hba->snic->rx_max_size;
align_pdu_size(max);
if (conn->max_recv_dlength) {
@@ -439,8 +436,7 @@ static inline int cxgb3i_conn_max_recv_dlength(struct iscsi_conn *conn)
conn->max_recv_dlength, max);
return -EINVAL;
}
- conn->max_recv_dlength = min_t(unsigned int,
- conn->max_recv_dlength, max);
+ conn->max_recv_dlength = min(conn->max_recv_dlength, max);
align_pdu_size(conn->max_recv_dlength);
} else
conn->max_recv_dlength = max;
@@ -844,7 +840,7 @@ static struct scsi_host_template cxgb3i_host_template = {
.proc_name = "cxgb3i",
.queuecommand = iscsi_queuecommand,
.change_queue_depth = iscsi_change_queue_depth,
- .can_queue = 128 * (ISCSI_DEF_XMIT_CMDS_MAX - 1),
+ .can_queue = CXGB3I_SCSI_QDEPTH_DFLT - 1,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index a865f1fefe8b..de3b3b614cca 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -23,19 +23,19 @@
#include "cxgb3i_ddp.h"
#ifdef __DEBUG_C3CN_CONN__
-#define c3cn_conn_debug cxgb3i_log_info
+#define c3cn_conn_debug cxgb3i_log_debug
#else
#define c3cn_conn_debug(fmt...)
#endif
#ifdef __DEBUG_C3CN_TX__
-#define c3cn_tx_debug cxgb3i_log_debug
+#define c3cn_tx_debug cxgb3i_log_debug
#else
#define c3cn_tx_debug(fmt...)
#endif
#ifdef __DEBUG_C3CN_RX__
-#define c3cn_rx_debug cxgb3i_log_debug
+#define c3cn_rx_debug cxgb3i_log_debug
#else
#define c3cn_rx_debug(fmt...)
#endif
@@ -47,9 +47,9 @@ static int cxgb3_rcv_win = 256 * 1024;
module_param(cxgb3_rcv_win, int, 0644);
MODULE_PARM_DESC(cxgb3_rcv_win, "TCP receive window in bytes (default=256KB)");
-static int cxgb3_snd_win = 64 * 1024;
+static int cxgb3_snd_win = 128 * 1024;
module_param(cxgb3_snd_win, int, 0644);
-MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=64KB)");
+MODULE_PARM_DESC(cxgb3_snd_win, "TCP send window in bytes (default=128KB)");
static int cxgb3_rx_credit_thres = 10 * 1024;
module_param(cxgb3_rx_credit_thres, int, 0644);
@@ -301,8 +301,8 @@ static void act_open_req_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
static void skb_entail(struct s3_conn *c3cn, struct sk_buff *skb,
int flags)
{
- CXGB3_SKB_CB(skb)->seq = c3cn->write_seq;
- CXGB3_SKB_CB(skb)->flags = flags;
+ skb_tcp_seq(skb) = c3cn->write_seq;
+ skb_flags(skb) = flags;
__skb_queue_tail(&c3cn->write_queue, skb);
}
@@ -457,12 +457,9 @@ static unsigned int wrlen __read_mostly;
* The number of WRs needed for an skb depends on the number of fragments
* in the skb and whether it has any payload in its main body. This maps the
* length of the gather list represented by an skb into the # of necessary WRs.
- *
- * The max. length of an skb is controlled by the max pdu size which is ~16K.
- * Also, assume the min. fragment length is the sector size (512), then add
- * extra fragment counts for iscsi bhs and payload padding.
+ * The extra two fragments are for iscsi bhs and payload padding.
*/
-#define SKB_WR_LIST_SIZE (16384/512 + 3)
+#define SKB_WR_LIST_SIZE (MAX_SKB_FRAGS + 2)
static unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly;
static void s3_init_wr_tab(unsigned int wr_len)
@@ -485,7 +482,7 @@ static void s3_init_wr_tab(unsigned int wr_len)
static inline void reset_wr_list(struct s3_conn *c3cn)
{
- c3cn->wr_pending_head = NULL;
+ c3cn->wr_pending_head = c3cn->wr_pending_tail = NULL;
}
/*
@@ -496,7 +493,7 @@ static inline void reset_wr_list(struct s3_conn *c3cn)
static inline void enqueue_wr(struct s3_conn *c3cn,
struct sk_buff *skb)
{
- skb_wr_data(skb) = NULL;
+ skb_tx_wr_next(skb) = NULL;
/*
* We want to take an extra reference since both us and the driver
@@ -509,10 +506,22 @@ static inline void enqueue_wr(struct s3_conn *c3cn,
if (!c3cn->wr_pending_head)
c3cn->wr_pending_head = skb;
else
- skb_wr_data(skb) = skb;
+ skb_tx_wr_next(c3cn->wr_pending_tail) = skb;
c3cn->wr_pending_tail = skb;
}
+static int count_pending_wrs(struct s3_conn *c3cn)
+{
+ int n = 0;
+ const struct sk_buff *skb = c3cn->wr_pending_head;
+
+ while (skb) {
+ n += skb->csum;
+ skb = skb_tx_wr_next(skb);
+ }
+ return n;
+}
+
static inline struct sk_buff *peek_wr(const struct s3_conn *c3cn)
{
return c3cn->wr_pending_head;
@@ -529,8 +538,8 @@ static inline struct sk_buff *dequeue_wr(struct s3_conn *c3cn)
if (likely(skb)) {
/* Don't bother clearing the tail */
- c3cn->wr_pending_head = skb_wr_data(skb);
- skb_wr_data(skb) = NULL;
+ c3cn->wr_pending_head = skb_tx_wr_next(skb);
+ skb_tx_wr_next(skb) = NULL;
}
return skb;
}
@@ -543,13 +552,14 @@ static void purge_wr_queue(struct s3_conn *c3cn)
}
static inline void make_tx_data_wr(struct s3_conn *c3cn, struct sk_buff *skb,
- int len)
+ int len, int req_completion)
{
struct tx_data_wr *req;
skb_reset_transport_header(skb);
req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req));
- req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA));
+ req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) |
+ (req_completion ? F_WR_COMPL : 0));
req->wr_lo = htonl(V_WR_TID(c3cn->tid));
req->sndseq = htonl(c3cn->snd_nxt);
/* len includes the length of any HW ULP additions */
@@ -592,7 +602,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
if (unlikely(c3cn->state == C3CN_STATE_CONNECTING ||
c3cn->state == C3CN_STATE_CLOSE_WAIT_1 ||
- c3cn->state == C3CN_STATE_ABORTING)) {
+ c3cn->state >= C3CN_STATE_ABORTING)) {
c3cn_tx_debug("c3cn 0x%p, in closing state %u.\n",
c3cn, c3cn->state);
return 0;
@@ -615,7 +625,7 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
if (c3cn->wr_avail < wrs_needed) {
c3cn_tx_debug("c3cn 0x%p, skb len %u/%u, frag %u, "
"wr %d < %u.\n",
- c3cn, skb->len, skb->datalen, frags,
+ c3cn, skb->len, skb->data_len, frags,
wrs_needed, c3cn->wr_avail);
break;
}
@@ -627,20 +637,24 @@ static int c3cn_push_tx_frames(struct s3_conn *c3cn, int req_completion)
c3cn->wr_unacked += wrs_needed;
enqueue_wr(c3cn, skb);
- if (likely(CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_NEED_HDR)) {
- len += ulp_extra_len(skb);
- make_tx_data_wr(c3cn, skb, len);
- c3cn->snd_nxt += len;
- if ((req_completion
- && c3cn->wr_unacked == wrs_needed)
- || (CXGB3_SKB_CB(skb)->flags & C3CB_FLAG_COMPL)
- || c3cn->wr_unacked >= c3cn->wr_max / 2) {
- struct work_request_hdr *wr = cplhdr(skb);
+ c3cn_tx_debug("c3cn 0x%p, enqueue, skb len %u/%u, frag %u, "
+ "wr %d, left %u, unack %u.\n",
+ c3cn, skb->len, skb->data_len, frags,
+ wrs_needed, c3cn->wr_avail, c3cn->wr_unacked);
+
- wr->wr_hi |= htonl(F_WR_COMPL);
+ if (likely(skb_flags(skb) & C3CB_FLAG_NEED_HDR)) {
+ if ((req_completion &&
+ c3cn->wr_unacked == wrs_needed) ||
+ (skb_flags(skb) & C3CB_FLAG_COMPL) ||
+ c3cn->wr_unacked >= c3cn->wr_max / 2) {
+ req_completion = 1;
c3cn->wr_unacked = 0;
}
- CXGB3_SKB_CB(skb)->flags &= ~C3CB_FLAG_NEED_HDR;
+ len += ulp_extra_len(skb);
+ make_tx_data_wr(c3cn, skb, len, req_completion);
+ c3cn->snd_nxt += len;
+ skb_flags(skb) &= ~C3CB_FLAG_NEED_HDR;
}
total_size += skb->truesize;
@@ -735,8 +749,11 @@ static void process_act_establish(struct s3_conn *c3cn, struct sk_buff *skb)
if (unlikely(c3cn_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED)))
/* upper layer has requested closing */
send_abort_req(c3cn);
- else if (c3cn_push_tx_frames(c3cn, 1))
+ else {
+ if (skb_queue_len(&c3cn->write_queue))
+ c3cn_push_tx_frames(c3cn, 1);
cxgb3i_conn_tx_open(c3cn);
+ }
}
static int do_act_establish(struct t3cdev *cdev, struct sk_buff *skb,
@@ -1082,8 +1099,8 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
return;
}
- CXGB3_SKB_CB(skb)->seq = ntohl(hdr_cpl->seq);
- CXGB3_SKB_CB(skb)->flags = 0;
+ skb_tcp_seq(skb) = ntohl(hdr_cpl->seq);
+ skb_flags(skb) = 0;
skb_reset_transport_header(skb);
__skb_pull(skb, sizeof(struct cpl_iscsi_hdr));
@@ -1103,12 +1120,12 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
goto abort_conn;
skb_ulp_mode(skb) = ULP2_FLAG_DATA_READY;
- skb_ulp_pdulen(skb) = ntohs(ddp_cpl.len);
- skb_ulp_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
+ skb_rx_pdulen(skb) = ntohs(ddp_cpl.len);
+ skb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc);
status = ntohl(ddp_cpl.ddp_status);
c3cn_rx_debug("rx skb 0x%p, len %u, pdulen %u, ddp status 0x%x.\n",
- skb, skb->len, skb_ulp_pdulen(skb), status);
+ skb, skb->len, skb_rx_pdulen(skb), status);
if (status & (1 << RX_DDP_STATUS_HCRC_SHIFT))
skb_ulp_mode(skb) |= ULP2_FLAG_HCRC_ERROR;
@@ -1126,7 +1143,7 @@ static void process_rx_iscsi_hdr(struct s3_conn *c3cn, struct sk_buff *skb)
} else if (status & (1 << RX_DDP_STATUS_DDP_SHIFT))
skb_ulp_mode(skb) |= ULP2_FLAG_DATA_DDPED;
- c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_ulp_pdulen(skb);
+ c3cn->rcv_nxt = ntohl(ddp_cpl.seq) + skb_rx_pdulen(skb);
__pskb_trim(skb, len);
__skb_queue_tail(&c3cn->receive_queue, skb);
cxgb3i_conn_pdu_ready(c3cn);
@@ -1151,12 +1168,27 @@ static int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx)
* Process an acknowledgment of WR completion. Advance snd_una and send the
* next batch of work requests from the write queue.
*/
+static void check_wr_invariants(struct s3_conn *c3cn)
+{
+ int pending = count_pending_wrs(c3cn);
+
+ if (unlikely(c3cn->wr_avail + pending != c3cn->wr_max))
+ cxgb3i_log_error("TID %u: credit imbalance: avail %u, "
+ "pending %u, total should be %u\n",
+ c3cn->tid, c3cn->wr_avail, pending,
+ c3cn->wr_max);
+}
+
static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
{
struct cpl_wr_ack *hdr = cplhdr(skb);
unsigned int credits = ntohs(hdr->credits);
u32 snd_una = ntohl(hdr->snd_una);
+ c3cn_tx_debug("%u WR credits, avail %u, unack %u, TID %u, state %u.\n",
+ credits, c3cn->wr_avail, c3cn->wr_unacked,
+ c3cn->tid, c3cn->state);
+
c3cn->wr_avail += credits;
if (c3cn->wr_unacked > c3cn->wr_max - c3cn->wr_avail)
c3cn->wr_unacked = c3cn->wr_max - c3cn->wr_avail;
@@ -1171,6 +1203,17 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
break;
}
if (unlikely(credits < p->csum)) {
+ struct tx_data_wr *w = cplhdr(p);
+ cxgb3i_log_error("TID %u got %u WR credits need %u, "
+ "len %u, main body %u, frags %u, "
+ "seq # %u, ACK una %u, ACK nxt %u, "
+ "WR_AVAIL %u, WRs pending %u\n",
+ c3cn->tid, credits, p->csum, p->len,
+ p->len - p->data_len,
+ skb_shinfo(p)->nr_frags,
+ ntohl(w->sndseq), snd_una,
+ ntohl(hdr->snd_nxt), c3cn->wr_avail,
+ count_pending_wrs(c3cn) - credits);
p->csum -= credits;
break;
} else {
@@ -1180,15 +1223,24 @@ static void process_wr_ack(struct s3_conn *c3cn, struct sk_buff *skb)
}
}
- if (unlikely(before(snd_una, c3cn->snd_una)))
+ check_wr_invariants(c3cn);
+
+ if (unlikely(before(snd_una, c3cn->snd_una))) {
+ cxgb3i_log_error("TID %u, unexpected sequence # %u in WR_ACK "
+ "snd_una %u\n",
+ c3cn->tid, snd_una, c3cn->snd_una);
goto out_free;
+ }
if (c3cn->snd_una != snd_una) {
c3cn->snd_una = snd_una;
dst_confirm(c3cn->dst_cache);
}
- if (skb_queue_len(&c3cn->write_queue) && c3cn_push_tx_frames(c3cn, 0))
+ if (skb_queue_len(&c3cn->write_queue)) {
+ if (c3cn_push_tx_frames(c3cn, 0))
+ cxgb3i_conn_tx_open(c3cn);
+ } else
cxgb3i_conn_tx_open(c3cn);
out_free:
__kfree_skb(skb);
@@ -1452,7 +1504,7 @@ static void init_offload_conn(struct s3_conn *c3cn,
struct dst_entry *dst)
{
BUG_ON(c3cn->cdev != cdev);
- c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs;
+ c3cn->wr_max = c3cn->wr_avail = T3C_DATA(cdev)->max_wrs - 1;
c3cn->wr_unacked = 0;
c3cn->mss_idx = select_mss(c3cn, dst_mtu(dst));
@@ -1671,9 +1723,17 @@ int cxgb3i_c3cn_send_pdus(struct s3_conn *c3cn, struct sk_buff *skb)
goto out_err;
}
- err = -EPIPE;
if (c3cn->err) {
c3cn_tx_debug("c3cn 0x%p, err %d.\n", c3cn, c3cn->err);
+ err = -EPIPE;
+ goto out_err;
+ }
+
+ if (c3cn->write_seq - c3cn->snd_una >= cxgb3_snd_win) {
+ c3cn_tx_debug("c3cn 0x%p, snd %u - %u > %u.\n",
+ c3cn, c3cn->write_seq, c3cn->snd_una,
+ cxgb3_snd_win);
+ err = -EAGAIN;
goto out_err;
}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
index d23156907ffd..6344b9eb2589 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
@@ -178,25 +178,33 @@ void cxgb3i_c3cn_release(struct s3_conn *);
* @flag: see C3CB_FLAG_* below
* @ulp_mode: ULP mode/submode of sk_buff
* @seq: tcp sequence number
- * @ddigest: pdu data digest
- * @pdulen: recovered pdu length
- * @wr_data: scratch area for tx wr
*/
+struct cxgb3_skb_rx_cb {
+ __u32 ddigest; /* data digest */
+ __u32 pdulen; /* recovered pdu length */
+};
+
+struct cxgb3_skb_tx_cb {
+ struct sk_buff *wr_next; /* next wr */
+};
+
struct cxgb3_skb_cb {
__u8 flags;
__u8 ulp_mode;
__u32 seq;
- __u32 ddigest;
- __u32 pdulen;
- struct sk_buff *wr_data;
+ union {
+ struct cxgb3_skb_rx_cb rx;
+ struct cxgb3_skb_tx_cb tx;
+ };
};
#define CXGB3_SKB_CB(skb) ((struct cxgb3_skb_cb *)&((skb)->cb[0]))
-
+#define skb_flags(skb) (CXGB3_SKB_CB(skb)->flags)
#define skb_ulp_mode(skb) (CXGB3_SKB_CB(skb)->ulp_mode)
-#define skb_ulp_ddigest(skb) (CXGB3_SKB_CB(skb)->ddigest)
-#define skb_ulp_pdulen(skb) (CXGB3_SKB_CB(skb)->pdulen)
-#define skb_wr_data(skb) (CXGB3_SKB_CB(skb)->wr_data)
+#define skb_tcp_seq(skb) (CXGB3_SKB_CB(skb)->seq)
+#define skb_rx_ddigest(skb) (CXGB3_SKB_CB(skb)->rx.ddigest)
+#define skb_rx_pdulen(skb) (CXGB3_SKB_CB(skb)->rx.pdulen)
+#define skb_tx_wr_next(skb) (CXGB3_SKB_CB(skb)->tx.wr_next)
enum c3cb_flags {
C3CB_FLAG_NEED_HDR = 1 << 0, /* packet needs a TX_DATA_WR header */
@@ -217,6 +225,7 @@ struct sge_opaque_hdr {
/* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */
#define TX_HEADER_LEN \
(sizeof(struct tx_data_wr) + sizeof(struct sge_opaque_hdr))
+#define SKB_TX_HEADROOM SKB_MAX_HEAD(TX_HEADER_LEN)
/*
* get and set private ip for iscsi traffic
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
index ce7ce8c6094c..17115c230d65 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c
@@ -32,6 +32,10 @@
#define cxgb3i_tx_debug(fmt...)
#endif
+/* always allocate rooms for AHS */
+#define SKB_TX_PDU_HEADER_LEN \
+ (sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE)
+static unsigned int skb_extra_headroom;
static struct page *pad_page;
/*
@@ -146,12 +150,13 @@ static inline void tx_skb_setmode(struct sk_buff *skb, int hcrc, int dcrc)
void cxgb3i_conn_cleanup_task(struct iscsi_task *task)
{
- struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgb3i_task_data *tdata = task->dd_data +
+ sizeof(struct iscsi_tcp_task);
/* never reached the xmit task callout */
- if (tcp_task->dd_data)
- kfree_skb(tcp_task->dd_data);
- tcp_task->dd_data = NULL;
+ if (tdata->skb)
+ __kfree_skb(tdata->skb);
+ memset(tdata, 0, sizeof(struct cxgb3i_task_data));
/* MNC - Do we need a check in case this is called but
* cxgb3i_conn_alloc_pdu has never been called on the task */
@@ -159,28 +164,102 @@ void cxgb3i_conn_cleanup_task(struct iscsi_task *task)
iscsi_tcp_cleanup_task(task);
}
-/*
- * We do not support ahs yet
- */
+static int sgl_seek_offset(struct scatterlist *sgl, unsigned int sgcnt,
+ unsigned int offset, unsigned int *off,
+ struct scatterlist **sgp)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sgl, sg, sgcnt, i) {
+ if (offset < sg->length) {
+ *off = offset;
+ *sgp = sg;
+ return 0;
+ }
+ offset -= sg->length;
+ }
+ return -EFAULT;
+}
+
+static int sgl_read_to_frags(struct scatterlist *sg, unsigned int sgoffset,
+ unsigned int dlen, skb_frag_t *frags,
+ int frag_max)
+{
+ unsigned int datalen = dlen;
+ unsigned int sglen = sg->length - sgoffset;
+ struct page *page = sg_page(sg);
+ int i;
+
+ i = 0;
+ do {
+ unsigned int copy;
+
+ if (!sglen) {
+ sg = sg_next(sg);
+ if (!sg) {
+ cxgb3i_log_error("%s, sg NULL, len %u/%u.\n",
+ __func__, datalen, dlen);
+ return -EINVAL;
+ }
+ sgoffset = 0;
+ sglen = sg->length;
+ page = sg_page(sg);
+
+ }
+ copy = min(datalen, sglen);
+ if (i && page == frags[i - 1].page &&
+ sgoffset + sg->offset ==
+ frags[i - 1].page_offset + frags[i - 1].size) {
+ frags[i - 1].size += copy;
+ } else {
+ if (i >= frag_max) {
+ cxgb3i_log_error("%s, too many pages %u, "
+ "dlen %u.\n", __func__,
+ frag_max, dlen);
+ return -EINVAL;
+ }
+
+ frags[i].page = page;
+ frags[i].page_offset = sg->offset + sgoffset;
+ frags[i].size = copy;
+ i++;
+ }
+ datalen -= copy;
+ sgoffset += copy;
+ sglen -= copy;
+ } while (datalen);
+
+ return i;
+}
+
int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
{
+ struct iscsi_conn *conn = task->conn;
struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct sk_buff *skb;
+ struct cxgb3i_task_data *tdata = task->dd_data + sizeof(*tcp_task);
+ struct scsi_cmnd *sc = task->sc;
+ int headroom = SKB_TX_PDU_HEADER_LEN;
+ tcp_task->dd_data = tdata;
task->hdr = NULL;
- /* always allocate rooms for AHS */
- skb = alloc_skb(sizeof(struct iscsi_hdr) + ISCSI_MAX_AHS_SIZE +
- TX_HEADER_LEN, GFP_ATOMIC);
- if (!skb)
+
+ /* write command, need to send data pdus */
+ if (skb_extra_headroom && (opcode == ISCSI_OP_SCSI_DATA_OUT ||
+ (opcode == ISCSI_OP_SCSI_CMD &&
+ (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE))))
+ headroom += min(skb_extra_headroom, conn->max_xmit_dlength);
+
+ tdata->skb = alloc_skb(TX_HEADER_LEN + headroom, GFP_ATOMIC);
+ if (!tdata->skb)
return -ENOMEM;
+ skb_reserve(tdata->skb, TX_HEADER_LEN);
cxgb3i_tx_debug("task 0x%p, opcode 0x%x, skb 0x%p.\n",
- task, opcode, skb);
+ task, opcode, tdata->skb);
- tcp_task->dd_data = skb;
- skb_reserve(skb, TX_HEADER_LEN);
- task->hdr = (struct iscsi_hdr *)skb->data;
- task->hdr_max = sizeof(struct iscsi_hdr);
+ task->hdr = (struct iscsi_hdr *)tdata->skb->data;
+ task->hdr_max = SKB_TX_PDU_HEADER_LEN;
/* data_out uses scsi_cmd's itt */
if (opcode != ISCSI_OP_SCSI_DATA_OUT)
@@ -192,13 +271,13 @@ int cxgb3i_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
unsigned int count)
{
- struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct sk_buff *skb = tcp_task->dd_data;
struct iscsi_conn *conn = task->conn;
- struct page *pg;
+ struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgb3i_task_data *tdata = tcp_task->dd_data;
+ struct sk_buff *skb = tdata->skb;
unsigned int datalen = count;
int i, padlen = iscsi_padding(count);
- skb_frag_t *frag;
+ struct page *pg;
cxgb3i_tx_debug("task 0x%p,0x%p, offset %u, count %u, skb 0x%p.\n",
task, task->sc, offset, count, skb);
@@ -209,90 +288,94 @@ int cxgb3i_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
return 0;
if (task->sc) {
- struct scatterlist *sg;
- struct scsi_data_buffer *sdb;
- unsigned int sgoffset = offset;
- struct page *sgpg;
- unsigned int sglen;
-
- sdb = scsi_out(task->sc);
- sg = sdb->table.sgl;
-
- for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) {
- cxgb3i_tx_debug("sg %d, page 0x%p, len %u offset %u\n",
- i, sg_page(sg), sg->length, sg->offset);
-
- if (sgoffset < sg->length)
- break;
- sgoffset -= sg->length;
+ struct scsi_data_buffer *sdb = scsi_out(task->sc);
+ struct scatterlist *sg = NULL;
+ int err;
+
+ tdata->offset = offset;
+ tdata->count = count;
+ err = sgl_seek_offset(sdb->table.sgl, sdb->table.nents,
+ tdata->offset, &tdata->sgoffset, &sg);
+ if (err < 0) {
+ cxgb3i_log_warn("tpdu, sgl %u, bad offset %u/%u.\n",
+ sdb->table.nents, tdata->offset,
+ sdb->length);
+ return err;
}
- sgpg = sg_page(sg);
- sglen = sg->length - sgoffset;
-
- do {
- int j = skb_shinfo(skb)->nr_frags;
- unsigned int copy;
-
- if (!sglen) {
- sg = sg_next(sg);
- sgpg = sg_page(sg);
- sgoffset = 0;
- sglen = sg->length;
- ++i;
+ err = sgl_read_to_frags(sg, tdata->sgoffset, tdata->count,
+ tdata->frags, MAX_PDU_FRAGS);
+ if (err < 0) {
+ cxgb3i_log_warn("tpdu, sgl %u, bad offset %u + %u.\n",
+ sdb->table.nents, tdata->offset,
+ tdata->count);
+ return err;
+ }
+ tdata->nr_frags = err;
+
+ if (tdata->nr_frags > MAX_SKB_FRAGS ||
+ (padlen && tdata->nr_frags == MAX_SKB_FRAGS)) {
+ char *dst = skb->data + task->hdr_len;
+ skb_frag_t *frag = tdata->frags;
+
+ /* data fits in the skb's headroom */
+ for (i = 0; i < tdata->nr_frags; i++, frag++) {
+ char *src = kmap_atomic(frag->page,
+ KM_SOFTIRQ0);
+
+ memcpy(dst, src+frag->page_offset, frag->size);
+ dst += frag->size;
+ kunmap_atomic(src, KM_SOFTIRQ0);
}
- copy = min(sglen, datalen);
- if (j && skb_can_coalesce(skb, j, sgpg,
- sg->offset + sgoffset)) {
- skb_shinfo(skb)->frags[j - 1].size += copy;
- } else {
- get_page(sgpg);
- skb_fill_page_desc(skb, j, sgpg,
- sg->offset + sgoffset, copy);
+ if (padlen) {
+ memset(dst, 0, padlen);
+ padlen = 0;
}
- sgoffset += copy;
- sglen -= copy;
- datalen -= copy;
- } while (datalen);
+ skb_put(skb, count + padlen);
+ } else {
+ /* data fit into frag_list */
+ for (i = 0; i < tdata->nr_frags; i++)
+ get_page(tdata->frags[i].page);
+
+ memcpy(skb_shinfo(skb)->frags, tdata->frags,
+ sizeof(skb_frag_t) * tdata->nr_frags);
+ skb_shinfo(skb)->nr_frags = tdata->nr_frags;
+ skb->len += count;
+ skb->data_len += count;
+ skb->truesize += count;
+ }
+
} else {
pg = virt_to_page(task->data);
- while (datalen) {
- i = skb_shinfo(skb)->nr_frags;
- frag = &skb_shinfo(skb)->frags[i];
-
- get_page(pg);
- frag->page = pg;
- frag->page_offset = 0;
- frag->size = min((unsigned int)PAGE_SIZE, datalen);
-
- skb_shinfo(skb)->nr_frags++;
- datalen -= frag->size;
- pg++;
- }
+ get_page(pg);
+ skb_fill_page_desc(skb, 0, pg, offset_in_page(task->data),
+ count);
+ skb->len += count;
+ skb->data_len += count;
+ skb->truesize += count;
}
if (padlen) {
i = skb_shinfo(skb)->nr_frags;
- frag = &skb_shinfo(skb)->frags[i];
- frag->page = pad_page;
- frag->page_offset = 0;
- frag->size = padlen;
- skb_shinfo(skb)->nr_frags++;
+ get_page(pad_page);
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, pad_page, 0,
+ padlen);
+
+ skb->data_len += padlen;
+ skb->truesize += padlen;
+ skb->len += padlen;
}
- datalen = count + padlen;
- skb->data_len += datalen;
- skb->truesize += datalen;
- skb->len += datalen;
return 0;
}
int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
{
- struct iscsi_tcp_task *tcp_task = task->dd_data;
- struct sk_buff *skb = tcp_task->dd_data;
struct iscsi_tcp_conn *tcp_conn = task->conn->dd_data;
struct cxgb3i_conn *cconn = tcp_conn->dd_data;
+ struct iscsi_tcp_task *tcp_task = task->dd_data;
+ struct cxgb3i_task_data *tdata = tcp_task->dd_data;
+ struct sk_buff *skb = tdata->skb;
unsigned int datalen;
int err;
@@ -300,13 +383,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
return 0;
datalen = skb->data_len;
- tcp_task->dd_data = NULL;
+ tdata->skb = NULL;
err = cxgb3i_c3cn_send_pdus(cconn->cep->c3cn, skb);
- cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
- task, skb, skb->len, skb->data_len, err);
if (err > 0) {
int pdulen = err;
+ cxgb3i_tx_debug("task 0x%p, skb 0x%p, len %u/%u, rv %d.\n",
+ task, skb, skb->len, skb->data_len, err);
+
if (task->conn->hdrdgst_en)
pdulen += ISCSI_DIGEST_SIZE;
if (datalen && task->conn->datadgst_en)
@@ -325,12 +409,14 @@ int cxgb3i_conn_xmit_pdu(struct iscsi_task *task)
return err;
}
/* reset skb to send when we are called again */
- tcp_task->dd_data = skb;
+ tdata->skb = skb;
return -EAGAIN;
}
int cxgb3i_pdu_init(void)
{
+ if (SKB_TX_HEADROOM > (512 * MAX_SKB_FRAGS))
+ skb_extra_headroom = SKB_TX_HEADROOM;
pad_page = alloc_page(GFP_KERNEL);
if (!pad_page)
return -ENOMEM;
@@ -366,7 +452,9 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn)
skb = skb_peek(&c3cn->receive_queue);
while (!err && skb) {
__skb_unlink(skb, &c3cn->receive_queue);
- read += skb_ulp_pdulen(skb);
+ read += skb_rx_pdulen(skb);
+ cxgb3i_rx_debug("conn 0x%p, cn 0x%p, rx skb 0x%p, pdulen %u.\n",
+ conn, c3cn, skb, skb_rx_pdulen(skb));
err = cxgb3i_conn_read_pdu_skb(conn, skb);
__kfree_skb(skb);
skb = skb_peek(&c3cn->receive_queue);
@@ -377,6 +465,11 @@ void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn)
cxgb3i_c3cn_rx_credits(c3cn, read);
}
conn->rxdata_octets += read;
+
+ if (err) {
+ cxgb3i_log_info("conn 0x%p rx failed err %d.\n", conn, err);
+ iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ }
}
void cxgb3i_conn_tx_open(struct s3_conn *c3cn)
diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.h b/drivers/scsi/cxgb3i/cxgb3i_pdu.h
index a3f685cc2362..0770b23d90da 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_pdu.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.h
@@ -53,7 +53,7 @@ struct cpl_rx_data_ddp_norss {
#define ULP2_FLAG_DCRC_ERROR 0x20
#define ULP2_FLAG_PAD_ERROR 0x40
-void cxgb3i_conn_closing(struct s3_conn *);
+void cxgb3i_conn_closing(struct s3_conn *c3cn);
void cxgb3i_conn_pdu_ready(struct s3_conn *c3cn);
void cxgb3i_conn_tx_open(struct s3_conn *c3cn);
#endif
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index a48e4990fe12..34be88d7afa5 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1251,6 +1251,7 @@ static struct pci_device_id hptiop_id_table[] = {
{ PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops },
+ { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops },
{ PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops },
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 91ef669d98f6..ed1e728763a2 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1322,7 +1322,9 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
&evt->ext_list_token);
if (!evt->ext_list) {
- scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
+ scsi_dma_unmap(scmd);
+ if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
+ scmd_printk(KERN_ERR, scmd, "Can't allocate memory for scatterlist\n");
return -ENOMEM;
}
}
@@ -1571,9 +1573,6 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
vfc_cmd->resp_len = sizeof(vfc_cmd->rsp);
vfc_cmd->cancel_key = (unsigned long)cmnd->device->hostdata;
vfc_cmd->tgt_scsi_id = rport->port_id;
- if ((rport->supported_classes & FC_COS_CLASS3) &&
- (fc_host_supported_classes(vhost->host) & FC_COS_CLASS3))
- vfc_cmd->flags = IBMVFC_CLASS_3_ERR;
vfc_cmd->iu.xfer_len = scsi_bufflen(cmnd);
int_to_scsilun(cmnd->device->lun, &vfc_cmd->iu.lun);
memcpy(vfc_cmd->iu.cdb, cmnd->cmnd, cmnd->cmd_len);
@@ -3264,6 +3263,7 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id)
return -ENOMEM;
}
+ memset(tgt, 0, sizeof(*tgt));
tgt->scsi_id = scsi_id;
tgt->new_scsi_id = scsi_id;
tgt->vhost = vhost;
@@ -3574,9 +3574,18 @@ static void ibmvfc_log_ae(struct ibmvfc_host *vhost, int events)
static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt)
{
struct ibmvfc_host *vhost = tgt->vhost;
- struct fc_rport *rport;
+ struct fc_rport *rport = tgt->rport;
unsigned long flags;
+ if (rport) {
+ tgt_dbg(tgt, "Setting rport roles\n");
+ fc_remote_port_rolechg(rport, tgt->ids.roles);
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ return;
+ }
+
tgt_dbg(tgt, "Adding rport\n");
rport = fc_remote_port_add(vhost->host, 0, &tgt->ids);
spin_lock_irqsave(vhost->host->host_lock, flags);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 87dafd0f8d44..b21e071b9862 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -32,7 +32,7 @@
#define IBMVFC_DRIVER_VERSION "1.0.4"
#define IBMVFC_DRIVER_DATE "(November 14, 2008)"
-#define IBMVFC_DEFAULT_TIMEOUT 15
+#define IBMVFC_DEFAULT_TIMEOUT 60
#define IBMVFC_INIT_TIMEOUT 120
#define IBMVFC_MAX_REQUESTS_DEFAULT 100
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 74d07d137dae..c9aa7611e408 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -432,6 +432,7 @@ static int map_sg_data(struct scsi_cmnd *cmd,
sdev_printk(KERN_ERR, cmd->device,
"Can't allocate memory "
"for indirect table\n");
+ scsi_dma_unmap(cmd);
return 0;
}
}
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 7225b6e2029e..809d32d95c76 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1981,6 +1981,7 @@ void iscsi_pool_free(struct iscsi_pool *q)
kfree(q->pool[i]);
if (q->pool)
kfree(q->pool);
+ kfree(q->queue);
}
EXPORT_SYMBOL_GPL(iscsi_pool_free);
@@ -1997,6 +1998,8 @@ int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
if (!shost->can_queue)
shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX;
+ if (!shost->transportt->eh_timed_out)
+ shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
return scsi_add_host(shost, pdev);
}
EXPORT_SYMBOL_GPL(iscsi_host_add);
@@ -2019,7 +2022,6 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
if (!shost)
return NULL;
- shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
if (qdepth > ISCSI_MAX_CMD_PER_LUN || qdepth < 1) {
if (qdepth != 0)
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index a8f30bdaff69..a7302480bc4a 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -5258,6 +5258,7 @@ lpfc_send_els_event(struct lpfc_vport *vport,
sizeof(struct lpfc_name));
break;
default:
+ kfree(els_data);
return;
}
memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name));
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c
index b264b499d982..7794fc158b17 100644
--- a/drivers/scsi/mvme16x_scsi.c
+++ b/drivers/scsi/mvme16x_scsi.c
@@ -34,7 +34,7 @@ static struct scsi_host_template mvme16x_scsi_driver_template = {
static struct platform_device *mvme16x_scsi_device;
static __devinit int
-mvme16x_probe(struct device *dev)
+mvme16x_probe(struct platform_device *dev)
{
struct Scsi_Host * host = NULL;
struct NCR_700_Host_Parameters *hostdata;
@@ -88,7 +88,7 @@ mvme16x_probe(struct device *dev)
out_be32(0xfff4202c, v);
}
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);
return 0;
@@ -102,9 +102,9 @@ mvme16x_probe(struct device *dev)
}
static __devexit int
-mvme16x_device_remove(struct device *dev)
+mvme16x_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
/* Disable scsi chip ints */
@@ -123,25 +123,27 @@ mvme16x_device_remove(struct device *dev)
return 0;
}
-static struct device_driver mvme16x_scsi_driver = {
- .name = "mvme16x-scsi",
- .bus = &platform_bus_type,
- .probe = mvme16x_probe,
- .remove = __devexit_p(mvme16x_device_remove),
+static struct platform_driver mvme16x_scsi_driver = {
+ .driver = {
+ .name = "mvme16x-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = mvme16x_probe,
+ .remove = __devexit_p(mvme16x_device_remove),
};
static int __init mvme16x_scsi_init(void)
{
int err;
- err = driver_register(&mvme16x_scsi_driver);
+ err = platform_driver_register(&mvme16x_scsi_driver);
if (err)
return err;
mvme16x_scsi_device = platform_device_register_simple("mvme16x-scsi",
-1, NULL, 0);
if (IS_ERR(mvme16x_scsi_device)) {
- driver_unregister(&mvme16x_scsi_driver);
+ platform_driver_unregister(&mvme16x_scsi_driver);
return PTR_ERR(mvme16x_scsi_device);
}
@@ -151,7 +153,7 @@ static int __init mvme16x_scsi_init(void)
static void __exit mvme16x_scsi_exit(void)
{
platform_device_unregister(mvme16x_scsi_device);
- driver_unregister(&mvme16x_scsi_driver);
+ platform_driver_unregister(&mvme16x_scsi_driver);
}
module_init(mvme16x_scsi_init);
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index c7acef50d5da..f4c57227ec18 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1016,6 +1016,9 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
struct Scsi_Host *host = rport_to_shost(rport);
fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+ if (!fcport)
+ return;
+
qla2x00_abort_fcport_cmds(fcport);
/*
@@ -1033,6 +1036,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
{
fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+ if (!fcport)
+ return;
+
/*
* At this point all fcport's software-states are cleared. Perform any
* final cleanup of firmware resources (PCBs and XCBs).
@@ -1259,13 +1265,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
msleep(1000);
- if (ha->mqenable) {
- if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS)
- qla_printk(KERN_WARNING, ha,
- "Queue delete failed.\n");
- vha->req_ques[0] = ha->req_q_map[0]->id;
- }
-
qla24xx_disable_vp(vha);
fc_remove_host(vha->host);
@@ -1287,6 +1286,12 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
vha->host_no, vha->vp_idx, vha));
}
+ if (ha->mqenable) {
+ if (qla25xx_delete_queues(vha, 0) != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, ha,
+ "Queue delete failed.\n");
+ }
+
scsi_host_put(vha->host);
qla_printk(KERN_INFO, ha, "vport %d deleted\n", id);
return 0;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 023ee77fb027..e0c5bb54b258 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2135,6 +2135,7 @@ struct qla_msix_entry {
/* Work events. */
enum qla_work_type {
QLA_EVT_AEN,
+ QLA_EVT_IDC_ACK,
};
@@ -2149,6 +2150,10 @@ struct qla_work_evt {
enum fc_host_event_code code;
u32 data;
} aen;
+ struct {
+#define QLA_IDC_ACK_REGS 7
+ uint16_t mb[QLA_IDC_ACK_REGS];
+ } idc_ack;
} u;
};
diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h
index d78d35e681ab..d6ea69df7c5c 100644
--- a/drivers/scsi/qla2xxx/qla_devtbl.h
+++ b/drivers/scsi/qla2xxx/qla_devtbl.h
@@ -72,7 +72,7 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = {
"QLA2462", "Sun PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x141 */
"QLE2460", "Sun PCI-Express to 2Gb FC, Single Channel", /* 0x142 */
"QLE2462", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x143 */
- "QEM2462" "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */
+ "QEM2462", "Server I/O Module 4Gb FC, Dual Channel", /* 0x144 */
"QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */
"QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */
"QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 7abb045a0410..ffff42554087 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1402,6 +1402,8 @@ struct access_chip_rsp_84xx {
#define MBA_IDC_NOTIFY 0x8101
#define MBA_IDC_TIME_EXT 0x8102
+#define MBC_IDC_ACK 0x101
+
struct nvram_81xx {
/* NVRAM header. */
uint8_t id[4];
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index ba4913353752..6de283f8f111 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -34,6 +34,7 @@ extern void qla24xx_update_fw_options(scsi_qla_host_t *);
extern void qla81xx_update_fw_options(scsi_qla_host_t *);
extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
+extern int qla81xx_load_risc(scsi_qla_host_t *, uint32_t *);
extern int qla2x00_loop_resync(scsi_qla_host_t *);
@@ -71,6 +72,7 @@ extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
fc_host_event_code, u32);
+extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
extern void qla2x00_abort_fcport_cmds(fc_port_t *);
extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
@@ -265,6 +267,8 @@ qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
+extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *);
+
/*
* Global Function Prototypes in qla_isr.c source file.
*/
@@ -375,10 +379,8 @@ extern int qla2x00_dfs_remove(scsi_qla_host_t *);
/* Globa function prototypes for multi-q */
extern int qla25xx_request_irq(struct rsp_que *);
-extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *,
- uint8_t);
-extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *,
- uint8_t);
+extern int qla25xx_init_req_que(struct scsi_qla_host *, struct req_que *);
+extern int qla25xx_init_rsp_que(struct scsi_qla_host *, struct rsp_que *);
extern int qla25xx_create_req_que(struct qla_hw_data *, uint16_t, uint8_t,
uint16_t, uint8_t, uint8_t);
extern int qla25xx_create_rsp_que(struct qla_hw_data *, uint16_t, uint8_t,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 9ad4d0968e5c..986501759ad4 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1226,9 +1226,8 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
icb->firmware_options_2 |=
__constant_cpu_to_le32(BIT_18);
- icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22);
+ icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22);
icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23);
- ha->rsp_q_map[0]->options = icb->firmware_options_2;
WRT_REG_DWORD(&reg->isp25mq.req_q_in, 0);
WRT_REG_DWORD(&reg->isp25mq.req_q_out, 0);
@@ -3493,7 +3492,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
rsp = ha->rsp_q_map[i];
if (rsp) {
rsp->options &= ~BIT_0;
- ret = qla25xx_init_rsp_que(base_vha, rsp, rsp->options);
+ ret = qla25xx_init_rsp_que(base_vha, rsp);
if (ret != QLA_SUCCESS)
DEBUG2_17(printk(KERN_WARNING
"%s Rsp que:%d init failed\n", __func__,
@@ -3507,7 +3506,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
if (req) {
/* Clear outstanding commands array. */
req->options &= ~BIT_0;
- ret = qla25xx_init_req_que(base_vha, req, req->options);
+ ret = qla25xx_init_req_que(base_vha, req);
if (ret != QLA_SUCCESS)
DEBUG2_17(printk(KERN_WARNING
"%s Req que:%d init failed\n", __func__,
@@ -3562,6 +3561,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
RD_REG_DWORD(&reg->hccr);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ if (IS_NOPOLLING_TYPE(ha))
+ ha->isp_ops->enable_intrs(ha);
}
/* On sparc systems, obtain port and node WWN from firmware
@@ -3847,6 +3849,10 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr)
uint32_t i;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
+
+ qla_printk(KERN_INFO, ha,
+ "FW: Loading from flash (%x)...\n", ha->flt_region_fw);
+
rval = QLA_SUCCESS;
segments = FA_RISC_CODE_SEGMENTS;
@@ -4022,8 +4028,8 @@ fail_fw_integrity:
return QLA_FUNCTION_FAILED;
}
-int
-qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
+static int
+qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
{
int rval;
int segments, fragment;
@@ -4043,12 +4049,12 @@ qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
qla_printk(KERN_ERR, ha, "Firmware images can be retrieved "
"from: " QLA_FW_URL ".\n");
- /* Try to load RISC code from flash. */
- qla_printk(KERN_ERR, ha, "Attempting to load (potentially "
- "outdated) firmware from flash.\n");
- return qla24xx_load_risc_flash(vha, srisc_addr);
+ return QLA_FUNCTION_FAILED;
}
+ qla_printk(KERN_INFO, ha,
+ "FW: Loading via request-firmware...\n");
+
rval = QLA_SUCCESS;
segments = FA_RISC_CODE_SEGMENTS;
@@ -4133,6 +4139,40 @@ fail_fw_integrity:
return QLA_FUNCTION_FAILED;
}
+int
+qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
+{
+ int rval;
+
+ /*
+ * FW Load priority:
+ * 1) Firmware via request-firmware interface (.bin file).
+ * 2) Firmware residing in flash.
+ */
+ rval = qla24xx_load_risc_blob(vha, srisc_addr);
+ if (rval == QLA_SUCCESS)
+ return rval;
+
+ return qla24xx_load_risc_flash(vha, srisc_addr);
+}
+
+int
+qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
+{
+ int rval;
+
+ /*
+ * FW Load priority:
+ * 1) Firmware residing in flash.
+ * 2) Firmware via request-firmware interface (.bin file).
+ */
+ rval = qla24xx_load_risc_flash(vha, srisc_addr);
+ if (rval == QLA_SUCCESS)
+ return rval;
+
+ return qla24xx_load_risc_blob(vha, srisc_addr);
+}
+
void
qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
{
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 789fc576f222..f250e5b7897c 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -266,6 +266,40 @@ qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
}
}
+static void
+qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
+{
+ static char *event[] =
+ { "Complete", "Request Notification", "Time Extension" };
+ int rval;
+ struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24;
+ uint16_t __iomem *wptr;
+ uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS];
+
+ /* Seed data -- mailbox1 -> mailbox7. */
+ wptr = (uint16_t __iomem *)&reg24->mailbox1;
+ for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++)
+ mb[cnt] = RD_REG_WORD(wptr);
+
+ DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- "
+ "%04x %04x %04x %04x %04x %04x %04x.\n", vha->host_no,
+ event[aen & 0xff],
+ mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6]));
+
+ /* Acknowledgement needed? [Notify && non-zero timeout]. */
+ timeout = (descr >> 8) & 0xf;
+ if (aen != MBA_IDC_NOTIFY || !timeout)
+ return;
+
+ DEBUG2(printk("scsi(%ld): Inter-Driver Commucation %s -- "
+ "ACK timeout=%d.\n", vha->host_no, event[aen & 0xff], timeout));
+
+ rval = qla2x00_post_idc_ack_work(vha, mb);
+ if (rval != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, vha->hw,
+ "IDC failed to post ACK.\n");
+}
+
/**
* qla2x00_async_event() - Process aynchronous events.
* @ha: SCSI driver HA context
@@ -714,21 +748,9 @@ skip_rio:
"%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3]));
break;
case MBA_IDC_COMPLETE:
- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation "
- "Complete -- %04x %04x %04x\n", vha->host_no, mb[1], mb[2],
- mb[3]));
- break;
case MBA_IDC_NOTIFY:
- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation "
- "Request Notification -- %04x %04x %04x\n", vha->host_no,
- mb[1], mb[2], mb[3]));
- /**** Mailbox registers 4 - 7 valid!!! */
- break;
case MBA_IDC_TIME_EXT:
- DEBUG2(printk("scsi(%ld): Inter-Driver Commucation "
- "Time Extension -- %04x %04x %04x\n", vha->host_no, mb[1],
- mb[2], mb[3]));
- /**** Mailbox registers 4 - 7 valid!!! */
+ qla81xx_idc_event(vha, mb[0], mb[1]);
break;
}
@@ -1707,7 +1729,6 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
struct qla_hw_data *ha;
struct rsp_que *rsp;
struct device_reg_24xx __iomem *reg;
- uint16_t msix_disabled_hccr = 0;
rsp = (struct rsp_que *) dev_id;
if (!rsp) {
@@ -1720,17 +1741,8 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
spin_lock_irq(&ha->hardware_lock);
- msix_disabled_hccr = rsp->options;
- if (!rsp->id)
- msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22);
- else
- msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6);
-
qla24xx_process_response_queue(rsp);
- if (!msix_disabled_hccr)
- WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
-
spin_unlock_irq(&ha->hardware_lock);
return IRQ_HANDLED;
@@ -1868,6 +1880,7 @@ qla24xx_disable_msix(struct qla_hw_data *ha)
static int
qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
{
+#define MIN_MSIX_COUNT 2
int i, ret;
struct msix_entry *entries;
struct qla_msix_entry *qentry;
@@ -1883,12 +1896,16 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
if (ret) {
+ if (ret < MIN_MSIX_COUNT)
+ goto msix_failed;
+
qla_printk(KERN_WARNING, ha,
"MSI-X: Failed to enable support -- %d/%d\n"
" Retry with %d vectors\n", ha->msix_count, ret, ret);
ha->msix_count = ret;
ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
if (ret) {
+msix_failed:
qla_printk(KERN_WARNING, ha, "MSI-X: Failed to enable"
" support, giving up -- %d/%d\n",
ha->msix_count, ret);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index db4df45234a5..4c7504cb3990 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -58,14 +58,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
* seconds. This is to serialize actual issuing of mailbox cmds during
* non ISP abort time.
*/
- if (!abort_active) {
- if (!wait_for_completion_timeout(&ha->mbx_cmd_comp,
- mcp->tov * HZ)) {
- /* Timeout occurred. Return error. */
- DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
- "Exiting.\n", __func__, base_vha->host_no));
- return QLA_FUNCTION_TIMEOUT;
- }
+ if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
+ /* Timeout occurred. Return error. */
+ DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
+ "Exiting.\n", __func__, base_vha->host_no));
+ return QLA_FUNCTION_TIMEOUT;
}
ha->flags.mbox_busy = 1;
@@ -265,8 +262,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
}
/* Allow next mbx cmd to come in. */
- if (!abort_active)
- complete(&ha->mbx_cmd_comp);
+ complete(&ha->mbx_cmd_comp);
if (rval) {
DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, "
@@ -3094,8 +3090,7 @@ verify_done:
}
int
-qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
- uint8_t options)
+qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
{
int rval;
unsigned long flags;
@@ -3105,7 +3100,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
struct qla_hw_data *ha = vha->hw;
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
- mcp->mb[1] = options;
+ mcp->mb[1] = req->options;
mcp->mb[2] = MSW(LSD(req->dma));
mcp->mb[3] = LSW(LSD(req->dma));
mcp->mb[6] = MSW(MSD(req->dma));
@@ -3132,7 +3127,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
mcp->tov = 60;
spin_lock_irqsave(&ha->hardware_lock, flags);
- if (!(options & BIT_0)) {
+ if (!(req->options & BIT_0)) {
WRT_REG_DWORD(&reg->req_q_in, 0);
WRT_REG_DWORD(&reg->req_q_out, 0);
}
@@ -3146,8 +3141,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req,
}
int
-qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
- uint8_t options)
+qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
{
int rval;
unsigned long flags;
@@ -3157,7 +3151,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
struct qla_hw_data *ha = vha->hw;
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
- mcp->mb[1] = options;
+ mcp->mb[1] = rsp->options;
mcp->mb[2] = MSW(LSD(rsp->dma));
mcp->mb[3] = LSW(LSD(rsp->dma));
mcp->mb[6] = MSW(MSD(rsp->dma));
@@ -3182,7 +3176,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
mcp->tov = 60;
spin_lock_irqsave(&ha->hardware_lock, flags);
- if (!(options & BIT_0)) {
+ if (!(rsp->options & BIT_0)) {
WRT_REG_DWORD(&reg->rsp_q_out, 0);
WRT_REG_DWORD(&reg->rsp_q_in, 0);
}
@@ -3197,3 +3191,29 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp,
return rval;
}
+int
+qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_IDC_ACK;
+ memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
+ mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index f53179c46423..3f23932210c4 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -396,7 +396,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
qla2x00_start_timer(vha, qla2x00_timer, WATCH_INTERVAL);
- memset(vha->req_ques, 0, sizeof(vha->req_ques) * QLA_MAX_HOST_QUES);
+ memset(vha->req_ques, 0, sizeof(vha->req_ques));
vha->req_ques[0] = ha->req_q_map[0]->id;
host->can_queue = ha->req_q_map[0]->length + 128;
host->this_id = 255;
@@ -471,7 +471,7 @@ qla25xx_delete_req_que(struct scsi_qla_host *vha, struct req_que *req)
if (req) {
req->options |= BIT_0;
- ret = qla25xx_init_req_que(vha, req, req->options);
+ ret = qla25xx_init_req_que(vha, req);
}
if (ret == QLA_SUCCESS)
qla25xx_free_req_que(vha, req);
@@ -486,7 +486,7 @@ qla25xx_delete_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
if (rsp) {
rsp->options |= BIT_0;
- ret = qla25xx_init_rsp_que(vha, rsp, rsp->options);
+ ret = qla25xx_init_rsp_que(vha, rsp);
}
if (ret == QLA_SUCCESS)
qla25xx_free_rsp_que(vha, rsp);
@@ -502,7 +502,7 @@ int qla25xx_update_req_que(struct scsi_qla_host *vha, uint8_t que, uint8_t qos)
req->options |= BIT_3;
req->qos = qos;
- ret = qla25xx_init_req_que(vha, req, req->options);
+ ret = qla25xx_init_req_que(vha, req);
if (ret != QLA_SUCCESS)
DEBUG2_17(printk(KERN_WARNING "%s failed\n", __func__));
/* restore options bit */
@@ -632,7 +632,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
req->max_q_depth = ha->req_q_map[0]->max_q_depth;
mutex_unlock(&ha->vport_lock);
- ret = qla25xx_init_req_que(base_vha, req, options);
+ ret = qla25xx_init_req_que(base_vha, req);
if (ret != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, "%s failed\n", __func__);
mutex_lock(&ha->vport_lock);
@@ -710,7 +710,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
if (ret)
goto que_failed;
- ret = qla25xx_init_rsp_que(base_vha, rsp, options);
+ ret = qla25xx_init_rsp_que(base_vha, rsp);
if (ret != QLA_SUCCESS) {
qla_printk(KERN_WARNING, ha, "%s failed\n", __func__);
mutex_lock(&ha->vport_lock);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index cf32653fe01a..2f5f72531e23 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -65,8 +65,6 @@ MODULE_PARM_DESC(ql2xextended_error_logging,
static void qla2x00_free_device(scsi_qla_host_t *);
-static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
-
int ql2xfdmienable=1;
module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR);
MODULE_PARM_DESC(ql2xfdmienable,
@@ -800,6 +798,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
if (ha->isp_ops->abort_command(vha, sp, req)) {
DEBUG2(printk("%s(%ld): abort_command "
"mbx failed.\n", __func__, vha->host_no));
+ ret = FAILED;
} else {
DEBUG3(printk("%s(%ld): abort_command "
"mbx success.\n", __func__, vha->host_no));
@@ -1241,9 +1240,8 @@ qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type)
* supported addressing method.
*/
static void
-qla2x00_config_dma_addressing(scsi_qla_host_t *vha)
+qla2x00_config_dma_addressing(struct qla_hw_data *ha)
{
- struct qla_hw_data *ha = vha->hw;
/* Assume a 32bit DMA mask. */
ha->flags.enable_64bit_addressing = 0;
@@ -1480,7 +1478,7 @@ static struct isp_operations qla81xx_isp_ops = {
.reset_adapter = qla24xx_reset_adapter,
.nvram_config = qla81xx_nvram_config,
.update_fw_options = qla81xx_update_fw_options,
- .load_risc = qla24xx_load_risc,
+ .load_risc = qla81xx_load_risc,
.pci_info_str = qla24xx_pci_info_str,
.fw_version_str = qla24xx_fw_version_str,
.intr_handler = qla24xx_intr_handler,
@@ -1869,6 +1867,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
set_bit(0, (unsigned long *) ha->vp_idx_map);
+ qla2x00_config_dma_addressing(ha);
ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp);
if (!ret) {
qla_printk(KERN_WARNING, ha,
@@ -1888,13 +1887,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
"[ERROR] Failed to allocate memory for scsi_host\n");
ret = -ENOMEM;
+ qla2x00_mem_free(ha);
+ qla2x00_free_que(ha, req, rsp);
goto probe_hw_failed;
}
pci_set_drvdata(pdev, base_vha);
- qla2x00_config_dma_addressing(base_vha);
-
host = base_vha->host;
base_vha->req_ques[0] = req->id;
host->can_queue = req->length + 128;
@@ -1917,14 +1916,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Set up the irqs */
ret = qla2x00_request_irqs(ha, rsp);
if (ret)
- goto probe_failed;
-
+ goto probe_init_failed;
/* Alloc arrays of request and response ring ptrs */
if (!qla2x00_alloc_queues(ha)) {
qla_printk(KERN_WARNING, ha,
"[ERROR] Failed to allocate memory for queue"
" pointers\n");
- goto probe_failed;
+ goto probe_init_failed;
}
ha->rsp_q_map[0] = rsp;
ha->req_q_map[0] = req;
@@ -1997,6 +1995,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
+probe_init_failed:
+ qla2x00_free_que(ha, req, rsp);
+ ha->max_queues = 0;
+
probe_failed:
qla2x00_free_device(base_vha);
@@ -2520,6 +2522,19 @@ qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code,
return qla2x00_post_work(vha, e, 1);
}
+int
+qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
+{
+ struct qla_work_evt *e;
+
+ e = qla2x00_alloc_work(vha, QLA_EVT_IDC_ACK, 1);
+ if (!e)
+ return QLA_FUNCTION_FAILED;
+
+ memcpy(e->u.idc_ack.mb, mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
+ return qla2x00_post_work(vha, e, 1);
+}
+
static void
qla2x00_do_work(struct scsi_qla_host *vha)
{
@@ -2537,6 +2552,9 @@ qla2x00_do_work(struct scsi_qla_host *vha)
fc_host_post_event(vha->host, fc_get_event_number(),
e->u.aen.code, e->u.aen.data);
break;
+ case QLA_EVT_IDC_ACK:
+ qla81xx_idc_ack(vha, e->u.idc_ack.mb);
+ break;
}
if (e->flags & QLA_EVT_FLAG_FREE)
kfree(e);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 303f8ee11f25..284827926eff 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -684,7 +684,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
"end=0x%x size=0x%x.\n", le32_to_cpu(region->code), start,
le32_to_cpu(region->end) >> 2, le32_to_cpu(region->size)));
- switch (le32_to_cpu(region->code)) {
+ switch (le32_to_cpu(region->code) & 0xff) {
case FLT_REG_FW:
ha->flt_region_fw = start;
break;
@@ -944,9 +944,9 @@ qla24xx_unprotect_flash(struct qla_hw_data *ha)
if (!ha->fdt_wrt_disable)
return;
- /* Disable flash write-protection. */
+ /* Disable flash write-protection, first clear SR protection bit */
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
- /* Some flash parts need an additional zero-write to clear bits.*/
+ /* Then write zero again to clear remaining SR bits.*/
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
}
@@ -980,12 +980,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
uint32_t dwords)
{
int ret;
- uint32_t liter, miter;
+ uint32_t liter;
uint32_t sec_mask, rest_addr;
- uint32_t fdata, findex;
+ uint32_t fdata;
dma_addr_t optrom_dma;
void *optrom = NULL;
- uint32_t *s, *d;
struct qla_hw_data *ha = vha->hw;
ret = QLA_SUCCESS;
@@ -1003,17 +1002,15 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
}
rest_addr = (ha->fdt_block_size >> 2) - 1;
- sec_mask = (ha->optrom_size >> 2) - (ha->fdt_block_size >> 2);
+ sec_mask = ~rest_addr;
qla24xx_unprotect_flash(ha);
for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
-
- findex = faddr;
- fdata = (findex & sec_mask) << 2;
+ fdata = (faddr & sec_mask) << 2;
/* Are we at the beginning of a sector? */
- if ((findex & rest_addr) == 0) {
+ if ((faddr & rest_addr) == 0) {
/* Do sector unprotect. */
if (ha->fdt_unprotect_sec_cmd)
qla24xx_write_flash_dword(ha,
@@ -1024,7 +1021,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
(fdata & 0xff00) |((fdata << 16) &
0xff0000) | ((fdata >> 16) & 0xff));
if (ret != QLA_SUCCESS) {
- DEBUG9(qla_printk("Unable to flash sector: "
+ DEBUG9(qla_printk("Unable to erase sector: "
"address=%x.\n", faddr));
break;
}
@@ -1033,9 +1030,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
/* Go with burst-write. */
if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) {
/* Copy data to DMA'ble buffer. */
- for (miter = 0, s = optrom, d = dwptr;
- miter < OPTROM_BURST_DWORDS; miter++, s++, d++)
- *s = cpu_to_le32(*d);
+ memcpy(optrom, dwptr, OPTROM_BURST_SIZE);
ret = qla2x00_load_ram(vha, optrom_dma,
flash_data_addr(ha, faddr),
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 808bab6ef06b..79f7053da99b 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.00-k1"
+#define QLA2XXX_VERSION "8.03.00-k3"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index d6be0762eb91..b586f27c3bd4 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -244,6 +244,7 @@ struct ddb_entry {
uint8_t ip_addr[ISCSI_IPADDR_SIZE];
uint8_t iscsi_name[ISCSI_NAME_SIZE]; /* 72 x48 */
uint8_t iscsi_alias[0x20];
+ uint8_t isid[6];
};
/*
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 109c5f5985ec..af8c3233e8ae 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -342,8 +342,12 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no,
__func__, fw_ddb_index));
list_for_each_entry(ddb_entry, &ha->ddb_list, list) {
- if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
- ISCSI_NAME_SIZE) == 0) {
+ if ((memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsi_name,
+ ISCSI_NAME_SIZE) == 0) &&
+ (ddb_entry->tpgt ==
+ le32_to_cpu(fw_ddb_entry->tgt_portal_grp)) &&
+ (memcmp(ddb_entry->isid, fw_ddb_entry->isid,
+ sizeof(ddb_entry->isid)) == 0)) {
found++;
break;
}
@@ -430,6 +434,8 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
ddb_entry->port = le16_to_cpu(fw_ddb_entry->port);
ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
+ memcpy(ddb_entry->isid, fw_ddb_entry->isid, sizeof(ddb_entry->isid));
+
memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],
min(sizeof(ddb_entry->iscsi_name),
sizeof(fw_ddb_entry->iscsi_name)));
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 940dc32ff0dc..b82ffd90632e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1040,12 +1040,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
action = ACTION_FAIL;
break;
case ABORTED_COMMAND:
+ action = ACTION_FAIL;
if (sshdr.asc == 0x10) { /* DIF */
description = "Target Data Integrity Failure";
- action = ACTION_FAIL;
error = -EILSEQ;
- } else
- action = ACTION_RETRY;
+ }
break;
case NOT_READY:
/* If the device is in the process of becoming
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 66505bb79410..8f4de20c9deb 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -317,6 +317,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
return sdev;
out_device_destroy:
+ scsi_device_set_state(sdev, SDEV_DEL);
transport_destroy_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
out:
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d57566b8be0a..55310dbc10a6 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -107,6 +107,7 @@ static void scsi_disk_release(struct device *cdev);
static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
static void sd_print_result(struct scsi_disk *, int);
+static DEFINE_SPINLOCK(sd_index_lock);
static DEFINE_IDA(sd_index_ida);
/* This semaphore is used to mediate the 0->1 reference get in the
@@ -1914,7 +1915,9 @@ static int sd_probe(struct device *dev)
if (!ida_pre_get(&sd_index_ida, GFP_KERNEL))
goto out_put;
+ spin_lock(&sd_index_lock);
error = ida_get_new(&sd_index_ida, &index);
+ spin_unlock(&sd_index_lock);
} while (error == -EAGAIN);
if (error)
@@ -1936,7 +1939,9 @@ static int sd_probe(struct device *dev)
return 0;
out_free_index:
+ spin_lock(&sd_index_lock);
ida_remove(&sd_index_ida, index);
+ spin_unlock(&sd_index_lock);
out_put:
put_disk(gd);
out_free:
@@ -1986,7 +1991,9 @@ static void scsi_disk_release(struct device *dev)
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct gendisk *disk = sdkp->disk;
+ spin_lock(&sd_index_lock);
ida_remove(&sd_index_ida, sdkp->index);
+ spin_unlock(&sd_index_lock);
disk->private_data = NULL;
put_disk(disk);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 8f0bd3f7a59f..516925d8b570 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1078,7 +1078,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
case BLKTRACESETUP:
return blk_trace_setup(sdp->device->request_queue,
sdp->disk->disk_name,
- sdp->device->sdev_gendev.devt,
+ MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
(char *)arg);
case BLKTRACESTART:
return blk_trace_startstop(sdp->device->request_queue, 1);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0d934bfbdd9b..b4b39811b445 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2083,6 +2083,20 @@ static int serial8250_startup(struct uart_port *port)
serial8250_set_mctrl(&up->port, up->port.mctrl);
+ /* Serial over Lan (SoL) hack:
+ Intel 8257x Gigabit ethernet chips have a
+ 16550 emulation, to be used for Serial Over Lan.
+ Those chips take a longer time than a normal
+ serial device to signalize that a transmission
+ data was queued. Due to that, the above test generally
+ fails. One solution would be to delay the reading of
+ iir. However, this is not reliable, since the timeout
+ is variable. So, let's just don't test if we receive
+ TX irq. This way, we'll never enable UART_BUG_TXEN.
+ */
+ if (up->port.flags & UPF_NO_TXEN_TEST)
+ goto dont_test_tx_en;
+
/*
* Do a quick test to see if we receive an
* interrupt when we enable the TX irq.
@@ -2102,6 +2116,7 @@ static int serial8250_startup(struct uart_port *port)
up->bugs &= ~UART_BUG_TXEN;
}
+dont_test_tx_en:
spin_unlock_irqrestore(&up->port.lock, flags);
/*
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 2a3671233b15..533f82025adf 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -798,6 +798,21 @@ pci_default_setup(struct serial_private *priv,
return setup_port(priv, port, bar, offset, board->reg_shift);
}
+static int skip_tx_en_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_port *port, int idx)
+{
+ port->flags |= UPF_NO_TXEN_TEST;
+ printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
+ "[%04x:%04x] subsystem [%04x:%04x]\n",
+ priv->dev->vendor,
+ priv->dev->device,
+ priv->dev->subsystem_vendor,
+ priv->dev->subsystem_device);
+
+ return pci_default_setup(priv, board, port, idx);
+}
+
/* This should be in linux/pci_ids.h */
#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
@@ -806,6 +821,8 @@ pci_default_setup(struct serial_private *priv,
#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208
#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
+#define PCI_VENDOR_ID_ADVANTECH 0x13fe
+#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -862,6 +879,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.init = pci_inteli960ni_init,
.setup = pci_default_setup,
},
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_8257X_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82573L_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82573E_SOL,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = skip_tx_en_setup,
+ },
/*
* ITE
*/
@@ -2152,6 +2190,10 @@ static int pciserial_resume_one(struct pci_dev *dev)
#endif
static struct pci_device_id serial_pci_tbl[] = {
+ /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */
+ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620,
+ PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0,
+ pbn_b2_8_921600 },
{ PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
PCI_SUBVENDOR_ID_CONNECT_TECH,
PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 3e525e38a5d9..9be11b0963f2 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -628,7 +628,7 @@ config SERIAL_MPSC_CONSOLE
config SERIAL_PXA
bool "PXA serial port support"
- depends on ARM && ARCH_PXA
+ depends on ARCH_PXA || ARCH_MMP
select SERIAL_CORE
help
If you have a machine based on an Intel XScale PXA2xx CPU you
@@ -982,7 +982,7 @@ config SERIAL_SH_SCI_CONSOLE
config SERIAL_PNX8XXX
bool "Enable PNX8XXX SoCs' UART Support"
- depends on MIPS && SOC_PNX8550
+ depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
select SERIAL_CORE
help
If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 89362d733d62..8f58f7ff0dd7 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -877,6 +877,10 @@ static int atmel_startup(struct uart_port *port)
}
}
+ /* Save current CSR for comparison in atmel_tasklet_func() */
+ atmel_port->irq_status_prev = UART_GET_CSR(port);
+ atmel_port->irq_status = atmel_port->irq_status_prev;
+
/*
* Finally, enable the serial port
*/
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index 338cf8a08b43..ac79cbe4c2cf 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -84,6 +84,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
brd->pci_dev = pdev;
if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM)
brd->maxports = 4;
+ else if (pdev->device == PCI_DEVICE_ID_DIGI_NEO_8)
+ brd->maxports = 8;
else
brd->maxports = 2;
@@ -180,7 +182,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
}
-static void jsm_remove_one(struct pci_dev *pdev)
+static void __devexit jsm_remove_one(struct pci_dev *pdev)
{
struct jsm_board *brd = pci_get_drvdata(pdev);
int i = 0;
@@ -212,6 +214,7 @@ static struct pci_device_id jsm_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 },
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 },
{ PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 },
+ { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, jsm_pci_tbl);
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 3547558d2caf..324c74d2f666 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -161,6 +161,11 @@ static void jsm_tty_stop_rx(struct uart_port *port)
channel->ch_bd->bd_ops->disable_receiver(channel);
}
+static void jsm_tty_enable_ms(struct uart_port *port)
+{
+ /* Nothing needed */
+}
+
static void jsm_tty_break(struct uart_port *port, int break_state)
{
unsigned long lock_flags;
@@ -345,6 +350,7 @@ static struct uart_ops jsm_ops = {
.start_tx = jsm_tty_start_tx,
.send_xchar = jsm_tty_send_xchar,
.stop_rx = jsm_tty_stop_rx,
+ .enable_ms = jsm_tty_enable_ms,
.break_ctl = jsm_tty_break,
.startup = jsm_tty_open,
.shutdown = jsm_tty_close,
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index b2001c5b145c..0eefb07bebaf 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -212,10 +212,18 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
{
unsigned long flags;
unsigned int baud, baudclk;
+#if defined(CONFIG_M5272)
+ unsigned int baudfr;
+#endif
unsigned char mr1, mr2;
baud = uart_get_baud_rate(port, termios, old, 0, 230400);
+#if defined(CONFIG_M5272)
+ baudclk = (MCF_BUSCLK / baud) / 32;
+ baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16;
+#else
baudclk = ((MCF_BUSCLK / baud) + 16) / 32;
+#endif
mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR;
mr2 = 0;
@@ -262,6 +270,9 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
writeb(mr2, port->membase + MCFUART_UMR);
writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1);
writeb((baudclk & 0xff), port->membase + MCFUART_UBG2);
+#if defined(CONFIG_M5272)
+ writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD);
+#endif
writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER,
port->membase + MCFUART_UCSR);
writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE,
@@ -502,7 +513,7 @@ static int __init mcf_console_setup(struct console *co, char *options)
int parity = 'n';
int flow = 'n';
- if ((co->index >= 0) && (co->index <= MCF_MAXPORTS))
+ if ((co->index < 0) || (co->index >= MCF_MAXPORTS))
co->index = 0;
port = &mcf_ports[co->index].port;
if (port->membase == 0)
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 0c3a2ab1612c..7f72f8ceaa6f 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -50,8 +50,8 @@
/* 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
+ * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible
+ * list.
*
* 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#>'
@@ -522,7 +522,7 @@ mpc52xx_uart_startup(struct uart_port *port)
/* Request IRQ */
ret = request_irq(port->irq, mpc52xx_uart_int,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED,
+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
"mpc52xx_psc_uart", port);
if (ret)
return ret;
@@ -1212,30 +1212,18 @@ mpc52xx_uart_of_resume(struct of_device *op)
#endif
static void
-mpc52xx_uart_of_assign(struct device_node *np, int idx)
+mpc52xx_uart_of_assign(struct device_node *np)
{
- int free_idx = -1;
int i;
- /* Find the first free node */
+ /* Find the first free PSC number */
for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
if (mpc52xx_uart_nodes[i] == NULL) {
- free_idx = i;
- break;
+ of_node_get(np);
+ mpc52xx_uart_nodes[i] = np;
+ return;
}
}
-
- if ((idx < 0) || (idx >= MPC52xx_PSC_MAXNUM))
- idx = free_idx;
-
- if (idx < 0)
- return; /* No free slot; abort */
-
- of_node_get(np);
- /* 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[idx] = np;
}
static void
@@ -1243,23 +1231,17 @@ mpc52xx_uart_of_enumerate(void)
{
static int enum_done;
struct device_node *np;
- const unsigned int *devno;
const struct of_device_id *match;
int i;
if (enum_done)
return;
- for_each_node_by_type(np, "serial") {
+ /* Assign index to each PSC in device tree */
+ for_each_matching_node(np, mpc52xx_uart_of_match) {
match = of_match_node(mpc52xx_uart_of_match, np);
- if (!match)
- continue;
-
psc_ops = match->data;
-
- /* Is a particular device number requested? */
- devno = of_get_property(np, "port-number", NULL);
- mpc52xx_uart_of_assign(np, devno ? *devno : -1);
+ mpc52xx_uart_of_assign(np);
}
enum_done = 1;
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index f6e3b86bb0be..a48a8a13d87b 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -43,13 +43,7 @@
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/clk.h>
-
-#include <asm/io.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <mach/pxa-regs.h>
-#include <mach/regs-uart.h>
-
+#include <linux/io.h>
struct uart_pxa_port {
struct uart_port port;
@@ -491,7 +485,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
* Ensure the port will be enabled.
* This is required especially for serial console.
*/
- up->ier |= IER_UUE;
+ up->ier |= UART_IER_UUE;
/*
* Update the per-port timeout.
@@ -784,19 +778,15 @@ static int serial_pxa_probe(struct platform_device *dev)
sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
sport->port.uartclk = clk_get_rate(sport->clk);
- /*
- * Is it worth keeping this?
- */
- if (mmres->start == __PREG(FFUART))
- sport->name = "FFUART";
- else if (mmres->start == __PREG(BTUART))
- sport->name = "BTUART";
- else if (mmres->start == __PREG(STUART))
- sport->name = "STUART";
- else if (mmres->start == __PREG(HWUART))
- sport->name = "HWUART";
- else
+ switch (dev->id) {
+ case 0: sport->name = "FFUART"; break;
+ case 1: sport->name = "BTUART"; break;
+ case 2: sport->name = "STUART"; break;
+ case 3: sport->name = "HWUART"; break;
+ default:
sport->name = "???";
+ break;
+ }
sport->port.membase = ioremap(mmres->start, mmres->end - mmres->start + 1);
if (!sport->port.membase) {
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 38c600c0dbbf..bb9fe1224880 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -1,6 +1,6 @@
#include <linux/serial_core.h>
#include <asm/io.h>
-#include <asm/gpio.h>
+#include <linux/gpio.h>
#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
#include <asm/regs306x.h>
@@ -32,7 +32,9 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721)
# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
-#define SCIF_ORER 0x0200 /* overrun error bit */
+# define PORT_PTCR 0xA405011EUL
+# define PORT_PVCR 0xA4050122UL
+# define SCIF_ORER 0x0200 /* overrun error bit */
#elif defined(CONFIG_SH_RTS7751R2D)
# define SCSPTR1 0xFFE0001C /* 8 bit SCIF */
# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
@@ -131,7 +133,7 @@
# define SCSPTR3 0xffed0024 /* 16 bit SCIF */
# define SCSPTR4 0xffee0024 /* 16 bit SCIF */
# define SCSPTR5 0xffef0024 /* 16 bit SCIF */
-# define SCIF_OPER 0x0001 /* Overrun error bit */
+# define SCIF_ORER 0x0001 /* Overrun error bit */
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
defined(CONFIG_CPU_SUBTYPE_SH7203) || \
@@ -393,6 +395,7 @@ SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16)
SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8)
SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16)
SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8)
+SCIx_FNS(SCSPTR, 0, 0, 0, 0)
SCIF_FNS(SCTDSR, 0x0c, 8)
SCIF_FNS(SCFER, 0x10, 16)
SCIF_FNS(SCFCR, 0x18, 16)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 45a299f35617..e09d3cebb4fb 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1438,12 +1438,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
} else {
printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id,
+ dev_name(&op->dev),
(unsigned long long) up[0].port.mapbase,
op->irqs[0], sunzilog_type(&up[0].port));
printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) "
"is a %s\n",
- op->dev.bus_id,
+ dev_name(&op->dev),
(unsigned long long) up[1].port.mapbase,
op->irqs[0], sunzilog_type(&up[1].port));
kbm_inst++;
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 63f0de29aa14..7e1257af3d41 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -424,7 +424,7 @@ static void maple_attach_driver(struct maple_device *mdev)
/* Do this silently - as not a real device */
function = 0;
mdev->driver = &maple_dummy_driver;
- sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port);
+ dev_set_name(&mdev->dev, "%d:0.port", mdev->port);
} else {
printk(KERN_INFO
"Maple bus at (%d, %d): Function 0x%lX\n",
@@ -440,8 +440,8 @@ static void maple_attach_driver(struct maple_device *mdev)
"No maple driver found.\n");
mdev->driver = &maple_dummy_driver;
}
- sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port,
- mdev->unit, function);
+ dev_set_name(&mdev->dev, "%d:0%d.%lX", mdev->port,
+ mdev->unit, function);
}
mdev->function = function;
mdev->dev.release = &maple_release_device;
@@ -780,7 +780,7 @@ struct bus_type maple_bus_type = {
EXPORT_SYMBOL_GPL(maple_bus_type);
static struct device maple_bus = {
- .bus_id = "maple",
+ .init_name = "maple",
.release = maple_bus_release,
};
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 4d0282b821b5..2d9e7f3d5611 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -22,7 +22,7 @@
static int superhyway_devices;
static struct device superhyway_bus_device = {
- .bus_id = "superhyway",
+ .init_name = "superhyway",
};
static void superhyway_device_release(struct device *dev)
@@ -83,7 +83,7 @@ int superhyway_add_device(unsigned long base, struct superhyway_device *sdev,
dev->id.id = dev->vcr.mod_id;
sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
- sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
+ dev_set_name(&dev->dev, "%02x", superhyway_devices);
superhyway_devices++;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 4a6fe01831a8..83a185d52961 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -230,17 +230,6 @@ config SPI_XILINX
#
comment "SPI Protocol Masters"
-config SPI_AT25
- tristate "SPI EEPROMs from most vendors"
- depends on SYSFS
- help
- Enable this driver to get read/write support to most SPI EEPROMs,
- after you configure the board init code to know about each eeprom
- on your target board.
-
- This driver can also be built as a module. If so, the module
- will be called at25.
-
config SPI_SPIDEV
tristate "User mode SPI device driver support"
depends on EXPERIMENTAL
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 5e9f521b8844..5d0451936d86 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
# ... add above this line ...
# SPI protocol drivers (device/link on bus)
-obj-$(CONFIG_SPI_AT25) += at25.o
obj-$(CONFIG_SPI_SPIDEV) += spidev.o
obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o
# ... add above this line ...
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 56ff3e6864ea..12e443cc4ac9 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -322,7 +322,7 @@ static void atmel_spi_next_message(struct spi_master *master)
spi = msg->spi;
dev_dbg(master->dev.parent, "start message %p for %s\n",
- msg, spi->dev.bus_id);
+ msg, dev_name(&spi->dev));
/* select chip if it's not still active */
if (as->stay) {
@@ -627,7 +627,7 @@ static int atmel_spi_setup(struct spi_device *spi)
if (!asd)
return -ENOMEM;
- ret = gpio_request(npcs_pin, spi->dev.bus_id);
+ ret = gpio_request(npcs_pin, dev_name(&spi->dev));
if (ret) {
kfree(asd);
return ret;
@@ -668,7 +668,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
as = spi_master_get_devdata(spi->master);
dev_dbg(controller, "new message %p submitted for %s\n",
- msg, spi->dev.bus_id);
+ msg, dev_name(&spi->dev));
if (unlikely(list_empty(&msg->transfers)))
return -EINVAL;
@@ -803,7 +803,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev)
as->clk = clk;
ret = request_irq(irq, atmel_spi_interrupt, 0,
- pdev->dev.bus_id, master);
+ dev_name(&pdev->dev), master);
if (ret)
goto out_unmap_regs;
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 3b97803e1d11..68c77a911595 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -429,7 +429,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
INIT_LIST_HEAD(&mps->queue);
mps->workqueue = create_singlethread_workqueue(
- master->dev.parent->bus_id);
+ dev_name(master->dev.parent));
if (mps->workqueue == NULL) {
ret = -EBUSY;
goto free_irq;
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 454a2712e629..1c65e380c845 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -1003,7 +1003,7 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
goto err1;
}
if (!request_mem_region(r->start, (r->end - r->start) + 1,
- pdev->dev.bus_id)) {
+ dev_name(&pdev->dev))) {
status = -EBUSY;
goto err1;
}
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index bab6ff061e91..60b5381c65c4 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -245,7 +245,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
#ifdef VERBOSE
pr_debug("%s: write-%d =%04x\n",
- spi->dev.bus_id, bits, val);
+ dev_name(&spi->dev), bits, val);
#endif
if (wait_uwire_csr_flag(CSRB, 0, 0))
goto eio;
@@ -305,7 +305,7 @@ static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
status += bytes;
#ifdef VERBOSE
pr_debug("%s: read-%d =%04x\n",
- spi->dev.bus_id, bits, val);
+ dev_name(&spi->dev), bits, val);
#endif
}
@@ -331,7 +331,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
uwire = spi_master_get_devdata(spi->master);
if (spi->chip_select > 3) {
- pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select);
+ pr_debug("%s: cs%d?\n", dev_name(&spi->dev), spi->chip_select);
status = -ENODEV;
goto done;
}
@@ -343,7 +343,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
bits = 8;
if (bits > 16) {
- pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits);
+ pr_debug("%s: wordsize %d?\n", dev_name(&spi->dev), bits);
status = -ENODEV;
goto done;
}
@@ -378,7 +378,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
hz = t->speed_hz;
if (!hz) {
- pr_debug("%s: zero speed?\n", spi->dev.bus_id);
+ pr_debug("%s: zero speed?\n", dev_name(&spi->dev));
status = -EINVAL;
goto done;
}
@@ -406,7 +406,7 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
}
if (div1_idx == 4) {
pr_debug("%s: lowest clock %ld, need %d\n",
- spi->dev.bus_id, rate / 10 / 8, hz);
+ dev_name(&spi->dev), rate / 10 / 8, hz);
status = -EDOM;
goto done;
}
diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c
index 014becb7d530..c8b0babdc2a6 100644
--- a/drivers/spi/orion_spi.c
+++ b/drivers/spi/orion_spi.c
@@ -496,7 +496,7 @@ static int __init orion_spi_probe(struct platform_device *pdev)
}
if (!request_mem_region(r->start, (r->end - r->start) + 1,
- pdev->dev.bus_id)) {
+ dev_name(&pdev->dev))) {
status = -EBUSY;
goto out;
}
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index d0fc4ca2f656..33fcef3150d4 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -34,8 +34,6 @@
#include <asm/delay.h>
#include <mach/dma.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/regs-ssp.h>
#include <mach/ssp.h>
#include <mach/pxa2xx_spi.h>
@@ -1333,7 +1331,7 @@ static int __init init_queue(struct driver_data *drv_data)
INIT_WORK(&drv_data->pump_messages, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->dev.parent->bus_id);
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;
@@ -1462,7 +1460,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR;
}
- status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
+ status = request_irq(ssp->irq, ssp_int, 0, dev_name(dev), drv_data);
if (status < 0) {
dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq);
goto out_error_master_alloc;
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index 7fea3cf4588a..3410b0c55ed2 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -1160,8 +1160,8 @@ static inline int init_queue(struct driver_data *drv_data)
/* init messages workqueue */
INIT_WORK(&drv_data->pump_messages, pump_messages);
- drv_data->workqueue =
- create_singlethread_workqueue(drv_data->master->dev.parent->bus_id);
+ drv_data->workqueue = create_singlethread_workqueue(
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c
index 49698cabc30d..d2866c293dee 100644
--- a/drivers/spi/spi_gpio.c
+++ b/drivers/spi/spi_gpio.c
@@ -114,7 +114,7 @@ static inline void setmosi(const struct spi_device *spi, int is_on)
static inline int getmiso(const struct spi_device *spi)
{
- return gpio_get_value(SPI_MISO_GPIO);
+ return !!gpio_get_value(SPI_MISO_GPIO);
}
#undef pdata
@@ -191,7 +191,7 @@ static int spi_gpio_setup(struct spi_device *spi)
return -EINVAL;
if (!spi->controller_state) {
- status = gpio_request(cs, spi->dev.bus_id);
+ status = gpio_request(cs, dev_name(&spi->dev));
if (status)
return status;
status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 269a55ec52ef..0480d8bb19d3 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1381,7 +1381,7 @@ static int __init init_queue(struct driver_data *drv_data)
INIT_WORK(&drv_data->work, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->dev.parent->bus_id);
+ dev_name(drv_data->master->dev.parent));
if (drv_data->workqueue == NULL)
return -EBUSY;
@@ -1525,7 +1525,8 @@ static int __init spi_imx_probe(struct platform_device *pdev)
status = -ENODEV;
goto err_no_irqres;
}
- status = request_irq(irq, spi_int, IRQF_DISABLED, dev->bus_id, drv_data);
+ status = request_irq(irq, spi_int, IRQF_DISABLED,
+ dev_name(dev), drv_data);
if (status < 0) {
dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status);
goto err_no_irqres;
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index ac0e3e4b3c54..44a2b46ccb79 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -637,7 +637,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
INIT_LIST_HEAD(&mpc83xx_spi->queue);
mpc83xx_spi->workqueue = create_singlethread_workqueue(
- master->dev.parent->bus_id);
+ dev_name(master->dev.parent));
if (mpc83xx_spi->workqueue == NULL) {
ret = -EBUSY;
goto free_irq;
@@ -649,7 +649,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
printk(KERN_INFO
"%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
- dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq);
+ dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq);
return ret;
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index 2296f37ea3c6..29cbb065618a 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -404,7 +404,8 @@ static int __init txx9spi_probe(struct platform_device *dev)
if (ret)
goto exit;
- c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id);
+ c->workqueue = create_singlethread_workqueue(
+ dev_name(master->dev.parent));
if (!c->workqueue)
goto exit_busy;
c->last_chipselect = -1;
diff --git a/drivers/staging/agnx/agnx.h b/drivers/staging/agnx/agnx.h
index a75b0db3726c..20f36da62475 100644
--- a/drivers/staging/agnx/agnx.h
+++ b/drivers/staging/agnx/agnx.h
@@ -1,6 +1,8 @@
#ifndef AGNX_H_
#define AGNX_H_
+#include <linux/io.h>
+
#include "xmit.h"
#define PFX KBUILD_MODNAME ": "
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
index 8e2b4ca0651d..f516140ca976 100644
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ b/drivers/staging/altpciechdma/altpciechdma.c
@@ -531,7 +531,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
goto fail;
/* allocate and map coherently-cached memory for a DMA-able buffer */
- /* @see 2.6.26.2/Documentation/DMA-mapping.txt line 318 */
+ /* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
buffer_virt = (u8 *)pci_alloc_consistent(dev, PAGE_SIZE * 4, &buffer_bus);
if (!buffer_virt) {
printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n");
@@ -846,7 +846,7 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
#if 1 // @todo For now, disable 64-bit, because I do not understand the implications (DAC!)
/* query for DMA transfer */
- /* @see Documentation/DMA-mapping.txt */
+ /* @see Documentation/PCI/PCI-DMA-mapping.txt */
if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)) {
pci_set_consistent_dma_mask(dev, DMA_64BIT_MASK);
/* use 64-bit DMA */
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 6b996db0dd6a..604bd1e0d546 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -27,6 +27,7 @@ menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
bool "Android RAM Console Enable error correction"
default n
depends on ANDROID_RAM_CONSOLE
+ depends on !ANDROID_RAM_CONSOLE_EARLY_INIT
select REED_SOLOMON
select REED_SOLOMON_ENC8
select REED_SOLOMON_DEC8
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 6a4ceacb33f5..758131cad08a 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -319,6 +319,7 @@ int task_get_unused_fd_flags(struct task_struct *tsk, int flags)
int fd, error;
struct fdtable *fdt;
unsigned long rlim_cur;
+ unsigned long irqs;
if (files == NULL)
return -ESRCH;
@@ -335,12 +336,11 @@ repeat:
* N.B. For clone tasks sharing a files structure, this test
* will limit the total number of files that can be opened.
*/
- rcu_read_lock();
- if (tsk->signal)
+ rlim_cur = 0;
+ if (lock_task_sighand(tsk, &irqs)) {
rlim_cur = tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
- else
- rlim_cur = 0;
- rcu_read_unlock();
+ unlock_task_sighand(tsk, &irqs);
+ }
if (fd >= rlim_cur)
goto out;
@@ -2649,14 +2649,14 @@ static void binder_vma_open(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot);
+ printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
dump_stack();
}
static void binder_vma_close(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot);
+ printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
proc->vma = NULL;
}
@@ -2677,7 +2677,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_end = vma->vm_start + SZ_4M;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, vma->vm_page_prot.pgprot);
+ printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
ret = -EPERM;
diff --git a/drivers/staging/android/lowmemorykiller.txt b/drivers/staging/android/lowmemorykiller.txt
new file mode 100644
index 000000000000..bd5c0c028968
--- /dev/null
+++ b/drivers/staging/android/lowmemorykiller.txt
@@ -0,0 +1,16 @@
+The lowmemorykiller driver lets user-space specify a set of memory thresholds
+where processes with a range of oom_adj values will get killed. Specify the
+minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
+number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
+files take a comma separated list of numbers in ascending order.
+
+For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
+"1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes
+with a oom_adj value of 8 or higher when the free memory drops below 4096 pages
+and kill processes with a oom_adj value of 0 or higher when the free memory
+drops below 1024 pages.
+
+The driver considers memory used for caches to be free, but if a large
+percentage of the cached memory is locked this can be very inaccurate
+and processes may not get killed until the normal oom killer is triggered.
+
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index bf006857a87a..643ac5ce381d 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -224,9 +224,23 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
ram_console_buffer_size =
buffer_size - sizeof(struct ram_console_buffer);
+ if (ram_console_buffer_size > buffer_size) {
+ pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n",
+ buffer, buffer_size, ram_console_buffer_size);
+ return 0;
+ }
+
#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size,
ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
+
+ if (ram_console_buffer_size > buffer_size) {
+ pr_err("ram_console: buffer %p, invalid size %d, "
+ "non-ecc datasize %d\n",
+ buffer, buffer_size, ram_console_buffer_size);
+ return 0;
+ }
+
ram_console_par_buffer = buffer->data + ram_console_buffer_size;
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index bea68c9fc942..33daff0481d2 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -18,7 +18,7 @@
#include <linux/platform_device.h>
#include <linux/hrtimer.h>
#include <linux/err.h>
-#include <asm/arch/gpio.h>
+#include <linux/gpio.h>
#include "timed_gpio.h"
@@ -49,7 +49,8 @@ static ssize_t gpio_enable_show(struct device *dev, struct device_attribute *att
if (hrtimer_active(&gpio_data->timer)) {
ktime_t r = hrtimer_get_remaining(&gpio_data->timer);
- remaining = r.tv.sec * 1000 + r.tv.nsec / 1000000;
+ struct timeval t = ktime_to_timeval(r);
+ remaining = t.tv_sec * 1000 + t.tv_usec / 1000;
} else
remaining = 0;
diff --git a/drivers/staging/at76_usb/Kconfig b/drivers/staging/at76_usb/Kconfig
index 4c0e55e15448..8606f9621624 100644
--- a/drivers/staging/at76_usb/Kconfig
+++ b/drivers/staging/at76_usb/Kconfig
@@ -1,6 +1,6 @@
config USB_ATMEL
tristate "Atmel at76c503/at76c505/at76c505a USB cards"
- depends on MAC80211 && WLAN_80211 && USB
+ depends on WLAN_80211 && USB
default N
select FW_LOADER
---help---
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
index 185533e54769..c8e4d31c7df2 100644
--- a/drivers/staging/at76_usb/at76_usb.c
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -6,7 +6,6 @@
* Copyright (c) 2004 Nick Jones
* Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
* Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
- * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -17,13 +16,6 @@
* Atmel AT76C503A/505/505A.
*
* Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
- *
- * TODO for the mac80211 port:
- * o adhoc support
- * o RTS/CTS support
- * o Power Save Mode support
- * o support for short/long preambles
- * o export variables through debugfs/sysfs
*/
#include <linux/init.h>
@@ -44,7 +36,7 @@
#include <net/ieee80211_radiotap.h>
#include <linux/firmware.h>
#include <linux/leds.h>
-#include <net/mac80211.h>
+#include <net/ieee80211.h>
#include "at76_usb.h"
@@ -84,43 +76,31 @@
#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
#define DBG_FW 0x10000000 /* firmware download */
#define DBG_DFU 0x20000000 /* device firmware upgrade */
-#define DBG_CMD 0x40000000
-#define DBG_MAC80211 0x80000000
#define DBG_DEFAULTS 0
/* Use our own dbg macro */
#define at76_dbg(bits, format, arg...) \
-do { \
- if (at76_debug & (bits)) \
- printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
-} while (0)
-
-#define at76_dbg_dump(bits, buf, len, format, arg...) \
-do { \
- if (at76_debug & (bits)) { \
+ do { \
+ if (at76_debug & (bits)) \
printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \
- } \
-} while (0)
+ } while (0)
static int at76_debug = DBG_DEFAULTS;
-#define FIRMWARE_IS_WPA(ver) ((ver.major == 1) && (ver.minor == 103))
-
/* Protect against concurrent firmware loading and parsing */
static struct mutex fw_mutex;
static struct fwentry firmwares[] = {
- [0] = { "" },
- [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" },
- [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" },
- [BOARD_503] = { "atmel_at76c503-rfmd.bin" },
- [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" },
- [BOARD_505] = { "atmel_at76c505-rfmd.bin" },
- [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" },
- [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" },
- [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" },
+ [0] = {""},
+ [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"},
+ [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"},
+ [BOARD_503] = {"atmel_at76c503-rfmd.bin"},
+ [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"},
+ [BOARD_505] = {"atmel_at76c505-rfmd.bin"},
+ [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"},
+ [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"},
+ [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"},
};
#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
@@ -130,133 +110,135 @@ static struct usb_device_id dev_table[] = {
* at76c503-i3861
*/
/* Generic AT76C503/3861 device */
- { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Linksys WUSB11 v2.1/v2.6 */
- { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Netgear MA101 rev. A */
- { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Tekram U300C / Allnet ALL0193 */
- { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* HP HN210W J7801A */
- { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Sitecom/Z-Com/Zyxel M4Y-750 */
- { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Dynalink/Askey WLL013 (intersil) */
- { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
- { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* BenQ AWL300 */
- { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Addtron AWU-120, Compex WLU11 */
- { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Intel AP310 AnyPoint II USB */
- { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Dynalink L11U */
- { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Arescom WL-210, FCC id 07J-GL2411USB */
- { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* I-O DATA WN-B11/USB */
- { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* BT Voyager 1010 */
- { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/*
* at76c503-i3863
*/
/* Generic AT76C503/3863 device */
- { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)},
/* Samsung SWL-2100U */
- { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)},
/*
* at76c503-rfmd
*/
/* Generic AT76C503/RFMD device */
- { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)},
/* Dynalink/Askey WLL013 (rfmd) */
- { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)},
/* Linksys WUSB11 v2.6 */
- { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)},
/* Network Everywhere NWU11B */
- { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)},
/* Netgear MA101 rev. B */
- { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)},
/* D-Link DWL-120 rev. E */
- { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)},
/* Actiontec 802UAT1, HWU01150-01UK */
- { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)},
/* AirVast W-Buddie WN210 */
- { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)},
/* Dick Smith Electronics XH1153 802.11b USB adapter */
- { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)},
/* CNet CNUSB611 */
- { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)},
/* FiberLine FL-WL200U */
- { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)},
/* BenQ AWL400 USB stick */
- { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)},
/* 3Com 3CRSHEW696 */
- { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)},
/* Siemens Santis ADSL WLAN USB adapter WLL 013 */
- { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)},
/* Belkin F5D6050, version 2 */
- { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)},
/* iBlitzz, BWU613 (not *B or *SB) */
- { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)},
/* Gigabyte GN-WLBM101 */
- { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)},
/* Planex GW-US11S */
- { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)},
/* Internal WLAN adapter in h5[4,5]xx series iPAQs */
- { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)},
/* Corega Wireless LAN USB-11 mini */
- { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)},
/* Corega Wireless LAN USB-11 mini2 */
- { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)},
/* Uniden PCW100 */
- { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)},
/*
* at76c503-rfmd-acc
*/
/* SMC2664W */
- { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) },
+ {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)},
/* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
- { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) },
+ {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)},
/*
* at76c505-rfmd
*/
/* Generic AT76C505/RFMD */
- { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) },
+ {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
/*
* at76c505-rfmd2958
*/
/* Generic AT76C505/RFMD, OvisLink WL-1130USB */
- { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
/* Fiberline FL-WL240U */
- { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)},
/* CNet CNUSB-611G */
- { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)},
/* Linksys WUSB11 v2.8 */
- { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)},
/* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
- { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)},
/* Corega WLAN USB Stick 11 */
- { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
/* Microstar MSI Box MS6978 */
- { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)},
/*
* at76c505a-rfmd2958
*/
/* Generic AT76C505A device */
- { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)},
/* Generic AT76C505AS device */
- { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)},
/* Siemens Gigaset USB WLAN Adapter 11 */
- { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)},
+ /* OQO Model 01+ Internal Wi-Fi */
+ {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)},
/*
* at76c505amx-rfmd
*/
/* Generic AT76C505AMX device */
- { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) },
- { }
+ {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
+ {}
};
MODULE_DEVICE_TABLE(usb, dev_table);
@@ -264,8 +246,26 @@ MODULE_DEVICE_TABLE(usb, dev_table);
/* Supported rates of this hardware, bit 7 marks basic rates */
static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
+/* Frequency of each channel in MHz */
+static const long channel_frequency[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+
+#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
+
static const char *const preambles[] = { "long", "short", "auto" };
+static const char *const mac_states[] = {
+ [MAC_INIT] = "INIT",
+ [MAC_SCANNING] = "SCANNING",
+ [MAC_AUTH] = "AUTH",
+ [MAC_ASSOC] = "ASSOC",
+ [MAC_JOINING] = "JOINING",
+ [MAC_CONNECTED] = "CONNECTED",
+ [MAC_OWN_IBSS] = "OWN_IBSS"
+};
+
/* Firmware download */
/* DFU states */
#define STATE_IDLE 0x00
@@ -300,30 +300,17 @@ struct dfu_status {
static inline int at76_is_intersil(enum board_type board)
{
- if (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863)
- return 1;
- return 0;
+ return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
}
static inline int at76_is_503rfmd(enum board_type board)
{
- if (board == BOARD_503 || board == BOARD_503_ACC)
- return 1;
- return 0;
-}
-
-static inline int at76_is_505(enum board_type board)
-{
- if (board == BOARD_505 || board == BOARD_505_2958)
- return 1;
- return 0;
+ return (board == BOARD_503 || board == BOARD_503_ACC);
}
static inline int at76_is_505a(enum board_type board)
{
- if (board == BOARD_505A || board == BOARD_505AMX)
- return 1;
- return 0;
+ return (board == BOARD_505A || board == BOARD_505AMX);
}
/* Load a block of the first (internal) part of the firmware */
@@ -504,6 +491,41 @@ exit:
return ret;
}
+/* Report that the scan results are ready */
+static inline void at76_iwevent_scan_complete(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name);
+}
+
+static inline void at76_iwevent_bss_connect(struct net_device *netdev,
+ u8 *bssid)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
+static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
#define HEX2STR_BUFFERS 4
#define HEX2STR_MAX_LEN 64
#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
@@ -575,6 +597,37 @@ static void at76_ledtrig_tx_activity(void)
mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
}
+/* Check if the given ssid is hidden */
+static inline int at76_is_hidden_ssid(u8 *ssid, int length)
+{
+ static const u8 zeros[32];
+
+ if (length == 0)
+ return 1;
+
+ if (length == 1 && ssid[0] == ' ')
+ return 1;
+
+ return (memcmp(ssid, zeros, length) == 0);
+}
+
+static inline void at76_free_bss_list(struct at76_priv *priv)
+{
+ struct list_head *next, *ptr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ priv->curr_bss = NULL;
+
+ list_for_each_safe(ptr, next, &priv->bss_list) {
+ list_del(ptr);
+ kfree(list_entry(ptr, struct bss_info, list));
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
static int at76_remap(struct usb_device *udev)
{
int ret;
@@ -598,7 +651,7 @@ static int at76_get_op_mode(struct usb_device *udev)
return -ENOMEM;
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
USB_TYPE_VENDOR | USB_DIR_IN |
- USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1,
+ USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
USB_CTRL_GET_TIMEOUT);
saved = *op_mode;
kfree(op_mode);
@@ -676,7 +729,7 @@ exit:
kfree(hwcfg);
if (ret < 0)
printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -685,15 +738,15 @@ static struct reg_domain const *at76_get_reg_domain(u16 code)
{
int i;
static struct reg_domain const fd_tab[] = {
- { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */
- { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */
- { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */
- { 0x31, "Spain", 0x600 }, /* ch 10-11 */
- { 0x32, "France", 0x1e00 }, /* ch 10-13 */
- { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */
- { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */
- { 0x50, "Israel", 0x3fc }, /* ch 3-9 */
- { 0x00, "<unknown>", 0xffffffff } /* ch 1-32 */
+ {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */
+ {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */
+ {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */
+ {0x31, "Spain", 0x600}, /* ch 10-11 */
+ {0x32, "France", 0x1e00}, /* ch 10-13 */
+ {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */
+ {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */
+ {0x50, "Israel", 0x3fc}, /* ch 3-9 */
+ {0x00, "<unknown>", 0xffffffff} /* ch 1-32 */
};
/* Last entry is fallback for unknown domain code */
@@ -731,7 +784,7 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
USB_TYPE_VENDOR | USB_DIR_IN |
USB_RECIP_INTERFACE, cmd, 0, stat_buf,
- sizeof(stat_buf), USB_CTRL_GET_TIMEOUT);
+ 40, USB_CTRL_GET_TIMEOUT);
if (ret >= 0)
ret = stat_buf[5];
kfree(stat_buf);
@@ -739,24 +792,6 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
return ret;
}
-#define MAKE_CMD_CASE(c) case (c): return #c
-
-static const char *at76_get_cmd_string(u8 cmd_status)
-{
- switch (cmd_status) {
- MAKE_CMD_CASE(CMD_SET_MIB);
- MAKE_CMD_CASE(CMD_GET_MIB);
- MAKE_CMD_CASE(CMD_SCAN);
- MAKE_CMD_CASE(CMD_JOIN);
- MAKE_CMD_CASE(CMD_START_IBSS);
- MAKE_CMD_CASE(CMD_RADIO_ON);
- MAKE_CMD_CASE(CMD_RADIO_OFF);
- MAKE_CMD_CASE(CMD_STARTUP);
- }
-
- return "UNKNOWN";
-}
-
static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
int buf_size)
{
@@ -772,10 +807,6 @@ static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
cmd_buf->size = cpu_to_le16(buf_size);
memcpy(cmd_buf->data, buf, buf_size);
- at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size,
- "issuing command %s (0x%02x)",
- at76_get_cmd_string(cmd), cmd);
-
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
0, 0, cmd_buf,
@@ -813,13 +844,13 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
status = at76_get_cmd_status(priv->udev, cmd);
if (status < 0) {
printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
- wiphy_name(priv->hw->wiphy), status);
+ priv->netdev->name, status);
break;
}
at76_dbg(DBG_WAIT_COMPLETE,
"%s: Waiting on cmd %d, status = %d (%s)",
- wiphy_name(priv->hw->wiphy), cmd, status,
+ priv->netdev->name, cmd, status,
at76_get_cmd_status_string(status));
if (status != CMD_STATUS_IN_PROGRESS
@@ -830,7 +861,7 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
if (time_after(jiffies, timeout)) {
printk(KERN_ERR
"%s: completion timeout for command %d\n",
- wiphy_name(priv->hw->wiphy), cmd);
+ priv->netdev->name, cmd);
status = -ETIMEDOUT;
break;
}
@@ -853,7 +884,7 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
if (ret != CMD_STATUS_COMPLETE) {
printk(KERN_INFO
"%s: set_mib: at76_wait_completion failed "
- "with %d\n", wiphy_name(priv->hw->wiphy), ret);
+ "with %d\n", priv->netdev->name, ret);
ret = -EIO;
}
@@ -874,7 +905,7 @@ static int at76_set_radio(struct at76_priv *priv, int enable)
ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
if (ret < 0)
printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
- wiphy_name(priv->hw->wiphy), cmd, ret);
+ priv->netdev->name, cmd, ret);
else
ret = 1;
@@ -895,7 +926,44 @@ static int at76_set_pm_mode(struct at76_priv *priv)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the association id for power save mode */
+static int at76_set_associd(struct at76_priv *priv, u16 id)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
+ priv->mib_buf.data.word = cpu_to_le16(id);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the listen interval for power save mode */
+static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
+ priv->mib_buf.data.word = cpu_to_le16(interval);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: set_mib (listen_interval) failed: %d\n",
+ priv->netdev->name, ret);
return ret;
}
@@ -912,7 +980,7 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -929,7 +997,7 @@ static int at76_set_frag(struct at76_priv *priv, u16 size)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -946,7 +1014,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -963,41 +1031,24 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
-static int at76_set_tkip_bssid(struct at76_priv *priv, const void *addr)
+static int at76_add_mac_address(struct at76_priv *priv, void *addr)
{
int ret = 0;
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
+ priv->mib_buf.type = MIB_MAC_ADDR;
priv->mib_buf.size = ETH_ALEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption, tkip_bssid);
+ priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
- printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, tkip_bssid) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
-
- return ret;
-}
-
-static int at76_reset_rsc(struct at76_priv *priv)
-{
- int ret = 0;
-
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
- priv->mib_buf.size = 4 * 8;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption, key_rsc);
- memset(priv->mib_buf.data.data, 0 , priv->mib_buf.size);
-
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret < 0)
- printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, key_rsc) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
+ priv->netdev->name, ret);
return ret;
}
@@ -1016,16 +1067,16 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv)
sizeof(struct mib_mac_addr));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
mac2str(m->mac_addr), m->res[0], m->res[1]);
for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
- "status %d", wiphy_name(priv->hw->wiphy), i,
+ "status %d", priv->netdev->name, i,
mac2str(m->group_addr[i]), m->group_addr_status[i]);
exit:
kfree(m);
@@ -1045,13 +1096,13 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
sizeof(struct mib_mac_wep));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
"key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
- "encr_level %u key %d", wiphy_name(priv->hw->wiphy),
+ "encr_level %u key %d", priv->netdev->name,
m->privacy_invoked, m->wep_default_key_id,
m->wep_key_mapping_len, m->exclude_unencrypted,
le32_to_cpu(m->wep_icv_error_count),
@@ -1063,55 +1114,12 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
for (i = 0; i < WEP_KEYS; i++)
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
- wiphy_name(priv->hw->wiphy), i,
+ priv->netdev->name, i,
hex2str(m->wep_default_keyvalue[i], key_len));
exit:
kfree(m);
}
-static void at76_dump_mib_mac_encryption(struct at76_priv *priv)
-{
- int i;
- int ret;
- /*int key_len;*/
- struct mib_mac_encryption *m;
-
- m = kmalloc(sizeof(struct mib_mac_encryption), GFP_KERNEL);
- if (!m)
- return;
-
- ret = at76_get_mib(priv->udev, MIB_MAC_ENCRYPTION, m,
- sizeof(struct mib_mac_encryption));
- if (ret < 0) {
- dev_err(&priv->udev->dev,
- "%s: at76_get_mib (MAC_ENCRYPTION) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- goto exit;
- }
-
- at76_dbg(DBG_MIB,
- "%s: MIB MAC_ENCRYPTION: tkip_bssid %s priv_invoked %u "
- "ciph_key_id %u grp_key_id %u excl_unencr %u "
- "ckip_key_perm %u wep_icv_err %u wep_excluded %u",
- wiphy_name(priv->hw->wiphy), mac2str(m->tkip_bssid),
- m->privacy_invoked, m->cipher_default_key_id,
- m->cipher_default_group_key_id, m->exclude_unencrypted,
- m->ckip_key_permutation,
- le32_to_cpu(m->wep_icv_error_count),
- le32_to_cpu(m->wep_excluded_count));
-
- /*key_len = (m->encryption_level == 1) ?
- WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;*/
-
- for (i = 0; i < CIPHER_KEYS; i++)
- at76_dbg(DBG_MIB, "%s: MIB MAC_ENCRYPTION: key %d: %s",
- wiphy_name(priv->hw->wiphy), i,
- hex2str(m->cipher_default_keyvalue[i],
- CIPHER_KEY_LEN));
-exit:
- kfree(m);
-}
-
static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
{
int ret;
@@ -1125,7 +1133,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
sizeof(struct mib_mac_mgmt));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1136,7 +1144,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
"pm_mode %d ibss_change %d res %d "
"multi_domain_capability_implemented %d "
"international_roaming %d country_string %.3s",
- wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period),
+ priv->netdev->name, le16_to_cpu(m->beacon_period),
le16_to_cpu(m->CFP_max_duration),
le16_to_cpu(m->medium_occupancy_limit),
le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
@@ -1161,7 +1169,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1171,8 +1179,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
"scan_type %d scan_channel %d probe_delay %u "
"min_channel_time %d max_channel_time %d listen_int %d "
"desired_ssid %s desired_bssid %s desired_bsstype %d",
- wiphy_name(priv->hw->wiphy),
- le32_to_cpu(m->max_tx_msdu_lifetime),
+ priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime),
le32_to_cpu(m->max_rx_lifetime),
le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
@@ -1198,7 +1205,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1207,7 +1214,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
"mpdu_max_length %d cca_mode_supported %d operation_rate_set "
"0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
"phy_type %d current_reg_domain %d",
- wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold),
+ priv->netdev->name, le32_to_cpu(m->ed_threshold),
le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
le16_to_cpu(m->preamble_length),
le16_to_cpu(m->plcp_header_length),
@@ -1231,14 +1238,13 @@ static void at76_dump_mib_local(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
"txautorate_fallback %d ssid_size %d promiscuous_mode %d "
- "preamble_type %d", wiphy_name(priv->hw->wiphy),
- m->beacon_enable,
+ "preamble_type %d", priv->netdev->name, m->beacon_enable,
m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
m->preamble_type);
exit:
@@ -1257,21 +1263,118 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
sizeof(struct mib_mdomain));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
hex2str(m->channel_list, sizeof(m->channel_list)));
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
exit:
kfree(m);
}
+static int at76_get_current_bssid(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_mac_mgmt *mac_mgmt =
+ kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
+
+ if (!mac_mgmt) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN);
+ printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name,
+ mac2str(priv->bssid));
+error:
+ kfree(mac_mgmt);
+exit:
+ return ret;
+}
+
+static int at76_get_current_channel(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!phy) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ priv->channel = phy->channel_id;
+error:
+ kfree(phy);
+exit:
+ return ret;
+}
+
+/**
+ * at76_start_scan - start a scan
+ *
+ * @use_essid - use the configured ESSID in non passive mode
+ */
+static int at76_start_scan(struct at76_priv *priv, int use_essid)
+{
+ struct at76_req_scan scan;
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xff, ETH_ALEN);
+
+ if (use_essid) {
+ memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ scan.essid_size = priv->essid_size;
+ } else
+ scan.essid_size = 0;
+
+ /* jal: why should we start at a certain channel? we do scan the whole
+ range allowed by reg domain. */
+ scan.channel = priv->channel;
+
+ /* atmelwlandriver differs between scan type 0 and 1 (active/passive)
+ For ad-hoc mode, it uses type 0 only. */
+ scan.scan_type = priv->scan_mode;
+
+ /* INFO: For probe_delay, not multiplying by 1024 as this will be
+ slightly less than min_channel_time
+ (per spec: probe delay < min. channel time) */
+ scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
+ scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
+ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
+ scan.international_scan = 0;
+
+ /* other values are set to 0 for type 0 */
+
+ at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
+ "channel = %d, probe_delay = %d, scan_min_time = %d, "
+ "scan_max_time = %d)",
+ priv->netdev->name, use_essid,
+ scan.international_scan, scan.channel,
+ le16_to_cpu(scan.probe_delay),
+ le16_to_cpu(scan.min_channel_time),
+ le16_to_cpu(scan.max_channel_time));
+
+ return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+}
+
/* Enable monitor mode */
static int at76_start_monitor(struct at76_priv *priv)
{
@@ -1292,6 +1395,86 @@ static int at76_start_monitor(struct at76_priv *priv)
return ret;
}
+static int at76_start_ibss(struct at76_priv *priv)
+{
+ struct at76_req_ibss bss;
+ int ret;
+
+ WARN_ON(priv->mac_state != MAC_OWN_IBSS);
+ if (priv->mac_state != MAC_OWN_IBSS)
+ return -EBUSY;
+
+ memset(&bss, 0, sizeof(struct at76_req_ibss));
+ memset(bss.bssid, 0xff, ETH_ALEN);
+ memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ bss.essid_size = priv->essid_size;
+ bss.bss_type = ADHOC_MODE;
+ bss.channel = priv->channel;
+
+ ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss,
+ sizeof(struct at76_req_ibss));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: start_ibss failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_wait_completion(priv, CMD_START_IBSS);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_ERR "%s: start_ibss failed to complete, %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_get_current_bssid(priv);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_get_current_channel(priv);
+ if (ret < 0)
+ return ret;
+
+ /* not sure what this is good for ??? */
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ return 0;
+}
+
+/* Request card to join BSS in managed or ad-hoc mode */
+static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr)
+{
+ struct at76_req_join join;
+
+ BUG_ON(!ptr);
+
+ memset(&join, 0, sizeof(struct at76_req_join));
+ memcpy(join.bssid, ptr->bssid, ETH_ALEN);
+ memcpy(join.essid, ptr->ssid, ptr->ssid_len);
+ join.essid_size = ptr->ssid_len;
+ join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2);
+ join.channel = ptr->channel;
+ join.timeout = cpu_to_le16(2000);
+
+ at76_dbg(DBG_PROGRESS,
+ "%s join addr %s ssid %s type %d ch %d timeout %d",
+ priv->netdev->name, mac2str(join.bssid), join.essid,
+ join.bss_type, join.channel, le16_to_cpu(join.timeout));
+ return at76_set_card_command(priv->udev, CMD_JOIN, &join,
+ sizeof(struct at76_req_join));
+}
+
/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
likely to compensate a flaw in the AT76C503A USB part ... */
static inline int at76_calc_padding(int wlen)
@@ -1310,6 +1493,14 @@ static inline int at76_calc_padding(int wlen)
return 0;
}
+/* We are doing a lot of things here in an interrupt. Need
+ a bh handler (Watching TV with a TV card is probably
+ a good test: if you see flickers, we are doing too much.
+ Currently I do see flickers... even with our tasklet :-( )
+ Maybe because the bttv driver and usb-uhci use the same interrupt
+*/
+/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
+ * solve everything.. (alex) */
static void at76_rx_callback(struct urb *urb)
{
struct at76_priv *priv = urb->context;
@@ -1319,6 +1510,1758 @@ static void at76_rx_callback(struct urb *urb)
return;
}
+static void at76_tx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+ struct net_device_stats *stats = &priv->stats;
+ unsigned long flags;
+ struct at76_tx_buffer *mgmt_buf;
+ int ret;
+
+ switch (urb->status) {
+ case 0:
+ stats->tx_packets++;
+ break;
+ case -ENOENT:
+ case -ECONNRESET:
+ /* urb has been unlinked */
+ return;
+ default:
+ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
+ __func__, urb->status);
+ stats->tx_errors++;
+ break;
+ }
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ mgmt_buf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (!mgmt_buf) {
+ netif_wake_queue(priv->netdev);
+ return;
+ }
+
+ /* we don't copy the padding bytes, but add them
+ to the length */
+ memcpy(priv->bulk_out_buffer, mgmt_buf,
+ le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(mgmt_buf);
+}
+
+/* Send a management frame on bulk-out. txbuf->wlength must be set */
+static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf)
+{
+ unsigned long flags;
+ int ret;
+ int urb_status;
+ void *oldbuf = NULL;
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+
+ urb_status = priv->tx_urb->status;
+ if (urb_status == -EINPROGRESS) {
+ /* cannot transmit now, put in the queue */
+ oldbuf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = txbuf;
+ }
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (oldbuf) {
+ /* a data/mgmt tx is already pending in the URB -
+ if this is no error in some situations we must
+ implement a queue or silently modify the old msg */
+ printk(KERN_ERR "%s: removed pending mgmt buffer %s\n",
+ priv->netdev->name, hex2str(oldbuf, 64));
+ kfree(oldbuf);
+ return 0;
+ }
+
+ txbuf->tx_rate = TX_RATE_1MBIT;
+ txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength));
+ memset(txbuf->reserved, 0, sizeof(txbuf->reserved));
+
+ if (priv->next_mgmt_bulk)
+ printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n",
+ priv->netdev->name, urb_status);
+
+ at76_dbg(DBG_TX_MGMT,
+ "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
+ priv->netdev->name, le16_to_cpu(txbuf->wlength),
+ txbuf->tx_rate, txbuf->padding,
+ hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength)));
+
+ /* txbuf was not consumed above -> send mgmt msg immediately */
+ memcpy(priv->bulk_out_buffer, txbuf,
+ le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(txbuf->wlength) + txbuf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(txbuf);
+
+ return ret;
+}
+
+/* Go to the next information element */
+static inline void next_ie(struct ieee80211_info_element **ie)
+{
+ *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
+}
+
+/* Challenge is the challenge string (in TLV format)
+ we got with seq_nr 2 for shared secret authentication only and
+ send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
+ otherwise it is NULL */
+static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss,
+ int seq_nr, struct ieee80211_info_element *challenge)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_auth *req;
+ int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
+ AUTH_FRAME_SIZE + 1 + 1 + challenge->len);
+
+ BUG_ON(!bss);
+ BUG_ON(seq_nr == 3 && !challenge);
+ tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_auth *)tx_buffer->packet;
+ mgmt = &req->header;
+
+ /* make wireless header */
+ /* first auth msg is not encrypted, only the second (seq_nr == 3) */
+ mgmt->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
+ (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ req->algorithm = cpu_to_le16(priv->auth_mode);
+ req->transaction = cpu_to_le16(seq_nr);
+ req->status = cpu_to_le16(0);
+
+ if (seq_nr == 3)
+ memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN);
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction));
+ if (seq_nr == 3)
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
+ priv->netdev->name, hex2str(req->info_element, 18));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_assoc_request *req;
+ struct ieee80211_info_element *ie;
+ char *essid;
+ int essid_len;
+ u16 capa;
+
+ BUG_ON(!bss);
+
+ tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_assoc_request *)tx_buffer->packet;
+ mgmt = &req->header;
+ ie = req->info_element;
+
+ /* make wireless header */
+ mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ASSOC_REQ);
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ /* we must set the Privacy bit in the capabilities to assure an
+ Agere-based AP with optional WEP transmits encrypted frames
+ to us. AP only set the Privacy bit in their capabilities
+ if WEP is mandatory in the BSS! */
+ capa = bss->capa;
+ if (priv->wep_enabled)
+ capa |= WLAN_CAPABILITY_PRIVACY;
+ if (priv->preamble_type != PREAMBLE_TYPE_LONG)
+ capa |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+ req->capability = cpu_to_le16(capa);
+
+ req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
+
+ /* write TLV data elements */
+
+ ie->id = MFIE_TYPE_SSID;
+ ie->len = bss->ssid_len;
+ memcpy(ie->data, bss->ssid, bss->ssid_len);
+ next_ie(&ie);
+
+ ie->id = MFIE_TYPE_RATES;
+ ie->len = sizeof(hw_rates);
+ memcpy(ie->data, hw_rates, sizeof(hw_rates));
+ next_ie(&ie); /* ie points behind the supp_rates field */
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
+
+ ie = req->info_element;
+ essid = ie->data;
+ essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
+
+ next_ie(&ie); /* points to IE of rates now */
+ at76_dbg(DBG_TX_MGMT,
+ "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->capability), essid_len, essid,
+ hex2str(ie->data, ie->len));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+/* We got to check the bss_list for old entries */
+static void at76_bss_list_timeout(unsigned long par)
+{
+ struct at76_priv *priv = (struct at76_priv *)par;
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *ptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+
+ ptr = list_entry(lptr, struct bss_info, list);
+
+ if (ptr != priv->curr_bss
+ && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) {
+ at76_dbg(DBG_BSS_TABLE_RM,
+ "%s: bss_list: removing old BSS %s ch %d",
+ priv->netdev->name, mac2str(ptr->bssid),
+ ptr->channel);
+ list_del(&ptr->list);
+ kfree(ptr);
+ }
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+ /* restart the timer */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
+}
+
+static inline void at76_set_mac_state(struct at76_priv *priv,
+ enum mac_state mac_state)
+{
+ at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
+ mac_states[mac_state]);
+ priv->mac_state = mac_state;
+}
+
+static void at76_dump_bss_table(struct at76_priv *priv)
+{
+ struct bss_info *ptr;
+ unsigned long flags;
+ struct list_head *lptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
+ priv->curr_bss);
+
+ list_for_each(lptr, &priv->bss_list) {
+ ptr = list_entry(lptr, struct bss_info, list);
+ at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s "
+ "(%s) capa 0x%04x rates %s rssi %d link %d noise %d",
+ ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len,
+ ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len),
+ ptr->capa, hex2str(ptr->rates, ptr->rates_len),
+ ptr->rssi, ptr->link_qual, ptr->noise_level);
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
+/* Called upon successful association to mark interface as connected */
+static void at76_work_assoc_done(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_assoc_done);
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ WARN_ON(!priv->curr_bss);
+ if (priv->mac_state != MAC_ASSOC || !priv->curr_bss)
+ goto exit;
+
+ if (priv->iw_mode == IW_MODE_INFRA) {
+ if (priv->pm_mode != AT76_PM_OFF) {
+ /* calculate the listen interval in units of
+ beacon intervals of the curr_bss */
+ u32 pm_period_beacon = (priv->pm_period >> 10) /
+ priv->curr_bss->beacon_interval;
+
+ pm_period_beacon = max(pm_period_beacon, 2u);
+ pm_period_beacon = min(pm_period_beacon, 0xffffu);
+
+ at76_dbg(DBG_PM,
+ "%s: pm_mode %d assoc id 0x%x listen int %d",
+ priv->netdev->name, priv->pm_mode,
+ priv->assoc_id, pm_period_beacon);
+
+ at76_set_associd(priv, priv->assoc_id);
+ at76_set_listen_interval(priv, (u16)pm_period_beacon);
+ }
+ schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
+ }
+ at76_set_pm_mode(priv);
+
+ netif_carrier_on(priv->netdev);
+ netif_wake_queue(priv->netdev);
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid);
+ at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* We only store the new mac address in netdev struct,
+ it gets set when the netdev is opened. */
+static int at76_set_mac_address(struct net_device *netdev, void *addr)
+{
+ struct sockaddr *mac = addr;
+ memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
+ return 1;
+}
+
+static struct net_device_stats *at76_get_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return &priv->stats;
+}
+
+static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
+ priv->wstats.qual.qual, priv->wstats.qual.level,
+ priv->wstats.qual.noise, priv->wstats.qual.updated);
+
+ return &priv->wstats;
+}
+
+static void at76_set_multicast(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int promisc;
+
+ promisc = ((netdev->flags & IFF_PROMISC) != 0);
+ if (promisc != priv->promisc) {
+ /* This gets called in interrupt, must reschedule */
+ priv->promisc = promisc;
+ schedule_work(&priv->work_set_promisc);
+ }
+}
+
+/* Stop all network activity, flush all pending tasks */
+static void at76_quiesce(struct at76_priv *priv)
+{
+ unsigned long flags;
+
+ netif_stop_queue(priv->netdev);
+ netif_carrier_off(priv->netdev);
+
+ at76_set_mac_state(priv, MAC_INIT);
+
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ cancel_delayed_work(&priv->dwork_restart);
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ kfree(priv->next_mgmt_bulk);
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+}
+
+/*******************************************************************************
+ * at76_priv implementations of iw_handler functions:
+ */
+static int at76_iw_handler_commit(struct net_device *netdev,
+ struct iw_request_info *info,
+ void *null, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
+ __func__);
+
+ if (priv->mac_state != MAC_INIT)
+ at76_quiesce(priv);
+
+ /* Wait half second before the restart to process subsequent
+ * requests from the same iwconfig in a single restart */
+ schedule_delayed_work(&priv->dwork_restart, HZ / 2);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_name(struct net_device *netdev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ strcpy(name, "IEEE 802.11b");
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
+ return 0;
+}
+
+static int at76_iw_handler_set_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int chan = -1;
+ int ret = -EIWCOMMIT;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d",
+ netdev->name, freq->m, freq->e);
+
+ if ((freq->e == 0) && (freq->m <= 1000))
+ /* Setting by channel number */
+ chan = freq->m;
+ else {
+ /* Setting by frequency - search the table */
+ int mult = 1;
+ int i;
+
+ for (i = 0; i < (6 - freq->e); i++)
+ mult *= 10;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ if (freq->m == (channel_frequency[i] * mult))
+ chan = i + 1;
+ }
+ }
+
+ if (chan < 1 || !priv->domain)
+ /* non-positive channels are invalid
+ * we need a domain info to set the channel
+ * either that or an invalid frequency was
+ * provided by the user */
+ ret = -EINVAL;
+ else if (!(priv->domain->channel_map & (1 << (chan - 1)))) {
+ printk(KERN_INFO "%s: channel %d not allowed for domain %s\n",
+ priv->netdev->name, chan, priv->domain->name);
+ ret = -EINVAL;
+ }
+
+ if (ret == -EIWCOMMIT) {
+ priv->channel = chan;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
+ chan);
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ freq->m = priv->channel;
+ freq->e = 0;
+
+ if (priv->channel)
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d",
+ netdev->name, channel_frequency[priv->channel - 1], 6);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
+ priv->channel);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
+
+ if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
+ (*mode != IW_MODE_MONITOR))
+ return -EINVAL;
+
+ priv->iw_mode = *mode;
+ if (priv->iw_mode != IW_MODE_INFRA)
+ priv->pm_mode = AT76_PM_OFF;
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ *mode = priv->iw_mode;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_range(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ /* inspired by atmel.c */
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct iw_range *range = (struct iw_range *)extra;
+ int i;
+
+ data->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ /* TODO: range->throughput = xxxxxx; */
+
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x0000;
+
+ /* this driver doesn't maintain sensitivity information */
+ range->sensitivity = 0;
+
+ range->max_qual.qual = 100;
+ range->max_qual.level = 100;
+ range->max_qual.noise = 0;
+ range->max_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->avg_qual.qual = 50;
+ range->avg_qual.level = 50;
+ range->avg_qual.noise = 0;
+ range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->bitrate[0] = 1000000;
+ range->bitrate[1] = 2000000;
+ range->bitrate[2] = 5500000;
+ range->bitrate[3] = 11000000;
+ range->num_bitrates = 4;
+
+ range->min_rts = 0;
+ range->max_rts = MAX_RTS_THRESHOLD;
+
+ range->min_frag = MIN_FRAG_THRESHOLD;
+ range->max_frag = MAX_FRAG_THRESHOLD;
+
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_ON;
+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R;
+
+ range->encoding_size[0] = WEP_SMALL_KEY_LEN;
+ range->encoding_size[1] = WEP_LARGE_KEY_LEN;
+ range->num_encoding_sizes = 2;
+ range->max_encoding_tokens = WEP_KEYS;
+
+ /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
+ - take this for all (ignore antenna gains) */
+ range->txpower[0] = 15;
+ range->num_txpower = 1;
+ range->txpower_capa = IW_TXPOW_DBM;
+
+ range->we_version_source = WIRELESS_EXT;
+ range->we_version_compiled = WIRELESS_EXT;
+
+ /* same as the values used in atmel.c */
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->r_time_flags = 0;
+ range->min_retry = 1;
+ range->max_retry = 255;
+
+ range->num_channels = NUM_CHANNELS;
+ range->num_frequency = 0;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ /* test if channel map bit is raised */
+ if (priv->domain->channel_map & (0x1 << i)) {
+ range->num_frequency += 1;
+
+ range->freq[i].i = i + 1;
+ range->freq[i].m = channel_frequency[i] * 100000;
+ range->freq[i].e = 1; /* freq * 10^1 */
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_spy(priv->netdev, info,
+ (union iwreq_data *)data, extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
+ chosen any or auto AP preference */
+ if (is_broadcast_ether_addr(ap_addr->sa_data)
+ || is_zero_ether_addr(ap_addr->sa_data))
+ priv->wanted_bssid_valid = 0;
+ else {
+ /* user wants to set a preferred AP address */
+ priv->wanted_bssid_valid = 1;
+ memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
+ }
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ return 0;
+}
+
+static int at76_iw_handler_set_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ if (!netif_running(netdev)) {
+ ret = -ENETDOWN;
+ goto exit;
+ }
+
+ /* jal: we don't allow "iwlist ethX scan" while we are
+ in monitor mode */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* Discard old scan results */
+ if ((jiffies - priv->last_scan) > (20 * HZ))
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ /* Initiate a scan command */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ priv->scan_state = SCAN_IN_PROGRESS;
+
+ at76_quiesce(priv);
+
+ /* Try to do passive or active scan if WE asks as. */
+ if (wrqu->data.length
+ && wrqu->data.length == sizeof(struct iw_scan_req)) {
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+
+ if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
+ priv->scan_mode = SCAN_TYPE_PASSIVE;
+ else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
+ priv->scan_mode = SCAN_TYPE_ACTIVE;
+
+ /* Sanity check values? */
+ if (req->min_channel_time > 0)
+ priv->scan_min_time = req->min_channel_time;
+
+ if (req->max_channel_time > 0)
+ priv->scan_max_time = req->max_channel_time;
+ }
+
+ /* change to scanning state */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+ return ret;
+}
+
+static int at76_iw_handler_get_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *curr_bss;
+ struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
+ char *curr_val, *curr_pos = extra;
+ int i;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
+
+ if (!iwe)
+ return -ENOMEM;
+
+ if (priv->scan_state != SCAN_COMPLETED) {
+ /* scan not yet finished */
+ kfree(iwe);
+ return -EAGAIN;
+ }
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+ curr_bss = list_entry(lptr, struct bss_info, list);
+
+ iwe->cmd = SIOCGIWAP;
+ iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_ADDR_LEN);
+
+ iwe->u.data.length = curr_bss->ssid_len;
+ iwe->cmd = SIOCGIWESSID;
+ iwe->u.data.flags = 1;
+
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ curr_bss->ssid);
+
+ iwe->cmd = SIOCGIWMODE;
+ iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
+ IW_MODE_ADHOC :
+ (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
+ IW_MODE_MASTER : IW_MODE_AUTO;
+ /* IW_MODE_AUTO = 0 which I thought is
+ * the most logical value to return in this case */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_UINT_LEN);
+
+ iwe->cmd = SIOCGIWFREQ;
+ iwe->u.freq.m = curr_bss->channel;
+ iwe->u.freq.e = 0;
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_FREQ_LEN);
+
+ iwe->cmd = SIOCGIWENCODE;
+ if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY)
+ iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe->u.data.flags = IW_ENCODE_DISABLED;
+
+ iwe->u.data.length = 0;
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ NULL);
+
+ /* Add quality statistics */
+ iwe->cmd = IWEVQUAL;
+ iwe->u.qual.noise = 0;
+ iwe->u.qual.updated =
+ IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
+ iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
+ if (iwe->u.qual.level > 100)
+ iwe->u.qual.level = 100;
+ if (at76_is_intersil(priv->board_type))
+ iwe->u.qual.qual = curr_bss->link_qual;
+ else {
+ iwe->u.qual.qual = 0;
+ iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
+ }
+ /* Add new value to event */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_QUAL_LEN);
+
+ /* Rate: stuffing multiple values in a single event requires
+ * a bit more of magic - Jean II */
+ curr_val = curr_pos + IW_EV_LCP_LEN;
+
+ iwe->cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe->u.bitrate.fixed = 0;
+ iwe->u.bitrate.disabled = 0;
+ /* Max 8 values */
+ for (i = 0; i < curr_bss->rates_len; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe->u.bitrate.value =
+ ((curr_bss->rates[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ curr_val = iwe_stream_add_value(info, curr_pos,
+ curr_val,
+ extra +
+ IW_SCAN_MAX_DATA, iwe,
+ IW_EV_PARAM_LEN);
+ }
+
+ /* Check if we added any event */
+ if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
+ curr_pos = curr_val;
+
+ /* more information may be sent back using IWECUSTOM */
+
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ data->length = (curr_pos - extra);
+ data->flags = 0;
+
+ kfree(iwe);
+ return 0;
+}
+
+static int at76_iw_handler_set_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
+
+ if (data->flags) {
+ memcpy(priv->essid, extra, data->length);
+ priv->essid_size = data->length;
+ } else
+ priv->essid_size = 0; /* Use any SSID */
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (priv->essid_size) {
+ /* not the ANY ssid in priv->essid */
+ data->flags = 1;
+ data->length = priv->essid_size;
+ memcpy(extra, priv->essid, data->length);
+ } else {
+ /* the ANY ssid was specified */
+ if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) {
+ /* report the SSID we have found */
+ data->flags = 1;
+ data->length = priv->curr_bss->ssid_len;
+ memcpy(extra, priv->curr_bss->ssid, data->length);
+ } else {
+ /* report ANY back */
+ data->flags = 0;
+ data->length = 0;
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
+ data->length, extra);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ switch (bitrate->value) {
+ case -1:
+ priv->txrate = TX_RATE_AUTO;
+ break; /* auto rate */
+ case 1000000:
+ priv->txrate = TX_RATE_1MBIT;
+ break;
+ case 2000000:
+ priv->txrate = TX_RATE_2MBIT;
+ break;
+ case 5500000:
+ priv->txrate = TX_RATE_5_5MBIT;
+ break;
+ case 11000000:
+ priv->txrate = TX_RATE_11MBIT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ switch (priv->txrate) {
+ /* return max rate if RATE_AUTO */
+ case TX_RATE_AUTO:
+ bitrate->value = 11000000;
+ break;
+ case TX_RATE_1MBIT:
+ bitrate->value = 1000000;
+ break;
+ case TX_RATE_2MBIT:
+ bitrate->value = 2000000;
+ break;
+ case TX_RATE_5_5MBIT:
+ bitrate->value = 5500000;
+ break;
+ case TX_RATE_11MBIT:
+ bitrate->value = 11000000;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
+ bitrate->disabled = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int rthr = rts->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ if (rts->disabled)
+ rthr = MAX_RTS_THRESHOLD;
+
+ if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->rts_threshold = rthr;
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ rts->value = priv->rts_threshold;
+ rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
+ rts->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int fthr = frag->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ if (frag->disabled)
+ fthr = MAX_FRAG_THRESHOLD;
+
+ if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->frag_threshold = fthr & ~0x1; /* get an even value */
+
+ return ret;
+}
+
+static int at76_iw_handler_get_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ frag->value = priv->frag_threshold;
+ frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
+ frag->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_get_txpow(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ power->value = 15;
+ power->fixed = 1; /* No power control */
+ power->disabled = 0;
+ power->flags = IW_TXPOW_DBM;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
+ power->value);
+
+ return 0;
+}
+
+/* jal: short retry is handled by the firmware (at least 0.90.x),
+ while long retry is not (?) */
+static int at76_iw_handler_set_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
+ netdev->name, retry->disabled, retry->flags, retry->value);
+
+ if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
+ if ((retry->flags & IW_RETRY_MIN) ||
+ !(retry->flags & IW_RETRY_MAX))
+ priv->short_retry_limit = retry->value;
+ else
+ ret = -EINVAL;
+ } else
+ ret = -EINVAL;
+
+ return ret;
+}
+
+/* Adapted (ripped) from atmel.c */
+static int at76_iw_handler_get_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
+
+ retry->disabled = 0; /* Can't be disabled */
+ retry->flags = IW_RETRY_LIMIT;
+ retry->value = priv->short_retry_limit;
+
+ return 0;
+}
+
+static int at76_iw_handler_set_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ int len = encoding->length;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
+ "auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id,
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ /* take the old default key if index is invalid */
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ if (len > 0) {
+ if (len > WEP_LARGE_KEY_LEN)
+ len = WEP_LARGE_KEY_LEN;
+
+ memset(priv->wep_keys[index], 0, WEP_KEY_LEN);
+ memcpy(priv->wep_keys[index], extra, len);
+ priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+ priv->wep_enabled = 1;
+ }
+
+ priv->wep_key_id = index;
+ priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
+
+ if (encoding->flags & IW_ENCODE_RESTRICTED)
+ priv->auth_mode = WLAN_AUTH_SHARED_KEY;
+ if (encoding->flags & IW_ENCODE_OPEN)
+ priv->auth_mode = WLAN_AUTH_OPEN;
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ encoding->flags =
+ (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
+ IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
+
+ if (!priv->wep_enabled)
+ encoding->flags |= IW_ENCODE_DISABLED;
+
+ if (encoding->pointer) {
+ encoding->length = priv->wep_keys_len[index];
+
+ memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
+
+ encoding->flags |= (index + 1);
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *prq, char *extra)
+{
+ int err = -EIWCOMMIT;
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x",
+ netdev->name, (prq->disabled) ? "true" : "false", prq->flags,
+ prq->value);
+
+ if (prq->disabled)
+ priv->pm_mode = AT76_PM_OFF;
+ else {
+ switch (prq->flags & IW_POWER_MODE) {
+ case IW_POWER_ALL_R:
+ case IW_POWER_ON:
+ break;
+ default:
+ err = -EINVAL;
+ goto exit;
+ }
+ if (prq->flags & IW_POWER_PERIOD)
+ priv->pm_period = prq->value;
+
+ if (prq->flags & IW_POWER_TIMEOUT) {
+ err = -EINVAL;
+ goto exit;
+ }
+ priv->pm_mode = AT76_PM_ON;
+ }
+exit:
+ return err;
+}
+
+static int at76_iw_handler_get_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ power->disabled = (priv->pm_mode == AT76_PM_OFF);
+ if (!power->disabled) {
+ power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R;
+ power->value = priv->pm_period;
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x",
+ netdev->name, power->disabled ? "disabled" : "enabled",
+ power->flags, power->value);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Private IOCTLS
+ */
+static int at76_iw_set_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
+ netdev->name, val);
+
+ if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
+ ret = -EINVAL;
+ else
+ priv->preamble_type = val;
+
+ return ret;
+}
+
+static int at76_iw_get_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
+ preambles[priv->preamble_type], priv->preamble_type);
+ return 0;
+}
+
+static int at76_iw_set_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ char *ptr;
+ u32 val;
+
+ if (data->length > 0) {
+ val = simple_strtol(extra, &ptr, 0);
+
+ if (ptr == extra)
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x",
+ netdev->name, data->length, extra, val);
+ } else
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
+ netdev->name, at76_debug, val);
+
+ /* jal: some more output to pin down lockups */
+ at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d "
+ "carrier_ok %d", netdev->name, netif_running(netdev),
+ netif_queue_stopped(netdev), netif_carrier_ok(netdev));
+
+ at76_debug = val;
+
+ return 0;
+}
+
+static int at76_iw_get_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
+ return 0;
+}
+
+static int at76_iw_set_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)",
+ netdev->name, val,
+ val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" :
+ val == AT76_PM_SMART ? "smart save" : "<invalid>");
+ if (val < AT76_PM_OFF || val > AT76_PM_SMART)
+ ret = -EINVAL;
+ else
+ priv->pm_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->pm_mode;
+ return 0;
+}
+
+static int at76_iw_set_scan_times(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int mint = *((int *)name);
+ int maxt = *((int *)name + 1);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d",
+ netdev->name, mint, maxt);
+ if (mint <= 0 || maxt <= 0 || mint > maxt)
+ ret = -EINVAL;
+ else {
+ priv->scan_min_time = mint;
+ priv->scan_max_time = maxt;
+ }
+
+ return ret;
+}
+
+static int at76_iw_get_scan_times(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_min_time;
+ param[1] = priv->scan_max_time;
+ return 0;
+}
+
+static int at76_iw_set_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s",
+ netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
+ (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
+
+ if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
+ ret = -EINVAL;
+ else
+ priv->scan_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_mode;
+ return 0;
+}
+
+#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
+
+/* Standard wireless handlers */
+static const iw_handler at76_handlers[] = {
+ AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit),
+ AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name),
+ AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq),
+ AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq),
+ AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode),
+ AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode),
+ AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range),
+ AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy),
+ AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy),
+ AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy),
+ AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy),
+ AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap),
+ AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap),
+ AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan),
+ AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan),
+ AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid),
+ AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid),
+ AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate),
+ AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate),
+ AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts),
+ AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts),
+ AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag),
+ AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag),
+ AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow),
+ AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry),
+ AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry),
+ AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode),
+ AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode),
+ AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power),
+ AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power)
+};
+
+#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
+
+/* Private wireless handlers */
+static const iw_handler at76_priv_handlers[] = {
+ AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble),
+ AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble),
+ AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug),
+ AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug),
+ AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode),
+ AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode),
+ AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times),
+ AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times),
+ AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode),
+ AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode),
+};
+
+/* Names and arguments of private wireless handlers */
+static const struct iw_priv_args at76_priv_args[] = {
+ /* 0 - long, 1 - short */
+ {AT76_SET_SHORT_PREAMBLE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
+
+ {AT76_GET_SHORT_PREAMBLE,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
+
+ /* we must pass the new debug mask as a string, because iwpriv cannot
+ * parse hex numbers starting with 0x :-( */
+ {AT76_SET_DEBUG,
+ IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"},
+
+ {AT76_GET_DEBUG,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
+
+ /* 1 - active, 2 - power save, 3 - smart power save */
+ {AT76_SET_POWERSAVE_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"},
+
+ {AT76_GET_POWERSAVE_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
+
+ /* min_channel_time, max_channel_time */
+ {AT76_SET_SCAN_TIMES,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"},
+
+ {AT76_GET_SCAN_TIMES,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
+
+ /* 0 - active, 1 - passive scan */
+ {AT76_SET_SCAN_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"},
+
+ {AT76_GET_SCAN_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
+};
+
+static const struct iw_handler_def at76_handler_def = {
+ .num_standard = ARRAY_SIZE(at76_handlers),
+ .num_private = ARRAY_SIZE(at76_priv_handlers),
+ .num_private_args = ARRAY_SIZE(at76_priv_args),
+ .standard = at76_handlers,
+ .private = at76_priv_handlers,
+ .private_args = at76_priv_args,
+ .get_wireless_stats = at76_get_wireless_stats,
+};
+
+static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
+
+/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
+ * a SNAP OID of 0 (0x00, 0x00, 0x00) */
+static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
+static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct net_device_stats *stats = &priv->stats;
+ int ret = 0;
+ int wlen;
+ int submit_len;
+ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)tx_buffer->packet;
+ u8 *payload = i802_11_hdr->payload;
+ struct ethhdr *eh = (struct ethhdr *)skb->data;
+
+ if (netif_queue_stopped(netdev)) {
+ printk(KERN_ERR "%s: %s called while netdev is stopped\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (priv->tx_urb->status == -EINPROGRESS) {
+ printk(KERN_ERR "%s: %s called while tx urb is pending\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (skb->len < ETH_HLEN) {
+ printk(KERN_ERR "%s: %s: skb too short (%d)\n",
+ netdev->name, __func__, skb->len);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+
+ /* we can get rid of memcpy if we set netdev->hard_header_len to
+ reserve enough space, but we would need to keep the skb around */
+
+ if (ntohs(eh->h_proto) <= ETH_DATA_LEN) {
+ /* this is a 802.3 packet */
+ if (skb->len >= ETH_HLEN + sizeof(rfc1042sig)
+ && skb->data[ETH_HLEN] == rfc1042sig[0]
+ && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) {
+ /* higher layer delivered SNAP header - keep it */
+ memcpy(payload, skb->data + ETH_HLEN,
+ skb->len - ETH_HLEN);
+ wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN;
+ } else {
+ printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet "
+ "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n",
+ priv->netdev->name, skb->data[ETH_HLEN],
+ skb->data[ETH_HLEN + 1],
+ skb->data[ETH_HLEN + 2]);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ } else {
+ /* add RFC 1042 header in front */
+ memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
+ memcpy(payload + sizeof(rfc1042sig), &eh->h_proto,
+ skb->len - offsetof(struct ethhdr, h_proto));
+ wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len -
+ offsetof(struct ethhdr, h_proto);
+ }
+
+ /* make wireless header */
+ i802_11_hdr->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_DATA |
+ (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
+ (priv->iw_mode ==
+ IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
+
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN);
+ } else if (priv->iw_mode == IW_MODE_INFRA) {
+ memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN);
+ }
+
+ i802_11_hdr->duration_id = cpu_to_le16(0);
+ i802_11_hdr->seq_ctl = cpu_to_le16(0);
+
+ /* setup 'Atmel' header */
+ tx_buffer->wlength = cpu_to_le16(wlen);
+ tx_buffer->tx_rate = priv->txrate;
+ /* for broadcast destination addresses, the firmware 0.100.x
+ seems to choose the highest rate set with CMD_STARTUP in
+ basic_rate_set replacing this value */
+
+ memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
+
+ tx_buffer->padding = at76_calc_padding(wlen);
+ submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding;
+
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name,
+ hex2str(skb->data, 32));
+ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s",
+ priv->netdev->name,
+ le16_to_cpu(tx_buffer->wlength),
+ tx_buffer->padding, tx_buffer->tx_rate,
+ hex2str(i802_11_hdr, sizeof(*i802_11_hdr)));
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name,
+ hex2str(payload, 48));
+
+ /* send stuff */
+ netif_stop_queue(netdev);
+ netdev->trans_start = jiffies;
+
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
+ submit_len, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret) {
+ stats->tx_errors++;
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ netdev->name, ret);
+ if (ret == -EINVAL)
+ printk(KERN_ERR
+ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
+ priv->netdev->name, priv->tx_urb,
+ priv->tx_urb->hcpriv, priv->tx_urb->complete);
+ } else {
+ stats->tx_bytes += skb->len;
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
+static void at76_tx_timeout(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (!priv)
+ return;
+ dev_warn(&netdev->dev, "tx timeout.");
+
+ usb_unlink_urb(priv->tx_urb);
+ priv->stats.tx_errors++;
+}
+
static int at76_submit_rx_urb(struct at76_priv *priv)
{
int ret;
@@ -1327,7 +3270,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
if (!priv->rx_urb) {
printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
- wiphy_name(priv->hw->wiphy), __func__);
+ priv->netdev->name, __func__);
return -EFAULT;
}
@@ -1335,7 +3278,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
if (!skb) {
printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
- wiphy_name(priv->hw->wiphy));
+ priv->netdev->name);
ret = -ENOMEM;
goto exit;
}
@@ -1355,18 +3298,110 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
"usb_submit_urb returned -ENODEV");
else
printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
}
exit:
if (ret < 0 && ret != -ENODEV)
printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
"driver and/or power cycle the device\n",
- wiphy_name(priv->hw->wiphy));
+ priv->netdev->name);
return ret;
}
+static int at76_open(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ /* if netdev->dev_addr != priv->mac_addr we must
+ set the mac address in the device ! */
+ if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) {
+ if (at76_add_mac_address(priv, netdev->dev_addr) >= 0)
+ at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
+ netdev->name, mac2str(netdev->dev_addr));
+ }
+
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ ret = at76_submit_rx_urb(priv);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
+ netdev->name, ret);
+ goto error;
+ }
+
+ schedule_delayed_work(&priv->dwork_restart, 0);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__);
+error:
+ mutex_unlock(&priv->mtx);
+ return ret < 0 ? ret : 0;
+}
+
+static int at76_stop(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ at76_quiesce(priv);
+
+ if (!priv->device_unplugged) {
+ /* We are called by "ifconfig ethX down", not because the
+ * device is not available anymore. */
+ at76_set_radio(priv, 0);
+
+ /* We unlink rx_urb because at76_open() re-submits it.
+ * If unplugged, at76_delete_device() takes care of it. */
+ usb_kill_urb(priv->rx_urb);
+ }
+
+ /* free the bss_list */
+ at76_free_bss_list(priv);
+
+ mutex_unlock(&priv->mtx);
+ at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__);
+
+ return 0;
+}
+
+static void at76_ethtool_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *info)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
+
+ usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info));
+
+ snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d",
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+}
+
+static u32 at76_ethtool_get_link(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return priv->mac_state == MAC_CONNECTED;
+}
+
+static struct ethtool_ops at76_ethtool_ops = {
+ .get_drvinfo = at76_ethtool_get_drvinfo,
+ .get_link = at76_ethtool_get_link,
+};
+
/* Download external firmware */
static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
{
@@ -1463,6 +3498,406 @@ exit:
return ret;
}
+static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ /* common criteria for both modi */
+
+ int ret = (priv->essid_size == 0 /* ANY ssid */ ||
+ (priv->essid_size == ptr->ssid_len &&
+ !memcmp(priv->essid, ptr->ssid, ptr->ssid_len)));
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: essid didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int ret;
+
+ if (priv->iw_mode == IW_MODE_ADHOC)
+ ret = ptr->capa & WLAN_CAPABILITY_IBSS;
+ else
+ ret = ptr->capa & WLAN_CAPABILITY_ESS;
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: mode didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int i;
+
+ for (i = 0; i < ptr->rates_len; i++) {
+ u8 rate = ptr->rates[i];
+
+ if (!(rate & 0x80))
+ continue;
+
+ /* this is a basic rate we have to support
+ (see IEEE802.11, ch. 7.3.2.2) */
+ if (rate != (0x80 | hw_rates[0])
+ && rate != (0x80 | hw_rates[1])
+ && rate != (0x80 | hw_rates[2])
+ && rate != (0x80 | hw_rates[3])) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: basic rate %02x not "
+ "supported", priv->netdev->name, ptr, rate);
+ return 0;
+ }
+ }
+
+ /* if we use short preamble, the bss must support it */
+ if (priv->preamble_type == PREAMBLE_TYPE_SHORT &&
+ !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: %p does not support short preamble",
+ priv->netdev->name, ptr);
+ return 0;
+ } else
+ return 1;
+}
+
+static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) {
+ /* we have disabled WEP, but the BSS signals privacy */
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: requires encryption",
+ priv->netdev->name, ptr);
+ return 0;
+ }
+ /* otherwise if the BSS does not signal privacy it may well
+ accept encrypted packets from us ... */
+ return 1;
+}
+
+static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wanted_bssid_valid ||
+ !compare_ether_addr(ptr->bssid, priv->wanted_bssid))
+ return 1;
+
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: requested bssid - %s does not match",
+ priv->netdev->name, mac2str(priv->wanted_bssid));
+ at76_dbg(DBG_BSS_MATCH,
+ " AP bssid - %s of bss table entry %p",
+ mac2str(ptr->bssid), ptr);
+ return 0;
+}
+
+/**
+ * at76_match_bss - try to find a matching bss in priv->bss
+ *
+ * last - last bss tried
+ *
+ * last == NULL signals a new round starting with priv->bss_list.next
+ * this function must be called inside an acquired priv->bss_list_spinlock
+ * otherwise the timeout on bss may remove the newly chosen entry
+ */
+static struct bss_info *at76_match_bss(struct at76_priv *priv,
+ struct bss_info *last)
+{
+ struct bss_info *ptr = NULL;
+ struct list_head *curr;
+
+ curr = last ? last->list.next : priv->bss_list.next;
+ while (curr != &priv->bss_list) {
+ ptr = list_entry(curr, struct bss_info, list);
+ if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr)
+ && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr)
+ && at76_match_bssid(priv, ptr))
+ break;
+ curr = curr->next;
+ }
+
+ if (curr == &priv->bss_list)
+ ptr = NULL;
+ /* otherwise ptr points to the struct bss_info we have chosen */
+
+ at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name,
+ __func__, ptr);
+ return ptr;
+}
+
+/* Start joining a matching BSS, or create own IBSS */
+static void at76_work_join(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_join);
+ int ret;
+ unsigned long flags;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_JOINING);
+ if (priv->mac_state != MAC_JOINING)
+ goto exit;
+
+ /* secure the access to priv->curr_bss ! */
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ priv->curr_bss = at76_match_bss(priv, priv->curr_bss);
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ if (!priv->curr_bss) {
+ /* here we haven't found a matching (i)bss ... */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ at76_set_mac_state(priv, MAC_OWN_IBSS);
+ at76_start_ibss(priv);
+ goto exit;
+ }
+ /* haven't found a matching BSS in infra mode - try again */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ goto exit;
+ }
+
+ ret = at76_join_bss(priv, priv->curr_bss);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: join_bss failed with %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ ret = at76_wait_completion(priv, CMD_JOIN);
+ if (ret != CMD_STATUS_COMPLETE) {
+ if (ret != CMD_STATUS_TIME_OUT)
+ printk(KERN_ERR "%s: join_bss completed with %d\n",
+ priv->netdev->name, ret);
+ else
+ printk(KERN_INFO "%s: join_bss ssid %s timed out\n",
+ priv->netdev->name,
+ mac2str(priv->curr_bss->bssid));
+
+ /* retry next BSS immediately */
+ schedule_work(&priv->work_join);
+ goto exit;
+ }
+
+ /* here we have joined the (I)BSS */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ struct bss_info *bptr = priv->curr_bss;
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ /* get ESSID, BSSID and channel for priv->curr_bss */
+ priv->essid_size = bptr->ssid_len;
+ memcpy(priv->essid, bptr->ssid, bptr->ssid_len);
+ memcpy(priv->bssid, bptr->bssid, ETH_ALEN);
+ priv->channel = bptr->channel;
+ at76_iwevent_bss_connect(priv->netdev, bptr->bssid);
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ /* just to be sure */
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ } else {
+ /* send auth req */
+ priv->retries = AUTH_RETRIES;
+ at76_set_mac_state(priv, MAC_AUTH);
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Reap scan results */
+static void at76_dwork_get_scan(struct work_struct *work)
+{
+ int status;
+ int ret;
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_get_scan.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ status = at76_get_cmd_status(priv->udev, CMD_SCAN);
+ if (status < 0) {
+ printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n",
+ priv->netdev->name, __func__, status);
+ status = CMD_STATUS_IN_PROGRESS;
+ /* INFO: Hope it was a one off error - if not, scanning
+ further down the line and stop this cycle */
+ }
+ at76_dbg(DBG_PROGRESS,
+ "%s %s: got cmd_status %d (state %s, need_any %d)",
+ priv->netdev->name, __func__, status,
+ mac_states[priv->mac_state], priv->scan_need_any);
+
+ if (status != CMD_STATUS_COMPLETE) {
+ if ((status != CMD_STATUS_IN_PROGRESS) &&
+ (status != CMD_STATUS_IDLE))
+ printk(KERN_ERR "%s: %s: Bad scan status: %s\n",
+ priv->netdev->name, __func__,
+ at76_get_cmd_status_string(status));
+
+ /* the first cmd status after scan start is always a IDLE ->
+ start the timer to poll again until COMPLETED */
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ goto exit;
+ }
+
+ if (at76_debug & DBG_BSS_TABLE)
+ at76_dump_bss_table(priv);
+
+ if (priv->scan_need_any) {
+ ret = at76_start_scan(priv, 0);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: %s: start_scan (ANY) failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks", __func__,
+ __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ priv->scan_need_any = 0;
+ } else {
+ priv->scan_state = SCAN_COMPLETED;
+ /* report the end of scan to user space */
+ at76_iwevent_scan_complete(priv->netdev);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle loss of beacons from the AP */
+static void at76_dwork_beacon(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_beacon.work);
+
+ mutex_lock(&priv->mtx);
+ if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA)
+ goto exit;
+
+ /* We haven't received any beacons from out AP for BEACON_TIMEOUT */
+ printk(KERN_INFO "%s: lost beacon bssid %s\n",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle authentication response timeout */
+static void at76_dwork_auth(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_auth.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_AUTH);
+ if (priv->mac_state != MAC_AUTH)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: authentication response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle association response timeout */
+static void at76_dwork_assoc(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_assoc.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ if (priv->mac_state != MAC_ASSOC)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: association response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Read new bssid in ad-hoc mode */
+static void at76_work_new_bss(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_new_bss);
+ int ret;
+ struct mib_mac_mgmt mac_mgmt;
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change);
+ memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN);
+ at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid));
+
+ at76_iwevent_bss_connect(priv->netdev, priv->bssid);
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
static int at76_startup_device(struct at76_priv *priv)
{
struct at76_card_config *ccfg = &priv->card_config;
@@ -1470,14 +3905,14 @@ static int at76_startup_device(struct at76_priv *priv)
at76_dbg(DBG_PARAMS,
"%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
- "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
- priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
+ "keylen %d", priv->netdev->name, priv->essid_size, priv->essid,
+ hex2str(priv->essid, IW_ESSID_MAX_SIZE),
priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
priv->channel, priv->wep_enabled ? "enabled" : "disabled",
priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
at76_dbg(DBG_PARAMS,
"%s param: preamble %s rts %d retry %d frag %d "
- "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy),
+ "txrate %s auth_mode %d", priv->netdev->name,
preambles[priv->preamble_type], priv->rts_threshold,
priv->short_retry_limit, priv->frag_threshold,
priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
@@ -1488,7 +3923,7 @@ static int at76_startup_device(struct at76_priv *priv)
at76_dbg(DBG_PARAMS,
"%s param: pm_mode %d pm_period %d auth_mode %s "
"scan_times %d %d scan_mode %s",
- wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period,
+ priv->netdev->name, priv->pm_mode, priv->pm_period,
priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
priv->scan_min_time, priv->scan_max_time,
priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
@@ -1522,8 +3957,7 @@ static int at76_startup_device(struct at76_priv *priv)
ccfg->ssid_len = priv->essid_size;
ccfg->wep_default_key_id = priv->wep_key_id;
- memcpy(ccfg->wep_default_key_value, priv->wep_keys,
- sizeof(priv->wep_keys));
+ memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN);
ccfg->short_preamble = priv->preamble_type;
ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
@@ -1532,7 +3966,7 @@ static int at76_startup_device(struct at76_priv *priv)
sizeof(struct at76_card_config));
if (ret < 0) {
printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -1578,6 +4012,69 @@ static int at76_startup_device(struct at76_priv *priv)
return 0;
}
+/* Restart the interface */
+static void at76_dwork_restart(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_restart.work);
+
+ mutex_lock(&priv->mtx);
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ at76_startup_device(priv);
+
+ if (priv->iw_mode != IW_MODE_MONITOR) {
+ priv->netdev->type = ARPHRD_ETHER;
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ } else {
+ priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
+ at76_start_monitor(priv);
+ }
+
+ mutex_unlock(&priv->mtx);
+}
+
+/* Initiate scanning */
+static void at76_work_start_scan(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_start_scan);
+ int ret;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ /* only clear the bss list when a scan is actively initiated,
+ * otherwise simply rely on at76_bss_list_timeout */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ at76_free_bss_list(priv);
+ priv->scan_need_any = 1;
+ } else
+ priv->scan_need_any = 0;
+
+ ret = at76_start_scan(priv, 1);
+
+ if (ret < 0)
+ printk(KERN_ERR "%s: %s: start_scan failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ else {
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
/* Enable or disable promiscuous mode */
static void at76_work_set_promisc(struct work_struct *work)
{
@@ -1595,7 +4092,7 @@ static void at76_work_set_promisc(struct work_struct *work)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
mutex_unlock(&priv->mtx);
}
@@ -1611,759 +4108,1088 @@ static void at76_work_submit_rx(struct work_struct *work)
mutex_unlock(&priv->mtx);
}
-static void at76_rx_tasklet(unsigned long param)
+/* We got an association response */
+static void at76_rx_mgmt_assoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct urb *urb = (struct urb *)param;
- struct at76_priv *priv = urb->context;
- struct at76_rx_buffer *buf;
- struct ieee80211_rx_status rx_status = { 0 };
-
- if (priv->device_unplugged) {
- at76_dbg(DBG_DEVSTART, "device unplugged");
- if (urb)
- at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ struct ieee80211_assoc_response *resp =
+ (struct ieee80211_assoc_response *)buf->packet;
+ u16 assoc_id = le16_to_cpu(resp->aid);
+ u16 status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status "
+ "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name,
+ mac2str(resp->header.addr3), le16_to_cpu(resp->capability),
+ status, assoc_id, hex2str(resp->info_element->data,
+ resp->info_element->len));
+
+ if (priv->mac_state != MAC_ASSOC) {
+ printk(KERN_INFO "%s: AssocResp in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
return;
}
- if (!priv->rx_skb || !priv->rx_skb->data)
- return;
-
- buf = (struct at76_rx_buffer *)priv->rx_skb->data;
-
- if (urb->status != 0) {
- if (urb->status != -ENOENT && urb->status != -ECONNRESET)
- at76_dbg(DBG_URB,
- "%s %s: - nonzero Rx bulk status received: %d",
- __func__, wiphy_name(priv->hw->wiphy),
- urb->status);
- return;
+ BUG_ON(!priv->curr_bss);
+
+ cancel_delayed_work(&priv->dwork_assoc);
+ if (status == WLAN_STATUS_SUCCESS) {
+ struct bss_info *ptr = priv->curr_bss;
+ priv->assoc_id = assoc_id & 0x3fff;
+ /* update iwconfig params */
+ memcpy(priv->bssid, ptr->bssid, ETH_ALEN);
+ memcpy(priv->essid, ptr->ssid, ptr->ssid_len);
+ priv->essid_size = ptr->ssid_len;
+ priv->channel = ptr->channel;
+ schedule_work(&priv->work_assoc_done);
+ } else {
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
}
+}
- at76_dbg(DBG_RX_ATMEL_HDR,
- "%s: rx frame: rate %d rssi %d noise %d link %d",
- wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi,
- buf->noise_level, buf->link_quality);
-
- skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength) + AT76_RX_HDRLEN);
- at76_dbg_dump(DBG_RX_DATA, &priv->rx_skb->data[AT76_RX_HDRLEN],
- priv->rx_skb->len, "RX: len=%d",
- (int)(priv->rx_skb->len - AT76_RX_HDRLEN));
+/* Process disassociation request from the AP */
+static void at76_rx_mgmt_disassoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx DisAssoc bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ /* We are not connected, ignore */
+ if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT
+ || !priv->curr_bss)
+ return;
- rx_status.signal = buf->rssi;
- /* FIXME: is rate_idx still present in structure? */
- rx_status.rate_idx = buf->rx_rate;
- rx_status.flag |= RX_FLAG_DECRYPTED;
- rx_status.flag |= RX_FLAG_IV_STRIPPED;
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
- skb_pull(priv->rx_skb, AT76_RX_HDRLEN);
- at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
- priv->rx_skb->len, priv->rx_skb->data_len);
- ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
- /* Use a new skb for the next receive */
- priv->rx_skb = NULL;
+ if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED
+ && priv->mac_state != MAC_JOINING) {
+ printk(KERN_INFO "%s: DisAssoc in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
- at76_submit_rx_urb(priv);
+ if (priv->mac_state == MAC_CONNECTED) {
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ }
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
}
-/* Load firmware into kernel memory and parse it */
-static struct fwentry *at76_load_firmware(struct usb_device *udev,
- enum board_type board_type)
+static void at76_rx_mgmt_auth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- int ret;
- char *str;
- struct at76_fw_header *fwh;
- struct fwentry *fwe = &firmwares[board_type];
-
- mutex_lock(&fw_mutex);
-
- if (fwe->loaded) {
- at76_dbg(DBG_FW, "re-using previously loaded fw");
- goto exit;
+ struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+ int seq_nr = le16_to_cpu(resp->transaction);
+ int alg = le16_to_cpu(resp->algorithm);
+ int status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
+ "destination %s", priv->netdev->name, mac2str(mgmt->addr3),
+ alg, seq_nr, status, mac2str(mgmt->addr1));
+
+ if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2)
+ at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
+ priv->netdev->name, hex2str(resp->info_element, 18));
+
+ if (priv->mac_state != MAC_AUTH) {
+ printk(KERN_INFO "%s: ignored AuthFrame in state %s\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
}
-
- at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
- ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
- if (ret < 0) {
- dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
- fwe->fwname);
- dev_printk(KERN_ERR, &udev->dev,
- "you may need to download the firmware from "
- "http://developer.berlios.de/projects/at76c503a/\n");
- goto exit;
+ if (priv->auth_mode != alg) {
+ printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n",
+ priv->netdev->name, alg);
+ return;
}
- at76_dbg(DBG_FW, "got it.");
- fwh = (struct at76_fw_header *)(fwe->fw->data);
+ BUG_ON(!priv->curr_bss);
- if (fwe->fw->size <= sizeof(*fwh)) {
- dev_printk(KERN_ERR, &udev->dev,
- "firmware is too short (0x%zx)\n", fwe->fw->size);
- goto exit;
+ /* Not our BSSID or not for our STA, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)
+ || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1))
+ return;
+
+ cancel_delayed_work(&priv->dwork_auth);
+ if (status != WLAN_STATUS_SUCCESS) {
+ /* try to join next bss */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ return;
}
- /* CRC currently not checked */
- fwe->board_type = le32_to_cpu(fwh->board_type);
- if (fwe->board_type != board_type) {
- dev_printk(KERN_ERR, &udev->dev,
- "board type mismatch, requested %u, got %u\n",
- board_type, fwe->board_type);
- goto exit;
+ if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) {
+ priv->retries = ASSOC_RETRIES;
+ at76_set_mac_state(priv, MAC_ASSOC);
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ return;
}
- fwe->fw_version.major = fwh->major;
- fwe->fw_version.minor = fwh->minor;
- fwe->fw_version.patch = fwh->patch;
- fwe->fw_version.build = fwh->build;
+ WARN_ON(seq_nr != 2);
+ at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__,
+ __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+}
- str = (char *)fwh + le32_to_cpu(fwh->str_offset);
- fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
- fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
- fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
- fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
+static void at76_rx_mgmt_deauth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT | DBG_PROGRESS,
+ "%s: rx DeAuth bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC
+ && priv->mac_state != MAC_CONNECTED) {
+ printk(KERN_INFO "%s: DeAuth in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
- fwe->loaded = 1;
+ BUG_ON(!priv->curr_bss);
- dev_printk(KERN_DEBUG, &udev->dev,
- "using firmware %s (version %d.%d.%d-%d)\n",
- fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
- at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
- le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
- le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
- at76_dbg(DBG_DEVSTART, "firmware id %s", str);
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
-exit:
- mutex_unlock(&fw_mutex);
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
- if (fwe->loaded)
- return fwe;
- else
- return NULL;
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
}
-static void at76_mac80211_tx_callback(struct urb *urb)
+static void at76_rx_mgmt_beacon(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = urb->context;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
+ int varpar_len;
+ /* beacon content */
+ struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &bdata->header;
+
+ struct list_head *lptr;
+ struct bss_info *match; /* entry matching addr3 with its bssid */
+ int new_entry = 0;
+ int len;
+ struct ieee80211_info_element *ie;
+ int have_ssid = 0;
+ int have_rates = 0;
+ int have_channel = 0;
+ int keep_going = 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ if (priv->mac_state == MAC_CONNECTED) {
+ /* in state MAC_CONNECTED we use the mgmt_timer to control
+ the beacon of the BSS */
+ BUG_ON(!priv->curr_bss);
+
+ if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) {
+ /* We got our AP's beacon, defer the timeout handler.
+ Kill pending work first, as schedule_delayed_work()
+ won't do it. */
+ cancel_delayed_work(&priv->dwork_beacon);
+ schedule_delayed_work(&priv->dwork_beacon,
+ BEACON_TIMEOUT);
+ priv->curr_bss->rssi = buf->rssi;
+ priv->beacons_received++;
+ goto exit;
+ }
+ }
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ /* look if we have this BSS already in the list */
+ match = NULL;
- switch (urb->status) {
- case 0:
- /* success */
- /* FIXME:
- * is the frame really ACKed when tx_callback is called ? */
- info->flags |= IEEE80211_TX_STAT_ACK;
- break;
- case -ENOENT:
- case -ECONNRESET:
- /* fail, urb has been unlinked */
- /* FIXME: add error message */
- break;
- default:
- at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
- __func__, urb->status);
- break;
+ if (!list_empty(&priv->bss_list)) {
+ list_for_each(lptr, &priv->bss_list) {
+ struct bss_info *bss_ptr =
+ list_entry(lptr, struct bss_info, list);
+ if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) {
+ match = bss_ptr;
+ break;
+ }
+ }
}
- memset(&info->status, 0, sizeof(info->status));
+ if (!match) {
+ /* BSS not in the list - append it */
+ match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC);
+ if (!match) {
+ at76_dbg(DBG_BSS_TABLE,
+ "%s: cannot kmalloc new bss info (%zd byte)",
+ priv->netdev->name, sizeof(struct bss_info));
+ goto exit;
+ }
+ new_entry = 1;
+ list_add_tail(&match->list, &priv->bss_list);
+ }
- ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+ match->capa = le16_to_cpu(bdata->capability);
+ match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
+ match->rssi = buf->rssi;
+ match->link_qual = buf->link_quality;
+ match->noise_level = buf->noise_level;
+ memcpy(match->bssid, mgmt->addr3, ETH_ALEN);
+ at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name,
+ mac2str(match->bssid));
+
+ ie = bdata->info_element;
+
+ /* length of var length beacon parameters */
+ varpar_len = min_t(int, le16_to_cpu(buf->wlength) -
+ sizeof(struct ieee80211_beacon),
+ BEACON_MAX_DATA_LENGTH);
+
+ /* This routine steps through the bdata->data array to get
+ * some useful information about the access point.
+ * Currently, this implementation supports receipt of: SSID,
+ * supported transfer rates and channel, in any order, with some
+ * tolerance for intermittent unknown codes (although this
+ * functionality may not be necessary as the useful information will
+ * usually arrive in consecutively, but there have been some
+ * reports of some of the useful information fields arriving in a
+ * different order).
+ * It does not support any more IE types although MFIE_TYPE_TIM may
+ * be supported (on my AP at least).
+ * The bdata->data array is about 1500 bytes long but only ~36 of those
+ * bytes are useful, hence the have_ssid etc optimizations. */
+
+ while (keep_going &&
+ ((&ie->data[ie->len] - (u8 *)bdata->info_element) <=
+ varpar_len)) {
+
+ switch (ie->id) {
+
+ case MFIE_TYPE_SSID:
+ if (have_ssid)
+ break;
- priv->tx_skb = NULL;
+ len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
- ieee80211_wake_queues(priv->hw);
-}
+ /* we copy only if this is a new entry,
+ or the incoming SSID is not a hidden SSID. This
+ will protect us from overwriting a real SSID read
+ in a ProbeResponse with a hidden one from a
+ following beacon. */
+ if (!new_entry && at76_is_hidden_ssid(ie->data, len)) {
+ have_ssid = 1;
+ break;
+ }
-static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct at76_priv *priv = hw->priv;
- struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- int padding, submit_len, ret;
+ match->ssid_len = len;
+ memcpy(match->ssid, ie->data, len);
+ at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s",
+ priv->netdev->name, len, match->ssid);
+ have_ssid = 1;
+ break;
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ case MFIE_TYPE_RATES:
+ if (have_rates)
+ break;
- if (priv->tx_urb->status == -EINPROGRESS) {
- printk(KERN_ERR "%s: %s called while tx urb is pending\n",
- wiphy_name(priv->hw->wiphy), __func__);
- return NETDEV_TX_BUSY;
- }
+ match->rates_len =
+ min_t(int, sizeof(match->rates), ie->len);
+ memcpy(match->rates, ie->data, match->rates_len);
+ have_rates = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s",
+ priv->netdev->name,
+ hex2str(ie->data, ie->len));
+ break;
- ieee80211_stop_queues(hw);
+ case MFIE_TYPE_DS_SET:
+ if (have_channel)
+ break;
- at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+ match->channel = ie->data[0];
+ have_channel = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
+ priv->netdev->name, match->channel);
+ break;
- WARN_ON(priv->tx_skb != NULL);
+ case MFIE_TYPE_CF_SET:
+ case MFIE_TYPE_TIM:
+ case MFIE_TYPE_IBSS_SET:
+ default:
+ at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
+ priv->netdev->name, ie->id, ie->len,
+ hex2str(ie->data, ie->len));
+ break;
+ }
- priv->tx_skb = skb;
- padding = at76_calc_padding(skb->len);
- submit_len = AT76_TX_HDRLEN + skb->len + padding;
+ /* advance to the next informational element */
+ next_ie(&ie);
- /* setup 'Atmel' header */
- memset(tx_buffer, 0, sizeof(*tx_buffer));
- tx_buffer->padding = padding;
- tx_buffer->wlength = cpu_to_le16(skb->len);
- tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value;
- if (FIRMWARE_IS_WPA(priv->fw_version) && info->control.hw_key) {
- tx_buffer->key_id = (info->control.hw_key->keyidx);
- tx_buffer->cipher_type =
- priv->keys[info->control.hw_key->keyidx].cipher;
- tx_buffer->cipher_length =
- priv->keys[info->control.hw_key->keyidx].keylen;
- tx_buffer->reserved = 0;
- } else {
- tx_buffer->key_id = 0;
- tx_buffer->cipher_type = 0;
- tx_buffer->cipher_length = 0;
- tx_buffer->reserved = 0;
- };
- /* memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); */
- memcpy(tx_buffer->packet, skb->data, skb->len);
+ /* Optimization: after all, the bdata->data array is
+ * varpar_len bytes long, whereas we get all of the useful
+ * information after only ~36 bytes, this saves us a lot of
+ * time (and trouble as the remaining portion of the array
+ * could be full of junk)
+ * Comment this out if you want to see what other information
+ * comes from the AP - although little of it may be useful */
+ }
- at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr",
- wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength),
- tx_buffer->padding, tx_buffer->tx_rate);
+ at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
+ priv->netdev->name);
- /* send stuff */
- at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len,
- "%s(): tx_buffer %d bytes:", __func__, submit_len);
- usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
- submit_len, at76_mac80211_tx_callback, priv);
- ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
- if (ret) {
- printk(KERN_ERR "%s: error in tx submit urb: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- if (ret == -EINVAL)
- printk(KERN_ERR
- "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
- wiphy_name(priv->hw->wiphy), priv->tx_urb,
- priv->tx_urb->hcpriv, priv->tx_urb->complete);
- }
+ match->last_rx = jiffies; /* record last rx of beacon */
- return 0;
+exit:
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
}
-static int at76_mac80211_start(struct ieee80211_hw *hw)
+/* Calculate the link level from a given rx_buffer */
+static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
{
- struct at76_priv *priv = hw->priv;
- int ret;
-
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ /* just a guess for now, might be different for other chips */
+ int max_rssi = 42;
- mutex_lock(&priv->mtx);
-
- ret = at76_submit_rx_urb(priv);
- if (ret < 0) {
- printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- goto error;
- }
+ qual->level = (buf->rssi * 100 / max_rssi);
+ if (qual->level > 100)
+ qual->level = 100;
+ qual->updated |= IW_QUAL_LEVEL_UPDATED;
+}
- at76_startup_device(priv);
+/* Calculate the link quality from a given rx_buffer */
+static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
+{
+ if (at76_is_intersil(priv->board_type))
+ qual->qual = buf->link_quality;
+ else {
+ unsigned long elapsed;
- at76_start_monitor(priv);
+ /* Update qual at most once a second */
+ elapsed = jiffies - priv->beacons_last_qual;
+ if (elapsed < 1 * HZ)
+ return;
-error:
- mutex_unlock(&priv->mtx);
+ qual->qual = qual->level * priv->beacons_received *
+ msecs_to_jiffies(priv->beacon_period) / elapsed;
- return 0;
+ priv->beacons_last_qual = jiffies;
+ priv->beacons_received = 0;
+ }
+ qual->qual = (qual->qual > 100) ? 100 : qual->qual;
+ qual->updated |= IW_QUAL_QUAL_UPDATED;
}
-static void at76_mac80211_stop(struct ieee80211_hw *hw)
+/* Calculate the noise quality from a given rx_buffer */
+static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
{
- struct at76_priv *priv = hw->priv;
-
- at76_dbg(DBG_MAC80211, "%s()", __func__);
-
- mutex_lock(&priv->mtx);
+ qual->noise = 0;
+ qual->updated |= IW_QUAL_NOISE_INVALID;
+}
- if (!priv->device_unplugged) {
- /* We are called by "ifconfig ethX down", not because the
- * device is not available anymore. */
- if (at76_set_radio(priv, 0) == 1)
- at76_wait_completion(priv, CMD_RADIO_ON);
+static void at76_update_wstats(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct iw_quality *qual = &priv->wstats.qual;
- /* We unlink rx_urb because at76_open() re-submits it.
- * If unplugged, at76_delete_device() takes care of it. */
- usb_kill_urb(priv->rx_urb);
+ if (buf->rssi && priv->mac_state == MAC_CONNECTED) {
+ qual->updated = 0;
+ at76_calc_level(priv, buf, qual);
+ at76_calc_qual(priv, buf, qual);
+ at76_calc_noise(priv, buf, qual);
+ } else {
+ qual->qual = 0;
+ qual->level = 0;
+ qual->noise = 0;
+ qual->updated = IW_QUAL_ALL_INVALID;
}
-
- mutex_unlock(&priv->mtx);
}
-static int at76_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
+static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = hw->priv;
- int ret = 0;
+ struct ieee80211_hdr_3addr *mgmt =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ u16 framectl = le16_to_cpu(mgmt->frame_ctl);
+
+ /* update wstats */
+ if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) {
+ /* jal: this is a dirty hack needed by Tim in ad-hoc mode */
+ /* Data packets always seem to have a 0 link level, so we
+ only read link quality info from management packets.
+ Atmel driver actually averages the present, and previous
+ values, we just present the raw value at the moment - TJS */
+ if (priv->iw_mode == IW_MODE_ADHOC
+ || (priv->curr_bss
+ && !compare_ether_addr(mgmt->addr3,
+ priv->curr_bss->bssid)))
+ at76_update_wstats(priv, buf);
+ }
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s",
+ priv->netdev->name, framectl,
+ hex2str(mgmt, le16_to_cpu(buf->wlength)));
- mutex_lock(&priv->mtx);
+ switch (framectl & IEEE80211_FCTL_STYPE) {
+ case IEEE80211_STYPE_BEACON:
+ case IEEE80211_STYPE_PROBE_RESP:
+ at76_rx_mgmt_beacon(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_ASSOC_RESP:
+ at76_rx_mgmt_assoc(priv, buf);
+ break;
- switch (conf->type) {
- case NL80211_IFTYPE_STATION:
- priv->iw_mode = IW_MODE_INFRA;
+ case IEEE80211_STYPE_DISASSOC:
+ at76_rx_mgmt_disassoc(priv, buf);
break;
+
+ case IEEE80211_STYPE_AUTH:
+ at76_rx_mgmt_auth(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_DEAUTH:
+ at76_rx_mgmt_deauth(priv, buf);
+ break;
+
default:
- ret = -EOPNOTSUPP;
- goto exit;
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, framectl);
}
-exit:
- mutex_unlock(&priv->mtx);
-
- return ret;
+ return;
}
-static void at76_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
+/* Convert the 802.11 header into an ethernet-style header, make skb
+ * ready for consumption by netif_rx() */
+static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
{
- at76_dbg(DBG_MAC80211, "%s()", __func__);
-}
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ struct ethhdr *eth_hdr_p;
+ u8 *src_addr;
+ u8 *dest_addr;
-static int at76_join(struct at76_priv *priv)
-{
- struct at76_req_join join;
- int ret;
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
- memset(&join, 0, sizeof(struct at76_req_join));
- memcpy(join.essid, priv->essid, priv->essid_size);
- join.essid_size = priv->essid_size;
- memcpy(join.bssid, priv->bssid, ETH_ALEN);
- join.bss_type = INFRASTRUCTURE_MODE;
- join.channel = priv->channel;
- join.timeout = cpu_to_le16(2000);
+ /* That would be the ethernet header if the hardware converted
+ * the frame for us. Make sure the source and the destination
+ * match the 802.11 header. Which hardware does it? */
+ eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN);
- at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
- ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
- sizeof(struct at76_req_join));
+ dest_addr = i802_11_hdr->addr1;
+ if (iw_mode == IW_MODE_ADHOC)
+ src_addr = i802_11_hdr->addr2;
+ else
+ src_addr = i802_11_hdr->addr3;
- if (ret < 0) {
- printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- return 0;
- }
+ if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) &&
+ !compare_ether_addr(eth_hdr_p->h_dest, dest_addr))
+ /* Yes, we already have an ethernet header */
+ skb_reset_mac_header(skb);
+ else {
+ u16 len;
+
+ /* Need to build an ethernet header */
+ if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
+ /* SNAP frame - decapsulate, keep proto */
+ skb_push(skb, offsetof(struct ethhdr, h_proto) -
+ sizeof(rfc1042sig));
+ len = 0;
+ } else {
+ /* 802.3 frame, proto is length */
+ len = skb->len;
+ skb_push(skb, ETH_HLEN);
+ }
- ret = at76_wait_completion(priv, CMD_JOIN);
- at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
- if (ret != CMD_STATUS_COMPLETE) {
- printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- return 0;
+ skb_reset_mac_header(skb);
+ eth_hdr_p = eth_hdr(skb);
+ /* This needs to be done in this order (eth_hdr_p->h_dest may
+ * overlap src_addr) */
+ memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
+ memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
+ if (len)
+ eth_hdr_p->h_proto = htons(len);
}
- at76_set_tkip_bssid(priv, priv->bssid);
- at76_set_pm_mode(priv);
-
- return 0;
+ skb->protocol = eth_type_trans(skb, skb->dev);
}
-static void at76_dwork_hw_scan(struct work_struct *work)
+/* Check for fragmented data in priv->rx_skb. If the packet was no fragment
+ or it was the last of a fragment set a skb containing the whole packet
+ is returned for further processing. Otherwise we get NULL and are
+ done and the packet is either stored inside the fragment buffer
+ or thrown away. Every returned skb starts with the ieee802_11 header
+ and contains _no_ FCS at the end */
+static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv)
{
- struct at76_priv *priv = container_of(work, struct at76_priv,
- dwork_hw_scan.work);
- int ret;
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ /* seq_ctrl, fragment_number, sequence number of new packet */
+ u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
+ u16 fragnr = sctl & 0xf;
+ u16 seqnr = sctl >> 4;
+ u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
- ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
- at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret);
+ /* Length including the IEEE802.11 header, but without the trailing
+ * FCS and without the Atmel Rx header */
+ int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN;
- /* FIXME: add maximum time for scan to complete */
+ /* where does the data payload start in skb->data ? */
+ u8 *data = i802_11_hdr->payload;
- if (ret != CMD_STATUS_COMPLETE) {
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
- goto exit;
+ /* length of payload, excl. the trailing FCS */
+ int data_len = length - IEEE80211_3ADDR_LEN;
+
+ int i;
+ struct rx_data_buf *bptr, *optr;
+ unsigned long oldest = ~0UL;
+
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
+ "length %d data %d: %s ...", priv->netdev->name, frame_ctl,
+ mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len,
+ hex2str(data, 32));
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
+ "tail %p end %p len %d", priv->netdev->name, skb->head,
+ skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
+ skb->len);
+
+ if (data_len < 0) {
+ /* make sure data starts in the buffer */
+ printk(KERN_INFO "%s: data frame too short\n",
+ priv->netdev->name);
+ return NULL;
}
- ieee80211_scan_completed(priv->hw);
+ WARN_ON(length <= AT76_RX_HDRLEN);
+ if (length <= AT76_RX_HDRLEN)
+ return NULL;
- if (is_valid_ether_addr(priv->bssid)) {
- ieee80211_wake_queues(priv->hw);
- at76_join(priv);
+ /* remove the at76_rx_buffer header - we don't need it anymore */
+ /* we need the IEEE802.11 header (for the addresses) if this packet
+ is the first of a chain */
+ skb_pull(skb, AT76_RX_HDRLEN);
+
+ /* remove FCS at end */
+ skb_trim(skb, length);
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
+ "end %p len %d data %p data_len %d", priv->netdev->name,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->len, data, data_len);
+
+ if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
+ /* unfragmented packet received */
+ /* Use a new skb for the next receive */
+ priv->rx_skb = NULL;
+ at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name);
+ return skb;
}
- ieee80211_wake_queues(priv->hw);
+ /* look if we've got a chain for the sender address.
+ afterwards optr points to first free or the oldest entry,
+ or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
+ sender address */
+ /* determining the oldest entry doesn't cope with jiffies wrapping
+ but I don't care to delete a young entry at these rare moments ... */
+
+ bptr = priv->rx_data;
+ optr = NULL;
+ for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) {
+ if (!bptr->skb) {
+ optr = bptr;
+ oldest = 0UL;
+ continue;
+ }
-exit:
- return;
-}
+ if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender))
+ break;
-static int at76_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
-{
- struct at76_priv *priv = hw->priv;
- struct at76_req_scan scan;
- int ret;
+ if (!optr) {
+ optr = bptr;
+ oldest = bptr->last_rx;
+ } else if (bptr->last_rx < oldest)
+ optr = bptr;
+ }
- at76_dbg(DBG_MAC80211, "%s():", __func__);
- at76_dbg_dump(DBG_MAC80211, ssid, len, "ssid %zd bytes:", len);
+ if (i < NR_RX_DATA_BUF) {
+
+ at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) "
+ "matched sender addr",
+ priv->netdev->name, i, bptr->seqnr, bptr->fragnr);
+
+ /* bptr points to an entry for the sender address */
+ if (bptr->seqnr == seqnr) {
+ int left;
+ /* the fragment has the current sequence number */
+ if (((bptr->fragnr + 1) & 0xf) != fragnr) {
+ /* wrong fragment number -> ignore it */
+ /* is & 0xf necessary above ??? */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: frag nr mismatch: %d + 1 != %d",
+ priv->netdev->name, bptr->fragnr,
+ fragnr);
+ return NULL;
+ }
+ bptr->last_rx = jiffies;
+ /* the next following fragment number ->
+ add the data at the end */
+
+ /* for test only ??? */
+ left = skb_tailroom(bptr->skb);
+ if (left < data_len)
+ printk(KERN_INFO
+ "%s: only %d byte free (need %d)\n",
+ priv->netdev->name, left, data_len);
+ else
+ memcpy(skb_put(bptr->skb, data_len), data,
+ data_len);
+
+ bptr->fragnr = fragnr;
+ if (frame_ctl & IEEE80211_FCTL_MOREFRAGS)
+ return NULL;
+
+ /* this was the last fragment - send it */
+ skb = bptr->skb;
+ bptr->skb = NULL; /* free the entry */
+ at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
+ priv->netdev->name, seqnr);
+ return skb;
+ }
- mutex_lock(&priv->mtx);
+ /* got another sequence number */
+ if (fragnr == 0) {
+ /* it's the start of a new chain - replace the
+ old one by this */
+ /* bptr->sender has the correct value already */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: start of new seq %d, removing old seq %d",
+ priv->netdev->name, seqnr, bptr->seqnr);
+ bptr->seqnr = seqnr;
+ bptr->fragnr = 0;
+ bptr->last_rx = jiffies;
+ /* swap bptr->skb and priv->rx_skb */
+ skb = bptr->skb;
+ bptr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
+ } else {
+ /* it from the middle of a new chain ->
+ delete the old entry and skip the new one */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: middle of new seq %d (%d) "
+ "removing old seq %d",
+ priv->netdev->name, seqnr, fragnr,
+ bptr->seqnr);
+ dev_kfree_skb(bptr->skb);
+ bptr->skb = NULL;
+ }
+ return NULL;
+ }
- ieee80211_stop_queues(hw);
+ /* if we didn't find a chain for the sender address, optr
+ points either to the first free or the oldest entry */
- memset(&scan, 0, sizeof(struct at76_req_scan));
- memset(scan.bssid, 0xFF, ETH_ALEN);
- scan.scan_type = SCAN_TYPE_ACTIVE;
- if (priv->essid_size > 0) {
- memcpy(scan.essid, ssid, len);
- scan.essid_size = len;
+ if (fragnr != 0) {
+ /* this is not the begin of a fragment chain ... */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: no chain for non-first fragment (%d)",
+ priv->netdev->name, fragnr);
+ return NULL;
}
- scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
- scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
- scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
- scan.international_scan = 0;
- at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__);
- ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+ BUG_ON(!optr);
+ if (optr->skb) {
+ /* swap the skb's */
+ skb = optr->skb;
+ optr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
- if (ret < 0) {
- err("CMD_SCAN failed: %d", ret);
- goto exit;
- }
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: free old contents: sender %s seq/frag %d/%d",
+ priv->netdev->name, mac2str(optr->sender),
+ optr->seqnr, optr->fragnr);
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
+ } else {
+ /* take the skb from priv->rx_skb */
+ optr->skb = priv->rx_skb;
+ /* let at76_submit_rx_urb() allocate a new skb */
+ priv->rx_skb = NULL;
-exit:
- mutex_unlock(&priv->mtx);
+ at76_dbg(DBG_RX_FRAGS, "%s: use a free entry",
+ priv->netdev->name);
+ }
+ memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
+ optr->seqnr = seqnr;
+ optr->fragnr = 0;
+ optr->last_rx = jiffies;
- return 0;
+ return NULL;
}
-static int at76_config(struct ieee80211_hw *hw, u32 changed)
+/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */
+static void at76_rx_data(struct at76_priv *priv)
{
- struct at76_priv *priv = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
+ struct net_device *netdev = priv->netdev;
+ struct net_device_stats *stats = &priv->stats;
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ int length = le16_to_cpu(buf->wlength);
- at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
- __func__, conf->channel->hw_value, conf->radio_enabled);
- at76_dbg_dump(DBG_MAC80211, priv->essid, priv->essid_size, "ssid:");
- at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
+ at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name,
+ hex2str(skb->data, AT76_RX_HDRLEN));
- mutex_lock(&priv->mtx);
+ at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s",
+ hex2str(skb->data + AT76_RX_HDRLEN, length));
- priv->channel = conf->channel->hw_value;
+ skb = at76_check_for_rx_frags(priv);
+ if (!skb)
+ return;
- if (is_valid_ether_addr(priv->bssid)) {
- at76_join(priv);
- ieee80211_wake_queues(priv->hw);
- } else {
- ieee80211_stop_queues(priv->hw);
- at76_start_monitor(priv);
- };
+ /* Atmel header and the FCS are already removed */
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
- mutex_unlock(&priv->mtx);
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */
- return 0;
-}
+ if (is_broadcast_ether_addr(i802_11_hdr->addr1)) {
+ if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast))
+ skb->pkt_type = PACKET_BROADCAST;
+ else
+ skb->pkt_type = PACKET_MULTICAST;
+ } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr))
+ skb->pkt_type = PACKET_OTHERHOST;
-static int at76_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct at76_priv *priv = hw->priv;
+ at76_ieee80211_to_eth(skb, priv->iw_mode);
- at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
- mutex_lock(&priv->mtx);
+ return;
+}
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-// memcpy(priv->essid, conf->ssid, conf->ssid_len);
-// priv->essid_size = conf->ssid_len;
+static void at76_rx_monitor_mode(struct at76_priv *priv)
+{
+ struct at76_rx_radiotap *rt;
+ u8 *payload;
+ int skblen;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf =
+ (struct at76_rx_buffer *)priv->rx_skb->data;
+ /* length including the IEEE802.11 header and the trailing FCS,
+ but not at76_rx_buffer */
+ int length = le16_to_cpu(buf->wlength);
+ struct sk_buff *skb = priv->rx_skb;
+ struct net_device_stats *stats = &priv->stats;
- if (is_valid_ether_addr(priv->bssid)) {
- /* mac80211 is joining a bss */
- ieee80211_wake_queues(priv->hw);
- at76_join(priv);
- } else
- ieee80211_stop_queues(priv->hw);
+ if (length < IEEE80211_FCS_LEN) {
+ /* buffer contains no data */
+ at76_dbg(DBG_MONITOR_MODE,
+ "%s: MONITOR MODE: rx skb without data",
+ priv->netdev->name);
+ return;
+ }
- mutex_unlock(&priv->mtx);
+ skblen = sizeof(struct at76_rx_radiotap) + length;
- return 0;
+ skb = dev_alloc_skb(skblen);
+ if (!skb) {
+ printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap "
+ "header returned NULL\n", priv->netdev->name);
+ return;
+ }
+
+ skb_put(skb, skblen);
+
+ rt = (struct at76_rx_radiotap *)skb->data;
+ payload = skb->data + sizeof(struct at76_rx_radiotap);
+
+ rt->rt_hdr.it_version = 0;
+ rt->rt_hdr.it_pad = 0;
+ rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap));
+ rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT);
+
+ rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time));
+ rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80);
+ rt->rt_signal = buf->rssi;
+ rt->rt_noise = buf->noise_level;
+ rt->rt_flags = IEEE80211_RADIOTAP_F_FCS;
+ if (buf->fragmentation)
+ rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+ memcpy(payload, buf->packet, length);
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
}
-/* must be atomic */
-static void at76_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags, int mc_count,
- struct dev_addr_list *mc_list)
+/* Check if we spy on the sender address in buf and update stats */
+static void at76_iwspy_update(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = hw->priv;
- int flags;
-
- at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
- "total_flags=0x%08x mc_count=%d",
- __func__, changed_flags, *total_flags, mc_count);
+ struct ieee80211_hdr_3addr *hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ struct iw_quality qual;
- flags = changed_flags & AT76_SUPPORTED_FILTERS;
- *total_flags = AT76_SUPPORTED_FILTERS;
+ /* We can only set the level here */
+ qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+ qual.level = 0;
+ qual.noise = 0;
+ at76_calc_level(priv, buf, &qual);
- /* FIXME: access to priv->promisc should be protected with
- * priv->mtx, but it's impossible because this function needs to be
- * atomic */
+ spin_lock_bh(&priv->spy_spinlock);
- if (flags && !priv->promisc) {
- /* mac80211 wants us to enable promiscuous mode */
- priv->promisc = 1;
- } else if (!flags && priv->promisc) {
- /* we need to disable promiscuous mode */
- priv->promisc = 0;
- } else
- return;
+ if (priv->spy_data.spy_number > 0)
+ wireless_spy_update(priv->netdev, hdr->addr2, &qual);
- queue_work(hw->workqueue, &priv->work_set_promisc);
+ spin_unlock_bh(&priv->spy_spinlock);
}
-static int at76_set_key_oldfw(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
+static void at76_rx_tasklet(unsigned long param)
{
- struct at76_priv *priv = hw->priv;
-
- int i;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ struct urb *urb = (struct urb *)param;
+ struct at76_priv *priv = urb->context;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ u16 frame_ctl;
- if (key->alg != ALG_WEP)
- return -EOPNOTSUPP;
+ if (priv->device_unplugged) {
+ at76_dbg(DBG_DEVSTART, "device unplugged");
+ if (urb)
+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ return;
+ }
- key->hw_key_idx = key->keyidx;
+ if (!priv->rx_skb || !netdev || !priv->rx_skb->data)
+ return;
- mutex_lock(&priv->mtx);
+ buf = (struct at76_rx_buffer *)priv->rx_skb->data;
- switch (cmd) {
- case SET_KEY:
- memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen);
- priv->wep_keys_len[key->keyidx] = key->keylen;
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
- /* FIXME: find out how to do this properly */
- priv->wep_key_id = key->keyidx;
+ frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
- break;
- case DISABLE_KEY:
- default:
- priv->wep_keys_len[key->keyidx] = 0;
- break;
+ if (urb->status != 0) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET)
+ at76_dbg(DBG_URB,
+ "%s %s: - nonzero Rx bulk status received: %d",
+ __func__, netdev->name, urb->status);
+ return;
}
- priv->wep_enabled = 0;
+ at76_dbg(DBG_RX_ATMEL_HDR,
+ "%s: rx frame: rate %d rssi %d noise %d link %d %s",
+ priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level,
+ buf->link_quality, hex2str(i802_11_hdr, 48));
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ at76_rx_monitor_mode(priv);
+ goto exit;
+ }
- for (i = 0; i < WEP_KEYS; i++) {
- if (priv->wep_keys_len[i] != 0)
- priv->wep_enabled = 1;
+ /* there is a new bssid around, accept it: */
+ if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) {
+ at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
+ schedule_work(&priv->work_new_bss);
}
- at76_startup_device(priv);
+ switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_DATA:
+ at76_rx_data(priv);
+ break;
- mutex_unlock(&priv->mtx);
+ case IEEE80211_FTYPE_MGMT:
+ /* jal: TODO: find out if we can update iwspy also on
+ other frames than management (might depend on the
+ radio chip / firmware version !) */
- return 0;
-}
+ at76_iwspy_update(priv, buf);
-static int at76_set_key_newfw(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
-{
- struct at76_priv *priv = hw->priv;
- int ret = -EOPNOTSUPP;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ at76_rx_mgmt(priv, buf);
+ break;
- mutex_lock(&priv->mtx);
+ case IEEE80211_FTYPE_CTL:
+ at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x",
+ priv->netdev->name, frame_ctl);
+ break;
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
+ default:
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, frame_ctl);
+ }
+exit:
+ at76_submit_rx_urb(priv);
+}
- if (cmd == DISABLE_KEY) {
- priv->mib_buf.size = CIPHER_KEY_LEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- cipher_default_keyvalue[key->keyidx]);
- memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN);
- if (at76_set_mib(priv, &priv->mib_buf) != CMD_STATUS_COMPLETE)
- ret = -EOPNOTSUPP; /* -EIO would be probably better */
- else {
+/* Load firmware into kernel memory and parse it */
+static struct fwentry *at76_load_firmware(struct usb_device *udev,
+ enum board_type board_type)
+{
+ int ret;
+ char *str;
+ struct at76_fw_header *fwh;
+ struct fwentry *fwe = &firmwares[board_type];
- priv->keys[key->keyidx].cipher = CIPHER_NONE;
- priv->keys[key->keyidx].keylen = 0;
- };
- if (priv->default_group_key == key->keyidx)
- priv->default_group_key = 0xff;
+ mutex_lock(&fw_mutex);
- if (priv->default_pairwise_key == key->keyidx)
- priv->default_pairwise_key = 0xff;
- /* If default pairwise key is removed, fall back to
- * group key? */
- ret = 0;
+ if (fwe->loaded) {
+ at76_dbg(DBG_FW, "re-using previously loaded fw");
goto exit;
- };
-
- if (cmd == SET_KEY) {
- /* store key into MIB */
- priv->mib_buf.size = CIPHER_KEY_LEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- cipher_default_keyvalue[key->keyidx]);
- memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN);
- memcpy(priv->mib_buf.data.data, key->key, key->keylen);
-
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == 5) {
- priv->keys[key->keyidx].cipher =
- CIPHER_WEP64;
- priv->keys[key->keyidx].keylen = 8;
- } else if (key->keylen == 13) {
- priv->keys[key->keyidx].cipher =
- CIPHER_WEP128;
- /* Firmware needs this */
- priv->keys[key->keyidx].keylen = 8;
- } else {
- ret = -EOPNOTSUPP;
- goto exit;
- };
- break;
- case ALG_TKIP:
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- priv->keys[key->keyidx].cipher = CIPHER_TKIP;
- priv->keys[key->keyidx].keylen = 12;
- break;
+ }
- case ALG_CCMP:
- if (!at76_is_505a(priv->board_type)) {
- ret = -EOPNOTSUPP;
- goto exit;
- };
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- priv->keys[key->keyidx].cipher = CIPHER_CCMP;
- priv->keys[key->keyidx].keylen = 16;
- break;
+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
+ fwe->fwname);
+ dev_printk(KERN_ERR, &udev->dev,
+ "you may need to download the firmware from "
+ "http://developer.berlios.de/projects/at76c503a/");
+ goto exit;
+ }
- default:
- ret = -EOPNOTSUPP;
- goto exit;
- };
-
- priv->mib_buf.data.data[38] = priv->keys[key->keyidx].cipher;
- priv->mib_buf.data.data[39] = 1; /* Taken from atmelwlandriver,
- not documented */
-
- if (is_valid_ether_addr(address))
- /* Pairwise key */
- priv->mib_buf.data.data[39] |= (KEY_PAIRWISE | KEY_TX);
- else if (is_broadcast_ether_addr(address))
- /* Group key */
- priv->mib_buf.data.data[39] |= (KEY_TX);
- else /* Key used only for transmission ??? */
- priv->mib_buf.data.data[39] |= (KEY_TX);
-
- if (at76_set_mib(priv, &priv->mib_buf) !=
- CMD_STATUS_COMPLETE) {
- ret = -EOPNOTSUPP; /* -EIO would be probably better */
- goto exit;
- };
+ at76_dbg(DBG_FW, "got it.");
+ fwh = (struct at76_fw_header *)(fwe->fw->data);
- if ((key->alg == ALG_TKIP) || (key->alg == ALG_CCMP))
- at76_reset_rsc(priv);
+ if (fwe->fw->size <= sizeof(*fwh)) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "firmware is too short (0x%zx)\n", fwe->fw->size);
+ goto exit;
+ }
- key->hw_key_idx = key->keyidx;
+ /* CRC currently not checked */
+ fwe->board_type = le32_to_cpu(fwh->board_type);
+ if (fwe->board_type != board_type) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "board type mismatch, requested %u, got %u\n",
+ board_type, fwe->board_type);
+ goto exit;
+ }
- /* Set up default keys */
- if (is_broadcast_ether_addr(address))
- priv->default_group_key = key->keyidx;
- if (is_valid_ether_addr(address))
- priv->default_pairwise_key = key->keyidx;
+ fwe->fw_version.major = fwh->major;
+ fwe->fw_version.minor = fwh->minor;
+ fwe->fw_version.patch = fwh->patch;
+ fwe->fw_version.build = fwh->build;
- /* Set up encryption MIBs */
+ str = (char *)fwh + le32_to_cpu(fwh->str_offset);
+ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
+ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
+ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
+ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
- /* first block of settings */
- priv->mib_buf.size = 3;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- privacy_invoked);
- priv->mib_buf.data.data[0] = 1; /* privacy_invoked */
- priv->mib_buf.data.data[1] = priv->default_pairwise_key;
- priv->mib_buf.data.data[2] = priv->default_group_key;
+ fwe->loaded = 1;
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret != CMD_STATUS_COMPLETE)
- goto exit;
+ dev_printk(KERN_DEBUG, &udev->dev,
+ "using firmware %s (version %d.%d.%d-%d)\n",
+ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
- /* second block of settings */
- priv->mib_buf.size = 3;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- exclude_unencrypted);
- priv->mib_buf.data.data[0] = 1; /* exclude_unencrypted */
- priv->mib_buf.data.data[1] = 0; /* wep_encryption_type */
- priv->mib_buf.data.data[2] = 0; /* ckip_key_permutation */
+ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
+ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
+ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
+ at76_dbg(DBG_DEVSTART, "firmware id %s", str);
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret != CMD_STATUS_COMPLETE)
- goto exit;
- ret = 0;
- };
exit:
- at76_dump_mib_mac_encryption(priv);
- mutex_unlock(&priv->mtx);
- return ret;
-}
-
-static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
-{
- struct at76_priv *priv = hw->priv;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ mutex_unlock(&fw_mutex);
- if (FIRMWARE_IS_WPA(priv->fw_version))
- return at76_set_key_newfw(hw, cmd, local_address, address, key);
+ if (fwe->loaded)
+ return fwe;
else
- return at76_set_key_oldfw(hw, cmd, local_address, address, key);
-
+ return NULL;
}
-static const struct ieee80211_ops at76_ops = {
- .tx = at76_mac80211_tx,
- .add_interface = at76_add_interface,
- .remove_interface = at76_remove_interface,
- .config = at76_config,
- .config_interface = at76_config_interface,
- .configure_filter = at76_configure_filter,
- .start = at76_mac80211_start,
- .stop = at76_mac80211_stop,
- .hw_scan = at76_hw_scan,
- .set_key = at76_set_key,
-};
-
/* Allocate network device and initialize private data */
static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
{
- struct ieee80211_hw *hw;
+ struct net_device *netdev;
struct at76_priv *priv;
+ int i;
- hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops);
- if (!hw) {
- printk(KERN_ERR DRIVER_NAME ": could not register"
- " ieee80211_hw\n");
+ /* allocate memory for our device state and initialize it */
+ netdev = alloc_etherdev(sizeof(struct at76_priv));
+ if (!netdev) {
+ dev_printk(KERN_ERR, &udev->dev, "out of memory\n");
return NULL;
}
- priv = hw->priv;
- priv->hw = hw;
+ priv = netdev_priv(netdev);
priv->udev = udev;
+ priv->netdev = netdev;
mutex_init(&priv->mtx);
+ INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done);
+ INIT_WORK(&priv->work_join, at76_work_join);
+ INIT_WORK(&priv->work_new_bss, at76_work_new_bss);
+ INIT_WORK(&priv->work_start_scan, at76_work_start_scan);
INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
- INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
+ INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart);
+ INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan);
+ INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon);
+ INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth);
+ INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc);
+
+ spin_lock_init(&priv->mgmt_spinlock);
+ priv->next_mgmt_bulk = NULL;
+ priv->mac_state = MAC_INIT;
+
+ /* initialize empty BSS list */
+ priv->curr_bss = NULL;
+ INIT_LIST_HEAD(&priv->bss_list);
+ spin_lock_init(&priv->bss_list_spinlock);
+
+ init_timer(&priv->bss_list_timer);
+ priv->bss_list_timer.data = (unsigned long)priv;
+ priv->bss_list_timer.function = at76_bss_list_timeout;
+
+ spin_lock_init(&priv->spy_spinlock);
+
+ /* mark all rx data entries as unused */
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ priv->rx_data[i].skb = NULL;
priv->rx_tasklet.func = at76_rx_tasklet;
priv->rx_tasklet.data = 0;
@@ -2371,9 +5197,6 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
priv->pm_mode = AT76_PM_OFF;
priv->pm_period = 0;
- /* unit us */
- priv->hw->channel_change_time = 100000;
-
return priv;
}
@@ -2436,42 +5259,11 @@ static int at76_alloc_urbs(struct at76_priv *priv,
return 0;
}
-static struct ieee80211_rate at76_rates[] = {
- { .bitrate = 10, .hw_value = TX_RATE_1MBIT, },
- { .bitrate = 20, .hw_value = TX_RATE_2MBIT, },
- { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, },
- { .bitrate = 110, .hw_value = TX_RATE_11MBIT, },
-};
-
-static struct ieee80211_channel at76_channels[] = {
- { .center_freq = 2412, .hw_value = 1 },
- { .center_freq = 2417, .hw_value = 2 },
- { .center_freq = 2422, .hw_value = 3 },
- { .center_freq = 2427, .hw_value = 4 },
- { .center_freq = 2432, .hw_value = 5 },
- { .center_freq = 2437, .hw_value = 6 },
- { .center_freq = 2442, .hw_value = 7 },
- { .center_freq = 2447, .hw_value = 8 },
- { .center_freq = 2452, .hw_value = 9 },
- { .center_freq = 2457, .hw_value = 10 },
- { .center_freq = 2462, .hw_value = 11 },
- { .center_freq = 2467, .hw_value = 12 },
- { .center_freq = 2472, .hw_value = 13 },
- { .center_freq = 2484, .hw_value = 14 }
-};
-
-static struct ieee80211_supported_band at76_supported_band = {
- .channels = at76_channels,
- .n_channels = ARRAY_SIZE(at76_channels),
- .bitrates = at76_rates,
- .n_bitrates = ARRAY_SIZE(at76_rates),
-};
-
/* Register network device and initialize the hardware */
static int at76_init_new_device(struct at76_priv *priv,
struct usb_interface *interface)
{
- struct device *dev = &interface->dev;
+ struct net_device *netdev = priv->netdev;
int ret;
/* set up the endpoint information */
@@ -2487,11 +5279,14 @@ static int at76_init_new_device(struct at76_priv *priv,
/* MAC address */
ret = at76_get_hw_config(priv);
if (ret < 0) {
- dev_err(dev, "cannot get MAC address\n");
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot get MAC address\n");
goto exit;
}
priv->domain = at76_get_reg_domain(priv->regulatory_domain);
+ /* init. netdev->dev_addr */
+ memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN);
priv->channel = DEF_CHANNEL;
priv->iw_mode = IW_MODE_INFRA;
@@ -2501,54 +5296,47 @@ static int at76_init_new_device(struct at76_priv *priv,
priv->txrate = TX_RATE_AUTO;
priv->preamble_type = PREAMBLE_TYPE_LONG;
priv->beacon_period = 100;
+ priv->beacons_last_qual = jiffies;
priv->auth_mode = WLAN_AUTH_OPEN;
priv->scan_min_time = DEF_SCAN_MIN_TIME;
priv->scan_max_time = DEF_SCAN_MAX_TIME;
priv->scan_mode = SCAN_TYPE_ACTIVE;
- priv->default_pairwise_key = 0xff;
- priv->default_group_key = 0xff;
-
- /* mac80211 initialisation */
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
- if (FIRMWARE_IS_WPA(priv->fw_version) &&
- (at76_is_503rfmd(priv->board_type) ||
- at76_is_505(priv->board_type)))
- priv->hw->flags = IEEE80211_HW_SIGNAL_UNSPEC;
- else
- priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_UNSPEC;
-
- priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-
- SET_IEEE80211_DEV(priv->hw, &interface->dev);
- SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
-
- ret = ieee80211_register_hw(priv->hw);
+ netdev->flags &= ~IFF_MULTICAST; /* not yet or never */
+ netdev->open = at76_open;
+ netdev->stop = at76_stop;
+ netdev->get_stats = at76_get_stats;
+ netdev->ethtool_ops = &at76_ethtool_ops;
+
+ /* Add pointers to enable iwspy support. */
+ priv->wireless_data.spy_data = &priv->spy_data;
+ netdev->wireless_data = &priv->wireless_data;
+
+ netdev->hard_start_xmit = at76_tx;
+ netdev->tx_timeout = at76_tx_timeout;
+ netdev->watchdog_timeo = 2 * HZ;
+ netdev->wireless_handlers = &at76_handler_def;
+ netdev->set_multicast_list = at76_set_multicast;
+ netdev->set_mac_address = at76_set_mac_address;
+ dev_alloc_name(netdev, "wlan%d");
+
+ ret = register_netdev(priv->netdev);
if (ret) {
- dev_err(dev, "cannot register mac80211 hw (status %d)!\n", ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot register netdevice (status %d)!\n", ret);
goto exit;
}
+ priv->netdev_registered = 1;
- priv->mac80211_registered = 1;
+ printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+ netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr),
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+ printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name,
+ priv->regulatory_domain, priv->domain->name);
- dev_info(dev, "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
- wiphy_name(priv->hw->wiphy),
- dev_name(&interface->dev), mac2str(priv->mac_addr),
- priv->fw_version.major, priv->fw_version.minor,
- priv->fw_version.patch, priv->fw_version.build);
- dev_info(dev, "%s: regulatory domain 0x%02x: %s\n",
- wiphy_name(priv->hw->wiphy),
- priv->regulatory_domain, priv->domain->name);
- dev_info(dev, "%s: WPA support: ", wiphy_name(priv->hw->wiphy));
- if (!FIRMWARE_IS_WPA(priv->fw_version))
- printk("none\n");
- else {
- if (!at76_is_505a(priv->board_type))
- printk("TKIP\n");
- else
- printk("TKIP, AES/CCMP\n");
- };
+ /* we let this timer run the whole time this driver instance lives */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
exit:
return ret;
@@ -2556,13 +5344,15 @@ exit:
static void at76_delete_device(struct at76_priv *priv)
{
+ int i;
+
at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
/* The device is gone, don't bother turning it off */
priv->device_unplugged = 1;
- if (priv->mac80211_registered)
- ieee80211_unregister_hw(priv->hw);
+ if (priv->netdev_registered)
+ unregister_netdev(priv->netdev);
/* assuming we used keventd, it must quiesce too */
flush_scheduled_work();
@@ -2583,11 +5373,25 @@ static void at76_delete_device(struct at76_priv *priv)
if (priv->rx_skb)
kfree_skb(priv->rx_skb);
+ at76_free_bss_list(priv);
+ del_timer_sync(&priv->bss_list_timer);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
+
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ if (priv->rx_data[i].skb) {
+ dev_kfree_skb(priv->rx_data[i].skb);
+ priv->rx_data[i].skb = NULL;
+ }
usb_put_dev(priv->udev);
- at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
- __func__);
- ieee80211_free_hw(priv->hw);
+ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__);
+ free_netdev(priv->netdev); /* priv is in netdev */
at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
}
@@ -2621,8 +5425,8 @@ static int at76_probe(struct usb_interface *interface,
we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
if (op_mode == OPMODE_HW_CONFIG_MODE) {
- dev_err(&interface->dev,
- "cannot handle a device in HW_CONFIG_MODE\n");
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot handle a device in HW_CONFIG_MODE\n");
ret = -EBUSY;
goto error;
}
@@ -2630,12 +5434,13 @@ static int at76_probe(struct usb_interface *interface,
if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
&& op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
/* download internal firmware part */
- dev_dbg(&interface->dev, "downloading internal firmware\n");
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading internal firmware\n");
ret = at76_load_internal_fw(udev, fwe);
if (ret < 0) {
- dev_err(&interface->dev,
- "error %d downloading internal firmware\n",
- ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d downloading internal firmware\n",
+ ret);
goto error;
}
usb_put_dev(udev);
@@ -2660,7 +5465,8 @@ static int at76_probe(struct usb_interface *interface,
need_ext_fw = 1;
if (need_ext_fw) {
- dev_dbg(&interface->dev, "downloading external firmware\n");
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading external firmware\n");
ret = at76_load_external_fw(udev, fwe);
if (ret)
@@ -2669,8 +5475,8 @@ static int at76_probe(struct usb_interface *interface,
/* Re-check firmware version */
ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
if (ret < 0) {
- dev_err(&interface->dev,
- "error %d getting firmware version\n", ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d getting firmware version\n", ret);
goto error;
}
}
@@ -2681,6 +5487,7 @@ static int at76_probe(struct usb_interface *interface,
goto error;
}
+ SET_NETDEV_DEV(priv->netdev, &interface->dev);
usb_set_intfdata(interface, priv);
memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
@@ -2708,7 +5515,7 @@ static void at76_disconnect(struct usb_interface *interface)
if (!priv)
return;
- printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
+ printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
at76_delete_device(priv);
dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
}
@@ -2764,8 +5571,5 @@ MODULE_AUTHOR("Alex <alex@foogod.com>");
MODULE_AUTHOR("Nick Jones");
MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
-MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
-MODULE_AUTHOR("Milan Plzik <milan.plzik@gmail.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
index 8bb352f16d45..b20be9da1fa1 100644
--- a/drivers/staging/at76_usb/at76_usb.h
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -34,6 +34,23 @@ enum board_type {
BOARD_505AMX = 8
};
+/* our private ioctl's */
+/* preamble length (0 - long, 1 - short, 2 - auto) */
+#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0)
+#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1)
+/* which debug channels are enabled */
+#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2)
+#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3)
+/* power save mode (incl. the Atmel proprietary smart save mode) */
+#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4)
+#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5)
+/* min and max channel times for scan */
+#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6)
+#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7)
+/* scan mode (0 - active, 1 - passive) */
+#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8)
+#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9)
+
#define CMD_STATUS_IDLE 0x00
#define CMD_STATUS_COMPLETE 0x01
#define CMD_STATUS_UNKNOWN 0x02
@@ -65,7 +82,6 @@ enum board_type {
#define MIB_MAC 0x03
#define MIB_MAC_MGMT 0x05
#define MIB_MAC_WEP 0x06
-#define MIB_MAC_ENCRYPTION 0x06
#define MIB_PHY 0x07
#define MIB_FW_VERSION 0x08
#define MIB_MDOMAIN 0x09
@@ -90,26 +106,6 @@ enum board_type {
#define AT76_PM_ON 2
#define AT76_PM_SMART 3
-/* cipher values for encryption keys */
-#define CIPHER_NONE 0 /* this value is only guessed */
-#define CIPHER_WEP64 1
-#define CIPHER_TKIP 2
-#define CIPHER_CCMP 3
-#define CIPHER_CCX 4 /* for consistency sake only */
-#define CIPHER_WEP128 5
-
-/* bit flags key types for encryption keys */
-#define KEY_PAIRWISE 2
-#define KEY_TX 4
-
-#define CIPHER_KEYS (4)
-#define CIPHER_KEY_LEN (40)
-
-struct key_config {
- u8 cipher;
- u8 keylen;
-};
-
struct hwcfg_r505 {
u8 cr39_values[14];
u8 reserved1[14];
@@ -151,9 +147,6 @@ union at76_hwcfg {
#define WEP_SMALL_KEY_LEN (40 / 8)
#define WEP_LARGE_KEY_LEN (104 / 8)
-#define WEP_KEYS (4)
-
-
struct at76_card_config {
u8 exclude_unencrypted;
@@ -168,7 +161,7 @@ struct at76_card_config {
u8 privacy_invoked;
u8 wep_default_key_id; /* 0..3 */
u8 current_ssid[32];
- u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN];
+ u8 wep_default_key_value[4][WEP_KEY_LEN];
u8 ssid_len;
u8 short_preamble;
__le16 beacon_period;
@@ -193,7 +186,7 @@ struct at76_rx_buffer {
u8 link_quality;
u8 noise_level;
__le32 rx_time;
- u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
} __attribute__((packed));
/* Length of Atmel-specific Tx header before 802.11 frame */
@@ -203,11 +196,8 @@ struct at76_tx_buffer {
__le16 wlength;
u8 tx_rate;
u8 padding;
- u8 key_id;
- u8 cipher_type;
- u8 cipher_length;
- u8 reserved;
- u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+ u8 reserved[4];
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
} __attribute__((packed));
/* defines for scan_type below */
@@ -254,7 +244,6 @@ struct set_mib_buffer {
u8 byte;
__le16 word;
u8 addr[ETH_ALEN];
- u8 data[256]; /* we need more space for mib_mac_encryption */
} data;
} __attribute__((packed));
@@ -328,24 +317,10 @@ struct mib_mac_wep {
u8 exclude_unencrypted;
__le32 wep_icv_error_count;
__le32 wep_excluded_count;
- u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN];
+ u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
} __attribute__((packed));
-struct mib_mac_encryption {
- u8 cipher_default_keyvalue[CIPHER_KEYS][CIPHER_KEY_LEN];
- u8 tkip_bssid[6];
- u8 privacy_invoked;
- u8 cipher_default_key_id;
- u8 cipher_default_group_key_id;
- u8 exclude_unencrypted;
- u8 wep_encryption_type;
- u8 ckip_key_permutation; /* bool */
- __le32 wep_icv_error_count;
- __le32 wep_excluded_count;
- u8 key_rsc[CIPHER_KEYS][8];
-} __attribute__((packed));
-
struct mib_phy {
__le32 ed_threshold;
@@ -389,6 +364,16 @@ struct at76_fw_header {
__le32 ext_fw_len; /* external firmware image length */
} __attribute__((packed));
+enum mac_state {
+ MAC_INIT,
+ MAC_SCANNING,
+ MAC_AUTH,
+ MAC_ASSOC,
+ MAC_JOINING,
+ MAC_CONNECTED,
+ MAC_OWN_IBSS
+};
+
/* a description of a regulatory domain and the allowed channels */
struct reg_domain {
u16 code;
@@ -396,6 +381,47 @@ struct reg_domain {
u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
};
+/* how long do we keep a (I)BSS in the bss_list in jiffies
+ this should be long enough for the user to retrieve the table
+ (by iwlist ?) after the device started, because all entries from
+ other channels than the one the device locks on get removed, too */
+#define BSS_LIST_TIMEOUT (120 * HZ)
+/* struct to store BSS info found during scan */
+#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */
+
+struct bss_info {
+ struct list_head list;
+
+ u8 bssid[ETH_ALEN]; /* bssid */
+ u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */
+ u8 ssid_len; /* length of ssid above */
+ u8 channel;
+ u16 capa; /* BSS capabilities */
+ u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */
+ u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of
+ 500 kbps, ORed with 0x80 for
+ basic rates */
+ u8 rates_len;
+
+ /* quality of received beacon */
+ u8 rssi;
+ u8 link_qual;
+ u8 noise_level;
+
+ unsigned long last_rx; /* time (jiffies) of last beacon received */
+};
+
+/* a rx data buffer to collect rx fragments */
+struct rx_data_buf {
+ u8 sender[ETH_ALEN]; /* sender address */
+ u16 seqnr; /* sequence number */
+ u16 fragnr; /* last fragment received */
+ unsigned long last_rx; /* jiffies of last rx */
+ struct sk_buff *skb; /* == NULL if entry is free */
+};
+
+#define NR_RX_DATA_BUF 8
+
/* Data for one loaded firmware file */
struct fwentry {
const char *const fwname;
@@ -412,9 +438,11 @@ struct fwentry {
struct at76_priv {
struct usb_device *udev; /* USB device pointer */
+ struct net_device *netdev; /* net device pointer */
+ struct net_device_stats stats; /* net device stats */
+ struct iw_statistics wstats; /* wireless stats */
struct sk_buff *rx_skb; /* skbuff for receiving data */
- struct sk_buff *tx_skb; /* skbuff for transmitting data */
void *bulk_out_buffer; /* buffer for sending data */
struct urb *tx_urb; /* URB for sending data */
@@ -426,17 +454,26 @@ struct at76_priv {
struct mutex mtx; /* locks this structure */
/* work queues */
+ struct work_struct work_assoc_done;
+ struct work_struct work_join;
+ struct work_struct work_new_bss;
+ struct work_struct work_start_scan;
struct work_struct work_set_promisc;
struct work_struct work_submit_rx;
- struct delayed_work dwork_hw_scan;
+ struct delayed_work dwork_restart;
+ struct delayed_work dwork_get_scan;
+ struct delayed_work dwork_beacon;
+ struct delayed_work dwork_auth;
+ struct delayed_work dwork_assoc;
struct tasklet_struct rx_tasklet;
/* the WEP stuff */
int wep_enabled; /* 1 if WEP is enabled */
int wep_key_id; /* key id to be used */
- u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */
- u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */
+ u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys,
+ 5 or 13 bytes are used */
+ u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */
int channel;
int iw_mode;
@@ -458,13 +495,44 @@ struct at76_priv {
int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
int scan_need_any; /* if set, need to scan for any ESSID */
+ /* the list we got from scanning */
+ spinlock_t bss_list_spinlock; /* protects bss_list operations */
+ struct list_head bss_list; /* list of BSS we got beacons from */
+ struct timer_list bss_list_timer; /* timer to purge old entries
+ from bss_list */
+ struct bss_info *curr_bss; /* current BSS */
u16 assoc_id; /* current association ID, if associated */
+ u8 wanted_bssid[ETH_ALEN];
+ int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */
+
+ /* some data for infrastructure mode only */
+ spinlock_t mgmt_spinlock; /* this spinlock protects access to
+ next_mgmt_bulk */
+
+ struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to
+ send via bulk out */
+ enum mac_state mac_state;
+ enum {
+ SCAN_IDLE,
+ SCAN_IN_PROGRESS,
+ SCAN_COMPLETED
+ } scan_state;
+ time_t last_scan;
+
+ int retries; /* remaining retries in case of timeout when
+ * sending AuthReq or AssocReq */
u8 pm_mode; /* power management mode */
u32 pm_period; /* power management period in microseconds */
struct reg_domain const *domain; /* reg domain description */
+ /* iwspy support */
+ spinlock_t spy_spinlock;
+ struct iw_spy_data spy_data;
+
+ struct iw_public_data wireless_data;
+
/* These fields contain HW config provided by the device (not all of
* these fields are used by all board types) */
u8 mac_addr[ETH_ALEN];
@@ -472,6 +540,9 @@ struct at76_priv {
struct at76_card_config card_config;
+ /* store rx fragments until complete */
+ struct rx_data_buf rx_data[NR_RX_DATA_BUF];
+
enum board_type board_type;
struct mib_fw_version fw_version;
@@ -479,20 +550,58 @@ struct at76_priv {
unsigned int netdev_registered:1;
struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
+ /* beacon counting */
int beacon_period; /* period of mgmt beacons, Kus */
+ int beacons_received;
+ unsigned long beacons_last_qual; /* time we restarted counting
+ beacons */
+};
- struct ieee80211_hw *hw;
- int mac80211_registered;
-
- struct key_config keys[4]; /* installed key types */
- u8 default_pairwise_key;
- u8 default_group_key;
+struct at76_rx_radiotap {
+ struct ieee80211_radiotap_header rt_hdr;
+ __le64 rt_tsft;
+ u8 rt_flags;
+ u8 rt_rate;
+ s8 rt_signal;
+ s8 rt_noise;
};
-#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS
+#define AT76_RX_RADIOTAP_PRESENT \
+ ((1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
+
+#define BEACON_MAX_DATA_LENGTH 1500
+
+/* the maximum size of an AssocReq packet */
+#define ASSOCREQ_MAX_SIZE \
+ (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \
+ 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4)
+
+/* for shared secret auth, add the challenge text size */
+#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth))
+
+/* Maximal number of AuthReq retries */
+#define AUTH_RETRIES 3
+/* Maximal number of AssocReq retries */
+#define ASSOC_RETRIES 3
+
+/* Beacon timeout in managed mode when we are connected */
+#define BEACON_TIMEOUT (10 * HZ)
+
+/* Timeout for authentication response */
+#define AUTH_TIMEOUT (1 * HZ)
+
+/* Timeout for association response */
+#define ASSOC_TIMEOUT (1 * HZ)
+
+/* Polling interval when scan is running */
#define SCAN_POLL_INTERVAL (HZ / 4)
+/* Command completion timeout */
#define CMD_COMPLETION_TIMEOUT (5 * HZ)
#define DEF_RTS_THRESHOLD 1536
@@ -502,6 +611,8 @@ struct at76_priv {
#define DEF_SCAN_MIN_TIME 10
#define DEF_SCAN_MAX_TIME 120
+#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1)
+
/* the max padding size for tx in bytes (see calc_padding) */
#define MAX_PADDING_SIZE 53
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index b501bfb9c754..b47ca1e7e383 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1,6 +1,7 @@
config COMEDI
tristate "Data Acquision support (comedi)"
default N
+ depends on m
---help---
Enable support a wide range of data acquision devices
for Linux.
diff --git a/drivers/staging/meilhaus/Kconfig b/drivers/staging/meilhaus/Kconfig
index 6def83fa2c96..923af22a4686 100644
--- a/drivers/staging/meilhaus/Kconfig
+++ b/drivers/staging/meilhaus/Kconfig
@@ -4,6 +4,7 @@
menuconfig MEILHAUS
tristate "Meilhaus support"
+ depends on m
---help---
If you have a Meilhaus card, say Y (or M) here.
@@ -18,7 +19,7 @@ if MEILHAUS
config ME0600
tristate "Meilhaus ME-600 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-600 family of boards
that do data collection and multipurpose I/O.
@@ -29,7 +30,7 @@ config ME0600
config ME0900
tristate "Meilhaus ME-900 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-900 family of boards
that do data collection and multipurpose I/O.
@@ -40,7 +41,7 @@ config ME0900
config ME1000
tristate "Meilhaus ME-1000 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-1000 family of boards
that do data collection and multipurpose I/O.
@@ -51,7 +52,7 @@ config ME1000
config ME1400
tristate "Meilhaus ME-1400 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-1400 family of boards
that do data collection and multipurpose I/O.
@@ -62,7 +63,7 @@ config ME1400
config ME1600
tristate "Meilhaus ME-1600 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-1600 family of boards
that do data collection and multipurpose I/O.
@@ -73,7 +74,7 @@ config ME1600
config ME4600
tristate "Meilhaus ME-4600 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-4600 family of boards
that do data collection and multipurpose I/O.
@@ -84,7 +85,7 @@ config ME4600
config ME6000
tristate "Meilhaus ME-6000 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-6000 family of boards
that do data collection and multipurpose I/O.
@@ -95,7 +96,7 @@ config ME6000
config ME8100
tristate "Meilhaus ME-8100 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-8100 family of boards
that do data collection and multipurpose I/O.
@@ -106,7 +107,7 @@ config ME8100
config ME8200
tristate "Meilhaus ME-8200 support"
default n
- depends on PCI
+ depends on PCI && m
help
This driver supports the Meilhaus ME-8200 family of boards
that do data collection and multipurpose I/O.
@@ -117,7 +118,7 @@ config ME8200
config MEDUMMY
tristate "Meilhaus dummy driver"
default n
- depends on PCI
+ depends on PCI && m
help
This provides a dummy driver for the Meilhaus driver package
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 5ffe269c2382..ab69c1bf36a8 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -622,7 +622,7 @@ static int set_ctrl_bits(void)
}
/* sets ctrl & data port bits according to current signals values */
-static void set_bits(void)
+static void panel_set_bits(void)
{
set_data_bits();
set_ctrl_bits();
@@ -707,12 +707,12 @@ static void lcd_send_serial(int byte)
*/
for (bit = 0; bit < 8; bit++) {
bits.cl = BIT_CLR; /* CLK low */
- set_bits();
+ panel_set_bits();
bits.da = byte & 1;
- set_bits();
+ panel_set_bits();
udelay(2); /* maintain the data during 2 us before CLK up */
bits.cl = BIT_SET; /* CLK high */
- set_bits();
+ panel_set_bits();
udelay(1); /* maintain the strobe during 1 us */
byte >>= 1;
}
@@ -727,7 +727,7 @@ static void lcd_backlight(int on)
/* The backlight is activated by seting the AUTOFEED line to +5V */
spin_lock(&pprt_lock);
bits.bl = on;
- set_bits();
+ panel_set_bits();
spin_unlock(&pprt_lock);
}
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
index ec343ef53a85..0d111ddfabb2 100644
--- a/drivers/staging/poch/poch.c
+++ b/drivers/staging/poch/poch.c
@@ -1026,7 +1026,7 @@ static int poch_ioctl(struct inode *inode, struct file *filp,
}
break;
case POCH_IOC_GET_COUNTERS:
- if (access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
+ if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters)))
return -EFAULT;
spin_lock_irq(&channel->counters_lock);
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 72e209276ea7..22f93dd0ba03 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -406,8 +406,20 @@ void usbip_start_threads(struct usbip_device *ud)
/*
* threads are invoked per one device (per one connection).
*/
- kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0);
- kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0);
+ int retval;
+
+ retval = kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0);
+ if (retval < 0) {
+ printk(KERN_ERR "Creating tcp_rx thread for ud %p failed.\n",
+ ud);
+ return;
+ }
+ retval = kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0);
+ if (retval < 0) {
+ printk(KERN_ERR "Creating tcp_tx thread for ud %p failed.\n",
+ ud);
+ return;
+ }
/* confirm threads are starting */
wait_for_completion(&ud->tcp_rx.thread_done);
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c
index f77f62a4b325..e5bd4470a570 100644
--- a/drivers/tc/tc.c
+++ b/drivers/tc/tc.c
@@ -86,7 +86,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
slot);
goto out_err;
}
- sprintf(tdev->dev.bus_id, "tc%x", slot);
+ dev_set_name(&tdev->dev, "tc%x", slot);
tdev->bus = tbus;
tdev->dev.parent = &tbus->dev;
tdev->dev.bus = &tc_bus_type;
@@ -104,7 +104,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
tdev->vendor[8] = 0;
tdev->name[8] = 0;
- pr_info("%s: %s %s %s\n", tdev->dev.bus_id, tdev->vendor,
+ pr_info("%s: %s %s %s\n", dev_name(&tdev->dev), tdev->vendor,
tdev->name, tdev->firmware);
devsize = readb(module + offset + TC_SLOT_SIZE);
@@ -118,7 +118,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus)
} else {
printk(KERN_ERR "%s: Cannot provide slot space "
"(%dMiB required, up to %dMiB supported)\n",
- tdev->dev.bus_id, devsize >> 20,
+ dev_name(&tdev->dev), devsize >> 20,
max(slotsize, extslotsize) >> 20);
kfree(tdev);
goto out_err;
@@ -146,7 +146,7 @@ static int __init tc_init(void)
return 0;
INIT_LIST_HEAD(&tc_bus.devices);
- strcpy(tc_bus.dev.bus_id, "tc");
+ dev_set_name(&tc_bus.dev, "tc");
device_register(&tc_bus.dev);
if (tc_bus.info.slot_size) {
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 04b954cfce76..7f86534de269 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -58,6 +58,24 @@ config UIO_SMX
If you compile this as a module, it will be called uio_smx.
+config UIO_AEC
+ tristate "AEC video timestamp device"
+ depends on PCI
+ default n
+ help
+
+ UIO driver for the Adrienne Electronics Corporation PCI time
+ code device.
+
+ This device differs from other UIO devices since it uses I/O
+ ports instead of memory mapped I/O. In order to make it
+ possible for UIO to work with this device a utility, uioport,
+ can be used to read and write the ports:
+
+ git clone git://ifup.org/philips/uioport.git
+
+ If you compile this as a module, it will be called uio_aec.
+
config UIO_SERCOS3
tristate "Automata Sercos III PCI card driver"
default n
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index e69558149859..5c2586d75797 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -3,4 +3,5 @@ obj-$(CONFIG_UIO_CIF) += uio_cif.o
obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
obj-$(CONFIG_UIO_SMX) += uio_smx.o
+obj-$(CONFIG_UIO_AEC) += uio_aec.o
obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 4ca85a113aa2..03efb065455f 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -61,6 +61,14 @@ struct uio_map {
};
#define to_map(map) container_of(map, struct uio_map, kobj)
+static ssize_t map_name_show(struct uio_mem *mem, char *buf)
+{
+ if (unlikely(!mem->name))
+ mem->name = "";
+
+ return sprintf(buf, "%s\n", mem->name);
+}
+
static ssize_t map_addr_show(struct uio_mem *mem, char *buf)
{
return sprintf(buf, "0x%lx\n", mem->addr);
@@ -82,6 +90,8 @@ struct map_sysfs_entry {
ssize_t (*store)(struct uio_mem *, const char *, size_t);
};
+static struct map_sysfs_entry name_attribute =
+ __ATTR(name, S_IRUGO, map_name_show, NULL);
static struct map_sysfs_entry addr_attribute =
__ATTR(addr, S_IRUGO, map_addr_show, NULL);
static struct map_sysfs_entry size_attribute =
@@ -90,6 +100,7 @@ static struct map_sysfs_entry offset_attribute =
__ATTR(offset, S_IRUGO, map_offset_show, NULL);
static struct attribute *attrs[] = {
+ &name_attribute.attr,
&addr_attribute.attr,
&size_attribute.attr,
&offset_attribute.attr,
@@ -133,6 +144,14 @@ struct uio_portio {
};
#define to_portio(portio) container_of(portio, struct uio_portio, kobj)
+static ssize_t portio_name_show(struct uio_port *port, char *buf)
+{
+ if (unlikely(!port->name))
+ port->name = "";
+
+ return sprintf(buf, "%s\n", port->name);
+}
+
static ssize_t portio_start_show(struct uio_port *port, char *buf)
{
return sprintf(buf, "0x%lx\n", port->start);
@@ -159,6 +178,8 @@ struct portio_sysfs_entry {
ssize_t (*store)(struct uio_port *, const char *, size_t);
};
+static struct portio_sysfs_entry portio_name_attribute =
+ __ATTR(name, S_IRUGO, portio_name_show, NULL);
static struct portio_sysfs_entry portio_start_attribute =
__ATTR(start, S_IRUGO, portio_start_show, NULL);
static struct portio_sysfs_entry portio_size_attribute =
@@ -167,6 +188,7 @@ static struct portio_sysfs_entry portio_porttype_attribute =
__ATTR(porttype, S_IRUGO, portio_porttype_show, NULL);
static struct attribute *portio_attrs[] = {
+ &portio_name_attribute.attr,
&portio_start_attribute.attr,
&portio_size_attribute.attr,
&portio_porttype_attribute.attr,
@@ -686,7 +708,8 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma)
return -EINVAL;
requested_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
- actual_pages = (idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
+ actual_pages = ((idev->info->mem[mi].addr & ~PAGE_MASK)
+ + idev->info->mem[mi].size + PAGE_SIZE -1) >> PAGE_SHIFT;
if (requested_pages > actual_pages)
return -EINVAL;
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c
new file mode 100644
index 000000000000..b7830e9a3baa
--- /dev/null
+++ b/drivers/uio/uio_aec.c
@@ -0,0 +1,175 @@
+/*
+ * uio_aec.c -- simple driver for Adrienne Electronics Corp time code PCI device
+ *
+ * Copyright (C) 2008 Brandon Philips <brandon@ifup.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * 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/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/uio_driver.h>
+
+#define PCI_VENDOR_ID_AEC 0xaecb
+#define PCI_DEVICE_ID_AEC_VITCLTC 0x6250
+
+#define INT_ENABLE_ADDR 0xFC
+#define INT_ENABLE 0x10
+#define INT_DISABLE 0x0
+
+#define INT_MASK_ADDR 0x2E
+#define INT_MASK_ALL 0x3F
+
+#define INTA_DRVR_ADDR 0xFE
+#define INTA_ENABLED_FLAG 0x08
+#define INTA_FLAG 0x01
+
+#define MAILBOX 0x0F
+
+static struct pci_device_id ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AEC, PCI_DEVICE_ID_AEC_VITCLTC), },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, ids);
+
+static irqreturn_t aectc_irq(int irq, struct uio_info *dev_info)
+{
+ void __iomem *int_flag = dev_info->priv + INTA_DRVR_ADDR;
+ unsigned char status = ioread8(int_flag);
+
+
+ if ((status & INTA_ENABLED_FLAG) && (status & INTA_FLAG)) {
+ /* application writes 0x00 to 0x2F to get next interrupt */
+ status = ioread8(dev_info->priv + MAILBOX);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void print_board_data(struct pci_dev *pdev, struct uio_info *i)
+{
+ dev_info(&pdev->dev, "PCI-TC board vendor: %x%x number: %x%x"
+ " revision: %c%c\n",
+ ioread8(i->priv + 0x01),
+ ioread8(i->priv + 0x00),
+ ioread8(i->priv + 0x03),
+ ioread8(i->priv + 0x02),
+ ioread8(i->priv + 0x06),
+ ioread8(i->priv + 0x07));
+}
+
+static int __devinit probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct uio_info *info;
+ int ret;
+
+ info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ if (pci_enable_device(pdev))
+ goto out_free;
+
+ if (pci_request_regions(pdev, "aectc"))
+ goto out_disable;
+
+ info->name = "aectc";
+ info->port[0].start = pci_resource_start(pdev, 0);
+ if (!info->port[0].start)
+ goto out_release;
+ info->priv = pci_iomap(pdev, 0, 0);
+ if (!info->priv)
+ goto out_release;
+ info->port[0].size = pci_resource_len(pdev, 0);
+ info->port[0].porttype = UIO_PORT_GPIO;
+
+ info->version = "0.0.1";
+ info->irq = pdev->irq;
+ info->irq_flags = IRQF_SHARED;
+ info->handler = aectc_irq;
+
+ print_board_data(pdev, info);
+ ret = uio_register_device(&pdev->dev, info);
+ if (ret)
+ goto out_unmap;
+
+ iowrite32(INT_ENABLE, info->priv + INT_ENABLE_ADDR);
+ iowrite8(INT_MASK_ALL, info->priv + INT_MASK_ADDR);
+ if (!(ioread8(info->priv + INTA_DRVR_ADDR)
+ & INTA_ENABLED_FLAG))
+ dev_err(&pdev->dev, "aectc: interrupts not enabled\n");
+
+ pci_set_drvdata(pdev, info);
+
+ return 0;
+
+out_unmap:
+ pci_iounmap(pdev, info->priv);
+out_release:
+ pci_release_regions(pdev);
+out_disable:
+ pci_disable_device(pdev);
+out_free:
+ kfree(info);
+ return -ENODEV;
+}
+
+static void remove(struct pci_dev *pdev)
+{
+ struct uio_info *info = pci_get_drvdata(pdev);
+
+ /* disable interrupts */
+ iowrite8(INT_DISABLE, info->priv + INT_MASK_ADDR);
+ iowrite32(INT_DISABLE, info->priv + INT_ENABLE_ADDR);
+ /* read mailbox to ensure board drops irq */
+ ioread8(info->priv + MAILBOX);
+
+ uio_unregister_device(info);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ iounmap(info->priv);
+
+ kfree(info);
+}
+
+static struct pci_driver pci_driver = {
+ .name = "aectc",
+ .id_table = ids,
+ .probe = probe,
+ .remove = remove,
+};
+
+static int __init aectc_init(void)
+{
+ return pci_register_driver(&pci_driver);
+}
+
+static void __exit aectc_exit(void)
+{
+ pci_unregister_driver(&pci_driver);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(aectc_init);
+module_exit(aectc_exit);
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 8b7c419b876e..89299a5ce168 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -11,12 +11,15 @@ obj-$(CONFIG_USB_MON) += mon/
obj-$(CONFIG_PCI) += host/
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_ISP116X_HCD) += host/
+obj-$(CONFIG_USB_ISP1760_HCD) += host/
obj-$(CONFIG_USB_OHCI_HCD) += host/
obj-$(CONFIG_USB_UHCI_HCD) += host/
+obj-$(CONFIG_USB_FHCI_HCD) += host/
obj-$(CONFIG_USB_SL811_HCD) += host/
obj-$(CONFIG_USB_U132_HCD) += host/
obj-$(CONFIG_USB_R8A66597_HCD) += host/
obj-$(CONFIG_USB_HWA_HCD) += host/
+obj-$(CONFIG_USB_ISP1760_HCD) += host/
obj-$(CONFIG_USB_C67X00_HCD) += c67x00/
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 00b47ea24f86..b3d5a23ab56f 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1349,6 +1349,9 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
{ USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
@@ -1370,6 +1373,18 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
+ { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
+ },
+ { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
+ .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
+ data interface instead of
+ communications interface.
+ Maybe we should define a new
+ quirk for this. */
+ },
/* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index b5775af3ba26..d2747a49b974 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -226,6 +226,7 @@ static const struct quirk_printer_struct quirk_printers[] = {
{ 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
{ 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
{ 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
+ { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
{ 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
{ 0, 0 }
};
@@ -879,16 +880,19 @@ static int usblp_wwait(struct usblp *usblp, int nonblock)
if (rc <= 0)
break;
- if (usblp->flags & LP_ABORT) {
- if (schedule_timeout(msecs_to_jiffies(5000)) == 0) {
+ if (schedule_timeout(msecs_to_jiffies(1500)) == 0) {
+ if (usblp->flags & LP_ABORT) {
err = usblp_check_status(usblp, err);
if (err == 1) { /* Paper out */
rc = -ENOSPC;
break;
}
+ } else {
+ /* Prod the printer, Gentoo#251237. */
+ mutex_lock(&usblp->mut);
+ usblp_read_status(usblp, usblp->statusbuf);
+ mutex_unlock(&usblp->mut);
}
- } else {
- schedule();
}
}
set_current_state(TASK_RUNNING);
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 6ec38175a817..73c108d117b4 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -187,7 +187,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,
}
/* this isn't checking for illegal values */
- switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(desc)) {
case USB_ENDPOINT_XFER_CONTROL:
type = "Ctrl";
if (speed == USB_SPEED_HIGH) /* uframes per NAK */
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 26fece124e0e..00f475314119 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -530,7 +530,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
{
int ret = 0;
- if (ps->dev->state != USB_STATE_ADDRESS
+ if (ps->dev->state != USB_STATE_UNAUTHENTICATED
+ && ps->dev->state != USB_STATE_ADDRESS
&& ps->dev->state != USB_STATE_CONFIGURED)
return -EHOSTUNREACH;
if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
@@ -1700,7 +1701,7 @@ const struct file_operations usbdev_file_operations = {
.release = usbdev_release,
};
-void usb_fs_classdev_common_remove(struct usb_device *udev)
+static void usbdev_remove(struct usb_device *udev)
{
struct dev_state *ps;
struct siginfo sinfo;
@@ -1742,10 +1743,15 @@ static void usb_classdev_remove(struct usb_device *dev)
{
if (dev->usb_classdev)
device_unregister(dev->usb_classdev);
- usb_fs_classdev_common_remove(dev);
}
-static int usb_classdev_notify(struct notifier_block *self,
+#else
+#define usb_classdev_add(dev) 0
+#define usb_classdev_remove(dev) do {} while (0)
+
+#endif
+
+static int usbdev_notify(struct notifier_block *self,
unsigned long action, void *dev)
{
switch (action) {
@@ -1755,15 +1761,15 @@ static int usb_classdev_notify(struct notifier_block *self,
break;
case USB_DEVICE_REMOVE:
usb_classdev_remove(dev);
+ usbdev_remove(dev);
break;
}
return NOTIFY_OK;
}
static struct notifier_block usbdev_nb = {
- .notifier_call = usb_classdev_notify,
+ .notifier_call = usbdev_notify,
};
-#endif
static struct cdev usb_device_cdev;
@@ -1798,9 +1804,8 @@ int __init usb_devio_init(void)
* to /sys/dev
*/
usb_classdev_class->dev_kobj = NULL;
-
- usb_register_notify(&usbdev_nb);
#endif
+ usb_register_notify(&usbdev_nb);
out:
return retval;
@@ -1811,8 +1816,8 @@ error_cdev:
void usb_devio_cleanup(void)
{
-#ifdef CONFIG_USB_DEVICE_CLASS
usb_unregister_notify(&usbdev_nb);
+#ifdef CONFIG_USB_DEVICE_CLASS
class_destroy(usb_classdev_class);
#endif
cdev_del(&usb_device_cdev);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 98760553bc95..d0a21a5f8201 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -284,7 +284,7 @@ static int usb_unbind_interface(struct device *dev)
* supports "soft" unbinding.
*/
if (!driver->soft_unbind)
- usb_disable_interface(udev, intf);
+ usb_disable_interface(udev, intf, false);
driver->disconnect(intf);
usb_cancel_queued_reset(intf);
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index e1710f260b4f..40dee2ac0133 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -66,7 +66,7 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr,
struct ep_device *ep = to_ep_device(dev);
char *type = "unknown";
- switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(ep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
type = "Control";
break;
@@ -94,7 +94,7 @@ static ssize_t show_ep_interval(struct device *dev,
in = (ep->desc->bEndpointAddress & USB_DIR_IN);
- switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(ep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */
interval = ep->desc->bInterval;
@@ -131,10 +131,9 @@ static ssize_t show_ep_direction(struct device *dev,
struct ep_device *ep = to_ep_device(dev);
char *direction;
- if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_CONTROL)
+ if (usb_endpoint_xfer_control(ep->desc))
direction = "both";
- else if (ep->desc->bEndpointAddress & USB_DIR_IN)
+ else if (usb_endpoint_dir_in(ep->desc))
direction = "in";
else
direction = "out";
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 507741ed4482..a4301dc02d27 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -128,7 +128,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
}
pci_set_master(dev);
- device_set_wakeup_enable(&dev->dev, 1);
retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED);
if (retval != 0)
@@ -201,6 +200,7 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
struct usb_hcd *hcd = pci_get_drvdata(dev);
int retval = 0;
int wake, w;
+ int has_pci_pm;
/* Root hub suspend should have stopped all downstream traffic,
* and all bus master traffic. And done so for both the interface
@@ -230,6 +230,15 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
synchronize_irq(dev->irq);
+ /* Downstream ports from this root hub should already be quiesced, so
+ * there will be no DMA activity. Now we can shut down the upstream
+ * link (except maybe for PME# resume signaling) and enter some PCI
+ * low power state, if the hardware allows.
+ */
+ pci_disable_device(dev);
+
+ pci_save_state(dev);
+
/* Don't fail on error to enable wakeup. We rely on pci code
* to reject requests the hardware can't implement, rather
* than coding the same thing.
@@ -241,35 +250,6 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message)
wake = w;
dev_dbg(&dev->dev, "wakeup: %d\n", wake);
- /* Downstream ports from this root hub should already be quiesced, so
- * there will be no DMA activity. Now we can shut down the upstream
- * link (except maybe for PME# resume signaling) and enter some PCI
- * low power state, if the hardware allows.
- */
- pci_disable_device(dev);
- done:
- return retval;
-}
-EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend);
-
-/**
- * usb_hcd_pci_suspend_late - suspend a PCI-based HCD after IRQs are disabled
- * @dev: USB Host Controller being suspended
- * @message: Power Management message describing this state transition
- *
- * Store this function in the HCD's struct pci_driver as .suspend_late.
- */
-int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t message)
-{
- int retval = 0;
- int has_pci_pm;
-
- /* We might already be suspended (runtime PM -- not yet written) */
- if (dev->current_state != PCI_D0)
- goto done;
-
- pci_save_state(dev);
-
/* Don't change state if we don't need to */
if (message.event == PM_EVENT_FREEZE ||
message.event == PM_EVENT_PRETHAW) {
@@ -315,18 +295,18 @@ int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t message)
done:
return retval;
}
-EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend_late);
+EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend);
/**
- * usb_hcd_pci_resume_early - resume a PCI-based HCD before IRQs are enabled
+ * usb_hcd_pci_resume - power management resume of a PCI-based HCD
* @dev: USB Host Controller being resumed
*
- * Store this function in the HCD's struct pci_driver as .resume_early.
+ * Store this function in the HCD's struct pci_driver as .resume.
*/
-int usb_hcd_pci_resume_early(struct pci_dev *dev)
+int usb_hcd_pci_resume(struct pci_dev *dev)
{
- int retval = 0;
- pci_power_t state = dev->current_state;
+ struct usb_hcd *hcd;
+ int retval;
#ifdef CONFIG_PPC_PMAC
/* Reenable ASIC clocks for USB */
@@ -340,63 +320,7 @@ int usb_hcd_pci_resume_early(struct pci_dev *dev)
}
#endif
- /* NOTE: chip docs cover clean "real suspend" cases (what Linux
- * calls "standby", "suspend to RAM", and so on). There are also
- * dirty cases when swsusp fakes a suspend in "shutdown" mode.
- */
- if (state != PCI_D0) {
-#ifdef DEBUG
- int pci_pm;
- u16 pmcr;
-
- pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
- pci_read_config_word(dev, pci_pm + PCI_PM_CTRL, &pmcr);
- pmcr &= PCI_PM_CTRL_STATE_MASK;
- if (pmcr) {
- /* Clean case: power to USB and to HC registers was
- * maintained; remote wakeup is easy.
- */
- dev_dbg(&dev->dev, "resume from PCI D%d\n", pmcr);
- } else {
- /* Clean: HC lost Vcc power, D0 uninitialized
- * + Vaux may have preserved port and transceiver
- * state ... for remote wakeup from D3cold
- * + or not; HCD must reinit + re-enumerate
- *
- * Dirty: D0 semi-initialized cases with swsusp
- * + after BIOS init
- * + after Linux init (HCD statically linked)
- */
- dev_dbg(&dev->dev, "resume from previous PCI D%d\n",
- state);
- }
-#endif
-
- retval = pci_set_power_state(dev, PCI_D0);
- } else {
- /* Same basic cases: clean (powered/not), dirty */
- dev_dbg(&dev->dev, "PCI legacy resume\n");
- }
-
- if (retval < 0)
- dev_err(&dev->dev, "can't resume: %d\n", retval);
- else
- pci_restore_state(dev);
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(usb_hcd_pci_resume_early);
-
-/**
- * usb_hcd_pci_resume - power management resume of a PCI-based HCD
- * @dev: USB Host Controller being resumed
- *
- * Store this function in the HCD's struct pci_driver as .resume.
- */
-int usb_hcd_pci_resume(struct pci_dev *dev)
-{
- struct usb_hcd *hcd;
- int retval;
+ pci_restore_state(dev);
hcd = pci_get_drvdata(dev);
if (hcd->state != HC_STATE_SUSPENDED) {
@@ -405,6 +329,8 @@ int usb_hcd_pci_resume(struct pci_dev *dev)
return 0;
}
+ pci_enable_wake(dev, PCI_D0, false);
+
retval = pci_enable_device(dev);
if (retval < 0) {
dev_err(&dev->dev, "can't re-enable after resume, %d!\n",
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 3c711db55d86..0eee32a65e23 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -901,7 +901,7 @@ static int register_root_hub(struct usb_hcd *hcd)
mutex_lock(&usb_bus_list_lock);
- usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+ usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
if (retval != sizeof usb_dev->descriptor) {
mutex_unlock(&usb_bus_list_lock);
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 572d2cf46e8d..f750eb1ab595 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -257,8 +257,6 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev);
#ifdef CONFIG_PM
extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg);
-extern int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t msg);
-extern int usb_hcd_pci_resume_early(struct pci_dev *dev);
extern int usb_hcd_pci_resume(struct pci_dev *dev);
#endif /* CONFIG_PM */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 94d5ee263c20..f17d9ebc44af 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev,
recursively_mark_NOTATTACHED(udev);
spin_unlock_irqrestore(&device_state_lock, flags);
}
+EXPORT_SYMBOL_GPL(usb_set_device_state);
/*
* WUSB devices are simple: they have no hubs behind, so the mapping
@@ -2382,8 +2383,8 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)
void usb_ep0_reinit(struct usb_device *udev)
{
- usb_disable_endpoint(udev, 0 + USB_DIR_IN);
- usb_disable_endpoint(udev, 0 + USB_DIR_OUT);
+ usb_disable_endpoint(udev, 0 + USB_DIR_IN, true);
+ usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true);
usb_enable_endpoint(udev, &udev->ep0, true);
}
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
@@ -2471,20 +2472,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
*/
switch (udev->speed) {
case USB_SPEED_VARIABLE: /* fixed at 512 */
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
break;
case USB_SPEED_HIGH: /* fixed at 64 */
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
break;
case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
/* to determine the ep0 maxpacket size, try to read
* the device descriptor to get bMaxPacketSize0 and
* then correct our initial guess.
*/
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
break;
case USB_SPEED_LOW: /* fixed at 8 */
- udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8);
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
break;
default:
goto fail;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 2a129cb7bb56..dff5760a37f6 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -717,7 +717,6 @@ static void usbfs_remove_device(struct usb_device *dev)
fs_remove_file (dev->usbfs_dentry);
dev->usbfs_dentry = NULL;
}
- usb_fs_classdev_common_remove(dev);
}
static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index de51667dd64d..49e7f56e0d7f 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type,
if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
- result = -EPROTO;
+ result = -ENODATA;
continue;
}
break;
@@ -696,8 +696,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid,
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(USB_DT_STRING << 8) + index, langid, buf, size,
USB_CTRL_GET_TIMEOUT);
- if (!(result == 0 || result == -EPIPE))
- break;
+ if (result == 0 || result == -EPIPE)
+ continue;
+ if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) {
+ result = -ENODATA;
+ continue;
+ }
+ break;
}
return result;
}
@@ -1039,14 +1044,15 @@ static void remove_intf_ep_devs(struct usb_interface *intf)
* @dev: the device whose endpoint is being disabled
* @epaddr: the endpoint's address. Endpoint number for output,
* endpoint number + USB_DIR_IN for input
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ * controller hardware
*
- * Deallocates hcd/hardware state for this endpoint ... and nukes all
- * pending urbs.
- *
- * If the HCD hasn't registered a disable() function, this sets the
- * endpoint's maxpacket size to 0 to prevent further submissions.
+ * Disables the endpoint for URB submission and nukes all pending URBs.
+ * If @reset_hardware is set then also deallocates hcd/hardware state
+ * for the endpoint.
*/
-void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
+void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+ bool reset_hardware)
{
unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
struct usb_host_endpoint *ep;
@@ -1056,15 +1062,18 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
if (usb_endpoint_out(epaddr)) {
ep = dev->ep_out[epnum];
- dev->ep_out[epnum] = NULL;
+ if (reset_hardware)
+ dev->ep_out[epnum] = NULL;
} else {
ep = dev->ep_in[epnum];
- dev->ep_in[epnum] = NULL;
+ if (reset_hardware)
+ dev->ep_in[epnum] = NULL;
}
if (ep) {
ep->enabled = 0;
usb_hcd_flush_endpoint(dev, ep);
- usb_hcd_disable_endpoint(dev, ep);
+ if (reset_hardware)
+ usb_hcd_disable_endpoint(dev, ep);
}
}
@@ -1072,17 +1081,21 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
* usb_disable_interface -- Disable all endpoints for an interface
* @dev: the device whose interface is being disabled
* @intf: pointer to the interface descriptor
+ * @reset_hardware: flag to erase any endpoint state stored in the
+ * controller hardware
*
* Disables all the endpoints for the interface's current altsetting.
*/
-void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf)
+void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
+ bool reset_hardware)
{
struct usb_host_interface *alt = intf->cur_altsetting;
int i;
for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
usb_disable_endpoint(dev,
- alt->endpoint[i].desc.bEndpointAddress);
+ alt->endpoint[i].desc.bEndpointAddress,
+ reset_hardware);
}
}
@@ -1103,8 +1116,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
skip_ep0 ? "non-ep0" : "all");
for (i = skip_ep0; i < 16; ++i) {
- usb_disable_endpoint(dev, i);
- usb_disable_endpoint(dev, i + USB_DIR_IN);
+ usb_disable_endpoint(dev, i, true);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}
dev->toggle[0] = dev->toggle[1] = 0;
@@ -1274,7 +1287,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
remove_intf_ep_devs(iface);
usb_remove_sysfs_intf_files(iface);
}
- usb_disable_interface(dev, iface);
+ usb_disable_interface(dev, iface, true);
iface->cur_altsetting = alt;
@@ -1353,8 +1366,8 @@ int usb_reset_configuration(struct usb_device *dev)
*/
for (i = 1; i < 16; ++i) {
- usb_disable_endpoint(dev, i);
- usb_disable_endpoint(dev, i + USB_DIR_IN);
+ usb_disable_endpoint(dev, i, true);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, true);
}
config = dev->actconfig;
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 58bc5e3c2560..7025d801f23a 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -295,7 +295,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
dev = urb->dev;
- if ((!dev) || (dev->state < USB_STATE_DEFAULT))
+ if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED))
return -ENODEV;
/* For now, get the endpoint from the pipe. Eventually drivers
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 386177867a8a..79d8a9ea559b 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -15,9 +15,10 @@ extern void usb_enable_endpoint(struct usb_device *dev,
struct usb_host_endpoint *ep, bool reset_toggle);
extern void usb_enable_interface(struct usb_device *dev,
struct usb_interface *intf, bool reset_toggles);
-extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr);
+extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
+ bool reset_hardware);
extern void usb_disable_interface(struct usb_device *dev,
- struct usb_interface *intf);
+ struct usb_interface *intf, bool reset_hardware);
extern void usb_release_interface_cache(struct kref *ref);
extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
extern int usb_deauthorize_device(struct usb_device *);
@@ -151,7 +152,6 @@ extern struct usb_driver usbfs_driver;
extern const struct file_operations usbfs_devices_fops;
extern const struct file_operations usbdev_file_operations;
extern void usbfs_conn_disc_event(void);
-extern void usb_fs_classdev_common_remove(struct usb_device *udev);
extern int usb_devio_init(void);
extern void usb_devio_cleanup(void);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3219d137340a..770b3eaa9184 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -191,6 +191,7 @@ config USB_GADGET_OMAP
boolean "OMAP USB Device Controller"
depends on ARCH_OMAP
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
+ select USB_OTG_UTILS if ARCH_OMAP
help
Many Texas Instruments OMAP processors have flexible full
speed USB device controllers, with support for up to 30
@@ -253,6 +254,7 @@ config USB_PXA25X_SMALL
config USB_GADGET_PXA27X
boolean "PXA 27x"
depends on ARCH_PXA && PXA27x
+ select USB_OTG_UTILS
help
Intel's PXA 27x series XScale ARM v5TE processors include
an integrated full speed USB 1.1 device controller.
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index abf8192f89e8..826f3adde5d8 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -551,7 +551,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
dma_desc->status = AMD_ADDBITS(dma_desc->status,
UDC_DMA_STP_STS_BS_HOST_BUSY,
UDC_DMA_STP_STS_BS);
- dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE);
+ dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE);
req->td_data = dma_desc;
req->td_data_last = NULL;
req->chain_len = 1;
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 65b03e3445a1..c22fab164113 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0,
.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .wMaxPacketSize = cpu_to_le16(64),
/* FIXME: I have no idea what to put here */
.bInterval = 1,
};
@@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc)
/* Avoid overly long expressions */
static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
+ if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
return true;
return false;
}
static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE))
+ if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE))
return true;
return false;
}
static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT))
+ if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT))
return true;
return false;
}
@@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
status = cpu_to_le16(udc->devstatus);
} else if (crq->bRequestType
== (USB_DIR_IN | USB_RECIP_INTERFACE)) {
- status = __constant_cpu_to_le16(0);
+ status = cpu_to_le16(0);
} else if (crq->bRequestType
== (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
struct usba_ep *target;
@@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
status = 0;
if (is_stalled(udc, target))
- status |= __constant_cpu_to_le16(1);
+ status |= cpu_to_le16(1);
} else
goto delegate;
/* Write directly to the FIFO. No queueing is done. */
- if (crq->wLength != __constant_cpu_to_le16(sizeof(status)))
+ if (crq->wLength != cpu_to_le16(sizeof(status)))
goto stall;
ep->state = DATA_STAGE_IN;
__raw_writew(status, ep->fifo);
@@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
struct usba_ep *target;
- if (crq->wLength != __constant_cpu_to_le16(0)
+ if (crq->wLength != cpu_to_le16(0)
|| !feature_is_ep_halt(crq))
goto stall;
target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
@@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
struct usba_ep *target;
- if (crq->wLength != __constant_cpu_to_le16(0)
+ if (crq->wLength != cpu_to_le16(0)
|| !feature_is_ep_halt(crq))
goto stall;
@@ -1514,7 +1514,7 @@ restart:
*/
ep->state = DATA_STAGE_IN;
} else {
- if (crq.crq.wLength != __constant_cpu_to_le16(0))
+ if (crq.crq.wLength != cpu_to_le16(0))
ep->state = DATA_STAGE_OUT;
else
ep->state = STATUS_STAGE_IN;
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 5495b171cf29..928137d3dbdc 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_COMM,
.bDeviceSubClass = 0,
@@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = {
/* .bMaxPacketSize0 = f(hardware) */
/* Vendor and product id can be overridden by module parameters. */
- .idVendor = __constant_cpu_to_le16(CDC_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(CDC_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(CDC_VENDOR_NUM),
+ .idProduct = cpu_to_le16(CDC_PRODUCT_NUM),
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
@@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
gadget->name,
cdc_config_driver.label);
device_desc.bcdDevice =
- __constant_cpu_to_le16(0x0300 | 0x0099);
+ cpu_to_le16(0x0300 | 0x0099);
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index bebf911c7e5f..22c65960c429 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -56,7 +56,6 @@
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
@@ -2626,7 +2625,7 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name)
INIT_LIST_HEAD(&udc->gadget.ep_list);
udc->gadget.ep0 = NULL;
- strcpy(udc->gadget.dev.bus_id, "gadget");
+ dev_set_name(&udc->gadget.dev, "gadget");
udc->gadget.dev.dma_mask = dev->dma_mask;
udc->gadget.dev.parent = dev;
udc->gadget.dev.release = udc_release;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f2da0269e1b1..40f1da77a006 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -149,16 +149,17 @@ done:
int usb_function_deactivate(struct usb_function *function)
{
struct usb_composite_dev *cdev = function->config->cdev;
+ unsigned long flags;
int status = 0;
- spin_lock(&cdev->lock);
+ spin_lock_irqsave(&cdev->lock, flags);
if (cdev->deactivations == 0)
status = usb_gadget_disconnect(cdev->gadget);
if (status == 0)
cdev->deactivations++;
- spin_unlock(&cdev->lock);
+ spin_unlock_irqrestore(&cdev->lock, flags);
return status;
}
@@ -683,6 +684,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
struct usb_request *req = cdev->req;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
+ u8 intf = w_index & 0xFF;
u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
struct usb_function *f = NULL;
@@ -769,10 +771,10 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
goto unknown;
if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
break;
- f = cdev->config->interface[w_index];
+ f = cdev->config->interface[intf];
if (!f)
break;
- if (w_value && !f->get_alt)
+ if (w_value && !f->set_alt)
break;
value = f->set_alt(f, w_index, w_value);
break;
@@ -781,7 +783,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
goto unknown;
if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
break;
- f = cdev->config->interface[w_index];
+ f = cdev->config->interface[intf];
if (!f)
break;
/* lots of interfaces only need altsetting zero... */
@@ -808,7 +810,7 @@ unknown:
*/
if ((ctrl->bRequestType & USB_RECIP_MASK)
== USB_RECIP_INTERFACE) {
- f = cdev->config->interface[w_index];
+ f = cdev->config->interface[intf];
if (f && f->setup)
value = f->setup(f, ctrl);
else
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 9064696636ac..3b42888b72f8 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1626,7 +1626,7 @@ static int dummy_hub_control (
hub_descriptor ((struct usb_hub_descriptor *) buf);
break;
case GetHubStatus:
- *(__le32 *) buf = __constant_cpu_to_le32 (0);
+ *(__le32 *) buf = cpu_to_le32 (0);
break;
case GetPortStatus:
if (wIndex != 1)
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index a36b1175b18d..cd0914ec898e 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -148,7 +148,7 @@ ep_matches (
return 0;
/* BOTH: "high bandwidth" works only at high speed */
- if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
+ if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) {
if (!gadget->is_dualspeed)
return 0;
/* configure your hardware with enough buffering!! */
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 37252d0012a7..d006dc652e02 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -156,7 +156,7 @@ static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16 (0x0200),
+ .bcdUSB = cpu_to_le16 (0x0200),
.bDeviceClass = USB_CLASS_COMM,
.bDeviceSubClass = 0,
@@ -167,8 +167,8 @@ static struct usb_device_descriptor device_desc = {
* we support. (As does bNumConfigurations.) These values can
* also be overridden by module parameters.
*/
- .idVendor = __constant_cpu_to_le16 (CDC_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
+ .idVendor = cpu_to_le16 (CDC_VENDOR_NUM),
+ .idProduct = cpu_to_le16 (CDC_PRODUCT_NUM),
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
@@ -318,7 +318,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
gadget->name,
eth_config_driver.label);
device_desc.bcdDevice =
- __constant_cpu_to_le16(0x0300 | 0x0099);
+ cpu_to_le16(0x0300 | 0x0099);
}
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index c1d34df0b157..7953948bfe4a 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -125,7 +125,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = {
.bLength = sizeof(acm_header_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_call_mgmt_descriptor
@@ -159,7 +159,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+ .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
.bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL,
};
@@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+ .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
.bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
};
@@ -205,14 +205,14 @@ static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *acm_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index 4ae579948e54..ecf5bdd0ae06 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -130,7 +130,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_union_desc ecm_union_desc __initdata = {
@@ -148,9 +148,9 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = {
/* this descriptor actually adds value, surprise! */
/* .iMACAddress = DYNAMIC */
- .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
- .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
- .wNumberMCFilters = __constant_cpu_to_le16(0),
+ .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+ .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
+ .wNumberMCFilters = cpu_to_le16(0),
.bNumberPowerFilters = 0,
};
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
@@ -245,7 +245,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
@@ -254,7 +254,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 8affe1dfc2c1..83301bdcdd1a 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -100,7 +100,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_loop_sink_desc = {
@@ -108,7 +108,7 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_loopback_descs[] = {
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index 80c2e7e9622f..46d6266f30ec 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -123,7 +123,7 @@ static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
.bLength = sizeof(obex_cdc_header_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0120),
+ .bcdCDC = cpu_to_le16(0x0120),
};
static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
@@ -138,7 +138,7 @@ static struct usb_cdc_obex_desc obex_desc __initdata = {
.bLength = sizeof(obex_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_OBEX_TYPE,
- .bcdVersion = __constant_cpu_to_le16(0x0100),
+ .bcdVersion = cpu_to_le16(0x0100),
};
/* High-Speed Support */
@@ -149,7 +149,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
@@ -158,7 +158,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_function[] __initdata = {
@@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f)
f->hs_descriptors = usb_copy_descriptors(hs_function);
obex->hs.obex_in = usb_find_endpoint(hs_function,
- f->descriptors, &obex_hs_ep_in_desc);
+ f->hs_descriptors, &obex_hs_ep_in_desc);
obex->hs.obex_out = usb_find_endpoint(hs_function,
- f->descriptors, &obex_hs_ep_out_desc);
+ f->hs_descriptors, &obex_hs_ep_out_desc);
}
/* Avoid letting this gadget enumerate until the userspace
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index c0916c7b217e..c1abeb89b413 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -79,7 +79,7 @@ pn_header_desc = {
.bLength = sizeof pn_header_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static const struct usb_cdc_header_desc
@@ -87,7 +87,7 @@ pn_phonet_desc = {
.bLength = sizeof pn_phonet_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_PHONET_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x1505), /* ??? */
+ .bcdCDC = cpu_to_le16(0x1505), /* ??? */
};
static struct usb_cdc_union_desc
@@ -138,7 +138,7 @@ pn_hs_sink_desc = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor
@@ -157,7 +157,7 @@ pn_hs_source_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *fs_pn_function[] = {
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 3a8bb53fc473..3122fb9f3d59 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -137,7 +137,7 @@ static struct usb_cdc_header_desc header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = {
@@ -187,7 +187,7 @@ static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
static struct usb_endpoint_descriptor hs_in_desc __initdata = {
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_out_desc __initdata = {
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *eth_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index fe5674db344b..db0aa93606ef 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -89,14 +89,14 @@ static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *gser_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index dc84d26d2835..6aca5c81414a 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -118,7 +118,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_sink_desc = {
@@ -126,7 +126,7 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_source_sink_descs[] = {
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index fe1832875771..a9c98fdb626d 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -108,7 +108,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
@@ -116,7 +116,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_MDLM_TYPE,
- .bcdVersion = __constant_cpu_to_le16(0x0100),
+ .bcdVersion = cpu_to_le16(0x0100),
.bGUID = {
0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
@@ -144,9 +144,9 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
/* this descriptor actually adds value, surprise! */
/* .iMACAddress = DYNAMIC */
- .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
- .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
- .wNumberMCFilters = __constant_cpu_to_le16(0),
+ .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+ .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
+ .wNumberMCFilters = cpu_to_le16(0),
.bNumberPowerFilters = 0,
};
@@ -186,7 +186,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
@@ -194,7 +194,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_eth_function[] __initdata = {
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index b10fa31cc915..d3c2464dee82 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -847,13 +847,13 @@ device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
/* The next three values can be overridden by module parameters */
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID),
- .bcdDevice = __constant_cpu_to_le16(0xffff),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_ID),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID),
+ .bcdDevice = cpu_to_le16(0xffff),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
@@ -926,7 +926,7 @@ fs_intr_in_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(2),
+ .wMaxPacketSize = cpu_to_le16(2),
.bInterval = 32, // frames -> 32 ms
};
@@ -954,7 +954,7 @@ dev_qualifier = {
.bLength = sizeof dev_qualifier,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bNumConfigurations = 1,
@@ -967,7 +967,7 @@ hs_bulk_in_desc = {
/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor
@@ -977,7 +977,7 @@ hs_bulk_out_desc = {
/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
.bInterval = 1, // NAK every 1 uframe
};
@@ -988,7 +988,7 @@ hs_intr_in_desc = {
/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(2),
+ .wMaxPacketSize = cpu_to_le16(2),
.bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms
};
@@ -2646,7 +2646,7 @@ static int send_status(struct fsg_dev *fsg)
struct bulk_cs_wrap *csw = bh->buf;
/* Store and send the Bulk-only CSW */
- csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
+ csw->Signature = cpu_to_le32(USB_BULK_CS_SIG);
csw->Tag = fsg->tag;
csw->Residue = cpu_to_le32(fsg->residue);
csw->Status = status;
@@ -3089,7 +3089,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
/* Is the CBW valid? */
if (req->actual != USB_BULK_CB_WRAP_LEN ||
- cbw->Signature != __constant_cpu_to_le32(
+ cbw->Signature != cpu_to_le32(
USB_BULK_CB_SIG)) {
DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
req->actual,
@@ -3879,7 +3879,11 @@ static int __init check_parameters(struct fsg_dev *fsg)
mod_data.protocol_type = USB_SC_SCSI;
mod_data.protocol_name = "Transparent SCSI";
- if (gadget_is_sh(fsg->gadget))
+ /* Some peripheral controllers are known not to be able to
+ * halt bulk endpoints correctly. If one of them is present,
+ * disable stalls.
+ */
+ if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget))
mod_data.can_stall = 0;
if (mod_data.release == 0xffff) { // Parameter wasn't set
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index d6c5bcd40064..d701bf4698d2 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -1622,6 +1622,8 @@ static int qe_ep_disable(struct usb_ep *_ep)
nuke(ep, -ESHUTDOWN);
ep->desc = NULL;
ep->stopped = 1;
+ ep->tx_req = NULL;
+ qe_ep_reset(udc, ep->epnum);
spin_unlock_irqrestore(&udc->lock, flags);
cpm_muram_free(cpm_muram_offset(ep->rxbase));
@@ -1681,14 +1683,11 @@ static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req)
kfree(req);
}
-/* queues (submits) an I/O request to an endpoint */
-static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
- gfp_t gfp_flags)
+static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req)
{
struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
struct qe_req *req = container_of(_req, struct qe_req, req);
struct qe_udc *udc;
- unsigned long flags;
int reval;
udc = ep->udc;
@@ -1732,7 +1731,7 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
list_add_tail(&req->queue, &ep->queue);
dev_vdbg(udc->dev, "gadget have request in %s! %d\n",
ep->name, req->req.length);
- spin_lock_irqsave(&udc->lock, flags);
+
/* push the request to device */
if (ep_is_in(ep))
reval = ep_req_send(ep, req);
@@ -1748,11 +1747,24 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
if (ep->dir == USB_DIR_OUT)
reval = ep_req_receive(ep, req);
- spin_unlock_irqrestore(&udc->lock, flags);
-
return 0;
}
+/* queues (submits) an I/O request to an endpoint */
+static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+ gfp_t gfp_flags)
+{
+ struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
+ struct qe_udc *udc = ep->udc;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ ret = __qe_ep_queue(_ep, _req);
+ spin_unlock_irqrestore(&udc->lock, flags);
+ return ret;
+}
+
/* dequeues (cancels, unlinks) an I/O request from an endpoint */
static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
{
@@ -2008,7 +2020,7 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value,
udc->ep0_dir = USB_DIR_IN;
/* data phase */
- status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
+ status = __qe_ep_queue(&ep->ep, &req->req);
if (status == 0)
return;
@@ -2151,6 +2163,9 @@ static int reset_irq(struct qe_udc *udc)
{
unsigned char i;
+ if (udc->usb_state == USB_STATE_DEFAULT)
+ return 0;
+
qe_usb_disable();
out_8(&udc->usb_regs->usb_usadr, 0);
@@ -2442,8 +2457,12 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc)
struct usb_ctlr __iomem *qe_usbregs;
qe_usbregs = udc->usb_regs;
- /* Init the usb register */
+ /* Spec says that we must enable the USB controller to change mode. */
out_8(&qe_usbregs->usb_usmod, 0x01);
+ /* Mode changed, now disable it, since muram isn't initialized yet. */
+ out_8(&qe_usbregs->usb_usmod, 0x00);
+
+ /* Initialize the rest. */
out_be16(&qe_usbregs->usb_usbmr, 0);
out_8(&qe_usbregs->usb_uscom, 0);
out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR);
@@ -2604,6 +2623,10 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
(unsigned long)udc_controller);
/* request irq and disable DR */
udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
+ if (!udc_controller->usb_irq) {
+ ret = -EINVAL;
+ goto err_noirq;
+ }
ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
driver_name, udc_controller);
@@ -2625,6 +2648,8 @@ static int __devinit qe_udc_probe(struct of_device *ofdev,
err6:
free_irq(udc_controller->usb_irq, udc_controller);
err5:
+ irq_dispose_mapping(udc_controller->usb_irq);
+err_noirq:
if (udc_controller->nullmap) {
dma_unmap_single(udc_controller->gadget.dev.parent,
udc_controller->nullp, 256,
@@ -2648,7 +2673,7 @@ err2:
iounmap(udc_controller->usb_regs);
err1:
kfree(udc_controller);
-
+ udc_controller = NULL;
return ret;
}
@@ -2710,6 +2735,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev)
kfree(ep->txframe);
free_irq(udc_controller->usb_irq, udc_controller);
+ irq_dispose_mapping(udc_controller->usb_irq);
tasklet_kill(&udc_controller->rx_tasklet);
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index f3c6703cffda..9d7b95d4e3d2 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -404,7 +404,10 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num,
}
if (zlt)
tmp |= EP_QUEUE_HEAD_ZLT_SEL;
+
p_QH->max_pkt_length = cpu_to_le32(tmp);
+ p_QH->next_dtd_ptr = 1;
+ p_QH->size_ioc_int_sts = 0;
return;
}
@@ -1799,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
out:
if (retval)
- printk("gadget driver register failed %d\n", retval);
+ printk(KERN_WARNING "gadget driver register failed %d\n",
+ retval);
return retval;
}
EXPORT_SYMBOL(usb_gadget_register_driver);
@@ -1844,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc_controller->gadget.dev.driver = NULL;
udc_controller->driver = NULL;
- printk("unregistered gadget driver '%s'\n", driver->driver.name);
+ printk(KERN_WARNING "unregistered gadget driver '%s'\n",
+ driver->driver.name);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -2452,7 +2457,7 @@ module_init(udc_init);
static void __exit udc_exit(void)
{
platform_driver_unregister(&udc_driver);
- printk("%s unregistered\n", driver_desc);
+ printk(KERN_WARNING "%s unregistered\n", driver_desc);
}
module_exit(udc_exit);
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 60d3f9e9b51f..bb738bc96d4a 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1);
static struct usb_device_descriptor device_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.bNumConfigurations = 1,
@@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = {
.bLength = USB_DT_AC_HEADER_SIZE(1),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
- .bcdADC = __constant_cpu_to_le16(0x0100),
- .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
+ .bcdADC = cpu_to_le16(0x0100),
+ .wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
.bInCollection = 1,
.baInterfaceNr = {
[0] = GMIDI_MS_INTERFACE,
@@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = {
.bLength = USB_DT_MS_HEADER_SIZE,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
- .bcdMSC = __constant_cpu_to_le16(0x0100),
- .wTotalLength = __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE
+ .bcdMSC = cpu_to_le16(0x0100),
+ .wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE
+ 2*USB_DT_MIDI_IN_SIZE
+ 2*USB_DT_MIDI_OUT_SIZE(1)),
};
@@ -1227,7 +1227,7 @@ autoconf_fail:
*/
pr_warning("%s: controller '%s' not recognized\n",
shortname, gadget->name);
- device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+ device_desc.bcdDevice = cpu_to_le16(0x9999);
}
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 63419c4d503c..de010c939dbb 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev)
/* active endpoint */
if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
goto stall;
- if (ctrl.wIndex & __constant_cpu_to_le16(
+ if (ctrl.wIndex & cpu_to_le16(
USB_DIR_IN)) {
if (!dev->ep[tmp].is_in)
goto stall;
@@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev)
if (dev->ep[tmp].is_in)
goto stall;
}
- if (ctrl.wValue != __constant_cpu_to_le16(
+ if (ctrl.wValue != cpu_to_le16(
USB_ENDPOINT_HALT))
goto stall;
if (tmp)
@@ -1493,7 +1493,7 @@ succeed:
return;
case USB_RECIP_DEVICE:
/* device remote wakeup: always clear */
- if (ctrl.wValue != __constant_cpu_to_le16(1))
+ if (ctrl.wValue != cpu_to_le16(1))
goto stall;
VDBG(dev, "clear dev remote wakeup\n");
goto succeed;
@@ -1519,7 +1519,7 @@ succeed:
dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION
&& ctrl.bRequestType == USB_RECIP_DEVICE);
if (unlikely(dev->req_config))
- dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0));
+ dev->configured = (ctrl.wValue != cpu_to_le16(0));
/* delegate everything to the gadget driver.
* it may respond after this irq handler returns.
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index cde8fdf15d5b..72cc1ccbeab1 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1,7 +1,7 @@
/*
* driver/usb/gadget/imx_udc.c
*
- * Copyright (C) 2005 Mike Lee(eemike@gmail.com)
+ * Copyright (C) 2005 Mike Lee <eemike@gmail.com>
* Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/timer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -51,7 +52,8 @@ void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb,
void imx_udc_enable(struct imx_udc_struct *imx_usb)
{
int temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL);
+ __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA,
+ imx_usb->base + USB_CTRL);
imx_usb->gadget.speed = USB_SPEED_FULL;
}
@@ -126,7 +128,8 @@ void imx_udc_config(struct imx_udc_struct *imx_usb)
for (j = 0; j < 5; j++) {
__raw_writeb(ep_conf[j],
imx_usb->base + USB_DDAT);
- do {} while (__raw_readl(imx_usb->base + USB_DADR)
+ do {} while (__raw_readl(imx_usb->base
+ + USB_DADR)
& DADR_BSY);
}
}
@@ -183,7 +186,8 @@ void imx_udc_init_ep(struct imx_udc_struct *imx_usb)
temp = (EP_DIR(imx_ep) << 7) | (max << 5)
| (imx_ep->bmAttributes << 3);
__raw_writel(temp, imx_usb->base + USB_EP_STAT(i));
- __raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i));
+ __raw_writel(temp | EPSTAT_FLUSH,
+ imx_usb->base + USB_EP_STAT(i));
D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i,
__raw_readl(imx_usb->base + USB_EP_STAT(i)));
}
@@ -278,15 +282,18 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
struct imx_udc_struct *imx_usb = imx_ep->imx_usb;
int temp, i;
- D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
+ D_ERR(imx_usb->dev,
+ "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
imx_flush(imx_ep);
/* Special care for ep0 */
- if (EP_NO(imx_ep)) {
+ if (!EP_NO(imx_ep)) {
temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
- do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
+ __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR,
+ imx_usb->base + USB_CTRL);
+ do { } while (__raw_readl(imx_usb->base + USB_CTRL)
+ & CTRL_CMDOVER);
temp = __raw_readl(imx_usb->base + USB_CTRL);
__raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL);
}
@@ -296,12 +303,13 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
for (i = 0; i < 100; i ++) {
- temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
- if (!temp & EPSTAT_STALL)
+ temp = __raw_readl(imx_usb->base
+ + USB_EP_STAT(EP_NO(imx_ep)));
+ if (!(temp & EPSTAT_STALL))
break;
udelay(20);
}
- if (i == 50)
+ if (i == 100)
D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
__func__, imx_ep->ep.name);
}
@@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget)
*******************************************************************************
*/
-static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_add_request(struct imx_ep_struct *imx_ep,
+ struct imx_request *req)
{
if (unlikely(!req))
return;
@@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req
list_add_tail(&req->queue, &imx_ep->queue);
}
-static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_del_request(struct imx_ep_struct *imx_ep,
+ struct imx_request *req)
{
if (unlikely(!req))
return;
@@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req
req->in_use = 0;
}
-static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status)
+static void done(struct imx_ep_struct *imx_ep,
+ struct imx_request *req, int status)
{
ep_del_request(imx_ep, req);
@@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req)
__func__, imx_ep->ep.name, req,
completed ? "completed" : "not completed");
if (!EP_NO(imx_ep))
- ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE);
+ ep0_chg_stat(__func__,
+ imx_ep->imx_usb, EP0_IDLE);
}
}
@@ -539,8 +551,7 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
struct imx_request *req = NULL;
int ret = 0;
- if (!list_empty(&imx_ep->queue))
- req = list_entry(imx_ep->queue.next, struct imx_request, queue);
+ req = list_entry(imx_ep->queue.next, struct imx_request, queue);
if (req) {
switch (imx_ep->imx_usb->ep0state) {
@@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
}
}
+ else
+ D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
+ __func__, imx_ep->ep.name);
+
return ret;
}
@@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb)
"<%s> no setup packet received\n", __func__);
goto stall;
}
- u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep)));
+ u.word[i] = __raw_readl(imx_usb->base
+ + USB_EP_FDAT(EP_NO(imx_ep)));
}
temp = imx_ep_empty(imx_ep);
@@ -759,7 +775,7 @@ static int imx_ep_queue
*/
if (imx_usb->set_config && !EP_NO(imx_ep)) {
imx_usb->set_config = 0;
- D_EPX(imx_usb->dev,
+ D_ERR(imx_usb->dev,
"<%s> gadget reply set config\n", __func__);
return 0;
}
@@ -779,28 +795,29 @@ static int imx_ep_queue
return -ESHUTDOWN;
}
- local_irq_save(flags);
-
/* Debug */
D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
__func__, EP_NO(imx_ep),
- ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
- || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length);
+ ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+ == EP0_IN_DATA_PHASE)
+ || (EP_NO(imx_ep) && EP_DIR(imx_ep)))
+ ? "IN" : "OUT", usb_req->length);
dump_req(__func__, imx_ep, usb_req);
if (imx_ep->stopped) {
usb_req->status = -ESHUTDOWN;
- ret = -ESHUTDOWN;
- goto out;
+ return -ESHUTDOWN;
}
if (req->in_use) {
D_ERR(imx_usb->dev,
"<%s> refusing to queue req %p (already queued)\n",
__func__, req);
- goto out;
+ return 0;
}
+ local_irq_save(flags);
+
usb_req->status = -EINPROGRESS;
usb_req->actual = 0;
@@ -810,7 +827,7 @@ static int imx_ep_queue
ret = handle_ep0(imx_ep);
else
ret = handle_ep(imx_ep);
-out:
+
local_irq_restore(flags);
return ret;
}
@@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb,
*******************************************************************************
*/
-static irqreturn_t imx_udc_irq(int irq, void *dev)
+/*
+ * Called when timer expires.
+ * Timer is started when CFG_CHG is received.
+ */
+static void handle_config(unsigned long data)
{
- struct imx_udc_struct *imx_usb = dev;
+ struct imx_udc_struct *imx_usb = (void *)data;
struct usb_ctrlrequest u;
int temp, cfg, intf, alt;
- int intr = __raw_readl(imx_usb->base + USB_INTR);
- if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
- | INTR_RESET_STOP | INTR_CFG_CHG)) {
- dump_intr(__func__, intr, imx_usb->dev);
- dump_usb_stat(__func__, imx_usb);
- }
-
- if (!imx_usb->driver) {
- /*imx_udc_disable(imx_usb);*/
- goto end_irq;
- }
-
- if (intr & INTR_WAKEUP) {
- if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
- && imx_usb->driver && imx_usb->driver->resume)
- imx_usb->driver->resume(&imx_usb->gadget);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_FULL;
- }
-
- if (intr & INTR_SUSPEND) {
- if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
- && imx_usb->driver && imx_usb->driver->suspend)
- imx_usb->driver->suspend(&imx_usb->gadget);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
- }
-
- if (intr & INTR_RESET_START) {
- __raw_writel(intr, imx_usb->base + USB_INTR);
- udc_stop_activity(imx_usb, imx_usb->driver);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
- }
-
- if (intr & INTR_RESET_STOP)
- imx_usb->gadget.speed = USB_SPEED_FULL;
-
- if (intr & INTR_CFG_CHG) {
- __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
- temp = __raw_readl(imx_usb->base + USB_STAT);
- cfg = (temp & STAT_CFG) >> 5;
- intf = (temp & STAT_INTF) >> 3;
- alt = temp & STAT_ALTSET;
+ local_irq_disable();
- D_REQ(imx_usb->dev,
- "<%s> orig config C=%d, I=%d, A=%d / "
- "req config C=%d, I=%d, A=%d\n",
- __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
- cfg, intf, alt);
+ temp = __raw_readl(imx_usb->base + USB_STAT);
+ cfg = (temp & STAT_CFG) >> 5;
+ intf = (temp & STAT_INTF) >> 3;
+ alt = temp & STAT_ALTSET;
- if (cfg != 1 && cfg != 2)
- goto end_irq;
+ D_REQ(imx_usb->dev,
+ "<%s> orig config C=%d, I=%d, A=%d / "
+ "req config C=%d, I=%d, A=%d\n",
+ __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
+ cfg, intf, alt);
- imx_usb->set_config = 0;
+ if (cfg == 1 || cfg == 2) {
- /* Config setup */
if (imx_usb->cfg != cfg) {
- D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__);
u.bRequest = USB_REQ_SET_CONFIGURATION;
u.bRequestType = USB_DIR_OUT |
USB_TYPE_STANDARD |
@@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
u.wIndex = 0;
u.wLength = 0;
imx_usb->cfg = cfg;
- imx_usb->set_config = 1;
imx_usb->driver->setup(&imx_usb->gadget, &u);
- imx_usb->set_config = 0;
- D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__);
}
if (imx_usb->intf != intf || imx_usb->alt != alt) {
- D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__);
u.bRequest = USB_REQ_SET_INTERFACE;
u.bRequestType = USB_DIR_OUT |
USB_TYPE_STANDARD |
@@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
u.wLength = 0;
imx_usb->intf = intf;
imx_usb->alt = alt;
- imx_usb->set_config = 1;
imx_usb->driver->setup(&imx_usb->gadget, &u);
- imx_usb->set_config = 0;
- D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__);
}
}
+ imx_usb->set_config = 0;
+
+ local_irq_enable();
+}
+
+static irqreturn_t imx_udc_irq(int irq, void *dev)
+{
+ struct imx_udc_struct *imx_usb = dev;
+ int intr = __raw_readl(imx_usb->base + USB_INTR);
+ int temp;
+
+ if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
+ | INTR_RESET_STOP | INTR_CFG_CHG)) {
+ dump_intr(__func__, intr, imx_usb->dev);
+ dump_usb_stat(__func__, imx_usb);
+ }
+
+ if (!imx_usb->driver)
+ goto end_irq;
+
if (intr & INTR_SOF) {
+ /* Copy from Motorola BSP.
+ We must enable SOF intr and set CMDOVER.
+ Datasheet don't specifiy this action, but it
+ is done in Motorola BSP, so just copy it.
+ */
if (imx_usb->ep0state == EP0_IDLE) {
temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
+ __raw_writel(temp | CTRL_CMDOVER,
+ imx_usb->base + USB_CTRL);
}
}
+ if (intr & INTR_CFG_CHG) {
+ /* A workaround of serious IMX UDC bug.
+ Handling of CFG_CHG should be delayed for some time, because
+ IMX does not NACK the host when CFG_CHG interrupt is pending.
+ There is no time to handle current CFG_CHG
+ if next CFG_CHG or SETUP packed is send immediately.
+ We have to clear CFG_CHG, start the timer and
+ NACK the host by setting CTRL_CMDOVER
+ if it sends any SETUP packet.
+ When timer expires, handler is called to handle configuration
+ changes. While CFG_CHG is not handled (set_config=1),
+ we must NACK the host to every SETUP packed.
+ This delay prevents from going out of sync with host.
+ */
+ __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
+ imx_usb->set_config = 1;
+ mod_timer(&imx_usb->timer, jiffies + 5);
+ goto end_irq;
+ }
+
+ if (intr & INTR_WAKEUP) {
+ if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
+ && imx_usb->driver && imx_usb->driver->resume)
+ imx_usb->driver->resume(&imx_usb->gadget);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_FULL;
+ }
+
+ if (intr & INTR_SUSPEND) {
+ if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
+ && imx_usb->driver && imx_usb->driver->suspend)
+ imx_usb->driver->suspend(&imx_usb->gadget);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+
+ if (intr & INTR_RESET_START) {
+ __raw_writel(intr, imx_usb->base + USB_INTR);
+ udc_stop_activity(imx_usb, imx_usb->driver);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+
+ if (intr & INTR_RESET_STOP)
+ imx_usb->gadget.speed = USB_SPEED_FULL;
+
end_irq:
__raw_writel(intr, imx_usb->base + USB_INTR);
return IRQ_HANDLED;
@@ -1109,6 +1155,7 @@ end_irq:
static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
{
struct imx_udc_struct *imx_usb = dev;
+ struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0];
int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0));
dump_ep_intr(__func__, 0, intr, imx_usb->dev);
@@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
return IRQ_HANDLED;
}
- /* DEVREQ IRQ has highest priority */
+ /* DEVREQ has highest priority */
if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ))
handle_ep0_devreq(imx_usb);
/* Seem i.MX is missing EOF interrupt sometimes.
- * Therefore we monitor both EOF and FIFO_EMPTY interrups
- * when transmiting, and both EOF and FIFO_FULL when
- * receiving data.
+ * Therefore we don't monitor EOF.
+ * We call handle_ep0() only if a request is queued for ep0.
*/
- else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL))
- handle_ep0(&imx_usb->imx_ep[0]);
+ else if (!list_empty(&imx_ep->queue))
+ handle_ep0(imx_ep);
__raw_writel(intr, imx_usb->base + USB_EP_INTR(0));
@@ -1186,8 +1232,8 @@ static struct imx_udc_struct controller = {
.ep0 = &controller.imx_ep[0].ep,
.name = driver_name,
.dev = {
- .bus_id = "gadget",
- },
+ .init_name = "gadget",
+ },
},
.imx_ep[0] = {
@@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc_stop_activity(imx_usb, driver);
imx_udc_disable(imx_usb);
+ del_timer(&imx_usb->timer);
driver->unbind(&imx_usb->gadget);
imx_usb->gadget.dev.driver = NULL;
@@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
usb_init_data(imx_usb);
imx_udc_init(imx_usb);
+ init_timer(&imx_usb->timer);
+ imx_usb->timer.function = handle_config;
+ imx_usb->timer.data = (unsigned long)imx_usb;
+
return 0;
fail3:
@@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
int i;
imx_udc_disable(imx_usb);
+ del_timer(&imx_usb->timer);
for (i = 0; i < IMX_USB_NB_EP + 1; i++)
free_irq(imx_usb->usbd_int[i], imx_usb);
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h
index 850076937d8d..b48ad59603d1 100644
--- a/drivers/usb/gadget/imx_udc.h
+++ b/drivers/usb/gadget/imx_udc.h
@@ -23,7 +23,8 @@
/* Helper macros */
#define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */
#define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0)
-#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
+#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \
+ ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
#define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0)
#define IMX_USB_NB_EP 6
@@ -58,6 +59,7 @@ struct imx_udc_struct {
struct device *dev;
struct imx_ep_struct imx_ep[IMX_USB_NB_EP];
struct clk *clk;
+ struct timer_list timer;
enum ep0_state ep0state;
struct resource *res;
void __iomem *base;
@@ -88,8 +90,8 @@ struct imx_udc_struct {
#define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */
#define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */
#define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */
-#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */
-#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */
+#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */
+#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */
#define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */
#define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */
#define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */
@@ -170,7 +172,7 @@ struct imx_udc_struct {
/* #define DEBUG_IRQ */
/* #define DEBUG_EPIRQ */
/* #define DEBUG_DUMP */
-#define DEBUG_ERR
+/* #define DEBUG_ERR */
#ifdef DEBUG_REQ
#define D_REQ(dev, args...) dev_dbg(dev, ## args)
@@ -228,7 +230,8 @@ struct imx_udc_struct {
#endif /* DEBUG_IRQ */
#ifdef DEBUG_EPIRQ
- static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev)
+ static void dump_ep_intr(const char *label, int nr, int irqreg,
+ struct device *dev)
{
dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr,
(irqreg & EPINTR_FIFO_FULL) ? " full" : "",
@@ -246,7 +249,8 @@ struct imx_udc_struct {
#endif /* DEBUG_IRQ */
#ifdef DEBUG_DUMP
- static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb)
+ static void dump_usb_stat(const char *label,
+ struct imx_udc_struct *imx_usb)
{
int temp = __raw_readl(imx_usb->base + USB_STAT);
@@ -259,12 +263,15 @@ struct imx_udc_struct {
(temp & STAT_ALTSET));
}
- static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep)
+ static void dump_ep_stat(const char *label,
+ struct imx_ep_struct *imx_ep)
{
- int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep)));
+ int temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_INTR(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n",
+ label, EP_NO(imx_ep),
(temp & EPINTR_FIFO_FULL) ? " full" : "",
(temp & EPINTR_FIFO_EMPTY) ? " fempty" : "",
(temp & EPINTR_FIFO_ERROR) ? " ferr" : "",
@@ -275,18 +282,22 @@ struct imx_udc_struct {
(temp & EPINTR_DEVREQ) ? " devreq" : "",
(temp & EPINTR_EOT) ? " eot" : "");
- temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
+ temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_STAT(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_STAT=[%s%s bcount=%d]\n",
+ label, EP_NO(imx_ep),
(temp & EPSTAT_SIP) ? " sip" : "",
(temp & EPSTAT_STALL) ? " stall" : "",
(temp & EPSTAT_BCOUNT) >> 16);
- temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)));
+ temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_FSTAT(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n",
+ label, EP_NO(imx_ep),
(temp & FSTAT_ERR) ? " ferr" : "",
(temp & FSTAT_UF) ? " funder" : "",
(temp & FSTAT_OF) ? " fover" : "",
@@ -296,19 +307,23 @@ struct imx_udc_struct {
(temp & FSTAT_EMPTY) ? " fempty" : "");
}
- static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req)
+ static void dump_req(const char *label, struct imx_ep_struct *imx_ep,
+ struct usb_request *req)
{
int i;
if (!req || !req->buf) {
- dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label);
+ dev_dbg(imx_ep->imx_usb->dev,
+ "<%s> req or req buf is free\n", label);
return;
}
- if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
+ if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+ == EP0_IN_DATA_PHASE)
|| (EP_NO(imx_ep) && EP_DIR(imx_ep))) {
- dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label);
+ dev_dbg(imx_ep->imx_usb->dev,
+ "<%s> request dump <", label);
for (i = 0; i < req->length; i++)
printk("%02x-", *((u8 *)req->buf + i));
printk(">\n");
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 317b48fdbf01..d20937f28a19 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev)
qual.bLength = sizeof qual;
qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER;
- qual.bcdUSB = __constant_cpu_to_le16 (0x0200);
+ qual.bcdUSB = cpu_to_le16 (0x0200);
desc = dev->dev;
qual.bDeviceClass = desc->bDeviceClass;
@@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|| dev->dev->bNumConfigurations != 1)
goto fail;
dev->dev->bNumConfigurations = 1;
- dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200);
+ dev->dev->bcdUSB = cpu_to_le16 (0x0200);
/* triggers gadgetfs_bind(); then we can enumerate. */
spin_unlock_irq (&dev->lock);
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index d554b0895603..6cd3d54f5640 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
device_add(&dev->gadget.dev);
retval = driver->bind(&dev->gadget);
if (retval) {
- printk("%s: bind to driver %s --> error %d\n", dev->gadget.name,
- driver->driver.name, retval);
+ printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
+ dev->gadget.name, driver->driver.name, retval);
device_del(&dev->gadget.dev);
dev->driver = 0;
@@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
* for set_configuration as well as eventual disconnect.
* NOTE: this shouldn't power up until later.
*/
- printk("%s: registered gadget driver '%s'\n", dev->gadget.name,
- driver->driver.name);
+ printk(KERN_WARNING "%s: registered gadget driver '%s'\n",
+ dev->gadget.name, driver->driver.name);
udc_enable(dev);
@@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
* discard the extra data.
*/
if (req->req.status != -EOVERFLOW)
- printk("%s overflow %d\n", ep->ep.name, count);
+ printk(KERN_WARNING "%s overflow %d\n",
+ ep->ep.name, count);
req->req.status = -EOVERFLOW;
} else {
*buf++ = byte;
@@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
queue);
if (!req) {
- printk("%s: NULL REQ %d\n",
+ printk(KERN_WARNING
+ "%s: NULL REQ %d\n",
__func__, ep_idx);
flush(ep);
break;
@@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
} else {
/* Throw packet away.. */
- printk("%s: No descriptor?!?\n", __func__);
+ printk(KERN_WARNING "%s: No descriptor?!?\n", __func__);
flush(ep);
}
}
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 12c6d83b218c..9498be87a724 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes)
#include "net2280.h"
-#define valid_bit __constant_cpu_to_le32 (1 << VALID_BIT)
-#define dma_done_ie __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
+#define valid_bit cpu_to_le32 (1 << VALID_BIT)
+#define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
/*-------------------------------------------------------------------------*/
@@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
return NULL;
}
td->dmacount = 0; /* not VALID */
- td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+ td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
td->dmadesc = td->dmaaddr;
req->td = td;
}
@@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
fill_dma_desc (ep, req, 1);
if (!use_dma_chaining)
- req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
+ req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN);
start_queue (ep, tmp, req->td_dma);
}
@@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
if (readl (&e->regs->ep_rsp)
& (1 << SET_ENDPOINT_HALT))
- status = __constant_cpu_to_le32 (1);
+ status = cpu_to_le32 (1);
else
- status = __constant_cpu_to_le32 (0);
+ status = cpu_to_le32 (0);
/* don't bother with a request object! */
writel (0, &dev->epregs [0].ep_irqenb);
@@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
req = list_entry (ep->queue.next,
struct net2280_request, queue);
dmacount = req->td->dmacount;
- dmacount &= __constant_cpu_to_le32 (
+ dmacount &= cpu_to_le32 (
(1 << VALID_BIT)
| DMA_BYTE_COUNT_MASK);
if (dmacount && (dmacount & valid_bit) == 0)
@@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
goto done;
}
td->dmacount = 0; /* not VALID */
- td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+ td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
td->dmadesc = td->dmaaddr;
dev->ep [i].dummy = td;
}
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 5a3034fdfe47..29500154d00c 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
- .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialNumber = STRING_SERIALNUM,
@@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512)
+ .wMaxPacketSize = cpu_to_le16(512)
};
static struct usb_endpoint_descriptor hs_ep_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512)
+ .wMaxPacketSize = cpu_to_le16(512)
};
static struct usb_qualifier_descriptor dev_qualifier = {
.bLength = sizeof dev_qualifier,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PRINTER,
.bNumConfigurations = 1
};
@@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget)
gadget->name);
/* unrecognized, but safe unless bulk is REALLY quirky */
device_desc.bcdDevice =
- __constant_cpu_to_le16(0xFFFF);
+ cpu_to_le16(0xFFFF);
}
snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
init_utsname()->sysname, init_utsname()->release,
gadget->name);
device_desc.idVendor =
- __constant_cpu_to_le16(PRINTER_VENDOR_NUM);
+ cpu_to_le16(PRINTER_VENDOR_NUM);
device_desc.idProduct =
- __constant_cpu_to_le16(PRINTER_PRODUCT_NUM);
+ cpu_to_le16(PRINTER_PRODUCT_NUM);
/* support optional vendor/distro customization */
if (idVendor) {
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index 9b36205c5759..0ce4e2819847 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -904,8 +904,8 @@ static void pxa25x_ep_fifo_flush(struct usb_ep *_ep)
/* most IN status is the same, but ISO can't stall */
*ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR
- | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
- ? 0 : UDCCS_BI_SST;
+ | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
+ ? 0 : UDCCS_BI_SST);
}
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 990f40f988d4..91ba1e939475 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -30,6 +30,7 @@
#include <linux/proc_fs.h>
#include <linux/clk.h>
#include <linux/irq.h>
+#include <linux/gpio.h>
#include <asm/byteorder.h>
#include <mach/hardware.h>
@@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc)
goto err_queues;
eps = debugfs_create_file("epstate", 0400, root, udc,
&eps_dbg_fops);
- if (!queues)
+ if (!eps)
goto err_eps;
udc->debugfs_root = root;
@@ -1471,6 +1472,32 @@ static struct usb_ep_ops pxa_ep_ops = {
.fifo_flush = pxa_ep_fifo_flush,
};
+/**
+ * dplus_pullup - Connect or disconnect pullup resistor to D+ pin
+ * @udc: udc device
+ * @on: 0 if disconnect pullup resistor, 1 otherwise
+ * Context: any
+ *
+ * Handle D+ pullup resistor, make the device visible to the usb bus, and
+ * declare it as a full speed usb device
+ */
+static void dplus_pullup(struct pxa_udc *udc, int on)
+{
+ if (on) {
+ if (gpio_is_valid(udc->mach->gpio_pullup))
+ gpio_set_value(udc->mach->gpio_pullup,
+ !udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+ } else {
+ if (gpio_is_valid(udc->mach->gpio_pullup))
+ gpio_set_value(udc->mach->gpio_pullup,
+ udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+ }
+ udc->pullup_on = on;
+}
/**
* pxa_udc_get_frame - Returns usb frame number
@@ -1500,21 +1527,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget)
return 0;
}
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * should_enable_udc - Tells if UDC should be enabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be enabled if :
+
+ * - the pullup resistor is connected
+ * - and a gadget driver is bound
+ * - and vbus is sensed (or no vbus sense is available)
+ *
+ * Returns 1 if UDC should be enabled, 0 otherwise
+ */
+static int should_enable_udc(struct pxa_udc *udc)
+{
+ int put_on;
+
+ put_on = ((udc->pullup_on) && (udc->driver));
+ put_on &= ((udc->vbus_sensed) || (!udc->transceiver));
+ return put_on;
+}
+
+/**
+ * should_disable_udc - Tells if UDC should be disabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be disabled if :
+ * - the pullup resistor is not connected
+ * - or no gadget driver is bound
+ * - or no vbus is sensed (when vbus sesing is available)
+ *
+ * Returns 1 if UDC should be disabled
+ */
+static int should_disable_udc(struct pxa_udc *udc)
+{
+ int put_off;
+
+ put_off = ((!udc->pullup_on) || (!udc->driver));
+ put_off |= ((!udc->vbus_sensed) && (udc->transceiver));
+ return put_off;
+}
+
+/**
+ * pxa_udc_pullup - Offer manual D+ pullup control
+ * @_gadget: usb gadget using the control
+ * @is_active: 0 if disconnect, else connect D+ pullup resistor
+ * Context: !in_interrupt()
+ *
+ * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup
+ */
+static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
+ return -EOPNOTSUPP;
+
+ dplus_pullup(udc, is_active);
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+ return 0;
+}
+
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc
+ * @_gadget: usb gadget
+ * @is_active: 0 if should disable the udc, 1 if should enable
+ *
+ * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the
+ * udc, and deactivates D+ pullup resistor.
+ *
+ * Returns 0
+ */
+static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ udc->vbus_sensed = is_active;
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+
+ return 0;
+}
+
+/**
+ * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed
+ * @_gadget: usb gadget
+ * @mA: current drawn
+ *
+ * Context: !in_interrupt()
+ *
+ * Called after a configuration was chosen by a USB host, to inform how much
+ * current can be drawn by the device from VBus line.
+ *
+ * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc
+ */
+static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
+{
+ struct pxa_udc *udc;
+
+ udc = to_gadget_udc(_gadget);
+ if (udc->transceiver)
+ return otg_set_power(udc->transceiver, mA);
+ return -EOPNOTSUPP;
+}
+
static const struct usb_gadget_ops pxa_udc_ops = {
.get_frame = pxa_udc_get_frame,
.wakeup = pxa_udc_wakeup,
- /* current versions must always be self-powered */
+ .pullup = pxa_udc_pullup,
+ .vbus_session = pxa_udc_vbus_session,
+ .vbus_draw = pxa_udc_vbus_draw,
};
/**
* udc_disable - disable udc device controller
* @udc: udc device
+ * Context: any
*
* Disables the udc device : disables clocks, udc interrupts, control endpoint
* interrupts.
*/
static void udc_disable(struct pxa_udc *udc)
{
+ if (!udc->enabled)
+ return;
+
udc_writel(udc, UDCICR0, 0);
udc_writel(udc, UDCICR1, 0);
@@ -1523,8 +1674,8 @@ static void udc_disable(struct pxa_udc *udc)
ep0_idle(udc);
udc->gadget.speed = USB_SPEED_UNKNOWN;
- if (udc->mach->udc_command)
- udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+
+ udc->enabled = 0;
}
/**
@@ -1570,6 +1721,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
*/
static void udc_enable(struct pxa_udc *udc)
{
+ if (udc->enabled)
+ return;
+
udc_writel(udc, UDCICR0, 0);
udc_writel(udc, UDCICR1, 0);
udc_clear_mask_UDCCR(udc, UDCCR_UDE);
@@ -1598,9 +1752,7 @@ static void udc_enable(struct pxa_udc *udc)
/* enable ep0 irqs */
pio_irq_enable(&udc->pxa_ep[0]);
- dev_info(udc->dev, "UDC connecting\n");
- if (udc->mach->udc_command)
- udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+ udc->enabled = 1;
}
/**
@@ -1612,6 +1764,9 @@ static void udc_enable(struct pxa_udc *udc)
* usb traffic follows until a disconnect is reported. Then a host may connect
* again, or the driver might get unbound.
*
+ * Note that the udc is not automatically enabled. Check function
+ * should_enable_udc().
+ *
* Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
*/
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
@@ -1630,6 +1785,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
/* first hook up the driver ... */
udc->driver = driver;
udc->gadget.dev.driver = &driver->driver;
+ dplus_pullup(udc, 1);
retval = device_add(&udc->gadget.dev);
if (retval) {
@@ -1645,9 +1801,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev_dbg(udc->dev, "registered gadget driver '%s'\n",
driver->driver.name);
- udc_enable(udc);
+ if (udc->transceiver) {
+ retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
+ if (retval) {
+ dev_err(udc->dev, "can't bind to transceiver\n");
+ goto transceiver_fail;
+ }
+ }
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
return 0;
+transceiver_fail:
+ if (driver->unbind)
+ driver->unbind(&udc->gadget);
bind_fail:
device_del(&udc->gadget.dev);
add_fail:
@@ -1699,14 +1867,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
stop_activity(udc, driver);
udc_disable(udc);
+ dplus_pullup(udc, 0);
driver->unbind(&udc->gadget);
udc->driver = NULL;
device_del(&udc->gadget.dev);
-
dev_info(udc->dev, "unregistered gadget driver '%s'\n",
driver->driver.name);
+
+ if (udc->transceiver)
+ return otg_set_peripheral(udc->transceiver, NULL);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -2212,7 +2383,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
{
struct resource *regs;
struct pxa_udc *udc = &memory;
- int retval;
+ int retval = 0, gpio;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs)
@@ -2223,6 +2394,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
udc->dev = &pdev->dev;
udc->mach = pdev->dev.platform_data;
+ udc->transceiver = otg_get_transceiver();
+
+ gpio = udc->mach->gpio_pullup;
+ if (gpio_is_valid(gpio)) {
+ retval = gpio_request(gpio, "USB D+ pullup");
+ if (retval == 0)
+ gpio_direction_output(gpio,
+ udc->mach->gpio_pullup_inverted);
+ }
+ if (retval) {
+ dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n",
+ gpio, retval);
+ return retval;
+ }
udc->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(udc->clk)) {
@@ -2240,6 +2425,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
device_initialize(&udc->gadget.dev);
udc->gadget.dev.parent = &pdev->dev;
udc->gadget.dev.dma_mask = NULL;
+ udc->vbus_sensed = 0;
the_controller = udc;
platform_set_drvdata(pdev, udc);
@@ -2273,11 +2459,17 @@ err_clk:
static int __exit pxa_udc_remove(struct platform_device *_dev)
{
struct pxa_udc *udc = platform_get_drvdata(_dev);
+ int gpio = udc->mach->gpio_pullup;
usb_gadget_unregister_driver(udc->driver);
free_irq(udc->irq, udc);
pxa_cleanup_debugfs(udc);
+ if (gpio_is_valid(gpio))
+ gpio_free(gpio);
+
+ otg_put_transceiver(udc->transceiver);
+ udc->transceiver = NULL;
platform_set_drvdata(_dev, NULL);
the_controller = NULL;
clk_put(udc->clk);
@@ -2319,6 +2511,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
}
udc_disable(udc);
+ udc->pullup_resume = udc->pullup_on;
+ dplus_pullup(udc, 0);
return 0;
}
@@ -2346,7 +2540,9 @@ static int pxa_udc_resume(struct platform_device *_dev)
ep->udccsr_value, ep->udccr_value);
}
- udc_enable(udc);
+ dplus_pullup(udc, udc->pullup_resume);
+ if (should_enable_udc(udc))
+ udc_enable(udc);
/*
* We do not handle OTG yet.
*
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index 1d1b7936ee11..db58125331da 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -26,6 +26,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+#include <linux/usb/otg.h>
/*
* Register definitions
@@ -421,10 +422,14 @@ struct udc_stats {
* @driver: bound gadget (zero, g_ether, g_file_storage, ...)
* @dev: device
* @mach: machine info, used to activate specific GPIO
+ * @transceiver: external transceiver to handle vbus sense and D+ pullup
* @ep0state: control endpoint state machine state
* @stats: statistics on udc usage
* @udc_usb_ep: array of usb endpoints offered by the gadget
* @pxa_ep: array of pxa available endpoints
+ * @enabled: UDC was enabled by a previous udc_enable()
+ * @pullup_on: if pullup resistor connected to D+ pin
+ * @pullup_resume: if pullup resistor should be connected to D+ pin on resume
* @config: UDC active configuration
* @last_interface: UDC interface of the last SET_INTERFACE host request
* @last_alternate: UDC altsetting of the last SET_INTERFACE host request
@@ -443,6 +448,7 @@ struct pxa_udc {
struct usb_gadget_driver *driver;
struct device *dev;
struct pxa2xx_udc_mach_info *mach;
+ struct otg_transceiver *transceiver;
enum ep0_state ep0state;
struct udc_stats stats;
@@ -450,6 +456,10 @@ struct pxa_udc {
struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS];
struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS];
+ unsigned enabled:1;
+ unsigned pullup_on:1;
+ unsigned pullup_resume:1;
+ unsigned vbus_sensed:1;
unsigned config:2;
unsigned last_interface:3;
unsigned last_alternate:3;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 37879af1c433..f46a60962dab 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = {
static struct usb_device_descriptor device_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
/* .bDeviceClass = f(use_acm) */
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
/* .bMaxPacketSize0 = f(hardware) */
- .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID),
+ .idVendor = cpu_to_le16(GS_VENDOR_ID),
/* .idProduct = f(use_acm) */
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
@@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
pr_warning("gs_bind: controller '%s' not recognized\n",
gadget->name);
device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099);
+ cpu_to_le16(GS_VERSION_NUM | 0x0099);
}
if (gadget_is_otg(cdev->gadget)) {
@@ -255,19 +255,19 @@ static int __init init(void)
serial_config_driver.bConfigurationValue = 2;
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
+ cpu_to_le16(GS_CDC_PRODUCT_ID);
} else if (use_obex) {
serial_config_driver.label = "CDC OBEX config";
serial_config_driver.bConfigurationValue = 3;
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
+ cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
} else {
serial_config_driver.label = "Generic Serial config";
serial_config_driver.bConfigurationValue = 1;
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_PRODUCT_ID);
+ cpu_to_le16(GS_PRODUCT_ID);
}
strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 53d59287f2bc..0a4d99ab40d8 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count)
gs_tty_driver->init_termios.c_ispeed = 9600;
gs_tty_driver->init_termios.c_ospeed = 9600;
- coding.dwDTERate = __constant_cpu_to_le32(9600);
+ coding.dwDTERate = cpu_to_le32(9600);
coding.bCharFormat = 8;
coding.bParityType = USB_CDC_NO_PARITY;
coding.bDataBits = USB_CDC_1_STOP_BITS;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 361d9659ac48..20614dce8db9 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -113,11 +113,11 @@ static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.bNumConfigurations = 2,
};
@@ -265,7 +265,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
*/
pr_warning("%s: controller '%s' not recognized\n",
longname, gadget->name);
- device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+ device_desc.bcdDevice = cpu_to_le16(0x9999);
}
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2b476b6b3d4d..845479f7c707 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -24,10 +24,7 @@ config USB_EHCI_HCD
The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
"high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
If your USB host controller supports USB 2.0, you will likely want to
- configure this Host Controller Driver. At the time of this writing,
- the primary implementation of EHCI is a chip from NEC, widely available
- in add-on PCI cards, but implementations are in the works from other
- vendors including Intel and Philips. Motherboard support is appearing.
+ configure this Host Controller Driver.
EHCI controllers are packaged with "companion" host controllers (OHCI
or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports
@@ -123,7 +120,7 @@ config USB_ISP116X_HCD
config USB_ISP1760_HCD
tristate "ISP 1760 HCD support"
- depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
+ depends on USB && EXPERIMENTAL
---help---
The ISP1760 chip is a USB 2.0 host controller.
@@ -140,6 +137,7 @@ config USB_OHCI_HCD
tristate "OHCI HCD support"
depends on USB && USB_ARCH_HAS_OHCI
select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
+ select USB_OTG_UTILS if ARCH_OMAP
---help---
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
@@ -238,6 +236,23 @@ config USB_UHCI_HCD
To compile this driver as a module, choose M here: the
module will be called uhci-hcd.
+config USB_FHCI_HCD
+ tristate "Freescale QE USB Host Controller support"
+ depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE
+ select FSL_GTM
+ select QE_USB
+ help
+ This driver enables support for Freescale QE USB Host Controller
+ (as found on MPC8360 and MPC8323 processors), the driver supports
+ Full and Low Speed USB.
+
+config FHCI_DEBUG
+ bool "Freescale QE USB Host Controller debug support"
+ depends on USB_FHCI_HCD && DEBUG_FS
+ help
+ Say "y" to see some FHCI debug information and statistics
+ throught debugfs.
+
config USB_U132_HCD
tristate "Elan U132 Adapter Host Controller"
depends on USB && USB_FTDI_ELAN
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index e5f3f20787e4..f163571e33d8 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -7,6 +7,11 @@ ifeq ($(CONFIG_USB_DEBUG),y)
endif
isp1760-objs := isp1760-hcd.o isp1760-if.o
+fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \
+ fhci-tds.o fhci-sched.o
+ifeq ($(CONFIG_FHCI_DEBUG),y)
+fhci-objs += fhci-dbg.o
+endif
obj-$(CONFIG_USB_WHCI_HCD) += whci/
@@ -17,6 +22,7 @@ obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
+obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4725d15d096f..f2618d17710d 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -110,6 +110,42 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
/*-------------------------------------------------------------------------*/
+static void
+timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
+{
+ /* Don't override timeouts which shrink or (later) disable
+ * the async ring; just the I/O watchdog. Note that if a
+ * SHRINK were pending, OFF would never be requested.
+ */
+ if (timer_pending(&ehci->watchdog)
+ && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+ & ehci->actions))
+ return;
+
+ if (!test_and_set_bit(action, &ehci->actions)) {
+ unsigned long t;
+
+ switch (action) {
+ case TIMER_IO_WATCHDOG:
+ t = EHCI_IO_JIFFIES;
+ break;
+ case TIMER_ASYNC_OFF:
+ t = EHCI_ASYNC_JIFFIES;
+ break;
+ /* case TIMER_ASYNC_SHRINK: */
+ default:
+ /* add a jiffie since we synch against the
+ * 8 KHz uframe counter.
+ */
+ t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
+ break;
+ }
+ mod_timer(&ehci->watchdog, t + jiffies);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
/*
* handshake - spin reading hc until handshake completes or fails
* @ptr: address of hc register to be read
@@ -485,6 +521,7 @@ static int ehci_init(struct usb_hcd *hcd)
* periodic_size can shrink by USBCMD update if hcc_params allows.
*/
ehci->periodic_size = DEFAULT_I_TDPS;
+ INIT_LIST_HEAD(&ehci->cached_itd_list);
if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
return retval;
@@ -497,6 +534,7 @@ static int ehci_init(struct usb_hcd *hcd)
ehci->reclaim = NULL;
ehci->next_uframe = -1;
+ ehci->clock_frame = -1;
/*
* dedicate a qh for the async ring head, since we couldn't unlink
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 0431397836f6..10d52919abbb 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh)
static void ehci_mem_cleanup (struct ehci_hcd *ehci)
{
+ free_cached_itd_list(ehci);
if (ehci->async)
qh_put (ehci->async);
ehci->async = NULL;
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index bdc6e86e1f8b..abb9a7706ec7 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -230,7 +230,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
pci_read_config_word(pdev, 0x62, &port_wake);
if (port_wake & 0x0001) {
dev_warn(&pdev->dev, "Enabling legacy PCI PM\n");
- device_init_wakeup(&pdev->dev, 1);
+ device_set_wakeup_capable(&pdev->dev, 1);
}
}
@@ -432,8 +432,6 @@ static struct pci_driver ehci_pci_driver = {
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
- .suspend_late = usb_hcd_pci_suspend_late,
- .resume_early = usb_hcd_pci_resume_early,
.resume = usb_hcd_pci_resume,
#endif
.shutdown = usb_hcd_pci_shutdown,
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 3712b925b315..6850ad56007a 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -333,12 +333,40 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
token = hc32_to_cpu(ehci, qtd->hw_token);
/* always clean up qtds the hc de-activated */
+ retry_xacterr:
if ((token & QTD_STS_ACTIVE) == 0) {
/* on STALL, error, and short reads this urb must
* complete and all its qtds must be recycled.
*/
if ((token & QTD_STS_HALT) != 0) {
+
+ /* retry transaction errors until we
+ * reach the software xacterr limit
+ */
+ if ((token & QTD_STS_XACT) &&
+ QTD_CERR(token) == 0 &&
+ --qh->xacterrs > 0 &&
+ !urb->unlinked) {
+ ehci_dbg(ehci,
+ "detected XactErr len %zu/%zu retry %d\n",
+ qtd->length - QTD_LENGTH(token), qtd->length,
+ QH_XACTERR_MAX - qh->xacterrs);
+
+ /* reset the token in the qtd and the
+ * qh overlay (which still contains
+ * the qtd) so that we pick up from
+ * where we left off
+ */
+ token &= ~QTD_STS_HALT;
+ token |= QTD_STS_ACTIVE |
+ (EHCI_TUNE_CERR << 10);
+ qtd->hw_token = cpu_to_hc32(ehci,
+ token);
+ wmb();
+ qh->hw_token = cpu_to_hc32(ehci, token);
+ goto retry_xacterr;
+ }
stopped = 1;
/* magic dummy for some short reads; qh won't advance.
@@ -421,6 +449,9 @@ halt:
/* remove qtd; it's recycled after possible urb completion */
list_del (&qtd->qtd_list);
last = qtd;
+
+ /* reinit the xacterr counter for the next qtd */
+ qh->xacterrs = QH_XACTERR_MAX;
}
/* last urb's completion might still need calling */
@@ -862,6 +893,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
head->qh_next.qh = qh;
head->hw_next = dma;
+ qh->xacterrs = QH_XACTERR_MAX;
qh->qh_state = QH_STATE_LINKED;
/* qtd completions reported later by interrupt */
}
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index a081ee65bde6..73256a43e270 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -563,7 +563,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
// and this qh is active in the current uframe
// (and overlay token SplitXstate is false?)
// THEN
- // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */);
+ // qh->hw_info1 |= cpu_to_hc32(1 << 7 /* "ignore" */);
/* high bandwidth, or otherwise part of every microframe */
if ((period = qh->period) == 0)
@@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
stream->bEndpointAddress &= 0x0f;
- stream->ep->hcpriv = NULL;
+ if (stream->ep)
+ stream->ep->hcpriv = NULL;
if (stream->rescheduled) {
ehci_info (ehci, "ep%d%s-iso rescheduled "
@@ -1653,14 +1654,28 @@ itd_complete (
(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
}
iso_stream_put (ehci, stream);
- /* OK to recycle this ITD now that its completion callback ran. */
+
done:
usb_put_urb(urb);
itd->urb = NULL;
- itd->stream = NULL;
- list_move(&itd->itd_list, &stream->free_list);
- iso_stream_put(ehci, stream);
-
+ if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
+ /* OK to recycle this ITD now. */
+ itd->stream = NULL;
+ list_move(&itd->itd_list, &stream->free_list);
+ iso_stream_put(ehci, stream);
+ } else {
+ /* HW might remember this ITD, so we can't recycle it yet.
+ * Move it to a safe place until a new frame starts.
+ */
+ list_move(&itd->itd_list, &ehci->cached_itd_list);
+ if (stream->refcount == 2) {
+ /* If iso_stream_put() were called here, stream
+ * would be freed. Instead, just prevent reuse.
+ */
+ stream->ep->hcpriv = NULL;
+ stream->ep = NULL;
+ }
+ }
return retval;
}
@@ -2101,6 +2116,20 @@ done:
/*-------------------------------------------------------------------------*/
+static void free_cached_itd_list(struct ehci_hcd *ehci)
+{
+ struct ehci_itd *itd, *n;
+
+ list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
+ struct ehci_iso_stream *stream = itd->stream;
+ itd->stream = NULL;
+ list_move(&itd->itd_list, &stream->free_list);
+ iso_stream_put(ehci, stream);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
static void
scan_periodic (struct ehci_hcd *ehci)
{
@@ -2115,10 +2144,17 @@ scan_periodic (struct ehci_hcd *ehci)
* Touches as few pages as possible: cache-friendly.
*/
now_uframe = ehci->next_uframe;
- if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
+ if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
clock = ehci_readl(ehci, &ehci->regs->frame_index);
- else
+ clock_frame = (clock >> 3) % ehci->periodic_size;
+ } else {
clock = now_uframe + mod - 1;
+ clock_frame = -1;
+ }
+ if (ehci->clock_frame != clock_frame) {
+ free_cached_itd_list(ehci);
+ ehci->clock_frame = clock_frame;
+ }
clock %= mod;
clock_frame = clock >> 3;
@@ -2277,6 +2313,10 @@ restart:
/* rescan the rest of this frame, then ... */
clock = now;
clock_frame = clock >> 3;
+ if (ehci->clock_frame != clock_frame) {
+ free_cached_itd_list(ehci);
+ ehci->clock_frame = clock_frame;
+ }
} else {
now_uframe++;
now_uframe %= mod;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index fb7054ccf4fc..6cff195e1a36 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -87,6 +87,10 @@ struct ehci_hcd { /* one per controller */
int next_uframe; /* scan periodic, start here */
unsigned periodic_sched; /* periodic activity count */
+ /* list of itds completed while clock_frame was still active */
+ struct list_head cached_itd_list;
+ unsigned clock_frame;
+
/* per root hub port */
unsigned long reset_done [EHCI_MAX_ROOT_PORTS];
@@ -186,39 +190,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
clear_bit (action, &ehci->actions);
}
-static inline void
-timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
-{
- /* Don't override timeouts which shrink or (later) disable
- * the async ring; just the I/O watchdog. Note that if a
- * SHRINK were pending, OFF would never be requested.
- */
- if (timer_pending(&ehci->watchdog)
- && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
- & ehci->actions))
- return;
-
- if (!test_and_set_bit (action, &ehci->actions)) {
- unsigned long t;
-
- switch (action) {
- case TIMER_IO_WATCHDOG:
- t = EHCI_IO_JIFFIES;
- break;
- case TIMER_ASYNC_OFF:
- t = EHCI_ASYNC_JIFFIES;
- break;
- // case TIMER_ASYNC_SHRINK:
- default:
- /* add a jiffie since we synch against the
- * 8 KHz uframe counter.
- */
- t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
- break;
- }
- mod_timer(&ehci->watchdog, t + jiffies);
- }
-}
+static void free_cached_itd_list(struct ehci_hcd *ehci);
/*-------------------------------------------------------------------------*/
@@ -281,7 +253,7 @@ struct ehci_qtd {
/*
* Now the following defines are not converted using the
- * __constant_cpu_to_le32() macro anymore, since we have to support
+ * cpu_to_le32() macro anymore, since we have to support
* "dynamic" switching between be and le support, so that the driver
* can be used on one system with SoC EHCI controller using big-endian
* descriptors as well as a normal little-endian PCI EHCI controller.
@@ -370,6 +342,9 @@ struct ehci_qh {
#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */
#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */
+ u8 xacterrs; /* XactErr retry counter */
+#define QH_XACTERR_MAX 32 /* XactErr retry limit */
+
/* periodic schedule info */
u8 usecs; /* intr bandwidth */
u8 gap_uf; /* uframes split/csplit gap */
diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c
new file mode 100644
index 000000000000..ea8a4255c5da
--- /dev/null
+++ b/drivers/usb/host/fhci-dbg.c
@@ -0,0 +1,139 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er)
+{
+ int i;
+
+ if (usb_er == -1) {
+ fhci->usb_irq_stat[12]++;
+ return;
+ }
+
+ for (i = 0; i < 12; ++i) {
+ if (usb_er & (1 << i))
+ fhci->usb_irq_stat[i]++;
+ }
+}
+
+static int fhci_dfs_regs_show(struct seq_file *s, void *v)
+{
+ struct fhci_hcd *fhci = s->private;
+ struct fhci_regs __iomem *regs = fhci->regs;
+
+ seq_printf(s,
+ "mode: 0x%x\n" "addr: 0x%x\n"
+ "command: 0x%x\n" "ep0: 0x%x\n"
+ "event: 0x%x\n" "mask: 0x%x\n"
+ "status: 0x%x\n" "SOF timer: %d\n"
+ "frame number: %d\n"
+ "lines status: 0x%x\n",
+ in_8(&regs->usb_mod), in_8(&regs->usb_addr),
+ in_8(&regs->usb_comm), in_be16(&regs->usb_ep[0]),
+ in_be16(&regs->usb_event), in_be16(&regs->usb_mask),
+ in_8(&regs->usb_status), in_be16(&regs->usb_sof_tmr),
+ in_be16(&regs->usb_frame_num),
+ fhci_ioports_check_bus_state(fhci));
+
+ return 0;
+}
+
+static int fhci_dfs_irq_stat_show(struct seq_file *s, void *v)
+{
+ struct fhci_hcd *fhci = s->private;
+ int *usb_irq_stat = fhci->usb_irq_stat;
+
+ seq_printf(s,
+ "RXB: %d\n" "TXB: %d\n" "BSY: %d\n"
+ "SOF: %d\n" "TXE0: %d\n" "TXE1: %d\n"
+ "TXE2: %d\n" "TXE3: %d\n" "IDLE: %d\n"
+ "RESET: %d\n" "SFT: %d\n" "MSF: %d\n"
+ "IDLE_ONLY: %d\n",
+ usb_irq_stat[0], usb_irq_stat[1], usb_irq_stat[2],
+ usb_irq_stat[3], usb_irq_stat[4], usb_irq_stat[5],
+ usb_irq_stat[6], usb_irq_stat[7], usb_irq_stat[8],
+ usb_irq_stat[9], usb_irq_stat[10], usb_irq_stat[11],
+ usb_irq_stat[12]);
+
+ return 0;
+}
+
+static int fhci_dfs_regs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, fhci_dfs_regs_show, inode->i_private);
+}
+
+static int fhci_dfs_irq_stat_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, fhci_dfs_irq_stat_show, inode->i_private);
+}
+
+static const struct file_operations fhci_dfs_regs_fops = {
+ .open = fhci_dfs_regs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct file_operations fhci_dfs_irq_stat_fops = {
+ .open = fhci_dfs_irq_stat_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+void fhci_dfs_create(struct fhci_hcd *fhci)
+{
+ struct device *dev = fhci_to_hcd(fhci)->self.controller;
+
+ fhci->dfs_root = debugfs_create_dir(dev_name(dev), NULL);
+ if (!fhci->dfs_root) {
+ WARN_ON(1);
+ return;
+ }
+
+ fhci->dfs_regs = debugfs_create_file("regs", S_IFREG | S_IRUGO,
+ fhci->dfs_root, fhci, &fhci_dfs_regs_fops);
+
+ fhci->dfs_irq_stat = debugfs_create_file("irq_stat",
+ S_IFREG | S_IRUGO, fhci->dfs_root, fhci,
+ &fhci_dfs_irq_stat_fops);
+
+ WARN_ON(!fhci->dfs_regs || !fhci->dfs_irq_stat);
+}
+
+void fhci_dfs_destroy(struct fhci_hcd *fhci)
+{
+ if (!fhci->dfs_root)
+ return;
+
+ if (fhci->dfs_irq_stat)
+ debugfs_remove(fhci->dfs_irq_stat);
+
+ if (fhci->dfs_regs)
+ debugfs_remove(fhci->dfs_regs);
+
+ debugfs_remove(fhci->dfs_root);
+}
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c
new file mode 100644
index 000000000000..0951818ef93b
--- /dev/null
+++ b/drivers/usb/host/fhci-hcd.c
@@ -0,0 +1,836 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <asm/qe.h>
+#include <asm/fsl_gtm.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+void fhci_start_sof_timer(struct fhci_hcd *fhci)
+{
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ /* clear frame_n */
+ out_be16(&fhci->pram->frame_num, 0);
+
+ out_be16(&fhci->regs->usb_sof_tmr, 0);
+ setbits8(&fhci->regs->usb_mod, USB_MODE_SFTE);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+void fhci_stop_sof_timer(struct fhci_hcd *fhci)
+{
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ clrbits8(&fhci->regs->usb_mod, USB_MODE_SFTE);
+ gtm_stop_timer16(fhci->timer);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+u16 fhci_get_sof_timer_count(struct fhci_usb *usb)
+{
+ return be16_to_cpu(in_be16(&usb->fhci->regs->usb_sof_tmr) / 12);
+}
+
+/* initialize the endpoint zero */
+static u32 endpoint_zero_init(struct fhci_usb *usb,
+ enum fhci_mem_alloc data_mem,
+ u32 ring_len)
+{
+ u32 rc;
+
+ rc = fhci_create_ep(usb, data_mem, ring_len);
+ if (rc)
+ return rc;
+
+ /* inilialize endpoint registers */
+ fhci_init_ep_registers(usb, usb->ep0, data_mem);
+
+ return 0;
+}
+
+/* enable the USB interrupts */
+void fhci_usb_enable_interrupt(struct fhci_usb *usb)
+{
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (usb->intr_nesting_cnt == 1) {
+ /* initialize the USB interrupt */
+ enable_irq(fhci_to_hcd(fhci)->irq);
+
+ /* initialize the event register and mask register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+
+ /* enable the timer interrupts */
+ enable_irq(fhci->timer->irq);
+ } else if (usb->intr_nesting_cnt > 1)
+ fhci_info(fhci, "unbalanced USB interrupts nesting\n");
+ usb->intr_nesting_cnt--;
+}
+
+/* diable the usb interrupt */
+void fhci_usb_disable_interrupt(struct fhci_usb *usb)
+{
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (usb->intr_nesting_cnt == 0) {
+ /* diable the timer interrupt */
+ disable_irq_nosync(fhci->timer->irq);
+
+ /* disable the usb interrupt */
+ disable_irq_nosync(fhci_to_hcd(fhci)->irq);
+ out_be16(&usb->fhci->regs->usb_mask, 0);
+ }
+ usb->intr_nesting_cnt++;
+}
+
+/* enable the USB controller */
+static u32 fhci_usb_enable(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+ setbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+
+ mdelay(100);
+
+ return 0;
+}
+
+/* disable the USB controller */
+static u32 fhci_usb_disable(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ fhci_usb_disable_interrupt(usb);
+ fhci_port_disable(fhci);
+
+ /* disable the usb controller */
+ if (usb->port_status == FHCI_PORT_FULL ||
+ usb->port_status == FHCI_PORT_LOW)
+ fhci_device_disconnected_interrupt(fhci);
+
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+
+ return 0;
+}
+
+/* check the bus state by polling the QE bit on the IO ports */
+int fhci_ioports_check_bus_state(struct fhci_hcd *fhci)
+{
+ u8 bits = 0;
+
+ /* check USBOE,if transmitting,exit */
+ if (!gpio_get_value(fhci->gpios[GPIO_USBOE]))
+ return -1;
+
+ /* check USBRP */
+ if (gpio_get_value(fhci->gpios[GPIO_USBRP]))
+ bits |= 0x2;
+
+ /* check USBRN */
+ if (gpio_get_value(fhci->gpios[GPIO_USBRN]))
+ bits |= 0x1;
+
+ return bits;
+}
+
+static void fhci_mem_free(struct fhci_hcd *fhci)
+{
+ struct ed *ed;
+ struct ed *next_ed;
+ struct td *td;
+ struct td *next_td;
+
+ list_for_each_entry_safe(ed, next_ed, &fhci->empty_eds, node) {
+ list_del(&ed->node);
+ kfree(ed);
+ }
+
+ list_for_each_entry_safe(td, next_td, &fhci->empty_tds, node) {
+ list_del(&td->node);
+ kfree(td);
+ }
+
+ kfree(fhci->vroot_hub);
+ fhci->vroot_hub = NULL;
+
+ kfree(fhci->hc_list);
+ fhci->hc_list = NULL;
+}
+
+static int fhci_mem_init(struct fhci_hcd *fhci)
+{
+ int i;
+
+ fhci->hc_list = kzalloc(sizeof(*fhci->hc_list), GFP_KERNEL);
+ if (!fhci->hc_list)
+ goto err;
+
+ INIT_LIST_HEAD(&fhci->hc_list->ctrl_list);
+ INIT_LIST_HEAD(&fhci->hc_list->bulk_list);
+ INIT_LIST_HEAD(&fhci->hc_list->iso_list);
+ INIT_LIST_HEAD(&fhci->hc_list->intr_list);
+ INIT_LIST_HEAD(&fhci->hc_list->done_list);
+
+ fhci->vroot_hub = kzalloc(sizeof(*fhci->vroot_hub), GFP_KERNEL);
+ if (!fhci->vroot_hub)
+ goto err;
+
+ INIT_LIST_HEAD(&fhci->empty_eds);
+ INIT_LIST_HEAD(&fhci->empty_tds);
+
+ /* initialize work queue to handle done list */
+ fhci_tasklet.data = (unsigned long)fhci;
+ fhci->process_done_task = &fhci_tasklet;
+
+ for (i = 0; i < MAX_TDS; i++) {
+ struct td *td;
+
+ td = kmalloc(sizeof(*td), GFP_KERNEL);
+ if (!td)
+ goto err;
+ fhci_recycle_empty_td(fhci, td);
+ }
+ for (i = 0; i < MAX_EDS; i++) {
+ struct ed *ed;
+
+ ed = kmalloc(sizeof(*ed), GFP_KERNEL);
+ if (!ed)
+ goto err;
+ fhci_recycle_empty_ed(fhci, ed);
+ }
+
+ fhci->active_urbs = 0;
+ return 0;
+err:
+ fhci_mem_free(fhci);
+ return -ENOMEM;
+}
+
+/* destroy the fhci_usb structure */
+static void fhci_usb_free(void *lld)
+{
+ struct fhci_usb *usb = lld;
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (usb) {
+ fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
+ fhci_ep0_free(usb);
+ kfree(usb->actual_frame);
+ kfree(usb);
+ }
+}
+
+/* initialize the USB */
+static int fhci_usb_init(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ memset_io(usb->fhci->pram, 0, FHCI_PRAM_SIZE);
+
+ usb->port_status = FHCI_PORT_DISABLED;
+ usb->max_frame_usage = FRAME_TIME_USAGE;
+ usb->sw_transaction_time = SW_FIX_TIME_BETWEEN_TRANSACTION;
+
+ usb->actual_frame = kzalloc(sizeof(*usb->actual_frame), GFP_KERNEL);
+ if (!usb->actual_frame) {
+ fhci_usb_free(usb);
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&usb->actual_frame->tds_list);
+
+ /* initializing registers on chip, clear frame number */
+ out_be16(&fhci->pram->frame_num, 0);
+
+ /* clear rx state */
+ out_be32(&fhci->pram->rx_state, 0);
+
+ /* set mask register */
+ usb->saved_msk = (USB_E_TXB_MASK |
+ USB_E_TXE1_MASK |
+ USB_E_IDLE_MASK |
+ USB_E_RESET_MASK | USB_E_SFT_MASK | USB_E_MSF_MASK);
+
+ out_8(&usb->fhci->regs->usb_mod, USB_MODE_HOST | USB_MODE_EN);
+
+ /* clearing the mask register */
+ out_be16(&usb->fhci->regs->usb_mask, 0);
+
+ /* initialing the event register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+
+ if (endpoint_zero_init(usb, DEFAULT_DATA_MEM, DEFAULT_RING_LEN) != 0) {
+ fhci_usb_free(usb);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* initialize the fhci_usb struct and the corresponding data staruct */
+static struct fhci_usb *fhci_create_lld(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb;
+
+ /* allocate memory for SCC data structure */
+ usb = kzalloc(sizeof(*usb), GFP_KERNEL);
+ if (!usb) {
+ fhci_err(fhci, "no memory for SCC data struct\n");
+ return NULL;
+ }
+
+ usb->fhci = fhci;
+ usb->hc_list = fhci->hc_list;
+ usb->vroot_hub = fhci->vroot_hub;
+
+ usb->transfer_confirm = fhci_transfer_confirm_callback;
+
+ return usb;
+}
+
+static int fhci_start(struct usb_hcd *hcd)
+{
+ int ret;
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+
+ ret = fhci_mem_init(fhci);
+ if (ret) {
+ fhci_err(fhci, "failed to allocate memory\n");
+ goto err;
+ }
+
+ fhci->usb_lld = fhci_create_lld(fhci);
+ if (!fhci->usb_lld) {
+ fhci_err(fhci, "low level driver config failed\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = fhci_usb_init(fhci);
+ if (ret) {
+ fhci_err(fhci, "low level driver initialize failed\n");
+ goto err;
+ }
+
+ spin_lock_init(&fhci->lock);
+
+ /* connect the virtual root hub */
+ fhci->vroot_hub->dev_num = 1; /* this field may be needed to fix */
+ fhci->vroot_hub->hub.wHubStatus = 0;
+ fhci->vroot_hub->hub.wHubChange = 0;
+ fhci->vroot_hub->port.wPortStatus = 0;
+ fhci->vroot_hub->port.wPortChange = 0;
+
+ hcd->state = HC_STATE_RUNNING;
+
+ /*
+ * From here on, khubd concurrently accesses the root
+ * hub; drivers will be talking to enumerated devices.
+ * (On restart paths, khubd already knows about the root
+ * hub and could find work as soon as we wrote FLAG_CF.)
+ *
+ * Before this point the HC was idle/ready. After, khubd
+ * and device drivers may start it running.
+ */
+ fhci_usb_enable(fhci);
+ return 0;
+err:
+ fhci_mem_free(fhci);
+ return ret;
+}
+
+static void fhci_stop(struct usb_hcd *hcd)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+
+ fhci_usb_disable_interrupt(fhci->usb_lld);
+ fhci_usb_disable(fhci);
+
+ fhci_usb_free(fhci->usb_lld);
+ fhci->usb_lld = NULL;
+ fhci_mem_free(fhci);
+}
+
+static int fhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ u32 pipe = urb->pipe;
+ int ret;
+ int i;
+ int size = 0;
+ struct urb_priv *urb_priv;
+ unsigned long flags;
+
+ switch (usb_pipetype(pipe)) {
+ case PIPE_CONTROL:
+ /* 1 td fro setup,1 for ack */
+ size = 2;
+ case PIPE_BULK:
+ /* one td for every 4096 bytes(can be upto 8k) */
+ size += urb->transfer_buffer_length / 4096;
+ /* ...add for any remaining bytes... */
+ if ((urb->transfer_buffer_length % 4096) != 0)
+ size++;
+ /* ..and maybe a zero length packet to wrap it up */
+ if (size == 0)
+ size++;
+ else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0
+ && (urb->transfer_buffer_length
+ % usb_maxpacket(urb->dev, pipe,
+ usb_pipeout(pipe))) != 0)
+ size++;
+ break;
+ case PIPE_ISOCHRONOUS:
+ size = urb->number_of_packets;
+ if (size <= 0)
+ return -EINVAL;
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].actual_length = 0;
+ urb->iso_frame_desc[i].status = (u32) (-EXDEV);
+ }
+ break;
+ case PIPE_INTERRUPT:
+ size = 1;
+ }
+
+ /* allocate the private part of the URB */
+ urb_priv = kzalloc(sizeof(*urb_priv), mem_flags);
+ if (!urb_priv)
+ return -ENOMEM;
+
+ /* allocate the private part of the URB */
+ urb_priv->tds = kzalloc(size * sizeof(struct td), mem_flags);
+ if (!urb_priv->tds) {
+ kfree(urb_priv);
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ ret = usb_hcd_link_urb_to_ep(hcd, urb);
+ if (ret)
+ goto err;
+
+ /* fill the private part of the URB */
+ urb_priv->num_of_tds = size;
+
+ urb->status = -EINPROGRESS;
+ urb->actual_length = 0;
+ urb->error_count = 0;
+ urb->hcpriv = urb_priv;
+
+ fhci_queue_urb(fhci, urb);
+err:
+ if (ret) {
+ kfree(urb_priv->tds);
+ kfree(urb_priv);
+ }
+ spin_unlock_irqrestore(&fhci->lock, flags);
+ return ret;
+}
+
+/* dequeue FHCI URB */
+static int fhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ struct fhci_usb *usb = fhci->usb_lld;
+ int ret = -EINVAL;
+ unsigned long flags;
+
+ if (!urb || !urb->dev || !urb->dev->bus)
+ goto out;
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (ret)
+ goto out2;
+
+ if (usb->port_status != FHCI_PORT_DISABLED) {
+ struct urb_priv *urb_priv;
+
+ /*
+ * flag the urb's data for deletion in some upcoming
+ * SF interrupt's delete list processing
+ */
+ urb_priv = urb->hcpriv;
+
+ if (!urb_priv || (urb_priv->state == URB_DEL))
+ goto out2;
+
+ urb_priv->state = URB_DEL;
+
+ /* already pending? */
+ urb_priv->ed->state = FHCI_ED_URB_DEL;
+ } else {
+ fhci_urb_complete_free(fhci, urb);
+ }
+
+out2:
+ spin_unlock_irqrestore(&fhci->lock, flags);
+out:
+ return ret;
+}
+
+static void fhci_endpoint_disable(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep)
+{
+ struct fhci_hcd *fhci;
+ struct ed *ed;
+ unsigned long flags;
+
+ fhci = hcd_to_fhci(hcd);
+ spin_lock_irqsave(&fhci->lock, flags);
+ ed = ep->hcpriv;
+ if (ed) {
+ while (ed->td_head != NULL) {
+ struct td *td = fhci_remove_td_from_ed(ed);
+ fhci_urb_complete_free(fhci, td->urb);
+ }
+ fhci_recycle_empty_ed(fhci, ed);
+ ep->hcpriv = NULL;
+ }
+ spin_unlock_irqrestore(&fhci->lock, flags);
+}
+
+static int fhci_get_frame_number(struct usb_hcd *hcd)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+
+ return get_frame_num(fhci);
+}
+
+static const struct hc_driver fhci_driver = {
+ .description = "fsl,usb-fhci",
+ .product_desc = "FHCI HOST Controller",
+ .hcd_priv_size = sizeof(struct fhci_hcd),
+
+ /* generic hardware linkage */
+ .irq = fhci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+
+ /* basic lifecycle operation */
+ .start = fhci_start,
+ .stop = fhci_stop,
+
+ /* managing i/o requests and associated device resources */
+ .urb_enqueue = fhci_urb_enqueue,
+ .urb_dequeue = fhci_urb_dequeue,
+ .endpoint_disable = fhci_endpoint_disable,
+
+ /* scheduling support */
+ .get_frame_number = fhci_get_frame_number,
+
+ /* root hub support */
+ .hub_status_data = fhci_hub_status_data,
+ .hub_control = fhci_hub_control,
+};
+
+static int __devinit of_fhci_probe(struct of_device *ofdev,
+ const struct of_device_id *ofid)
+{
+ struct device *dev = &ofdev->dev;
+ struct device_node *node = ofdev->node;
+ struct usb_hcd *hcd;
+ struct fhci_hcd *fhci;
+ struct resource usb_regs;
+ unsigned long pram_addr;
+ unsigned int usb_irq;
+ const char *sprop;
+ const u32 *iprop;
+ int size;
+ int ret;
+ int i;
+ int j;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ sprop = of_get_property(node, "mode", NULL);
+ if (sprop && strcmp(sprop, "host"))
+ return -ENODEV;
+
+ hcd = usb_create_hcd(&fhci_driver, dev, dev_name(dev));
+ if (!hcd) {
+ dev_err(dev, "could not create hcd\n");
+ return -ENOMEM;
+ }
+
+ fhci = hcd_to_fhci(hcd);
+ hcd->self.controller = dev;
+ dev_set_drvdata(dev, hcd);
+
+ iprop = of_get_property(node, "hub-power-budget", &size);
+ if (iprop && size == sizeof(*iprop))
+ hcd->power_budget = *iprop;
+
+ /* FHCI registers. */
+ ret = of_address_to_resource(node, 0, &usb_regs);
+ if (ret) {
+ dev_err(dev, "could not get regs\n");
+ goto err_regs;
+ }
+
+ hcd->regs = ioremap(usb_regs.start, usb_regs.end - usb_regs.start + 1);
+ if (!hcd->regs) {
+ dev_err(dev, "could not ioremap regs\n");
+ ret = -ENOMEM;
+ goto err_regs;
+ }
+ fhci->regs = hcd->regs;
+
+ /* Parameter RAM. */
+ iprop = of_get_property(node, "reg", &size);
+ if (!iprop || size < sizeof(*iprop) * 4) {
+ dev_err(dev, "can't get pram offset\n");
+ ret = -EINVAL;
+ goto err_pram;
+ }
+
+ pram_addr = cpm_muram_alloc_fixed(iprop[2], FHCI_PRAM_SIZE);
+ if (IS_ERR_VALUE(pram_addr)) {
+ dev_err(dev, "failed to allocate usb pram\n");
+ ret = -ENOMEM;
+ goto err_pram;
+ }
+ fhci->pram = cpm_muram_addr(pram_addr);
+
+ /* GPIOs and pins */
+ for (i = 0; i < NUM_GPIOS; i++) {
+ int gpio;
+ enum of_gpio_flags flags;
+
+ gpio = of_get_gpio_flags(node, i, &flags);
+ fhci->gpios[i] = gpio;
+ fhci->alow_gpios[i] = flags & OF_GPIO_ACTIVE_LOW;
+
+ if (!gpio_is_valid(gpio)) {
+ if (i < GPIO_SPEED) {
+ dev_err(dev, "incorrect GPIO%d: %d\n",
+ i, gpio);
+ goto err_gpios;
+ } else {
+ dev_info(dev, "assuming board doesn't have "
+ "%s gpio\n", i == GPIO_SPEED ?
+ "speed" : "power");
+ continue;
+ }
+ }
+
+ ret = gpio_request(gpio, dev_name(dev));
+ if (ret) {
+ dev_err(dev, "failed to request gpio %d", i);
+ goto err_gpios;
+ }
+
+ if (i >= GPIO_SPEED) {
+ ret = gpio_direction_output(gpio, 0);
+ if (ret) {
+ dev_err(dev, "failed to set gpio %d as "
+ "an output\n", i);
+ i++;
+ goto err_gpios;
+ }
+ }
+ }
+
+ for (j = 0; j < NUM_PINS; j++) {
+ fhci->pins[j] = qe_pin_request(ofdev->node, j);
+ if (IS_ERR(fhci->pins[j])) {
+ ret = PTR_ERR(fhci->pins[j]);
+ dev_err(dev, "can't get pin %d: %d\n", j, ret);
+ goto err_pins;
+ }
+ }
+
+ /* Frame limit timer and its interrupt. */
+ fhci->timer = gtm_get_timer16();
+ if (IS_ERR(fhci->timer)) {
+ ret = PTR_ERR(fhci->timer);
+ dev_err(dev, "failed to request qe timer: %i", ret);
+ goto err_get_timer;
+ }
+
+ ret = request_irq(fhci->timer->irq, fhci_frame_limit_timer_irq,
+ IRQF_DISABLED, "qe timer (usb)", hcd);
+ if (ret) {
+ dev_err(dev, "failed to request timer irq");
+ goto err_timer_irq;
+ }
+
+ /* USB Host interrupt. */
+ usb_irq = irq_of_parse_and_map(node, 0);
+ if (usb_irq == NO_IRQ) {
+ dev_err(dev, "could not get usb irq\n");
+ ret = -EINVAL;
+ goto err_usb_irq;
+ }
+
+ /* Clocks. */
+ sprop = of_get_property(node, "fsl,fullspeed-clock", NULL);
+ if (sprop) {
+ fhci->fullspeed_clk = qe_clock_source(sprop);
+ if (fhci->fullspeed_clk == QE_CLK_DUMMY) {
+ dev_err(dev, "wrong fullspeed-clock\n");
+ ret = -EINVAL;
+ goto err_clocks;
+ }
+ }
+
+ sprop = of_get_property(node, "fsl,lowspeed-clock", NULL);
+ if (sprop) {
+ fhci->lowspeed_clk = qe_clock_source(sprop);
+ if (fhci->lowspeed_clk == QE_CLK_DUMMY) {
+ dev_err(dev, "wrong lowspeed-clock\n");
+ ret = -EINVAL;
+ goto err_clocks;
+ }
+ }
+
+ if (fhci->fullspeed_clk == QE_CLK_NONE &&
+ fhci->lowspeed_clk == QE_CLK_NONE) {
+ dev_err(dev, "no clocks specified\n");
+ ret = -EINVAL;
+ goto err_clocks;
+ }
+
+ dev_info(dev, "at 0x%p, irq %d\n", hcd->regs, usb_irq);
+
+ fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
+
+ /* Start with full-speed, if possible. */
+ if (fhci->fullspeed_clk != QE_CLK_NONE) {
+ fhci_config_transceiver(fhci, FHCI_PORT_FULL);
+ qe_usb_clock_set(fhci->fullspeed_clk, USB_CLOCK);
+ } else {
+ fhci_config_transceiver(fhci, FHCI_PORT_LOW);
+ qe_usb_clock_set(fhci->lowspeed_clk, USB_CLOCK >> 3);
+ }
+
+ /* Clear and disable any pending interrupts. */
+ out_be16(&fhci->regs->usb_event, 0xffff);
+ out_be16(&fhci->regs->usb_mask, 0);
+
+ ret = usb_add_hcd(hcd, usb_irq, IRQF_DISABLED);
+ if (ret < 0)
+ goto err_add_hcd;
+
+ fhci_dfs_create(fhci);
+
+ return 0;
+
+err_add_hcd:
+err_clocks:
+ irq_dispose_mapping(usb_irq);
+err_usb_irq:
+ free_irq(fhci->timer->irq, hcd);
+err_timer_irq:
+ gtm_put_timer16(fhci->timer);
+err_get_timer:
+err_pins:
+ while (--j >= 0)
+ qe_pin_free(fhci->pins[j]);
+err_gpios:
+ while (--i >= 0) {
+ if (gpio_is_valid(fhci->gpios[i]))
+ gpio_free(fhci->gpios[i]);
+ }
+ cpm_muram_free(pram_addr);
+err_pram:
+ iounmap(hcd->regs);
+err_regs:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int __devexit fhci_remove(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ int i;
+ int j;
+
+ usb_remove_hcd(hcd);
+ free_irq(fhci->timer->irq, hcd);
+ gtm_put_timer16(fhci->timer);
+ cpm_muram_free(cpm_muram_offset(fhci->pram));
+ for (i = 0; i < NUM_GPIOS; i++) {
+ if (!gpio_is_valid(fhci->gpios[i]))
+ continue;
+ gpio_free(fhci->gpios[i]);
+ }
+ for (j = 0; j < NUM_PINS; j++)
+ qe_pin_free(fhci->pins[j]);
+ fhci_dfs_destroy(fhci);
+ usb_put_hcd(hcd);
+ return 0;
+}
+
+static int __devexit of_fhci_remove(struct of_device *ofdev)
+{
+ return fhci_remove(&ofdev->dev);
+}
+
+static struct of_device_id of_fhci_match[] = {
+ { .compatible = "fsl,mpc8323-qe-usb", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_fhci_match);
+
+static struct of_platform_driver of_fhci_driver = {
+ .name = "fsl,usb-fhci",
+ .match_table = of_fhci_match,
+ .probe = of_fhci_probe,
+ .remove = __devexit_p(of_fhci_remove),
+};
+
+static int __init fhci_module_init(void)
+{
+ return of_register_platform_driver(&of_fhci_driver);
+}
+module_init(fhci_module_init);
+
+static void __exit fhci_module_exit(void)
+{
+ of_unregister_platform_driver(&of_fhci_driver);
+}
+module_exit(fhci_module_exit);
+
+MODULE_DESCRIPTION("USB Freescale Host Controller Interface Driver");
+MODULE_AUTHOR("Shlomi Gridish <gridish@freescale.com>, "
+ "Jerry Huang <Chang-Ming.Huang@freescale.com>, "
+ "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c
new file mode 100644
index 000000000000..0cfaedc3e124
--- /dev/null
+++ b/drivers/usb/host/fhci-hub.c
@@ -0,0 +1,345 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <linux/gpio.h>
+#include <asm/qe.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+/* virtual root hub specific descriptor */
+static u8 root_hub_des[] = {
+ 0x09, /* blength */
+ 0x29, /* bDescriptorType;hub-descriptor */
+ 0x01, /* bNbrPorts */
+ 0x00, /* wHubCharacteristics */
+ 0x00,
+ 0x01, /* bPwrOn2pwrGood;2ms */
+ 0x00, /* bHubContrCurrent;0mA */
+ 0x00, /* DeviceRemoveable */
+ 0xff, /* PortPwrCtrlMask */
+};
+
+static void fhci_gpio_set_value(struct fhci_hcd *fhci, int gpio_nr, bool on)
+{
+ int gpio = fhci->gpios[gpio_nr];
+ bool alow = fhci->alow_gpios[gpio_nr];
+
+ if (!gpio_is_valid(gpio))
+ return;
+
+ gpio_set_value(gpio, on ^ alow);
+ mdelay(5);
+}
+
+void fhci_config_transceiver(struct fhci_hcd *fhci,
+ enum fhci_port_status status)
+{
+ fhci_dbg(fhci, "-> %s: %d\n", __func__, status);
+
+ switch (status) {
+ case FHCI_PORT_POWER_OFF:
+ fhci_gpio_set_value(fhci, GPIO_POWER, false);
+ break;
+ case FHCI_PORT_DISABLED:
+ case FHCI_PORT_WAITING:
+ fhci_gpio_set_value(fhci, GPIO_POWER, true);
+ break;
+ case FHCI_PORT_LOW:
+ fhci_gpio_set_value(fhci, GPIO_SPEED, false);
+ break;
+ case FHCI_PORT_FULL:
+ fhci_gpio_set_value(fhci, GPIO_SPEED, true);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+
+ fhci_dbg(fhci, "<- %s: %d\n", __func__, status);
+}
+
+/* disable the USB port by clearing the EN bit in the USBMOD register */
+void fhci_port_disable(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = (struct fhci_usb *)fhci->usb_lld;
+ enum fhci_port_status port_status;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_stop_sof_timer(fhci);
+
+ fhci_flush_all_transmissions(usb);
+
+ fhci_usb_disable_interrupt((struct fhci_usb *)fhci->usb_lld);
+ port_status = usb->port_status;
+ usb->port_status = FHCI_PORT_DISABLED;
+
+ /* Enable IDLE since we want to know if something comes along */
+ usb->saved_msk |= USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+
+ /* check if during the disconnection process attached new device */
+ if (port_status == FHCI_PORT_WAITING)
+ fhci_device_connected_interrupt(fhci);
+ usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_ENABLE;
+ usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
+ fhci_usb_enable_interrupt((struct fhci_usb *)fhci->usb_lld);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+/* enable the USB port by setting the EN bit in the USBMOD register */
+void fhci_port_enable(void *lld)
+{
+ struct fhci_usb *usb = (struct fhci_usb *)lld;
+ struct fhci_hcd *fhci = usb->fhci;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_config_transceiver(fhci, usb->port_status);
+
+ if ((usb->port_status != FHCI_PORT_FULL) &&
+ (usb->port_status != FHCI_PORT_LOW))
+ fhci_start_sof_timer(fhci);
+
+ usb->vroot_hub->port.wPortStatus |= USB_PORT_STAT_ENABLE;
+ usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE;
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+void fhci_io_port_generate_reset(struct fhci_hcd *fhci)
+{
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ gpio_direction_output(fhci->gpios[GPIO_USBOE], 0);
+ gpio_direction_output(fhci->gpios[GPIO_USBTP], 0);
+ gpio_direction_output(fhci->gpios[GPIO_USBTN], 0);
+
+ mdelay(5);
+
+ qe_pin_set_dedicated(fhci->pins[PIN_USBOE]);
+ qe_pin_set_dedicated(fhci->pins[PIN_USBTP]);
+ qe_pin_set_dedicated(fhci->pins[PIN_USBTN]);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+/* generate the RESET condition on the bus */
+void fhci_port_reset(void *lld)
+{
+ struct fhci_usb *usb = (struct fhci_usb *)lld;
+ struct fhci_hcd *fhci = usb->fhci;
+ u8 mode;
+ u16 mask;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_stop_sof_timer(fhci);
+ /* disable the USB controller */
+ mode = in_8(&fhci->regs->usb_mod);
+ out_8(&fhci->regs->usb_mod, mode & (~USB_MODE_EN));
+
+ /* disable idle interrupts */
+ mask = in_be16(&fhci->regs->usb_mask);
+ out_be16(&fhci->regs->usb_mask, mask & (~USB_E_IDLE_MASK));
+
+ fhci_io_port_generate_reset(fhci);
+
+ /* enable interrupt on this endpoint */
+ out_be16(&fhci->regs->usb_mask, mask);
+
+ /* enable the USB controller */
+ mode = in_8(&fhci->regs->usb_mod);
+ out_8(&fhci->regs->usb_mod, mode | USB_MODE_EN);
+ fhci_start_sof_timer(fhci);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+int fhci_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ int ret = 0;
+ unsigned long flags;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ if (fhci->vroot_hub->port.wPortChange & (USB_PORT_STAT_C_CONNECTION |
+ USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_SUSPEND |
+ USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_OVERCURRENT)) {
+ *buf = 1 << 1;
+ ret = 1;
+ fhci_dbg(fhci, "-- %s\n", __func__);
+ }
+
+ spin_unlock_irqrestore(&fhci->lock, flags);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+
+ return ret;
+}
+
+int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buf, u16 wLength)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ int retval = 0;
+ int len = 0;
+ struct usb_hub_status *hub_status;
+ struct usb_port_status *port_status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ switch (typeReq) {
+ case ClearHubFeature:
+ switch (wValue) {
+ case C_HUB_LOCAL_POWER:
+ case C_HUB_OVER_CURRENT:
+ break;
+ default:
+ goto error;
+ }
+ break;
+ case ClearPortFeature:
+ fhci->vroot_hub->feature &= (1 << wValue);
+
+ switch (wValue) {
+ case USB_PORT_FEAT_ENABLE:
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_ENABLE;
+ fhci_port_disable(fhci);
+ break;
+ case USB_PORT_FEAT_C_ENABLE:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_ENABLE;
+ break;
+ case USB_PORT_FEAT_SUSPEND:
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_SUSPEND;
+ fhci_stop_sof_timer(fhci);
+ break;
+ case USB_PORT_FEAT_C_SUSPEND:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_SUSPEND;
+ break;
+ case USB_PORT_FEAT_POWER:
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_POWER;
+ fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
+ break;
+ case USB_PORT_FEAT_C_CONNECTION:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_CONNECTION;
+ break;
+ case USB_PORT_FEAT_C_OVER_CURRENT:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_OVERCURRENT;
+ break;
+ case USB_PORT_FEAT_C_RESET:
+ fhci->vroot_hub->port.wPortChange &=
+ ~USB_PORT_STAT_C_RESET;
+ break;
+ default:
+ goto error;
+ }
+ break;
+ case GetHubDescriptor:
+ memcpy(buf, root_hub_des, sizeof(root_hub_des));
+ buf[3] = 0x11; /* per-port power, no ovrcrnt */
+ len = (buf[0] < wLength) ? buf[0] : wLength;
+ break;
+ case GetHubStatus:
+ hub_status = (struct usb_hub_status *)buf;
+ hub_status->wHubStatus =
+ cpu_to_le16(fhci->vroot_hub->hub.wHubStatus);
+ hub_status->wHubChange =
+ cpu_to_le16(fhci->vroot_hub->hub.wHubChange);
+ len = 4;
+ break;
+ case GetPortStatus:
+ port_status = (struct usb_port_status *)buf;
+ port_status->wPortStatus =
+ cpu_to_le16(fhci->vroot_hub->port.wPortStatus);
+ port_status->wPortChange =
+ cpu_to_le16(fhci->vroot_hub->port.wPortChange);
+ len = 4;
+ break;
+ case SetHubFeature:
+ switch (wValue) {
+ case C_HUB_OVER_CURRENT:
+ case C_HUB_LOCAL_POWER:
+ break;
+ default:
+ goto error;
+ }
+ break;
+ case SetPortFeature:
+ fhci->vroot_hub->feature |= (1 << wValue);
+
+ switch (wValue) {
+ case USB_PORT_FEAT_ENABLE:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_ENABLE;
+ fhci_port_enable(fhci->usb_lld);
+ break;
+ case USB_PORT_FEAT_SUSPEND:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_SUSPEND;
+ fhci_stop_sof_timer(fhci);
+ break;
+ case USB_PORT_FEAT_RESET:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_RESET;
+ fhci_port_reset(fhci->usb_lld);
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_ENABLE;
+ fhci->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_RESET;
+ break;
+ case USB_PORT_FEAT_POWER:
+ fhci->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_POWER;
+ fhci_config_transceiver(fhci, FHCI_PORT_WAITING);
+ break;
+ default:
+ goto error;
+ }
+ break;
+ default:
+error:
+ retval = -EPIPE;
+ }
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+
+ spin_unlock_irqrestore(&fhci->lock, flags);
+
+ return retval;
+}
diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c
new file mode 100644
index 000000000000..2c0736c99712
--- /dev/null
+++ b/drivers/usb/host/fhci-mem.c
@@ -0,0 +1,113 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+static void init_td(struct td *td)
+{
+ memset(td, 0, sizeof(*td));
+ INIT_LIST_HEAD(&td->node);
+ INIT_LIST_HEAD(&td->frame_lh);
+}
+
+static void init_ed(struct ed *ed)
+{
+ memset(ed, 0, sizeof(*ed));
+ INIT_LIST_HEAD(&ed->td_list);
+ INIT_LIST_HEAD(&ed->node);
+}
+
+static struct td *get_empty_td(struct fhci_hcd *fhci)
+{
+ struct td *td;
+
+ if (!list_empty(&fhci->empty_tds)) {
+ td = list_entry(fhci->empty_tds.next, struct td, node);
+ list_del(fhci->empty_tds.next);
+ } else {
+ td = kmalloc(sizeof(*td), GFP_ATOMIC);
+ if (!td)
+ fhci_err(fhci, "No memory to allocate to TD\n");
+ else
+ init_td(td);
+ }
+
+ return td;
+}
+
+void fhci_recycle_empty_td(struct fhci_hcd *fhci, struct td *td)
+{
+ init_td(td);
+ list_add(&td->node, &fhci->empty_tds);
+}
+
+struct ed *fhci_get_empty_ed(struct fhci_hcd *fhci)
+{
+ struct ed *ed;
+
+ if (!list_empty(&fhci->empty_eds)) {
+ ed = list_entry(fhci->empty_eds.next, struct ed, node);
+ list_del(fhci->empty_eds.next);
+ } else {
+ ed = kmalloc(sizeof(*ed), GFP_ATOMIC);
+ if (!ed)
+ fhci_err(fhci, "No memory to allocate to ED\n");
+ else
+ init_ed(ed);
+ }
+
+ return ed;
+}
+
+void fhci_recycle_empty_ed(struct fhci_hcd *fhci, struct ed *ed)
+{
+ init_ed(ed);
+ list_add(&ed->node, &fhci->empty_eds);
+}
+
+struct td *fhci_td_fill(struct fhci_hcd *fhci, struct urb *urb,
+ struct urb_priv *urb_priv, struct ed *ed, u16 index,
+ enum fhci_ta_type type, int toggle, u8 *data, u32 len,
+ u16 interval, u16 start_frame, bool ioc)
+{
+ struct td *td = get_empty_td(fhci);
+
+ if (!td)
+ return NULL;
+
+ td->urb = urb;
+ td->ed = ed;
+ td->type = type;
+ td->toggle = toggle;
+ td->data = data;
+ td->len = len;
+ td->iso_index = index;
+ td->interval = interval;
+ td->start_frame = start_frame;
+ td->ioc = ioc;
+ td->status = USB_TD_OK;
+
+ urb_priv->tds[index] = td;
+
+ return td;
+}
diff --git a/drivers/usb/host/fhci-q.c b/drivers/usb/host/fhci-q.c
new file mode 100644
index 000000000000..b0a1446ba292
--- /dev/null
+++ b/drivers/usb/host/fhci-q.c
@@ -0,0 +1,284 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+/* maps the hardware error code to the USB error code */
+static int status_to_error(u32 status)
+{
+ if (status == USB_TD_OK)
+ return 0;
+ else if (status & USB_TD_RX_ER_CRC)
+ return -EILSEQ;
+ else if (status & USB_TD_RX_ER_NONOCT)
+ return -EPROTO;
+ else if (status & USB_TD_RX_ER_OVERUN)
+ return -ECOMM;
+ else if (status & USB_TD_RX_ER_BITSTUFF)
+ return -EPROTO;
+ else if (status & USB_TD_RX_ER_PID)
+ return -EILSEQ;
+ else if (status & (USB_TD_TX_ER_NAK | USB_TD_TX_ER_TIMEOUT))
+ return -ETIMEDOUT;
+ else if (status & USB_TD_TX_ER_STALL)
+ return -EPIPE;
+ else if (status & USB_TD_TX_ER_UNDERUN)
+ return -ENOSR;
+ else if (status & USB_TD_RX_DATA_UNDERUN)
+ return -EREMOTEIO;
+ else if (status & USB_TD_RX_DATA_OVERUN)
+ return -EOVERFLOW;
+ else
+ return -EINVAL;
+}
+
+void fhci_add_td_to_frame(struct fhci_time_frame *frame, struct td *td)
+{
+ list_add_tail(&td->frame_lh, &frame->tds_list);
+}
+
+void fhci_add_tds_to_ed(struct ed *ed, struct td **td_list, int number)
+{
+ int i;
+
+ for (i = 0; i < number; i++) {
+ struct td *td = td_list[i];
+ list_add_tail(&td->node, &ed->td_list);
+ }
+ if (ed->td_head == NULL)
+ ed->td_head = td_list[0];
+}
+
+static struct td *peek_td_from_ed(struct ed *ed)
+{
+ struct td *td;
+
+ if (!list_empty(&ed->td_list))
+ td = list_entry(ed->td_list.next, struct td, node);
+ else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_remove_td_from_frame(struct fhci_time_frame *frame)
+{
+ struct td *td;
+
+ if (!list_empty(&frame->tds_list)) {
+ td = list_entry(frame->tds_list.next, struct td, frame_lh);
+ list_del_init(frame->tds_list.next);
+ } else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_peek_td_from_frame(struct fhci_time_frame *frame)
+{
+ struct td *td;
+
+ if (!list_empty(&frame->tds_list))
+ td = list_entry(frame->tds_list.next, struct td, frame_lh);
+ else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_remove_td_from_ed(struct ed *ed)
+{
+ struct td *td;
+
+ if (!list_empty(&ed->td_list)) {
+ td = list_entry(ed->td_list.next, struct td, node);
+ list_del_init(ed->td_list.next);
+
+ /* if this TD was the ED's head, find next TD */
+ if (!list_empty(&ed->td_list))
+ ed->td_head = list_entry(ed->td_list.next, struct td,
+ node);
+ else
+ ed->td_head = NULL;
+ } else
+ td = NULL;
+
+ return td;
+}
+
+struct td *fhci_remove_td_from_done_list(struct fhci_controller_list *p_list)
+{
+ struct td *td;
+
+ if (!list_empty(&p_list->done_list)) {
+ td = list_entry(p_list->done_list.next, struct td, node);
+ list_del_init(p_list->done_list.next);
+ } else
+ td = NULL;
+
+ return td;
+}
+
+void fhci_move_td_from_ed_to_done_list(struct fhci_usb *usb, struct ed *ed)
+{
+ struct td *td;
+
+ td = ed->td_head;
+ list_del_init(&td->node);
+
+ /* If this TD was the ED's head,find next TD */
+ if (!list_empty(&ed->td_list))
+ ed->td_head = list_entry(ed->td_list.next, struct td, node);
+ else {
+ ed->td_head = NULL;
+ ed->state = FHCI_ED_SKIP;
+ }
+ ed->toggle_carry = td->toggle;
+ list_add_tail(&td->node, &usb->hc_list->done_list);
+ if (td->ioc)
+ usb->transfer_confirm(usb->fhci);
+}
+
+/* free done FHCI URB resource such as ED and TD */
+static void free_urb_priv(struct fhci_hcd *fhci, struct urb *urb)
+{
+ int i;
+ struct urb_priv *urb_priv = urb->hcpriv;
+ struct ed *ed = urb_priv->ed;
+
+ for (i = 0; i < urb_priv->num_of_tds; i++) {
+ list_del_init(&urb_priv->tds[i]->node);
+ fhci_recycle_empty_td(fhci, urb_priv->tds[i]);
+ }
+
+ /* if this TD was the ED's head,find the next TD */
+ if (!list_empty(&ed->td_list))
+ ed->td_head = list_entry(ed->td_list.next, struct td, node);
+ else
+ ed->td_head = NULL;
+
+ kfree(urb_priv->tds);
+ kfree(urb_priv);
+ urb->hcpriv = NULL;
+
+ /* if this TD was the ED's head,find next TD */
+ if (ed->td_head == NULL)
+ list_del_init(&ed->node);
+ fhci->active_urbs--;
+}
+
+/* this routine called to complete and free done URB */
+void fhci_urb_complete_free(struct fhci_hcd *fhci, struct urb *urb)
+{
+ free_urb_priv(fhci, urb);
+
+ if (urb->status == -EINPROGRESS) {
+ if (urb->actual_length != urb->transfer_buffer_length &&
+ urb->transfer_flags & URB_SHORT_NOT_OK)
+ urb->status = -EREMOTEIO;
+ else
+ urb->status = 0;
+ }
+
+ usb_hcd_unlink_urb_from_ep(fhci_to_hcd(fhci), urb);
+
+ spin_unlock(&fhci->lock);
+
+ usb_hcd_giveback_urb(fhci_to_hcd(fhci), urb, urb->status);
+
+ spin_lock(&fhci->lock);
+}
+
+/*
+ * caculate transfer length/stats and update the urb
+ * Precondition: irqsafe(only for urb-?status locking)
+ */
+void fhci_done_td(struct urb *urb, struct td *td)
+{
+ struct ed *ed = td->ed;
+ u32 cc = td->status;
+
+ /* ISO...drivers see per-TD length/status */
+ if (ed->mode == FHCI_TF_ISO) {
+ u32 len;
+ if (!(urb->transfer_flags & URB_SHORT_NOT_OK &&
+ cc == USB_TD_RX_DATA_UNDERUN))
+ cc = USB_TD_OK;
+
+ if (usb_pipeout(urb->pipe))
+ len = urb->iso_frame_desc[td->iso_index].length;
+ else
+ len = td->actual_len;
+
+ urb->actual_length += len;
+ urb->iso_frame_desc[td->iso_index].actual_length = len;
+ urb->iso_frame_desc[td->iso_index].status =
+ status_to_error(cc);
+ }
+
+ /* BULK,INT,CONTROL... drivers see aggregate length/status,
+ * except that "setup" bytes aren't counted and "short" transfers
+ * might not be reported as errors.
+ */
+ else {
+ if (td->error_cnt >= 3)
+ urb->error_count = 3;
+
+ /* control endpoint only have soft stalls */
+
+ /* update packet status if needed(short may be ok) */
+ if (!(urb->transfer_flags & URB_SHORT_NOT_OK) &&
+ cc == USB_TD_RX_DATA_UNDERUN) {
+ ed->state = FHCI_ED_OPER;
+ cc = USB_TD_OK;
+ }
+ if (cc != USB_TD_OK) {
+ if (urb->status == -EINPROGRESS)
+ urb->status = status_to_error(cc);
+ }
+
+ /* count all non-empty packets except control SETUP packet */
+ if (td->type != FHCI_TA_SETUP || td->iso_index != 0)
+ urb->actual_length += td->actual_len;
+ }
+}
+
+/* there are some pedning request to unlink */
+void fhci_del_ed_list(struct fhci_hcd *fhci, struct ed *ed)
+{
+ struct td *td = peek_td_from_ed(ed);
+ struct urb *urb = td->urb;
+ struct urb_priv *urb_priv = urb->hcpriv;
+
+ if (urb_priv->state == URB_DEL) {
+ td = fhci_remove_td_from_ed(ed);
+ /* HC may have partly processed this TD */
+ if (td->status != USB_TD_INPROGRESS)
+ fhci_done_td(urb, td);
+
+ /* URB is done;clean up */
+ if (++(urb_priv->tds_cnt) == urb_priv->num_of_tds)
+ fhci_urb_complete_free(fhci, urb);
+ }
+}
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c
new file mode 100644
index 000000000000..bb63b68ddb77
--- /dev/null
+++ b/drivers/usb/host/fhci-sched.c
@@ -0,0 +1,888 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <asm/qe.h>
+#include <asm/fsl_gtm.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+static void recycle_frame(struct fhci_usb *usb, struct packet *pkt)
+{
+ pkt->data = NULL;
+ pkt->len = 0;
+ pkt->status = USB_TD_OK;
+ pkt->info = 0;
+ pkt->priv_data = NULL;
+
+ cq_put(usb->ep0->empty_frame_Q, pkt);
+}
+
+/* confirm submitted packet */
+void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt)
+{
+ struct td *td;
+ struct packet *td_pkt;
+ struct ed *ed;
+ u32 trans_len;
+ bool td_done = false;
+
+ td = fhci_remove_td_from_frame(usb->actual_frame);
+ td_pkt = td->pkt;
+ trans_len = pkt->len;
+ td->status = pkt->status;
+ if (td->type == FHCI_TA_IN && td_pkt->info & PKT_DUMMY_PACKET) {
+ if ((td->data + td->actual_len) && trans_len)
+ memcpy(td->data + td->actual_len, pkt->data,
+ trans_len);
+ cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+ }
+
+ recycle_frame(usb, pkt);
+
+ ed = td->ed;
+ if (ed->mode == FHCI_TF_ISO) {
+ if (ed->td_list.next->next != &ed->td_list) {
+ struct td *td_next =
+ list_entry(ed->td_list.next->next, struct td,
+ node);
+
+ td_next->start_frame = usb->actual_frame->frame_num;
+ }
+ td->actual_len = trans_len;
+ td_done = true;
+ } else if ((td->status & USB_TD_ERROR) &&
+ !(td->status & USB_TD_TX_ER_NAK)) {
+ /*
+ * There was an error on the transaction (but not NAK).
+ * If it is fatal error (data underrun, stall, bad pid or 3
+ * errors exceeded), mark this TD as done.
+ */
+ if ((td->status & USB_TD_RX_DATA_UNDERUN) ||
+ (td->status & USB_TD_TX_ER_STALL) ||
+ (td->status & USB_TD_RX_ER_PID) ||
+ (++td->error_cnt >= 3)) {
+ ed->state = FHCI_ED_HALTED;
+ td_done = true;
+
+ if (td->status & USB_TD_RX_DATA_UNDERUN) {
+ fhci_dbg(usb->fhci, "td err fu\n");
+ td->toggle = !td->toggle;
+ td->actual_len += trans_len;
+ } else {
+ fhci_dbg(usb->fhci, "td err f!u\n");
+ }
+ } else {
+ fhci_dbg(usb->fhci, "td err !f\n");
+ /* it is not a fatal error -retry this transaction */
+ td->nak_cnt = 0;
+ td->error_cnt++;
+ td->status = USB_TD_OK;
+ }
+ } else if (td->status & USB_TD_TX_ER_NAK) {
+ /* there was a NAK response */
+ fhci_vdbg(usb->fhci, "td nack\n");
+ td->nak_cnt++;
+ td->error_cnt = 0;
+ td->status = USB_TD_OK;
+ } else {
+ /* there was no error on transaction */
+ td->error_cnt = 0;
+ td->nak_cnt = 0;
+ td->toggle = !td->toggle;
+ td->actual_len += trans_len;
+
+ if (td->len == td->actual_len)
+ td_done = true;
+ }
+
+ if (td_done)
+ fhci_move_td_from_ed_to_done_list(usb, ed);
+}
+
+/*
+ * Flush all transmitted packets from BDs
+ * This routine is called when disabling the USB port to flush all
+ * transmissions that are allready scheduled in the BDs
+ */
+void fhci_flush_all_transmissions(struct fhci_usb *usb)
+{
+ u8 mode;
+ struct td *td;
+
+ mode = in_8(&usb->fhci->regs->usb_mod);
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN);
+
+ fhci_flush_bds(usb);
+
+ while ((td = fhci_peek_td_from_frame(usb->actual_frame)) != NULL) {
+ struct packet *pkt = td->pkt;
+
+ pkt->status = USB_TD_TX_ER_TIMEOUT;
+ fhci_transaction_confirm(usb, pkt);
+ }
+
+ usb->actual_frame->frame_status = FRAME_END_TRANSMISSION;
+
+ /* reset the event register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ /* enable the USB controller */
+ out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN);
+}
+
+/*
+ * This function forms the packet and transmit the packet. This function
+ * will handle all endpoint type:ISO,interrupt,control and bulk
+ */
+static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td)
+{
+ u32 fw_transaction_time, len = 0;
+ struct packet *pkt;
+ u8 *data = NULL;
+
+ /* calcalate data address,len and toggle and then add the transaction */
+ if (td->toggle == USB_TD_TOGGLE_CARRY)
+ td->toggle = ed->toggle_carry;
+
+ switch (ed->mode) {
+ case FHCI_TF_ISO:
+ len = td->len;
+ if (td->type != FHCI_TA_IN)
+ data = td->data;
+ break;
+ case FHCI_TF_CTRL:
+ case FHCI_TF_BULK:
+ len = min(td->len - td->actual_len, ed->max_pkt_size);
+ if (!((td->type == FHCI_TA_IN) &&
+ ((len + td->actual_len) == td->len)))
+ data = td->data + td->actual_len;
+ break;
+ case FHCI_TF_INTR:
+ len = min(td->len, ed->max_pkt_size);
+ if (!((td->type == FHCI_TA_IN) &&
+ ((td->len + CRC_SIZE) >= ed->max_pkt_size)))
+ data = td->data;
+ break;
+ default:
+ break;
+ }
+
+ if (usb->port_status == FHCI_PORT_FULL)
+ fw_transaction_time = (((len + PROTOCOL_OVERHEAD) * 11) >> 4);
+ else
+ fw_transaction_time = ((len + PROTOCOL_OVERHEAD) * 6);
+
+ /* check if there's enough space in this frame to submit this TD */
+ if (usb->actual_frame->total_bytes + len + PROTOCOL_OVERHEAD >=
+ usb->max_bytes_per_frame) {
+ fhci_vdbg(usb->fhci, "not enough space in this frame: "
+ "%d %d %d\n", usb->actual_frame->total_bytes, len,
+ usb->max_bytes_per_frame);
+ return -1;
+ }
+
+ /* check if there's enough time in this frame to submit this TD */
+ if (usb->actual_frame->frame_status != FRAME_IS_PREPARED &&
+ (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION ||
+ (fw_transaction_time + usb->sw_transaction_time >=
+ 1000 - fhci_get_sof_timer_count(usb)))) {
+ fhci_dbg(usb->fhci, "not enough time in this frame\n");
+ return -1;
+ }
+
+ /* update frame object fields before transmitting */
+ pkt = cq_get(usb->ep0->empty_frame_Q);
+ if (!pkt) {
+ fhci_dbg(usb->fhci, "there is no empty frame\n");
+ return -1;
+ }
+ td->pkt = pkt;
+
+ pkt->info = 0;
+ if (data == NULL) {
+ data = cq_get(usb->ep0->dummy_packets_Q);
+ BUG_ON(!data);
+ pkt->info = PKT_DUMMY_PACKET;
+ }
+ pkt->data = data;
+ pkt->len = len;
+ pkt->status = USB_TD_OK;
+ /* update TD status field before transmitting */
+ td->status = USB_TD_INPROGRESS;
+ /* update actual frame time object with the actual transmission */
+ usb->actual_frame->total_bytes += (len + PROTOCOL_OVERHEAD);
+ fhci_add_td_to_frame(usb->actual_frame, td);
+
+ if (usb->port_status != FHCI_PORT_FULL &&
+ usb->port_status != FHCI_PORT_LOW) {
+ pkt->status = USB_TD_TX_ER_TIMEOUT;
+ pkt->len = 0;
+ fhci_transaction_confirm(usb, pkt);
+ } else if (fhci_host_transaction(usb, pkt, td->type, ed->dev_addr,
+ ed->ep_addr, ed->mode, ed->speed, td->toggle)) {
+ /* remove TD from actual frame */
+ list_del_init(&td->frame_lh);
+ td->status = USB_TD_OK;
+ if (pkt->info & PKT_DUMMY_PACKET)
+ cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+ recycle_frame(usb, pkt);
+ usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD);
+ fhci_err(usb->fhci, "host transaction failed\n");
+ return -1;
+ }
+
+ return len;
+}
+
+static void move_head_to_tail(struct list_head *list)
+{
+ struct list_head *node = list->next;
+
+ if (!list_empty(list)) {
+ list_del(node);
+ list_add_tail(node, list);
+ }
+}
+
+/*
+ * This function goes through the endpoint list and schedules the
+ * transactions within this list
+ */
+static int scan_ed_list(struct fhci_usb *usb,
+ struct list_head *list, enum fhci_tf_mode list_type)
+{
+ static const int frame_part[4] = {
+ [FHCI_TF_CTRL] = MAX_BYTES_PER_FRAME,
+ [FHCI_TF_ISO] = (MAX_BYTES_PER_FRAME *
+ MAX_PERIODIC_FRAME_USAGE) / 100,
+ [FHCI_TF_BULK] = MAX_BYTES_PER_FRAME,
+ [FHCI_TF_INTR] = (MAX_BYTES_PER_FRAME *
+ MAX_PERIODIC_FRAME_USAGE) / 100
+ };
+ struct ed *ed;
+ struct td *td;
+ int ans = 1;
+ u32 save_transaction_time = usb->sw_transaction_time;
+
+ list_for_each_entry(ed, list, node) {
+ td = ed->td_head;
+
+ if (!td || (td && td->status == USB_TD_INPROGRESS))
+ continue;
+
+ if (ed->state != FHCI_ED_OPER) {
+ if (ed->state == FHCI_ED_URB_DEL) {
+ td->status = USB_TD_OK;
+ fhci_move_td_from_ed_to_done_list(usb, ed);
+ ed->state = FHCI_ED_SKIP;
+ }
+ continue;
+ }
+
+ /*
+ * if it isn't interrupt pipe or it is not iso pipe and the
+ * interval time passed
+ */
+ if ((list_type == FHCI_TF_INTR || list_type == FHCI_TF_ISO) &&
+ (((usb->actual_frame->frame_num -
+ td->start_frame) & 0x7ff) < td->interval))
+ continue;
+
+ if (add_packet(usb, ed, td) < 0)
+ continue;
+
+ /* update time stamps in the TD */
+ td->start_frame = usb->actual_frame->frame_num;
+ usb->sw_transaction_time += save_transaction_time;
+
+ if (usb->actual_frame->total_bytes >=
+ usb->max_bytes_per_frame) {
+ usb->actual_frame->frame_status =
+ FRAME_DATA_END_TRANSMISSION;
+ fhci_push_dummy_bd(usb->ep0);
+ ans = 0;
+ break;
+ }
+
+ if (usb->actual_frame->total_bytes >= frame_part[list_type])
+ break;
+ }
+
+ /* be fair to each ED(move list head around) */
+ move_head_to_tail(list);
+ usb->sw_transaction_time = save_transaction_time;
+
+ return ans;
+}
+
+static u32 rotate_frames(struct fhci_usb *usb)
+{
+ struct fhci_hcd *fhci = usb->fhci;
+
+ if (!list_empty(&usb->actual_frame->tds_list)) {
+ if ((((in_be16(&fhci->pram->frame_num) & 0x07ff) -
+ usb->actual_frame->frame_num) & 0x7ff) > 5)
+ fhci_flush_actual_frame(usb);
+ else
+ return -EINVAL;
+ }
+
+ usb->actual_frame->frame_status = FRAME_IS_PREPARED;
+ usb->actual_frame->frame_num = in_be16(&fhci->pram->frame_num) & 0x7ff;
+ usb->actual_frame->total_bytes = 0;
+
+ return 0;
+}
+
+/*
+ * This function schedule the USB transaction and will process the
+ * endpoint in the following order: iso, interrupt, control and bulk.
+ */
+void fhci_schedule_transactions(struct fhci_usb *usb)
+{
+ int left = 1;
+
+ if (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)
+ if (rotate_frames(usb) != 0)
+ return;
+
+ if (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)
+ return;
+
+ if (usb->actual_frame->total_bytes == 0) {
+ /*
+ * schedule the next available ISO transfer
+ *or next stage of the ISO transfer
+ */
+ scan_ed_list(usb, &usb->hc_list->iso_list, FHCI_TF_ISO);
+
+ /*
+ * schedule the next available interrupt transfer or
+ * the next stage of the interrupt transfer
+ */
+ scan_ed_list(usb, &usb->hc_list->intr_list, FHCI_TF_INTR);
+
+ /*
+ * schedule the next available control transfer
+ * or the next stage of the control transfer
+ */
+ left = scan_ed_list(usb, &usb->hc_list->ctrl_list,
+ FHCI_TF_CTRL);
+ }
+
+ /*
+ * schedule the next available bulk transfer or the next stage of the
+ * bulk transfer
+ */
+ if (left > 0)
+ scan_ed_list(usb, &usb->hc_list->bulk_list, FHCI_TF_BULK);
+}
+
+/* Handles SOF interrupt */
+static void sof_interrupt(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ if ((usb->port_status == FHCI_PORT_DISABLED) &&
+ (usb->vroot_hub->port.wPortStatus & USB_PORT_STAT_CONNECTION) &&
+ !(usb->vroot_hub->port.wPortChange & USB_PORT_STAT_C_CONNECTION)) {
+ if (usb->vroot_hub->port.wPortStatus & USB_PORT_STAT_LOW_SPEED)
+ usb->port_status = FHCI_PORT_LOW;
+ else
+ usb->port_status = FHCI_PORT_FULL;
+ /* Disable IDLE */
+ usb->saved_msk &= ~USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+ }
+
+ gtm_set_exact_timer16(fhci->timer, usb->max_frame_usage, false);
+
+ fhci_host_transmit_actual_frame(usb);
+ usb->actual_frame->frame_status = FRAME_IS_TRANSMITTED;
+
+ fhci_schedule_transactions(usb);
+}
+
+/* Handles device disconnected interrupt on port */
+void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci)
+{
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_usb_disable_interrupt(usb);
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+ usb->port_status = FHCI_PORT_DISABLED;
+
+ fhci_stop_sof_timer(fhci);
+
+ /* Enable IDLE since we want to know if something comes along */
+ usb->saved_msk |= USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk);
+
+ usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_CONNECTION;
+ usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_CONNECTION;
+ usb->max_bytes_per_frame = 0;
+ fhci_usb_enable_interrupt(usb);
+
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+/* detect a new device connected on the USB port */
+void fhci_device_connected_interrupt(struct fhci_hcd *fhci)
+{
+
+ struct fhci_usb *usb = fhci->usb_lld;
+ int state;
+ int ret;
+
+ fhci_dbg(fhci, "-> %s\n", __func__);
+
+ fhci_usb_disable_interrupt(usb);
+ state = fhci_ioports_check_bus_state(fhci);
+
+ /* low-speed device was connected to the USB port */
+ if (state == 1) {
+ ret = qe_usb_clock_set(fhci->lowspeed_clk, USB_CLOCK >> 3);
+ if (ret) {
+ fhci_warn(fhci, "Low-Speed device is not supported, "
+ "try use BRGx\n");
+ goto out;
+ }
+
+ usb->port_status = FHCI_PORT_LOW;
+ setbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+ usb->vroot_hub->port.wPortStatus |=
+ (USB_PORT_STAT_LOW_SPEED |
+ USB_PORT_STAT_CONNECTION);
+ usb->vroot_hub->port.wPortChange |=
+ USB_PORT_STAT_C_CONNECTION;
+ usb->max_bytes_per_frame =
+ (MAX_BYTES_PER_FRAME >> 3) - 7;
+ fhci_port_enable(usb);
+ } else if (state == 2) {
+ ret = qe_usb_clock_set(fhci->fullspeed_clk, USB_CLOCK);
+ if (ret) {
+ fhci_warn(fhci, "Full-Speed device is not supported, "
+ "try use CLKx\n");
+ goto out;
+ }
+
+ usb->port_status = FHCI_PORT_FULL;
+ clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS);
+ usb->vroot_hub->port.wPortStatus &=
+ ~USB_PORT_STAT_LOW_SPEED;
+ usb->vroot_hub->port.wPortStatus |=
+ USB_PORT_STAT_CONNECTION;
+ usb->vroot_hub->port.wPortChange |=
+ USB_PORT_STAT_C_CONNECTION;
+ usb->max_bytes_per_frame = (MAX_BYTES_PER_FRAME - 15);
+ fhci_port_enable(usb);
+ }
+out:
+ fhci_usb_enable_interrupt(usb);
+ fhci_dbg(fhci, "<- %s\n", __func__);
+}
+
+irqreturn_t fhci_frame_limit_timer_irq(int irq, void *_hcd)
+{
+ struct usb_hcd *hcd = _hcd;
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ struct fhci_usb *usb = fhci->usb_lld;
+
+ spin_lock(&fhci->lock);
+
+ gtm_set_exact_timer16(fhci->timer, 1000, false);
+
+ if (usb->actual_frame->frame_status == FRAME_IS_TRANSMITTED) {
+ usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
+ fhci_push_dummy_bd(usb->ep0);
+ }
+
+ fhci_schedule_transactions(usb);
+
+ spin_unlock(&fhci->lock);
+
+ return IRQ_HANDLED;
+}
+
+/* Cancel transmission on the USB endpoint */
+static void abort_transmission(struct fhci_usb *usb)
+{
+ fhci_dbg(usb->fhci, "-> %s\n", __func__);
+ /* issue stop Tx command */
+ qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0);
+ /* flush Tx FIFOs */
+ out_8(&usb->fhci->regs->usb_comm, USB_CMD_FLUSH_FIFO | EP_ZERO);
+ udelay(1000);
+ /* reset Tx BDs */
+ fhci_flush_bds(usb);
+ /* issue restart Tx command */
+ qe_issue_cmd(QE_USB_RESTART_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0);
+ fhci_dbg(usb->fhci, "<- %s\n", __func__);
+}
+
+irqreturn_t fhci_irq(struct usb_hcd *hcd)
+{
+ struct fhci_hcd *fhci = hcd_to_fhci(hcd);
+ struct fhci_usb *usb;
+ u16 usb_er = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fhci->lock, flags);
+
+ usb = fhci->usb_lld;
+
+ usb_er |= in_be16(&usb->fhci->regs->usb_event) &
+ in_be16(&usb->fhci->regs->usb_mask);
+
+ /* clear event bits for next time */
+ out_be16(&usb->fhci->regs->usb_event, usb_er);
+
+ fhci_dbg_isr(fhci, usb_er);
+
+ if (usb_er & USB_E_RESET_MASK) {
+ if ((usb->port_status == FHCI_PORT_FULL) ||
+ (usb->port_status == FHCI_PORT_LOW)) {
+ fhci_device_disconnected_interrupt(fhci);
+ usb_er &= ~USB_E_IDLE_MASK;
+ } else if (usb->port_status == FHCI_PORT_WAITING) {
+ usb->port_status = FHCI_PORT_DISCONNECTING;
+
+ /* Turn on IDLE since we want to disconnect */
+ usb->saved_msk |= USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_event,
+ usb->saved_msk);
+ } else if (usb->port_status == FHCI_PORT_DISABLED) {
+ if (fhci_ioports_check_bus_state(fhci) == 1 &&
+ usb->port_status != FHCI_PORT_LOW &&
+ usb->port_status != FHCI_PORT_FULL)
+ fhci_device_connected_interrupt(fhci);
+ }
+ usb_er &= ~USB_E_RESET_MASK;
+ }
+
+ if (usb_er & USB_E_MSF_MASK) {
+ abort_transmission(fhci->usb_lld);
+ usb_er &= ~USB_E_MSF_MASK;
+ }
+
+ if (usb_er & (USB_E_SOF_MASK | USB_E_SFT_MASK)) {
+ sof_interrupt(fhci);
+ usb_er &= ~(USB_E_SOF_MASK | USB_E_SFT_MASK);
+ }
+
+ if (usb_er & USB_E_TXB_MASK) {
+ fhci_tx_conf_interrupt(fhci->usb_lld);
+ usb_er &= ~USB_E_TXB_MASK;
+ }
+
+ if (usb_er & USB_E_TXE1_MASK) {
+ fhci_tx_conf_interrupt(fhci->usb_lld);
+ usb_er &= ~USB_E_TXE1_MASK;
+ }
+
+ if (usb_er & USB_E_IDLE_MASK) {
+ if (usb->port_status == FHCI_PORT_DISABLED &&
+ usb->port_status != FHCI_PORT_LOW &&
+ usb->port_status != FHCI_PORT_FULL) {
+ usb_er &= ~USB_E_RESET_MASK;
+ fhci_device_connected_interrupt(fhci);
+ } else if (usb->port_status ==
+ FHCI_PORT_DISCONNECTING) {
+ /* XXX usb->port_status = FHCI_PORT_WAITING; */
+ /* Disable IDLE */
+ usb->saved_msk &= ~USB_E_IDLE_MASK;
+ out_be16(&usb->fhci->regs->usb_mask,
+ usb->saved_msk);
+ } else {
+ fhci_dbg_isr(fhci, -1);
+ }
+
+ usb_er &= ~USB_E_IDLE_MASK;
+ }
+
+ spin_unlock_irqrestore(&fhci->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * Process normal completions(error or sucess) and clean the schedule.
+ *
+ * This is the main path for handing urbs back to drivers. The only other patth
+ * is process_del_list(),which unlinks URBs by scanning EDs,instead of scanning
+ * the (re-reversed) done list as this does.
+ */
+static void process_done_list(unsigned long data)
+{
+ struct urb *urb;
+ struct ed *ed;
+ struct td *td;
+ struct urb_priv *urb_priv;
+ struct fhci_hcd *fhci = (struct fhci_hcd *)data;
+
+ disable_irq(fhci->timer->irq);
+ disable_irq(fhci_to_hcd(fhci)->irq);
+ spin_lock(&fhci->lock);
+
+ td = fhci_remove_td_from_done_list(fhci->hc_list);
+ while (td != NULL) {
+ urb = td->urb;
+ urb_priv = urb->hcpriv;
+ ed = td->ed;
+
+ /* update URB's length and status from TD */
+ fhci_done_td(urb, td);
+ urb_priv->tds_cnt++;
+
+ /*
+ * if all this urb's TDs are done, call complete()
+ * Interrupt transfers are the onley special case:
+ * they are reissued,until "deleted" by usb_unlink_urb
+ * (real work done in a SOF intr, by process_del_list)
+ */
+ if (urb_priv->tds_cnt == urb_priv->num_of_tds) {
+ fhci_urb_complete_free(fhci, urb);
+ } else if (urb_priv->state == URB_DEL &&
+ ed->state == FHCI_ED_SKIP) {
+ fhci_del_ed_list(fhci, ed);
+ ed->state = FHCI_ED_OPER;
+ } else if (ed->state == FHCI_ED_HALTED) {
+ urb_priv->state = URB_DEL;
+ ed->state = FHCI_ED_URB_DEL;
+ fhci_del_ed_list(fhci, ed);
+ ed->state = FHCI_ED_OPER;
+ }
+
+ td = fhci_remove_td_from_done_list(fhci->hc_list);
+ }
+
+ spin_unlock(&fhci->lock);
+ enable_irq(fhci->timer->irq);
+ enable_irq(fhci_to_hcd(fhci)->irq);
+}
+
+DECLARE_TASKLET(fhci_tasklet, process_done_list, 0);
+
+/* transfer complted callback */
+u32 fhci_transfer_confirm_callback(struct fhci_hcd *fhci)
+{
+ if (!fhci->process_done_task->state)
+ tasklet_schedule(fhci->process_done_task);
+ return 0;
+}
+
+/*
+ * adds urb to the endpoint descriptor list
+ * arguments:
+ * fhci data structure for the Low level host controller
+ * ep USB Host endpoint data structure
+ * urb USB request block data structure
+ */
+void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
+{
+ struct ed *ed = urb->ep->hcpriv;
+ struct urb_priv *urb_priv = urb->hcpriv;
+ u32 data_len = urb->transfer_buffer_length;
+ int urb_state = 0;
+ int toggle = 0;
+ struct td *td;
+ u8 *data;
+ u16 cnt = 0;
+
+ if (ed == NULL) {
+ ed = fhci_get_empty_ed(fhci);
+ ed->dev_addr = usb_pipedevice(urb->pipe);
+ ed->ep_addr = usb_pipeendpoint(urb->pipe);
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_CONTROL:
+ ed->mode = FHCI_TF_CTRL;
+ break;
+ case PIPE_BULK:
+ ed->mode = FHCI_TF_BULK;
+ break;
+ case PIPE_INTERRUPT:
+ ed->mode = FHCI_TF_INTR;
+ break;
+ case PIPE_ISOCHRONOUS:
+ ed->mode = FHCI_TF_ISO;
+ break;
+ default:
+ break;
+ }
+ ed->speed = (urb->dev->speed == USB_SPEED_LOW) ?
+ FHCI_LOW_SPEED : FHCI_FULL_SPEED;
+ ed->max_pkt_size = usb_maxpacket(urb->dev,
+ urb->pipe, usb_pipeout(urb->pipe));
+ urb->ep->hcpriv = ed;
+ fhci_dbg(fhci, "new ep speed=%d max_pkt_size=%d\n",
+ ed->speed, ed->max_pkt_size);
+ }
+
+ /* for ISO transfer calculate start frame index */
+ if (ed->mode == FHCI_TF_ISO && urb->transfer_flags & URB_ISO_ASAP)
+ urb->start_frame = ed->td_head ? ed->last_iso + 1 :
+ get_frame_num(fhci);
+
+ /*
+ * OHCI handles the DATA toggle itself,we just use the USB
+ * toggle bits
+ */
+ if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+ usb_pipeout(urb->pipe)))
+ toggle = USB_TD_TOGGLE_CARRY;
+ else {
+ toggle = USB_TD_TOGGLE_DATA0;
+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+ usb_pipeout(urb->pipe), 1);
+ }
+
+ urb_priv->tds_cnt = 0;
+ urb_priv->ed = ed;
+ if (data_len > 0)
+ data = urb->transfer_buffer;
+ else
+ data = NULL;
+
+ switch (ed->mode) {
+ case FHCI_TF_BULK:
+ if (urb->transfer_flags & URB_ZERO_PACKET &&
+ urb->transfer_buffer_length > 0 &&
+ ((urb->transfer_buffer_length %
+ usb_maxpacket(urb->dev, urb->pipe,
+ usb_pipeout(urb->pipe))) == 0))
+ urb_state = US_BULK0;
+ while (data_len > 4096) {
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ cnt ? USB_TD_TOGGLE_CARRY :
+ toggle,
+ data, 4096, 0, 0, true);
+ data += 4096;
+ data_len -= 4096;
+ cnt++;
+ }
+
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN,
+ cnt ? USB_TD_TOGGLE_CARRY : toggle,
+ data, data_len, 0, 0, true);
+ cnt++;
+
+ if (urb->transfer_flags & URB_ZERO_PACKET &&
+ cnt < urb_priv->num_of_tds) {
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ USB_TD_TOGGLE_CARRY, NULL, 0, 0, 0, true);
+ cnt++;
+ }
+ break;
+ case FHCI_TF_INTR:
+ urb->start_frame = get_frame_num(fhci) + 1;
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN,
+ USB_TD_TOGGLE_DATA0, data, data_len,
+ urb->interval, urb->start_frame, true);
+ break;
+ case FHCI_TF_CTRL:
+ ed->dev_addr = usb_pipedevice(urb->pipe);
+ ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe,
+ usb_pipeout(urb->pipe));
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP,
+ USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true);
+
+ if (data_len > 0) {
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ USB_TD_TOGGLE_DATA1, data, data_len, 0, 0,
+ true);
+ }
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ usb_pipeout(urb->pipe) ? FHCI_TA_IN : FHCI_TA_OUT,
+ USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true);
+ urb_state = US_CTRL_SETUP;
+ break;
+ case FHCI_TF_ISO:
+ for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
+ u16 frame = urb->start_frame;
+
+ /*
+ * FIXME scheduling should handle frame counter
+ * roll-around ... exotic case (and OHCI has
+ * a 2^16 iso range, vs other HCs max of 2^10)
+ */
+ frame += cnt * urb->interval;
+ frame &= 0x07ff;
+ td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
+ FHCI_TA_IN,
+ USB_TD_TOGGLE_DATA0,
+ data + urb->iso_frame_desc[cnt].offset,
+ urb->iso_frame_desc[cnt].length,
+ urb->interval, frame, true);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * set the state of URB
+ * control pipe:3 states -- setup,data,status
+ * interrupt and bulk pipe:1 state -- data
+ */
+ urb->pipe &= ~0x1f;
+ urb->pipe |= urb_state & 0x1f;
+
+ urb_priv->state = URB_INPROGRESS;
+
+ if (!ed->td_head) {
+ ed->state = FHCI_ED_OPER;
+ switch (ed->mode) {
+ case FHCI_TF_CTRL:
+ list_add(&ed->node, &fhci->hc_list->ctrl_list);
+ break;
+ case FHCI_TF_BULK:
+ list_add(&ed->node, &fhci->hc_list->bulk_list);
+ break;
+ case FHCI_TF_INTR:
+ list_add(&ed->node, &fhci->hc_list->intr_list);
+ break;
+ case FHCI_TF_ISO:
+ list_add(&ed->node, &fhci->hc_list->iso_list);
+ break;
+ default:
+ break;
+ }
+ }
+
+ fhci_add_tds_to_ed(ed, urb_priv->tds, urb_priv->num_of_tds);
+ fhci->active_urbs++;
+}
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c
new file mode 100644
index 000000000000..b40332290319
--- /dev/null
+++ b/drivers/usb/host/fhci-tds.c
@@ -0,0 +1,626 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include "../core/hcd.h"
+#include "fhci.h"
+
+#define DUMMY_BD_BUFFER 0xdeadbeef
+#define DUMMY2_BD_BUFFER 0xbaadf00d
+
+/* Transaction Descriptors bits */
+#define TD_R 0x8000 /* ready bit */
+#define TD_W 0x2000 /* wrap bit */
+#define TD_I 0x1000 /* interrupt on completion */
+#define TD_L 0x0800 /* last */
+#define TD_TC 0x0400 /* transmit CRC */
+#define TD_CNF 0x0200 /* CNF - Must be always 1 */
+#define TD_LSP 0x0100 /* Low-speed transaction */
+#define TD_PID 0x00c0 /* packet id */
+#define TD_RXER 0x0020 /* Rx error or not */
+
+#define TD_NAK 0x0010 /* No ack. */
+#define TD_STAL 0x0008 /* Stall recieved */
+#define TD_TO 0x0004 /* time out */
+#define TD_UN 0x0002 /* underrun */
+#define TD_NO 0x0010 /* Rx Non Octet Aligned Packet */
+#define TD_AB 0x0008 /* Frame Aborted */
+#define TD_CR 0x0004 /* CRC Error */
+#define TD_OV 0x0002 /* Overrun */
+#define TD_BOV 0x0001 /* Buffer Overrun */
+
+#define TD_ERRORS (TD_NAK | TD_STAL | TD_TO | TD_UN | \
+ TD_NO | TD_AB | TD_CR | TD_OV | TD_BOV)
+
+#define TD_PID_DATA0 0x0080 /* Data 0 toggle */
+#define TD_PID_DATA1 0x00c0 /* Data 1 toggle */
+#define TD_PID_TOGGLE 0x00c0 /* Data 0/1 toggle mask */
+
+#define TD_TOK_SETUP 0x0000
+#define TD_TOK_OUT 0x4000
+#define TD_TOK_IN 0x8000
+#define TD_ISO 0x1000
+#define TD_ENDP 0x0780
+#define TD_ADDR 0x007f
+
+#define TD_ENDP_SHIFT 7
+
+struct usb_td {
+ __be16 status;
+ __be16 length;
+ __be32 buf_ptr;
+ __be16 extra;
+ __be16 reserved;
+};
+
+static struct usb_td __iomem *next_bd(struct usb_td __iomem *base,
+ struct usb_td __iomem *td,
+ u16 status)
+{
+ if (status & TD_W)
+ return base;
+ else
+ return ++td;
+}
+
+void fhci_push_dummy_bd(struct endpoint *ep)
+{
+ if (ep->already_pushed_dummy_bd == false) {
+ u16 td_status = in_be16(&ep->empty_td->status);
+
+ out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER);
+ /* get the next TD in the ring */
+ ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
+ ep->already_pushed_dummy_bd = true;
+ }
+}
+
+/* destroy an USB endpoint */
+void fhci_ep0_free(struct fhci_usb *usb)
+{
+ struct endpoint *ep;
+ int size;
+
+ ep = usb->ep0;
+ if (ep) {
+ if (ep->td_base)
+ cpm_muram_free(cpm_muram_offset(ep->td_base));
+
+ if (ep->conf_frame_Q) {
+ size = cq_howmany(ep->conf_frame_Q);
+ for (; size; size--) {
+ struct packet *pkt = cq_get(ep->conf_frame_Q);
+
+ kfree(pkt);
+ }
+ cq_delete(ep->conf_frame_Q);
+ }
+
+ if (ep->empty_frame_Q) {
+ size = cq_howmany(ep->empty_frame_Q);
+ for (; size; size--) {
+ struct packet *pkt = cq_get(ep->empty_frame_Q);
+
+ kfree(pkt);
+ }
+ cq_delete(ep->empty_frame_Q);
+ }
+
+ if (ep->dummy_packets_Q) {
+ size = cq_howmany(ep->dummy_packets_Q);
+ for (; size; size--) {
+ u8 *buff = cq_get(ep->dummy_packets_Q);
+
+ kfree(buff);
+ }
+ cq_delete(ep->dummy_packets_Q);
+ }
+
+ kfree(ep);
+ usb->ep0 = NULL;
+ }
+}
+
+/*
+ * create the endpoint structure
+ *
+ * arguments:
+ * usb A pointer to the data structure of the USB
+ * data_mem The data memory partition(BUS)
+ * ring_len TD ring length
+ */
+u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
+ u32 ring_len)
+{
+ struct endpoint *ep;
+ struct usb_td __iomem *td;
+ unsigned long ep_offset;
+ char *err_for = "enpoint PRAM";
+ int ep_mem_size;
+ u32 i;
+
+ /* we need at least 3 TDs in the ring */
+ if (!(ring_len > 2)) {
+ fhci_err(usb->fhci, "illegal TD ring length parameters\n");
+ return -EINVAL;
+ }
+
+ ep = kzalloc(sizeof(*ep), GFP_KERNEL);
+ if (!ep)
+ return -ENOMEM;
+
+ ep_mem_size = ring_len * sizeof(*td) + sizeof(struct fhci_ep_pram);
+ ep_offset = cpm_muram_alloc(ep_mem_size, 32);
+ if (IS_ERR_VALUE(ep_offset))
+ goto err;
+ ep->td_base = cpm_muram_addr(ep_offset);
+
+ /* zero all queue pointers */
+ ep->conf_frame_Q = cq_new(ring_len + 2);
+ ep->empty_frame_Q = cq_new(ring_len + 2);
+ ep->dummy_packets_Q = cq_new(ring_len + 2);
+ if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) {
+ err_for = "frame_queues";
+ goto err;
+ }
+
+ for (i = 0; i < (ring_len + 1); i++) {
+ struct packet *pkt;
+ u8 *buff;
+
+ pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
+ if (!pkt) {
+ err_for = "frame";
+ goto err;
+ }
+
+ buff = kmalloc(1028 * sizeof(*buff), GFP_KERNEL);
+ if (!buff) {
+ kfree(pkt);
+ err_for = "buffer";
+ goto err;
+ }
+ cq_put(ep->empty_frame_Q, pkt);
+ cq_put(ep->dummy_packets_Q, buff);
+ }
+
+ /* we put the endpoint parameter RAM right behind the TD ring */
+ ep->ep_pram_ptr = (void __iomem *)ep->td_base + sizeof(*td) * ring_len;
+
+ ep->conf_td = ep->td_base;
+ ep->empty_td = ep->td_base;
+
+ ep->already_pushed_dummy_bd = false;
+
+ /* initialize tds */
+ td = ep->td_base;
+ for (i = 0; i < ring_len; i++) {
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->status, 0);
+ out_be16(&td->length, 0);
+ out_be16(&td->extra, 0);
+ td++;
+ }
+ td--;
+ out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
+ out_be16(&td->length, 0);
+
+ /* endpoint structure has been created */
+ usb->ep0 = ep;
+
+ return 0;
+err:
+ fhci_ep0_free(usb);
+ kfree(ep);
+ fhci_err(usb->fhci, "no memory for the %s\n", err_for);
+ return -ENOMEM;
+}
+
+/*
+ * initialize the endpoint register according to the given parameters
+ *
+ * artuments:
+ * usb A pointer to the data strucutre of the USB
+ * ep A pointer to the endpoint structre
+ * data_mem The data memory partition(BUS)
+ */
+void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep,
+ enum fhci_mem_alloc data_mem)
+{
+ u8 rt;
+
+ /* set the endpoint registers according to the endpoint */
+ out_be16(&usb->fhci->regs->usb_ep[0],
+ USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE);
+ out_be16(&usb->fhci->pram->ep_ptr[0],
+ cpm_muram_offset(ep->ep_pram_ptr));
+
+ rt = (BUS_MODE_BO_BE | BUS_MODE_GBL);
+#ifdef MULTI_DATA_BUS
+ if (data_mem == MEM_SECONDARY)
+ rt |= BUS_MODE_DTB;
+#endif
+ out_8(&ep->ep_pram_ptr->rx_func_code, rt);
+ out_8(&ep->ep_pram_ptr->tx_func_code, rt);
+ out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028);
+ out_be16(&ep->ep_pram_ptr->rx_base, 0);
+ out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base));
+ out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0);
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base));
+ out_be32(&ep->ep_pram_ptr->tx_state, 0);
+}
+
+/*
+ * Collect the submitted frames and inform the application about them
+ * It is also prepearing the TDs for new frames. If the Tx interrupts
+ * are diabled, the application should call that routine to get
+ * confirmation about the submitted frames. Otherwise, the routine is
+ * called frome the interrupt service routine during the Tx interrupt.
+ * In that case the application is informed by calling the application
+ * specific 'fhci_transaction_confirm' routine
+ */
+static void fhci_td_transaction_confirm(struct fhci_usb *usb)
+{
+ struct endpoint *ep = usb->ep0;
+ struct packet *pkt;
+ struct usb_td __iomem *td;
+ u16 extra_data;
+ u16 td_status;
+ u16 td_length;
+ u32 buf;
+
+ /*
+ * collect transmitted BDs from the chip. The routine clears all BDs
+ * with R bit = 0 and the pointer to data buffer is not NULL, that is
+ * BDs which point to the transmitted data buffer
+ */
+ while (1) {
+ td = ep->conf_td;
+ td_status = in_be16(&td->status);
+ td_length = in_be16(&td->length);
+ buf = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+
+ /* check if the TD is empty */
+ if (!(!(td_status & TD_R) && ((td_status & ~TD_W) || buf)))
+ break;
+ /* check if it is a dummy buffer */
+ else if ((buf == DUMMY_BD_BUFFER) && !(td_status & ~TD_W))
+ break;
+
+ /* mark TD as empty */
+ clrbits16(&td->status, ~TD_W);
+ out_be16(&td->length, 0);
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->extra, 0);
+ /* advance the TD pointer */
+ ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status);
+
+ /* check if it is a dummy buffer(type2) */
+ if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
+ continue;
+
+ pkt = cq_get(ep->conf_frame_Q);
+ if (!pkt)
+ fhci_err(usb->fhci, "no frame to confirm\n");
+
+ if (td_status & TD_ERRORS) {
+ if (td_status & TD_RXER) {
+ if (td_status & TD_CR)
+ pkt->status = USB_TD_RX_ER_CRC;
+ else if (td_status & TD_AB)
+ pkt->status = USB_TD_RX_ER_BITSTUFF;
+ else if (td_status & TD_OV)
+ pkt->status = USB_TD_RX_ER_OVERUN;
+ else if (td_status & TD_BOV)
+ pkt->status = USB_TD_RX_DATA_OVERUN;
+ else if (td_status & TD_NO)
+ pkt->status = USB_TD_RX_ER_NONOCT;
+ else
+ fhci_err(usb->fhci, "illegal error "
+ "occured\n");
+ } else if (td_status & TD_NAK)
+ pkt->status = USB_TD_TX_ER_NAK;
+ else if (td_status & TD_TO)
+ pkt->status = USB_TD_TX_ER_TIMEOUT;
+ else if (td_status & TD_UN)
+ pkt->status = USB_TD_TX_ER_UNDERUN;
+ else if (td_status & TD_STAL)
+ pkt->status = USB_TD_TX_ER_STALL;
+ else
+ fhci_err(usb->fhci, "illegal error occured\n");
+ } else if ((extra_data & TD_TOK_IN) &&
+ pkt->len > td_length - CRC_SIZE) {
+ pkt->status = USB_TD_RX_DATA_UNDERUN;
+ }
+
+ if (extra_data & TD_TOK_IN)
+ pkt->len = td_length - CRC_SIZE;
+ else if (pkt->info & PKT_ZLP)
+ pkt->len = 0;
+ else
+ pkt->len = td_length;
+
+ fhci_transaction_confirm(usb, pkt);
+ }
+}
+
+/*
+ * Submitting a data frame to a specified endpoint of a USB device
+ * The frame is put in the driver's transmit queue for this endpoint
+ *
+ * Arguments:
+ * usb A pointer to the USB structure
+ * pkt A pointer to the user frame structure
+ * trans_type Transaction tyep - IN,OUT or SETUP
+ * dest_addr Device address - 0~127
+ * dest_ep Endpoint number of the device - 0~16
+ * trans_mode Pipe type - ISO,Interrupt,bulk or control
+ * dest_speed USB speed - Low speed or FULL speed
+ * data_toggle Data sequence toggle - 0 or 1
+ */
+u32 fhci_host_transaction(struct fhci_usb *usb,
+ struct packet *pkt,
+ enum fhci_ta_type trans_type,
+ u8 dest_addr,
+ u8 dest_ep,
+ enum fhci_tf_mode trans_mode,
+ enum fhci_speed dest_speed, u8 data_toggle)
+{
+ struct endpoint *ep = usb->ep0;
+ struct usb_td __iomem *td;
+ u16 extra_data;
+ u16 td_status;
+
+ fhci_usb_disable_interrupt(usb);
+ /* start from the next BD that should be filled */
+ td = ep->empty_td;
+ td_status = in_be16(&td->status);
+
+ if (td_status & TD_R && in_be16(&td->length)) {
+ /* if the TD is not free */
+ fhci_usb_enable_interrupt(usb);
+ return -1;
+ }
+
+ /* get the next TD in the ring */
+ ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
+ fhci_usb_enable_interrupt(usb);
+ pkt->priv_data = td;
+ out_be32(&td->buf_ptr, virt_to_phys(pkt->data));
+ /* sets up transaction parameters - addr,endp,dir,and type */
+ extra_data = (dest_ep << TD_ENDP_SHIFT) | dest_addr;
+ switch (trans_type) {
+ case FHCI_TA_IN:
+ extra_data |= TD_TOK_IN;
+ break;
+ case FHCI_TA_OUT:
+ extra_data |= TD_TOK_OUT;
+ break;
+ case FHCI_TA_SETUP:
+ extra_data |= TD_TOK_SETUP;
+ break;
+ }
+ if (trans_mode == FHCI_TF_ISO)
+ extra_data |= TD_ISO;
+ out_be16(&td->extra, extra_data);
+
+ /* sets up the buffer descriptor */
+ td_status = ((td_status & TD_W) | TD_R | TD_L | TD_I | TD_CNF);
+ if (!(pkt->info & PKT_NO_CRC))
+ td_status |= TD_TC;
+
+ switch (trans_type) {
+ case FHCI_TA_IN:
+ if (data_toggle)
+ pkt->info |= PKT_PID_DATA1;
+ else
+ pkt->info |= PKT_PID_DATA0;
+ break;
+ default:
+ if (data_toggle) {
+ td_status |= TD_PID_DATA1;
+ pkt->info |= PKT_PID_DATA1;
+ } else {
+ td_status |= TD_PID_DATA0;
+ pkt->info |= PKT_PID_DATA0;
+ }
+ break;
+ }
+
+ if ((dest_speed == FHCI_LOW_SPEED) &&
+ (usb->port_status == FHCI_PORT_FULL))
+ td_status |= TD_LSP;
+
+ out_be16(&td->status, td_status);
+
+ /* set up buffer length */
+ if (trans_type == FHCI_TA_IN)
+ out_be16(&td->length, pkt->len + CRC_SIZE);
+ else
+ out_be16(&td->length, pkt->len);
+
+ /* put the frame to the confirmation queue */
+ cq_put(ep->conf_frame_Q, pkt);
+
+ if (cq_howmany(ep->conf_frame_Q) == 1)
+ out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
+
+ return 0;
+}
+
+/* Reset the Tx BD ring */
+void fhci_flush_bds(struct fhci_usb *usb)
+{
+ u16 extra_data;
+ u16 td_status;
+ u32 buf;
+ struct usb_td __iomem *td;
+ struct endpoint *ep = usb->ep0;
+
+ td = ep->td_base;
+ while (1) {
+ td_status = in_be16(&td->status);
+ buf = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+
+ /* if the TD is not empty - we'll confirm it as Timeout */
+ if (td_status & TD_R)
+ out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
+ /* if this TD is dummy - let's skip this TD */
+ else if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER)
+ out_be32(&td->buf_ptr, DUMMY2_BD_BUFFER);
+ /* if this is the last TD - break */
+ if (td_status & TD_W)
+ break;
+
+ td++;
+ }
+
+ fhci_td_transaction_confirm(usb);
+
+ td = ep->td_base;
+ do {
+ out_be16(&td->status, 0);
+ out_be16(&td->length, 0);
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->extra, 0);
+ td++;
+ } while (!(in_be16(&td->status) & TD_W));
+ out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
+ out_be16(&td->length, 0);
+ out_be32(&td->buf_ptr, 0);
+ out_be16(&td->extra, 0);
+
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
+ in_be16(&ep->ep_pram_ptr->tx_base));
+ out_be32(&ep->ep_pram_ptr->tx_state, 0);
+ out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
+ ep->empty_td = ep->td_base;
+ ep->conf_td = ep->td_base;
+}
+
+/*
+ * Flush all transmitted packets from TDs in the actual frame.
+ * This routine is called when something wrong with the controller and
+ * we want to get rid of the actual frame and start again next frame
+ */
+void fhci_flush_actual_frame(struct fhci_usb *usb)
+{
+ u8 mode;
+ u16 tb_ptr;
+ u16 extra_data;
+ u16 td_status;
+ u32 buf_ptr;
+ struct usb_td __iomem *td;
+ struct endpoint *ep = usb->ep0;
+
+ /* disable the USB controller */
+ mode = in_8(&usb->fhci->regs->usb_mod);
+ out_8(&usb->fhci->regs->usb_mod, mode & ~USB_MODE_EN);
+
+ tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
+ td = cpm_muram_addr(tb_ptr);
+ td_status = in_be16(&td->status);
+ buf_ptr = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+ do {
+ if (td_status & TD_R) {
+ out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
+ } else {
+ out_be32(&td->buf_ptr, 0);
+ ep->already_pushed_dummy_bd = false;
+ break;
+ }
+
+ /* advance the TD pointer */
+ td = next_bd(ep->td_base, td, td_status);
+ td_status = in_be16(&td->status);
+ buf_ptr = in_be32(&td->buf_ptr);
+ extra_data = in_be16(&td->extra);
+ } while ((td_status & TD_R) || buf_ptr);
+
+ fhci_td_transaction_confirm(usb);
+
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
+ in_be16(&ep->ep_pram_ptr->tx_base));
+ out_be32(&ep->ep_pram_ptr->tx_state, 0);
+ out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
+ ep->empty_td = ep->td_base;
+ ep->conf_td = ep->td_base;
+
+ usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
+
+ /* reset the event register */
+ out_be16(&usb->fhci->regs->usb_event, 0xffff);
+ /* enable the USB controller */
+ out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN);
+}
+
+/* handles Tx confirm and Tx error interrupt */
+void fhci_tx_conf_interrupt(struct fhci_usb *usb)
+{
+ fhci_td_transaction_confirm(usb);
+
+ /*
+ * Schedule another transaction to this frame only if we have
+ * already confirmed all transaction in the frame.
+ */
+ if (((fhci_get_sof_timer_count(usb) < usb->max_frame_usage) ||
+ (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)) &&
+ (list_empty(&usb->actual_frame->tds_list)))
+ fhci_schedule_transactions(usb);
+}
+
+void fhci_host_transmit_actual_frame(struct fhci_usb *usb)
+{
+ u16 tb_ptr;
+ u16 td_status;
+ struct usb_td __iomem *td;
+ struct endpoint *ep = usb->ep0;
+
+ tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
+ td = cpm_muram_addr(tb_ptr);
+
+ if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) {
+ struct usb_td __iomem *old_td = td;
+
+ ep->already_pushed_dummy_bd = false;
+ td_status = in_be16(&td->status);
+ /* gets the next TD in the ring */
+ td = next_bd(ep->td_base, td, td_status);
+ tb_ptr = cpm_muram_offset(td);
+ out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr);
+
+ /* start transmit only if we have something in the TDs */
+ if (in_be16(&td->status) & TD_R)
+ out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
+
+ if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) {
+ out_be32(&old_td->buf_ptr, 0);
+ ep->conf_td = next_bd(ep->td_base, ep->conf_td,
+ td_status);
+ } else {
+ out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER);
+ }
+ }
+}
diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h
new file mode 100644
index 000000000000..7116284ed21a
--- /dev/null
+++ b/drivers/usb/host/fhci.h
@@ -0,0 +1,607 @@
+/*
+ * Freescale QUICC Engine USB Host Controller Driver
+ *
+ * Copyright (c) Freescale Semicondutor, Inc. 2006.
+ * Shlomi Gridish <gridish@freescale.com>
+ * Jerry Huang <Chang-Ming.Huang@freescale.com>
+ * Copyright (c) Logic Product Development, Inc. 2007
+ * Peter Barada <peterb@logicpd.com>
+ * Copyright (c) MontaVista Software, Inc. 2008.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __FHCI_H
+#define __FHCI_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/io.h>
+#include <linux/usb.h>
+#include <asm/qe.h>
+#include "../core/hcd.h"
+
+#define USB_CLOCK 48000000
+
+#define FHCI_PRAM_SIZE 0x100
+
+#define MAX_EDS 32
+#define MAX_TDS 32
+
+
+/* CRC16 field size */
+#define CRC_SIZE 2
+
+/* USB protocol overhead for each frame transmitted from the host */
+#define PROTOCOL_OVERHEAD 7
+
+/* Packet structure, info field */
+#define PKT_PID_DATA0 0x80000000 /* PID - Data toggle zero */
+#define PKT_PID_DATA1 0x40000000 /* PID - Data toggle one */
+#define PKT_PID_SETUP 0x20000000 /* PID - Setup bit */
+#define PKT_SETUP_STATUS 0x10000000 /* Setup status bit */
+#define PKT_SETADDR_STATUS 0x08000000 /* Set address status bit */
+#define PKT_SET_HOST_LAST 0x04000000 /* Last data packet */
+#define PKT_HOST_DATA 0x02000000 /* Data packet */
+#define PKT_FIRST_IN_FRAME 0x01000000 /* First packet in the frame */
+#define PKT_TOKEN_FRAME 0x00800000 /* Token packet */
+#define PKT_ZLP 0x00400000 /* Zero length packet */
+#define PKT_IN_TOKEN_FRAME 0x00200000 /* IN token packet */
+#define PKT_OUT_TOKEN_FRAME 0x00100000 /* OUT token packet */
+#define PKT_SETUP_TOKEN_FRAME 0x00080000 /* SETUP token packet */
+#define PKT_STALL_FRAME 0x00040000 /* STALL packet */
+#define PKT_NACK_FRAME 0x00020000 /* NACK packet */
+#define PKT_NO_PID 0x00010000 /* No PID */
+#define PKT_NO_CRC 0x00008000 /* don't append CRC */
+#define PKT_HOST_COMMAND 0x00004000 /* Host command packet */
+#define PKT_DUMMY_PACKET 0x00002000 /* Dummy packet, used for mmm */
+#define PKT_LOW_SPEED_PACKET 0x00001000 /* Low-Speed packet */
+
+#define TRANS_OK (0)
+#define TRANS_INPROGRESS (-1)
+#define TRANS_DISCARD (-2)
+#define TRANS_FAIL (-3)
+
+#define PS_INT 0
+#define PS_DISCONNECTED 1
+#define PS_CONNECTED 2
+#define PS_READY 3
+#define PS_MISSING 4
+
+/* Transfer Descriptor status field */
+#define USB_TD_OK 0x00000000 /* TD transmited or received ok */
+#define USB_TD_INPROGRESS 0x80000000 /* TD is being transmitted */
+#define USB_TD_RX_ER_NONOCT 0x40000000 /* Tx Non Octet Aligned Packet */
+#define USB_TD_RX_ER_BITSTUFF 0x20000000 /* Frame Aborted-Received pkt */
+#define USB_TD_RX_ER_CRC 0x10000000 /* CRC error */
+#define USB_TD_RX_ER_OVERUN 0x08000000 /* Over - run occured */
+#define USB_TD_RX_ER_PID 0x04000000 /* wrong PID received */
+#define USB_TD_RX_DATA_UNDERUN 0x02000000 /* shorter than expected */
+#define USB_TD_RX_DATA_OVERUN 0x01000000 /* longer than expected */
+#define USB_TD_TX_ER_NAK 0x00800000 /* NAK handshake */
+#define USB_TD_TX_ER_STALL 0x00400000 /* STALL handshake */
+#define USB_TD_TX_ER_TIMEOUT 0x00200000 /* transmit time out */
+#define USB_TD_TX_ER_UNDERUN 0x00100000 /* transmit underrun */
+
+#define USB_TD_ERROR (USB_TD_RX_ER_NONOCT | USB_TD_RX_ER_BITSTUFF | \
+ USB_TD_RX_ER_CRC | USB_TD_RX_ER_OVERUN | USB_TD_RX_ER_PID | \
+ USB_TD_RX_DATA_UNDERUN | USB_TD_RX_DATA_OVERUN | \
+ USB_TD_TX_ER_NAK | USB_TD_TX_ER_STALL | \
+ USB_TD_TX_ER_TIMEOUT | USB_TD_TX_ER_UNDERUN)
+
+/* Transfer Descriptor toggle field */
+#define USB_TD_TOGGLE_DATA0 0
+#define USB_TD_TOGGLE_DATA1 1
+#define USB_TD_TOGGLE_CARRY 2
+
+/* #define MULTI_DATA_BUS */
+
+/* Bus mode register RBMR/TBMR */
+#define BUS_MODE_GBL 0x20 /* Global snooping */
+#define BUS_MODE_BO 0x18 /* Byte ordering */
+#define BUS_MODE_BO_BE 0x10 /* Byte ordering - Big-endian */
+#define BUS_MODE_DTB 0x02 /* Data bus */
+
+/* FHCI QE USB Register Description */
+
+/* USB Mode Register bit define */
+#define USB_MODE_EN 0x01
+#define USB_MODE_HOST 0x02
+#define USB_MODE_TEST 0x04
+#define USB_MODE_SFTE 0x08
+#define USB_MODE_RESUME 0x40
+#define USB_MODE_LSS 0x80
+
+/* USB Slave Address Register Mask */
+#define USB_SLVADDR_MASK 0x7F
+
+/* USB Endpoint register define */
+#define USB_EPNUM_MASK 0xF000
+#define USB_EPNUM_SHIFT 12
+
+#define USB_TRANS_MODE_SHIFT 8
+#define USB_TRANS_CTR 0x0000
+#define USB_TRANS_INT 0x0100
+#define USB_TRANS_BULK 0x0200
+#define USB_TRANS_ISO 0x0300
+
+#define USB_EP_MF 0x0020
+#define USB_EP_RTE 0x0010
+
+#define USB_THS_SHIFT 2
+#define USB_THS_MASK 0x000c
+#define USB_THS_NORMAL 0x0
+#define USB_THS_IGNORE_IN 0x0004
+#define USB_THS_NACK 0x0008
+#define USB_THS_STALL 0x000c
+
+#define USB_RHS_SHIFT 0
+#define USB_RHS_MASK 0x0003
+#define USB_RHS_NORMAL 0x0
+#define USB_RHS_IGNORE_OUT 0x0001
+#define USB_RHS_NACK 0x0002
+#define USB_RHS_STALL 0x0003
+
+#define USB_RTHS_MASK 0x000f
+
+/* USB Command Register define */
+#define USB_CMD_STR_FIFO 0x80
+#define USB_CMD_FLUSH_FIFO 0x40
+#define USB_CMD_ISFT 0x20
+#define USB_CMD_DSFT 0x10
+#define USB_CMD_EP_MASK 0x03
+
+/* USB Event and Mask Register define */
+#define USB_E_MSF_MASK 0x0800
+#define USB_E_SFT_MASK 0x0400
+#define USB_E_RESET_MASK 0x0200
+#define USB_E_IDLE_MASK 0x0100
+#define USB_E_TXE4_MASK 0x0080
+#define USB_E_TXE3_MASK 0x0040
+#define USB_E_TXE2_MASK 0x0020
+#define USB_E_TXE1_MASK 0x0010
+#define USB_E_SOF_MASK 0x0008
+#define USB_E_BSY_MASK 0x0004
+#define USB_E_TXB_MASK 0x0002
+#define USB_E_RXB_MASK 0x0001
+
+/* Freescale USB Host controller registers */
+struct fhci_regs {
+ u8 usb_mod; /* mode register */
+ u8 usb_addr; /* address register */
+ u8 usb_comm; /* command register */
+ u8 reserved1[1];
+ __be16 usb_ep[4]; /* endpoint register */
+ u8 reserved2[4];
+ __be16 usb_event; /* event register */
+ u8 reserved3[2];
+ __be16 usb_mask; /* mask register */
+ u8 reserved4[1];
+ u8 usb_status; /* status register */
+ __be16 usb_sof_tmr; /* Start Of Frame timer */
+ u8 reserved5[2];
+ __be16 usb_frame_num; /* frame number register */
+ u8 reserved6[1];
+};
+
+/* Freescale USB HOST */
+struct fhci_pram {
+ __be16 ep_ptr[4]; /* Endpoint porter reg */
+ __be32 rx_state; /* Rx internal state */
+ __be32 rx_ptr; /* Rx internal data pointer */
+ __be16 frame_num; /* Frame number */
+ __be16 rx_cnt; /* Rx byte count */
+ __be32 rx_temp; /* Rx temp */
+ __be32 rx_data_temp; /* Rx data temp */
+ __be16 rx_u_ptr; /* Rx microcode return address temp */
+ u8 reserved1[2]; /* reserved area */
+ __be32 sof_tbl; /* SOF lookup table pointer */
+ u8 sof_u_crc_temp; /* SOF micorcode CRC5 temp reg */
+ u8 reserved2[0xdb];
+};
+
+/* Freescale USB Endpoint*/
+struct fhci_ep_pram {
+ __be16 rx_base; /* Rx BD base address */
+ __be16 tx_base; /* Tx BD base address */
+ u8 rx_func_code; /* Rx function code */
+ u8 tx_func_code; /* Tx function code */
+ __be16 rx_buff_len; /* Rx buffer length */
+ __be16 rx_bd_ptr; /* Rx BD pointer */
+ __be16 tx_bd_ptr; /* Tx BD pointer */
+ __be32 tx_state; /* Tx internal state */
+ __be32 tx_ptr; /* Tx internal data pointer */
+ __be16 tx_crc; /* temp transmit CRC */
+ __be16 tx_cnt; /* Tx byte count */
+ __be32 tx_temp; /* Tx temp */
+ __be16 tx_u_ptr; /* Tx microcode return address temp */
+ __be16 reserved;
+};
+
+struct fhci_controller_list {
+ struct list_head ctrl_list; /* control endpoints */
+ struct list_head bulk_list; /* bulk endpoints */
+ struct list_head iso_list; /* isochronous endpoints */
+ struct list_head intr_list; /* interruput endpoints */
+ struct list_head done_list; /* done transfers */
+};
+
+struct virtual_root_hub {
+ int dev_num; /* USB address of the root hub */
+ u32 feature; /* indicates what feature has been set */
+ struct usb_hub_status hub;
+ struct usb_port_status port;
+};
+
+enum fhci_gpios {
+ GPIO_USBOE = 0,
+ GPIO_USBTP,
+ GPIO_USBTN,
+ GPIO_USBRP,
+ GPIO_USBRN,
+ /* these are optional */
+ GPIO_SPEED,
+ GPIO_POWER,
+ NUM_GPIOS,
+};
+
+enum fhci_pins {
+ PIN_USBOE = 0,
+ PIN_USBTP,
+ PIN_USBTN,
+ NUM_PINS,
+};
+
+struct fhci_hcd {
+ enum qe_clock fullspeed_clk;
+ enum qe_clock lowspeed_clk;
+ struct qe_pin *pins[NUM_PINS];
+ int gpios[NUM_GPIOS];
+ bool alow_gpios[NUM_GPIOS];
+
+ struct fhci_regs __iomem *regs; /* I/O memory used to communicate */
+ struct fhci_pram __iomem *pram; /* Parameter RAM */
+ struct gtm_timer *timer;
+
+ spinlock_t lock;
+ struct fhci_usb *usb_lld; /* Low-level driver */
+ struct virtual_root_hub *vroot_hub; /* the virtual root hub */
+ int active_urbs;
+ struct fhci_controller_list *hc_list;
+ struct tasklet_struct *process_done_task; /* tasklet for done list */
+
+ struct list_head empty_eds;
+ struct list_head empty_tds;
+
+#ifdef CONFIG_FHCI_DEBUG
+ int usb_irq_stat[13];
+ struct dentry *dfs_root;
+ struct dentry *dfs_regs;
+ struct dentry *dfs_irq_stat;
+#endif
+};
+
+#define USB_FRAME_USAGE 90
+#define FRAME_TIME_USAGE (USB_FRAME_USAGE*10) /* frame time usage */
+#define SW_FIX_TIME_BETWEEN_TRANSACTION 150 /* SW */
+#define MAX_BYTES_PER_FRAME (USB_FRAME_USAGE*15)
+#define MAX_PERIODIC_FRAME_USAGE 90
+
+/* transaction type */
+enum fhci_ta_type {
+ FHCI_TA_IN = 0, /* input transaction */
+ FHCI_TA_OUT, /* output transaction */
+ FHCI_TA_SETUP, /* setup transaction */
+};
+
+/* transfer mode */
+enum fhci_tf_mode {
+ FHCI_TF_CTRL = 0,
+ FHCI_TF_ISO,
+ FHCI_TF_BULK,
+ FHCI_TF_INTR,
+};
+
+enum fhci_speed {
+ FHCI_FULL_SPEED,
+ FHCI_LOW_SPEED,
+};
+
+/* endpoint state */
+enum fhci_ed_state {
+ FHCI_ED_NEW = 0, /* pipe is new */
+ FHCI_ED_OPER, /* pipe is operating */
+ FHCI_ED_URB_DEL, /* pipe is in hold because urb is being deleted */
+ FHCI_ED_SKIP, /* skip this pipe */
+ FHCI_ED_HALTED, /* pipe is halted */
+};
+
+enum fhci_port_status {
+ FHCI_PORT_POWER_OFF = 0,
+ FHCI_PORT_DISABLED,
+ FHCI_PORT_DISCONNECTING,
+ FHCI_PORT_WAITING, /* waiting for connection */
+ FHCI_PORT_FULL, /* full speed connected */
+ FHCI_PORT_LOW, /* low speed connected */
+};
+
+enum fhci_mem_alloc {
+ MEM_CACHABLE_SYS = 0x00000001, /* primary DDR,cachable */
+ MEM_NOCACHE_SYS = 0x00000004, /* primary DDR,non-cachable */
+ MEM_SECONDARY = 0x00000002, /* either secondary DDR or SDRAM */
+ MEM_PRAM = 0x00000008, /* multi-user RAM identifier */
+};
+
+/* USB default parameters*/
+#define DEFAULT_RING_LEN 8
+#define DEFAULT_DATA_MEM MEM_CACHABLE_SYS
+
+struct ed {
+ u8 dev_addr; /* device address */
+ u8 ep_addr; /* endpoint address */
+ enum fhci_tf_mode mode; /* USB transfer mode */
+ enum fhci_speed speed;
+ unsigned int max_pkt_size;
+ enum fhci_ed_state state;
+ struct list_head td_list; /* a list of all queued TD to this pipe */
+ struct list_head node;
+
+ /* read only parameters, should be cleared upon initialization */
+ u8 toggle_carry; /* toggle carry from the last TD submitted */
+ u32 last_iso; /* time stamp of last queued ISO transfer */
+ struct td *td_head; /* a pointer to the current TD handled */
+};
+
+struct td {
+ void *data; /* a pointer to the data buffer */
+ unsigned int len; /* length of the data to be submitted */
+ unsigned int actual_len; /* actual bytes transfered on this td */
+ enum fhci_ta_type type; /* transaction type */
+ u8 toggle; /* toggle for next trans. within this TD */
+ u16 iso_index; /* ISO transaction index */
+ u16 start_frame; /* start frame time stamp */
+ u16 interval; /* interval between trans. (for ISO/Intr) */
+ u32 status; /* status of the TD */
+ struct ed *ed; /* a handle to the corresponding ED */
+ struct urb *urb; /* a handle to the corresponding URB */
+ bool ioc; /* Inform On Completion */
+ struct list_head node;
+
+ /* read only parameters should be cleared upon initialization */
+ struct packet *pkt;
+ int nak_cnt;
+ int error_cnt;
+ struct list_head frame_lh;
+};
+
+struct packet {
+ u8 *data; /* packet data */
+ u32 len; /* packet length */
+ u32 status; /* status of the packet - equivalent to the status
+ * field for the corresponding structure td */
+ u32 info; /* packet information */
+ void __iomem *priv_data; /* private data of the driver (TDs or BDs) */
+};
+
+/* struct for each URB */
+#define URB_INPROGRESS 0
+#define URB_DEL 1
+
+/* URB states (state field) */
+#define US_BULK 0
+#define US_BULK0 1
+
+/* three setup states */
+#define US_CTRL_SETUP 2
+#define US_CTRL_DATA 1
+#define US_CTRL_ACK 0
+
+#define EP_ZERO 0
+
+struct urb_priv {
+ int num_of_tds;
+ int tds_cnt;
+ int state;
+
+ struct td **tds;
+ struct ed *ed;
+ struct timer_list time_out;
+};
+
+struct endpoint {
+ /* Pointer to ep parameter RAM */
+ struct fhci_ep_pram __iomem *ep_pram_ptr;
+
+ /* Host transactions */
+ struct usb_td __iomem *td_base; /* first TD in the ring */
+ struct usb_td __iomem *conf_td; /* next TD for confirm after transac */
+ struct usb_td __iomem *empty_td;/* next TD for new transaction req. */
+ struct kfifo *empty_frame_Q; /* Empty frames list to use */
+ struct kfifo *conf_frame_Q; /* frames passed to TDs,waiting for tx */
+ struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */
+
+ bool already_pushed_dummy_bd;
+};
+
+/* struct for each 1mSec frame time */
+#define FRAME_IS_TRANSMITTED 0x00
+#define FRAME_TIMER_END_TRANSMISSION 0x01
+#define FRAME_DATA_END_TRANSMISSION 0x02
+#define FRAME_END_TRANSMISSION 0x03
+#define FRAME_IS_PREPARED 0x04
+
+struct fhci_time_frame {
+ u16 frame_num; /* frame number */
+ u16 total_bytes; /* total bytes submitted within this frame */
+ u8 frame_status; /* flag that indicates to stop fill this frame */
+ struct list_head tds_list; /* all tds of this frame */
+};
+
+/* internal driver structure*/
+struct fhci_usb {
+ u16 saved_msk; /* saving of the USB mask register */
+ struct endpoint *ep0; /* pointer for endpoint0 structure */
+ int intr_nesting_cnt; /* interrupt nesting counter */
+ u16 max_frame_usage; /* max frame time usage,in micro-sec */
+ u16 max_bytes_per_frame; /* max byte can be tx in one time frame */
+ u32 sw_transaction_time; /* sw complete trans time,in micro-sec */
+ struct fhci_time_frame *actual_frame;
+ struct fhci_controller_list *hc_list; /* main structure for hc */
+ struct virtual_root_hub *vroot_hub;
+ enum fhci_port_status port_status; /* v_rh port status */
+
+ u32 (*transfer_confirm)(struct fhci_hcd *fhci);
+
+ struct fhci_hcd *fhci;
+};
+
+/*
+ * Various helpers and prototypes below.
+ */
+
+static inline u16 get_frame_num(struct fhci_hcd *fhci)
+{
+ return in_be16(&fhci->pram->frame_num) & 0x07ff;
+}
+
+#define fhci_dbg(fhci, fmt, args...) \
+ dev_dbg(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_vdbg(fhci, fmt, args...) \
+ dev_vdbg(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_err(fhci, fmt, args...) \
+ dev_err(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_info(fhci, fmt, args...) \
+ dev_info(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+#define fhci_warn(fhci, fmt, args...) \
+ dev_warn(fhci_to_hcd(fhci)->self.controller, fmt, ##args)
+
+static inline struct fhci_hcd *hcd_to_fhci(struct usb_hcd *hcd)
+{
+ return (struct fhci_hcd *)hcd->hcd_priv;
+}
+
+static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci)
+{
+ return container_of((void *)fhci, struct usb_hcd, hcd_priv);
+}
+
+/* fifo of pointers */
+static inline struct kfifo *cq_new(int size)
+{
+ return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL);
+}
+
+static inline void cq_delete(struct kfifo *kfifo)
+{
+ kfifo_free(kfifo);
+}
+
+static inline unsigned int cq_howmany(struct kfifo *kfifo)
+{
+ return __kfifo_len(kfifo) / sizeof(void *);
+}
+
+static inline int cq_put(struct kfifo *kfifo, void *p)
+{
+ return __kfifo_put(kfifo, (void *)&p, sizeof(p));
+}
+
+static inline void *cq_get(struct kfifo *kfifo)
+{
+ void *p = NULL;
+
+ __kfifo_get(kfifo, (void *)&p, sizeof(p));
+ return p;
+}
+
+/* fhci-hcd.c */
+void fhci_start_sof_timer(struct fhci_hcd *fhci);
+void fhci_stop_sof_timer(struct fhci_hcd *fhci);
+u16 fhci_get_sof_timer_count(struct fhci_usb *usb);
+void fhci_usb_enable_interrupt(struct fhci_usb *usb);
+void fhci_usb_disable_interrupt(struct fhci_usb *usb);
+int fhci_ioports_check_bus_state(struct fhci_hcd *fhci);
+
+/* fhci-mem.c */
+void fhci_recycle_empty_td(struct fhci_hcd *fhci, struct td *td);
+void fhci_recycle_empty_ed(struct fhci_hcd *fhci, struct ed *ed);
+struct ed *fhci_get_empty_ed(struct fhci_hcd *fhci);
+struct td *fhci_td_fill(struct fhci_hcd *fhci, struct urb *urb,
+ struct urb_priv *urb_priv, struct ed *ed, u16 index,
+ enum fhci_ta_type type, int toggle, u8 *data, u32 len,
+ u16 interval, u16 start_frame, bool ioc);
+void fhci_add_tds_to_ed(struct ed *ed, struct td **td_list, int number);
+
+/* fhci-hub.c */
+void fhci_config_transceiver(struct fhci_hcd *fhci,
+ enum fhci_port_status status);
+void fhci_port_disable(struct fhci_hcd *fhci);
+void fhci_port_enable(void *lld);
+void fhci_io_port_generate_reset(struct fhci_hcd *fhci);
+void fhci_port_reset(void *lld);
+int fhci_hub_status_data(struct usb_hcd *hcd, char *buf);
+int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buf, u16 wLength);
+
+/* fhci-tds.c */
+void fhci_flush_bds(struct fhci_usb *usb);
+void fhci_flush_actual_frame(struct fhci_usb *usb);
+u32 fhci_host_transaction(struct fhci_usb *usb, struct packet *pkt,
+ enum fhci_ta_type trans_type, u8 dest_addr,
+ u8 dest_ep, enum fhci_tf_mode trans_mode,
+ enum fhci_speed dest_speed, u8 data_toggle);
+void fhci_host_transmit_actual_frame(struct fhci_usb *usb);
+void fhci_tx_conf_interrupt(struct fhci_usb *usb);
+void fhci_push_dummy_bd(struct endpoint *ep);
+u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
+ u32 ring_len);
+void fhci_init_ep_registers(struct fhci_usb *usb,
+ struct endpoint *ep,
+ enum fhci_mem_alloc data_mem);
+void fhci_ep0_free(struct fhci_usb *usb);
+
+/* fhci-sched.c */
+extern struct tasklet_struct fhci_tasklet;
+void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt);
+void fhci_flush_all_transmissions(struct fhci_usb *usb);
+void fhci_schedule_transactions(struct fhci_usb *usb);
+void fhci_device_connected_interrupt(struct fhci_hcd *fhci);
+void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci);
+void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb);
+u32 fhci_transfer_confirm_callback(struct fhci_hcd *fhci);
+irqreturn_t fhci_irq(struct usb_hcd *hcd);
+irqreturn_t fhci_frame_limit_timer_irq(int irq, void *_hcd);
+
+/* fhci-q.h */
+void fhci_urb_complete_free(struct fhci_hcd *fhci, struct urb *urb);
+struct td *fhci_remove_td_from_ed(struct ed *ed);
+struct td *fhci_remove_td_from_frame(struct fhci_time_frame *frame);
+void fhci_move_td_from_ed_to_done_list(struct fhci_usb *usb, struct ed *ed);
+struct td *fhci_peek_td_from_frame(struct fhci_time_frame *frame);
+void fhci_add_td_to_frame(struct fhci_time_frame *frame, struct td *td);
+struct td *fhci_remove_td_from_done_list(struct fhci_controller_list *p_list);
+void fhci_done_td(struct urb *urb, struct td *td);
+void fhci_del_ed_list(struct fhci_hcd *fhci, struct ed *ed);
+
+#ifdef CONFIG_FHCI_DEBUG
+
+void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er);
+void fhci_dfs_destroy(struct fhci_hcd *fhci);
+void fhci_dfs_create(struct fhci_hcd *fhci);
+
+#else
+
+static inline void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er) {}
+static inline void fhci_dfs_destroy(struct fhci_hcd *fhci) {}
+static inline void fhci_dfs_create(struct fhci_hcd *fhci) {}
+
+#endif /* CONFIG_FHCI_DEBUG */
+
+#endif /* __FHCI_H */
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
index aa211bafcff9..12db961acdfb 100644
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -563,7 +563,7 @@ static void urb_dbg(struct urb *urb, char *msg)
*/
static inline void dump_ptd(struct ptd *ptd)
{
- printk("td: %x %d%c%d %d,%d,%d %x %x%x%x\n",
+ printk(KERN_WARNING "td: %x %d%c%d %d,%d,%d %x %x%x%x\n",
PTD_GET_CC(ptd), PTD_GET_FA(ptd),
PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
@@ -576,7 +576,7 @@ static inline void dump_ptd_out_data(struct ptd *ptd, u8 * buf)
int k;
if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) {
- printk("-> ");
+ printk(KERN_WARNING "-> ");
for (k = 0; k < PTD_GET_LEN(ptd); ++k)
printk("%02x ", ((u8 *) buf)[k]);
printk("\n");
@@ -588,13 +588,13 @@ static inline void dump_ptd_in_data(struct ptd *ptd, u8 * buf)
int k;
if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) {
- printk("<- ");
+ printk(KERN_WARNING "<- ");
for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
printk("%02x ", ((u8 *) buf)[k]);
printk("\n");
}
if (PTD_GET_LAST(ptd))
- printk("-\n");
+ printk(KERN_WARNING "-\n");
}
#else
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index b899f1a59c26..3172c0fd2a6d 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -644,7 +644,7 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh,
if (urb->dev->speed != USB_SPEED_HIGH) {
/* split */
- ptd->dw5 = __constant_cpu_to_le32(0x1c);
+ ptd->dw5 = cpu_to_le32(0x1c);
if (qh->period >= 32)
period = qh->period / 2;
@@ -1054,7 +1054,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
atl_regs, sizeof(ptd));
- ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID);
+ ptd.dw0 |= cpu_to_le32(PTD_VALID);
priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs +
atl_regs, sizeof(ptd));
@@ -2235,9 +2235,10 @@ void deinit_kmem_cache(void)
kmem_cache_destroy(qh_cachep);
}
-struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
- u64 irqflags, struct device *dev, const char *busname,
- unsigned int devflags)
+struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
+ int irq, unsigned long irqflags,
+ struct device *dev, const char *busname,
+ unsigned int devflags)
{
struct usb_hcd *hcd;
struct isp1760_hcd *priv;
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
index a9daea587962..462f4943cb1b 100644
--- a/drivers/usb/host/isp1760-hcd.h
+++ b/drivers/usb/host/isp1760-hcd.h
@@ -2,9 +2,10 @@
#define _ISP1760_HCD_H_
/* exports for if */
-struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
- u64 irqflags, struct device *dev, const char *busname,
- unsigned int devflags);
+struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
+ int irq, unsigned long irqflags,
+ struct device *dev, const char *busname,
+ unsigned int devflags);
int init_kmem_once(void);
void deinit_kmem_cache(void);
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 4cf7ca428b33..3fa3a1702796 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -10,6 +10,7 @@
#include <linux/usb.h>
#include <linux/io.h>
+#include <linux/platform_device.h>
#include "../core/hcd.h"
#include "isp1760-hcd.h"
@@ -300,39 +301,101 @@ static struct pci_driver isp1761_pci_driver = {
};
#endif
+static int __devinit isp1760_plat_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct usb_hcd *hcd;
+ struct resource *mem_res;
+ struct resource *irq_res;
+ resource_size_t mem_size;
+ unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_res) {
+ pr_warning("isp1760: Memory resource not available\n");
+ ret = -ENODEV;
+ goto out;
+ }
+ mem_size = resource_size(mem_res);
+ if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
+ pr_warning("isp1760: Cannot reserve the memory resource\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq_res) {
+ pr_warning("isp1760: IRQ resource not available\n");
+ return -ENODEV;
+ }
+ irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
+
+ hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
+ irqflags, &pdev->dev, dev_name(&pdev->dev), 0);
+ if (IS_ERR(hcd)) {
+ pr_warning("isp1760: Failed to register the HCD device\n");
+ ret = -ENODEV;
+ goto cleanup;
+ }
+
+ pr_info("ISP1760 USB device initialised\n");
+ return ret;
+
+cleanup:
+ release_mem_region(mem_res->start, mem_size);
+out:
+ return ret;
+}
+
+static int __devexit isp1760_plat_remove(struct platform_device *pdev)
+{
+ struct resource *mem_res;
+ resource_size_t mem_size;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mem_size = resource_size(mem_res);
+ release_mem_region(mem_res->start, mem_size);
+
+ return 0;
+}
+
+static struct platform_driver isp1760_plat_driver = {
+ .probe = isp1760_plat_probe,
+ .remove = isp1760_plat_remove,
+ .driver = {
+ .name = "isp1760",
+ },
+};
+
static int __init isp1760_init(void)
{
- int ret;
+ int ret, any_ret = -ENODEV;
init_kmem_once();
+ ret = platform_driver_register(&isp1760_plat_driver);
+ if (!ret)
+ any_ret = 0;
#ifdef CONFIG_PPC_OF
ret = of_register_platform_driver(&isp1760_of_driver);
- if (ret) {
- deinit_kmem_cache();
- return ret;
- }
+ if (!ret)
+ any_ret = 0;
#endif
#ifdef CONFIG_PCI
ret = pci_register_driver(&isp1761_pci_driver);
- if (ret)
- goto unreg_of;
+ if (!ret)
+ any_ret = 0;
#endif
- return ret;
-#ifdef CONFIG_PCI
-unreg_of:
-#endif
-#ifdef CONFIG_PPC_OF
- of_unregister_platform_driver(&isp1760_of_driver);
-#endif
- deinit_kmem_cache();
- return ret;
+ if (any_ret)
+ deinit_kmem_cache();
+ return any_ret;
}
module_init(isp1760_init);
static void __exit isp1760_exit(void)
{
+ platform_driver_unregister(&isp1760_plat_driver);
#ifdef CONFIG_PPC_OF
of_unregister_platform_driver(&isp1760_of_driver);
#endif
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index fb3055f084b5..7cf74f8c2db1 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -28,8 +28,6 @@
#include <linux/signal.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
-
static struct clk *usb_host_clock;
static void ep93xx_start_hc(struct device *dev)
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 65a9609f4ad6..5cf5f1eca4f4 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -593,12 +593,10 @@ static int ohci_run (struct ohci_hcd *ohci)
* to be checked in case boot firmware (BIOS/SMM/...) has set up
* wakeup in a way the bus isn't aware of (e.g., legacy PCI PM).
* If the bus glue detected wakeup capability then it should
- * already be enabled. Either way, if wakeup should be enabled
- * but isn't, we'll enable it now.
+ * already be enabled; if so we'll just enable it again.
*/
- if ((ohci->hc_control & OHCI_CTRL_RWC) != 0
- && !device_can_wakeup(hcd->self.controller))
- device_init_wakeup(hcd->self.controller, 1);
+ if ((ohci->hc_control & OHCI_CTRL_RWC) != 0)
+ device_set_wakeup_capable(hcd->self.controller, 1);
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 4bbddb73abd9..f3aaba35e912 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -315,14 +315,14 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
return -ENODEV;
}
- usb_host_ck = clk_get(0, "usb_hhc_ck");
+ usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck");
if (IS_ERR(usb_host_ck))
return PTR_ERR(usb_host_ck);
if (!cpu_is_omap15xx())
- usb_dc_ck = clk_get(0, "usb_dc_ck");
+ usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
else
- usb_dc_ck = clk_get(0, "lb_ck");
+ usb_dc_ck = clk_get(&pdev->dev, "lb_ck");
if (IS_ERR(usb_dc_ck)) {
clk_put(usb_host_ck);
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 8b28ae7865ba..f9961b4c0da3 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -487,8 +487,6 @@ static struct pci_driver ohci_pci_driver = {
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
- .suspend_late = usb_hcd_pci_suspend_late,
- .resume_early = usb_hcd_pci_resume_early,
.resume = usb_hcd_pci_resume,
#endif
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 75548f7c716b..2947c69b3476 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -845,14 +845,14 @@ static inline void qh_update(struct oxu_hcd *oxu,
is_out = !(qtd->hw_token & cpu_to_le32(1 << 8));
epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f;
if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
- qh->hw_token &= ~__constant_cpu_to_le32(QTD_TOGGLE);
+ qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE);
usb_settoggle(qh->dev, epnum, is_out, 1);
}
}
/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
wmb();
- qh->hw_token &= __constant_cpu_to_le32(QTD_TOGGLE | QTD_STS_PING);
+ qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING);
}
/* If it weren't for a common silicon quirk (writing the dummy into the qh
@@ -937,7 +937,7 @@ __acquires(oxu->lock)
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
/* S-mask in a QH means it's an interrupt urb */
- if ((qh->hw_info2 & __constant_cpu_to_le32(QH_SMASK)) != 0) {
+ if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */
oxu_to_hcd(oxu)->self.bandwidth_int_reqs--;
@@ -981,7 +981,7 @@ static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh);
static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh);
-#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
+#define HALT_BIT cpu_to_le32(QTD_STS_HALT)
/* Process and free completed qtds for a qh, returning URBs to drivers.
* Chases up to qh->hw_current. Returns number of completions called,
@@ -1160,7 +1160,7 @@ halt:
/* should be rare for periodic transfers,
* except maybe high bandwidth ...
*/
- if ((__constant_cpu_to_le32(QH_SMASK)
+ if ((cpu_to_le32(QH_SMASK)
& qh->hw_info2) != 0) {
intr_deschedule(oxu, qh);
(void) qh_schedule(oxu, qh);
@@ -1350,7 +1350,7 @@ static struct list_head *qh_urb_transaction(struct oxu_hcd *oxu,
}
/* by default, enable interrupt on urb completion */
- qtd->hw_token |= __constant_cpu_to_le32(QTD_IOC);
+ qtd->hw_token |= cpu_to_le32(QTD_IOC);
return head;
cleanup:
@@ -1539,7 +1539,7 @@ static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh)
/* qtd completions reported later by interrupt */
}
-#define QH_ADDR_MASK __constant_cpu_to_le32(0x7f)
+#define QH_ADDR_MASK cpu_to_le32(0x7f)
/*
* For control/bulk/interrupt, return QH with these TDs appended.
@@ -2012,7 +2012,7 @@ static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh)
* and this qh is active in the current uframe
* (and overlay token SplitXstate is false?)
* THEN
- * qh->hw_info1 |= __constant_cpu_to_le32(1 << 7 "ignore");
+ * qh->hw_info1 |= cpu_to_le32(1 << 7 "ignore");
*/
/* high bandwidth, or otherwise part of every microframe */
@@ -2057,7 +2057,7 @@ static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh)
* active high speed queues may need bigger delays...
*/
if (list_empty(&qh->qtd_list)
- || (__constant_cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0)
+ || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0)
wait = 2;
else
wait = 55; /* worst case: 3 * 1024 */
@@ -2183,10 +2183,10 @@ static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh)
qh->start = frame;
/* reset S-frame and (maybe) C-frame masks */
- qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
+ qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK));
qh->hw_info2 |= qh->period
? cpu_to_le32(1 << uframe)
- : __constant_cpu_to_le32(QH_SMASK);
+ : cpu_to_le32(QH_SMASK);
qh->hw_info2 |= c_mask;
} else
oxu_dbg(oxu, "reused qh %p schedule\n", qh);
diff --git a/drivers/usb/host/oxu210hp.h b/drivers/usb/host/oxu210hp.h
index 8910e271cc7d..1c216ad9aad2 100644
--- a/drivers/usb/host/oxu210hp.h
+++ b/drivers/usb/host/oxu210hp.h
@@ -235,21 +235,21 @@ struct ehci_qtd {
} __attribute__ ((aligned(32)));
/* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
+#define QTD_MASK cpu_to_le32 (~0x1f)
#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
/* Type tag from {qh, itd, sitd, fstn}->hw_next */
-#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
+#define Q_NEXT_TYPE(dma) ((dma) & cpu_to_le32 (3 << 1))
/* values for that type tag */
-#define Q_TYPE_QH __constant_cpu_to_le32 (1 << 1)
+#define Q_TYPE_QH cpu_to_le32 (1 << 1)
/* next async queue entry, or pointer to interrupt/periodic QH */
#define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
/* for periodic/async schedules and qtd lists, mark end of list */
-#define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */
+#define EHCI_LIST_END cpu_to_le32(1) /* "null pointer" to hw */
/*
* Entries in periodic shadow table are pointers to one of four kinds
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 75b69847918e..033c2846ce59 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -234,7 +234,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
*/
hcc_params = readl(base + EHCI_HCC_PARAMS);
offset = (hcc_params >> 8) & 0xff;
- while (offset && count--) {
+ while (offset && --count) {
u32 cap;
int msec;
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 319041205b57..5e942d94aebe 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -660,9 +660,9 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min;
memset(array, 0, sizeof(array));
- switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ switch (usb_endpoint_type(ep)) {
case USB_ENDPOINT_XFER_BULK:
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ if (usb_endpoint_dir_in(ep))
array[i++] = 4;
else {
array[i++] = 3;
@@ -670,7 +670,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
}
break;
case USB_ENDPOINT_XFER_INT:
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+ if (usb_endpoint_dir_in(ep)) {
array[i++] = 6;
array[i++] = 7;
array[i++] = 8;
@@ -678,7 +678,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
array[i++] = 9;
break;
case USB_ENDPOINT_XFER_ISOC:
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ if (usb_endpoint_dir_in(ep))
array[i++] = 2;
else
array[i++] = 1;
@@ -928,10 +928,9 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
info.pipenum = get_empty_pipenum(r8a66597, ep);
info.address = get_urb_to_r8a66597_addr(r8a66597, urb);
- info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ info.epnum = usb_endpoint_num(ep);
info.maxpacket = le16_to_cpu(ep->wMaxPacketSize);
- info.type = get_r8a66597_type(ep->bmAttributes
- & USB_ENDPOINT_XFERTYPE_MASK);
+ info.type = get_r8a66597_type(usb_endpoint_type(ep));
info.bufnum = get_bufnum(info.pipenum);
info.buf_bsize = get_buf_bsize(info.pipenum);
if (info.type == R8A66597_BULK) {
@@ -941,7 +940,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
info.interval = get_interval(urb, ep->bInterval);
info.timer_interval = get_timer_interval(urb, ep->bInterval);
}
- if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ if (usb_endpoint_dir_in(ep))
info.dir_in = 1;
else
info.dir_in = 0;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 4e221060f58c..cf5e4cf7ea42 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -942,8 +942,6 @@ static struct pci_driver uhci_pci_driver = {
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
- .suspend_late = usb_hcd_pci_suspend_late,
- .resume_early = usb_hcd_pci_resume_early,
.resume = usb_hcd_pci_resume,
#endif /* PM */
};
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 7d01c5677f92..26bd1b2bcbfc 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -73,11 +73,11 @@
#define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
#define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
-#define UHCI_PTR_BITS __constant_cpu_to_le32(0x000F)
-#define UHCI_PTR_TERM __constant_cpu_to_le32(0x0001)
-#define UHCI_PTR_QH __constant_cpu_to_le32(0x0002)
-#define UHCI_PTR_DEPTH __constant_cpu_to_le32(0x0004)
-#define UHCI_PTR_BREADTH __constant_cpu_to_le32(0x0000)
+#define UHCI_PTR_BITS cpu_to_le32(0x000F)
+#define UHCI_PTR_TERM cpu_to_le32(0x0001)
+#define UHCI_PTR_QH cpu_to_le32(0x0002)
+#define UHCI_PTR_DEPTH cpu_to_le32(0x0004)
+#define UHCI_PTR_BREADTH cpu_to_le32(0x0000)
#define UHCI_NUMFRAMES 1024 /* in the frame list [array] */
#define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 5631d89c8730..58f873679145 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -402,7 +402,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
/* Otherwise all the toggles in the URB have to be switched */
} else {
list_for_each_entry(td, &urbp->td_list, list) {
- td->token ^= __constant_cpu_to_le32(
+ td->token ^= cpu_to_le32(
TD_TOKEN_TOGGLE);
toggle ^= 1;
}
@@ -883,7 +883,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb();
- qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
+ qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE);
qh->dummy_td = td;
/* Low-speed transfers get a different queue, and won't hog the bus.
@@ -1003,7 +1003,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
* fast side but not enough to justify delaying an interrupt
* more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT
* flag setting. */
- td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+ td->status |= cpu_to_le32(TD_CTRL_IOC);
/*
* Build the new dummy TD and activate the old one
@@ -1015,7 +1015,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb();
- qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
+ qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE);
qh->dummy_td = td;
usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
@@ -1317,7 +1317,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
}
/* Set the interrupt-on-completion flag on the last packet. */
- td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
+ td->status |= cpu_to_le32(TD_CTRL_IOC);
/* Add the TDs to the frame list */
frame = urb->start_frame;
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index 577c0d29849d..958751ccea43 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -170,12 +170,17 @@ void asl_stop(struct whc *whc)
void asl_update(struct whc *whc, uint32_t wusbcmd)
{
struct wusbhc *wusbhc = &whc->wusbhc;
+ long t;
mutex_lock(&wusbhc->mutex);
if (wusbhc->active) {
whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
- wait_event(whc->async_list_wq,
- (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0);
+ t = wait_event_timeout(
+ whc->async_list_wq,
+ (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0,
+ msecs_to_jiffies(1000));
+ if (t == 0)
+ whc_hw_error(whc, "ASL update timeout");
}
mutex_unlock(&wusbhc->mutex);
}
@@ -222,13 +227,13 @@ void scan_async_work(struct work_struct *work)
* Now that the ASL is updated, complete the removal of any
* removed qsets.
*/
- spin_lock(&whc->lock);
+ spin_lock_irq(&whc->lock);
list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) {
qset_remove_complete(whc, qset);
}
- spin_unlock(&whc->lock);
+ spin_unlock_irq(&whc->lock);
}
/**
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c
index d498e7203217..6afa2e379160 100644
--- a/drivers/usb/host/whci/hw.c
+++ b/drivers/usb/host/whci/hw.c
@@ -87,3 +87,18 @@ out:
return ret;
}
+
+/**
+ * whc_hw_error - recover from a hardware error
+ * @whc: the WHCI HC that broke.
+ * @reason: a description of the failure.
+ *
+ * Recover from broken hardware with a full reset.
+ */
+void whc_hw_error(struct whc *whc, const char *reason)
+{
+ struct wusbhc *wusbhc = &whc->wusbhc;
+
+ dev_err(&whc->umc->dev, "hardware error: %s\n", reason);
+ wusbhc_reset_all(wusbhc);
+}
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index 2ae5abf69a6a..df8b85f07092 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc)
void pzl_update(struct whc *whc, uint32_t wusbcmd)
{
struct wusbhc *wusbhc = &whc->wusbhc;
+ long t;
mutex_lock(&wusbhc->mutex);
if (wusbhc->active) {
whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
- wait_event(whc->periodic_list_wq,
- (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0);
+ t = wait_event_timeout(
+ whc->periodic_list_wq,
+ (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0,
+ msecs_to_jiffies(1000));
+ if (t == 0)
+ whc_hw_error(whc, "PZL update timeout");
}
mutex_unlock(&wusbhc->mutex);
}
@@ -250,13 +255,13 @@ void scan_periodic_work(struct work_struct *work)
* Now that the PZL is updated, complete the removal of any
* removed qsets.
*/
- spin_lock(&whc->lock);
+ spin_lock_irq(&whc->lock);
list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) {
qset_remove_complete(whc, qset);
}
- spin_unlock(&whc->lock);
+ spin_unlock_irq(&whc->lock);
}
/**
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h
index 0f3540f04f53..d3543a181dc9 100644
--- a/drivers/usb/host/whci/whcd.h
+++ b/drivers/usb/host/whci/whcd.h
@@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc);
/* hw.c */
void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val);
int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len);
+void whc_hw_error(struct whc *whc, const char *reason);
/* wusb.c */
int whc_wusbhc_start(struct wusbhc *wusbhc);
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 878c77ca086e..efc075cda656 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -188,7 +188,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x01,
.bmAttributes = 0x02,
- .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .wMaxPacketSize = cpu_to_le16(8),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
@@ -198,7 +198,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x82,
.bmAttributes = 0x03,
- .wMaxPacketSize = __constant_cpu_to_le16(8),
+ .wMaxPacketSize = cpu_to_le16(8),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
@@ -208,7 +208,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x03,
.bmAttributes = 0x02,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .wMaxPacketSize = cpu_to_le16(64),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
@@ -218,7 +218,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] =
.bDescriptorType = 0,
.bEndpointAddress = 0x84,
.bmAttributes = 0x02,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .wMaxPacketSize = cpu_to_le16(64),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 189a9db03509..ad4fb15b5dcb 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -57,7 +57,6 @@
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 /* USB Product ID of Machine Test System */
#define USB_VENDOR_ID_VERNIER 0x08f7
-#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
@@ -85,7 +84,6 @@ static struct usb_device_id ld_usb_table [] = {
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) },
- { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index e06810aef2df..f8d9045d668a 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -37,9 +37,13 @@
#define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
+/* #9 was MON_IOCT_SETAPI */
+#define MON_IOCX_GETX _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get)
+
#ifdef CONFIG_COMPAT
#define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32)
#define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32)
+#define MON_IOCX_GETX32 _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get32)
#endif
/*
@@ -91,7 +95,29 @@ struct mon_bin_hdr {
int status;
unsigned int len_urb; /* Length of data (submitted or actual) */
unsigned int len_cap; /* Delivered length */
- unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+ union {
+ unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+ struct iso_rec {
+ int error_count;
+ int numdesc;
+ } iso;
+ } s;
+ int interval;
+ int start_frame;
+ unsigned int xfer_flags;
+ unsigned int ndesc; /* Actual number of ISO descriptors */
+};
+
+/*
+ * ISO vector, packed into the head of data stream.
+ * This has to take 16 bytes to make sure that the end of buffer
+ * wrap is not happening in the middle of a descriptor.
+ */
+struct mon_bin_isodesc {
+ int iso_status;
+ unsigned int iso_off;
+ unsigned int iso_len;
+ u32 _pad;
};
/* per file statistic */
@@ -101,7 +127,7 @@ struct mon_bin_stats {
};
struct mon_bin_get {
- struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */
+ struct mon_bin_hdr __user *hdr; /* Can be 48 bytes or 64. */
void __user *data;
size_t alloc; /* Length of data (can be zero) */
};
@@ -130,6 +156,11 @@ struct mon_bin_mfetch32 {
#define PKT_ALIGN 64
#define PKT_SIZE 64
+#define PKT_SZ_API0 48 /* API 0 (2.6.20) size */
+#define PKT_SZ_API1 64 /* API 1 size: extra fields */
+
+#define ISODESC_MAX 128 /* Same number as usbfs allows, 2048 bytes. */
+
/* max number of USB bus supported */
#define MON_BIN_MAX_MINOR 128
@@ -359,12 +390,8 @@ static inline char mon_bin_get_setup(unsigned char *setupb,
const struct urb *urb, char ev_type)
{
- if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S')
- return '-';
-
if (urb->setup_packet == NULL)
return 'Z';
-
memcpy(setupb, urb->setup_packet, SETUP_LEN);
return 0;
}
@@ -386,6 +413,26 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp,
return 0;
}
+static void mon_bin_get_isodesc(const struct mon_reader_bin *rp,
+ unsigned int offset, struct urb *urb, char ev_type, unsigned int ndesc)
+{
+ struct mon_bin_isodesc *dp;
+ struct usb_iso_packet_descriptor *fp;
+
+ fp = urb->iso_frame_desc;
+ while (ndesc-- != 0) {
+ dp = (struct mon_bin_isodesc *)
+ (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE);
+ dp->iso_status = fp->status;
+ dp->iso_off = fp->offset;
+ dp->iso_len = (ev_type == 'S') ? fp->length : fp->actual_length;
+ dp->_pad = 0;
+ if ((offset += sizeof(struct mon_bin_isodesc)) >= rp->b_size)
+ offset = 0;
+ fp++;
+ }
+}
+
static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
char ev_type, int status)
{
@@ -395,6 +442,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
unsigned int urb_length;
unsigned int offset;
unsigned int length;
+ unsigned int ndesc, lendesc;
unsigned char dir;
struct mon_bin_hdr *ep;
char data_tag = 0;
@@ -406,6 +454,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
/*
* Find the maximum allowable length, then allocate space.
*/
+ if (usb_endpoint_xfer_isoc(epd)) {
+ if (urb->number_of_packets < 0) {
+ ndesc = 0;
+ } else if (urb->number_of_packets >= ISODESC_MAX) {
+ ndesc = ISODESC_MAX;
+ } else {
+ ndesc = urb->number_of_packets;
+ }
+ } else {
+ ndesc = 0;
+ }
+ lendesc = ndesc*sizeof(struct mon_bin_isodesc);
+
urb_length = (ev_type == 'S') ?
urb->transfer_buffer_length : urb->actual_length;
length = urb_length;
@@ -428,10 +489,12 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
dir = 0;
}
- if (rp->mmap_active)
- offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE);
- else
- offset = mon_buff_area_alloc(rp, length + PKT_SIZE);
+ if (rp->mmap_active) {
+ offset = mon_buff_area_alloc_contiguous(rp,
+ length + PKT_SIZE + lendesc);
+ } else {
+ offset = mon_buff_area_alloc(rp, length + PKT_SIZE + lendesc);
+ }
if (offset == ~0) {
rp->cnt_lost++;
spin_unlock_irqrestore(&rp->b_lock, flags);
@@ -455,9 +518,31 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
ep->ts_usec = ts.tv_usec;
ep->status = status;
ep->len_urb = urb_length;
- ep->len_cap = length;
+ ep->len_cap = length + lendesc;
+ ep->xfer_flags = urb->transfer_flags;
+
+ if (usb_endpoint_xfer_int(epd)) {
+ ep->interval = urb->interval;
+ } else if (usb_endpoint_xfer_isoc(epd)) {
+ ep->interval = urb->interval;
+ ep->start_frame = urb->start_frame;
+ ep->s.iso.error_count = urb->error_count;
+ ep->s.iso.numdesc = urb->number_of_packets;
+ }
+
+ if (usb_endpoint_xfer_control(epd) && ev_type == 'S') {
+ ep->flag_setup = mon_bin_get_setup(ep->s.setup, urb, ev_type);
+ } else {
+ ep->flag_setup = '-';
+ }
+
+ if (ndesc != 0) {
+ ep->ndesc = ndesc;
+ mon_bin_get_isodesc(rp, offset, urb, ev_type, ndesc);
+ if ((offset += lendesc) >= rp->b_size)
+ offset -= rp->b_size;
+ }
- ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type);
if (length != 0) {
ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */
@@ -591,7 +676,8 @@ err_alloc:
* Returns zero or error.
*/
static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp,
- struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes)
+ struct mon_bin_hdr __user *hdr, unsigned int hdrbytes,
+ void __user *data, unsigned int nbytes)
{
unsigned long flags;
struct mon_bin_hdr *ep;
@@ -608,7 +694,7 @@ static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp,
ep = MON_OFF2HDR(rp, rp->b_out);
- if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) {
+ if (copy_to_user(hdr, ep, hdrbytes)) {
mutex_unlock(&rp->fetch_lock);
return -EFAULT;
}
@@ -656,6 +742,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
{
struct mon_reader_bin *rp = file->private_data;
+ unsigned int hdrbytes = PKT_SZ_API0;
unsigned long flags;
struct mon_bin_hdr *ep;
unsigned int offset;
@@ -673,8 +760,8 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
ep = MON_OFF2HDR(rp, rp->b_out);
- if (rp->b_read < sizeof(struct mon_bin_hdr)) {
- step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read);
+ if (rp->b_read < hdrbytes) {
+ step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read));
ptr = ((char *)ep) + rp->b_read;
if (step_len && copy_to_user(buf, ptr, step_len)) {
mutex_unlock(&rp->fetch_lock);
@@ -686,13 +773,13 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
done += step_len;
}
- if (rp->b_read >= sizeof(struct mon_bin_hdr)) {
+ if (rp->b_read >= hdrbytes) {
step_len = ep->len_cap;
- step_len -= rp->b_read - sizeof(struct mon_bin_hdr);
+ step_len -= rp->b_read - hdrbytes;
if (step_len > nbytes)
step_len = nbytes;
offset = rp->b_out + PKT_SIZE;
- offset += rp->b_read - sizeof(struct mon_bin_hdr);
+ offset += rp->b_read - hdrbytes;
if (offset >= rp->b_size)
offset -= rp->b_size;
if (copy_from_buf(rp, offset, buf, step_len)) {
@@ -708,7 +795,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf,
/*
* Check if whole packet was read, and if so, jump to the next one.
*/
- if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) {
+ if (rp->b_read >= hdrbytes + ep->len_cap) {
spin_lock_irqsave(&rp->b_lock, flags);
mon_buff_area_free(rp, PKT_SIZE + ep->len_cap);
spin_unlock_irqrestore(&rp->b_lock, flags);
@@ -907,6 +994,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
break;
case MON_IOCX_GET:
+ case MON_IOCX_GETX:
{
struct mon_bin_get getb;
@@ -916,26 +1004,12 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
if (getb.alloc > 0x10000000) /* Want to cast to u32 */
return -EINVAL;
- ret = mon_bin_get_event(file, rp,
- getb.hdr, getb.data, (unsigned int)getb.alloc);
+ ret = mon_bin_get_event(file, rp, getb.hdr,
+ (cmd == MON_IOCX_GET)? PKT_SZ_API0: PKT_SZ_API1,
+ getb.data, (unsigned int)getb.alloc);
}
break;
-#ifdef CONFIG_COMPAT
- case MON_IOCX_GET32: {
- struct mon_bin_get32 getb;
-
- if (copy_from_user(&getb, (void __user *)arg,
- sizeof(struct mon_bin_get32)))
- return -EFAULT;
-
- ret = mon_bin_get_event(file, rp,
- compat_ptr(getb.hdr32), compat_ptr(getb.data32),
- getb.alloc32);
- }
- break;
-#endif
-
case MON_IOCX_MFETCH:
{
struct mon_bin_mfetch mfetch;
@@ -962,7 +1036,59 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
}
break;
+ case MON_IOCG_STATS: {
+ struct mon_bin_stats __user *sp;
+ unsigned int nevents;
+ unsigned int ndropped;
+
+ spin_lock_irqsave(&rp->b_lock, flags);
+ ndropped = rp->cnt_lost;
+ rp->cnt_lost = 0;
+ spin_unlock_irqrestore(&rp->b_lock, flags);
+ nevents = mon_bin_queued(rp);
+
+ sp = (struct mon_bin_stats __user *)arg;
+ if (put_user(rp->cnt_lost, &sp->dropped))
+ return -EFAULT;
+ if (put_user(nevents, &sp->queued))
+ return -EFAULT;
+
+ }
+ break;
+
+ default:
+ return -ENOTTY;
+ }
+
+ return ret;
+}
+
#ifdef CONFIG_COMPAT
+static long mon_bin_compat_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct mon_reader_bin *rp = file->private_data;
+ int ret;
+
+ switch (cmd) {
+
+ case MON_IOCX_GET32:
+ case MON_IOCX_GETX32:
+ {
+ struct mon_bin_get32 getb;
+
+ if (copy_from_user(&getb, (void __user *)arg,
+ sizeof(struct mon_bin_get32)))
+ return -EFAULT;
+
+ ret = mon_bin_get_event(file, rp, compat_ptr(getb.hdr32),
+ (cmd == MON_IOCX_GET32)? PKT_SZ_API0: PKT_SZ_API1,
+ compat_ptr(getb.data32), getb.alloc32);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+
case MON_IOCX_MFETCH32:
{
struct mon_bin_mfetch32 mfetch;
@@ -986,37 +1112,25 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file,
return ret;
if (put_user(ret, &uptr->nfetch32))
return -EFAULT;
- ret = 0;
}
- break;
-#endif
-
- case MON_IOCG_STATS: {
- struct mon_bin_stats __user *sp;
- unsigned int nevents;
- unsigned int ndropped;
-
- spin_lock_irqsave(&rp->b_lock, flags);
- ndropped = rp->cnt_lost;
- rp->cnt_lost = 0;
- spin_unlock_irqrestore(&rp->b_lock, flags);
- nevents = mon_bin_queued(rp);
+ return 0;
- sp = (struct mon_bin_stats __user *)arg;
- if (put_user(rp->cnt_lost, &sp->dropped))
- return -EFAULT;
- if (put_user(nevents, &sp->queued))
- return -EFAULT;
+ case MON_IOCG_STATS:
+ return mon_bin_ioctl(NULL, file, cmd,
+ (unsigned long) compat_ptr(arg));
- }
- break;
+ case MON_IOCQ_URB_LEN:
+ case MON_IOCQ_RING_SIZE:
+ case MON_IOCT_RING_SIZE:
+ case MON_IOCH_MFLUSH:
+ return mon_bin_ioctl(NULL, file, cmd, arg);
default:
- return -ENOTTY;
+ ;
}
-
- return ret;
+ return -ENOTTY;
}
+#endif /* CONFIG_COMPAT */
static unsigned int
mon_bin_poll(struct file *file, struct poll_table_struct *wait)
@@ -1094,6 +1208,9 @@ static const struct file_operations mon_fops_binary = {
/* .write = mon_text_write, */
.poll = mon_bin_poll,
.ioctl = mon_bin_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = mon_bin_compat_ioctl,
+#endif
.release = mon_bin_release,
.mmap = mon_bin_mmap,
};
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 5af7379cd9a3..b66e8544d8b9 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC
depends on (USB || USB_GADGET) && HAVE_CLK
depends on !SUPERH
select TWL4030_USB if MACH_OMAP_3430SDP
+ select USB_OTG_UTILS
tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
help
Say Y here if your system has a dual role high speed USB
@@ -19,8 +20,8 @@ config USB_MUSB_HDRC
it's being used with, including the USB peripheral role,
or the USB host role, or both.
- Texas Instruments parts using this IP include DaVinci 644x,
- OMAP 243x, OMAP 343x, and TUSB 6010.
+ Texas Instruments familiies using this IP include DaVinci
+ (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010.
Analog Devices parts using this IP include Blackfin BF54x,
BF525 and BF527.
@@ -39,7 +40,7 @@ config USB_MUSB_SOC
default y if (BF54x && !BF544)
default y if (BF52x && !BF522 && !BF523)
-comment "DaVinci 644x USB support"
+comment "DaVinci 35x and 644x USB support"
depends on USB_MUSB_HDRC && ARCH_DAVINCI
comment "OMAP 243x high speed USB support"
@@ -49,7 +50,7 @@ comment "OMAP 343x high speed USB support"
depends on USB_MUSB_HDRC && ARCH_OMAP34XX
comment "Blackfin high speed USB Support"
- depends on USB_MUSB_HDRC && (BF54x && !BF544) || (BF52x && !BF522 && !BF523)
+ depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523))
config USB_TUSB6010
boolean "TUSB 6010 support"
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 5ad6d0893cbe..569ef0fed0f6 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -9,6 +9,7 @@
#include <linux/usb.h>
#include "musb_core.h"
+#include "musb_debug.h"
#include "cppi_dma.h"
@@ -423,6 +424,7 @@ cppi_rndis_update(struct cppi_channel *c, int is_rx,
}
}
+#ifdef CONFIG_USB_MUSB_DEBUG
static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd)
{
pr_debug("RXBD/%s %08x: "
@@ -431,10 +433,11 @@ static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd)
bd->hw_next, bd->hw_bufp, bd->hw_off_len,
bd->hw_options);
}
+#endif
static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx)
{
-#if MUSB_DEBUG > 0
+#ifdef CONFIG_USB_MUSB_DEBUG
struct cppi_descriptor *bd;
if (!_dbg_level(level))
@@ -881,12 +884,14 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)
bd->hw_options |= CPPI_SOP_SET;
tail->hw_options |= CPPI_EOP_SET;
- if (debug >= 5) {
+#ifdef CONFIG_USB_MUSB_DEBUG
+ if (_dbg_level(5)) {
struct cppi_descriptor *d;
for (d = rx->head; d; d = d->next)
cppi_dump_rxbd("S", d);
}
+#endif
/* in case the preceding transfer left some state... */
tail = rx->last_processed;
@@ -990,6 +995,7 @@ static int cppi_channel_program(struct dma_channel *ch,
cppi_ch->offset = 0;
cppi_ch->maxpacket = maxpacket;
cppi_ch->buf_len = len;
+ cppi_ch->channel.actual_len = 0;
/* TX channel? or RX? */
if (cppi_ch->transmit)
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 0d566dc5ce06..10d11ab113ab 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -32,9 +32,10 @@
#include <linux/io.h>
#include <linux/gpio.h>
-#include <mach/arch/hardware.h>
-#include <mach/arch/memory.h>
-#include <mach/arch/gpio.h>
+#include <mach/hardware.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+
#include <asm/mach-types.h>
#include "musb_core.h"
@@ -47,6 +48,9 @@
#include "cppi_dma.h"
+#define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR)
+#define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR)
+
/* REVISIT (PM) we should be able to keep the PHY in low power mode most
* of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
* and, when in host mode, autosuspending idle root ports... PHYPLLON
@@ -55,20 +59,26 @@
static inline void phy_on(void)
{
- /* start the on-chip PHY and its PLL */
- __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON,
- (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR));
- while ((__raw_readl((void __force __iomem *)
- IO_ADDRESS(USBPHY_CTL_PADDR))
- & USBPHY_PHYCLKGD) == 0)
+ u32 phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+ /* power everything up; start the on-chip PHY and its PLL */
+ phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN);
+ phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON;
+ __raw_writel(phy_ctrl, USB_PHY_CTRL);
+
+ /* wait for PLL to lock before proceeding */
+ while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0)
cpu_relax();
}
static inline void phy_off(void)
{
- /* powerdown the on-chip PHY and its oscillator */
- __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *)
- IO_ADDRESS(USBPHY_CTL_PADDR));
+ u32 phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+ /* powerdown the on-chip PHY, its PLL, and the OTG block */
+ phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON);
+ phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN;
+ __raw_writel(phy_ctrl, USB_PHY_CTRL);
}
static int dma_off = 1;
@@ -125,10 +135,6 @@ void musb_platform_disable(struct musb *musb)
}
-/* REVISIT it's not clear whether DaVinci can support full OTG. */
-
-static int vbus_state = -1;
-
#ifdef CONFIG_USB_MUSB_HDRC_HCD
#define portstate(stmt) stmt
#else
@@ -136,10 +142,19 @@ static int vbus_state = -1;
#endif
-/* VBUS SWITCHING IS BOARD-SPECIFIC */
+/*
+ * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM,
+ * which doesn't wire DRVVBUS to the FET that switches it. Unclear
+ * if that's a problem with the DM6446 chip or just with that board.
+ *
+ * In either case, the DM355 EVM automates DRVVBUS the normal way,
+ * when J10 is out, and TI documents it as handling OTG.
+ */
#ifdef CONFIG_MACH_DAVINCI_EVM
+static int vbus_state = -1;
+
/* I2C operations are always synchronous, and require a task context.
* With unloaded systems, using the shared workqueue seems to suffice
* to satisfy the 100msec A_WAIT_VRISE timeout...
@@ -149,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored)
gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
vbus_state = !vbus_state;
}
-static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
#endif /* EVM */
static void davinci_source_power(struct musb *musb, int is_on, int immediate)
{
+#ifdef CONFIG_MACH_DAVINCI_EVM
if (is_on)
is_on = 1;
@@ -162,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
return;
vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */
-#ifdef CONFIG_MACH_DAVINCI_EVM
if (machine_is_davinci_evm()) {
+ static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
+
if (immediate)
gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
else
schedule_work(&evm_vbus_work);
}
-#endif
if (immediate)
vbus_state = is_on;
+#endif
}
static void davinci_set_vbus(struct musb *musb, int is_on)
@@ -370,30 +386,14 @@ int musb_platform_set_mode(struct musb *musb, u8 mode)
return -EIO;
}
-int musb_platform_set_mode(struct musb *musb, u8 mode)
-{
- /* EVM can't do this (right?) */
- return -EIO;
-}
-
int __init musb_platform_init(struct musb *musb)
{
void __iomem *tibase = musb->ctrl_base;
u32 revision;
musb->mregs += DAVINCI_BASE_OFFSET;
-#if 0
- /* REVISIT there's something odd about clocking, this
- * didn't appear do the job ...
- */
- musb->clock = clk_get(pDevice, "usb");
- if (IS_ERR(musb->clock))
- return PTR_ERR(musb->clock);
- status = clk_enable(musb->clock);
- if (status < 0)
- return -ENODEV;
-#endif
+ clk_enable(musb->clock);
/* returns zero if e.g. not clocked */
revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
@@ -406,6 +406,17 @@ int __init musb_platform_init(struct musb *musb)
musb->board_set_vbus = davinci_set_vbus;
davinci_source_power(musb, 0, 1);
+ /* dm355 EVM swaps D+/D- for signal integrity, and
+ * is clocked from the main 24 MHz crystal.
+ */
+ if (machine_is_davinci_dm355_evm()) {
+ u32 phy_ctrl = __raw_readl(USB_PHY_CTRL);
+
+ phy_ctrl &= ~(3 << 9);
+ phy_ctrl |= USBPHY_DATAPOL;
+ __raw_writel(phy_ctrl, USB_PHY_CTRL);
+ }
+
/* reset the controller */
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
@@ -416,8 +427,7 @@ int __init musb_platform_init(struct musb *musb)
/* NOTE: irqs are in mixed mode, not bypass to pure-musb */
pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
- revision, __raw_readl((void __force __iomem *)
- IO_ADDRESS(USBPHY_CTL_PADDR)),
+ revision, __raw_readl(USB_PHY_CTRL),
musb_readb(tibase, DAVINCI_USB_CTRL_REG));
musb->isr = davinci_interrupt;
@@ -458,5 +468,8 @@ int musb_platform_exit(struct musb *musb)
}
phy_off();
+
+ clk_disable(musb->clock);
+
return 0;
}
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h
index 7fb6238e270f..046c84433cad 100644
--- a/drivers/usb/musb/davinci.h
+++ b/drivers/usb/musb/davinci.h
@@ -15,14 +15,21 @@
*/
/* Integrated highspeed/otg PHY */
-#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
-#define USBPHY_PHYCLKGD (1 << 8)
-#define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */
-#define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */
-#define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */
-#define USBPHY_CLKO1SEL (1 << 3)
-#define USBPHY_OSCPDWN (1 << 2)
-#define USBPHY_PHYPDWN (1 << 0)
+#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
+#define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */
+#define USBPHY_PHYCLKGD BIT(8)
+#define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */
+#define USBPHY_VBDTCTEN BIT(6) /* v(bus) comparator */
+#define USBPHY_VBUSSENS BIT(5) /* (dm355,ro) is vbus > 0.5V */
+#define USBPHY_PHYPLLON BIT(4) /* override pll suspend */
+#define USBPHY_CLKO1SEL BIT(3)
+#define USBPHY_OSCPDWN BIT(2)
+#define USBPHY_OTGPDWN BIT(1)
+#define USBPHY_PHYPDWN BIT(0)
+
+#define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48)
+#define DRVVBUS_FORCE BIT(2)
+#define DRVVBUS_OVERRIDE BIT(1)
/* For now include usb OTG module registers here */
#define DAVINCI_USB_VERSION_REG 0x00
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 6c7faacfb535..338cd1611ab3 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -115,7 +115,7 @@
unsigned musb_debug;
-module_param(musb_debug, uint, S_IRUGO | S_IWUSR);
+module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug message level. Default = 0");
#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
@@ -767,8 +767,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
#ifdef CONFIG_USB_MUSB_HDRC_HCD
case OTG_STATE_A_HOST:
case OTG_STATE_A_SUSPEND:
+ usb_hcd_resume_root_hub(musb_to_hcd(musb));
musb_root_disconnect(musb);
- if (musb->a_wait_bcon != 0)
+ if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
musb_platform_try_idle(musb, jiffies
+ msecs_to_jiffies(musb->a_wait_bcon));
break;
@@ -1815,7 +1816,7 @@ static void musb_free(struct musb *musb)
#ifdef CONFIG_SYSFS
device_remove_file(musb->controller, &dev_attr_mode);
device_remove_file(musb->controller, &dev_attr_vbus);
-#ifdef CONFIG_USB_MUSB_OTG
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
device_remove_file(musb->controller, &dev_attr_srp);
#endif
#endif
@@ -1824,8 +1825,9 @@ static void musb_free(struct musb *musb)
musb_gadget_cleanup(musb);
#endif
- if (musb->nIrq >= 0 && musb->irq_wake) {
- disable_irq_wake(musb->nIrq);
+ if (musb->nIrq >= 0) {
+ if (musb->irq_wake)
+ disable_irq_wake(musb->nIrq);
free_irq(musb->nIrq, musb);
}
if (is_dma_capable() && musb->dma_controller) {
@@ -2062,7 +2064,7 @@ fail2:
#ifdef CONFIG_SYSFS
device_remove_file(musb->controller, &dev_attr_mode);
device_remove_file(musb->controller, &dev_attr_vbus);
-#ifdef CONFIG_USB_MUSB_OTG
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
device_remove_file(musb->controller, &dev_attr_srp);
#endif
#endif
@@ -2242,10 +2244,10 @@ static int __init musb_init(void)
return platform_driver_probe(&musb_driver, musb_probe);
}
-/* make us init after usbcore and before usb
- * gadget and host-side drivers start to register
+/* make us init after usbcore and i2c (transceivers, regulators, etc)
+ * and before usb gadget and host-side drivers start to register
*/
-subsys_initcall(musb_init);
+fs_initcall(musb_init);
static void __exit musb_cleanup(void)
{
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 630946a2d9fc..efb39b5e55b5 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -331,7 +331,6 @@ struct musb {
struct list_head control; /* of musb_qh */
struct list_head in_bulk; /* of musb_qh */
struct list_head out_bulk; /* of musb_qh */
- struct musb_qh *periodic[32]; /* tree of interrupt+iso */
#endif
/* called with IRQs blocked; ON/nonzero implies starting a session,
@@ -479,10 +478,11 @@ static inline void musb_configure_ep0(struct musb *musb)
static inline int musb_read_fifosize(struct musb *musb,
struct musb_hw_ep *hw_ep, u8 epnum)
{
+ void *mbase = musb->mregs;
u8 reg = 0;
/* read from core using indexed model */
- reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
+ reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE));
/* 0's returned when no more endpoints */
if (!reg)
return -ENODEV;
@@ -509,6 +509,7 @@ static inline void musb_configure_ep0(struct musb *musb)
{
musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
+ musb->endpoints[0].is_shared_fifo = true;
}
#endif /* CONFIG_BLACKFIN */
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 6197daeab8f9..c7ebd0867fcc 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -575,7 +575,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
struct usb_request *request = &req->request;
struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
void __iomem *epio = musb->endpoints[epnum].regs;
- u16 fifo_count = 0;
+ unsigned fifo_count = 0;
u16 len = musb_ep->packet_sz;
csr = musb_readw(epio, MUSB_RXCSR);
@@ -687,7 +687,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
len, fifo_count,
musb_ep->packet_sz);
- fifo_count = min(len, fifo_count);
+ fifo_count = min_t(unsigned, len, fifo_count);
#ifdef CONFIG_USB_TUSB_OMAP_DMA
if (tusb_dma_omap() && musb_ep->dma) {
@@ -874,10 +874,10 @@ static int musb_gadget_enable(struct usb_ep *ep,
status = -EBUSY;
goto fail;
}
- musb_ep->type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ musb_ep->type = usb_endpoint_type(desc);
/* check direction and (later) maxpacket size against endpoint */
- if ((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != epnum)
+ if (usb_endpoint_num(desc) != epnum)
goto fail;
/* REVISIT this rules out high bandwidth periodic transfers */
@@ -890,7 +890,7 @@ static int musb_gadget_enable(struct usb_ep *ep,
* packet size (or fail), set the mode, clear the fifo
*/
musb_ep_select(mbase, epnum);
- if (desc->bEndpointAddress & USB_DIR_IN) {
+ if (usb_endpoint_dir_in(desc)) {
u16 int_txe = musb_readw(mbase, MUSB_INTRTXE);
if (hw_ep->is_shared_fifo)
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 99fa61234876..499c431a6d62 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -64,11 +64,8 @@
*
* - DMA (Mentor/OMAP) ...has at least toggle update problems
*
- * - Still no traffic scheduling code to make NAKing for bulk or control
- * transfers unable to starve other requests; or to make efficient use
- * of hardware with periodic transfers. (Note that network drivers
- * commonly post bulk reads that stay pending for a long time; these
- * would make very visible trouble.)
+ * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet
+ * starvation ... nothing yet for TX, interrupt, or bulk.
*
* - Not tested with HNP, but some SRP paths seem to behave.
*
@@ -88,11 +85,8 @@
*
* CONTROL transfers all go through ep0. BULK ones go through dedicated IN
* and OUT endpoints ... hardware is dedicated for those "async" queue(s).
- *
* (Yes, bulk _could_ use more of the endpoints than that, and would even
- * benefit from it ... one remote device may easily be NAKing while others
- * need to perform transfers in that same direction. The same thing could
- * be done in software though, assuming dma cooperates.)
+ * benefit from it.)
*
* INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints.
* So far that scheduling is both dumb and optimistic: the endpoint will be
@@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
len = urb->iso_frame_desc[0].length;
break;
default: /* bulk, interrupt */
- buf = urb->transfer_buffer;
- len = urb->transfer_buffer_length;
+ /* actual_length may be nonzero on retry paths */
+ buf = urb->transfer_buffer + urb->actual_length;
+ len = urb->transfer_buffer_length - urb->actual_length;
}
DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
@@ -335,16 +330,11 @@ musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb)
static struct musb_qh *
musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
{
- int is_in;
struct musb_hw_ep *ep = qh->hw_ep;
struct musb *musb = ep->musb;
+ int is_in = usb_pipein(urb->pipe);
int ready = qh->is_ready;
- if (ep->is_shared_fifo)
- is_in = 1;
- else
- is_in = usb_pipein(urb->pipe);
-
/* save toggle eagerly, for paranoia */
switch (qh->type) {
case USB_ENDPOINT_XFER_BULK:
@@ -400,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
* de-allocated if it's tracked and allocated;
* and where we'd update the schedule tree...
*/
- musb->periodic[ep->epnum] = NULL;
kfree(qh);
qh = NULL;
break;
@@ -432,7 +421,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb,
else
qh = musb_giveback(qh, urb, urb->status);
- if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) {
+ if (qh != NULL && qh->is_ready) {
DBG(4, "... next ep%d %cX urb %p\n",
hw_ep->epnum, is_in ? 'R' : 'T',
next_urb(qh));
@@ -942,8 +931,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
switch (musb->ep0_stage) {
case MUSB_EP0_IN:
fifo_dest = urb->transfer_buffer + urb->actual_length;
- fifo_count = min(len, ((u16) (urb->transfer_buffer_length
- - urb->actual_length)));
+ fifo_count = min_t(size_t, len, urb->transfer_buffer_length -
+ urb->actual_length);
if (fifo_count < len)
urb->status = -EOVERFLOW;
@@ -976,10 +965,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
}
/* FALLTHROUGH */
case MUSB_EP0_OUT:
- fifo_count = min(qh->maxpacket, ((u16)
- (urb->transfer_buffer_length
- - urb->actual_length)));
-
+ fifo_count = min_t(size_t, qh->maxpacket,
+ urb->transfer_buffer_length -
+ urb->actual_length);
if (fifo_count) {
fifo_dest = (u8 *) (urb->transfer_buffer
+ urb->actual_length);
@@ -1051,7 +1039,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
/* NOTE: this code path would be a good place to PAUSE a
* control transfer, if another one is queued, so that
- * ep0 is more likely to stay busy.
+ * ep0 is more likely to stay busy. That's already done
+ * for bulk RX transfers.
*
* if (qh->ring.next != &musb->control), then
* we have a candidate... NAKing is *NOT* an error
@@ -1161,7 +1150,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
struct urb *urb;
struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
void __iomem *epio = hw_ep->regs;
- struct musb_qh *qh = hw_ep->out_qh;
+ struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh
+ : hw_ep->out_qh;
u32 status = 0;
void __iomem *mbase = musb->mregs;
struct dma_channel *dma;
@@ -1202,6 +1192,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
/* NOTE: this code path would be a good place to PAUSE a
* transfer, if there's some other (nonperiodic) tx urb
* that could use this fifo. (dma complicates it...)
+ * That's already done for bulk RX transfers.
*
* if (bulk && qh->ring.next != &musb->out_bulk), then
* we have a candidate... NAKing is *NOT* an error
@@ -1308,7 +1299,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
* packets before updating TXCSR ... other docs disagree ...
*/
/* PIO: start next packet in this URB */
- wLength = min(qh->maxpacket, (u16) wLength);
+ if (wLength > qh->maxpacket)
+ wLength = qh->maxpacket;
musb_write_fifo(hw_ep, wLength, buf);
qh->segsize = wLength;
@@ -1362,6 +1354,50 @@ finish:
#endif
+/* Schedule next QH from musb->in_bulk and move the current qh to
+ * the end; avoids starvation for other endpoints.
+ */
+static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
+{
+ struct dma_channel *dma;
+ struct urb *urb;
+ void __iomem *mbase = musb->mregs;
+ void __iomem *epio = ep->regs;
+ struct musb_qh *cur_qh, *next_qh;
+ u16 rx_csr;
+
+ musb_ep_select(mbase, ep->epnum);
+ dma = is_dma_capable() ? ep->rx_channel : NULL;
+
+ /* clear nak timeout bit */
+ rx_csr = musb_readw(epio, MUSB_RXCSR);
+ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+ rx_csr &= ~MUSB_RXCSR_DATAERROR;
+ musb_writew(epio, MUSB_RXCSR, rx_csr);
+
+ cur_qh = first_qh(&musb->in_bulk);
+ if (cur_qh) {
+ urb = next_urb(cur_qh);
+ if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+ dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+ musb->dma_controller->channel_abort(dma);
+ urb->actual_length += dma->actual_len;
+ dma->actual_len = 0L;
+ }
+ musb_save_toggle(ep, 1, urb);
+
+ /* move cur_qh to end of queue */
+ list_move_tail(&cur_qh->ring, &musb->in_bulk);
+
+ /* get the next qh from musb->in_bulk */
+ next_qh = first_qh(&musb->in_bulk);
+
+ /* set rx_reinit and schedule the next qh */
+ ep->rx_reinit = 1;
+ musb_start_urb(musb, 1, next_qh);
+ }
+}
+
/*
* Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
* and high-bandwidth IN transfer cases.
@@ -1425,18 +1461,26 @@ void musb_host_rx(struct musb *musb, u8 epnum)
} else if (rx_csr & MUSB_RXCSR_DATAERROR) {
if (USB_ENDPOINT_XFER_ISOC != qh->type) {
- /* NOTE this code path would be a good place to PAUSE a
- * transfer, if there's some other (nonperiodic) rx urb
- * that could use this fifo. (dma complicates it...)
+ DBG(6, "RX end %d NAK timeout\n", epnum);
+
+ /* NOTE: NAKing is *NOT* an error, so we want to
+ * continue. Except ... if there's a request for
+ * another QH, use that instead of starving it.
*
- * if (bulk && qh->ring.next != &musb->in_bulk), then
- * we have a candidate... NAKing is *NOT* an error
+ * Devices like Ethernet and serial adapters keep
+ * reads posted at all times, which will starve
+ * other devices without this logic.
*/
- DBG(6, "RX end %d NAK timeout\n", epnum);
+ if (usb_pipebulk(urb->pipe)
+ && qh->mux == 1
+ && !list_is_singular(&musb->in_bulk)) {
+ musb_bulk_rx_nak_timeout(musb, hw_ep);
+ return;
+ }
musb_ep_select(mbase, epnum);
- musb_writew(epio, MUSB_RXCSR,
- MUSB_RXCSR_H_WZC_BITS
- | MUSB_RXCSR_H_REQPKT);
+ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+ rx_csr &= ~MUSB_RXCSR_DATAERROR;
+ musb_writew(epio, MUSB_RXCSR, rx_csr);
goto finish;
} else {
@@ -1715,31 +1759,27 @@ static int musb_schedule(
/* else, periodic transfers get muxed to other endpoints */
- /* FIXME this doesn't consider direction, so it can only
- * work for one half of the endpoint hardware, and assumes
- * the previous cases handled all non-shared endpoints...
- */
-
- /* we know this qh hasn't been scheduled, so all we need to do
+ /*
+ * We know this qh hasn't been scheduled, so all we need to do
* is choose which hardware endpoint to put it on ...
*
* REVISIT what we really want here is a regular schedule tree
- * like e.g. OHCI uses, but for now musb->periodic is just an
- * array of the _single_ logical endpoint associated with a
- * given physical one (identity mapping logical->physical).
- *
- * that simplistic approach makes TT scheduling a lot simpler;
- * there is none, and thus none of its complexity...
+ * like e.g. OHCI uses.
*/
best_diff = 4096;
best_end = -1;
- for (epnum = 1; epnum < musb->nr_endpoints; epnum++) {
+ for (epnum = 1, hw_ep = musb->endpoints + 1;
+ epnum < musb->nr_endpoints;
+ epnum++, hw_ep++) {
int diff;
- if (musb->periodic[epnum])
+ if (is_in || hw_ep->is_shared_fifo) {
+ if (hw_ep->in_qh != NULL)
+ continue;
+ } else if (hw_ep->out_qh != NULL)
continue;
- hw_ep = &musb->endpoints[epnum];
+
if (hw_ep == musb->bulk_ep)
continue;
@@ -1760,6 +1800,17 @@ static int musb_schedule(
head = &musb->in_bulk;
else
head = &musb->out_bulk;
+
+ /* Enable bulk RX NAK timeout scheme when bulk requests are
+ * multiplexed. This scheme doen't work in high speed to full
+ * speed scenario as NAK interrupts are not coming from a
+ * full speed device connected to a high speed device.
+ * NAK timeout interval is 8 (128 uframe or 16ms) for HS and
+ * 4 (8 frame or 8ms) for FS device.
+ */
+ if (is_in && qh->dev)
+ qh->intv_reg =
+ (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4;
goto success;
} else if (best_end < 0) {
return -ENOSPC;
@@ -1768,7 +1819,6 @@ static int musb_schedule(
idle = 1;
qh->mux = 0;
hw_ep = musb->endpoints + best_end;
- musb->periodic[best_end] = qh;
DBG(4, "qh %p periodic slot %d\n", qh, best_end);
success:
if (head) {
@@ -1847,8 +1897,8 @@ static int musb_urb_enqueue(
goto done;
}
- qh->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- qh->type = epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ qh->epnum = usb_endpoint_num(epd);
+ qh->type = usb_endpoint_type(epd);
/* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */
qh->addr_reg = (u8) usb_pipedevice(urb->pipe);
@@ -1867,19 +1917,21 @@ static int musb_urb_enqueue(
}
qh->type_reg = type_reg;
- /* precompute rxinterval/txinterval register */
- interval = min((u8)16, epd->bInterval); /* log encoding */
+ /* Precompute RXINTERVAL/TXINTERVAL register */
switch (qh->type) {
case USB_ENDPOINT_XFER_INT:
- /* fullspeed uses linear encoding */
- if (USB_SPEED_FULL == urb->dev->speed) {
- interval = epd->bInterval;
- if (!interval)
- interval = 1;
+ /*
+ * Full/low speeds use the linear encoding,
+ * high speed uses the logarithmic encoding.
+ */
+ if (urb->dev->speed <= USB_SPEED_FULL) {
+ interval = max_t(u8, epd->bInterval, 1);
+ break;
}
/* FALLTHROUGH */
case USB_ENDPOINT_XFER_ISOC:
- /* iso always uses log encoding */
+ /* ISO always uses logarithmic encoding */
+ interval = min_t(u8, epd->bInterval, 16);
break;
default:
/* REVISIT we actually want to use NAK limits, hinting to the
@@ -1890,13 +1942,11 @@ static int musb_urb_enqueue(
*
* The downside of disabling this is that transfer scheduling
* gets VERY unfair for nonperiodic transfers; a misbehaving
- * peripheral could make that hurt. Or for reads, one that's
- * perfectly normal: network and other drivers keep reads
- * posted at all times, having one pending for a week should
- * be perfectly safe.
+ * peripheral could make that hurt. That's perfectly normal
+ * for reads from network or serial adapters ... so we have
+ * partial NAKlimit support for bulk RX.
*
- * The upside of disabling it is avoidng transfer scheduling
- * code to put this aside for while.
+ * The upside of disabling it is simpler transfer scheduling.
*/
interval = 0;
}
@@ -2037,9 +2087,9 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
goto done;
/* Any URB not actively programmed into endpoint hardware can be
- * immediately given back. Such an URB must be at the head of its
+ * immediately given back; that's any URB not at the head of an
* endpoint queue, unless someday we get real DMA queues. And even
- * then, it might not be known to the hardware...
+ * if it's at the head, it might not be known to the hardware...
*
* Otherwise abort current transfer, pending dma, etc.; urb->status
* has already been updated. This is a synchronous abort; it'd be
@@ -2078,6 +2128,15 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
qh->is_ready = 0;
__musb_giveback(musb, urb, 0);
qh->is_ready = ready;
+
+ /* If nothing else (usually musb_giveback) is using it
+ * and its URB list has emptied, recycle this qh.
+ */
+ if (ready && list_empty(&qh->hep->urb_list)) {
+ qh->hep->hcpriv = NULL;
+ list_del(&qh->ring);
+ kfree(qh);
+ }
} else
ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
done:
@@ -2093,15 +2152,16 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
unsigned long flags;
struct musb *musb = hcd_to_musb(hcd);
u8 is_in = epnum & USB_DIR_IN;
- struct musb_qh *qh = hep->hcpriv;
- struct urb *urb, *tmp;
+ struct musb_qh *qh;
+ struct urb *urb;
struct list_head *sched;
- if (!qh)
- return;
-
spin_lock_irqsave(&musb->lock, flags);
+ qh = hep->hcpriv;
+ if (qh == NULL)
+ goto exit;
+
switch (qh->type) {
case USB_ENDPOINT_XFER_CONTROL:
sched = &musb->control;
@@ -2135,13 +2195,28 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
/* cleanup */
musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
- } else
- urb = NULL;
- /* then just nuke all the others */
- list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list)
- musb_giveback(qh, urb, -ESHUTDOWN);
+ /* Then nuke all the others ... and advance the
+ * queue on hw_ep (e.g. bulk ring) when we're done.
+ */
+ while (!list_empty(&hep->urb_list)) {
+ urb = next_urb(qh);
+ urb->status = -ESHUTDOWN;
+ musb_advance_schedule(musb, urb, qh->hw_ep, is_in);
+ }
+ } else {
+ /* Just empty the queue; the hardware is busy with
+ * other transfers, and since !qh->is_ready nothing
+ * will activate any of these as it advances.
+ */
+ while (!list_empty(&hep->urb_list))
+ __musb_giveback(musb, next_urb(qh), -ESHUTDOWN);
+ hep->hcpriv = NULL;
+ list_del(&qh->ring);
+ kfree(qh);
+ }
+exit:
spin_unlock_irqrestore(&musb->lock, flags);
}
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index e0e9ce584175..bf677acc83db 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -285,7 +285,7 @@ int musb_hub_control(
desc->bDescLength = 9;
desc->bDescriptorType = 0x29;
desc->bNbrPorts = 1;
- desc->wHubCharacteristics = __constant_cpu_to_le16(
+ desc->wHubCharacteristics = cpu_to_le16(
0x0001 /* per-port power switching */
| 0x0010 /* no overcurrent reporting */
);
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 52f7f29cebda..7e073a0d7ac9 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -15,8 +15,8 @@
#include <linux/usb.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <asm/arch/dma.h>
-#include <asm/arch/mux.h>
+#include <mach/dma.h>
+#include <mach/mux.h>
#include "musb_core.h"
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index 8e8dbdb9b39b..aa884d072f0b 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -6,14 +6,14 @@
comment "OTG and related infrastructure"
-if USB || USB_GADGET
-
config USB_OTG_UTILS
bool
help
Select this to make sure the build includes objects from
the OTG infrastructure directory.
+if USB || USB_GADGET
+
#
# USB Transceiver Drivers
#
@@ -43,7 +43,7 @@ config ISP1301_OMAP
config TWL4030_USB
tristate "TWL4030 USB Transceiver Driver"
- depends on TWL4030_CORE
+ depends on TWL4030_CORE && REGULATOR_TWL4030
select USB_OTG_UTILS
help
Enable this to support the USB OTG transceiver on TWL4030
@@ -51,4 +51,12 @@ config TWL4030_USB
This transceiver supports high and full speed devices plus,
in host mode, low speed.
+config NOP_USB_XCEIV
+ tristate "NOP USB Transceiver Driver"
+ select USB_OTG_UTILS
+ help
+ this driver is to be used by all the usb transceiver which are either
+ built-in with usb ip or which are autonomous and doesn't require any
+ phy programming such as ISP1x04 etc.
+
endif # USB || OTG
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile
index d73c7cf5e2f7..208167856529 100644
--- a/drivers/usb/otg/Makefile
+++ b/drivers/usb/otg/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o
obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o
+obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG
ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index 63a6036f04be..1c26c94513e9 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -13,6 +13,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
+#include <linux/workqueue.h>
#include <linux/regulator/consumer.h>
@@ -34,6 +35,7 @@ struct gpio_vbus_data {
struct regulator *vbus_draw;
int vbus_draw_enabled;
unsigned mA;
+ struct work_struct work;
};
@@ -76,24 +78,26 @@ static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA)
gpio_vbus->mA = mA;
}
-/* VBUS change IRQ handler */
-static irqreturn_t gpio_vbus_irq(int irq, void *data)
+static int is_vbus_powered(struct gpio_vbus_mach_info *pdata)
{
- struct platform_device *pdev = data;
- struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
- struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
- int gpio, vbus;
+ int vbus;
vbus = gpio_get_value(pdata->gpio_vbus);
if (pdata->gpio_vbus_inverted)
vbus = !vbus;
- dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n",
- vbus ? "supplied" : "inactive",
- gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none");
+ return vbus;
+}
+
+static void gpio_vbus_work(struct work_struct *work)
+{
+ struct gpio_vbus_data *gpio_vbus =
+ container_of(work, struct gpio_vbus_data, work);
+ struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
+ int gpio;
if (!gpio_vbus->otg.gadget)
- return IRQ_HANDLED;
+ return;
/* Peripheral controllers which manage the pullup themselves won't have
* gpio_pullup configured here. If it's configured here, we'll do what
@@ -101,7 +105,7 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data)
* that may complicate usb_gadget_{,dis}connect() support.
*/
gpio = pdata->gpio_pullup;
- if (vbus) {
+ if (is_vbus_powered(pdata)) {
gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL;
usb_gadget_vbus_connect(gpio_vbus->otg.gadget);
@@ -121,6 +125,21 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data)
usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget);
gpio_vbus->otg.state = OTG_STATE_B_IDLE;
}
+}
+
+/* VBUS change IRQ handler */
+static irqreturn_t gpio_vbus_irq(int irq, void *data)
+{
+ struct platform_device *pdev = data;
+ struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
+ struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
+
+ dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n",
+ is_vbus_powered(pdata) ? "supplied" : "inactive",
+ gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none");
+
+ if (gpio_vbus->otg.gadget)
+ schedule_work(&gpio_vbus->work);
return IRQ_HANDLED;
}
@@ -257,6 +276,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
irq, err);
goto err_irq;
}
+ INIT_WORK(&gpio_vbus->work, gpio_vbus_work);
/* only active when a gadget is registered */
err = otg_set_transceiver(&gpio_vbus->otg);
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
new file mode 100644
index 000000000000..4b933f646f2e
--- /dev/null
+++ b/drivers/usb/otg/nop-usb-xceiv.c
@@ -0,0 +1,180 @@
+/*
+ * drivers/usb/otg/nop-usb-xceiv.c
+ *
+ * NOP USB transceiver for all USB transceiver which are either built-in
+ * into USB IP or which are mostly autonomous.
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Current status:
+ * this is to add "nop" transceiver for all those phy which is
+ * autonomous such as isp1504 etc.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/otg.h>
+
+struct nop_usb_xceiv {
+ struct otg_transceiver otg;
+ struct device *dev;
+};
+
+static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device nop_xceiv_device = {
+ .name = "nop_usb_xceiv",
+ .id = -1,
+ .dev = {
+ .dma_mask = &nop_xceiv_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ .platform_data = NULL,
+ },
+};
+
+void usb_nop_xceiv_register(void)
+{
+ if (platform_device_register(&nop_xceiv_device) < 0) {
+ printk(KERN_ERR "Unable to register usb nop transceiver\n");
+ return;
+ }
+}
+
+void usb_nop_xceiv_unregister(void)
+{
+ platform_device_unregister(&nop_xceiv_device);
+}
+
+static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x)
+{
+ return container_of(x, struct nop_usb_xceiv, otg);
+}
+
+static int nop_set_suspend(struct otg_transceiver *x, int suspend)
+{
+ return 0;
+}
+
+static int nop_set_peripheral(struct otg_transceiver *x,
+ struct usb_gadget *gadget)
+{
+ struct nop_usb_xceiv *nop;
+
+ if (!x)
+ return -ENODEV;
+
+ nop = xceiv_to_nop(x);
+
+ if (!gadget) {
+ nop->otg.gadget = NULL;
+ return -ENODEV;
+ }
+
+ nop->otg.gadget = gadget;
+ nop->otg.state = OTG_STATE_B_IDLE;
+ return 0;
+}
+
+static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host)
+{
+ struct nop_usb_xceiv *nop;
+
+ if (!x)
+ return -ENODEV;
+
+ nop = xceiv_to_nop(x);
+
+ if (!host) {
+ nop->otg.host = NULL;
+ return -ENODEV;
+ }
+
+ nop->otg.host = host;
+ return 0;
+}
+
+static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
+{
+ struct nop_usb_xceiv *nop;
+ int err;
+
+ nop = kzalloc(sizeof *nop, GFP_KERNEL);
+ if (!nop)
+ return -ENOMEM;
+
+ nop->dev = &pdev->dev;
+ nop->otg.dev = nop->dev;
+ nop->otg.label = "nop-xceiv";
+ nop->otg.state = OTG_STATE_UNDEFINED;
+ nop->otg.set_host = nop_set_host;
+ nop->otg.set_peripheral = nop_set_peripheral;
+ nop->otg.set_suspend = nop_set_suspend;
+
+ err = otg_set_transceiver(&nop->otg);
+ if (err) {
+ dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
+ err);
+ goto exit;
+ }
+
+ platform_set_drvdata(pdev, nop);
+
+ return 0;
+exit:
+ kfree(nop);
+ return err;
+}
+
+static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)
+{
+ struct nop_usb_xceiv *nop = platform_get_drvdata(pdev);
+
+ otg_set_transceiver(NULL);
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(nop);
+
+ return 0;
+}
+
+static struct platform_driver nop_usb_xceiv_driver = {
+ .probe = nop_usb_xceiv_probe,
+ .remove = __devexit_p(nop_usb_xceiv_remove),
+ .driver = {
+ .name = "nop_usb_xceiv",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init nop_usb_xceiv_init(void)
+{
+ return platform_driver_register(&nop_usb_xceiv_driver);
+}
+subsys_initcall(nop_usb_xceiv_init);
+
+static void __exit nop_usb_xceiv_exit(void)
+{
+ platform_driver_unregister(&nop_usb_xceiv_driver);
+}
+module_exit(nop_usb_xceiv_exit);
+
+MODULE_ALIAS("platform:nop_usb_xceiv");
+MODULE_AUTHOR("Texas Instruments Inc");
+MODULE_DESCRIPTION("NOP USB Transceiver driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 416e4410be02..d9478d0e1c8b 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -34,6 +34,8 @@
#include <linux/delay.h>
#include <linux/usb/otg.h>
#include <linux/i2c/twl4030.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
/* Register defines */
@@ -246,6 +248,11 @@ struct twl4030_usb {
struct otg_transceiver otg;
struct device *dev;
+ /* TWL4030 internal USB regulator supplies */
+ struct regulator *usb1v5;
+ struct regulator *usb1v8;
+ struct regulator *usb3v1;
+
/* for vbus reporting with irqs disabled */
spinlock_t lock;
@@ -434,6 +441,18 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
if (on) {
+ regulator_enable(twl->usb3v1);
+ regulator_enable(twl->usb1v8);
+ /*
+ * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP
+ * in twl4030) resets the VUSB_DEDICATED2 register. This reset
+ * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to
+ * SLEEP. We work around this by clearing the bit after usv3v1
+ * is re-activated. This ensures that VUSB3V1 is really active.
+ */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0,
+ VUSB_DEDICATED2);
+ regulator_enable(twl->usb1v5);
pwr &= ~PHY_PWR_PHYPWD;
WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
twl4030_usb_write(twl, PHY_CLK_CTRL,
@@ -443,6 +462,9 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on)
} else {
pwr |= PHY_PWR_PHYPWD;
WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0);
+ regulator_disable(twl->usb1v5);
+ regulator_disable(twl->usb1v8);
+ regulator_disable(twl->usb3v1);
}
}
@@ -468,7 +490,7 @@ static void twl4030_phy_resume(struct twl4030_usb *twl)
twl->asleep = 0;
}
-static void twl4030_usb_ldo_init(struct twl4030_usb *twl)
+static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
{
/* Enable writing to power configuration registers */
twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY);
@@ -480,20 +502,45 @@ static void twl4030_usb_ldo_init(struct twl4030_usb *twl)
/* input to VUSB3V1 LDO is from VBAT, not VBUS */
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1);
- /* turn on 3.1V regulator */
- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB3V1_DEV_GRP);
+ /* Initialize 3.1V regulator */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP);
+
+ twl->usb3v1 = regulator_get(twl->dev, "usb3v1");
+ if (IS_ERR(twl->usb3v1))
+ return -ENODEV;
+
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE);
- /* turn on 1.5V regulator */
- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V5_DEV_GRP);
+ /* Initialize 1.5V regulator */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP);
+
+ twl->usb1v5 = regulator_get(twl->dev, "usb1v5");
+ if (IS_ERR(twl->usb1v5))
+ goto fail1;
+
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE);
- /* turn on 1.8V regulator */
- twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V8_DEV_GRP);
+ /* Initialize 1.8V regulator */
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP);
+
+ twl->usb1v8 = regulator_get(twl->dev, "usb1v8");
+ if (IS_ERR(twl->usb1v8))
+ goto fail2;
+
twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE);
/* disable access to power configuration registers */
twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY);
+
+ return 0;
+
+fail2:
+ regulator_put(twl->usb1v5);
+ twl->usb1v5 = NULL;
+fail1:
+ regulator_put(twl->usb3v1);
+ twl->usb3v1 = NULL;
+ return -ENODEV;
}
static ssize_t twl4030_usb_vbus_show(struct device *dev,
@@ -598,7 +645,7 @@ static int __init twl4030_usb_probe(struct platform_device *pdev)
{
struct twl4030_usb_data *pdata = pdev->dev.platform_data;
struct twl4030_usb *twl;
- int status;
+ int status, err;
if (!pdata) {
dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -622,7 +669,12 @@ static int __init twl4030_usb_probe(struct platform_device *pdev)
/* init spinlock for workqueue */
spin_lock_init(&twl->lock);
- twl4030_usb_ldo_init(twl);
+ err = twl4030_usb_ldo_init(twl);
+ if (err) {
+ dev_err(&pdev->dev, "ldo init failed\n");
+ kfree(twl);
+ return err;
+ }
otg_set_transceiver(&twl->otg);
platform_set_drvdata(pdev, twl);
@@ -688,6 +740,9 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev)
twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
twl4030_phy_power(twl, 0);
+ regulator_put(twl->usb1v5);
+ regulator_put(twl->usb1v8);
+ regulator_put(twl->usb3v1);
kfree(twl);
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index b361f05cafac..4afe73e8ec4a 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -472,6 +472,15 @@ config USB_SERIAL_OTI6858
To compile this driver as a module, choose M here: the
module will be called oti6858.
+config USB_SERIAL_QUALCOMM
+ tristate "USB Qualcomm Serial modem"
+ help
+ Say Y here if you have a Qualcomm USB modem device. These are
+ usually wireless cellular modems.
+
+ To compile this driver as a module, choose M here: the
+ module will be called qcserial.
+
config USB_SERIAL_SPCP8X5
tristate "USB SPCP8x5 USB To Serial Driver"
help
@@ -515,6 +524,15 @@ config USB_SERIAL_SIERRAWIRELESS
To compile this driver as a module, choose M here: the
module will be called sierra.
+config USB_SERIAL_SYMBOL
+ tristate "USB Symbol Barcode driver (serial mode)"
+ help
+ Say Y here if you want to use a Symbol USB Barcode device
+ in serial emulation mode.
+
+ To compile this driver as a module, choose M here: the
+ module will be called symbolserial.
+
config USB_SERIAL_TI
tristate "USB TI 3410/5052 Serial Driver"
help
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index b75be91eb8f1..94043babe1d3 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -45,10 +45,12 @@ obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o
obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
+obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o
obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o
obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o
+obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o
obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 537f953bd7f8..6d106e74265e 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -621,9 +621,9 @@ static int __init aircable_init(void)
goto failed_usb_register;
return 0;
-failed_serial_register:
- usb_serial_deregister(&aircable_device);
failed_usb_register:
+ usb_serial_deregister(&aircable_device);
+failed_serial_register:
return retval;
}
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index f61e3ca64305..ab4cc277aa65 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -1,5 +1,7 @@
/*
* Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk>
+ * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de>
+ * Copyright 2009, Boris Hajduk <boris@hajduk.org>
*
* ch341.c implements a serial port driver for the Winchiphead CH341.
*
@@ -21,9 +23,39 @@
#include <linux/usb/serial.h>
#include <linux/serial.h>
-#define DEFAULT_BAUD_RATE 2400
+#define DEFAULT_BAUD_RATE 9600
#define DEFAULT_TIMEOUT 1000
+/* flags for IO-Bits */
+#define CH341_BIT_RTS (1 << 6)
+#define CH341_BIT_DTR (1 << 5)
+
+/******************************/
+/* interrupt pipe definitions */
+/******************************/
+/* always 4 interrupt bytes */
+/* first irq byte normally 0x08 */
+/* second irq byte base 0x7d + below */
+/* third irq byte base 0x94 + below */
+/* fourth irq byte normally 0xee */
+
+/* second interrupt byte */
+#define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */
+
+/* status returned in third interrupt answer byte, inverted in data
+ from irq */
+#define CH341_BIT_CTS 0x01
+#define CH341_BIT_DSR 0x02
+#define CH341_BIT_RI 0x04
+#define CH341_BIT_DCD 0x08
+#define CH341_BITS_MODEM_STAT 0x0f /* all bits */
+
+/*******************************/
+/* baudrate calculation factor */
+/*******************************/
+#define CH341_BAUDBASE_FACTOR 1532620800
+#define CH341_BAUDBASE_DIVMAX 3
+
static int debug;
static struct usb_device_id id_table [] = {
@@ -34,9 +66,12 @@ static struct usb_device_id id_table [] = {
MODULE_DEVICE_TABLE(usb, id_table);
struct ch341_private {
- unsigned baud_rate;
- u8 dtr;
- u8 rts;
+ spinlock_t lock; /* access lock */
+ wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
+ unsigned baud_rate; /* set baud rate */
+ u8 line_control; /* set line control value RTS/DTR */
+ u8 line_status; /* active status of modem control inputs */
+ u8 multi_status_change; /* status changed multiple since last call */
};
static int ch341_control_out(struct usb_device *dev, u8 request,
@@ -72,37 +107,28 @@ static int ch341_set_baudrate(struct usb_device *dev,
{
short a, b;
int r;
+ unsigned long factor;
+ short divisor;
dbg("ch341_set_baudrate(%d)", priv->baud_rate);
- switch (priv->baud_rate) {
- case 2400:
- a = 0xd901;
- b = 0x0038;
- break;
- case 4800:
- a = 0x6402;
- b = 0x001f;
- break;
- case 9600:
- a = 0xb202;
- b = 0x0013;
- break;
- case 19200:
- a = 0xd902;
- b = 0x000d;
- break;
- case 38400:
- a = 0x6403;
- b = 0x000a;
- break;
- case 115200:
- a = 0xcc03;
- b = 0x0008;
- break;
- default:
+
+ if (!priv->baud_rate)
return -EINVAL;
+ factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);
+ divisor = CH341_BAUDBASE_DIVMAX;
+
+ while ((factor > 0xfff0) && divisor) {
+ factor >>= 3;
+ divisor--;
}
+ if (factor > 0xfff0)
+ return -EINVAL;
+
+ factor = 0x10000 - factor;
+ a = (factor & 0xff00) | divisor;
+ b = factor & 0xff;
+
r = ch341_control_out(dev, 0x9a, 0x1312, a);
if (!r)
r = ch341_control_out(dev, 0x9a, 0x0f2c, b);
@@ -110,19 +136,18 @@ static int ch341_set_baudrate(struct usb_device *dev,
return r;
}
-static int ch341_set_handshake(struct usb_device *dev,
- struct ch341_private *priv)
+static int ch341_set_handshake(struct usb_device *dev, u8 control)
{
- dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts);
- return ch341_control_out(dev, 0xa4,
- ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0);
+ dbg("ch341_set_handshake(0x%02x)", control);
+ return ch341_control_out(dev, 0xa4, ~control, 0);
}
-static int ch341_get_status(struct usb_device *dev)
+static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
{
char *buffer;
int r;
const unsigned size = 8;
+ unsigned long flags;
dbg("ch341_get_status()");
@@ -134,10 +159,15 @@ static int ch341_get_status(struct usb_device *dev)
if (r < 0)
goto out;
- /* Not having the datasheet for the CH341, we ignore the bytes returned
- * from the device. Return error if the device did not respond in time.
- */
- r = 0;
+ /* setup the private status if available */
+ if (r == 2) {
+ r = 0;
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT;
+ priv->multi_status_change = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ } else
+ r = -EPROTO;
out: kfree(buffer);
return r;
@@ -180,7 +210,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
goto out;
/* expect 0xff 0xee */
- r = ch341_get_status(dev);
+ r = ch341_get_status(dev, priv);
if (r < 0)
goto out;
@@ -192,12 +222,12 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
if (r < 0)
goto out;
- r = ch341_set_handshake(dev, priv);
+ r = ch341_set_handshake(dev, priv->line_control);
if (r < 0)
goto out;
/* expect 0x9f 0xee */
- r = ch341_get_status(dev);
+ r = ch341_get_status(dev, priv);
out: kfree(buffer);
return r;
@@ -216,9 +246,10 @@ static int ch341_attach(struct usb_serial *serial)
if (!priv)
return -ENOMEM;
+ spin_lock_init(&priv->lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
priv->baud_rate = DEFAULT_BAUD_RATE;
- priv->dtr = 1;
- priv->rts = 1;
+ priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
r = ch341_configure(serial->dev, priv);
if (r < 0)
@@ -231,6 +262,35 @@ error: kfree(priv);
return r;
}
+static void ch341_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ unsigned int c_cflag;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* shutdown our urbs */
+ dbg("%s - shutting down urbs", __func__);
+ usb_kill_urb(port->write_urb);
+ usb_kill_urb(port->read_urb);
+ usb_kill_urb(port->interrupt_in_urb);
+
+ if (tty) {
+ c_cflag = tty->termios->c_cflag;
+ if (c_cflag & HUPCL) {
+ /* drop DTR and RTS */
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_control = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ch341_set_handshake(port->serial->dev, 0);
+ }
+ }
+ wake_up_interruptible(&priv->delta_msr_wait);
+}
+
+
/* open this device, set default parameters */
static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp)
@@ -242,14 +302,13 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
dbg("ch341_open()");
priv->baud_rate = DEFAULT_BAUD_RATE;
- priv->dtr = 1;
- priv->rts = 1;
+ priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
r = ch341_configure(serial->dev, priv);
if (r)
goto out;
- r = ch341_set_handshake(serial->dev, priv);
+ r = ch341_set_handshake(serial->dev, priv->line_control);
if (r)
goto out;
@@ -257,6 +316,16 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
if (r)
goto out;
+ dbg("%s - submitting interrupt urb", __func__);
+ port->interrupt_in_urb->dev = serial->dev;
+ r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+ if (r) {
+ dev_err(&port->dev, "%s - failed submitting interrupt urb,"
+ " error %d\n", __func__, r);
+ ch341_close(tty, port, NULL);
+ return -EPROTO;
+ }
+
r = usb_serial_generic_open(tty, port, filp);
out: return r;
@@ -270,46 +339,224 @@ static void ch341_set_termios(struct tty_struct *tty,
{
struct ch341_private *priv = usb_get_serial_port_data(port);
unsigned baud_rate;
+ unsigned long flags;
dbg("ch341_set_termios()");
+ if (!tty || !tty->termios)
+ return;
+
baud_rate = tty_get_baud_rate(tty);
- switch (baud_rate) {
- case 2400:
- case 4800:
- case 9600:
- case 19200:
- case 38400:
- case 115200:
- priv->baud_rate = baud_rate;
- break;
- default:
- dbg("Rate %d not supported, using %d",
- baud_rate, DEFAULT_BAUD_RATE);
- priv->baud_rate = DEFAULT_BAUD_RATE;
+ priv->baud_rate = baud_rate;
+
+ if (baud_rate) {
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ch341_set_baudrate(port->serial->dev, priv);
+ } else {
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
- ch341_set_baudrate(port->serial->dev, priv);
+ ch341_set_handshake(port->serial->dev, priv->line_control);
/* Unimplemented:
* (cflag & CSIZE) : data bits [5, 8]
* (cflag & PARENB) : parity {NONE, EVEN, ODD}
* (cflag & CSTOPB) : stop bits [1, 2]
*/
+}
+
+static int ch341_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 control;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (set & TIOCM_RTS)
+ priv->line_control |= CH341_BIT_RTS;
+ if (set & TIOCM_DTR)
+ priv->line_control |= CH341_BIT_DTR;
+ if (clear & TIOCM_RTS)
+ priv->line_control &= ~CH341_BIT_RTS;
+ if (clear & TIOCM_DTR)
+ priv->line_control &= ~CH341_BIT_DTR;
+ control = priv->line_control;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return ch341_set_handshake(port->serial->dev, control);
+}
+
+static void ch341_read_int_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+ unsigned char *data = urb->transfer_buffer;
+ unsigned int actual_length = urb->actual_length;
+ int status;
+
+ dbg("%s (%d)", __func__, port->number);
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
+ goto exit;
+ }
- /* Copy back the old hardware settings */
- tty_termios_copy_hw(tty->termios, old_termios);
- /* And re-encode with the new baud */
- tty_encode_baud_rate(tty, baud_rate, baud_rate);
+ usb_serial_debug_data(debug, &port->dev, __func__,
+ urb->actual_length, urb->transfer_buffer);
+
+ if (actual_length >= 4) {
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT;
+ if ((data[1] & CH341_MULT_STAT))
+ priv->multi_status_change = 1;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ wake_up_interruptible(&priv->delta_msr_wait);
+ }
+
+exit:
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status)
+ dev_err(&urb->dev->dev,
+ "%s - usb_submit_urb failed with result %d\n",
+ __func__, status);
+}
+
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 prevstatus;
+ u8 status;
+ u8 changed;
+ u8 multi_change = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ prevstatus = priv->line_status;
+ priv->multi_status_change = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (!multi_change) {
+ interruptible_sleep_on(&priv->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ multi_change = priv->multi_status_change;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ changed = prevstatus ^ status;
+
+ if (((arg & TIOCM_RNG) && (changed & CH341_BIT_RI)) ||
+ ((arg & TIOCM_DSR) && (changed & CH341_BIT_DSR)) ||
+ ((arg & TIOCM_CD) && (changed & CH341_BIT_DCD)) ||
+ ((arg & TIOCM_CTS) && (changed & CH341_BIT_CTS))) {
+ return 0;
+ }
+ prevstatus = status;
+ }
+
+ return 0;
+}
+
+/*static int ch341_ioctl(struct usb_serial_port *port, struct file *file,*/
+static int ch341_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
+
+ switch (cmd) {
+ case TIOCMIWAIT:
+ dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+ return wait_modem_info(port, arg);
+
+ default:
+ dbg("%s not supported = 0x%04x", __func__, cmd);
+ break;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+static int ch341_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ch341_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+ u8 mcr;
+ u8 status;
+ unsigned int result;
+
+ dbg("%s (%d)", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ mcr = priv->line_control;
+ status = priv->line_status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0)
+ | ((mcr & CH341_BIT_RTS) ? TIOCM_RTS : 0)
+ | ((status & CH341_BIT_CTS) ? TIOCM_CTS : 0)
+ | ((status & CH341_BIT_DSR) ? TIOCM_DSR : 0)
+ | ((status & CH341_BIT_RI) ? TIOCM_RI : 0)
+ | ((status & CH341_BIT_DCD) ? TIOCM_CD : 0);
+
+ dbg("%s - result = %x", __func__, result);
+
+ return result;
+}
+
+
+static int ch341_reset_resume(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_serial *serial = NULL;
+ struct ch341_private *priv;
+
+ serial = usb_get_intfdata(intf);
+ priv = usb_get_serial_port_data(serial->port[0]);
+
+ /*reconfigure ch341 serial port after bus-reset*/
+ ch341_configure(dev, priv);
+
+ usb_serial_resume(intf);
+
+ return 0;
}
static struct usb_driver ch341_driver = {
.name = "ch341",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+ .suspend = usb_serial_suspend,
+ .resume = usb_serial_resume,
+ .reset_resume = ch341_reset_resume,
.id_table = id_table,
.no_dynamic_id = 1,
+ .supports_autosuspend = 1,
};
static struct usb_serial_driver ch341_device = {
@@ -317,12 +564,17 @@ static struct usb_serial_driver ch341_device = {
.owner = THIS_MODULE,
.name = "ch341-uart",
},
- .id_table = id_table,
- .usb_driver = &ch341_driver,
- .num_ports = 1,
- .open = ch341_open,
- .set_termios = ch341_set_termios,
- .attach = ch341_attach,
+ .id_table = id_table,
+ .usb_driver = &ch341_driver,
+ .num_ports = 1,
+ .open = ch341_open,
+ .close = ch341_close,
+ .ioctl = ch341_ioctl,
+ .set_termios = ch341_set_termios,
+ .tiocmget = ch341_tiocmget,
+ .tiocmset = ch341_tiocmset,
+ .read_int_callback = ch341_read_int_callback,
+ .attach = ch341_attach,
};
static int __init ch341_init(void)
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index cfaf1f085535..027f4b7dde86 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -85,6 +85,8 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
+ { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
+ { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */
{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
{ USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c70a8f667d85..56f06e9a0597 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -660,6 +660,9 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
+ { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
+ { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -1062,8 +1065,10 @@ static int set_serial_info(struct tty_struct *tty,
if (!capable(CAP_SYS_ADMIN)) {
if (((new_serial.flags & ~ASYNC_USR_MASK) !=
- (priv->flags & ~ASYNC_USR_MASK)))
+ (priv->flags & ~ASYNC_USR_MASK))) {
+ unlock_kernel();
return -EPERM;
+ }
priv->flags = ((priv->flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK));
priv->custom_divisor = new_serial.custom_divisor;
@@ -1928,15 +1933,13 @@ static void ftdi_process_read(struct work_struct *work)
/* Compare new line status to the old one, signal if different/
N.B. packet may be processed more than once, but differences
are only processed once. */
- if (priv != NULL) {
- char new_status = data[packet_offset + 0] &
- FTDI_STATUS_B0_MASK;
- if (new_status != priv->prev_status) {
- priv->diff_status |=
- new_status ^ priv->prev_status;
- wake_up_interruptible(&priv->delta_msr_wait);
- priv->prev_status = new_status;
- }
+ char new_status = data[packet_offset + 0] &
+ FTDI_STATUS_B0_MASK;
+ if (new_status != priv->prev_status) {
+ priv->diff_status |=
+ new_status ^ priv->prev_status;
+ wake_up_interruptible(&priv->delta_msr_wait);
+ priv->prev_status = new_status;
}
length = min(PKTSZ, urb->actual_length-packet_offset)-2;
@@ -2284,11 +2287,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
0, 0,
buf, 1, WDR_TIMEOUT);
- if (ret < 0) {
- dbg("%s Could not get modem status of device - err: %d", __func__,
- ret);
+ if (ret < 0)
return ret;
- }
break;
case FT8U232AM:
case FT232BM:
@@ -2303,15 +2303,11 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
0, priv->interface,
buf, 2, WDR_TIMEOUT);
- if (ret < 0) {
- dbg("%s Could not get modem status of device - err: %d", __func__,
- ret);
+ if (ret < 0)
return ret;
- }
break;
default:
return -EFAULT;
- break;
}
return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 373ee09975bb..e300c840f8ca 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -844,6 +844,9 @@
#define TML_VID 0x1B91 /* Vendor ID */
#define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */
+/* NDI Polaris System */
+#define FTDI_NDI_HUC_PID 0xDA70
+
/* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
@@ -854,6 +857,10 @@
#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */
#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */
+/* Alti-2 products http://www.alti-2.com */
+#define ALTI2_VID 0x1BC9
+#define ALTI2_N3_PID 0x6001 /* Neptune 3 */
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
@@ -881,6 +888,11 @@
#define RATOC_PRODUCT_ID_USB60F 0xb020
/*
+ * DIEBOLD BCS SE923
+ */
+#define DIEBOLD_BCS_SE923_PID 0xfb99
+
+/*
* BmRequestType: 1100 0000b
* bRequest: FTDI_E2_READ
* wValue: 0
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 814909f1ee63..9d57cace3731 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -177,14 +177,6 @@ int usb_serial_generic_resume(struct usb_serial *serial)
struct usb_serial_port *port;
int i, c = 0, r;
-#ifdef CONFIG_PM
- /*
- * If this is an autoresume, don't submit URBs.
- * They will be submitted in the open function instead.
- */
- if (serial->dev->auto_pm)
- return 0;
-#endif
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
if (port->port.count && port->read_urb) {
@@ -196,6 +188,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
return c ? -EIO : 0;
}
+EXPORT_SYMBOL_GPL(usb_serial_generic_resume);
void usb_serial_generic_close(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp)
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 9878c0fb3859..00daa8f7759a 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1507,7 +1507,7 @@ static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
} else {
dev_warn(&serial->interface->dev,
"unsupported endpoint type %x\n",
- ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+ usb_endpoint_type(ep_desc));
usb_free_urb(urb);
return NULL;
}
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index cea326f1f105..839583dc8b6a 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -1,8 +1,8 @@
/*
* Opticon USB barcode to serial driver
*
- * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
- * Copyright (C) 2008 Novell Inc.
+ * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (C) 2008 - 2009 Novell Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
@@ -14,6 +14,7 @@
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
+#include <linux/serial.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
@@ -40,8 +41,12 @@ struct opticon_private {
bool throttled;
bool actually_throttled;
bool rts;
+ int outstanding_urbs;
};
+/* max number of write urbs in flight */
+#define URB_UPPER_LIMIT 4
+
static void opticon_bulk_callback(struct urb *urb)
{
struct opticon_private *priv = urb->context;
@@ -106,7 +111,6 @@ static void opticon_bulk_callback(struct urb *urb)
priv->rts = false;
else
priv->rts = true;
- /* FIXME change the RTS level */
} else {
dev_dbg(&priv->udev->dev,
"Unknown data packet received from the device:"
@@ -188,6 +192,120 @@ static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port,
usb_kill_urb(priv->bulk_read_urb);
}
+static void opticon_write_bulk_callback(struct urb *urb)
+{
+ struct opticon_private *priv = urb->context;
+ int status = urb->status;
+ unsigned long flags;
+
+ /* free up the transfer buffer, as usb_free_urb() does not do this */
+ kfree(urb->transfer_buffer);
+
+ if (status)
+ dbg("%s - nonzero write bulk status received: %d",
+ __func__, status);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ --priv->outstanding_urbs;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ usb_serial_port_softint(priv->port);
+}
+
+static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
+{
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+ struct usb_serial *serial = port->serial;
+ struct urb *urb;
+ unsigned char *buffer;
+ unsigned long flags;
+ int status;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dbg("%s - write limit hit\n", __func__);
+ return 0;
+ }
+ priv->outstanding_urbs++;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ buffer = kmalloc(count, GFP_ATOMIC);
+ if (!buffer) {
+ dev_err(&port->dev, "out of memory\n");
+ count = -ENOMEM;
+ goto error_no_buffer;
+ }
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ dev_err(&port->dev, "no more free urbs\n");
+ count = -ENOMEM;
+ goto error_no_urb;
+ }
+
+ memcpy(buffer, buf, count);
+
+ usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
+
+ usb_fill_bulk_urb(urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
+ port->bulk_out_endpointAddress),
+ buffer, count, opticon_write_bulk_callback, priv);
+
+ /* send it down the pipe */
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status) {
+ dev_err(&port->dev,
+ "%s - usb_submit_urb(write bulk) failed with status = %d\n",
+ __func__, status);
+ count = status;
+ goto error;
+ }
+
+ /* we are done with this urb, so let the host driver
+ * really free it when it is finished with it */
+ usb_free_urb(urb);
+
+ return count;
+error:
+ usb_free_urb(urb);
+error_no_urb:
+ kfree(buffer);
+error_no_buffer:
+ spin_lock_irqsave(&priv->lock, flags);
+ --priv->outstanding_urbs;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return count;
+}
+
+static int opticon_write_room(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /*
+ * We really can take almost anything the user throws at us
+ * but let's pick a nice big number to tell the tty
+ * layer that we have lots of free space, unless we don't.
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dbg("%s - write limit hit\n", __func__);
+ return 0;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 2048;
+}
+
static void opticon_throttle(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
@@ -223,6 +341,67 @@ static void opticon_unthrottle(struct tty_struct *tty)
__func__, result);
}
+static int opticon_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+ int result = 0;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->rts)
+ result = TIOCM_RTS;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ dbg("%s - %x", __func__, result);
+ return result;
+}
+
+static int get_serial_info(struct opticon_private *priv,
+ struct serial_struct __user *serial)
+{
+ struct serial_struct tmp;
+
+ if (!serial)
+ return -EFAULT;
+
+ memset(&tmp, 0x00, sizeof(tmp));
+
+ /* fake emulate a 16550 uart to make userspace code happy */
+ tmp.type = PORT_16550A;
+ tmp.line = priv->serial->minor;
+ tmp.port = 0;
+ tmp.irq = 0;
+ tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+ tmp.xmit_fifo_size = 1024;
+ tmp.baud_base = 9600;
+ tmp.close_delay = 5*HZ;
+ tmp.closing_wait = 30*HZ;
+
+ if (copy_to_user(serial, &tmp, sizeof(*serial)))
+ return -EFAULT;
+ return 0;
+}
+
+static int opticon_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct opticon_private *priv = usb_get_serial_data(port->serial);
+
+ dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+ switch (cmd) {
+ case TIOCGSERIAL:
+ return get_serial_info(priv,
+ (struct serial_struct __user *)arg);
+ }
+
+ return -ENOIOCTLCMD;
+}
+
static int opticon_startup(struct usb_serial *serial)
{
struct opticon_private *priv;
@@ -306,11 +485,37 @@ static void opticon_shutdown(struct usb_serial *serial)
usb_set_serial_data(serial, NULL);
}
+static int opticon_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct usb_serial *serial = usb_get_intfdata(intf);
+ struct opticon_private *priv = usb_get_serial_data(serial);
+
+ usb_kill_urb(priv->bulk_read_urb);
+ return 0;
+}
+
+static int opticon_resume(struct usb_interface *intf)
+{
+ struct usb_serial *serial = usb_get_intfdata(intf);
+ struct opticon_private *priv = usb_get_serial_data(serial);
+ struct usb_serial_port *port = serial->port[0];
+ int result;
+
+ mutex_lock(&port->mutex);
+ if (port->port.count)
+ result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO);
+ else
+ result = 0;
+ mutex_unlock(&port->mutex);
+ return result;
+}
static struct usb_driver opticon_driver = {
.name = "opticon",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+ .suspend = opticon_suspend,
+ .resume = opticon_resume,
.id_table = id_table,
.no_dynamic_id = 1,
};
@@ -326,9 +531,13 @@ static struct usb_serial_driver opticon_device = {
.attach = opticon_startup,
.open = opticon_open,
.close = opticon_close,
+ .write = opticon_write,
+ .write_room = opticon_write_room,
.shutdown = opticon_shutdown,
.throttle = opticon_throttle,
.unthrottle = opticon_unthrottle,
+ .ioctl = opticon_ioctl,
+ .tiocmget = opticon_tiocmget,
};
static int __init opticon_init(void)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5ed183477aaf..5dc4bb3d3b74 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -62,6 +62,8 @@ static int option_tiocmget(struct tty_struct *tty, struct file *file);
static int option_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
+static int option_suspend(struct usb_serial *serial, pm_message_t message);
+static int option_resume(struct usb_serial *serial);
/* Vendor and product IDs */
#define OPTION_VENDOR_ID 0x0AF0
@@ -158,6 +160,13 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define HUAWEI_PRODUCT_E143E 0x143E
#define HUAWEI_PRODUCT_E143F 0x143F
+#define QUANTA_VENDOR_ID 0x0408
+#define QUANTA_PRODUCT_Q101 0xEA02
+#define QUANTA_PRODUCT_Q111 0xEA03
+#define QUANTA_PRODUCT_GLX 0xEA04
+#define QUANTA_PRODUCT_GKE 0xEA05
+#define QUANTA_PRODUCT_GLE 0xEA06
+
#define NOVATELWIRELESS_VENDOR_ID 0x1410
/* YISO PRODUCTS */
@@ -192,14 +201,15 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400
/* FUTURE NOVATEL PRODUCTS */
-#define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000
-#define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000
-#define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000
-#define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000
-#define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001
-#define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001
-#define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001
-#define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001
+#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000
+#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
+#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000
+#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001
+#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000
+#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001
+#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000
+#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001
+#define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001
/* AMOI PRODUCTS */
#define AMOI_VENDOR_ID 0x1614
@@ -209,6 +219,27 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define DELL_VENDOR_ID 0x413C
+/* Dell modems */
+#define DELL_PRODUCT_5700_MINICARD 0x8114
+#define DELL_PRODUCT_5500_MINICARD 0x8115
+#define DELL_PRODUCT_5505_MINICARD 0x8116
+#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117
+#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118
+
+#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128
+#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129
+
+#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133
+#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134
+#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135
+#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136
+#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137
+#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138
+
+#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180
+#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181
+#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182
+
#define KYOCERA_VENDOR_ID 0x0c88
#define KYOCERA_PRODUCT_KPC650 0x17da
#define KYOCERA_PRODUCT_KPC680 0x180a
@@ -224,7 +255,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define ONDA_VENDOR_ID 0x19d2
#define ONDA_PRODUCT_MSA501HS 0x0001
#define ONDA_PRODUCT_ET502HS 0x0002
-#define ONDA_PRODUCT_MT503HS 0x0200
+#define ONDA_PRODUCT_MT503HS 0x2000
#define BANDRICH_VENDOR_ID 0x1A8D
#define BANDRICH_PRODUCT_C100_1 0x1002
@@ -265,13 +296,11 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
/* Ericsson products */
#define ERICSSON_VENDOR_ID 0x0bdb
-#define ERICSSON_PRODUCT_F3507G 0x1900
+#define ERICSSON_PRODUCT_F3507G_1 0x1900
+#define ERICSSON_PRODUCT_F3507G_2 0x1902
-/* Pantech products */
-#define PANTECH_VENDOR_ID 0x106c
-#define PANTECH_PRODUCT_PC5740 0x3701
-#define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */
-#define PANTECH_PRODUCT_UM150 0x3711
+#define BENQ_VENDOR_ID 0x04a5
+#define BENQ_PRODUCT_H10 0x4068
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -298,6 +327,11 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
@@ -383,31 +417,37 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) },
- { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
- { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
+ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
@@ -475,10 +515,10 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
- { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) },
- { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) },
- { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) },
- { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) },
+ { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_1) },
+ { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_2) },
+ { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
+ { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
@@ -487,6 +527,8 @@ static struct usb_driver option_driver = {
.name = "option",
.probe = usb_serial_probe,
.disconnect = usb_serial_disconnect,
+ .suspend = usb_serial_suspend,
+ .resume = usb_serial_resume,
.id_table = option_ids,
.no_dynamic_id = 1,
};
@@ -515,6 +557,8 @@ static struct usb_serial_driver option_1port_device = {
.attach = option_startup,
.shutdown = option_shutdown,
.read_int_callback = option_instat_callback,
+ .suspend = option_suspend,
+ .resume = option_resume,
};
static int debug;
@@ -785,10 +829,10 @@ static void option_instat_callback(struct urb *urb)
req_pkt->bRequestType, req_pkt->bRequest);
}
} else
- dbg("%s: error %d", __func__, status);
+ err("%s: error %d", __func__, status);
/* Resubmit urb so we continue receiving IRQ data */
- if (status != -ESHUTDOWN) {
+ if (status != -ESHUTDOWN && status != -ENOENT) {
urb->dev = serial->dev;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
@@ -807,7 +851,6 @@ static int option_write_room(struct tty_struct *tty)
portdata = usb_get_serial_port_data(port);
-
for (i = 0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i];
if (this_urb && !test_bit(i, &portdata->out_busy))
@@ -1069,14 +1112,12 @@ bail_out_error:
return 1;
}
-static void option_shutdown(struct usb_serial *serial)
+static void stop_read_write_urbs(struct usb_serial *serial)
{
int i, j;
struct usb_serial_port *port;
struct option_port_private *portdata;
- dbg("%s", __func__);
-
/* Stop reading/writing urbs */
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
@@ -1086,6 +1127,17 @@ static void option_shutdown(struct usb_serial *serial)
for (j = 0; j < N_OUT_URB; j++)
usb_kill_urb(portdata->out_urbs[j]);
}
+}
+
+static void option_shutdown(struct usb_serial *serial)
+{
+ int i, j;
+ struct usb_serial_port *port;
+ struct option_port_private *portdata;
+
+ dbg("%s", __func__);
+
+ stop_read_write_urbs(serial);
/* Now free them */
for (i = 0; i < serial->num_ports; ++i) {
@@ -1116,6 +1168,66 @@ static void option_shutdown(struct usb_serial *serial)
}
}
+static int option_suspend(struct usb_serial *serial, pm_message_t message)
+{
+ dbg("%s entered", __func__);
+ stop_read_write_urbs(serial);
+
+ return 0;
+}
+
+static int option_resume(struct usb_serial *serial)
+{
+ int err, i, j;
+ struct usb_serial_port *port;
+ struct urb *urb;
+ struct option_port_private *portdata;
+
+ dbg("%s entered", __func__);
+ /* get the interrupt URBs resubmitted unconditionally */
+ for (i = 0; i < serial->num_ports; i++) {
+ port = serial->port[i];
+ if (!port->interrupt_in_urb) {
+ dbg("%s: No interrupt URB for port %d\n", __func__, i);
+ continue;
+ }
+ port->interrupt_in_urb->dev = serial->dev;
+ err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
+ dbg("Submitted interrupt URB for port %d (result %d)", i, err);
+ if (err < 0) {
+ err("%s: Error %d for interrupt URB of port%d",
+ __func__, err, i);
+ return err;
+ }
+ }
+
+ for (i = 0; i < serial->num_ports; i++) {
+ /* walk all ports */
+ port = serial->port[i];
+ portdata = usb_get_serial_port_data(port);
+ mutex_lock(&port->mutex);
+
+ /* skip closed ports */
+ if (!port->port.count) {
+ mutex_unlock(&port->mutex);
+ continue;
+ }
+
+ for (j = 0; j < N_IN_URB; j++) {
+ urb = portdata->in_urbs[j];
+ err = usb_submit_urb(urb, GFP_NOIO);
+ if (err < 0) {
+ mutex_unlock(&port->mutex);
+ err("%s: Error %d for bulk URB %d",
+ __func__, err, i);
+ return err;
+ }
+ }
+ mutex_unlock(&port->mutex);
+ }
+ return 0;
+}
+
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
new file mode 100644
index 000000000000..6c6add50feaa
--- /dev/null
+++ b/drivers/usb/serial/qcserial.c
@@ -0,0 +1,145 @@
+/*
+ * Qualcomm Serial USB driver
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated.
+ * Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (c) 2009 Novell Inc.
+ *
+ * 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/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+#define DRIVER_AUTHOR "Qualcomm Inc"
+#define DRIVER_DESC "Qualcomm USB Serial driver"
+
+static int debug;
+
+static struct usb_device_id id_table[] = {
+ {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */
+ {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver qcdriver = {
+ .name = "qcserial",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+ .suspend = usb_serial_suspend,
+ .resume = usb_serial_resume,
+ .supports_autosuspend = true,
+};
+
+static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
+{
+ int retval = -ENODEV;
+ __u8 nintf;
+ __u8 ifnum;
+
+ dbg("%s", __func__);
+
+ nintf = serial->dev->actconfig->desc.bNumInterfaces;
+ dbg("Num Interfaces = %d", nintf);
+ ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
+ dbg("This Interface = %d", ifnum);
+
+ switch (nintf) {
+ case 1:
+ /* QDL mode */
+ if (serial->interface->num_altsetting == 2) {
+ struct usb_host_interface *intf;
+
+ intf = &serial->interface->altsetting[1];
+ if (intf->desc.bNumEndpoints == 2) {
+ if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
+ usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
+ dbg("QDL port found");
+ retval = usb_set_interface(serial->dev, ifnum, 1);
+ if (retval < 0) {
+ dev_err(&serial->dev->dev,
+ "Could not set interface, error %d\n",
+ retval);
+ retval = -ENODEV;
+ }
+ return retval;
+ }
+ }
+ }
+ break;
+
+ case 4:
+ /* Composite mode */
+ if (ifnum == 2) {
+ dbg("Modem port found");
+ retval = usb_set_interface(serial->dev, ifnum, 0);
+ if (retval < 0) {
+ dev_err(&serial->dev->dev,
+ "Could not set interface, error %d\n",
+ retval);
+ retval = -ENODEV;
+ }
+ return retval;
+ }
+ break;
+
+ default:
+ dev_err(&serial->dev->dev,
+ "unknown number of interfaces: %d\n", nintf);
+ return -ENODEV;
+ }
+
+ return retval;
+}
+
+static struct usb_serial_driver qcdevice = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "qcserial",
+ },
+ .description = "Qualcomm USB modem",
+ .id_table = id_table,
+ .usb_driver = &qcdriver,
+ .num_ports = 1,
+ .probe = qcprobe,
+};
+
+static int __init qcinit(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&qcdevice);
+ if (retval)
+ return retval;
+
+ retval = usb_register(&qcdriver);
+ if (retval) {
+ usb_serial_deregister(&qcdevice);
+ return retval;
+ }
+
+ return 0;
+}
+
+static void __exit qcexit(void)
+{
+ usb_deregister(&qcdriver);
+ usb_serial_deregister(&qcdevice);
+}
+
+module_init(qcinit);
+module_exit(qcexit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL v2");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
new file mode 100644
index 000000000000..c5990fd88e2c
--- /dev/null
+++ b/drivers/usb/serial/symbolserial.c
@@ -0,0 +1,340 @@
+/*
+ * Symbol USB barcode to serial driver
+ *
+ * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (C) 2009 Novell Inc.
+ *
+ * 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/init.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <linux/uaccess.h>
+
+static int debug;
+
+static struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x05e0, 0x0600) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* This structure holds all of the individual device information */
+struct symbol_private {
+ struct usb_device *udev;
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ unsigned char *int_buffer;
+ struct urb *int_urb;
+ int buffer_size;
+ u8 bInterval;
+ u8 int_address;
+ spinlock_t lock; /* protects the following flags */
+ bool throttled;
+ bool actually_throttled;
+ bool rts;
+};
+
+static void symbol_int_callback(struct urb *urb)
+{
+ struct symbol_private *priv = urb->context;
+ unsigned char *data = urb->transfer_buffer;
+ struct usb_serial_port *port = priv->port;
+ int status = urb->status;
+ struct tty_struct *tty;
+ int result;
+ int available_room = 0;
+ int data_length;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ switch (status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d",
+ __func__, status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d",
+ __func__, status);
+ goto exit;
+ }
+
+ usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length,
+ data);
+
+ if (urb->actual_length > 1) {
+ data_length = urb->actual_length - 1;
+
+ /*
+ * Data from the device comes with a 1 byte header:
+ *
+ * <size of data>data...
+ * This is real data to be sent to the tty layer
+ * we pretty much just ignore the size and send everything
+ * else to the tty layer.
+ */
+ tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ available_room = tty_buffer_request_room(tty,
+ data_length);
+ if (available_room) {
+ tty_insert_flip_string(tty, &data[1],
+ available_room);
+ tty_flip_buffer_push(tty);
+ }
+ tty_kref_put(tty);
+ }
+ } else {
+ dev_dbg(&priv->udev->dev,
+ "Improper ammount of data received from the device, "
+ "%d bytes", urb->actual_length);
+ }
+
+exit:
+ spin_lock(&priv->lock);
+
+ /* Continue trying to always read if we should */
+ if (!priv->throttled) {
+ usb_fill_int_urb(priv->int_urb, priv->udev,
+ usb_rcvintpipe(priv->udev,
+ priv->int_address),
+ priv->int_buffer, priv->buffer_size,
+ symbol_int_callback, priv, priv->bInterval);
+ result = usb_submit_urb(priv->int_urb, GFP_ATOMIC);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ } else
+ priv->actually_throttled = true;
+ spin_unlock(&priv->lock);
+}
+
+static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+ int result = 0;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->throttled = false;
+ priv->actually_throttled = false;
+ priv->port = port;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /*
+ * Force low_latency on so that our tty_push actually forces the data
+ * through, otherwise it is scheduled, and with high data rates (like
+ * with OHCI) data can get lost.
+ */
+ if (tty)
+ tty->low_latency = 1;
+
+ /* Start reading from the device */
+ usb_fill_int_urb(priv->int_urb, priv->udev,
+ usb_rcvintpipe(priv->udev, priv->int_address),
+ priv->int_buffer, priv->buffer_size,
+ symbol_int_callback, priv, priv->bInterval);
+ result = usb_submit_urb(priv->int_urb, GFP_KERNEL);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ return result;
+}
+
+static void symbol_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* shutdown our urbs */
+ usb_kill_urb(priv->int_urb);
+}
+
+static void symbol_throttle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+
+ dbg("%s - port %d", __func__, port->number);
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->throttled = true;
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void symbol_unthrottle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct symbol_private *priv = usb_get_serial_data(port->serial);
+ unsigned long flags;
+ int result;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->throttled = false;
+ priv->actually_throttled = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ priv->int_urb->dev = port->serial->dev;
+ result = usb_submit_urb(priv->int_urb, GFP_ATOMIC);
+ if (result)
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
+}
+
+static int symbol_startup(struct usb_serial *serial)
+{
+ struct symbol_private *priv;
+ struct usb_host_interface *intf;
+ int i;
+ int retval = -ENOMEM;
+ bool int_in_found = false;
+
+ /* create our private serial structure */
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (priv == NULL) {
+ dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+ return -ENOMEM;
+ }
+ spin_lock_init(&priv->lock);
+ priv->serial = serial;
+ priv->port = serial->port[0];
+ priv->udev = serial->dev;
+
+ /* find our interrupt endpoint */
+ intf = serial->interface->altsetting;
+ for (i = 0; i < intf->desc.bNumEndpoints; ++i) {
+ struct usb_endpoint_descriptor *endpoint;
+
+ endpoint = &intf->endpoint[i].desc;
+ if (!usb_endpoint_is_int_in(endpoint))
+ continue;
+
+ priv->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!priv->int_urb) {
+ dev_err(&priv->udev->dev, "out of memory\n");
+ goto error;
+ }
+
+ priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2;
+ priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL);
+ if (!priv->int_buffer) {
+ dev_err(&priv->udev->dev, "out of memory\n");
+ goto error;
+ }
+
+ priv->int_address = endpoint->bEndpointAddress;
+ priv->bInterval = endpoint->bInterval;
+
+ /* set up our int urb */
+ usb_fill_int_urb(priv->int_urb, priv->udev,
+ usb_rcvintpipe(priv->udev,
+ endpoint->bEndpointAddress),
+ priv->int_buffer, priv->buffer_size,
+ symbol_int_callback, priv, priv->bInterval);
+
+ int_in_found = true;
+ break;
+ }
+
+ if (!int_in_found) {
+ dev_err(&priv->udev->dev,
+ "Error - the proper endpoints were not found!\n");
+ goto error;
+ }
+
+ usb_set_serial_data(serial, priv);
+ return 0;
+
+error:
+ usb_free_urb(priv->int_urb);
+ kfree(priv->int_buffer);
+ kfree(priv);
+ return retval;
+}
+
+static void symbol_shutdown(struct usb_serial *serial)
+{
+ struct symbol_private *priv = usb_get_serial_data(serial);
+
+ dbg("%s", __func__);
+
+ usb_kill_urb(priv->int_urb);
+ usb_free_urb(priv->int_urb);
+ kfree(priv->int_buffer);
+ kfree(priv);
+ usb_set_serial_data(serial, NULL);
+}
+
+static struct usb_driver symbol_driver = {
+ .name = "symbol",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+ .no_dynamic_id = 1,
+};
+
+static struct usb_serial_driver symbol_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "symbol",
+ },
+ .id_table = id_table,
+ .usb_driver = &symbol_driver,
+ .num_ports = 1,
+ .attach = symbol_startup,
+ .open = symbol_open,
+ .close = symbol_close,
+ .shutdown = symbol_shutdown,
+ .throttle = symbol_throttle,
+ .unthrottle = symbol_unthrottle,
+};
+
+static int __init symbol_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&symbol_device);
+ if (retval)
+ return retval;
+ retval = usb_register(&symbol_driver);
+ if (retval)
+ usb_serial_deregister(&symbol_device);
+ return retval;
+}
+
+static void __exit symbol_exit(void)
+{
+ usb_deregister(&symbol_driver);
+ usb_serial_deregister(&symbol_device);
+}
+
+module_init(symbol_init);
+module_exit(symbol_exit);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 3cf41df302d7..2620bf6fe5e1 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -176,7 +176,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -184,16 +184,20 @@ static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -205,6 +209,9 @@ static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] =
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
{ }
};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index 7e4752fbf232..f323c6025858 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -27,7 +27,11 @@
/* Vendor and product ids */
#define TI_VENDOR_ID 0x0451
+#define IBM_VENDOR_ID 0x04b3
#define TI_3410_PRODUCT_ID 0x3410
+#define IBM_4543_PRODUCT_ID 0x4543
+#define IBM_454B_PRODUCT_ID 0x454b
+#define IBM_454C_PRODUCT_ID 0x454c
#define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */
#define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */
#define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index cfcfd5ab06ce..742a5bc44be8 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -204,6 +204,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
goto bailout_kref_put;
}
+ if (port->serial->disconnected) {
+ retval = -ENODEV;
+ goto bailout_kref_put;
+ }
+
if (mutex_lock_interruptible(&port->mutex)) {
retval = -ERESTARTSYS;
goto bailout_kref_put;
@@ -1067,6 +1072,8 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
struct usb_serial_port *port;
int i, r = 0;
+ serial->suspending = 1;
+
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port)
@@ -1083,10 +1090,15 @@ EXPORT_SYMBOL(usb_serial_suspend);
int usb_serial_resume(struct usb_interface *intf)
{
struct usb_serial *serial = usb_get_intfdata(intf);
+ int rv;
+ serial->suspending = 0;
if (serial->type->resume)
- return serial->type->resume(serial);
- return 0;
+ rv = serial->type->resume(serial);
+ else
+ rv = usb_serial_generic_resume(serial);
+
+ return rv;
}
EXPORT_SYMBOL(usb_serial_resume);
@@ -1222,7 +1234,6 @@ static void fixup_generic(struct usb_serial_driver *device)
set_to_generic_if_null(device, read_bulk_callback);
set_to_generic_if_null(device, write_bulk_callback);
set_to_generic_if_null(device, shutdown);
- set_to_generic_if_null(device, resume);
}
int usb_serial_register(struct usb_serial_driver *driver)
@@ -1230,6 +1241,9 @@ int usb_serial_register(struct usb_serial_driver *driver)
/* must be called with BKL held */
int retval;
+ if (usb_disabled())
+ return -ENODEV;
+
fixup_generic(driver);
if (!driver->description)
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 9df6887b91f6..8a372bac0e43 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -2,8 +2,8 @@
# USB Storage driver configuration
#
-comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;"
-comment "see USB_STORAGE Help for more information"
+comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may"
+comment "also be needed; see USB_STORAGE Help for more info"
depends on USB
config USB_STORAGE
@@ -32,21 +32,25 @@ config USB_STORAGE_DEBUG
verbose debugging messages.
config USB_STORAGE_DATAFAB
- bool "Datafab Compact Flash Reader support"
+ tristate "Datafab Compact Flash Reader support"
depends on USB_STORAGE
help
Support for certain Datafab CompactFlash readers.
Datafab has a web page at <http://www.datafabusa.com/>.
+ If this driver is compiled as a module, it will be named ums-datafab.
+
config USB_STORAGE_FREECOM
- bool "Freecom USB/ATAPI Bridge support"
+ tristate "Freecom USB/ATAPI Bridge support"
depends on USB_STORAGE
help
Support for the Freecom USB to IDE/ATAPI adaptor.
Freecom has a web page at <http://www.freecom.de/>.
+ If this driver is compiled as a module, it will be named ums-freecom.
+
config USB_STORAGE_ISD200
- bool "ISD-200 USB/ATA Bridge support"
+ tristate "ISD-200 USB/ATA Bridge support"
depends on USB_STORAGE
---help---
Say Y here if you want to use USB Mass Store devices based
@@ -61,8 +65,10 @@ config USB_STORAGE_ISD200
- CyQ've CQ8060A CDRW drive
- Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U)
+ If this driver is compiled as a module, it will be named ums-isd200.
+
config USB_STORAGE_USBAT
- bool "USBAT/USBAT02-based storage support"
+ tristate "USBAT/USBAT02-based storage support"
depends on USB_STORAGE
help
Say Y here to include additional code to support storage devices
@@ -82,30 +88,38 @@ config USB_STORAGE_USBAT
- RCA LYRA MP3 portable
- Sandisk ImageMate SDDR-05b
+ If this driver is compiled as a module, it will be named ums-usbat.
+
config USB_STORAGE_SDDR09
- bool "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support"
+ tristate "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Sandisk SDDR-09
SmartMedia reader in the USB Mass Storage driver.
Also works for the Microtech Zio! CompactFlash/SmartMedia reader.
+ If this driver is compiled as a module, it will be named ums-sddr09.
+
config USB_STORAGE_SDDR55
- bool "SanDisk SDDR-55 SmartMedia support"
+ tristate "SanDisk SDDR-55 SmartMedia support"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Sandisk SDDR-55
SmartMedia reader in the USB Mass Storage driver.
+ If this driver is compiled as a module, it will be named ums-sddr55.
+
config USB_STORAGE_JUMPSHOT
- bool "Lexar Jumpshot Compact Flash Reader"
+ tristate "Lexar Jumpshot Compact Flash Reader"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Lexar Jumpshot
USB CompactFlash reader.
+ If this driver is compiled as a module, it will be named ums-jumpshot.
+
config USB_STORAGE_ALAUDA
- bool "Olympus MAUSB-10/Fuji DPC-R1 support"
+ tristate "Olympus MAUSB-10/Fuji DPC-R1 support"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Olympus MAUSB-10
@@ -114,8 +128,10 @@ config USB_STORAGE_ALAUDA
These devices are based on the Alauda chip and support both
XD and SmartMedia cards.
+ If this driver is compiled as a module, it will be named ums-alauda.
+
config USB_STORAGE_ONETOUCH
- bool "Support OneTouch Button on Maxtor Hard Drives"
+ tristate "Support OneTouch Button on Maxtor Hard Drives"
depends on USB_STORAGE
depends on INPUT=y || INPUT=USB_STORAGE
help
@@ -127,8 +143,10 @@ config USB_STORAGE_ONETOUCH
this input in any keybinding software. (e.g. gnome's keyboard short-
cuts)
+ If this driver is compiled as a module, it will be named ums-onetouch.
+
config USB_STORAGE_KARMA
- bool "Support for Rio Karma music player"
+ tristate "Support for Rio Karma music player"
depends on USB_STORAGE
help
Say Y here to include additional code to support the Rio Karma
@@ -139,8 +157,10 @@ config USB_STORAGE_KARMA
on the resulting scsi device node returns the Karma to normal
operation.
+ If this driver is compiled as a module, it will be named ums-karma.
+
config USB_STORAGE_CYPRESS_ATACB
- bool "SAT emulation on Cypress USB/ATA Bridge with ATACB"
+ tristate "SAT emulation on Cypress USB/ATA Bridge with ATACB"
depends on USB_STORAGE
---help---
Say Y here if you want to use SAT (ata pass through) on devices based
@@ -150,6 +170,8 @@ config USB_STORAGE_CYPRESS_ATACB
If you say no here your device will still work with the standard usb
mass storage class.
+ If this driver is compiled as a module, it will be named ums-cypress.
+
config USB_LIBUSUAL
bool "The shared table of common (or usual) storage devices"
depends on USB
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index b32069313390..5be54c019662 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -10,21 +10,36 @@ EXTRA_CFLAGS := -Idrivers/scsi
obj-$(CONFIG_USB_STORAGE) += usb-storage.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_USBAT) += shuttle_usbat.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y)
-ifneq ($(CONFIG_USB_LIBUSUAL),)
- obj-$(CONFIG_USB) += libusual.o
+ifeq ($(CONFIG_USB_LIBUSUAL),)
+ usb-storage-objs += usual-tables.o
+else
+ obj-$(CONFIG_USB) += libusual.o usual-tables.o
endif
+
+obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o
+obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o
+obj-$(CONFIG_USB_STORAGE_DATAFAB) += ums-datafab.o
+obj-$(CONFIG_USB_STORAGE_FREECOM) += ums-freecom.o
+obj-$(CONFIG_USB_STORAGE_ISD200) += ums-isd200.o
+obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += ums-jumpshot.o
+obj-$(CONFIG_USB_STORAGE_KARMA) += ums-karma.o
+obj-$(CONFIG_USB_STORAGE_ONETOUCH) += ums-onetouch.o
+obj-$(CONFIG_USB_STORAGE_SDDR09) += ums-sddr09.o
+obj-$(CONFIG_USB_STORAGE_SDDR55) += ums-sddr55.o
+obj-$(CONFIG_USB_STORAGE_USBAT) += ums-usbat.o
+
+ums-alauda-objs := alauda.o
+ums-cypress-objs := cypress_atacb.o
+ums-datafab-objs := datafab.o
+ums-freecom-objs := freecom.o
+ums-isd200-objs := isd200.o
+ums-jumpshot-objs := jumpshot.o
+ums-karma-objs := karma.o
+ums-onetouch-objs := onetouch.o
+ums-sddr09-objs := sddr09.o
+ums-sddr55-objs := sddr55.o
+ums-usbat-objs := shuttle_usbat.o
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 8d3711a7ff06..d3a88ebe690b 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -31,6 +31,8 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/module.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
@@ -39,7 +41,75 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "alauda.h"
+
+/*
+ * Status bytes
+ */
+#define ALAUDA_STATUS_ERROR 0x01
+#define ALAUDA_STATUS_READY 0x40
+
+/*
+ * Control opcodes (for request field)
+ */
+#define ALAUDA_GET_XD_MEDIA_STATUS 0x08
+#define ALAUDA_GET_SM_MEDIA_STATUS 0x98
+#define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a
+#define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a
+#define ALAUDA_GET_XD_MEDIA_SIG 0x86
+#define ALAUDA_GET_SM_MEDIA_SIG 0x96
+
+/*
+ * Bulk command identity (byte 0)
+ */
+#define ALAUDA_BULK_CMD 0x40
+
+/*
+ * Bulk opcodes (byte 1)
+ */
+#define ALAUDA_BULK_GET_REDU_DATA 0x85
+#define ALAUDA_BULK_READ_BLOCK 0x94
+#define ALAUDA_BULK_ERASE_BLOCK 0xa3
+#define ALAUDA_BULK_WRITE_BLOCK 0xb4
+#define ALAUDA_BULK_GET_STATUS2 0xb7
+#define ALAUDA_BULK_RESET_MEDIA 0xe0
+
+/*
+ * Port to operate on (byte 8)
+ */
+#define ALAUDA_PORT_XD 0x00
+#define ALAUDA_PORT_SM 0x01
+
+/*
+ * LBA and PBA are unsigned ints. Special values.
+ */
+#define UNDEF 0xffff
+#define SPARE 0xfffe
+#define UNUSABLE 0xfffd
+
+struct alauda_media_info {
+ unsigned long capacity; /* total media size in bytes */
+ unsigned int pagesize; /* page size in bytes */
+ unsigned int blocksize; /* number of pages per block */
+ unsigned int uzonesize; /* number of usable blocks per zone */
+ unsigned int zonesize; /* number of blocks per zone */
+ unsigned int blockmask; /* mask to get page from address */
+
+ unsigned char pageshift;
+ unsigned char blockshift;
+ unsigned char zoneshift;
+
+ u16 **lba_to_pba; /* logical to physical block map */
+ u16 **pba_to_lba; /* physical to logical block map */
+};
+
+struct alauda_info {
+ struct alauda_media_info port[2];
+ int wr_ep; /* endpoint to write data out of */
+
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
#define LSB_of(s) ((s)&0xFF)
@@ -52,6 +122,48 @@
#define PBA_HI(pba) (pba >> 3)
#define PBA_ZONE(pba) (pba >> 11)
+static int init_alauda(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id alauda_usb_ids[] = {
+# include "unusual_alauda.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, alauda_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev alauda_unusual_dev_list[] = {
+# include "unusual_alauda.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
/*
* Media handling
*/
@@ -307,7 +419,8 @@ static int alauda_init_media(struct us_data *us)
data[0], data[1], data[2], data[3]);
media_info = alauda_card_find_id(data[1]);
if (media_info == NULL) {
- printk("alauda_init_media: Unrecognised media signature: "
+ printk(KERN_WARNING
+ "alauda_init_media: Unrecognised media signature: "
"%02X %02X %02X %02X\n",
data[0], data[1], data[2], data[3]);
return USB_STOR_TRANSPORT_ERROR;
@@ -518,7 +631,8 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
/* check even parity */
if (parity[data[6] ^ data[7]]) {
- printk("alauda_read_map: Bad parity in LBA for block %d"
+ printk(KERN_WARNING
+ "alauda_read_map: Bad parity in LBA for block %d"
" (%02X %02X)\n", i, data[6], data[7]);
pba_to_lba[i] = UNUSABLE;
continue;
@@ -538,13 +652,16 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
*/
if (lba_offset >= uzonesize) {
- printk("alauda_read_map: Bad low LBA %d for block %d\n",
+ printk(KERN_WARNING
+ "alauda_read_map: Bad low LBA %d for block %d\n",
lba_real, blocknum);
continue;
}
if (lba_to_pba[lba_offset] != UNDEF) {
- printk("alauda_read_map: LBA %d seen for PBA %d and %d\n",
+ printk(KERN_WARNING
+ "alauda_read_map: "
+ "LBA %d seen for PBA %d and %d\n",
lba_real, lba_to_pba[lba_offset], blocknum);
continue;
}
@@ -712,13 +829,15 @@ static int alauda_write_lba(struct us_data *us, u16 lba,
if (pba == 1) {
/* Maybe it is impossible to write to PBA 1.
Fake success, but don't do anything. */
- printk("alauda_write_lba: avoid writing to pba 1\n");
+ printk(KERN_WARNING
+ "alauda_write_lba: avoid writing to pba 1\n");
return USB_STOR_TRANSPORT_GOOD;
}
new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
if (!new_pba) {
- printk("alauda_write_lba: Out of unused blocks\n");
+ printk(KERN_WARNING
+ "alauda_write_lba: Out of unused blocks\n");
return USB_STOR_TRANSPORT_ERROR;
}
@@ -818,7 +937,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
len = min(sectors, blocksize) * (pagesize + 64);
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("alauda_read_data: Out of memory\n");
+ printk(KERN_WARNING "alauda_read_data: Out of memory\n");
return USB_STOR_TRANSPORT_ERROR;
}
@@ -911,7 +1030,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
len = min(sectors, blocksize) * pagesize;
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("alauda_write_data: Out of memory\n");
+ printk(KERN_WARNING "alauda_write_data: Out of memory\n");
return USB_STOR_TRANSPORT_ERROR;
}
@@ -921,7 +1040,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
*/
blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
if (blockbuffer == NULL) {
- printk("alauda_write_data: Out of memory\n");
+ printk(KERN_WARNING "alauda_write_data: Out of memory\n");
kfree(buffer);
return USB_STOR_TRANSPORT_ERROR;
}
@@ -991,7 +1110,7 @@ static void alauda_info_destructor(void *extra)
/*
* Initialize alauda_info struct and find the data-write endpoint
*/
-int init_alauda(struct us_data *us)
+static int init_alauda(struct us_data *us)
{
struct alauda_info *info;
struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
@@ -1013,7 +1132,7 @@ int init_alauda(struct us_data *us)
return USB_STOR_TRANSPORT_GOOD;
}
-int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int rc;
struct alauda_info *info = (struct alauda_info *) us->extra;
@@ -1121,3 +1240,48 @@ int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
return USB_STOR_TRANSPORT_FAILED;
}
+static int alauda_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - alauda_usb_ids) + alauda_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Alauda Control/Bulk";
+ us->transport = alauda_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver alauda_driver = {
+ .name = "ums-alauda",
+ .probe = alauda_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = alauda_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init alauda_init(void)
+{
+ return usb_register(&alauda_driver);
+}
+
+static void __exit alauda_exit(void)
+{
+ usb_deregister(&alauda_driver);
+}
+
+module_init(alauda_init);
+module_exit(alauda_exit);
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h
deleted file mode 100644
index a700f87d0803..000000000000
--- a/drivers/usb/storage/alauda.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Driver for Alauda-based card readers
- *
- * Current development and maintenance by:
- * (c) 2005 Daniel Drake <dsd@gentoo.org>
- *
- * See alauda.c for more explanation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_ALAUDA_H
-#define _USB_ALAUDA_H
-
-/*
- * Status bytes
- */
-#define ALAUDA_STATUS_ERROR 0x01
-#define ALAUDA_STATUS_READY 0x40
-
-/*
- * Control opcodes (for request field)
- */
-#define ALAUDA_GET_XD_MEDIA_STATUS 0x08
-#define ALAUDA_GET_SM_MEDIA_STATUS 0x98
-#define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a
-#define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a
-#define ALAUDA_GET_XD_MEDIA_SIG 0x86
-#define ALAUDA_GET_SM_MEDIA_SIG 0x96
-
-/*
- * Bulk command identity (byte 0)
- */
-#define ALAUDA_BULK_CMD 0x40
-
-/*
- * Bulk opcodes (byte 1)
- */
-#define ALAUDA_BULK_GET_REDU_DATA 0x85
-#define ALAUDA_BULK_READ_BLOCK 0x94
-#define ALAUDA_BULK_ERASE_BLOCK 0xa3
-#define ALAUDA_BULK_WRITE_BLOCK 0xb4
-#define ALAUDA_BULK_GET_STATUS2 0xb7
-#define ALAUDA_BULK_RESET_MEDIA 0xe0
-
-/*
- * Port to operate on (byte 8)
- */
-#define ALAUDA_PORT_XD 0x00
-#define ALAUDA_PORT_SM 0x01
-
-/*
- * LBA and PBA are unsigned ints. Special values.
- */
-#define UNDEF 0xffff
-#define SPARE 0xfffe
-#define UNUSABLE 0xfffd
-
-int init_alauda(struct us_data *us);
-int alauda_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct alauda_media_info {
- unsigned long capacity; /* total media size in bytes */
- unsigned int pagesize; /* page size in bytes */
- unsigned int blocksize; /* number of pages per block */
- unsigned int uzonesize; /* number of usable blocks per zone */
- unsigned int zonesize; /* number of blocks per zone */
- unsigned int blockmask; /* mask to get page from address */
-
- unsigned char pageshift;
- unsigned char blockshift;
- unsigned char zoneshift;
-
- u16 **lba_to_pba; /* logical to physical block map */
- u16 **pba_to_lba; /* physical to logical block map */
-};
-
-struct alauda_info {
- struct alauda_media_info port[2];
- int wr_ep; /* endpoint to write data out of */
-
- unsigned char sense_key;
- unsigned long sense_asc; /* additional sense code */
- unsigned long sense_ascq; /* additional sense code qualifier */
-};
-
-#endif
-
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c
index 898e67d30e56..19306f7b1dae 100644
--- a/drivers/usb/storage/cypress_atacb.c
+++ b/drivers/usb/storage/cypress_atacb.c
@@ -19,6 +19,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/module.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_eh.h>
@@ -29,6 +30,46 @@
#include "scsiglue.h"
#include "debug.h"
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id cypress_usb_ids[] = {
+# include "unusual_cypress.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, cypress_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev cypress_unusual_dev_list[] = {
+# include "unusual_cypress.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
/*
* ATACB is a protocol used on cypress usb<->ata bridge to
* send raw ATA command over mass storage
@@ -36,7 +77,7 @@
* More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf
* datasheet from cypress.com.
*/
-void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
+static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
{
unsigned char save_cmnd[MAX_COMMAND_SIZE];
@@ -133,19 +174,18 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
/* build the command for
* reading the ATA registers */
- scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0);
- srb->sdb.length = sizeof(regs);
- sg_init_one(&ses.sense_sgl, regs, srb->sdb.length);
- srb->sdb.table.sgl = &ses.sense_sgl;
- srb->sc_data_direction = DMA_FROM_DEVICE;
- srb->sdb.table.nents = 1;
+ scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sizeof(regs));
+
/* we use the same command as before, but we set
* the read taskfile bit, for not executing atacb command,
* but reading register selected in srb->cmnd[4]
*/
+ srb->cmd_len = 16;
+ srb->cmnd = ses.cmnd;
srb->cmnd[2] = 1;
usb_stor_transparent_scsi_command(srb, us);
+ memcpy(regs, srb->sense_buffer, sizeof(regs));
tmp_result = srb->result;
scsi_eh_restore_cmnd(srb, &ses);
/* we fail to get registers, report invalid command */
@@ -162,8 +202,8 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
/* XXX we should generate sk, asc, ascq from status and error
* regs
- * (see 11.1 Error translation ­ ATA device error to SCSI error map)
- * and ata_to_sense_error from libata.
+ * (see 11.1 Error translation ATA device error to SCSI error
+ * map, and ata_to_sense_error from libata.)
*/
/* Sense data is current and format is descriptor. */
@@ -198,3 +238,48 @@ end:
if (srb->cmnd[0] == ATA_12)
srb->cmd_len = 12;
}
+
+
+static int cypress_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - cypress_usb_ids) + cypress_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->protocol_name = "Transparent SCSI with Cypress ATACB";
+ us->proto_handler = cypress_atacb_passthrough;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver cypress_driver = {
+ .name = "ums-cypress",
+ .probe = cypress_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = cypress_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init cypress_init(void)
+{
+ return usb_register(&cypress_driver);
+}
+
+static void __exit cypress_exit(void)
+{
+ usb_deregister(&cypress_driver);
+}
+
+module_init(cypress_init);
+module_exit(cypress_exit);
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index 17f1ae232919..2d8d83519090 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -49,6 +49,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -58,12 +59,61 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "datafab.h"
+
+struct datafab_info {
+ unsigned long sectors; /* total sector count */
+ unsigned long ssize; /* sector size in bytes */
+ signed char lun; /* used for dual-slot readers */
+
+ /* the following aren't used yet */
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
static int datafab_determine_lun(struct us_data *us,
struct datafab_info *info);
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id datafab_usb_ids[] = {
+# include "unusual_datafab.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, datafab_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev datafab_unusual_dev_list[] = {
+# include "unusual_datafab.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
static inline int
datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) {
if (len == 0)
@@ -500,7 +550,7 @@ static void datafab_info_destructor(void *extra)
// Transport for the Datafab MDCFE-B
//
-int datafab_transport(struct scsi_cmnd * srb, struct us_data *us)
+static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us)
{
struct datafab_info *info;
int rc;
@@ -665,3 +715,49 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us)
info->sense_ascq = 0x00;
return USB_STOR_TRANSPORT_FAILED;
}
+
+static int datafab_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - datafab_usb_ids) + datafab_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Datafab Bulk-Only";
+ us->transport = datafab_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver datafab_driver = {
+ .name = "ums-datafab",
+ .probe = datafab_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = datafab_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init datafab_init(void)
+{
+ return usb_register(&datafab_driver);
+}
+
+static void __exit datafab_exit(void)
+{
+ usb_deregister(&datafab_driver);
+}
+
+module_init(datafab_init);
+module_exit(datafab_exit);
diff --git a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h
deleted file mode 100644
index 32e3f271e582..000000000000
--- a/drivers/usb/storage/datafab.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Driver for Datafab MDCFE-B USB Compact Flash reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Jimmie Mayfield (mayfield+datafab@sackheads.org)
- *
- * See datafab.c for more explanation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_DATAFAB_MDCFE_B_H
-#define _USB_DATAFAB_MDCFE_B_H
-
-extern int datafab_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct datafab_info {
- unsigned long sectors; // total sector count
- unsigned long ssize; // sector size in bytes
- signed char lun; // used for dual-slot readers
-
- // the following aren't used yet
- unsigned char sense_key;
- unsigned long sense_asc; // additional sense code
- unsigned long sense_ascq; // additional sense code qualifier
-};
-
-#endif
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
index 73ac7262239e..393047b3890d 100644
--- a/drivers/usb/storage/freecom.c
+++ b/drivers/usb/storage/freecom.c
@@ -26,6 +26,7 @@
* (http://www.freecom.de/)
*/
+#include <linux/module.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -33,7 +34,6 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "freecom.h"
#ifdef CONFIG_USB_STORAGE_DEBUG
static void pdump (void *, int);
@@ -103,6 +103,47 @@ struct freecom_status {
#define FCM_PACKET_LENGTH 64
#define FCM_STATUS_PACKET_LENGTH 4
+static int init_freecom(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id freecom_usb_ids[] = {
+# include "unusual_freecom.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, freecom_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev freecom_unusual_dev_list[] = {
+# include "unusual_freecom.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
static int
freecom_readdata (struct scsi_cmnd *srb, struct us_data *us,
unsigned int ipipe, unsigned int opipe, int count)
@@ -173,7 +214,7 @@ freecom_writedata (struct scsi_cmnd *srb, struct us_data *us,
* Transport for the Freecom USB/IDE adaptor.
*
*/
-int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
{
struct freecom_cb_wrap *fcb;
struct freecom_status *fst;
@@ -377,8 +418,7 @@ int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
return USB_STOR_TRANSPORT_GOOD;
}
-int
-freecom_init (struct us_data *us)
+static int init_freecom(struct us_data *us)
{
int result;
char *buffer = us->iobuf;
@@ -417,7 +457,7 @@ freecom_init (struct us_data *us)
return USB_STOR_TRANSPORT_GOOD;
}
-int usb_stor_freecom_reset(struct us_data *us)
+static int usb_stor_freecom_reset(struct us_data *us)
{
printk (KERN_CRIT "freecom reset called\n");
@@ -479,3 +519,48 @@ static void pdump (void *ibuffer, int length)
}
#endif
+static int freecom_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - freecom_usb_ids) + freecom_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Freecom";
+ us->transport = freecom_transport;
+ us->transport_reset = usb_stor_freecom_reset;
+ us->max_lun = 0;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver freecom_driver = {
+ .name = "ums-freecom",
+ .probe = freecom_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = freecom_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init freecom_init(void)
+{
+ return usb_register(&freecom_driver);
+}
+
+static void __exit freecom_exit(void)
+{
+ usb_deregister(&freecom_driver);
+}
+
+module_init(freecom_init);
+module_exit(freecom_exit);
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 383abf2516a5..df943008538c 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -44,6 +44,7 @@
#include <linux/jiffies.h>
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/hdreg.h>
#include <linux/scatterlist.h>
@@ -57,7 +58,50 @@
#include "protocol.h"
#include "debug.h"
#include "scsiglue.h"
-#include "isd200.h"
+
+
+static int isd200_Initialization(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id isd200_usb_ids[] = {
+# include "unusual_isd200.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, isd200_usb_ids);
+
+#undef UNUSUAL_DEV
+#undef USUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev isd200_unusual_dev_list[] = {
+# include "unusual_isd200.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+#undef USUAL_DEV
/* Timeout defines (in Seconds) */
@@ -1518,7 +1562,7 @@ static int isd200_init_info(struct us_data *us)
* Initialization for the ISD200
*/
-int isd200_Initialization(struct us_data *us)
+static int isd200_Initialization(struct us_data *us)
{
US_DEBUGP("ISD200 Initialization...\n");
@@ -1549,7 +1593,7 @@ int isd200_Initialization(struct us_data *us)
*
*/
-void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
+static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
{
int sendToTransport = 1, orig_bufflen;
union ata_cdb ataCdb;
@@ -1570,3 +1614,47 @@ void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
isd200_srb_set_bufflen(srb, orig_bufflen);
}
+
+static int isd200_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - isd200_usb_ids) + isd200_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->protocol_name = "ISD200 ATA/ATAPI";
+ us->proto_handler = isd200_ata_command;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver isd200_driver = {
+ .name = "ums-isd200",
+ .probe = isd200_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = isd200_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init isd200_init(void)
+{
+ return usb_register(&isd200_driver);
+}
+
+static void __exit isd200_exit(void)
+{
+ usb_deregister(&isd200_driver);
+}
+
+module_init(isd200_init);
+module_exit(isd200_exit);
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index df67f13c9e73..a50d6dc1fe64 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -46,6 +46,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -55,9 +56,57 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "jumpshot.h"
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id jumpshot_usb_ids[] = {
+# include "unusual_jumpshot.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, jumpshot_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev jumpshot_unusual_dev_list[] = {
+# include "unusual_jumpshot.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
+struct jumpshot_info {
+ unsigned long sectors; /* total sector count */
+ unsigned long ssize; /* sector size in bytes */
+
+ /* the following aren't used yet */
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
+
static inline int jumpshot_bulk_read(struct us_data *us,
unsigned char *data,
unsigned int len)
@@ -429,7 +478,7 @@ static void jumpshot_info_destructor(void *extra)
// Transport for the Lexar 'Jumpshot'
//
-int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us)
+static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us)
{
struct jumpshot_info *info;
int rc;
@@ -592,3 +641,49 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us)
info->sense_ascq = 0x00;
return USB_STOR_TRANSPORT_FAILED;
}
+
+static int jumpshot_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Lexar Jumpshot Control/Bulk";
+ us->transport = jumpshot_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver jumpshot_driver = {
+ .name = "ums-jumpshot",
+ .probe = jumpshot_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = jumpshot_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init jumpshot_init(void)
+{
+ return usb_register(&jumpshot_driver);
+}
+
+static void __exit jumpshot_exit(void)
+{
+ usb_deregister(&jumpshot_driver);
+}
+
+module_init(jumpshot_init);
+module_exit(jumpshot_exit);
diff --git a/drivers/usb/storage/jumpshot.h b/drivers/usb/storage/jumpshot.h
deleted file mode 100644
index 19bac9d1558f..000000000000
--- a/drivers/usb/storage/jumpshot.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Driver for Lexar "Jumpshot" USB Compact Flash reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Jimmie Mayfield (mayfield+usb@sackheads.org)
- *
- * See jumpshot.c for more explanation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_JUMPSHOT_H
-#define _USB_JUMPSHOT_H
-
-extern int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-struct jumpshot_info {
- unsigned long sectors; // total sector count
- unsigned long ssize; // sector size in bytes
-
- // the following aren't used yet
- unsigned char sense_key;
- unsigned long sense_asc; // additional sense code
- unsigned long sense_ascq; // additional sense code qualifier
-};
-
-#endif
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c
index 0d79ae5683f7..cfb8e60866b8 100644
--- a/drivers/usb/storage/karma.c
+++ b/drivers/usb/storage/karma.c
@@ -18,6 +18,8 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/module.h>
+
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
@@ -25,7 +27,6 @@
#include "usb.h"
#include "transport.h"
#include "debug.h"
-#include "karma.h"
#define RIO_PREFIX "RIOP\x00"
#define RIO_PREFIX_LEN 5
@@ -36,13 +37,53 @@
#define RIO_LEAVE_STORAGE 0x2
#define RIO_RESET 0xC
-extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data *);
-
struct karma_data {
int in_storage;
char *recv;
};
+static int rio_karma_init(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id karma_usb_ids[] = {
+# include "unusual_karma.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, karma_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev karma_unusual_dev_list[] = {
+# include "unusual_karma.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
/*
* Send commands to Rio Karma.
*
@@ -104,7 +145,7 @@ err:
* Trap START_STOP and READ_10 to leave/re-enter storage mode.
* Everything else is propagated to the normal bulk layer.
*/
-int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int ret;
struct karma_data *data = (struct karma_data *) us->extra;
@@ -133,7 +174,7 @@ static void rio_karma_destructor(void *extra)
kfree(data->recv);
}
-int rio_karma_init(struct us_data *us)
+static int rio_karma_init(struct us_data *us)
{
int ret = 0;
struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO);
@@ -153,3 +194,48 @@ int rio_karma_init(struct us_data *us)
out:
return ret;
}
+
+static int karma_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - karma_usb_ids) + karma_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "Rio Karma/Bulk";
+ us->transport = rio_karma_transport;
+ us->transport_reset = usb_stor_Bulk_reset;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver karma_driver = {
+ .name = "ums-karma",
+ .probe = karma_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = karma_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init karma_init(void)
+{
+ return usb_register(&karma_driver);
+}
+
+static void __exit karma_exit(void)
+{
+ usb_deregister(&karma_driver);
+}
+
+module_init(karma_init);
+module_exit(karma_exit);
diff --git a/drivers/usb/storage/karma.h b/drivers/usb/storage/karma.h
deleted file mode 100644
index 8a60972af8c5..000000000000
--- a/drivers/usb/storage/karma.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _KARMA_USB_H
-#define _KARMA_USB_H
-
-extern int rio_karma_init(struct us_data *us);
-extern int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us);
-
-#endif
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c
index f970b27ba308..fe3ffe1459b2 100644
--- a/drivers/usb/storage/libusual.c
+++ b/drivers/usb/storage/libusual.c
@@ -38,37 +38,6 @@ static atomic_t total_threads = ATOMIC_INIT(0);
static int usu_probe_thread(void *arg);
/*
- * The table.
- */
-#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
- vendorName, productName,useProtocol, useTransport, \
- initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
- .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
-
-#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
- vendorName, productName, useProtocol, useTransport, \
- initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
- .driver_info = (flags) }
-
-#define USUAL_DEV(useProto, useTrans, useType) \
-{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
- .driver_info = ((useType)<<24) }
-
-struct usb_device_id storage_usb_ids [] = {
-# include "unusual_devs.h"
- { } /* Terminating entry */
-};
-
-#undef USUAL_DEV
-#undef UNUSUAL_DEV
-#undef COMPLIANT_DEV
-
-MODULE_DEVICE_TABLE(usb, storage_usb_ids);
-EXPORT_SYMBOL_GPL(storage_usb_ids);
-
-/*
* @type: the module type as an integer
*/
void usb_usual_set_present(int type)
@@ -167,7 +136,7 @@ static struct usb_driver usu_driver = {
.name = "libusual",
.probe = usu_probe,
.disconnect = usu_disconnect,
- .id_table = storage_usb_ids,
+ .id_table = usb_storage_usb_ids,
};
/*
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index c7bf8954b4e4..8bd095635a99 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -35,9 +35,12 @@
#include <linux/module.h>
#include <linux/usb/input.h>
#include "usb.h"
-#include "onetouch.h"
#include "debug.h"
+#define ONETOUCH_PKT_LEN 0x02
+#define ONETOUCH_BUTTON KEY_PROG1
+
+static int onetouch_connect_input(struct us_data *ss);
static void onetouch_release_input(void *onetouch_);
struct usb_onetouch {
@@ -52,6 +55,46 @@ struct usb_onetouch {
unsigned int is_open:1;
};
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id onetouch_usb_ids[] = {
+# include "unusual_onetouch.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, onetouch_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev onetouch_unusual_dev_list[] = {
+# include "unusual_onetouch.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
static void usb_onetouch_irq(struct urb *urb)
{
struct usb_onetouch *onetouch = urb->context;
@@ -127,7 +170,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action)
}
#endif /* CONFIG_PM */
-int onetouch_connect_input(struct us_data *ss)
+static int onetouch_connect_input(struct us_data *ss)
{
struct usb_device *udev = ss->pusb_dev;
struct usb_host_interface *interface;
@@ -236,3 +279,46 @@ static void onetouch_release_input(void *onetouch_)
onetouch->data, onetouch->data_dma);
}
}
+
+static int onetouch_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - onetouch_usb_ids) + onetouch_unusual_dev_list);
+ if (result)
+ return result;
+
+ /* Use default transport and protocol */
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver onetouch_driver = {
+ .name = "ums-onetouch",
+ .probe = onetouch_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = onetouch_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init onetouch_init(void)
+{
+ return usb_register(&onetouch_driver);
+}
+
+static void __exit onetouch_exit(void)
+{
+ usb_deregister(&onetouch_driver);
+}
+
+module_init(onetouch_init);
+module_exit(onetouch_exit);
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h
deleted file mode 100644
index 41c7aa8f0446..000000000000
--- a/drivers/usb/storage/onetouch.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _ONETOUCH_H_
-#define _ONETOUCH_H_
-
-#define ONETOUCH_PKT_LEN 0x02
-#define ONETOUCH_BUTTON KEY_PROG1
-
-int onetouch_connect_input(struct us_data *ss);
-
-#endif
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index be441d84bc64..fc310f75eada 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -121,6 +121,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
/* send the command to the transport layer */
usb_stor_invoke_transport(srb, us);
}
+EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command);
/***********************************************************************
* Scatter-gather transfer buffer access routines
@@ -199,6 +200,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
/* Return the amount actually transferred */
return cnt;
}
+EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf);
/* Store the contents of buffer into srb's transfer buffer and set the
* SCSI residue.
@@ -215,3 +217,4 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
if (buflen < scsi_bufflen(srb))
scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
}
+EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf);
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 2a42b862aa9f..b98fedfb3253 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -64,6 +64,7 @@
*/
#define VENDOR_ID_NOKIA 0x0421
#define VENDOR_ID_NIKON 0x04b0
+#define VENDOR_ID_PENTAX 0x0a17
#define VENDOR_ID_MOTOROLA 0x22b8
/***********************************************************************
@@ -158,6 +159,7 @@ static int slave_configure(struct scsi_device *sdev)
switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) {
case VENDOR_ID_NOKIA:
case VENDOR_ID_NIKON:
+ case VENDOR_ID_PENTAX:
case VENDOR_ID_MOTOROLA:
if (!(us->fflags & (US_FL_FIX_CAPACITY |
US_FL_CAPACITY_OK)))
@@ -561,4 +563,4 @@ unsigned char usb_stor_sense_invalidCDB[18] = {
[7] = 0x0a, /* additional length */
[12] = 0x24 /* Invalid Field in CDB */
};
-
+EXPORT_SYMBOL_GPL(usb_stor_sense_invalidCDB);
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 531ae5c5abf3..170ad86b2d3e 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -41,6 +41,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -51,7 +52,50 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "sddr09.h"
+
+
+static int usb_stor_sddr09_dpcm_init(struct us_data *us);
+static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
+static int usb_stor_sddr09_init(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id sddr09_usb_ids[] = {
+# include "unusual_sddr09.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, sddr09_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev sddr09_unusual_dev_list[] = {
+# include "unusual_sddr09.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
@@ -723,7 +767,7 @@ sddr09_read_data(struct us_data *us,
len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("sddr09_read_data: Out of memory\n");
+ printk(KERN_WARNING "sddr09_read_data: Out of memory\n");
return -ENOMEM;
}
@@ -838,7 +882,8 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
if (pba == UNDEF) {
pba = sddr09_find_unused_pba(info, lba);
if (!pba) {
- printk("sddr09_write_lba: Out of unused blocks\n");
+ printk(KERN_WARNING
+ "sddr09_write_lba: Out of unused blocks\n");
return -ENOSPC;
}
info->pba_to_lba[pba] = lba;
@@ -849,7 +894,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
if (pba == 1) {
/* Maybe it is impossible to write to PBA 1.
Fake success, but don't do anything. */
- printk("sddr09: avoid writing to pba 1\n");
+ printk(KERN_WARNING "sddr09: avoid writing to pba 1\n");
return 0;
}
@@ -954,7 +999,7 @@ sddr09_write_data(struct us_data *us,
blocklen = (pagelen << info->blockshift);
blockbuffer = kmalloc(blocklen, GFP_NOIO);
if (!blockbuffer) {
- printk("sddr09_write_data: Out of memory\n");
+ printk(KERN_WARNING "sddr09_write_data: Out of memory\n");
return -ENOMEM;
}
@@ -965,7 +1010,7 @@ sddr09_write_data(struct us_data *us,
len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL) {
- printk("sddr09_write_data: Out of memory\n");
+ printk(KERN_WARNING "sddr09_write_data: Out of memory\n");
kfree(blockbuffer);
return -ENOMEM;
}
@@ -1112,7 +1157,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
if (result) {
US_DEBUGP("Result of read_deviceID is %d\n", result);
- printk("sddr09: could not read card info\n");
+ printk(KERN_WARNING "sddr09: could not read card info\n");
return NULL;
}
@@ -1153,7 +1198,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
sprintf(blurbtxt + strlen(blurbtxt),
", WP");
- printk("%s\n", blurbtxt);
+ printk(KERN_WARNING "%s\n", blurbtxt);
return cardinfo;
}
@@ -1184,7 +1229,7 @@ sddr09_read_map(struct us_data *us) {
alloc_len = (alloc_blocks << CONTROL_SHIFT);
buffer = kmalloc(alloc_len, GFP_NOIO);
if (buffer == NULL) {
- printk("sddr09_read_map: out of memory\n");
+ printk(KERN_WARNING "sddr09_read_map: out of memory\n");
result = -1;
goto done;
}
@@ -1198,7 +1243,7 @@ sddr09_read_map(struct us_data *us) {
info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO);
if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) {
- printk("sddr09_read_map: out of memory\n");
+ printk(KERN_WARNING "sddr09_read_map: out of memory\n");
result = -1;
goto done;
}
@@ -1238,7 +1283,8 @@ sddr09_read_map(struct us_data *us) {
if (ptr[j] != 0)
goto nonz;
info->pba_to_lba[i] = UNUSABLE;
- printk("sddr09: PBA %d has no logical mapping\n", i);
+ printk(KERN_WARNING "sddr09: PBA %d has no logical mapping\n",
+ i);
continue;
nonz:
@@ -1251,7 +1297,8 @@ sddr09_read_map(struct us_data *us) {
nonff:
/* normal PBAs start with six FFs */
if (j < 6) {
- printk("sddr09: PBA %d has no logical mapping: "
+ printk(KERN_WARNING
+ "sddr09: PBA %d has no logical mapping: "
"reserved area = %02X%02X%02X%02X "
"data status %02X block status %02X\n",
i, ptr[0], ptr[1], ptr[2], ptr[3],
@@ -1261,7 +1308,8 @@ sddr09_read_map(struct us_data *us) {
}
if ((ptr[6] >> 4) != 0x01) {
- printk("sddr09: PBA %d has invalid address field "
+ printk(KERN_WARNING
+ "sddr09: PBA %d has invalid address field "
"%02X%02X/%02X%02X\n",
i, ptr[6], ptr[7], ptr[11], ptr[12]);
info->pba_to_lba[i] = UNUSABLE;
@@ -1270,7 +1318,8 @@ sddr09_read_map(struct us_data *us) {
/* check even parity */
if (parity[ptr[6] ^ ptr[7]]) {
- printk("sddr09: Bad parity in LBA for block %d"
+ printk(KERN_WARNING
+ "sddr09: Bad parity in LBA for block %d"
" (%02X %02X)\n", i, ptr[6], ptr[7]);
info->pba_to_lba[i] = UNUSABLE;
continue;
@@ -1289,7 +1338,8 @@ sddr09_read_map(struct us_data *us) {
*/
if (lba >= 1000) {
- printk("sddr09: Bad low LBA %d for block %d\n",
+ printk(KERN_WARNING
+ "sddr09: Bad low LBA %d for block %d\n",
lba, i);
goto possibly_erase;
}
@@ -1297,7 +1347,8 @@ sddr09_read_map(struct us_data *us) {
lba += 1000*(i/0x400);
if (info->lba_to_pba[lba] != UNDEF) {
- printk("sddr09: LBA %d seen for PBA %d and %d\n",
+ printk(KERN_WARNING
+ "sddr09: LBA %d seen for PBA %d and %d\n",
lba, info->lba_to_pba[lba], i);
goto possibly_erase;
}
@@ -1399,7 +1450,7 @@ sddr09_common_init(struct us_data *us) {
* unusual devices list but called from here then LUN 0 of the combo reader
* is not recognized. But I do not know what precisely these calls do.
*/
-int
+static int
usb_stor_sddr09_dpcm_init(struct us_data *us) {
int result;
unsigned char *data = us->iobuf;
@@ -1449,7 +1500,7 @@ usb_stor_sddr09_dpcm_init(struct us_data *us) {
/*
* Transport for the Microtech DPCM-USB
*/
-int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int ret;
@@ -1491,7 +1542,7 @@ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us)
/*
* Transport for the Sandisk SDDR-09
*/
-int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
{
static unsigned char sensekey = 0, sensecode = 0;
static unsigned char havefakesense = 0;
@@ -1690,7 +1741,60 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
/*
* Initialization routine for the sddr09 subdriver
*/
-int
+static int
usb_stor_sddr09_init(struct us_data *us) {
return sddr09_common_init(us);
}
+
+static int sddr09_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - sddr09_usb_ids) + sddr09_unusual_dev_list);
+ if (result)
+ return result;
+
+ if (us->protocol == US_PR_DPCM_USB) {
+ us->transport_name = "Control/Bulk-EUSB/SDDR09";
+ us->transport = dpcm_transport;
+ us->transport_reset = usb_stor_CB_reset;
+ us->max_lun = 1;
+ } else {
+ us->transport_name = "EUSB/SDDR09";
+ us->transport = sddr09_transport;
+ us->transport_reset = usb_stor_CB_reset;
+ us->max_lun = 0;
+ }
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver sddr09_driver = {
+ .name = "ums-sddr09",
+ .probe = sddr09_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = sddr09_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init sddr09_init(void)
+{
+ return usb_register(&sddr09_driver);
+}
+
+static void __exit sddr09_exit(void)
+{
+ usb_deregister(&sddr09_driver);
+}
+
+module_init(sddr09_init);
+module_exit(sddr09_exit);
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h
deleted file mode 100644
index b701172e12e3..000000000000
--- a/drivers/usb/storage/sddr09.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Driver for SanDisk SDDR-09 SmartMedia reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Robert Baruch (autophile@dol.net)
- * (c) 2002 Andries Brouwer (aeb@cwi.nl)
- *
- * See sddr09.c for more explanation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_SHUTTLE_EUSB_SDDR09_H
-#define _USB_SHUTTLE_EUSB_SDDR09_H
-
-/* Sandisk SDDR-09 stuff */
-
-extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_sddr09_init(struct us_data *us);
-
-/* Microtech DPCM-USB stuff */
-
-extern int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_sddr09_dpcm_init(struct us_data *us);
-
-#endif
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index 0d8df7577899..e97716f8eb02 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -24,6 +24,7 @@
#include <linux/jiffies.h>
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
@@ -33,7 +34,45 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "sddr55.h"
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id sddr55_usb_ids[] = {
+# include "unusual_sddr55.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, sddr55_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev sddr55_unusual_dev_list[] = {
+# include "unusual_sddr55.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
@@ -513,7 +552,8 @@ static int sddr55_read_deviceID(struct us_data *us,
}
-int sddr55_reset(struct us_data *us) {
+static int sddr55_reset(struct us_data *us)
+{
return 0;
}
@@ -703,7 +743,9 @@ static int sddr55_read_map(struct us_data *us) {
if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED &&
!info->force_read_only) {
- printk("sddr55: map inconsistency at LBA %04X\n", lba + zone * 1000);
+ printk(KERN_WARNING
+ "sddr55: map inconsistency at LBA %04X\n",
+ lba + zone * 1000);
info->force_read_only = 1;
}
@@ -732,7 +774,7 @@ static void sddr55_card_info_destructor(void *extra) {
/*
* Transport for the Sandisk SDDR-55
*/
-int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
+static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int result;
static unsigned char inquiry_response[8] = {
@@ -929,3 +971,49 @@ int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer?
}
+
+static int sddr55_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - sddr55_usb_ids) + sddr55_unusual_dev_list);
+ if (result)
+ return result;
+
+ us->transport_name = "SDDR55";
+ us->transport = sddr55_transport;
+ us->transport_reset = sddr55_reset;
+ us->max_lun = 0;
+
+ result = usb_stor_probe2(us);
+ return result;
+}
+
+static struct usb_driver sddr55_driver = {
+ .name = "ums-sddr55",
+ .probe = sddr55_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = sddr55_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init sddr55_init(void)
+{
+ return usb_register(&sddr55_driver);
+}
+
+static void __exit sddr55_exit(void)
+{
+ usb_deregister(&sddr55_driver);
+}
+
+module_init(sddr55_init);
+module_exit(sddr55_exit);
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index ae6d64810d2a..d4fe0bb327a7 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -42,6 +42,7 @@
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/cdrom.h>
@@ -52,7 +53,97 @@
#include "transport.h"
#include "protocol.h"
#include "debug.h"
-#include "shuttle_usbat.h"
+
+
+/* Supported device types */
+#define USBAT_DEV_HP8200 0x01
+#define USBAT_DEV_FLASH 0x02
+
+#define USBAT_EPP_PORT 0x10
+#define USBAT_EPP_REGISTER 0x30
+#define USBAT_ATA 0x40
+#define USBAT_ISA 0x50
+
+/* Commands (need to be logically OR'd with an access type */
+#define USBAT_CMD_READ_REG 0x00
+#define USBAT_CMD_WRITE_REG 0x01
+#define USBAT_CMD_READ_BLOCK 0x02
+#define USBAT_CMD_WRITE_BLOCK 0x03
+#define USBAT_CMD_COND_READ_BLOCK 0x04
+#define USBAT_CMD_COND_WRITE_BLOCK 0x05
+#define USBAT_CMD_WRITE_REGS 0x07
+
+/* Commands (these don't need an access type) */
+#define USBAT_CMD_EXEC_CMD 0x80
+#define USBAT_CMD_SET_FEAT 0x81
+#define USBAT_CMD_UIO 0x82
+
+/* Methods of accessing UIO register */
+#define USBAT_UIO_READ 1
+#define USBAT_UIO_WRITE 0
+
+/* Qualifier bits */
+#define USBAT_QUAL_FCQ 0x20 /* full compare */
+#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */
+
+/* USBAT Flash Media status types */
+#define USBAT_FLASH_MEDIA_NONE 0
+#define USBAT_FLASH_MEDIA_CF 1
+
+/* USBAT Flash Media change types */
+#define USBAT_FLASH_MEDIA_SAME 0
+#define USBAT_FLASH_MEDIA_CHANGED 1
+
+/* USBAT ATA registers */
+#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */
+#define USBAT_ATA_FEATURES 0x11 /* set features (W) */
+#define USBAT_ATA_ERROR 0x11 /* error (R) */
+#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */
+#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */
+#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */
+#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */
+#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */
+#define USBAT_ATA_STATUS 0x17 /* device status (R) */
+#define USBAT_ATA_CMD 0x17 /* device command (W) */
+#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */
+
+/* USBAT User I/O Data registers */
+#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */
+#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */
+ /* CDT = ACKD & !UI1 & !UI0 */
+#define USBAT_UIO_1 0x20 /* I/O 1 */
+#define USBAT_UIO_0 0x10 /* I/O 0 */
+#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */
+#define USBAT_UIO_UI1 0x04 /* Input 1 */
+#define USBAT_UIO_UI0 0x02 /* Input 0 */
+#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
+
+/* USBAT User I/O Enable registers */
+#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */
+#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */
+#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */
+ /* If ACKD=1, set OE1 to 1 also. */
+#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */
+#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */
+
+/* USBAT Features */
+#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */
+#define USBAT_FEAT_U1 0x08
+#define USBAT_FEAT_U0 0x04
+#define USBAT_FEAT_ET1 0x02
+#define USBAT_FEAT_ET2 0x01
+
+struct usbat_info {
+ int devicetype;
+
+ /* Used for Flash readers only */
+ unsigned long sectors; /* total sector count */
+ unsigned long ssize; /* sector size in bytes */
+
+ unsigned char sense_key;
+ unsigned long sense_asc; /* additional sense code */
+ unsigned long sense_ascq; /* additional sense code qualifier */
+};
#define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) )
#define LSB_of(s) ((s)&0xFF)
@@ -63,6 +154,48 @@ static int transferred = 0;
static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us);
static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us);
+static int init_usbat_cd(struct us_data *us);
+static int init_usbat_flash(struct us_data *us);
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+struct usb_device_id usbat_usb_ids[] = {
+# include "unusual_usbat.h"
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, usbat_usb_ids);
+
+#undef UNUSUAL_DEV
+
+/*
+ * The flags table
+ */
+#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
+ vendor_name, product_name, use_protocol, use_transport, \
+ init_function, Flags) \
+{ \
+ .vendorName = vendor_name, \
+ .productName = product_name, \
+ .useProtocol = use_protocol, \
+ .useTransport = use_transport, \
+ .initFunction = init_function, \
+}
+
+static struct us_unusual_dev usbat_unusual_dev_list[] = {
+# include "unusual_usbat.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
/*
* Convenience function to produce an ATA read/write sectors command
* Use cmd=0x20 for read, cmd=0x30 for write
@@ -1684,37 +1817,61 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us)
return USB_STOR_TRANSPORT_FAILED;
}
-int init_usbat_cd(struct us_data *us)
+static int init_usbat_cd(struct us_data *us)
{
return init_usbat(us, USBAT_DEV_HP8200);
}
-
-int init_usbat_flash(struct us_data *us)
+static int init_usbat_flash(struct us_data *us)
{
return init_usbat(us, USBAT_DEV_FLASH);
}
-int init_usbat_probe(struct us_data *us)
+static int usbat_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
- return init_usbat(us, 0);
+ struct us_data *us;
+ int result;
+
+ result = usb_stor_probe1(&us, intf, id,
+ (id - usbat_usb_ids) + usbat_unusual_dev_list);
+ if (result)
+ return result;
+
+ /* The actual transport will be determined later by the
+ * initialization routine; this is just a placeholder.
+ */
+ us->transport_name = "Shuttle USBAT";
+ us->transport = usbat_flash_transport;
+ us->transport_reset = usb_stor_CB_reset;
+ us->max_lun = 1;
+
+ result = usb_stor_probe2(us);
+ return result;
}
-/*
- * Default transport function. Attempts to detect which transport function
- * should be called, makes it the new default, and calls it.
- *
- * This function should never be called. Our usbat_init() function detects the
- * device type and changes the us->transport ptr to the transport function
- * relevant to the device.
- * However, we'll support this impossible(?) case anyway.
- */
-int usbat_transport(struct scsi_cmnd *srb, struct us_data *us)
+static struct usb_driver usbat_driver = {
+ .name = "ums-usbat",
+ .probe = usbat_probe,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = usbat_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init usbat_init(void)
{
- struct usbat_info *info = (struct usbat_info*) (us->extra);
-
- if (usbat_set_transport(us, info, 0))
- return USB_STOR_TRANSPORT_ERROR;
+ return usb_register(&usbat_driver);
+}
- return us->transport(srb, us);
+static void __exit usbat_exit(void)
+{
+ usb_deregister(&usbat_driver);
}
+
+module_init(usbat_init);
+module_exit(usbat_exit);
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
deleted file mode 100644
index d8bfc43e9044..000000000000
--- a/drivers/usb/storage/shuttle_usbat.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Driver for SCM Microsystems USB-ATAPI cable
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2000 Robert Baruch (autophile@dol.net)
- * (c) 2004, 2005 Daniel Drake <dsd@gentoo.org>
- *
- * See shuttle_usbat.c for more explanation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_SHUTTLE_USBAT_H
-#define _USB_SHUTTLE_USBAT_H
-
-/* Supported device types */
-#define USBAT_DEV_HP8200 0x01
-#define USBAT_DEV_FLASH 0x02
-
-#define USBAT_EPP_PORT 0x10
-#define USBAT_EPP_REGISTER 0x30
-#define USBAT_ATA 0x40
-#define USBAT_ISA 0x50
-
-/* Commands (need to be logically OR'd with an access type */
-#define USBAT_CMD_READ_REG 0x00
-#define USBAT_CMD_WRITE_REG 0x01
-#define USBAT_CMD_READ_BLOCK 0x02
-#define USBAT_CMD_WRITE_BLOCK 0x03
-#define USBAT_CMD_COND_READ_BLOCK 0x04
-#define USBAT_CMD_COND_WRITE_BLOCK 0x05
-#define USBAT_CMD_WRITE_REGS 0x07
-
-/* Commands (these don't need an access type) */
-#define USBAT_CMD_EXEC_CMD 0x80
-#define USBAT_CMD_SET_FEAT 0x81
-#define USBAT_CMD_UIO 0x82
-
-/* Methods of accessing UIO register */
-#define USBAT_UIO_READ 1
-#define USBAT_UIO_WRITE 0
-
-/* Qualifier bits */
-#define USBAT_QUAL_FCQ 0x20 /* full compare */
-#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */
-
-/* USBAT Flash Media status types */
-#define USBAT_FLASH_MEDIA_NONE 0
-#define USBAT_FLASH_MEDIA_CF 1
-
-/* USBAT Flash Media change types */
-#define USBAT_FLASH_MEDIA_SAME 0
-#define USBAT_FLASH_MEDIA_CHANGED 1
-
-/* USBAT ATA registers */
-#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */
-#define USBAT_ATA_FEATURES 0x11 /* set features (W) */
-#define USBAT_ATA_ERROR 0x11 /* error (R) */
-#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */
-#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */
-#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */
-#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */
-#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */
-#define USBAT_ATA_STATUS 0x17 /* device status (R) */
-#define USBAT_ATA_CMD 0x17 /* device command (W) */
-#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */
-
-/* USBAT User I/O Data registers */
-#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */
-#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */
- /* CDT = ACKD & !UI1 & !UI0 */
-#define USBAT_UIO_1 0x20 /* I/O 1 */
-#define USBAT_UIO_0 0x10 /* I/O 0 */
-#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */
-#define USBAT_UIO_UI1 0x04 /* Input 1 */
-#define USBAT_UIO_UI0 0x02 /* Input 0 */
-#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */
-
-/* USBAT User I/O Enable registers */
-#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */
-#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */
-#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */
- /* If ACKD=1, set OE1 to 1 also. */
-#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */
-#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */
-
-/* USBAT Features */
-#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */
-#define USBAT_FEAT_U1 0x08
-#define USBAT_FEAT_U0 0x04
-#define USBAT_FEAT_ET1 0x02
-#define USBAT_FEAT_ET2 0x01
-
-extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int init_usbat_cd(struct us_data *us);
-extern int init_usbat_flash(struct us_data *us);
-extern int init_usbat_probe(struct us_data *us);
-
-struct usbat_info {
- int devicetype;
-
- /* Used for Flash readers only */
- unsigned long sectors; /* total sector count */
- unsigned long ssize; /* sector size in bytes */
-
- unsigned char sense_key;
- unsigned long sense_asc; /* additional sense code */
- unsigned long sense_ascq; /* additional sense code qualifier */
-};
-
-#endif
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 1d5438e6363b..d48c8553539d 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -220,6 +220,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
status = us->current_urb->actual_length;
return status;
}
+EXPORT_SYMBOL_GPL(usb_stor_control_msg);
/* This is a version of usb_clear_halt() that allows early termination and
* doesn't read the status from the device -- this is because some devices
@@ -254,6 +255,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
US_DEBUGP("%s: result = %d\n", __func__, result);
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_clear_halt);
/*
@@ -352,6 +354,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe,
return interpret_urb_result(us, pipe, size, result,
us->current_urb->actual_length);
}
+EXPORT_SYMBOL_GPL(usb_stor_ctrl_transfer);
/*
* Receive one interrupt buffer, without timeouts, but allowing early
@@ -407,6 +410,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
return interpret_urb_result(us, pipe, length, result,
us->current_urb->actual_length);
}
+EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_buf);
/*
* Transfer a scatter-gather list via bulk transfer
@@ -474,6 +478,7 @@ int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
scsi_set_resid(srb, scsi_bufflen(srb) - partial);
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_bulk_srb);
/*
* Transfer an entire SCSI command's worth of data payload over the bulk
@@ -509,6 +514,7 @@ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
*residual = length_left;
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_sg);
/***********************************************************************
* Transport routines
@@ -558,32 +564,10 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) {
- /* The command succeeded. If the capacity is odd
- * (i.e., if the sector number is even) then the
- * "always-even" heuristic would be wrong for this
- * device. Issue a WARN() so that the kerneloops.org
- * project will be notified and we will then know to
- * mark the device with a CAPACITY_OK flag. Hopefully
- * this will occur for only a few devices.
- *
- * Use the sign of us->last_sector_hacks to tell whether
- * the warning has already been issued; we don't need
- * more than one warning per device.
+ /* The command succeeded. We know this device doesn't
+ * have the last-sector bug, so stop checking it.
*/
- if (!(sector & 1) && us->use_last_sector_hacks > 0) {
- unsigned vid = le16_to_cpu(
- us->pusb_dev->descriptor.idVendor);
- unsigned pid = le16_to_cpu(
- us->pusb_dev->descriptor.idProduct);
- unsigned rev = le16_to_cpu(
- us->pusb_dev->descriptor.bcdDevice);
-
- WARN(1, "%s: Successful last sector success at %u, "
- "device %04x:%04x:%04x\n",
- sdkp->disk->disk_name, sector,
- vid, pid, rev);
- us->use_last_sector_hacks = -1;
- }
+ us->use_last_sector_hacks = 0;
} else {
/* The command failed. Allow up to 3 retries in case this
@@ -599,14 +583,6 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
srb->result = SAM_STAT_CHECK_CONDITION;
memcpy(srb->sense_buffer, record_not_found,
sizeof(record_not_found));
-
- /* In theory we might want to issue a WARN() here if the
- * capacity is even, since it could indicate the device
- * has the READ CAPACITY bug _and_ the real capacity is
- * odd. But it could also indicate that the device
- * simply can't access its last sector, a failure mode
- * which is surprisingly common. So no warning.
- */
}
done:
@@ -970,6 +946,7 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
usb_stor_clear_halt(us, pipe);
return USB_STOR_TRANSPORT_FAILED;
}
+EXPORT_SYMBOL_GPL(usb_stor_CB_transport);
/*
* Bulk only transport
@@ -1186,6 +1163,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
/* we should never get here, but if we do, we're in trouble */
return USB_STOR_TRANSPORT_ERROR;
}
+EXPORT_SYMBOL_GPL(usb_stor_Bulk_transport);
/***********************************************************************
* Reset routines
@@ -1260,6 +1238,7 @@ int usb_stor_CB_reset(struct us_data *us)
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE);
}
+EXPORT_SYMBOL_GPL(usb_stor_CB_reset);
/* This issues a Bulk-only Reset to the device in question, including
* clearing the subsequent endpoint halts that may occur.
@@ -1272,6 +1251,7 @@ int usb_stor_Bulk_reset(struct us_data *us)
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, us->ifnum, NULL, 0);
}
+EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset);
/* Issue a USB port reset to the device. The caller must not hold
* us->dev_mutex.
diff --git a/drivers/usb/storage/freecom.h b/drivers/usb/storage/unusual_alauda.h
index 20d0fe6ba0c8..8c412f885dd2 100644
--- a/drivers/usb/storage/freecom.h
+++ b/drivers/usb/storage/unusual_alauda.h
@@ -1,13 +1,4 @@
-/* Driver for Freecom USB/IDE adaptor
- *
- * Freecom v0.1:
- *
- * First release
- *
- * Current development and maintenance by:
- * (c) 2000 David Brown <usb-storage@davidb.org>
- *
- * See freecom.c for more explanation
+/* Unusual Devices File for the Alauda-based card readers
*
* 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
@@ -24,11 +15,17 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _FREECOM_USB_H
-#define _FREECOM_USB_H
+#if defined(CONFIG_USB_STORAGE_ALAUDA) || \
+ defined(CONFIG_USB_STORAGE_ALAUDA_MODULE)
+
+UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102,
+ "Fujifilm",
+ "DPC-R1 (Alauda)",
+ US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0),
-extern int freecom_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int usb_stor_freecom_reset(struct us_data *us);
-extern int freecom_init (struct us_data *us);
+UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102,
+ "Olympus",
+ "MAUSB-10 (Alauda)",
+ US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0),
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_ALAUDA) || ... */
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h
new file mode 100644
index 000000000000..44be6d75dab6
--- /dev/null
+++ b/drivers/usb/storage/unusual_cypress.h
@@ -0,0 +1,34 @@
+/* Unusual Devices File for devices based on the Cypress USB/ATA bridge
+ * with support for ATACB
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || \
+ defined(CONFIG_USB_STORAGE_CYPRESS_ATACB_MODULE)
+
+/* CY7C68300 : support atacb */
+UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999,
+ "Cypress",
+ "Cypress AT2LP",
+ US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0),
+
+/* CY7C68310 : support atacb and atacb2 */
+UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999,
+ "Cypress",
+ "Cypress ISD-300LP",
+ US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */
diff --git a/drivers/usb/storage/unusual_datafab.h b/drivers/usb/storage/unusual_datafab.h
new file mode 100644
index 000000000000..c9298ce9f223
--- /dev/null
+++ b/drivers/usb/storage/unusual_datafab.h
@@ -0,0 +1,98 @@
+/* Unusual Devices File for the Datafab USB Compact Flash reader
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_USB_STORAGE_DATAFAB) || \
+ defined(CONFIG_USB_STORAGE_DATAFAB_MODULE)
+
+UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015,
+ "Datafab",
+ "MDCFE-B USB CF Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/*
+ * The following Datafab-based devices may or may not work
+ * using the current driver...the 0xffff is arbitrary since I
+ * don't know what device versions exist for these guys.
+ *
+ * The 0xa003 and 0xa004 devices in particular I'm curious about.
+ * I'm told they exist but so far nobody has come forward to say that
+ * they work with this driver. Given the success we've had getting
+ * other Datafab-based cards operational with this driver, I've decided
+ * to leave these two devices in the list.
+ */
+UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
+ "SIIG/Datafab",
+ "SIIG/Datafab Memory Stick+CF Reader/Writer",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */
+UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff,
+ "Datafab/Unknown",
+ "MD2/MD3 Disk enclosure",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ US_FL_SINGLE_LUN),
+
+UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
+ "Datafab/Unknown",
+ "Datafab-based Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
+ "Datafab/Unknown",
+ "Datafab-based Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
+ "PNY/Datafab",
+ "PNY/Datafab CF+SM Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
+ "Simple Tech/Datafab",
+ "Simple Tech/Datafab CF+SM Reader",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/* Submitted by Olaf Hering <olh@suse.de> */
+UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
+ "Datafab Systems, Inc.",
+ "USB to CF + SM Combo (LC1)",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+/* Reported by Felix Moeller <felix@derklecks.de>
+ * in Germany this is sold by Hama with the productnumber 46952
+ * as "DualSlot CompactFlash(TM) & MStick Drive USB"
+ */
+UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff,
+ "DataFab Systems Inc.",
+ "USB CF+MS",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ 0),
+
+UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
+ "Acomdata",
+ "CF",
+ US_SC_SCSI, US_PR_DATAFAB, NULL,
+ US_FL_SINGLE_LUN),
+
+#endif /* defined(CONFIG_USB_STORAGE_DATAFAB) || ... */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index a7f9513fa19d..9b39a48f0159 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -53,6 +53,11 @@
* as opposed to devices that do something strangely or wrongly.
*/
+#if !defined(CONFIG_USB_STORAGE_SDDR09) && \
+ !defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
+#define NO_SDDR09
+#endif
+
/* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
*/
UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100,
@@ -80,18 +85,6 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200,
"CD-Writer+",
US_SC_8070, US_PR_CB, NULL, 0),
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
- "HP",
- "CD-Writer+ 8200e",
- US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-
-UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
- "HP",
- "CD-Writer+ CD-4e",
- US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
-#endif
-
/* Reported by Ben Efros <ben@pc-doctor.com> */
UNUSUAL_DEV( 0x03f0, 0x070c, 0x0000, 0x0000,
"HP",
@@ -246,12 +239,7 @@ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
- "Microtech",
- "CameraMate (DPCM_USB)",
- US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#else
+#ifdef NO_SDDR09
UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
"Microtech",
"CameraMate",
@@ -288,13 +276,6 @@ UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NOT_LOCKABLE ),
-#ifdef CONFIG_USB_STORAGE_KARMA
-UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101,
- "Rio",
- "Rio Karma",
- US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),
-#endif
-
/* Reported by Tamas Kerecsen <kerecsen@bigfoot.com>
* Obviously the PROM has not been customized by the VAR;
* the Vendor and Product string descriptors are:
@@ -375,22 +356,6 @@ UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110,
US_SC_DEVICE, US_PR_CB, NULL,
US_FL_MAX_SECTORS_MIN),
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-/* CY7C68300 : support atacb */
-UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999,
- "Cypress",
- "Cypress AT2LP",
- US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
- 0),
-
-/* CY7C68310 : support atacb and atacb2 */
-UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999,
- "Cypress",
- "Cypress ISD-300LP",
- US_SC_CYP_ATACB, US_PR_DEVICE, NULL,
- 0),
-#endif
-
/* Reported by Simon Levitt <simon@whattf.com>
* This entry needs Sub and Proto fields */
UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100,
@@ -467,20 +432,7 @@ UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
US_FL_SCM_MULT_TARG ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
- "Sandisk",
- "ImageMate SDDR09",
- US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
- 0),
-
-/* This entry is from Andries.Brouwer@cwi.nl */
-UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
- "SCM Microsystems",
- "eUSB SmartMedia / CompactFlash Adapter",
- US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
- 0),
-#else
+#ifdef NO_SDDR09
UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
"SCM Microsystems",
"eUSB CompactFlash Adapter",
@@ -535,14 +487,6 @@ UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200,
"CD-RW Device",
US_SC_8020, US_PR_CB, NULL, 0),
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999,
- "Shuttle/SCM",
- "USBAT-02",
- US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
- US_FL_SINGLE_LUN),
-#endif
-
/* Reported by Dmitry Khlystov <adminimus@gmail.com> */
UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220,
"Samsung",
@@ -645,14 +589,6 @@ UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110,
- "Sony",
- "Portable USB Harddrive V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-#endif
-
/* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */
UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000,
"Sony",
@@ -749,13 +685,6 @@ UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999,
"Silicon Media R/W",
US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102,
- "Fujifilm",
- "DPC-R1 (Alauda)",
- US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
/* Reported by RTE <raszilki@yandex.ru> */
UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141,
"JetFlash",
@@ -798,32 +727,6 @@ UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110,
US_SC_SCSI, US_PR_BULK, NULL,
US_FL_NEED_OVERRIDE ),
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110,
- "In-System",
- "USB/IDE Bridge (ATA/ATAPI)",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-
-UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110,
- "In-System",
- "Portable USB Harddrive V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-
-UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110,
- "In-System",
- "Portable USB Harddrive V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-
-UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110,
- "In-System",
- "USB Storage Adapter V2",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-#endif
-
/* Submitted by Sven Anderson <sven-linux@anderson.de>
* There are at least four ProductIDs used for iPods, so I added 0x1202 and
* 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears
@@ -877,14 +780,6 @@ UNUSUAL_DEV( 0x05c6, 0x1000, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, option_ms_init,
0),
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001,
- "Lexar",
- "Jumpshot USB CF Reader",
- US_SC_SCSI, US_PR_JUMPSHOT, NULL,
- US_FL_NEED_OVERRIDE ),
-#endif
-
/* Reported by Blake Matheny <bmatheny@purdue.edu> */
UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113,
"Lexar",
@@ -907,13 +802,13 @@ UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Optical",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Disk",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ),
/* Reported by Ben Efros <ben@pc-doctor.com> */
UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451,
@@ -935,14 +830,6 @@ UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100,
"Floppy Drive",
US_SC_UFI, US_PR_CB, NULL, 0 ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
- "Olympus",
- "Camedia MAUSB-2",
- US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
- 0),
-#endif
-
/* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */
UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
"SigmaTel",
@@ -995,6 +882,16 @@ UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
+/* Reported by Jean-Baptiste Onofre <jb@nanthrax.net>
+ * Support the following product :
+ * "Dane-Elec MediaTouch"
+ */
+UNUSUAL_DEV( 0x071b, 0x32bb, 0x0000, 0x0000,
+ "RockChip",
+ "MTP",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
+
/* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com>
* This USB MP3/AVI player device fails and disconnects if more than 128
* sectors (64kB) are read/written in a single command, and may be present
@@ -1031,35 +928,12 @@ UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
-#ifdef CONFIG_USB_STORAGE_USBAT
-UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
- "Sandisk",
- "ImageMate SDDR-05b",
- US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
- US_FL_SINGLE_LUN ),
-#endif
-
UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100,
"Sandisk",
"ImageMate SDDR-12",
US_SC_SCSI, US_PR_CB, NULL,
US_FL_SINGLE_LUN ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
- "Sandisk",
- "ImageMate SDDR-09",
- US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
- 0),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999,
- "Freecom",
- "USB-IDE",
- US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
-#endif
-
/* Reported by Eero Volotinen <eero@ping-viini.org> */
UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999,
"Freecom Technologies",
@@ -1079,12 +953,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
US_FL_SCM_MULT_TARG ),
-#ifdef CONFIG_USB_STORAGE_SDDR09
-UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
- "Microtech",
- "CameraMate (DPCM_USB)",
- US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
-#else
+#ifdef NO_SDDR09
UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
"Microtech",
"CameraMate",
@@ -1092,108 +961,6 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
US_FL_SINGLE_LUN ),
#endif
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102,
- "Olympus",
- "MAUSB-10 (Alauda)",
- US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015,
- "Datafab",
- "MDCFE-B USB CF Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-/*
- * The following Datafab-based devices may or may not work
- * using the current driver...the 0xffff is arbitrary since I
- * don't know what device versions exist for these guys.
- *
- * The 0xa003 and 0xa004 devices in particular I'm curious about.
- * I'm told they exist but so far nobody has come forward to say that
- * they work with this driver. Given the success we've had getting
- * other Datafab-based cards operational with this driver, I've decided
- * to leave these two devices in the list.
- */
-UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff,
- "SIIG/Datafab",
- "SIIG/Datafab Memory Stick+CF Reader/Writer",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-/* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */
-UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff,
- "Datafab/Unknown",
- "MD2/MD3 Disk enclosure",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_SINGLE_LUN ),
-
-UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff,
- "Datafab/Unknown",
- "Datafab-based Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff,
- "Datafab/Unknown",
- "Datafab-based Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff,
- "PNY/Datafab",
- "PNY/Datafab CF+SM Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff,
- "Simple Tech/Datafab",
- "Simple Tech/Datafab CF+SM Reader",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* Contributed by Peter Waechtler */
-UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
- "Datafab",
- "MDSM-B reader",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_FIX_INQUIRY ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Submitted by Olaf Hering <olh@suse.de> */
-UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
- "Datafab Systems, Inc.",
- "USB to CF + SM Combo (LC1)",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-/* SM part - aeb <Andries.Brouwer@cwi.nl> */
-UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
- "Datafab Systems, Inc.",
- "USB to CF + SM Combo (LC1)",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_SINGLE_LUN ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-/* Reported by Felix Moeller <felix@derklecks.de>
- * in Germany this is sold by Hama with the productnumber 46952
- * as "DualSlot CompactFlash(TM) & MStick Drive USB"
- */
-UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff,
- "DataFab Systems Inc.",
- "USB CF+MS",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- 0 ),
-
-#endif
-
/* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100
* Only revision 1.13 tested (same for all of the above devices,
* based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY.
@@ -1204,7 +971,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
"Datafab",
"KECF-USB",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
+ US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ),
/* Reported by Rauch Wolke <rauchwolke@gmx.net> */
UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff,
@@ -1251,6 +1018,13 @@ UNUSUAL_DEV( 0x0840, 0x0084, 0x0001, 0x0001,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY),
+/* Reported by Martijn Hijdra <martijn.hijdra@gmail.com> */
+UNUSUAL_DEV( 0x0840, 0x0085, 0x0001, 0x0001,
+ "Argosy",
+ "Storage",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY),
+
/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
* Flag will support Bulk devices which use a standards-violating 32-byte
* Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
@@ -1337,21 +1111,6 @@ UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
-
-/* Submitted by Per Winkvist <per.winkvist@uk.com> */
-UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
- "Pentax",
- "Optio S/S4",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_INQUIRY ),
-
-/* Reported by Jaak Ristioja <Ristioja@gmail.com> */
-UNUSUAL_DEV( 0x0a17, 0x006e, 0x0100, 0x0100,
- "Pentax",
- "K10D",
- US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_FIX_CAPACITY ),
-
/* These are virtual windows driver CDs, which the zd1211rw driver
* automatically converts into WLAN devices. */
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
@@ -1395,29 +1154,6 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SANE_SENSE ),
-#ifdef CONFIG_USB_STORAGE_ISD200
-UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
- "ATI",
- "USB Cable 205",
- US_SC_ISD200, US_PR_BULK, isd200_Initialization,
- 0 ),
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
- "Acomdata",
- "CF",
- US_SC_SCSI, US_PR_DATAFAB, NULL,
- US_FL_SINGLE_LUN ),
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
- "Acomdata",
- "SM",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_SINGLE_LUN ),
-#endif
-
UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999,
"Maxtor",
"USB to SATA",
@@ -1434,23 +1170,6 @@ UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
-/* Submitted by: Nick Sillik <n.sillik@temple.edu>
- * Needed for OneTouch extension to usb-storage
- *
- */
-#ifdef CONFIG_USB_STORAGE_ONETOUCH
- UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999,
- "Maxtor",
- "OneTouch External Harddrive",
- US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
- 0),
- UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
- "Maxtor",
- "OneTouch External Harddrive",
- US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
- 0),
-#endif
-
/* Submitted by Joris Struyve <joris@struyve.be> */
UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
"Medion",
@@ -1589,6 +1308,13 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NO_WP_DETECT ),
+/* Reported by The Solutor <thesolutor@gmail.com> */
+UNUSUAL_DEV( 0x0fce, 0xd0e1, 0x0000, 0x0000,
+ "Sony Ericsson",
+ "MD400",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE),
+
/* Reported by Jan Mate <mate@fiit.stuba.sk>
* and by Soeren Sonnenburg <kernel@nn7.de> */
UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000,
@@ -2031,15 +1757,11 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
-/* Reported by Mauro Andreolini <andreoli@weblab.ing.unimo.it>
- * This entry is needed to bypass the ZeroCD mechanism
- * and to properly load as a modem device.
- */
-UNUSUAL_DEV( 0x19d2, 0x2000, 0x0000, 0x0000,
- "Onda ET502HS",
- "USB MMC Storage",
+UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
+ "ST",
+ "2A",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_IGNORE_DEVICE),
+ US_FL_FIX_CAPACITY),
/* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
* and Renato Perini <rperini@email.it>
@@ -2100,14 +1822,6 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100,
"Micro Mini 1GB",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
-#ifdef CONFIG_USB_STORAGE_SDDR55
-UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999,
- "Sandisk",
- "ImageMate SDDR55",
- US_SC_SCSI, US_PR_SDDR55, NULL,
- US_FL_SINGLE_LUN),
-#endif
-
/* Reported by Andrew Simmons <andrew.simmons@gmail.com> */
UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
"DataStor",
diff --git a/drivers/usb/storage/cypress_atacb.h b/drivers/usb/storage/unusual_freecom.h
index fbada898d56b..375867942391 100644
--- a/drivers/usb/storage/cypress_atacb.h
+++ b/drivers/usb/storage/unusual_freecom.h
@@ -1,8 +1,4 @@
-/*
- * Support for emulating SAT (ata pass through) on devices based
- * on the Cypress USB/ATA bridge supporting ATACB.
- *
- * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr)
+/* Unusual Devices File for the Freecom USB/IDE adaptor
*
* 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
@@ -19,7 +15,12 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _CYPRESS_ATACB_H_
-#define _CYPRESS_ATACB_H_
-extern void cypress_atacb_passthrough(struct scsi_cmnd*, struct us_data*);
-#endif
+#if defined(CONFIG_USB_STORAGE_FREECOM) || \
+ defined(CONFIG_USB_STORAGE_FREECOM_MODULE)
+
+UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999,
+ "Freecom",
+ "USB-IDE",
+ US_SC_QIC, US_PR_FREECOM, init_freecom, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_FREECOM) || ... */
diff --git a/drivers/usb/storage/unusual_isd200.h b/drivers/usb/storage/unusual_isd200.h
new file mode 100644
index 000000000000..0d99dde3382a
--- /dev/null
+++ b/drivers/usb/storage/unusual_isd200.h
@@ -0,0 +1,57 @@
+/* Unusual Devices File for In-System Design, Inc. ISD200 ASIC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_USB_STORAGE_ISD200) || \
+ defined(CONFIG_USB_STORAGE_ISD200_MODULE)
+
+UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110,
+ "Sony",
+ "Portable USB Harddrive V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110,
+ "In-System",
+ "USB/IDE Bridge (ATA/ATAPI)",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110,
+ "In-System",
+ "Portable USB Harddrive V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110,
+ "In-System",
+ "Portable USB Harddrive V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110,
+ "In-System",
+ "USB Storage Adapter V2",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
+ "ATI",
+ "USB Cable 205",
+ US_SC_ISD200, US_PR_BULK, isd200_Initialization,
+ 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_ISD200) || ... */
diff --git a/drivers/usb/storage/sddr55.h b/drivers/usb/storage/unusual_jumpshot.h
index a815a0470c84..2e549b1c2c62 100644
--- a/drivers/usb/storage/sddr55.h
+++ b/drivers/usb/storage/unusual_jumpshot.h
@@ -1,10 +1,4 @@
-/* Driver for SanDisk SDDR-55 SmartMedia reader
- * Header File
- *
- * Current development and maintenance by:
- * (c) 2002 Simon Munton
- *
- * See sddr55.c for more explanation
+/* Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader
*
* 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
@@ -21,12 +15,13 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _USB_SHUTTLE_EUSB_SDDR55_H
-#define _USB_SHUTTLE_EUSB_SDDR55_H
-
-/* Sandisk SDDR-55 stuff */
+#if defined(CONFIG_USB_STORAGE_JUMPSHOT) || \
+ defined(CONFIG_USB_STORAGE_JUMPSHOT_MODULE)
-extern int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us);
-extern int sddr55_reset(struct us_data *us);
+UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001,
+ "Lexar",
+ "Jumpshot USB CF Reader",
+ US_SC_SCSI, US_PR_JUMPSHOT, NULL,
+ US_FL_NEED_OVERRIDE),
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_JUMPSHOT) || ... */
diff --git a/drivers/usb/storage/isd200.h b/drivers/usb/storage/unusual_karma.h
index 0a35f4fa78f8..12ae3a03e802 100644
--- a/drivers/usb/storage/isd200.h
+++ b/drivers/usb/storage/unusual_karma.h
@@ -1,11 +1,4 @@
-/* Header File for In-System Design, Inc. ISD200 ASIC
- *
- * First release
- *
- * Current development and maintenance by:
- * (c) 2000 In-System Design, Inc. (support@in-system.com)
- *
- * See isd200.c for more information.
+/* Unusual Devices File for the Rio Karma
*
* 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
@@ -22,10 +15,12 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _USB_ISD200_H
-#define _USB_ISD200_H
+#if defined(CONFIG_USB_STORAGE_KARMA) || \
+ defined(CONFIG_USB_STORAGE_KARMA_MODULE)
-extern void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us);
-extern int isd200_Initialization(struct us_data *us);
+UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101,
+ "Rio",
+ "Rio Karma",
+ US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),
-#endif
+#endif /* defined(CONFIG_USB_STORAGE_KARMA) || ... */
diff --git a/drivers/usb/storage/unusual_onetouch.h b/drivers/usb/storage/unusual_onetouch.h
new file mode 100644
index 000000000000..bd9306b637df
--- /dev/null
+++ b/drivers/usb/storage/unusual_onetouch.h
@@ -0,0 +1,36 @@
+/* Unusual Devices File for the Maxtor OneTouch USB hard drive's button
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_USB_STORAGE_ONETOUCH) || \
+ defined(CONFIG_USB_STORAGE_ONETOUCH_MODULE)
+
+/* Submitted by: Nick Sillik <n.sillik@temple.edu>
+ * Needed for OneTouch extension to usb-storage
+ */
+UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999,
+ "Maxtor",
+ "OneTouch External Harddrive",
+ US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+ 0),
+
+UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999,
+ "Maxtor",
+ "OneTouch External Harddrive",
+ US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input,
+ 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_ONETOUCH) || ... */
diff --git a/drivers/usb/storage/unusual_sddr09.h b/drivers/usb/storage/unusual_sddr09.h
new file mode 100644
index 000000000000..50cab511a4d7
--- /dev/null
+++ b/drivers/usb/storage/unusual_sddr09.h
@@ -0,0 +1,56 @@
+/* Unusual Devices File for SanDisk SDDR-09 SmartMedia reader
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_USB_STORAGE_SDDR09) || \
+ defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
+
+UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100,
+ "Microtech",
+ "CameraMate (DPCM_USB)",
+ US_SC_SCSI, US_PR_DPCM_USB, NULL, 0),
+
+UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999,
+ "Sandisk",
+ "ImageMate SDDR09",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+ 0),
+
+/* This entry is from Andries.Brouwer@cwi.nl */
+UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208,
+ "SCM Microsystems",
+ "eUSB SmartMedia / CompactFlash Adapter",
+ US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
+ 0),
+
+UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100,
+ "Olympus",
+ "Camedia MAUSB-2",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+ 0),
+
+UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999,
+ "Sandisk",
+ "ImageMate SDDR-09",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+ 0),
+
+UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100,
+ "Microtech",
+ "CameraMate (DPCM_USB)",
+ US_SC_SCSI, US_PR_DPCM_USB, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_SDDR09) || ... */
diff --git a/drivers/usb/storage/unusual_sddr55.h b/drivers/usb/storage/unusual_sddr55.h
new file mode 100644
index 000000000000..ae81ef7a1cfd
--- /dev/null
+++ b/drivers/usb/storage/unusual_sddr55.h
@@ -0,0 +1,44 @@
+/* Unusual Devices File for SanDisk SDDR-55 SmartMedia reader
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_USB_STORAGE_SDDR55) || \
+ defined(CONFIG_USB_STORAGE_SDDR55_MODULE)
+
+/* Contributed by Peter Waechtler */
+UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999,
+ "Datafab",
+ "MDSM-B reader",
+ US_SC_SCSI, US_PR_SDDR55, NULL,
+ US_FL_FIX_INQUIRY),
+
+/* SM part - aeb <Andries.Brouwer@cwi.nl> */
+UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff,
+ "Datafab Systems, Inc.",
+ "USB to CF + SM Combo (LC1)",
+ US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff,
+ "Acomdata",
+ "SM",
+ US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999,
+ "Sandisk",
+ "ImageMate SDDR55",
+ US_SC_SCSI, US_PR_SDDR55, NULL, 0),
+
+#endif /* defined(CONFIG_USB_STORAGE_SDDR55) || ... */
diff --git a/drivers/usb/storage/unusual_usbat.h b/drivers/usb/storage/unusual_usbat.h
new file mode 100644
index 000000000000..80e869f10180
--- /dev/null
+++ b/drivers/usb/storage/unusual_usbat.h
@@ -0,0 +1,43 @@
+/* Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(CONFIG_USB_STORAGE_USBAT) || \
+ defined(CONFIG_USB_STORAGE_USBAT_MODULE)
+
+UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001,
+ "HP",
+ "CD-Writer+ 8200e",
+ US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
+
+UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001,
+ "HP",
+ "CD-Writer+ CD-4e",
+ US_SC_8070, US_PR_USBAT, init_usbat_cd, 0),
+
+UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999,
+ "Shuttle/SCM",
+ "USBAT-02",
+ US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
+ US_FL_SINGLE_LUN),
+
+UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005,
+ "Sandisk",
+ "ImageMate SDDR-05b",
+ US_SC_SCSI, US_PR_USBAT, init_usbat_flash,
+ US_FL_SINGLE_LUN),
+
+#endif /* defined(CONFIG_USB_STORAGE_USBAT) || ... */
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 4becf495ca2d..8060b85fe1a3 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -5,7 +5,7 @@
*
* Developed with the assistance of:
* (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
- * (c) 2003 Alan Stern (stern@rowland.harvard.edu)
+ * (c) 2003-2009 Alan Stern (stern@rowland.harvard.edu)
*
* Initial work by:
* (c) 1999 Michael Gee (michael@linuxspecific.com)
@@ -66,39 +66,6 @@
#include "debug.h"
#include "initializers.h"
-#ifdef CONFIG_USB_STORAGE_USBAT
-#include "shuttle_usbat.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#include "sddr09.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#include "sddr55.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#include "freecom.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ISD200
-#include "isd200.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#include "datafab.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#include "jumpshot.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ONETOUCH
-#include "onetouch.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_ALAUDA
-#include "alauda.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_KARMA
-#include "karma.h"
-#endif
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
-#include "cypress_atacb.h"
-#endif
#include "sierra_ms.h"
#include "option_ms.h"
@@ -118,36 +85,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
/*
* The entries in this table correspond, line for line,
- * with the entries of us_unusual_dev_list[].
+ * with the entries in usb_storage_usb_ids[], defined in usual-tables.c.
*/
-#ifndef CONFIG_USB_LIBUSUAL
-
-#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
- vendorName, productName,useProtocol, useTransport, \
- initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
- .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
-
-#define COMPLIANT_DEV UNUSUAL_DEV
-
-#define USUAL_DEV(useProto, useTrans, useType) \
-{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
- .driver_info = (USB_US_TYPE_STOR<<24) }
-
-static struct usb_device_id storage_usb_ids [] = {
-
-# include "unusual_devs.h"
-#undef UNUSUAL_DEV
-#undef COMPLIANT_DEV
-#undef USUAL_DEV
- /* Terminating entry */
- { }
-};
-
-MODULE_DEVICE_TABLE (usb, storage_usb_ids);
-#endif /* CONFIG_USB_LIBUSUAL */
-
-/* This is the list of devices we recognize, along with their flag data */
/* The vendor name should be kept at eight characters or less, and
* the product name should be kept at 16 characters or less. If a device
@@ -179,18 +118,17 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
static struct us_unusual_dev us_unusual_dev_list[] = {
# include "unusual_devs.h"
-# undef UNUSUAL_DEV
-# undef COMPLIANT_DEV
-# undef USUAL_DEV
-
- /* Terminating entry */
- { NULL }
+ { } /* Terminating entry */
};
+#undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
+#undef USUAL_DEV
+
#ifdef CONFIG_PM /* Minimal support for suspend and resume */
-static int storage_suspend(struct usb_interface *iface, pm_message_t message)
+int usb_stor_suspend(struct usb_interface *iface, pm_message_t message)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -207,8 +145,9 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message)
mutex_unlock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_suspend);
-static int storage_resume(struct usb_interface *iface)
+int usb_stor_resume(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -221,8 +160,9 @@ static int storage_resume(struct usb_interface *iface)
mutex_unlock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_resume);
-static int storage_reset_resume(struct usb_interface *iface)
+int usb_stor_reset_resume(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -235,6 +175,7 @@ static int storage_reset_resume(struct usb_interface *iface)
* the device */
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_reset_resume);
#endif /* CONFIG_PM */
@@ -243,7 +184,7 @@ static int storage_reset_resume(struct usb_interface *iface)
* a USB port reset, whether from this driver or a different one.
*/
-static int storage_pre_reset(struct usb_interface *iface)
+int usb_stor_pre_reset(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -253,8 +194,9 @@ static int storage_pre_reset(struct usb_interface *iface)
mutex_lock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_pre_reset);
-static int storage_post_reset(struct usb_interface *iface)
+int usb_stor_post_reset(struct usb_interface *iface)
{
struct us_data *us = usb_get_intfdata(iface);
@@ -269,6 +211,7 @@ static int storage_post_reset(struct usb_interface *iface)
mutex_unlock(&us->dev_mutex);
return 0;
}
+EXPORT_SYMBOL_GPL(usb_stor_post_reset);
/*
* fill_inquiry_response takes an unsigned char array (which must
@@ -311,6 +254,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
usb_stor_set_xfer_buf(data, data_len, us->srb);
}
+EXPORT_SYMBOL_GPL(fill_inquiry_response);
static int usb_stor_control_thread(void * __us)
{
@@ -551,20 +495,13 @@ static void adjust_quirks(struct us_data *us)
vid, pid, f);
}
-/* Find an unusual_dev descriptor (always succeeds in the current code) */
-static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
-{
- const int id_index = id - storage_usb_ids;
- return &us_unusual_dev_list[id_index];
-}
-
/* Get the unusual_devs entries and the string descriptors */
-static int get_device_info(struct us_data *us, const struct usb_device_id *id)
+static int get_device_info(struct us_data *us, const struct usb_device_id *id,
+ struct us_unusual_dev *unusual_dev)
{
struct usb_device *dev = us->pusb_dev;
struct usb_interface_descriptor *idesc =
&us->pusb_intf->cur_altsetting->desc;
- struct us_unusual_dev *unusual_dev = find_unusual(id);
/* Store the entries */
us->unusual_dev = unusual_dev;
@@ -629,7 +566,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
}
/* Get the transport settings */
-static int get_transport(struct us_data *us)
+static void get_transport(struct us_data *us)
{
switch (us->protocol) {
case US_PR_CB:
@@ -651,100 +588,11 @@ static int get_transport(struct us_data *us)
us->transport = usb_stor_Bulk_transport;
us->transport_reset = usb_stor_Bulk_reset;
break;
-
-#ifdef CONFIG_USB_STORAGE_USBAT
- case US_PR_USBAT:
- us->transport_name = "Shuttle USBAT";
- us->transport = usbat_transport;
- us->transport_reset = usb_stor_CB_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
- case US_PR_EUSB_SDDR09:
- us->transport_name = "EUSB/SDDR09";
- us->transport = sddr09_transport;
- us->transport_reset = usb_stor_CB_reset;
- us->max_lun = 0;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_SDDR55
- case US_PR_SDDR55:
- us->transport_name = "SDDR55";
- us->transport = sddr55_transport;
- us->transport_reset = sddr55_reset;
- us->max_lun = 0;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DPCM
- case US_PR_DPCM_USB:
- us->transport_name = "Control/Bulk-EUSB/SDDR09";
- us->transport = dpcm_transport;
- us->transport_reset = usb_stor_CB_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
- case US_PR_FREECOM:
- us->transport_name = "Freecom";
- us->transport = freecom_transport;
- us->transport_reset = usb_stor_freecom_reset;
- us->max_lun = 0;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
- case US_PR_DATAFAB:
- us->transport_name = "Datafab Bulk-Only";
- us->transport = datafab_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
- case US_PR_JUMPSHOT:
- us->transport_name = "Lexar Jumpshot Control/Bulk";
- us->transport = jumpshot_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_ALAUDA
- case US_PR_ALAUDA:
- us->transport_name = "Alauda Control/Bulk";
- us->transport = alauda_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- us->max_lun = 1;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_KARMA
- case US_PR_KARMA:
- us->transport_name = "Rio Karma/Bulk";
- us->transport = rio_karma_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- break;
-#endif
-
- default:
- return -EIO;
}
- US_DEBUGP("Transport: %s\n", us->transport_name);
-
- /* fix for single-lun devices */
- if (us->fflags & US_FL_SINGLE_LUN)
- us->max_lun = 0;
- return 0;
}
/* Get the protocol settings */
-static int get_protocol(struct us_data *us)
+static void get_protocol(struct us_data *us)
{
switch (us->subclass) {
case US_SC_RBC:
@@ -779,26 +627,7 @@ static int get_protocol(struct us_data *us)
us->protocol_name = "Uniform Floppy Interface (UFI)";
us->proto_handler = usb_stor_ufi_command;
break;
-
-#ifdef CONFIG_USB_STORAGE_ISD200
- case US_SC_ISD200:
- us->protocol_name = "ISD200 ATA/ATAPI";
- us->proto_handler = isd200_ata_command;
- break;
-#endif
-
-#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
- case US_SC_CYP_ATACB:
- us->protocol_name = "Transparent SCSI with Cypress ATACB";
- us->proto_handler = cypress_atacb_passthrough;
- break;
-#endif
-
- default:
- return -EIO;
}
- US_DEBUGP("Protocol: %s\n", us->protocol_name);
- return 0;
}
/* Get the pipe settings */
@@ -846,12 +675,12 @@ static int get_pipes(struct us_data *us)
us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev,
- ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_out));
us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev,
- ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_in));
if (ep_int) {
us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev,
- ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_int));
us->ep_bInterval = ep_int->bInterval;
}
return 0;
@@ -1012,17 +841,15 @@ static int usb_stor_scan_thread(void * __us)
}
-/* Probe to see if we can drive a newly-connected USB device */
-static int storage_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+/* First part of general USB mass-storage probing */
+int usb_stor_probe1(struct us_data **pus,
+ struct usb_interface *intf,
+ const struct usb_device_id *id,
+ struct us_unusual_dev *unusual_dev)
{
struct Scsi_Host *host;
struct us_data *us;
int result;
- struct task_struct *th;
-
- if (usb_usual_check_type(id, USB_US_TYPE_STOR))
- return -ENXIO;
US_DEBUGP("USB Mass Storage device detected\n");
@@ -1041,7 +868,7 @@ static int storage_probe(struct usb_interface *intf,
* Allow 16-byte CDBs and thus > 2TB
*/
host->max_cmd_len = 16;
- us = host_to_us(host);
+ *pus = us = host_to_us(host);
memset(us, 0, sizeof(struct us_data));
mutex_init(&(us->dev_mutex));
init_completion(&us->cmnd_ready);
@@ -1054,24 +881,46 @@ static int storage_probe(struct usb_interface *intf,
if (result)
goto BadDevice;
- /*
- * Get the unusual_devs entries and the descriptors
- *
- * id_index is calculated in the declaration to be the index number
- * of the match from the usb_device_id table, so we can find the
- * corresponding entry in the private table.
- */
- result = get_device_info(us, id);
+ /* Get the unusual_devs entries and the descriptors */
+ result = get_device_info(us, id, unusual_dev);
if (result)
goto BadDevice;
- /* Get the transport, protocol, and pipe settings */
- result = get_transport(us);
- if (result)
- goto BadDevice;
- result = get_protocol(us);
- if (result)
+ /* Get standard transport and protocol settings */
+ get_transport(us);
+ get_protocol(us);
+
+ /* Give the caller a chance to fill in specialized transport
+ * or protocol settings.
+ */
+ return 0;
+
+BadDevice:
+ US_DEBUGP("storage_probe() failed\n");
+ release_everything(us);
+ return result;
+}
+EXPORT_SYMBOL_GPL(usb_stor_probe1);
+
+/* Second part of general USB mass-storage probing */
+int usb_stor_probe2(struct us_data *us)
+{
+ struct task_struct *th;
+ int result;
+
+ /* Make sure the transport and protocol have both been set */
+ if (!us->transport || !us->proto_handler) {
+ result = -ENXIO;
goto BadDevice;
+ }
+ US_DEBUGP("Transport: %s\n", us->transport_name);
+ US_DEBUGP("Protocol: %s\n", us->protocol_name);
+
+ /* fix for single-lun devices */
+ if (us->fflags & US_FL_SINGLE_LUN)
+ us->max_lun = 0;
+
+ /* Find the endpoints and calculate pipe values */
result = get_pipes(us);
if (result)
goto BadDevice;
@@ -1080,7 +929,7 @@ static int storage_probe(struct usb_interface *intf,
result = usb_stor_acquire_resources(us);
if (result)
goto BadDevice;
- result = scsi_add_host(host, &intf->dev);
+ result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev);
if (result) {
printk(KERN_WARNING USB_STORAGE
"Unable to add the scsi host\n");
@@ -1108,9 +957,10 @@ BadDevice:
release_everything(us);
return result;
}
+EXPORT_SYMBOL_GPL(usb_stor_probe2);
-/* Handle a disconnect event from the USB core */
-static void storage_disconnect(struct usb_interface *intf)
+/* Handle a USB mass-storage disconnect */
+void usb_stor_disconnect(struct usb_interface *intf)
{
struct us_data *us = usb_get_intfdata(intf);
@@ -1118,6 +968,42 @@ static void storage_disconnect(struct usb_interface *intf)
quiesce_and_remove_host(us);
release_everything(us);
}
+EXPORT_SYMBOL_GPL(usb_stor_disconnect);
+
+/* The main probe routine for standard devices */
+static int storage_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+
+ /*
+ * If libusual is configured, let it decide whether a standard
+ * device should be handled by usb-storage or by ub.
+ * If the device isn't standard (is handled by a subdriver
+ * module) then don't accept it.
+ */
+ if (usb_usual_check_type(id, USB_US_TYPE_STOR) ||
+ usb_usual_ignore_device(intf))
+ return -ENXIO;
+
+ /*
+ * Call the general probe procedures.
+ *
+ * The unusual_dev_list array is parallel to the usb_storage_usb_ids
+ * table, so we use the index of the id entry to find the
+ * corresponding unusual_devs entry.
+ */
+ result = usb_stor_probe1(&us, intf, id,
+ (id - usb_storage_usb_ids) + us_unusual_dev_list);
+ if (result)
+ return result;
+
+ /* No special transport or protocol settings in the main module */
+
+ result = usb_stor_probe2(us);
+ return result;
+}
/***********************************************************************
* Initialization and registration
@@ -1126,15 +1012,13 @@ static void storage_disconnect(struct usb_interface *intf)
static struct usb_driver usb_storage_driver = {
.name = "usb-storage",
.probe = storage_probe,
- .disconnect = storage_disconnect,
-#ifdef CONFIG_PM
- .suspend = storage_suspend,
- .resume = storage_resume,
- .reset_resume = storage_reset_resume,
-#endif
- .pre_reset = storage_pre_reset,
- .post_reset = storage_post_reset,
- .id_table = storage_usb_ids,
+ .disconnect = usb_stor_disconnect,
+ .suspend = usb_stor_suspend,
+ .resume = usb_stor_resume,
+ .reset_resume = usb_stor_reset_resume,
+ .pre_reset = usb_stor_pre_reset,
+ .post_reset = usb_stor_post_reset,
+ .id_table = usb_storage_usb_ids,
.soft_unbind = 1,
};
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 65e674e4be99..2609efb2bd7e 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -177,4 +177,25 @@ extern void fill_inquiry_response(struct us_data *us,
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
#define scsi_lock(host) spin_lock_irq(host->host_lock)
+/* General routines provided by the usb-storage standard core */
+#ifdef CONFIG_PM
+extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message);
+extern int usb_stor_resume(struct usb_interface *iface);
+extern int usb_stor_reset_resume(struct usb_interface *iface);
+#else
+#define usb_stor_suspend NULL
+#define usb_stor_resume NULL
+#define usb_stor_reset_resume NULL
+#endif
+
+extern int usb_stor_pre_reset(struct usb_interface *iface);
+extern int usb_stor_post_reset(struct usb_interface *iface);
+
+extern int usb_stor_probe1(struct us_data **pus,
+ struct usb_interface *intf,
+ const struct usb_device_id *id,
+ struct us_unusual_dev *unusual_dev);
+extern int usb_stor_probe2(struct us_data *us);
+extern void usb_stor_disconnect(struct usb_interface *intf);
+
#endif
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c
new file mode 100644
index 000000000000..468bde7d1971
--- /dev/null
+++ b/drivers/usb/storage/usual-tables.c
@@ -0,0 +1,116 @@
+/* Driver for USB Mass Storage devices
+ * Usual Tables File for usb-storage and libusual
+ *
+ * Copyright (C) 2009 Alan Stern (stern@rowland.harvard.edu)
+ *
+ * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
+ * information about this driver.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+
+
+/*
+ * The table of devices
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
+ .driver_info = (flags) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+ .driver_info = ((useType)<<24) }
+
+struct usb_device_id usb_storage_usb_ids[] = {
+# include "unusual_devs.h"
+ { } /* Terminating entry */
+};
+EXPORT_SYMBOL_GPL(usb_storage_usb_ids);
+
+MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);
+
+#undef UNUSUAL_DEV
+#undef COMPLIANT_DEV
+#undef USUAL_DEV
+
+
+/*
+ * The table of devices to ignore
+ */
+struct ignore_entry {
+ u16 vid, pid, bcdmin, bcdmax;
+};
+
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+ vendorName, productName, useProtocol, useTransport, \
+ initFunction, flags) \
+{ \
+ .vid = id_vendor, \
+ .pid = id_product, \
+ .bcdmin = bcdDeviceMin, \
+ .bcdmax = bcdDeviceMax, \
+}
+
+static struct ignore_entry ignore_ids[] = {
+# include "unusual_alauda.h"
+# include "unusual_cypress.h"
+# include "unusual_datafab.h"
+# include "unusual_freecom.h"
+# include "unusual_isd200.h"
+# include "unusual_jumpshot.h"
+# include "unusual_karma.h"
+# include "unusual_onetouch.h"
+# include "unusual_sddr09.h"
+# include "unusual_sddr55.h"
+# include "unusual_usbat.h"
+ { } /* Terminating entry */
+};
+
+#undef UNUSUAL_DEV
+
+
+/* Return an error if a device is in the ignore_ids list */
+int usb_usual_ignore_device(struct usb_interface *intf)
+{
+ struct usb_device *udev;
+ unsigned vid, pid, bcd;
+ struct ignore_entry *p;
+
+ udev = interface_to_usbdev(intf);
+ vid = le16_to_cpu(udev->descriptor.idVendor);
+ pid = le16_to_cpu(udev->descriptor.idProduct);
+ bcd = le16_to_cpu(udev->descriptor.bcdDevice);
+
+ for (p = ignore_ids; p->vid; ++p) {
+ if (p->vid == vid && p->pid == pid &&
+ p->bcdmin <= bcd && p->bcdmax >= bcd)
+ return -ENXIO;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usb_usual_ignore_device);
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index be76084c8d7e..60ba631e99c2 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -410,7 +410,9 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
}
/* let the user know what node this device is now attached to */
- info("USB Skeleton device now attached to USBSkel-%d", interface->minor);
+ dev_info(&interface->dev,
+ "USB Skeleton device now attached to USBSkel-%d",
+ interface->minor);
return 0;
error:
@@ -441,7 +443,7 @@ static void skel_disconnect(struct usb_interface *interface)
/* decrement our usage count */
kref_put(&dev->kref, skel_delete);
- info("USB Skeleton #%d now disconnected", minor);
+ dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
}
static void skel_draw_down(struct usb_skel *dev)
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index e2e7e4bc8463..f0aac0cf315a 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -386,6 +386,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
| USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
if (wusb_dev) {
+ dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx);
if (!list_empty(&wusb_dev->cack_node))
list_del_init(&wusb_dev->cack_node);
/* For the one in cack_add() */
@@ -888,6 +889,8 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev)
if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
return; /* skip non wusb and wusb RHs */
+ usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED);
+
wusbhc = wusbhc_get_by_usb_dev(usb_dev);
if (wusbhc == NULL)
goto error_nodev;
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c
index 3937bf6f8cef..9fe4246cecb9 100644
--- a/drivers/usb/wusbcore/rh.c
+++ b/drivers/usb/wusbcore/rh.c
@@ -100,6 +100,9 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);
struct wusb_dev *wusb_dev = port->wusb_dev;
+ if (wusb_dev == NULL)
+ return -ENOTCONN;
+
port->status |= USB_PORT_STAT_RESET;
port->change |= USB_PORT_STAT_C_RESET;
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index f4aa28eca70d..8118db7f1d8d 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -312,6 +312,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
result = wusb_set_dev_addr(wusbhc, wusb_dev, 0);
if (result < 0)
goto error_addr0;
+ usb_set_device_state(usb_dev, USB_STATE_DEFAULT);
usb_ep0_reinit(usb_dev);
/* Set new (authenticated) address. */
@@ -327,6 +328,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address);
if (result < 0)
goto error_addr;
+ usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
usb_ep0_reinit(usb_dev);
usb_dev->authenticated = 1;
error_addr:
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c
index c8185e6b0cd5..c13cec7dcbc5 100644
--- a/drivers/uwb/allocator.c
+++ b/drivers/uwb/allocator.c
@@ -15,7 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/uwb.h>
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 2b4f9406789d..4f5ca99a04b9 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -66,14 +66,14 @@ static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg,
} else
dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n");
- spin_lock(&rc->rsvs_lock);
+ spin_lock_bh(&rc->rsvs_lock);
if (rc->set_drp_ie_pending > 1) {
rc->set_drp_ie_pending = 0;
uwb_rsv_queue_update(rc);
} else {
rc->set_drp_ie_pending = 0;
}
- spin_unlock(&rc->rsvs_lock);
+ spin_unlock_bh(&rc->rsvs_lock);
}
/**
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index ec6eecb32f30..6b76f4bb4cc7 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -114,7 +114,8 @@ void uwb_rsv_dump(char *text, struct uwb_rsv *rsv)
devaddr = rsv->target.devaddr;
uwb_dev_addr_print(target, sizeof(target), &devaddr);
- dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state));
+ dev_dbg(dev, "rsv %s %s -> %s: %s\n",
+ text, owner, target, uwb_rsv_state_str(rsv->state));
}
static void uwb_rsv_release(struct kref *kref)
@@ -511,8 +512,7 @@ void uwb_rsv_remove(struct uwb_rsv *rsv)
if (uwb_rsv_is_owner(rsv))
uwb_rsv_put_stream(rsv);
-
- del_timer_sync(&rsv->timer);
+
uwb_dev_put(rsv->owner);
if (rsv->target.type == UWB_RSV_TARGET_DEV)
uwb_dev_put(rsv->target.dev);
@@ -870,7 +870,7 @@ void uwb_rsv_queue_update(struct uwb_rc *rc)
*/
void uwb_rsv_sched_update(struct uwb_rc *rc)
{
- spin_lock(&rc->rsvs_lock);
+ spin_lock_bh(&rc->rsvs_lock);
if (!delayed_work_pending(&rc->rsv_update_work)) {
if (rc->set_drp_ie_pending > 0) {
rc->set_drp_ie_pending++;
@@ -879,7 +879,7 @@ void uwb_rsv_sched_update(struct uwb_rc *rc)
uwb_rsv_queue_update(rc);
}
unlock:
- spin_unlock(&rc->rsvs_lock);
+ spin_unlock_bh(&rc->rsvs_lock);
}
/*
@@ -943,13 +943,22 @@ void uwb_rsv_remove_all(struct uwb_rc *rc)
mutex_lock(&rc->rsvs_mutex);
list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
- uwb_rsv_remove(rsv);
+ if (rsv->state != UWB_RSV_STATE_NONE)
+ uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE);
+ del_timer_sync(&rsv->timer);
}
/* Cancel any postponed update. */
rc->set_drp_ie_pending = 0;
mutex_unlock(&rc->rsvs_mutex);
cancel_delayed_work_sync(&rc->rsv_update_work);
+ flush_workqueue(rc->rsv_workq);
+
+ mutex_lock(&rc->rsvs_mutex);
+ list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) {
+ uwb_rsv_remove(rsv);
+ }
+ mutex_unlock(&rc->rsvs_mutex);
}
void uwb_rsv_init(struct uwb_rc *rc)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6372f8b17b45..b82aee5ae943 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -41,7 +41,7 @@ menuconfig FB
You need an utility program called fbset to make full use of frame
buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
and the Framebuffer-HOWTO at
- <http://www.tahallah.demon.co.uk/programming/prog.html> for more
+ <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.2.html> for more
information.
Say Y here and to the driver for your graphics board below if you
@@ -1054,9 +1054,7 @@ config FB_RIVA_BACKLIGHT
config FB_I810
tristate "Intel 810/815 support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86_32
- select AGP
- select AGP_INTEL
+ depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1119,9 +1117,7 @@ config FB_CARILLO_RANCH
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)"
- depends on FB && EXPERIMENTAL && PCI && X86
- select AGP
- select AGP_INTEL
+ depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL
select FB_MODE_HELPERS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -2123,6 +2119,32 @@ config FB_PRE_INIT_FB
Select this option if display contents should be inherited as set by
the bootloader.
+config FB_MX3
+ tristate "MX3 Framebuffer support"
+ depends on FB && MX3_IPU
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+ help
+ This is a framebuffer device for the i.MX31 LCD Controller. So
+ far only synchronous displays are supported. If you plan to use
+ an LCD display with your i.MX31 system, say Y here.
+
+config FB_BROADSHEET
+ tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This driver implements support for the E-Ink Broadsheet
+ controller. The release name for this device was Epson S1D13521
+ and could also have been called by other names when coupled with
+ a bridge adapter.
+
source "drivers/video/omap/Kconfig"
source "drivers/video/backlight/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index be2b657546ef..edd5a85c1eb5 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
obj-$(CONFIG_FB_MAXINE) += maxinefb.o
obj-$(CONFIG_FB_METRONOME) += metronomefb.o
+obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_SH7760) += sh7760fb.o
obj-$(CONFIG_FB_IMX) += imxfb.o
@@ -132,6 +133,7 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o
obj-$(CONFIG_FB_OF) += offb.o
obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
+obj-$(CONFIG_FB_MX3) += mx3fb.o
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 8058572a7428..018850c116c6 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -841,7 +841,7 @@ static int tt_detect(void)
tt_dmasnd.ctrl = DMASND_CTRL_OFF;
udelay(20); /* wait a while for things to settle down */
}
- mono_moni = (mfp.par_dt_reg & 0x80) == 0;
+ mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
tt_get_par(&par);
tt_encode_var(&atafb_predefined[0], &par);
@@ -2035,7 +2035,7 @@ static int stste_detect(void)
tt_dmasnd.ctrl = DMASND_CTRL_OFF;
udelay(20); /* wait a while for things to settle down */
}
- mono_moni = (mfp.par_dt_reg & 0x80) == 0;
+ mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
stste_get_par(&par);
stste_encode_var(&atafb_predefined[0], &par);
@@ -2086,20 +2086,20 @@ static void st_ovsc_switch(void)
return;
local_irq_save(flags);
- mfp.tim_ct_b = 0x10;
- mfp.active_edge |= 8;
- mfp.tim_ct_b = 0;
- mfp.tim_dt_b = 0xf0;
- mfp.tim_ct_b = 8;
- while (mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */
+ st_mfp.tim_ct_b = 0x10;
+ st_mfp.active_edge |= 8;
+ st_mfp.tim_ct_b = 0;
+ st_mfp.tim_dt_b = 0xf0;
+ st_mfp.tim_ct_b = 8;
+ while (st_mfp.tim_dt_b > 1) /* TOS does it this way, don't ask why */
;
- new = mfp.tim_dt_b;
+ new = st_mfp.tim_dt_b;
do {
udelay(LINE_DELAY);
old = new;
- new = mfp.tim_dt_b;
+ new = st_mfp.tim_dt_b;
} while (old != new);
- mfp.tim_ct_b = 0x10;
+ st_mfp.tim_ct_b = 0x10;
udelay(SYNC_DELAY);
if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index db16112cf197..2181ce4d7ebd 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1475,7 +1475,7 @@ static int aty128fb_set_par(struct fb_info *info)
aty128_set_pll(&par->pll, par);
aty128_set_fifo(&par->fifo_reg, par);
- config = aty_ld_le32(CONFIG_CNTL) & ~3;
+ config = aty_ld_le32(CNFG_CNTL) & ~3;
#if defined(__BIG_ENDIAN)
if (par->crtc.bpp == 32)
@@ -1484,7 +1484,7 @@ static int aty128fb_set_par(struct fb_info *info)
config |= 1; /* make aperture do 16 bit swapping */
#endif
- aty_st_le32(CONFIG_CNTL, config);
+ aty_st_le32(CNFG_CNTL, config);
aty_st_8(CRTC_EXT_CNTL + 1, 0); /* turn the video back on */
info->fix.line_length = (par->crtc.vxres * par->crtc.bpp) >> 3;
@@ -1875,7 +1875,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
u32 dac;
/* Get the chip revision */
- chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
+ chip_rev = (aty_ld_le32(CNFG_CNTL) >> 16) & 0x1F;
strcpy(video_card, "Rage128 XX ");
video_card[8] = ent->device >> 8;
@@ -2057,7 +2057,7 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_
/* Grab memory size from the card */
// How does this relate to the resource length from the PCI hardware?
- par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+ par->vram_size = aty_ld_le32(CNFG_MEMSIZE) & 0x03FFFFFF;
/* Virtualize the framebuffer */
info->screen_base = ioremap(fb_addr, par->vram_size);
@@ -2365,7 +2365,6 @@ static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, int dx
static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
{
u32 pmgt;
- u16 pwr_command;
struct pci_dev *pdev = par->pdev;
if (!par->pm_reg)
@@ -2374,6 +2373,8 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
/* Set the chip into the appropriate suspend mode (we use D2,
* D3 would require a complete re-initialisation of the chip,
* including PCI config registers, clocks, AGP configuration, ...)
+ *
+ * For resume, the core will have already brought us back to D0
*/
if (suspend) {
/* Make sure CRTC2 is reset. Remove that the day we decide to
@@ -2391,17 +2392,9 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
aty_st_le32(BUS_CNTL1, 0x00000010);
aty_st_le32(MEM_POWER_MISC, 0x0c830000);
mdelay(100);
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
+
/* Switch PCI power management to D2 */
- pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL,
- (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | 2);
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
- } else {
- /* Switch back PCI power management to D0 */
- mdelay(100);
- pci_write_config_word(pdev, par->pm_reg+PCI_PM_CTRL, 0);
- pci_read_config_word(pdev, par->pm_reg+PCI_PM_CTRL, &pwr_command);
- mdelay(100);
+ pci_set_power_state(pdev, PCI_D2);
}
}
@@ -2410,6 +2403,12 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
struct fb_info *info = pci_get_drvdata(pdev);
struct aty128fb_par *par = info->par;
+ /* Because we may change PCI D state ourselves, we need to
+ * first save the config space content so the core can
+ * restore it properly on resume.
+ */
+ pci_save_state(pdev);
+
/* We don't do anything but D2, for now we return 0, but
* we may want to change that. How do we know if the BIOS
* can properly take care of D3 ? Also, with swsusp, we
@@ -2476,6 +2475,11 @@ static int aty128_do_resume(struct pci_dev *pdev)
if (pdev->dev.power.power_state.event == PM_EVENT_ON)
return 0;
+ /* PCI state will have been restored by the core, so
+ * we should be in D0 now with our config space fully
+ * restored
+ */
+
/* Wakeup chip */
aty128_set_suspend(par, 0);
par->asleep = 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index cc6b470073da..1207c208a30b 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -135,7 +135,7 @@
#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \
defined (CONFIG_FB_ATY_GENERIC_LCD) || defined(CONFIG_FB_ATY_BACKLIGHT)
static const u32 lt_lcd_regs[] = {
- CONFIG_PANEL_LG,
+ CNFG_PANEL_LG,
LCD_GEN_CNTL_LG,
DSTN_CONTROL_LG,
HFB_PITCH_ADDR_LG,
@@ -446,7 +446,7 @@ static int __devinit correct_chipset(struct atyfb_par *par)
par->pll_limits.ecp_max = aty_chips[i].ecp_max;
par->features = aty_chips[i].features;
- chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
+ chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
type = chip_id & CFG_CHIP_TYPE;
rev = (chip_id & CFG_CHIP_REV) >> 24;
@@ -629,7 +629,7 @@ static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc)
crtc->lcd_index = aty_ld_le32(LCD_INDEX, par);
aty_st_le32(LCD_INDEX, crtc->lcd_index, par);
}
- crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par);
+ crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par);
crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par);
@@ -676,7 +676,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN), par);
/* update non-shadow registers first */
- aty_st_lcd(CONFIG_PANEL, crtc->lcd_config_panel, par);
+ aty_st_lcd(CNFG_PANEL, crtc->lcd_config_panel, par);
aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl &
~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN), par);
@@ -858,7 +858,7 @@ static int aty_var_to_crtc(const struct fb_info *info,
if (!M64_HAS(MOBIL_BUS))
crtc->lcd_index |= CRTC2_DISPLAY_DIS;
- crtc->lcd_config_panel = aty_ld_lcd(CONFIG_PANEL, par) | 0x4000;
+ crtc->lcd_config_panel = aty_ld_lcd(CNFG_PANEL, par) | 0x4000;
crtc->lcd_gen_cntl = aty_ld_lcd(LCD_GEN_CNTL, par) & ~CRTC_RW_SELECT;
crtc->lcd_gen_cntl &=
@@ -1978,7 +1978,7 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
return timeout ? 0 : -EIO;
}
-#endif
+#endif /* CONFIG_PPC_PMAC */
static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -2002,9 +2002,15 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
par->asleep = 1;
par->lock_blank = 1;
+ /* Because we may change PCI D state ourselves, we need to
+ * first save the config space content so the core can
+ * restore it properly on resume.
+ */
+ pci_save_state(pdev);
+
#ifdef CONFIG_PPC_PMAC
/* Set chip to "suspend" mode */
- if (aty_power_mgmt(1, par)) {
+ if (machine_is(powermac) && aty_power_mgmt(1, par)) {
par->asleep = 0;
par->lock_blank = 0;
atyfb_blank(FB_BLANK_UNBLANK, info);
@@ -2047,11 +2053,15 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
acquire_console_sem();
+ /* PCI state will have been restored by the core, so
+ * we should be in D0 now with our config space fully
+ * restored
+ */
+
#ifdef CONFIG_PPC_PMAC
- if (pdev->dev.power.power_state.event == 2)
+ if (machine_is(powermac) &&
+ pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
aty_power_mgmt(0, par);
-#else
- pci_set_power_state(pdev, PCI_D0);
#endif
aty_resume_chip(info);
@@ -2254,7 +2264,7 @@ static int __devinit aty_init(struct fb_info *info)
if (!M64_HAS(INTEGRATED)) {
u32 stat0;
u8 dac_type, dac_subtype, clk_type;
- stat0 = aty_ld_le32(CONFIG_STAT0, par);
+ stat0 = aty_ld_le32(CNFG_STAT0, par);
par->bus_type = (stat0 >> 0) & 0x07;
par->ram_type = (stat0 >> 3) & 0x07;
ramname = aty_gx_ram[par->ram_type];
@@ -2324,7 +2334,7 @@ static int __devinit aty_init(struct fb_info *info)
par->dac_ops = &aty_dac_ct;
par->pll_ops = &aty_pll_ct;
par->bus_type = PCI;
- par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
+ par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
ramname = aty_ct_ram[par->ram_type];
/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
@@ -2433,7 +2443,7 @@ static int __devinit aty_init(struct fb_info *info)
}
if (M64_HAS(MAGIC_VRAM_SIZE)) {
- if (aty_ld_le32(CONFIG_STAT1, par) & 0x40000000)
+ if (aty_ld_le32(CNFG_STAT1, par) & 0x40000000)
info->fix.smem_len += 0x400000;
}
@@ -2946,7 +2956,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
* Fix PROMs idea of MEM_CNTL settings...
*/
mem = aty_ld_le32(MEM_CNTL, par);
- chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
+ chip_id = aty_ld_le32(CNFG_CHIP_ID, par);
if (((chip_id & CFG_CHIP_TYPE) == VT_CHIP_ID) && !((chip_id >> 24) & 1)) {
switch (mem & 0x0f) {
case 3:
@@ -2964,7 +2974,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
default:
break;
}
- if ((aty_ld_le32(CONFIG_STAT0, par) & 7) >= SDRAM)
+ if ((aty_ld_le32(CNFG_STAT0, par) & 7) >= SDRAM)
mem &= ~(0x00700000);
}
mem &= ~(0xcf80e000); /* Turn off all undocumented bits. */
@@ -3572,7 +3582,7 @@ static int __init atyfb_atari_probe(void)
}
/* Fake pci_id for correct_chipset() */
- switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) {
+ switch (aty_ld_le32(CNFG_CHIP_ID, par) & CFG_CHIP_TYPE) {
case 0x00d7:
par->pci_id = PCI_CHIP_MACH64GX;
break;
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index c50c7cf26fe9..2745b8539485 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -8,6 +8,9 @@
#include <asm/io.h>
#include <video/mach64.h>
#include "atyfb.h"
+#ifdef CONFIG_PPC
+#include <asm/machdep.h>
+#endif
#undef DEBUG
@@ -536,6 +539,14 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info,
pll->ct.xclk_post_div_real = postdividers[xpost_div];
pll->ct.mclk_fb_div = q * pll->ct.xclk_post_div_real / 8;
+#ifdef CONFIG_PPC
+ if (machine_is(powermac)) {
+ /* Override PLL_EXT_CNTL & 0x07. */
+ pll->ct.xclk_post_div = xpost_div;
+ pll->ct.xclk_ref_div = 1;
+ }
+#endif
+
#ifdef DEBUG
pllmclk = (1000000 * pll->ct.mclk_fb_mult * pll->ct.mclk_fb_div) /
(par->ref_clk_per * pll->ct.pll_ref_div);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index d0f1a7fc2c9d..16bb7e3c0310 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1936,8 +1936,8 @@ static void fixup_memory_mappings(struct radeonfb_info *rinfo)
OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
mdelay(100);
- aper_base = INREG(CONFIG_APER_0_BASE);
- aper_size = INREG(CONFIG_APER_SIZE);
+ aper_base = INREG(CNFG_APER_0_BASE);
+ aper_size = INREG(CNFG_APER_SIZE);
#ifdef SET_MC_FB_FROM_APERTURE
/* Set framebuffer to be at the same address as set in PCI BAR */
@@ -2024,11 +2024,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
~CRTC_H_CUTOFF_ACTIVE_EN);
}
} else {
- tmp = INREG(CONFIG_MEMSIZE);
+ tmp = INREG(CNFG_MEMSIZE);
}
/* mem size is bits [28:0], mask off the rest */
- rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+ rinfo->video_ram = tmp & CNFG_MEMSIZE_MASK;
/*
* Hack to get around some busted production M6's
@@ -2228,7 +2228,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
*/
rinfo->errata = 0;
if (rinfo->family == CHIP_FAMILY_R300 &&
- (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK)
+ (INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK)
== CFG_ATI_REV_A11)
rinfo->errata |= CHIP_ERRATA_R300_CG;
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 2c5567175dca..359fc64e761a 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -72,7 +72,6 @@ static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name)
snprintf(chan->adapter.name, sizeof(chan->adapter.name),
"radeonfb %s", name);
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_RADEON;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->rinfo->pdev->dev;
chan->algo.setsda = radeon_gpio_setsda;
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 675abdafc2d8..ca5f0dc28546 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -333,7 +333,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
if (!rinfo->has_CRTC2) {
tmp = INPLL(pllSCLK_CNTL);
- if ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
+ if ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) > CFG_ATI_REV_A13)
tmp &= ~(SCLK_CNTL__FORCE_CP | SCLK_CNTL__FORCE_RB);
tmp &= ~(SCLK_CNTL__FORCE_HDP | SCLK_CNTL__FORCE_DISP1 |
SCLK_CNTL__FORCE_TOP | SCLK_CNTL__FORCE_SE |
@@ -468,9 +468,9 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
/*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/
if ((rinfo->family == CHIP_FAMILY_RV250 &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) ||
((rinfo->family == CHIP_FAMILY_RV100) &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) <= CFG_ATI_REV_A13))) {
tmp |= SCLK_CNTL__FORCE_CP;
tmp |= SCLK_CNTL__FORCE_VIP;
}
@@ -486,7 +486,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
/* RV200::A11 A12 RV250::A11 A12 */
if (((rinfo->family == CHIP_FAMILY_RV200) ||
(rinfo->family == CHIP_FAMILY_RV250)) &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13))
tmp |= SCLK_MORE_CNTL__FORCEON;
OUTPLL(pllSCLK_MORE_CNTL, tmp);
@@ -497,7 +497,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
/* RV200::A11 A12, RV250::A11 A12 */
if (((rinfo->family == CHIP_FAMILY_RV200) ||
(rinfo->family == CHIP_FAMILY_RV250)) &&
- ((INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
+ ((INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK) < CFG_ATI_REV_A13)) {
tmp = INPLL(pllPLL_PWRMGT_CNTL);
tmp |= PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE;
OUTPLL(pllPLL_PWRMGT_CNTL, tmp);
@@ -702,7 +702,7 @@ static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
@@ -1723,7 +1723,7 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)
OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
OUTREG(BUS_CNTL, rinfo->save_regs[36]);
OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]);
@@ -1961,7 +1961,7 @@ static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo)
OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/);
OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/);
OUTREG(MC_IND_INDEX, 0);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
mdelay(20);
}
@@ -2361,7 +2361,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249);
OUTREG(MC_IND_INDEX, 0);
- OUTREG(CONFIG_MEMSIZE, rinfo->video_ram);
+ OUTREG(CNFG_MEMSIZE, rinfo->video_ram);
radeon_pm_full_reset_sdram(rinfo);
@@ -2509,9 +2509,7 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
{
- u16 pwr_cmd;
u32 tmp;
- int i;
if (!rinfo->pm_reg)
return;
@@ -2557,32 +2555,14 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
}
}
- for (i = 0; i < 64; ++i)
- pci_read_config_dword(rinfo->pdev, i * 4,
- &rinfo->cfg_save[i]);
-
/* Switch PCI power management to D2. */
pci_disable_device(rinfo->pdev);
- for (;;) {
- pci_read_config_word(
- rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
- &pwr_cmd);
- if (pwr_cmd & 2)
- break;
- pci_write_config_word(
- rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
- (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
- mdelay(500);
- }
+ pci_save_state(rinfo->pdev);
+ pci_set_power_state(rinfo->pdev, PCI_D2);
} else {
printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n",
pci_name(rinfo->pdev));
- /* Switch back PCI powermanagment to D0 */
- mdelay(200);
- pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
- mdelay(500);
-
if (rinfo->family <= CHIP_FAMILY_RV250) {
/* Reset the SDRAM controller */
radeon_pm_full_reset_sdram(rinfo);
@@ -2598,37 +2578,10 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
}
}
-static int radeon_restore_pci_cfg(struct radeonfb_info *rinfo)
-{
- int i;
- static u32 radeon_cfg_after_resume[64];
-
- for (i = 0; i < 64; ++i)
- pci_read_config_dword(rinfo->pdev, i * 4,
- &radeon_cfg_after_resume[i]);
-
- if (radeon_cfg_after_resume[PCI_BASE_ADDRESS_0/4]
- == rinfo->cfg_save[PCI_BASE_ADDRESS_0/4])
- return 0; /* assume everything is ok */
-
- for (i = PCI_BASE_ADDRESS_0/4; i < 64; ++i) {
- if (radeon_cfg_after_resume[i] != rinfo->cfg_save[i])
- pci_write_config_dword(rinfo->pdev, i * 4,
- rinfo->cfg_save[i]);
- }
- pci_write_config_word(rinfo->pdev, PCI_CACHE_LINE_SIZE,
- rinfo->cfg_save[PCI_CACHE_LINE_SIZE/4]);
- pci_write_config_word(rinfo->pdev, PCI_COMMAND,
- rinfo->cfg_save[PCI_COMMAND/4]);
- return 1;
-}
-
-
int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct radeonfb_info *rinfo = info->par;
- int i;
if (mesg.event == pdev->dev.power.power_state.event)
return 0;
@@ -2674,6 +2627,11 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
pmac_suspend_agp_for_card(pdev);
#endif /* CONFIG_PPC_PMAC */
+ /* It's unclear whether or when the generic code will do that, so let's
+ * do it ourselves. We save state before we do any power management
+ */
+ pci_save_state(pdev);
+
/* If we support wakeup from poweroff, we save all regs we can including cfg
* space
*/
@@ -2698,9 +2656,6 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
mdelay(20);
OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) & ~(LVDS_DIGON));
}
- // FIXME: Use PCI layer
- for (i = 0; i < 64; ++i)
- pci_read_config_dword(pdev, i * 4, &rinfo->cfg_save[i]);
pci_disable_device(pdev);
}
/* If we support D2, we go to it (should be fixed later with a flag forcing
@@ -2717,6 +2672,13 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
return 0;
}
+static int radeon_check_power_loss(struct radeonfb_info *rinfo)
+{
+ return rinfo->save_regs[4] != INPLL(CLK_PIN_CNTL) ||
+ rinfo->save_regs[2] != INPLL(MCLK_CNTL) ||
+ rinfo->save_regs[3] != INPLL(SCLK_CNTL);
+}
+
int radeonfb_pci_resume(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
@@ -2735,20 +2697,13 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n",
pci_name(pdev), pdev->dev.power.power_state.event);
-
- if (pci_enable_device(pdev)) {
- rc = -ENODEV;
- printk(KERN_ERR "radeonfb (%s): can't enable PCI device !\n",
- pci_name(pdev));
- goto bail;
- }
- pci_set_master(pdev);
-
+ /* PCI state will have been restored by the core, so
+ * we should be in D0 now with our config space fully
+ * restored
+ */
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
- /* Wakeup chip. Check from config space if we were powered off
- * (todo: additionally, check CLK_PIN_CNTL too)
- */
- if ((rinfo->pm_mode & radeon_pm_off) && radeon_restore_pci_cfg(rinfo)) {
+ /* Wakeup chip */
+ if ((rinfo->pm_mode & radeon_pm_off) && radeon_check_power_loss(rinfo)) {
if (rinfo->reinit_func != NULL)
rinfo->reinit_func(rinfo);
else {
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 3ea1b00fdd22..7351e66c7f54 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -361,8 +361,6 @@ struct radeonfb_info {
#ifdef CONFIG_FB_RADEON_I2C
struct radeon_i2c_chan i2c[4];
#endif
-
- u32 cfg_save[64];
};
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 62bd4441b5e0..378f27745a1d 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops =
/* AU1100 LCD controller device driver */
-static int __init au1100fb_drv_probe(struct device *dev)
+static int __init au1100fb_drv_probe(struct platform_device *dev)
{
struct au1100fb_device *fbdev = NULL;
struct resource *regs_res;
@@ -475,7 +475,7 @@ static int __init au1100fb_drv_probe(struct device *dev)
fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
- dev_set_drvdata(dev, (void*)fbdev);
+ platform_set_drvdata(dev, (void *)fbdev);
/* Allocate region for our registers and map them */
if (!(regs_res = platform_get_resource(to_platform_device(dev),
@@ -583,19 +583,19 @@ failed:
fb_dealloc_cmap(&fbdev->info.cmap);
}
kfree(fbdev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
return 0;
}
-int au1100fb_drv_remove(struct device *dev)
+int au1100fb_drv_remove(struct platform_device *dev)
{
struct au1100fb_device *fbdev = NULL;
if (!dev)
return -ENODEV;
- fbdev = (struct au1100fb_device*) dev_get_drvdata(dev);
+ fbdev = (struct au1100fb_device *) platform_get_drvdata(dev);
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
@@ -620,9 +620,9 @@ int au1100fb_drv_remove(struct device *dev)
static u32 sys_clksrc;
static struct au1100fb_regs fbregs;
-int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
+int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state)
{
- struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+ struct au1100fb_device *fbdev = platform_get_drvdata(dev);
if (!fbdev)
return 0;
@@ -641,9 +641,9 @@ int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
return 0;
}
-int au1100fb_drv_resume(struct device *dev)
+int au1100fb_drv_resume(struct platform_device *dev)
{
- struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+ struct au1100fb_device *fbdev = platform_get_drvdata(dev);
if (!fbdev)
return 0;
@@ -663,10 +663,11 @@ int au1100fb_drv_resume(struct device *dev)
#define au1100fb_drv_resume NULL
#endif
-static struct device_driver au1100fb_driver = {
- .name = "au1100-lcd",
- .bus = &platform_bus_type,
-
+static struct platform_driver au1100fb_driver = {
+ .driver = {
+ .name = "au1100-lcd",
+ .owner = THIS_MODULE,
+ },
.probe = au1100fb_drv_probe,
.remove = au1100fb_drv_remove,
.suspend = au1100fb_drv_suspend,
@@ -753,12 +754,12 @@ int __init au1100fb_init(void)
return ret;
}
- return driver_register(&au1100fb_driver);
+ return platform_driver_register(&au1100fb_driver);
}
void __exit au1100fb_cleanup(void)
{
- driver_unregister(&au1100fb_driver);
+ platform_driver_unregister(&au1100fb_driver);
kfree(drv_info.opt_mode);
}
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 03e57ef88378..0d96f1d2d4c5 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1622,7 +1622,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
/* AU1200 LCD controller device driver */
-static int au1200fb_drv_probe(struct device *dev)
+static int au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
unsigned long page;
@@ -1645,7 +1645,7 @@ static int au1200fb_drv_probe(struct device *dev)
/* Allocate the framebuffer to the maximum screen size */
fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
- fbdev->fb_mem = dma_alloc_noncoherent(dev,
+ fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
PAGE_ALIGN(fbdev->fb_len),
&fbdev->fb_phys, GFP_KERNEL);
if (!fbdev->fb_mem) {
@@ -1715,7 +1715,7 @@ failed:
return ret;
}
-static int au1200fb_drv_remove(struct device *dev)
+static int au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
int plane;
@@ -1733,7 +1733,8 @@ static int au1200fb_drv_remove(struct device *dev)
/* Clean up all probe data */
unregister_framebuffer(&fbdev->fb_info);
if (fbdev->fb_mem)
- dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
+ dma_free_noncoherent(&dev->dev,
+ PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem, fbdev->fb_phys);
if (fbdev->fb_info.cmap.len != 0)
fb_dealloc_cmap(&fbdev->fb_info.cmap);
@@ -1747,22 +1748,24 @@ static int au1200fb_drv_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
+static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
{
/* TODO */
return 0;
}
-static int au1200fb_drv_resume(struct device *dev, u32 level)
+static int au1200fb_drv_resume(struct platform_device *dev)
{
/* TODO */
return 0;
}
#endif /* CONFIG_PM */
-static struct device_driver au1200fb_driver = {
- .name = "au1200-lcd",
- .bus = &platform_bus_type,
+static struct platform_driver au1200fb_driver = {
+ .driver = {
+ .name = "au1200-lcd",
+ .owner = THIS_MODULE,
+ },
.probe = au1200fb_drv_probe,
.remove = au1200fb_drv_remove,
#ifdef CONFIG_PM
@@ -1906,12 +1909,12 @@ static int __init au1200fb_init(void)
printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
#endif
- return driver_register(&au1200fb_driver);
+ return platform_driver_register(&au1200fb_driver);
}
static void __exit au1200fb_cleanup(void)
{
- driver_unregister(&au1200fb_driver);
+ platform_driver_unregister(&au1200fb_driver);
}
module_init(au1200fb_init);
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 363b3cb2f01b..63d759498165 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
-obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o
+obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
diff --git a/drivers/video/backlight/da903x.c b/drivers/video/backlight/da903x_bl.c
index 93bb4340cc64..93bb4340cc64 100644
--- a/drivers/video/backlight/da903x.c
+++ b/drivers/video/backlight/da903x_bl.c
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 2a423d3a2a8e..90cfddabf1f7 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -447,7 +447,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init bfin_t350mcqb_probe(struct platform_device *pdev)
+static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
{
struct bfin_t350mcqbfb_info *info;
struct fb_info *fbinfo;
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/broadsheetfb.c
new file mode 100644
index 000000000000..509cb92e8731
--- /dev/null
+++ b/drivers/video/broadsheetfb.c
@@ -0,0 +1,568 @@
+/*
+ * broadsheetfb.c -- FB driver for E-Ink Broadsheet controller
+ *
+ * Copyright (C) 2008, Jaya Kumar
+ *
+ * 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.
+ *
+ * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
+ *
+ * This driver is written to be used with the Broadsheet display controller.
+ *
+ * It is intended to be architecture independent. A board specific driver
+ * must be used to perform all the physical IO interactions.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/uaccess.h>
+
+#include <video/broadsheetfb.h>
+
+/* Display specific information */
+#define DPY_W 800
+#define DPY_H 600
+
+static struct fb_fix_screeninfo broadsheetfb_fix __devinitdata = {
+ .id = "broadsheetfb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .line_length = DPY_W,
+ .accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo broadsheetfb_var __devinitdata = {
+ .xres = DPY_W,
+ .yres = DPY_H,
+ .xres_virtual = DPY_W,
+ .yres_virtual = DPY_H,
+ .bits_per_pixel = 8,
+ .grayscale = 1,
+ .red = { 0, 4, 0 },
+ .green = { 0, 4, 0 },
+ .blue = { 0, 4, 0 },
+ .transp = { 0, 0, 0 },
+};
+
+/* main broadsheetfb functions */
+static void broadsheet_issue_data(struct broadsheetfb_par *par, u16 data)
+{
+ par->board->set_ctl(par, BS_WR, 0);
+ par->board->set_hdb(par, data);
+ par->board->set_ctl(par, BS_WR, 1);
+}
+
+static void broadsheet_issue_cmd(struct broadsheetfb_par *par, u16 data)
+{
+ par->board->set_ctl(par, BS_DC, 0);
+ broadsheet_issue_data(par, data);
+}
+
+static void broadsheet_send_command(struct broadsheetfb_par *par, u16 data)
+{
+ par->board->wait_for_rdy(par);
+
+ par->board->set_ctl(par, BS_CS, 0);
+ broadsheet_issue_cmd(par, data);
+ par->board->set_ctl(par, BS_DC, 1);
+ par->board->set_ctl(par, BS_CS, 1);
+}
+
+static void broadsheet_send_cmdargs(struct broadsheetfb_par *par, u16 cmd,
+ int argc, u16 *argv)
+{
+ int i;
+
+ par->board->wait_for_rdy(par);
+
+ par->board->set_ctl(par, BS_CS, 0);
+ broadsheet_issue_cmd(par, cmd);
+ par->board->set_ctl(par, BS_DC, 1);
+
+ for (i = 0; i < argc; i++)
+ broadsheet_issue_data(par, argv[i]);
+ par->board->set_ctl(par, BS_CS, 1);
+}
+
+static void broadsheet_burst_write(struct broadsheetfb_par *par, int size,
+ u16 *data)
+{
+ int i;
+ u16 tmp;
+
+ par->board->set_ctl(par, BS_CS, 0);
+ par->board->set_ctl(par, BS_DC, 1);
+
+ for (i = 0; i < size; i++) {
+ par->board->set_ctl(par, BS_WR, 0);
+ tmp = (data[i] & 0x0F) << 4;
+ tmp |= (data[i] & 0x0F00) << 4;
+ par->board->set_hdb(par, tmp);
+ par->board->set_ctl(par, BS_WR, 1);
+ }
+
+ par->board->set_ctl(par, BS_CS, 1);
+}
+
+static u16 broadsheet_get_data(struct broadsheetfb_par *par)
+{
+ u16 res;
+ /* wait for ready to go hi. (lo is busy) */
+ par->board->wait_for_rdy(par);
+
+ /* cs lo, dc lo for cmd, we lo for each data, db as usual */
+ par->board->set_ctl(par, BS_DC, 1);
+ par->board->set_ctl(par, BS_CS, 0);
+ par->board->set_ctl(par, BS_WR, 0);
+
+ res = par->board->get_hdb(par);
+
+ /* strobe wr */
+ par->board->set_ctl(par, BS_WR, 1);
+ par->board->set_ctl(par, BS_CS, 1);
+
+ return res;
+}
+
+static void broadsheet_write_reg(struct broadsheetfb_par *par, u16 reg,
+ u16 data)
+{
+ /* wait for ready to go hi. (lo is busy) */
+ par->board->wait_for_rdy(par);
+
+ /* cs lo, dc lo for cmd, we lo for each data, db as usual */
+ par->board->set_ctl(par, BS_CS, 0);
+
+ broadsheet_issue_cmd(par, BS_CMD_WR_REG);
+
+ par->board->set_ctl(par, BS_DC, 1);
+
+ broadsheet_issue_data(par, reg);
+ broadsheet_issue_data(par, data);
+
+ par->board->set_ctl(par, BS_CS, 1);
+}
+
+static u16 broadsheet_read_reg(struct broadsheetfb_par *par, u16 reg)
+{
+ broadsheet_send_command(par, reg);
+ msleep(100);
+ return broadsheet_get_data(par);
+}
+
+static void __devinit broadsheet_init_display(struct broadsheetfb_par *par)
+{
+ u16 args[5];
+
+ args[0] = DPY_W;
+ args[1] = DPY_H;
+ args[2] = (100 | (1 << 8) | (1 << 9)); /* sdcfg */
+ args[3] = 2; /* gdrv cfg */
+ args[4] = (4 | (1 << 7)); /* lut index format */
+ broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args);
+
+ /* did the controller really set it? */
+ broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_CFG, 5, args);
+
+ args[0] = 4; /* fsync len */
+ args[1] = (10 << 8) | 4; /* fend/fbegin len */
+ args[2] = 10; /* line sync len */
+ args[3] = (100 << 8) | 4; /* line end/begin len */
+ args[4] = 6; /* pixel clock cfg */
+ broadsheet_send_cmdargs(par, BS_CMD_INIT_DSPE_TMG, 5, args);
+
+ /* setup waveform */
+ args[0] = 0x886;
+ args[1] = 0;
+ broadsheet_send_cmdargs(par, BS_CMD_RD_WFM_INFO, 2, args);
+
+ broadsheet_send_command(par, BS_CMD_UPD_GDRV_CLR);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG);
+
+ broadsheet_write_reg(par, 0x330, 0x84);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG);
+
+ args[0] = (0x3 << 4);
+ broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args);
+
+ args[0] = 0x154;
+ broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
+
+ broadsheet_burst_write(par, DPY_W*DPY_H/2,
+ (u16 *) par->info->screen_base);
+
+ broadsheet_send_command(par, BS_CMD_LD_IMG_END);
+
+ args[0] = 0x4300;
+ broadsheet_send_cmdargs(par, BS_CMD_UPD_FULL, 1, args);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND);
+
+ par->board->wait_for_rdy(par);
+}
+
+static void __devinit broadsheet_init(struct broadsheetfb_par *par)
+{
+ broadsheet_send_command(par, BS_CMD_INIT_SYS_RUN);
+ /* the controller needs a second */
+ msleep(1000);
+ broadsheet_init_display(par);
+}
+
+static void broadsheetfb_dpy_update_pages(struct broadsheetfb_par *par,
+ u16 y1, u16 y2)
+{
+ u16 args[5];
+ unsigned char *buf = (unsigned char *)par->info->screen_base;
+
+ /* y1 must be a multiple of 4 so drop the lower bits */
+ y1 &= 0xFFFC;
+ /* y2 must be a multiple of 4 , but - 1 so up the lower bits */
+ y2 |= 0x0003;
+
+ args[0] = 0x3 << 4;
+ args[1] = 0;
+ args[2] = y1;
+ args[3] = cpu_to_le16(par->info->var.xres);
+ args[4] = y2;
+ broadsheet_send_cmdargs(par, BS_CMD_LD_IMG_AREA, 5, args);
+
+ args[0] = 0x154;
+ broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
+
+ buf += y1 * par->info->var.xres;
+ broadsheet_burst_write(par, ((1 + y2 - y1) * par->info->var.xres)/2,
+ (u16 *) buf);
+
+ broadsheet_send_command(par, BS_CMD_LD_IMG_END);
+
+ args[0] = 0x4300;
+ broadsheet_send_cmdargs(par, BS_CMD_UPD_FULL, 1, args);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND);
+
+ par->board->wait_for_rdy(par);
+
+}
+
+static void broadsheetfb_dpy_update(struct broadsheetfb_par *par)
+{
+ u16 args[5];
+
+ args[0] = 0x3 << 4;
+ broadsheet_send_cmdargs(par, BS_CMD_LD_IMG, 1, args);
+
+ args[0] = 0x154;
+ broadsheet_send_cmdargs(par, BS_CMD_WR_REG, 1, args);
+ broadsheet_burst_write(par, DPY_W*DPY_H/2,
+ (u16 *) par->info->screen_base);
+
+ broadsheet_send_command(par, BS_CMD_LD_IMG_END);
+
+ args[0] = 0x4300;
+ broadsheet_send_cmdargs(par, BS_CMD_UPD_FULL, 1, args);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_TRG);
+
+ broadsheet_send_command(par, BS_CMD_WAIT_DSPE_FREND);
+
+ par->board->wait_for_rdy(par);
+
+}
+
+/* this is called back from the deferred io workqueue */
+static void broadsheetfb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ u16 y1 = 0, h = 0;
+ int prev_index = -1;
+ struct page *cur;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+ int h_inc;
+ u16 yres = info->var.yres;
+ u16 xres = info->var.xres;
+
+ /* height increment is fixed per page */
+ h_inc = DIV_ROUND_UP(PAGE_SIZE , xres);
+
+ /* walk the written page list and swizzle the data */
+ list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+ if (prev_index < 0) {
+ /* just starting so assign first page */
+ y1 = (cur->index << PAGE_SHIFT) / xres;
+ h = h_inc;
+ } else if ((prev_index + 1) == cur->index) {
+ /* this page is consecutive so increase our height */
+ h += h_inc;
+ } else {
+ /* page not consecutive, issue previous update first */
+ broadsheetfb_dpy_update_pages(info->par, y1, y1 + h);
+ /* start over with our non consecutive page */
+ y1 = (cur->index << PAGE_SHIFT) / xres;
+ h = h_inc;
+ }
+ prev_index = cur->index;
+ }
+
+ /* if we still have any pages to update we do so now */
+ if (h >= yres) {
+ /* its a full screen update, just do it */
+ broadsheetfb_dpy_update(info->par);
+ } else {
+ broadsheetfb_dpy_update_pages(info->par, y1,
+ min((u16) (y1 + h), yres));
+ }
+}
+
+static void broadsheetfb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
+{
+ struct broadsheetfb_par *par = info->par;
+
+ sys_fillrect(info, rect);
+
+ broadsheetfb_dpy_update(par);
+}
+
+static void broadsheetfb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ struct broadsheetfb_par *par = info->par;
+
+ sys_copyarea(info, area);
+
+ broadsheetfb_dpy_update(par);
+}
+
+static void broadsheetfb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+ struct broadsheetfb_par *par = info->par;
+
+ sys_imageblit(info, image);
+
+ broadsheetfb_dpy_update(par);
+}
+
+/*
+ * this is the slow path from userspace. they can seek and write to
+ * the fb. it's inefficient to do anything less than a full screen draw
+ */
+static ssize_t broadsheetfb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct broadsheetfb_par *par = info->par;
+ unsigned long p = *ppos;
+ void *dst;
+ int err = 0;
+ unsigned long total_size;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EFBIG;
+
+ if (count > total_size) {
+ err = -EFBIG;
+ count = total_size;
+ }
+
+ if (count + p > total_size) {
+ if (!err)
+ err = -ENOSPC;
+
+ count = total_size - p;
+ }
+
+ dst = (void *)(info->screen_base + p);
+
+ if (copy_from_user(dst, buf, count))
+ err = -EFAULT;
+
+ if (!err)
+ *ppos += count;
+
+ broadsheetfb_dpy_update(par);
+
+ return (err) ? err : count;
+}
+
+static struct fb_ops broadsheetfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_read = fb_sys_read,
+ .fb_write = broadsheetfb_write,
+ .fb_fillrect = broadsheetfb_fillrect,
+ .fb_copyarea = broadsheetfb_copyarea,
+ .fb_imageblit = broadsheetfb_imageblit,
+};
+
+static struct fb_deferred_io broadsheetfb_defio = {
+ .delay = HZ/4,
+ .deferred_io = broadsheetfb_dpy_deferred_io,
+};
+
+static int __devinit broadsheetfb_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ struct broadsheet_board *board;
+ int retval = -ENOMEM;
+ int videomemorysize;
+ unsigned char *videomemory;
+ struct broadsheetfb_par *par;
+ int i;
+
+ /* pick up board specific routines */
+ board = dev->dev.platform_data;
+ if (!board)
+ return -EINVAL;
+
+ /* try to count device specific driver, if can't, platform recalls */
+ if (!try_module_get(board->owner))
+ return -ENODEV;
+
+ info = framebuffer_alloc(sizeof(struct broadsheetfb_par), &dev->dev);
+ if (!info)
+ goto err;
+
+ videomemorysize = (DPY_W*DPY_H);
+ videomemory = vmalloc(videomemorysize);
+ if (!videomemory)
+ goto err_fb_rel;
+
+ memset(videomemory, 0, videomemorysize);
+
+ info->screen_base = (char *)videomemory;
+ info->fbops = &broadsheetfb_ops;
+
+ info->var = broadsheetfb_var;
+ info->fix = broadsheetfb_fix;
+ info->fix.smem_len = videomemorysize;
+ par = info->par;
+ par->info = info;
+ par->board = board;
+ par->write_reg = broadsheet_write_reg;
+ par->read_reg = broadsheet_read_reg;
+ init_waitqueue_head(&par->waitq);
+
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ info->fbdefio = &broadsheetfb_defio;
+ fb_deferred_io_init(info);
+
+ retval = fb_alloc_cmap(&info->cmap, 16, 0);
+ if (retval < 0) {
+ dev_err(&dev->dev, "Failed to allocate colormap\n");
+ goto err_vfree;
+ }
+
+ /* set cmap */
+ for (i = 0; i < 16; i++)
+ info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/32;
+ memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*16);
+ memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*16);
+
+ retval = par->board->setup_irq(info);
+ if (retval < 0)
+ goto err_cmap;
+
+ /* this inits the dpy */
+ retval = board->init(par);
+ if (retval < 0)
+ goto err_free_irq;
+
+ broadsheet_init(par);
+
+ retval = register_framebuffer(info);
+ if (retval < 0)
+ goto err_free_irq;
+ platform_set_drvdata(dev, info);
+
+ printk(KERN_INFO
+ "fb%d: Broadsheet frame buffer, using %dK of video memory\n",
+ info->node, videomemorysize >> 10);
+
+
+ return 0;
+
+err_free_irq:
+ board->cleanup(par);
+err_cmap:
+ fb_dealloc_cmap(&info->cmap);
+err_vfree:
+ vfree(videomemory);
+err_fb_rel:
+ framebuffer_release(info);
+err:
+ module_put(board->owner);
+ return retval;
+
+}
+
+static int __devexit broadsheetfb_remove(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+
+ if (info) {
+ struct broadsheetfb_par *par = info->par;
+ unregister_framebuffer(info);
+ fb_deferred_io_cleanup(info);
+ par->board->cleanup(par);
+ fb_dealloc_cmap(&info->cmap);
+ vfree((void *)info->screen_base);
+ module_put(par->board->owner);
+ framebuffer_release(info);
+ }
+ return 0;
+}
+
+static struct platform_driver broadsheetfb_driver = {
+ .probe = broadsheetfb_probe,
+ .remove = broadsheetfb_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "broadsheetfb",
+ },
+};
+
+static int __init broadsheetfb_init(void)
+{
+ return platform_driver_register(&broadsheetfb_driver);
+}
+
+static void __exit broadsheetfb_exit(void)
+{
+ platform_driver_unregister(&broadsheetfb_driver);
+}
+
+module_init(broadsheetfb_init);
+module_exit(broadsheetfb_exit);
+
+MODULE_DESCRIPTION("fbdev driver for Broadsheet controller");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 7a9e42e3a9a9..51b373657aa2 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1425,7 +1425,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
#ifdef CONFIG_ARCH_SHARK
-#include <mach/hardware.h>
+#include <mach/framebuffer.h>
static int __devinit cyberpro_vl_probe(void)
{
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 91b78e691505..f53b9f1d6aba 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -250,10 +250,6 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
int rc, size = cmap->len * sizeof(u16);
struct fb_cmap umap;
- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
- !info->fbops->fb_setcmap))
- return -EINVAL;
-
memset(&umap, 0, sizeof(struct fb_cmap));
rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
if (rc)
@@ -262,11 +258,23 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
copy_from_user(umap.green, cmap->green, size) ||
copy_from_user(umap.blue, cmap->blue, size) ||
(cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
- fb_dealloc_cmap(&umap);
- return -EFAULT;
+ rc = -EFAULT;
+ goto out;
}
umap.start = cmap->start;
+ if (!lock_fb_info(info)) {
+ rc = -ENODEV;
+ goto out;
+ }
+ if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
+ !info->fbops->fb_setcmap)) {
+ rc = -EINVAL;
+ goto out1;
+ }
rc = fb_set_cmap(&umap, info);
+out1:
+ unlock_fb_info(info);
+out:
fb_dealloc_cmap(&umap);
return rc;
}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 756efeb91abc..cfd9dce1ce0b 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1013,132 +1013,139 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
struct fb_con2fbmap con2fb;
+ struct fb_cmap cmap_from;
struct fb_cmap_user cmap;
struct fb_event event;
void __user *argp = (void __user *)arg;
long ret = 0;
- fb = info->fbops;
- if (!fb)
- return -ENODEV;
-
switch (cmd) {
case FBIOGET_VSCREENINFO:
- ret = copy_to_user(argp, &info->var,
- sizeof(var)) ? -EFAULT : 0;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ var = info->var;
+ unlock_fb_info(info);
+
+ ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;
break;
case FBIOPUT_VSCREENINFO:
- if (copy_from_user(&var, argp, sizeof(var))) {
- ret = -EFAULT;
- break;
- }
+ if (copy_from_user(&var, argp, sizeof(var)))
+ return -EFAULT;
+ if (!lock_fb_info(info))
+ return -ENODEV;
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
- if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
+ unlock_fb_info(info);
+ if (!ret && copy_to_user(argp, &var, sizeof(var)))
ret = -EFAULT;
break;
case FBIOGET_FSCREENINFO:
- ret = copy_to_user(argp, &info->fix,
- sizeof(fix)) ? -EFAULT : 0;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ fix = info->fix;
+ unlock_fb_info(info);
+
+ ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0;
break;
case FBIOPUTCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
- ret = -EFAULT;
- else
- ret = fb_set_user_cmap(&cmap, info);
+ return -EFAULT;
+ ret = fb_set_user_cmap(&cmap, info);
break;
case FBIOGETCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
- ret = -EFAULT;
- else
- ret = fb_cmap_to_user(&info->cmap, &cmap);
+ return -EFAULT;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ cmap_from = info->cmap;
+ unlock_fb_info(info);
+ ret = fb_cmap_to_user(&cmap_from, &cmap);
break;
case FBIOPAN_DISPLAY:
- if (copy_from_user(&var, argp, sizeof(var))) {
- ret = -EFAULT;
- break;
- }
+ if (copy_from_user(&var, argp, sizeof(var)))
+ return -EFAULT;
+ if (!lock_fb_info(info))
+ return -ENODEV;
acquire_console_sem();
ret = fb_pan_display(info, &var);
release_console_sem();
+ unlock_fb_info(info);
if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
- ret = -EFAULT;
+ return -EFAULT;
break;
case FBIO_CURSOR:
ret = -EINVAL;
break;
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
- ret = -EFAULT;
- else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
- ret = -EINVAL;
- else {
- con2fb.framebuffer = -1;
- event.info = info;
- event.data = &con2fb;
- fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP,
- &event);
- ret = copy_to_user(argp, &con2fb,
- sizeof(con2fb)) ? -EFAULT : 0;
- }
+ return -EFAULT;
+ if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
+ return -EINVAL;
+ con2fb.framebuffer = -1;
+ event.data = &con2fb;
+
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ event.info = info;
+ fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
+ unlock_fb_info(info);
+
+ ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
break;
case FBIOPUT_CON2FBMAP:
- if (copy_from_user(&con2fb, argp, sizeof(con2fb))) {
- ret = -EFAULT;
- break;
- }
- if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) {
- ret = -EINVAL;
- break;
- }
- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) {
- ret = -EINVAL;
- break;
- }
+ if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
+ return -EFAULT;
+ if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
+ return -EINVAL;
+ if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
+ return -EINVAL;
if (!registered_fb[con2fb.framebuffer])
request_module("fb%d", con2fb.framebuffer);
if (!registered_fb[con2fb.framebuffer]) {
ret = -EINVAL;
break;
}
- event.info = info;
event.data = &con2fb;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ event.info = info;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
&event);
+ unlock_fb_info(info);
break;
case FBIOBLANK:
+ if (!lock_fb_info(info))
+ return -ENODEV;
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_blank(info, arg);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
- break;;
+ unlock_fb_info(info);
+ break;
default:
- if (fb->fb_ioctl == NULL)
- ret = -ENOTTY;
- else
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ fb = info->fbops;
+ if (fb->fb_ioctl)
ret = fb->fb_ioctl(info, cmd, arg);
+ else
+ ret = -ENOTTY;
+ unlock_fb_info(info);
}
return ret;
}
static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-__acquires(&info->lock)
-__releases(&info->lock)
{
struct inode *inode = file->f_path.dentry->d_inode;
int fbidx = iminor(inode);
- struct fb_info *info;
- long ret;
+ struct fb_info *info = registered_fb[fbidx];
- info = registered_fb[fbidx];
- mutex_lock(&info->lock);
- ret = do_fb_ioctl(info, cmd, arg);
- mutex_unlock(&info->lock);
- return ret;
+ return do_fb_ioctl(info, cmd, arg);
}
#ifdef CONFIG_COMPAT
@@ -1257,8 +1264,6 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,
static long fb_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
-__acquires(&info->lock)
-__releases(&info->lock)
{
struct inode *inode = file->f_path.dentry->d_inode;
int fbidx = iminor(inode);
@@ -1266,7 +1271,6 @@ __releases(&info->lock)
struct fb_ops *fb = info->fbops;
long ret = -ENOIOCTLCMD;
- mutex_lock(&info->lock);
switch(cmd) {
case FBIOGET_VSCREENINFO:
case FBIOPUT_VSCREENINFO:
@@ -1292,7 +1296,6 @@ __releases(&info->lock)
ret = fb->fb_compat_ioctl(info, cmd, arg);
break;
}
- mutex_unlock(&info->lock);
return ret;
}
#endif
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 751e491ca8c8..f20eff8c4a81 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -136,13 +136,10 @@ static int gx1fb_set_par(struct fb_info *info)
{
struct geodefb_par *par = info->par;
- if (info->var.bits_per_pixel == 16) {
+ if (info->var.bits_per_pixel == 16)
info->fix.visual = FB_VISUAL_TRUECOLOR;
- fb_dealloc_cmap(&info->cmap);
- } else {
+ else
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
- }
info->fix.line_length = gx1_line_delta(info->var.xres, info->var.bits_per_pixel);
@@ -315,6 +312,10 @@ static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
if (!par->panel_x)
par->enable_crt = 1; /* fall back to CRT if no panel is specified */
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ framebuffer_release(info);
+ return NULL;
+ }
return info;
}
@@ -374,8 +375,11 @@ static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *
release_mem_region(gx1_gx_base() + 0x8300, 0x100);
}
- if (info)
+ if (info) {
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
+ }
+
return ret;
}
@@ -395,6 +399,7 @@ static void gx1fb_remove(struct pci_dev *pdev)
iounmap(par->dc_regs);
release_mem_region(gx1_gx_base() + 0x8300, 0x100);
+ fb_dealloc_cmap(&info->cmap);
pci_set_drvdata(pdev, NULL);
framebuffer_release(info);
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 484118926318..2552cac39e1c 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -171,13 +171,10 @@ static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static int gxfb_set_par(struct fb_info *info)
{
- if (info->var.bits_per_pixel > 8) {
+ if (info->var.bits_per_pixel > 8)
info->fix.visual = FB_VISUAL_TRUECOLOR;
- fb_dealloc_cmap(&info->cmap);
- } else {
+ else
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
- }
info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel);
@@ -331,6 +328,11 @@ static struct fb_info * __init gxfb_init_fbinfo(struct device *dev)
info->var.grayscale = 0;
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ framebuffer_release(info);
+ return NULL;
+ }
+
return info;
}
@@ -443,8 +445,10 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
pci_release_region(pdev, 1);
}
- if (info)
+ if (info) {
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
+ }
return ret;
}
@@ -467,6 +471,7 @@ static void gxfb_remove(struct pci_dev *pdev)
iounmap(par->gp_regs);
pci_release_region(pdev, 1);
+ fb_dealloc_cmap(&info->cmap);
pci_set_drvdata(pdev, NULL);
framebuffer_release(info);
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index b965ecdbc604..889cbe39e580 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -278,13 +278,10 @@ static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static int lxfb_set_par(struct fb_info *info)
{
- if (info->var.bits_per_pixel > 8) {
+ if (info->var.bits_per_pixel > 8)
info->fix.visual = FB_VISUAL_TRUECOLOR;
- fb_dealloc_cmap(&info->cmap);
- } else {
+ else
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
- }
info->fix.line_length = lx_get_pitch(info->var.xres,
info->var.bits_per_pixel);
@@ -451,6 +448,11 @@ static struct fb_info * __init lxfb_init_fbinfo(struct device *dev)
info->pseudo_palette = (void *)par + sizeof(struct lxfb_par);
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ framebuffer_release(info);
+ return NULL;
+ }
+
info->var.grayscale = 0;
return info;
@@ -579,8 +581,10 @@ err:
pci_release_region(pdev, 3);
}
- if (info)
+ if (info) {
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
+ }
return ret;
}
@@ -604,6 +608,7 @@ static void lxfb_remove(struct pci_dev *pdev)
iounmap(par->vp_regs);
pci_release_region(pdev, 3);
+ fb_dealloc_cmap(&info->cmap);
pci_set_drvdata(pdev, NULL);
framebuffer_release(info);
}
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 7787c3322ffb..9dd55e5324a1 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -90,7 +90,6 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
chan->adapter.owner = THIS_MODULE;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->dev->dev;
- chan->adapter.id = I2C_HW_B_I810;
chan->algo.setsda = i810i2c_setsda;
chan->algo.setscl = i810i2c_setscl;
chan->algo.getsda = i810i2c_getsda;
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index 5d896b81f4e0..b3065492bb20 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -111,7 +111,6 @@ static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
"intelfb %s", name);
chan->adapter.class = class;
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_INTELFB;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
chan->algo.setsda = intelfb_gpio_setsda;
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
new file mode 100644
index 000000000000..8a75d05f4334
--- /dev/null
+++ b/drivers/video/mx3fb.c
@@ -0,0 +1,1555 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/console.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <mach/hardware.h>
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define MX3FB_NAME "mx3_sdc_fb"
+
+#define MX3FB_REG_OFFSET 0xB4
+
+/* SDC Registers */
+#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET)
+#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET)
+#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET)
+#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET)
+#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET)
+#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET)
+#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET)
+#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET)
+#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET)
+#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET)
+#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET)
+
+/* Register bits */
+#define SDC_COM_TFT_COLOR 0x00000001UL
+#define SDC_COM_FG_EN 0x00000010UL
+#define SDC_COM_GWSEL 0x00000020UL
+#define SDC_COM_GLB_A 0x00000040UL
+#define SDC_COM_KEY_COLOR_G 0x00000080UL
+#define SDC_COM_BG_EN 0x00000200UL
+#define SDC_COM_SHARP 0x00001000UL
+
+#define SDC_V_SYNC_WIDTH_L 0x00000001UL
+
+/* Display Interface registers */
+#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET)
+#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET)
+#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET)
+#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET)
+#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET)
+#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET)
+#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET)
+#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET)
+#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET)
+#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET)
+#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET)
+#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET)
+#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET)
+#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET)
+#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET)
+#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET)
+#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET)
+#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET)
+#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET)
+#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET)
+#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET)
+#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET)
+#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET)
+#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET)
+#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET)
+#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET)
+#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET)
+#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET)
+#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET)
+#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET)
+#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET)
+#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET)
+#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET)
+#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET)
+#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET)
+#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET)
+#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET)
+#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET)
+#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET)
+
+/* DI_DISP_SIG_POL bits */
+#define DI_D3_VSYNC_POL_SHIFT 28
+#define DI_D3_HSYNC_POL_SHIFT 27
+#define DI_D3_DRDY_SHARP_POL_SHIFT 26
+#define DI_D3_CLK_POL_SHIFT 25
+#define DI_D3_DATA_POL_SHIFT 24
+
+/* DI_DISP_IF_CONF bits */
+#define DI_D3_CLK_IDLE_SHIFT 26
+#define DI_D3_CLK_SEL_SHIFT 25
+#define DI_D3_DATAMSK_SHIFT 24
+
+enum ipu_panel {
+ IPU_PANEL_SHARP_TFT,
+ IPU_PANEL_TFT,
+};
+
+struct ipu_di_signal_cfg {
+ unsigned datamask_en:1;
+ unsigned clksel_en:1;
+ unsigned clkidle_en:1;
+ unsigned data_pol:1; /* true = inverted */
+ unsigned clk_pol:1; /* true = rising edge */
+ unsigned enable_pol:1;
+ unsigned Hsync_pol:1; /* true = active high */
+ unsigned Vsync_pol:1;
+};
+
+static const struct fb_videomode mx3fb_modedb[] = {
+ {
+ /* 240x320 @ 60 Hz */
+ .name = "Sharp-QVGA",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
+ FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
+ FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x33 @ 60 Hz */
+ .name = "Sharp-CLI",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 33,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9 + 287,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
+ FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
+ FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 640x480 @ 60 Hz */
+ .name = "NEC-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 38255,
+ .left_margin = 144,
+ .right_margin = 0,
+ .upper_margin = 34,
+ .lower_margin = 40,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* NTSC TV output */
+ .name = "TV-NTSC",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 37538,
+ .left_margin = 38,
+ .right_margin = 858 - 640 - 38 - 3,
+ .upper_margin = 36,
+ .lower_margin = 518 - 480 - 36 - 1,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* PAL TV output */
+ .name = "TV-PAL",
+ .refresh = 50,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 37538,
+ .left_margin = 38,
+ .right_margin = 960 - 640 - 38 - 32,
+ .upper_margin = 32,
+ .lower_margin = 555 - 480 - 32 - 3,
+ .hsync_len = 32,
+ .vsync_len = 3,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* TV output VGA mode, 640x480 @ 65 Hz */
+ .name = "TV-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 40574,
+ .left_margin = 35,
+ .right_margin = 45,
+ .upper_margin = 9,
+ .lower_margin = 1,
+ .hsync_len = 46,
+ .vsync_len = 5,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+struct mx3fb_data {
+ struct fb_info *fbi;
+ int backlight_level;
+ void __iomem *reg_base;
+ spinlock_t lock;
+ struct device *dev;
+
+ uint32_t h_start_width;
+ uint32_t v_start_width;
+};
+
+struct dma_chan_request {
+ struct mx3fb_data *mx3fb;
+ enum ipu_channel id;
+};
+
+/* MX3 specific framebuffer information. */
+struct mx3fb_info {
+ int blank;
+ enum ipu_channel ipu_ch;
+ uint32_t cur_ipu_buf;
+
+ u32 pseudo_palette[16];
+
+ struct completion flip_cmpl;
+ struct mutex mutex; /* Protects fb-ops */
+ struct mx3fb_data *mx3fb;
+ struct idmac_channel *idmac_channel;
+ struct dma_async_tx_descriptor *txd;
+ dma_cookie_t cookie;
+ struct scatterlist sg[2];
+
+ u32 sync; /* preserve var->sync flags */
+};
+
+static void mx3fb_dma_done(void *);
+
+/* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */
+static const char *fb_mode;
+static unsigned long default_bpp = 16;
+
+static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg)
+{
+ return __raw_readl(mx3fb->reg_base + reg);
+}
+
+static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg)
+{
+ __raw_writel(value, mx3fb->reg_base + reg);
+}
+
+static const uint32_t di_mappings[] = {
+ 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */
+ 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */
+ 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */
+ 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */
+};
+
+static void sdc_fb_init(struct mx3fb_info *fbi)
+{
+ struct mx3fb_data *mx3fb = fbi->mx3fb;
+ uint32_t reg;
+
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+
+ mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF);
+}
+
+/* Returns enabled flag before uninit */
+static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi)
+{
+ struct mx3fb_data *mx3fb = fbi->mx3fb;
+ uint32_t reg;
+
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+
+ mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF);
+
+ return reg & SDC_COM_BG_EN;
+}
+
+static void sdc_enable_channel(struct mx3fb_info *mx3_fbi)
+{
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+ struct idmac_channel *ichan = mx3_fbi->idmac_channel;
+ struct dma_chan *dma_chan = &ichan->dma_chan;
+ unsigned long flags;
+ dma_cookie_t cookie;
+
+ dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi,
+ to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg);
+
+ /* This enables the channel */
+ if (mx3_fbi->cookie < 0) {
+ mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan,
+ &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
+ if (!mx3_fbi->txd) {
+ dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n",
+ dma_chan->chan_id);
+ return;
+ }
+
+ mx3_fbi->txd->callback_param = mx3_fbi->txd;
+ mx3_fbi->txd->callback = mx3fb_dma_done;
+
+ cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd);
+ dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__,
+ mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
+ } else {
+ if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) {
+ dev_err(mx3fb->dev, "Cannot enable channel %d\n",
+ dma_chan->chan_id);
+ return;
+ }
+
+ /* Just re-activate the same buffer */
+ dma_async_issue_pending(dma_chan);
+ cookie = mx3_fbi->cookie;
+ dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__,
+ mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
+ }
+
+ if (cookie >= 0) {
+ spin_lock_irqsave(&mx3fb->lock, flags);
+ sdc_fb_init(mx3_fbi);
+ mx3_fbi->cookie = cookie;
+ spin_unlock_irqrestore(&mx3fb->lock, flags);
+ }
+
+ /*
+ * Attention! Without this msleep the channel keeps generating
+ * interrupts. Next sdc_set_brightness() is going to be called
+ * from mx3fb_blank().
+ */
+ msleep(2);
+}
+
+static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
+{
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+ uint32_t enabled;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mx3fb->lock, flags);
+
+ enabled = sdc_fb_uninit(mx3_fbi);
+
+ spin_unlock_irqrestore(&mx3fb->lock, flags);
+
+ mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan);
+ mx3_fbi->txd = NULL;
+ mx3_fbi->cookie = -EINVAL;
+}
+
+/**
+ * sdc_set_window_pos() - set window position of the respective plane.
+ * @mx3fb: mx3fb context.
+ * @channel: IPU DMAC channel ID.
+ * @x_pos: X coordinate relative to the top left corner to place window at.
+ * @y_pos: Y coordinate relative to the top left corner to place window at.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel,
+ int16_t x_pos, int16_t y_pos)
+{
+ x_pos += mx3fb->h_start_width;
+ y_pos += mx3fb->v_start_width;
+
+ if (channel != IDMAC_SDC_0)
+ return -EINVAL;
+
+ mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS);
+ return 0;
+}
+
+/**
+ * sdc_init_panel() - initialize a synchronous LCD panel.
+ * @mx3fb: mx3fb context.
+ * @panel: panel type.
+ * @pixel_clk: desired pixel clock frequency in Hz.
+ * @width: width of panel in pixels.
+ * @height: height of panel in pixels.
+ * @pixel_fmt: pixel format of buffer as FOURCC ASCII code.
+ * @h_start_width: number of pixel clocks between the HSYNC signal pulse
+ * and the start of valid data.
+ * @h_sync_width: width of the HSYNC signal in units of pixel clocks.
+ * @h_end_width: number of pixel clocks between the end of valid data
+ * and the HSYNC signal for next line.
+ * @v_start_width: number of lines between the VSYNC signal pulse and the
+ * start of valid data.
+ * @v_sync_width: width of the VSYNC signal in units of lines
+ * @v_end_width: number of lines between the end of valid data and the
+ * VSYNC signal for next frame.
+ * @sig: bitfield of signal polarities for LCD interface.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
+ uint32_t pixel_clk,
+ uint16_t width, uint16_t height,
+ enum pixel_fmt pixel_fmt,
+ uint16_t h_start_width, uint16_t h_sync_width,
+ uint16_t h_end_width, uint16_t v_start_width,
+ uint16_t v_sync_width, uint16_t v_end_width,
+ struct ipu_di_signal_cfg sig)
+{
+ unsigned long lock_flags;
+ uint32_t reg;
+ uint32_t old_conf;
+ uint32_t div;
+ struct clk *ipu_clk;
+
+ dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height);
+
+ if (v_sync_width == 0 || h_sync_width == 0)
+ return -EINVAL;
+
+ /* Init panel size and blanking periods */
+ reg = ((uint32_t) (h_sync_width - 1) << 26) |
+ ((uint32_t) (width + h_start_width + h_end_width - 1) << 16);
+ mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF);
+
+#ifdef DEBUG
+ printk(KERN_CONT " hor_conf %x,", reg);
+#endif
+
+ reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L |
+ ((uint32_t) (height + v_start_width + v_end_width - 1) << 16);
+ mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF);
+
+#ifdef DEBUG
+ printk(KERN_CONT " ver_conf %x\n", reg);
+#endif
+
+ mx3fb->h_start_width = h_start_width;
+ mx3fb->v_start_width = v_start_width;
+
+ switch (panel) {
+ case IPU_PANEL_SHARP_TFT:
+ mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1);
+ mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2);
+ mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF);
+ break;
+ case IPU_PANEL_TFT:
+ mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Init clocking */
+
+ /*
+ * Calculate divider: fractional part is 4 bits so simply multiple by
+ * 24 to get fractional part, as long as we stay under ~250MHz and on
+ * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz
+ */
+ dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk);
+
+ ipu_clk = clk_get(mx3fb->dev, "ipu_clk");
+ div = clk_get_rate(ipu_clk) * 16 / pixel_clk;
+ clk_put(ipu_clk);
+
+ if (div < 0x40) { /* Divider less than 4 */
+ dev_dbg(mx3fb->dev,
+ "InitPanel() - Pixel clock divider less than 4\n");
+ div = 0x40;
+ }
+
+ spin_lock_irqsave(&mx3fb->lock, lock_flags);
+
+ /*
+ * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits
+ * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing
+ * debug. DISP3_IF_CLK_UP_WR is 0
+ */
+ mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF);
+
+ /* DI settings */
+ old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF;
+ old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT |
+ sig.clksel_en << DI_D3_CLK_SEL_SHIFT |
+ sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT;
+ mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF);
+
+ old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF;
+ old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT |
+ sig.clk_pol << DI_D3_CLK_POL_SHIFT |
+ sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
+ sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
+ sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
+ mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL);
+
+ switch (pixel_fmt) {
+ case IPU_PIX_FMT_RGB24:
+ mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ case IPU_PIX_FMT_RGB666:
+ mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ case IPU_PIX_FMT_BGR666:
+ mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ default:
+ mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP);
+ mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP);
+ mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
+ ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC);
+ break;
+ }
+
+ spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
+
+ dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n",
+ mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF));
+ dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n",
+ mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL));
+ dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n",
+ mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF));
+
+ return 0;
+}
+
+/**
+ * sdc_set_color_key() - set the transparent color key for SDC graphic plane.
+ * @mx3fb: mx3fb context.
+ * @channel: IPU DMAC channel ID.
+ * @enable: boolean to enable or disable color keyl.
+ * @color_key: 24-bit RGB color to use as transparent color key.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel,
+ bool enable, uint32_t color_key)
+{
+ uint32_t reg, sdc_conf;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&mx3fb->lock, lock_flags);
+
+ sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+ if (channel == IDMAC_SDC_0)
+ sdc_conf &= ~SDC_COM_GWSEL;
+ else
+ sdc_conf |= SDC_COM_GWSEL;
+
+ if (enable) {
+ reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L;
+ mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL),
+ SDC_GW_CTRL);
+
+ sdc_conf |= SDC_COM_KEY_COLOR_G;
+ } else {
+ sdc_conf &= ~SDC_COM_KEY_COLOR_G;
+ }
+ mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF);
+
+ spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
+
+ return 0;
+}
+
+/**
+ * sdc_set_global_alpha() - set global alpha blending modes.
+ * @mx3fb: mx3fb context.
+ * @enable: boolean to enable or disable global alpha blending. If disabled,
+ * per pixel blending is used.
+ * @alpha: global alpha value.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha)
+{
+ uint32_t reg;
+ unsigned long lock_flags;
+
+ spin_lock_irqsave(&mx3fb->lock, lock_flags);
+
+ if (enable) {
+ reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL;
+ mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL);
+
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+ mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF);
+ } else {
+ reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
+ mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF);
+ }
+
+ spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
+
+ return 0;
+}
+
+static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)
+{
+ /* This might be board-specific */
+ mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL);
+ return;
+}
+
+static uint32_t bpp_to_pixfmt(int bpp)
+{
+ uint32_t pixfmt = 0;
+ switch (bpp) {
+ case 24:
+ pixfmt = IPU_PIX_FMT_BGR24;
+ break;
+ case 32:
+ pixfmt = IPU_PIX_FMT_BGR32;
+ break;
+ case 16:
+ pixfmt = IPU_PIX_FMT_RGB565;
+ break;
+ }
+ return pixfmt;
+}
+
+static int mx3fb_blank(int blank, struct fb_info *fbi);
+static int mx3fb_map_video_memory(struct fb_info *fbi);
+static int mx3fb_unmap_video_memory(struct fb_info *fbi);
+
+/**
+ * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings.
+ * @info: framebuffer information pointer
+ * @return: 0 on success or negative error code on failure.
+ */
+static int mx3fb_set_fix(struct fb_info *fbi)
+{
+ struct fb_fix_screeninfo *fix = &fbi->fix;
+ struct fb_var_screeninfo *var = &fbi->var;
+
+ strncpy(fix->id, "DISP3 BG", 8);
+
+ fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->accel = FB_ACCEL_NONE;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->xpanstep = 1;
+ fix->ypanstep = 1;
+
+ return 0;
+}
+
+static void mx3fb_dma_done(void *arg)
+{
+ struct idmac_tx_desc *tx_desc = to_tx_desc(arg);
+ struct dma_chan *chan = tx_desc->txd.chan;
+ struct idmac_channel *ichannel = to_idmac_chan(chan);
+ struct mx3fb_data *mx3fb = ichannel->client;
+ struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
+
+ dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq);
+
+ /* We only need one interrupt, it will be re-enabled as needed */
+ disable_irq(ichannel->eof_irq);
+
+ complete(&mx3_fbi->flip_cmpl);
+}
+
+/**
+ * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
+ * @fbi: framebuffer information pointer.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int mx3fb_set_par(struct fb_info *fbi)
+{
+ u32 mem_len;
+ struct ipu_di_signal_cfg sig_cfg;
+ enum ipu_panel mode = IPU_PANEL_TFT;
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+ struct idmac_channel *ichan = mx3_fbi->idmac_channel;
+ struct idmac_video_param *video = &ichan->params.video;
+ struct scatterlist *sg = mx3_fbi->sg;
+ size_t screen_size;
+
+ dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');
+
+ mutex_lock(&mx3_fbi->mutex);
+
+ /* Total cleanup */
+ if (mx3_fbi->txd)
+ sdc_disable_channel(mx3_fbi);
+
+ mx3fb_set_fix(fbi);
+
+ mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
+ if (mem_len > fbi->fix.smem_len) {
+ if (fbi->fix.smem_start)
+ mx3fb_unmap_video_memory(fbi);
+
+ fbi->fix.smem_len = mem_len;
+ if (mx3fb_map_video_memory(fbi) < 0) {
+ mutex_unlock(&mx3_fbi->mutex);
+ return -ENOMEM;
+ }
+ }
+
+ screen_size = fbi->fix.line_length * fbi->var.yres;
+
+ sg_init_table(&sg[0], 1);
+ sg_init_table(&sg[1], 1);
+
+ sg_dma_address(&sg[0]) = fbi->fix.smem_start;
+ sg_set_page(&sg[0], virt_to_page(fbi->screen_base),
+ fbi->fix.smem_len,
+ offset_in_page(fbi->screen_base));
+
+ if (mx3_fbi->ipu_ch == IDMAC_SDC_0) {
+ memset(&sig_cfg, 0, sizeof(sig_cfg));
+ if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ sig_cfg.Hsync_pol = true;
+ if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ sig_cfg.Vsync_pol = true;
+ if (fbi->var.sync & FB_SYNC_CLK_INVERT)
+ sig_cfg.clk_pol = true;
+ if (fbi->var.sync & FB_SYNC_DATA_INVERT)
+ sig_cfg.data_pol = true;
+ if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
+ sig_cfg.enable_pol = true;
+ if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
+ sig_cfg.clkidle_en = true;
+ if (fbi->var.sync & FB_SYNC_CLK_SEL_EN)
+ sig_cfg.clksel_en = true;
+ if (fbi->var.sync & FB_SYNC_SHARP_MODE)
+ mode = IPU_PANEL_SHARP_TFT;
+
+ dev_dbg(fbi->device, "pixclock = %ul Hz\n",
+ (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
+
+ if (sdc_init_panel(mx3fb, mode,
+ (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
+ fbi->var.xres, fbi->var.yres,
+ (fbi->var.sync & FB_SYNC_SWAP_RGB) ?
+ IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666,
+ fbi->var.left_margin,
+ fbi->var.hsync_len,
+ fbi->var.right_margin +
+ fbi->var.hsync_len,
+ fbi->var.upper_margin,
+ fbi->var.vsync_len,
+ fbi->var.lower_margin +
+ fbi->var.vsync_len, sig_cfg) != 0) {
+ mutex_unlock(&mx3_fbi->mutex);
+ dev_err(fbi->device,
+ "mx3fb: Error initializing panel.\n");
+ return -EINVAL;
+ }
+ }
+
+ sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0);
+
+ mx3_fbi->cur_ipu_buf = 0;
+
+ video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel);
+ video->out_width = fbi->var.xres;
+ video->out_height = fbi->var.yres;
+ video->out_stride = fbi->var.xres_virtual;
+
+ if (mx3_fbi->blank == FB_BLANK_UNBLANK)
+ sdc_enable_channel(mx3_fbi);
+
+ mutex_unlock(&mx3_fbi->mutex);
+
+ return 0;
+}
+
+/**
+ * mx3fb_check_var() - check and adjust framebuffer variable parameters.
+ * @var: framebuffer variable parameters
+ * @fbi: framebuffer information pointer
+ */
+static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ u32 vtotal;
+ u32 htotal;
+
+ dev_dbg(fbi->device, "%s\n", __func__);
+
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+
+ if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
+ (var->bits_per_pixel != 16))
+ var->bits_per_pixel = default_bpp;
+
+ switch (var->bits_per_pixel) {
+ case 16:
+ var->red.length = 5;
+ var->red.offset = 11;
+ var->red.msb_right = 0;
+
+ var->green.length = 6;
+ var->green.offset = 5;
+ var->green.msb_right = 0;
+
+ var->blue.length = 5;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 24:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 0;
+ var->transp.offset = 0;
+ var->transp.msb_right = 0;
+ break;
+ case 32:
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->red.msb_right = 0;
+
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->green.msb_right = 0;
+
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ var->blue.msb_right = 0;
+
+ var->transp.length = 8;
+ var->transp.offset = 24;
+ var->transp.msb_right = 0;
+ break;
+ }
+
+ if (var->pixclock < 1000) {
+ htotal = var->xres + var->right_margin + var->hsync_len +
+ var->left_margin;
+ vtotal = var->yres + var->lower_margin + var->vsync_len +
+ var->upper_margin;
+ var->pixclock = (vtotal * htotal * 6UL) / 100UL;
+ var->pixclock = KHZ2PICOS(var->pixclock);
+ dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n",
+ var->pixclock);
+ }
+
+ var->height = -1;
+ var->width = -1;
+ var->grayscale = 0;
+
+ /* Preserve sync flags */
+ var->sync |= mx3_fbi->sync;
+ mx3_fbi->sync |= var->sync;
+
+ return 0;
+}
+
+static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
+ unsigned int green, unsigned int blue,
+ unsigned int trans, struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ u32 val;
+ int ret = 1;
+
+ dev_dbg(fbi->device, "%s\n", __func__);
+
+ mutex_lock(&mx3_fbi->mutex);
+ /*
+ * If greyscale is true, then we convert the RGB value
+ * to greyscale no matter what visual we are using.
+ */
+ if (fbi->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green +
+ 7471 * blue) >> 16;
+ switch (fbi->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /*
+ * 16-bit True Colour. We encode the RGB value
+ * according to the RGB bitfield information.
+ */
+ if (regno < 16) {
+ u32 *pal = fbi->pseudo_palette;
+
+ val = chan_to_field(red, &fbi->var.red);
+ val |= chan_to_field(green, &fbi->var.green);
+ val |= chan_to_field(blue, &fbi->var.blue);
+
+ pal[regno] = val;
+
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ break;
+ }
+ mutex_unlock(&mx3_fbi->mutex);
+
+ return ret;
+}
+
+/**
+ * mx3fb_blank() - blank the display.
+ */
+static int mx3fb_blank(int blank, struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
+
+ dev_dbg(fbi->device, "%s\n", __func__);
+
+ dev_dbg(fbi->device, "blank = %d\n", blank);
+
+ if (mx3_fbi->blank == blank)
+ return 0;
+
+ mutex_lock(&mx3_fbi->mutex);
+ mx3_fbi->blank = blank;
+
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ sdc_disable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, 0);
+ break;
+ case FB_BLANK_UNBLANK:
+ sdc_enable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, mx3fb->backlight_level);
+ break;
+ }
+ mutex_unlock(&mx3_fbi->mutex);
+
+ return 0;
+}
+
+/**
+ * mx3fb_pan_display() - pan or wrap the display
+ * @var: variable screen buffer information.
+ * @info: framebuffer information pointer.
+ *
+ * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+static int mx3fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *fbi)
+{
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ u32 y_bottom;
+ unsigned long base;
+ off_t offset;
+ dma_cookie_t cookie;
+ struct scatterlist *sg = mx3_fbi->sg;
+ struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan;
+ struct dma_async_tx_descriptor *txd;
+ int ret;
+
+ dev_dbg(fbi->device, "%s [%c]\n", __func__,
+ list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+');
+
+ if (var->xoffset > 0) {
+ dev_dbg(fbi->device, "x panning not supported\n");
+ return -EINVAL;
+ }
+
+ if (fbi->var.xoffset == var->xoffset &&
+ fbi->var.yoffset == var->yoffset)
+ return 0; /* No change, do nothing */
+
+ y_bottom = var->yoffset;
+
+ if (!(var->vmode & FB_VMODE_YWRAP))
+ y_bottom += var->yres;
+
+ if (y_bottom > fbi->var.yres_virtual)
+ return -EINVAL;
+
+ mutex_lock(&mx3_fbi->mutex);
+
+ offset = (var->yoffset * var->xres_virtual + var->xoffset) *
+ (var->bits_per_pixel / 8);
+ base = fbi->fix.smem_start + offset;
+
+ dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
+ mx3_fbi->cur_ipu_buf, base);
+
+ /*
+ * We enable the End of Frame interrupt, which will free a tx-descriptor,
+ * which we will need for the next device_prep_slave_sg(). The
+ * IRQ-handler will disable the IRQ again.
+ */
+ init_completion(&mx3_fbi->flip_cmpl);
+ enable_irq(mx3_fbi->idmac_channel->eof_irq);
+
+ ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10);
+ if (ret <= 0) {
+ mutex_unlock(&mx3_fbi->mutex);
+ dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ?
+ "user interrupt" : "timeout");
+ return ret ? : -ETIMEDOUT;
+ }
+
+ mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf;
+
+ sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base;
+ sg_set_page(&sg[mx3_fbi->cur_ipu_buf],
+ virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len,
+ offset_in_page(fbi->screen_base + offset));
+
+ txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg +
+ mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
+ if (!txd) {
+ dev_err(fbi->device,
+ "Error preparing a DMA transaction descriptor.\n");
+ mutex_unlock(&mx3_fbi->mutex);
+ return -EIO;
+ }
+
+ txd->callback_param = txd;
+ txd->callback = mx3fb_dma_done;
+
+ /*
+ * Emulate original mx3fb behaviour: each new call to idmac_tx_submit()
+ * should switch to another buffer
+ */
+ cookie = txd->tx_submit(txd);
+ dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie);
+ if (cookie < 0) {
+ dev_err(fbi->device,
+ "Error updating SDC buf %d to address=0x%08lX\n",
+ mx3_fbi->cur_ipu_buf, base);
+ mutex_unlock(&mx3_fbi->mutex);
+ return -EIO;
+ }
+
+ if (mx3_fbi->txd)
+ async_tx_ack(mx3_fbi->txd);
+ mx3_fbi->txd = txd;
+
+ fbi->var.xoffset = var->xoffset;
+ fbi->var.yoffset = var->yoffset;
+
+ if (var->vmode & FB_VMODE_YWRAP)
+ fbi->var.vmode |= FB_VMODE_YWRAP;
+ else
+ fbi->var.vmode &= ~FB_VMODE_YWRAP;
+
+ mutex_unlock(&mx3_fbi->mutex);
+
+ dev_dbg(fbi->device, "Update complete\n");
+
+ return 0;
+}
+
+/*
+ * This structure contains the pointers to the control functions that are
+ * invoked by the core framebuffer driver to perform operations like
+ * blitting, rectangle filling, copy regions and cursor definition.
+ */
+static struct fb_ops mx3fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_set_par = mx3fb_set_par,
+ .fb_check_var = mx3fb_check_var,
+ .fb_setcolreg = mx3fb_setcolreg,
+ .fb_pan_display = mx3fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_blank = mx3fb_blank,
+};
+
+#ifdef CONFIG_PM
+/*
+ * Power management hooks. Note that we won't be called from IRQ context,
+ * unlike the blank functions above, so we may sleep.
+ */
+
+/*
+ * Suspends the framebuffer and blanks the screen. Power management support
+ */
+static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
+ struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
+
+ acquire_console_sem();
+ fb_set_suspend(drv_data->fbi, 1);
+ release_console_sem();
+
+ if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
+ sdc_disable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, 0);
+
+ }
+ return 0;
+}
+
+/*
+ * Resumes the framebuffer and unblanks the screen. Power management support
+ */
+static int mx3fb_resume(struct platform_device *pdev)
+{
+ struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
+ struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
+
+ if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
+ sdc_enable_channel(mx3_fbi);
+ sdc_set_brightness(mx3fb, drv_data->backlight_level);
+ }
+
+ acquire_console_sem();
+ fb_set_suspend(drv_data->fbi, 0);
+ release_console_sem();
+
+ return 0;
+}
+#else
+#define mx3fb_suspend NULL
+#define mx3fb_resume NULL
+#endif
+
+/*
+ * Main framebuffer functions
+ */
+
+/**
+ * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
+ * @fbi: framebuffer information pointer
+ * @return: Error code indicating success or failure
+ *
+ * This buffer is remapped into a non-cached, non-buffered, memory region to
+ * allow palette and pixel writes to occur without flushing the cache. Once this
+ * area is remapped, all virtual memory access to the video memory should occur
+ * at the new region.
+ */
+static int mx3fb_map_video_memory(struct fb_info *fbi)
+{
+ int retval = 0;
+ dma_addr_t addr;
+
+ fbi->screen_base = dma_alloc_writecombine(fbi->device,
+ fbi->fix.smem_len,
+ &addr, GFP_DMA);
+
+ if (!fbi->screen_base) {
+ dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",
+ fbi->fix.smem_len);
+ retval = -EBUSY;
+ goto err0;
+ }
+
+ fbi->fix.smem_start = addr;
+
+ dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",
+ (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
+
+ fbi->screen_size = fbi->fix.smem_len;
+
+ /* Clear the screen */
+ memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
+
+ return 0;
+
+err0:
+ fbi->fix.smem_len = 0;
+ fbi->fix.smem_start = 0;
+ fbi->screen_base = NULL;
+ return retval;
+}
+
+/**
+ * mx3fb_unmap_video_memory() - de-allocate frame buffer memory.
+ * @fbi: framebuffer information pointer
+ * @return: error code indicating success or failure
+ */
+static int mx3fb_unmap_video_memory(struct fb_info *fbi)
+{
+ dma_free_writecombine(fbi->device, fbi->fix.smem_len,
+ fbi->screen_base, fbi->fix.smem_start);
+
+ fbi->screen_base = 0;
+ fbi->fix.smem_start = 0;
+ fbi->fix.smem_len = 0;
+ return 0;
+}
+
+/**
+ * mx3fb_init_fbinfo() - initialize framebuffer information object.
+ * @return: initialized framebuffer structure.
+ */
+static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)
+{
+ struct fb_info *fbi;
+ struct mx3fb_info *mx3fbi;
+ int ret;
+
+ /* Allocate sufficient memory for the fb structure */
+ fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev);
+ if (!fbi)
+ return NULL;
+
+ mx3fbi = fbi->par;
+ mx3fbi->cookie = -EINVAL;
+ mx3fbi->cur_ipu_buf = 0;
+
+ fbi->var.activate = FB_ACTIVATE_NOW;
+
+ fbi->fbops = ops;
+ fbi->flags = FBINFO_FLAG_DEFAULT;
+ fbi->pseudo_palette = mx3fbi->pseudo_palette;
+
+ mutex_init(&mx3fbi->mutex);
+
+ /* Allocate colormap */
+ ret = fb_alloc_cmap(&fbi->cmap, 16, 0);
+ if (ret < 0) {
+ framebuffer_release(fbi);
+ return NULL;
+ }
+
+ return fbi;
+}
+
+static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
+{
+ struct device *dev = mx3fb->dev;
+ struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data;
+ const char *name = mx3fb_pdata->name;
+ unsigned int irq;
+ struct fb_info *fbi;
+ struct mx3fb_info *mx3fbi;
+ const struct fb_videomode *mode;
+ int ret, num_modes;
+
+ ichan->client = mx3fb;
+ irq = ichan->eof_irq;
+
+ if (ichan->dma_chan.chan_id != IDMAC_SDC_0)
+ return -EINVAL;
+
+ fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops);
+ if (!fbi)
+ return -ENOMEM;
+
+ if (!fb_mode)
+ fb_mode = name;
+
+ if (!fb_mode) {
+ ret = -EINVAL;
+ goto emode;
+ }
+
+ if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) {
+ mode = mx3fb_pdata->mode;
+ num_modes = mx3fb_pdata->num_modes;
+ } else {
+ mode = mx3fb_modedb;
+ num_modes = ARRAY_SIZE(mx3fb_modedb);
+ }
+
+ if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode,
+ num_modes, NULL, default_bpp)) {
+ ret = -EBUSY;
+ goto emode;
+ }
+
+ fb_videomode_to_modelist(mode, num_modes, &fbi->modelist);
+
+ /* Default Y virtual size is 2x panel size */
+ fbi->var.yres_virtual = fbi->var.yres * 2;
+
+ mx3fb->fbi = fbi;
+
+ /* set Display Interface clock period */
+ mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER);
+ /* Might need to trigger HSP clock change - see 44.3.3.8.5 */
+
+ sdc_set_brightness(mx3fb, 255);
+ sdc_set_global_alpha(mx3fb, true, 0xFF);
+ sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0);
+
+ mx3fbi = fbi->par;
+ mx3fbi->idmac_channel = ichan;
+ mx3fbi->ipu_ch = ichan->dma_chan.chan_id;
+ mx3fbi->mx3fb = mx3fb;
+ mx3fbi->blank = FB_BLANK_NORMAL;
+
+ init_completion(&mx3fbi->flip_cmpl);
+ disable_irq(ichan->eof_irq);
+ dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
+ ret = mx3fb_set_par(fbi);
+ if (ret < 0)
+ goto esetpar;
+
+ mx3fb_blank(FB_BLANK_UNBLANK, fbi);
+
+ dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode);
+
+ ret = register_framebuffer(fbi);
+ if (ret < 0)
+ goto erfb;
+
+ return 0;
+
+erfb:
+esetpar:
+emode:
+ fb_dealloc_cmap(&fbi->cmap);
+ framebuffer_release(fbi);
+
+ return ret;
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ struct dma_chan_request *rq = arg;
+ struct device *dev;
+ struct mx3fb_platform_data *mx3fb_pdata;
+
+ if (!rq)
+ return false;
+
+ dev = rq->mx3fb->dev;
+ mx3fb_pdata = dev->platform_data;
+
+ return rq->id == chan->chan_id &&
+ mx3fb_pdata->dma_dev == chan->device->dev;
+}
+
+static void release_fbi(struct fb_info *fbi)
+{
+ mx3fb_unmap_video_memory(fbi);
+
+ fb_dealloc_cmap(&fbi->cmap);
+
+ unregister_framebuffer(fbi);
+ framebuffer_release(fbi);
+}
+
+static int mx3fb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int ret;
+ struct resource *sdc_reg;
+ struct mx3fb_data *mx3fb;
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+ struct dma_chan_request rq;
+
+ /*
+ * Display Interface (DI) and Synchronous Display Controller (SDC)
+ * registers
+ */
+ sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!sdc_reg)
+ return -EINVAL;
+
+ mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL);
+ if (!mx3fb)
+ return -ENOMEM;
+
+ spin_lock_init(&mx3fb->lock);
+
+ mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg));
+ if (!mx3fb->reg_base) {
+ ret = -ENOMEM;
+ goto eremap;
+ }
+
+ pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end,
+ mx3fb->reg_base);
+
+ /* IDMAC interface */
+ dmaengine_get();
+
+ mx3fb->dev = dev;
+ platform_set_drvdata(pdev, mx3fb);
+
+ rq.mx3fb = mx3fb;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ rq.id = IDMAC_SDC_0;
+ chan = dma_request_channel(mask, chan_filter, &rq);
+ if (!chan) {
+ ret = -EBUSY;
+ goto ersdc0;
+ }
+
+ ret = init_fb_chan(mx3fb, to_idmac_chan(chan));
+ if (ret < 0)
+ goto eisdc0;
+
+ mx3fb->backlight_level = 255;
+
+ return 0;
+
+eisdc0:
+ dma_release_channel(chan);
+ersdc0:
+ dmaengine_put();
+ iounmap(mx3fb->reg_base);
+eremap:
+ kfree(mx3fb);
+ dev_err(dev, "mx3fb: failed to register fb\n");
+ return ret;
+}
+
+static int mx3fb_remove(struct platform_device *dev)
+{
+ struct mx3fb_data *mx3fb = platform_get_drvdata(dev);
+ struct fb_info *fbi = mx3fb->fbi;
+ struct mx3fb_info *mx3_fbi = fbi->par;
+ struct dma_chan *chan;
+
+ chan = &mx3_fbi->idmac_channel->dma_chan;
+ release_fbi(fbi);
+
+ dma_release_channel(chan);
+ dmaengine_put();
+
+ iounmap(mx3fb->reg_base);
+ kfree(mx3fb);
+ return 0;
+}
+
+static struct platform_driver mx3fb_driver = {
+ .driver = {
+ .name = MX3FB_NAME,
+ },
+ .probe = mx3fb_probe,
+ .remove = mx3fb_remove,
+ .suspend = mx3fb_suspend,
+ .resume = mx3fb_resume,
+};
+
+/*
+ * Parse user specified options (`video=mx3fb:')
+ * example:
+ * video=mx3fb:bpp=16
+ */
+static int mx3fb_setup(void)
+{
+#ifndef MODULE
+ char *opt, *options = NULL;
+
+ if (fb_get_options("mx3fb", &options))
+ return -ENODEV;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+ if (!strncmp(opt, "bpp=", 4))
+ default_bpp = simple_strtoul(opt + 4, NULL, 0);
+ else
+ fb_mode = opt;
+ }
+#endif
+
+ return 0;
+}
+
+static int __init mx3fb_init(void)
+{
+ int ret = mx3fb_setup();
+
+ if (ret < 0)
+ return ret;
+
+ ret = platform_driver_register(&mx3fb_driver);
+ return ret;
+}
+
+static void __exit mx3fb_exit(void)
+{
+ platform_driver_unregister(&mx3fb_driver);
+}
+
+module_init(mx3fb_init);
+module_exit(mx3fb_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MX3 framebuffer driver");
+MODULE_ALIAS("platform:" MX3FB_NAME);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 6fd7cb8f9b8e..6aaddb4f6788 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -87,7 +87,6 @@ static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name,
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_NVIDIA;
chan->adapter.class = i2c_class;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pci_dev->dev;
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index 6e2ea7518761..ab3949256677 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -800,14 +800,14 @@ static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode,
/* FIXME:
* According to errata some platforms have a clock rate limitiation
*/
- lcdc.lcd_ck = clk_get(NULL, "lcd_ck");
+ lcdc.lcd_ck = clk_get(fbdev->dev, "lcd_ck");
if (IS_ERR(lcdc.lcd_ck)) {
dev_err(fbdev->dev, "unable to access LCD clock\n");
r = PTR_ERR(lcdc.lcd_ck);
goto fail0;
}
- tc_ck = clk_get(NULL, "tc_ck");
+ tc_ck = clk_get(fbdev->dev, "tc_ck");
if (IS_ERR(tc_ck)) {
dev_err(fbdev->dev, "unable to access TC clock\n");
r = PTR_ERR(tc_ck);
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index 3a3f80f65219..0573ec685a57 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -151,7 +151,7 @@ static int __init pmagbafb_probe(struct device *dev)
info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
if (!info) {
- printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
return -ENOMEM;
}
@@ -160,7 +160,7 @@ static int __init pmagbafb_probe(struct device *dev)
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
printk(KERN_ERR "%s: Cannot allocate color map\n",
- dev->bus_id);
+ dev_name(dev));
err = -ENOMEM;
goto err_alloc;
}
@@ -173,8 +173,9 @@ static int __init pmagbafb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id)) {
- printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ if (!request_mem_region(start, len, dev_name(dev))) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n",
+ dev_name(dev));
err = -EBUSY;
goto err_cmap;
}
@@ -183,7 +184,7 @@ static int __init pmagbafb_probe(struct device *dev)
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
if (!par->mmio) {
- printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
err = -ENOMEM;
goto err_resource;
}
@@ -194,7 +195,7 @@ static int __init pmagbafb_probe(struct device *dev)
info->screen_base = ioremap_nocache(info->fix.smem_start,
info->fix.smem_len);
if (!info->screen_base) {
- printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
err = -ENOMEM;
goto err_mmio_map;
}
@@ -205,14 +206,14 @@ static int __init pmagbafb_probe(struct device *dev)
err = register_framebuffer(info);
if (err < 0) {
printk(KERN_ERR "%s: Cannot register framebuffer\n",
- dev->bus_id);
+ dev_name(dev));
goto err_smem_map;
}
get_device(dev);
pr_info("fb%d: %s frame buffer device at %s\n",
- info->node, info->fix.id, dev->bus_id);
+ info->node, info->fix.id, dev_name(dev));
return 0;
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 9b80597241b0..98748723af9f 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -258,7 +258,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
if (!info) {
- printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
return -ENOMEM;
}
@@ -267,7 +267,7 @@ static int __init pmagbbfb_probe(struct device *dev)
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
printk(KERN_ERR "%s: Cannot allocate color map\n",
- dev->bus_id);
+ dev_name(dev));
err = -ENOMEM;
goto err_alloc;
}
@@ -280,8 +280,9 @@ static int __init pmagbbfb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id)) {
- printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ if (!request_mem_region(start, len, dev_name(dev))) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n",
+ dev_name(dev));
err = -EBUSY;
goto err_cmap;
}
@@ -290,7 +291,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
if (!par->mmio) {
- printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev_name(dev));
err = -ENOMEM;
goto err_resource;
}
@@ -301,7 +302,7 @@ static int __init pmagbbfb_probe(struct device *dev)
info->fix.smem_start = start + PMAGB_B_FBMEM;
par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
if (!par->smem) {
- printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ printk(KERN_ERR "%s: Cannot map FB\n", dev_name(dev));
err = -ENOMEM;
goto err_mmio_map;
}
@@ -316,7 +317,7 @@ static int __init pmagbbfb_probe(struct device *dev)
err = register_framebuffer(info);
if (err < 0) {
printk(KERN_ERR "%s: Cannot register framebuffer\n",
- dev->bus_id);
+ dev_name(dev));
goto err_smem_map;
}
@@ -328,7 +329,7 @@ static int __init pmagbbfb_probe(struct device *dev)
par->osc1 / 1000, par->osc1 % 1000);
pr_info("fb%d: %s frame buffer device at %s\n",
- info->node, info->fix.id, dev->bus_id);
+ info->node, info->fix.id, dev_name(dev));
pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n",
info->node, freq0, par->osc1 ? freq1 : "disabled",
par->osc1 != 0);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 87f826e4c958..e00c1dff55de 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -1213,7 +1213,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
dev->core.driver_data = info;
dev_info(info->device, "%s %s, using %u KiB of video memory\n",
- dev_driver_string(info->dev), info->dev->bus_id,
+ dev_driver_string(info->dev), dev_name(info->dev),
info->fix.smem_len >> 10);
task = kthread_run(ps3fbd, info, DEVICE_NAME);
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 48ff701d3a72..287aa1d2a13c 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -59,7 +59,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/div64.h>
-#include <mach/pxa-regs.h>
#include <mach/bitfield.h>
#include <mach/pxafb.h>
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 79cf0b1976aa..b0b4513ba537 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -1017,6 +1017,10 @@ static int s3c2410fb_resume(struct platform_device *dev)
s3c2410fb_init_registers(fbinfo);
+ /* re-activate our display after resume */
+ s3c2410fb_activate_var(fbinfo);
+ s3c2410fb_blank(FB_BLANK_UNBLANK, fbinfo);
+
return 0;
}
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 076f946fa0f5..022d07abbf99 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -251,22 +251,6 @@ static struct sa1100fb_mach_info pal_info __initdata = {
#endif
#endif
-#ifdef CONFIG_SA1100_H3800
-static struct sa1100fb_mach_info h3800_info __initdata = {
- .pixclock = 174757, .bpp = 16,
- .xres = 320, .yres = 240,
-
- .hsync_len = 3, .vsync_len = 3,
- .left_margin = 12, .upper_margin = 10,
- .right_margin = 17, .lower_margin = 1,
-
- .cmap_static = 1,
-
- .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
- .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#endif
-
#ifdef CONFIG_SA1100_H3600
static struct sa1100fb_mach_info h3600_info __initdata = {
.pixclock = 174757, .bpp = 16,
@@ -432,11 +416,6 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
fbi->rgb[RGB_16] = &h3600_rgb_16;
}
#endif
-#ifdef CONFIG_SA1100_H3800
- if (machine_is_h3800()) {
- inf = &h3800_info;
- }
-#endif
#ifdef CONFIG_SA1100_COLLIE
if (machine_is_collie()) {
inf = &collie_info;
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 783d4adffb93..574b29e9f8f2 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -137,7 +137,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
if (chan->par) {
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_SAVAGE;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pcidev->dev;
chan->algo.udelay = 10;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 0e2b8fd24df1..e8d24ea8f65d 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -689,7 +689,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
}
error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
- pdev->dev.bus_id, priv);
+ dev_name(&pdev->dev), priv);
if (error) {
dev_err(&pdev->dev, "unable to request irq\n");
goto err1;
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index 7baf2dd12d50..a1eb0862255b 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -751,7 +751,7 @@ static int __devinit tmiofb_probe(struct platform_device *dev)
}
retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
- dev->dev.bus_id, info);
+ dev_name(&dev->dev), info);
if (retval)
goto err_request_irq;
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index bef6b45e8a5c..330aacbdec1f 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -192,7 +192,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
drv = container_of(vp_dev->vdev.dev.driver,
struct virtio_driver, driver);
- if (drv->config_changed)
+ if (drv && drv->config_changed)
drv->config_changed(&vp_dev->vdev);
}
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 2c8dff9f77da..1ed3d554e372 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -115,7 +115,7 @@ static struct w1_therm_family_converter w1_therm_families[] = {
static inline int w1_DS18B20_convert_temp(u8 rom[9])
{
- s16 t = (rom[1] << 8) | rom[0];
+ int t = ((s16)rom[1] << 8) | rom[0];
t = t*1000/16;
return t;
}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3efa12f9ee50..c7352f7195ee 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -187,10 +187,10 @@ config EP93XX_WATCHDOG
config OMAP_WATCHDOG
tristate "OMAP Watchdog"
- depends on ARCH_OMAP16XX || ARCH_OMAP24XX
+ depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
help
- Support for TI OMAP1610/OMAP1710/OMAP2420 watchdog. Say 'Y' here to
- enable the OMAP1610/OMAP1710 watchdog timer.
+ Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y'
+ here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer.
config PNX4008_WATCHDOG
tristate "PNX4008 Watchdog"
@@ -406,7 +406,7 @@ config ITCO_WDT
---help---
Hardware driver for the intel TCO timer based watchdog devices.
These drivers are included in the Intel 82801 I/O Controller
- Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB
+ Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB
controller hub.
The TCO (Total Cost of Ownership) timer is a watchdog timer
@@ -772,7 +772,7 @@ config TXX9_WDT
config GEF_WDT
tristate "GE Fanuc Watchdog Timer"
- depends on GEF_SBC610
+ depends on GEF_SBC610 || GEF_SBC310
---help---
Watchdog timer found in a number of GE Fanuc single board computers.
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 993e5f52afef..e35d54589232 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -13,6 +13,7 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
@@ -106,10 +107,10 @@ static int at91_wdt_close(struct inode *inode, struct file *file)
static int at91_wdt_settimeout(int new_time)
{
/*
- * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz
+ * All counting occurs at SLOW_CLOCK / 128 = 256 Hz
*
* Since WDV is a 16-bit counter, the maximum period is
- * 65536 / 0.256 = 256 seconds.
+ * 65536 / 256 = 256 seconds.
*/
if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
return -EINVAL;
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index b1da287f90ec..a56ac84381b1 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -18,6 +18,7 @@
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index 2474ebca88f6..d8264ad0be41 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -1,7 +1,7 @@
/*
* intel TCO vendor specific watchdog driver support
*
- * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>.
+ * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,7 +19,7 @@
/* Module and version information */
#define DRV_NAME "iTCO_vendor_support"
-#define DRV_VERSION "1.02"
+#define DRV_VERSION "1.03"
#define PFX DRV_NAME ": "
/* Includes */
@@ -77,6 +77,26 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (n
* 20.6 seconds.
*/
+static void supermicro_old_pre_start(unsigned long acpibase)
+{
+ unsigned long val32;
+
+ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
+ val32 = inl(SMI_EN);
+ val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
+ outl(val32, SMI_EN); /* Needed to activate watchdog */
+}
+
+static void supermicro_old_pre_stop(unsigned long acpibase)
+{
+ unsigned long val32;
+
+ /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */
+ val32 = inl(SMI_EN);
+ val32 |= 0x00002000; /* Turn on SMI clearing watchdog */
+ outl(val32, SMI_EN); /* Needed to deactivate watchdog */
+}
+
static void supermicro_old_pre_keepalive(unsigned long acpibase)
{
/* Reload TCO Timer (done in iTCO_wdt_keepalive) + */
@@ -228,14 +248,18 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat)
void iTCO_vendor_pre_start(unsigned long acpibase,
unsigned int heartbeat)
{
- if (vendorsupport == SUPERMICRO_NEW_BOARD)
+ if (vendorsupport == SUPERMICRO_OLD_BOARD)
+ supermicro_old_pre_start(acpibase);
+ else if (vendorsupport == SUPERMICRO_NEW_BOARD)
supermicro_new_pre_start(heartbeat);
}
EXPORT_SYMBOL(iTCO_vendor_pre_start);
void iTCO_vendor_pre_stop(unsigned long acpibase)
{
- if (vendorsupport == SUPERMICRO_NEW_BOARD)
+ if (vendorsupport == SUPERMICRO_OLD_BOARD)
+ supermicro_old_pre_stop(acpibase);
+ else if (vendorsupport == SUPERMICRO_NEW_BOARD)
supermicro_new_pre_stop();
}
EXPORT_SYMBOL(iTCO_vendor_pre_stop);
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 5b395a4ddfdf..352334947ea3 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -1,7 +1,7 @@
/*
- * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
+ * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets)
*
- * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>.
+ * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -63,7 +63,7 @@
/* Module and version information */
#define DRV_NAME "iTCO_wdt"
-#define DRV_VERSION "1.04"
+#define DRV_VERSION "1.05"
#define PFX DRV_NAME ": "
/* Includes */
@@ -236,16 +236,16 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
/* Address definitions for the TCO */
/* TCO base address */
-#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
+#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
/* SMI Control and Enable Register */
-#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
+#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */
#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */
-#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
-#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
-#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
-#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
+#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
+#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
+#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
+#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */
#define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */
#define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */
#define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */
@@ -338,7 +338,6 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void)
static int iTCO_wdt_start(void)
{
unsigned int val;
- unsigned long val32;
spin_lock(&iTCO_wdt_private.io_lock);
@@ -351,11 +350,6 @@ static int iTCO_wdt_start(void)
return -EIO;
}
- /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
- val32 = inl(SMI_EN);
- val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
- outl(val32, SMI_EN);
-
/* Force the timer to its reload value by writing to the TCO_RLD
register */
if (iTCO_wdt_private.iTCO_version == 2)
@@ -378,7 +372,6 @@ static int iTCO_wdt_start(void)
static int iTCO_wdt_stop(void)
{
unsigned int val;
- unsigned long val32;
spin_lock(&iTCO_wdt_private.io_lock);
@@ -390,11 +383,6 @@ static int iTCO_wdt_stop(void)
outw(val, TCO1_CNT);
val = inw(TCO1_CNT);
- /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */
- val32 = inl(SMI_EN);
- val32 |= 0x00002000;
- outl(val32, SMI_EN);
-
/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
iTCO_wdt_set_NO_REBOOT_bit();
@@ -649,6 +637,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
int ret;
u32 base_address;
unsigned long RCBA;
+ unsigned long val32;
/*
* Find the ACPI/PM base I/O address which is the base
@@ -695,6 +684,10 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
ret = -EIO;
goto out;
}
+ /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */
+ val32 = inl(SMI_EN);
+ val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */
+ outl(val32, SMI_EN);
/* The TCO I/O registers reside in a 32-byte range pointed to
by the TCOBASE value */
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index bf92802f2bbe..36e221beedcd 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -37,7 +37,7 @@
#include <linux/io.h>
#include <linux/uaccess.h>
-#include <asm/mach-rdc321x/rdc321x_defs.h>
+#include <asm/rdc321x_defs.h>
#define RDC_WDT_MASK 0x80000000 /* Mask */
#define RDC_WDT_EN 0x00800000 /* Enable bit */
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index f1ae3729a19e..cce1982a1b58 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -59,8 +59,8 @@ static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long);
static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *);
static const struct resource *wdt_gpi_get_resource(struct platform_device *,
const char *, unsigned int);
-static int __init wdt_gpi_probe(struct device *);
-static int __exit wdt_gpi_remove(struct device *);
+static int __init wdt_gpi_probe(struct platform_device *);
+static int __exit wdt_gpi_remove(struct platform_device *);
static const char wdt_gpi_name[] = "wdt_gpi";
@@ -346,10 +346,9 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
}
/* No hotplugging on the platform bus - use __init */
-static int __init wdt_gpi_probe(struct device *dev)
+static int __init wdt_gpi_probe(struct platform_device *pdv)
{
int res;
- struct platform_device * const pdv = to_platform_device(dev);
const struct resource
* const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS,
IORESOURCE_MEM),
@@ -374,7 +373,7 @@ static int __init wdt_gpi_probe(struct device *dev)
return res;
}
-static int __exit wdt_gpi_remove(struct device *dev)
+static int __exit wdt_gpi_remove(struct platform_device *dev)
{
int res;
@@ -387,15 +386,13 @@ static int __exit wdt_gpi_remove(struct device *dev)
/* Device driver init & exit */
-static struct device_driver wdt_gpi_driver = {
- .name = (char *) wdt_gpi_name,
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
+static struct platform_driver wgt_gpi_driver = {
+ .driver = {
+ .name = wdt_gpi_name,
+ .owner = THIS_MODULE,
+ },
.probe = wdt_gpi_probe,
- .remove = __exit_p(wdt_gpi_remove),
- .shutdown = NULL,
- .suspend = NULL,
- .resume = NULL,
+ .remove = __devexit_p(wdt_gpi_remove),
};
static int __init wdt_gpi_init_module(void)
@@ -403,12 +400,12 @@ static int __init wdt_gpi_init_module(void)
atomic_set(&opencnt, 1);
if (timeout > MAX_TIMEOUT_SECONDS)
timeout = MAX_TIMEOUT_SECONDS;
- return driver_register(&wdt_gpi_driver);
+ return platform_driver_register(&wdt_gpi_driver);
}
static void __exit wdt_gpi_cleanup_module(void)
{
- driver_unregister(&wdt_gpi_driver);
+ platform_driver_unregister(&wdt_gpi_driver);
}
module_init(wdt_gpi_init_module);
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index e19b45794717..4b84f296d30c 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -30,7 +30,7 @@
#include <linux/timex.h>
#ifdef CONFIG_ARCH_PXA
-#include <mach/pxa-regs.h>
+#include <mach/regs-ost.h>
#endif
#include <mach/reset.h>
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 8dc7109d61b7..efa4b363ce72 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -298,6 +298,14 @@ static int decrease_reservation(unsigned long nr_pages)
frame_list[i] = pfn_to_mfn(pfn);
scrub_page(page);
+
+ if (!PageHighMem(page)) {
+ ret = HYPERVISOR_update_va_mapping(
+ (unsigned long)__va(pfn << PAGE_SHIFT),
+ __pte_ma(0), 0);
+ BUG_ON(ret);
+ }
+
}
/* Ensure that ballooned highmem pages don't have kmaps. */
@@ -490,7 +498,7 @@ static ssize_t store_target_kb(struct sys_device *dev,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- target_bytes = memparse(buf, &endchar);
+ target_bytes = simple_strtoull(buf, &endchar, 0) * 1024;
balloon_set_new_target(target_bytes >> PAGE_SHIFT);
@@ -500,8 +508,39 @@ static ssize_t store_target_kb(struct sys_device *dev,
static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR,
show_target_kb, store_target_kb);
+
+static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%llu\n",
+ (u64)balloon_stats.target_pages << PAGE_SHIFT);
+}
+
+static ssize_t store_target(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ char *endchar;
+ unsigned long long target_bytes;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ target_bytes = memparse(buf, &endchar);
+
+ balloon_set_new_target(target_bytes >> PAGE_SHIFT);
+
+ return count;
+}
+
+static SYSDEV_ATTR(target, S_IRUGO | S_IWUSR,
+ show_target, store_target);
+
+
static struct sysdev_attribute *balloon_attrs[] = {
&attr_target_kb,
+ &attr_target,
};
static struct attribute *balloon_info_attrs[] = {
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index eb0dfdeaa949..30963af5dba0 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -26,9 +26,11 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/string.h>
+#include <linux/bootmem.h>
#include <asm/ptrace.h>
#include <asm/irq.h>
+#include <asm/idle.h>
#include <asm/sync_bitops.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
@@ -50,36 +52,55 @@ static DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
/* IRQ <-> IPI mapping */
static DEFINE_PER_CPU(int, ipi_to_irq[XEN_NR_IPIS]) = {[0 ... XEN_NR_IPIS-1] = -1};
-/* Packed IRQ information: binding type, sub-type index, and event channel. */
-struct packed_irq
-{
- unsigned short evtchn;
- unsigned char index;
- unsigned char type;
-};
-
-static struct packed_irq irq_info[NR_IRQS];
-
-/* Binding types. */
-enum {
- IRQT_UNBOUND,
+/* Interrupt types. */
+enum xen_irq_type {
+ IRQT_UNBOUND = 0,
IRQT_PIRQ,
IRQT_VIRQ,
IRQT_IPI,
IRQT_EVTCHN
};
-/* Convenient shorthand for packed representation of an unbound IRQ. */
-#define IRQ_UNBOUND mk_irq_info(IRQT_UNBOUND, 0, 0)
+/*
+ * Packed IRQ information:
+ * type - enum xen_irq_type
+ * event channel - irq->event channel mapping
+ * cpu - cpu this event channel is bound to
+ * index - type-specific information:
+ * PIRQ - vector, with MSB being "needs EIO"
+ * VIRQ - virq number
+ * IPI - IPI vector
+ * EVTCHN -
+ */
+struct irq_info
+{
+ enum xen_irq_type type; /* type */
+ unsigned short evtchn; /* event channel */
+ unsigned short cpu; /* cpu bound */
+
+ union {
+ unsigned short virq;
+ enum ipi_vector ipi;
+ struct {
+ unsigned short gsi;
+ unsigned short vector;
+ } pirq;
+ } u;
+};
+
+static struct irq_info irq_info[NR_IRQS];
static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
[0 ... NR_EVENT_CHANNELS-1] = -1
};
-static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG];
-static u8 cpu_evtchn[NR_EVENT_CHANNELS];
-
-/* Reference counts for bindings to IRQs. */
-static int irq_bindcount[NR_IRQS];
+struct cpu_evtchn_s {
+ unsigned long bits[NR_EVENT_CHANNELS/BITS_PER_LONG];
+};
+static struct cpu_evtchn_s *cpu_evtchn_mask_p;
+static inline unsigned long *cpu_evtchn_mask(int cpu)
+{
+ return cpu_evtchn_mask_p[cpu].bits;
+}
/* Xen will never allocate port zero for any purpose. */
#define VALID_EVTCHN(chn) ((chn) != 0)
@@ -87,27 +108,108 @@ static int irq_bindcount[NR_IRQS];
static struct irq_chip xen_dynamic_chip;
/* Constructor for packed IRQ information. */
-static inline struct packed_irq mk_irq_info(u32 type, u32 index, u32 evtchn)
+static struct irq_info mk_unbound_info(void)
+{
+ return (struct irq_info) { .type = IRQT_UNBOUND };
+}
+
+static struct irq_info mk_evtchn_info(unsigned short evtchn)
+{
+ return (struct irq_info) { .type = IRQT_EVTCHN, .evtchn = evtchn,
+ .cpu = 0 };
+}
+
+static struct irq_info mk_ipi_info(unsigned short evtchn, enum ipi_vector ipi)
{
- return (struct packed_irq) { evtchn, index, type };
+ return (struct irq_info) { .type = IRQT_IPI, .evtchn = evtchn,
+ .cpu = 0, .u.ipi = ipi };
+}
+
+static struct irq_info mk_virq_info(unsigned short evtchn, unsigned short virq)
+{
+ return (struct irq_info) { .type = IRQT_VIRQ, .evtchn = evtchn,
+ .cpu = 0, .u.virq = virq };
+}
+
+static struct irq_info mk_pirq_info(unsigned short evtchn,
+ unsigned short gsi, unsigned short vector)
+{
+ return (struct irq_info) { .type = IRQT_PIRQ, .evtchn = evtchn,
+ .cpu = 0, .u.pirq = { .gsi = gsi, .vector = vector } };
}
/*
* Accessors for packed IRQ information.
*/
-static inline unsigned int evtchn_from_irq(int irq)
+static struct irq_info *info_for_irq(unsigned irq)
+{
+ return &irq_info[irq];
+}
+
+static unsigned int evtchn_from_irq(unsigned irq)
{
- return irq_info[irq].evtchn;
+ return info_for_irq(irq)->evtchn;
}
-static inline unsigned int index_from_irq(int irq)
+static enum ipi_vector ipi_from_irq(unsigned irq)
{
- return irq_info[irq].index;
+ struct irq_info *info = info_for_irq(irq);
+
+ BUG_ON(info == NULL);
+ BUG_ON(info->type != IRQT_IPI);
+
+ return info->u.ipi;
}
-static inline unsigned int type_from_irq(int irq)
+static unsigned virq_from_irq(unsigned irq)
{
- return irq_info[irq].type;
+ struct irq_info *info = info_for_irq(irq);
+
+ BUG_ON(info == NULL);
+ BUG_ON(info->type != IRQT_VIRQ);
+
+ return info->u.virq;
+}
+
+static unsigned gsi_from_irq(unsigned irq)
+{
+ struct irq_info *info = info_for_irq(irq);
+
+ BUG_ON(info == NULL);
+ BUG_ON(info->type != IRQT_PIRQ);
+
+ return info->u.pirq.gsi;
+}
+
+static unsigned vector_from_irq(unsigned irq)
+{
+ struct irq_info *info = info_for_irq(irq);
+
+ BUG_ON(info == NULL);
+ BUG_ON(info->type != IRQT_PIRQ);
+
+ return info->u.pirq.vector;
+}
+
+static enum xen_irq_type type_from_irq(unsigned irq)
+{
+ return info_for_irq(irq)->type;
+}
+
+static unsigned cpu_from_irq(unsigned irq)
+{
+ return info_for_irq(irq)->cpu;
+}
+
+static unsigned int cpu_from_evtchn(unsigned int evtchn)
+{
+ int irq = evtchn_to_irq[evtchn];
+ unsigned ret = 0;
+
+ if (irq != -1)
+ ret = cpu_from_irq(irq);
+
+ return ret;
}
static inline unsigned long active_evtchns(unsigned int cpu,
@@ -115,7 +217,7 @@ static inline unsigned long active_evtchns(unsigned int cpu,
unsigned int idx)
{
return (sh->evtchn_pending[idx] &
- cpu_evtchn_mask[cpu][idx] &
+ cpu_evtchn_mask(cpu)[idx] &
~sh->evtchn_mask[idx]);
}
@@ -125,13 +227,13 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
BUG_ON(irq == -1);
#ifdef CONFIG_SMP
- irq_to_desc(irq)->affinity = cpumask_of_cpu(cpu);
+ cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu));
#endif
- __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]);
- __set_bit(chn, cpu_evtchn_mask[cpu]);
+ __clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq)));
+ __set_bit(chn, cpu_evtchn_mask(cpu));
- cpu_evtchn[chn] = cpu;
+ irq_info[irq].cpu = cpu;
}
static void init_evtchn_cpu_bindings(void)
@@ -142,17 +244,11 @@ static void init_evtchn_cpu_bindings(void)
/* By default all event channels notify CPU#0. */
for_each_irq_desc(i, desc) {
- desc->affinity = cpumask_of_cpu(0);
+ cpumask_copy(desc->affinity, cpumask_of(0));
}
#endif
- memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
- memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
-}
-
-static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
-{
- return cpu_evtchn[evtchn];
+ memset(cpu_evtchn_mask(0), ~0, sizeof(cpu_evtchn_mask(0)));
}
static inline void clear_evtchn(int port)
@@ -232,9 +328,8 @@ static int find_unbound_irq(void)
int irq;
struct irq_desc *desc;
- /* Only allocate from dynirq range */
for (irq = 0; irq < nr_irqs; irq++)
- if (irq_bindcount[irq] == 0)
+ if (irq_info[irq].type == IRQT_UNBOUND)
break;
if (irq == nr_irqs)
@@ -244,6 +339,8 @@ static int find_unbound_irq(void)
if (WARN_ON(desc == NULL))
return -1;
+ dynamic_irq_init(irq);
+
return irq;
}
@@ -258,16 +355,13 @@ int bind_evtchn_to_irq(unsigned int evtchn)
if (irq == -1) {
irq = find_unbound_irq();
- dynamic_irq_init(irq);
set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
handle_level_irq, "event");
evtchn_to_irq[evtchn] = irq;
- irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
+ irq_info[irq] = mk_evtchn_info(evtchn);
}
- irq_bindcount[irq]++;
-
spin_unlock(&irq_mapping_update_lock);
return irq;
@@ -282,12 +376,12 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
spin_lock(&irq_mapping_update_lock);
irq = per_cpu(ipi_to_irq, cpu)[ipi];
+
if (irq == -1) {
irq = find_unbound_irq();
if (irq < 0)
goto out;
- dynamic_irq_init(irq);
set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
handle_level_irq, "ipi");
@@ -298,15 +392,12 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
evtchn = bind_ipi.port;
evtchn_to_irq[evtchn] = irq;
- irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
-
+ irq_info[irq] = mk_ipi_info(evtchn, ipi);
per_cpu(ipi_to_irq, cpu)[ipi] = irq;
bind_evtchn_to_cpu(evtchn, cpu);
}
- irq_bindcount[irq]++;
-
out:
spin_unlock(&irq_mapping_update_lock);
return irq;
@@ -332,20 +423,17 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
irq = find_unbound_irq();
- dynamic_irq_init(irq);
set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
handle_level_irq, "virq");
evtchn_to_irq[evtchn] = irq;
- irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
+ irq_info[irq] = mk_virq_info(evtchn, virq);
per_cpu(virq_to_irq, cpu)[virq] = irq;
bind_evtchn_to_cpu(evtchn, cpu);
}
- irq_bindcount[irq]++;
-
spin_unlock(&irq_mapping_update_lock);
return irq;
@@ -358,7 +446,7 @@ static void unbind_from_irq(unsigned int irq)
spin_lock(&irq_mapping_update_lock);
- if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
+ if (VALID_EVTCHN(evtchn)) {
close.port = evtchn;
if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
BUG();
@@ -366,11 +454,11 @@ static void unbind_from_irq(unsigned int irq)
switch (type_from_irq(irq)) {
case IRQT_VIRQ:
per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
- [index_from_irq(irq)] = -1;
+ [virq_from_irq(irq)] = -1;
break;
case IRQT_IPI:
per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
- [index_from_irq(irq)] = -1;
+ [ipi_from_irq(irq)] = -1;
break;
default:
break;
@@ -380,7 +468,7 @@ static void unbind_from_irq(unsigned int irq)
bind_evtchn_to_cpu(evtchn, 0);
evtchn_to_irq[evtchn] = -1;
- irq_info[irq] = IRQ_UNBOUND;
+ irq_info[irq] = mk_unbound_info();
dynamic_irq_cleanup(irq);
}
@@ -498,8 +586,8 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
for(i = 0; i < NR_EVENT_CHANNELS; i++) {
if (sync_test_bit(i, sh->evtchn_pending)) {
printk(" %d: event %d -> irq %d\n",
- cpu_evtchn[i], i,
- evtchn_to_irq[i]);
+ cpu_from_evtchn(i), i,
+ evtchn_to_irq[i]);
}
}
@@ -508,7 +596,6 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-
/*
* Search the CPUs pending events bitmasks. For each one found, map
* the event number to an irq, and feed it into do_IRQ() for
@@ -521,11 +608,15 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
void xen_evtchn_do_upcall(struct pt_regs *regs)
{
int cpu = get_cpu();
+ struct pt_regs *old_regs = set_irq_regs(regs);
struct shared_info *s = HYPERVISOR_shared_info;
struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
static DEFINE_PER_CPU(unsigned, nesting_count);
unsigned count;
+ exit_idle();
+ irq_enter();
+
do {
unsigned long pending_words;
@@ -550,7 +641,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
int irq = evtchn_to_irq[port];
if (irq != -1)
- xen_do_IRQ(irq, regs);
+ handle_irq(irq, regs);
}
}
@@ -561,12 +652,17 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
} while(count != 1);
out:
+ irq_exit();
+ set_irq_regs(old_regs);
+
put_cpu();
}
/* Rebind a new event channel to an existing irq. */
void rebind_evtchn_irq(int evtchn, int irq)
{
+ struct irq_info *info = info_for_irq(irq);
+
/* Make sure the irq is masked, since the new event channel
will also be masked. */
disable_irq(irq);
@@ -576,11 +672,11 @@ void rebind_evtchn_irq(int evtchn, int irq)
/* After resume the irq<->evtchn mappings are all cleared out */
BUG_ON(evtchn_to_irq[evtchn] != -1);
/* Expect irq to have been bound before,
- so the bindcount should be non-0 */
- BUG_ON(irq_bindcount[irq] == 0);
+ so there should be a proper type */
+ BUG_ON(info->type == IRQT_UNBOUND);
evtchn_to_irq[evtchn] = irq;
- irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
+ irq_info[irq] = mk_evtchn_info(evtchn);
spin_unlock(&irq_mapping_update_lock);
@@ -690,8 +786,7 @@ static void restore_cpu_virqs(unsigned int cpu)
if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
continue;
- BUG_ON(irq_info[irq].type != IRQT_VIRQ);
- BUG_ON(irq_info[irq].index != virq);
+ BUG_ON(virq_from_irq(irq) != virq);
/* Get a new binding from Xen. */
bind_virq.virq = virq;
@@ -703,7 +798,7 @@ static void restore_cpu_virqs(unsigned int cpu)
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
- irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
+ irq_info[irq] = mk_virq_info(evtchn, virq);
bind_evtchn_to_cpu(evtchn, cpu);
/* Ready for use. */
@@ -720,8 +815,7 @@ static void restore_cpu_ipis(unsigned int cpu)
if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1)
continue;
- BUG_ON(irq_info[irq].type != IRQT_IPI);
- BUG_ON(irq_info[irq].index != ipi);
+ BUG_ON(ipi_from_irq(irq) != ipi);
/* Get a new binding from Xen. */
bind_ipi.vcpu = cpu;
@@ -732,7 +826,7 @@ static void restore_cpu_ipis(unsigned int cpu)
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
- irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
+ irq_info[irq] = mk_ipi_info(evtchn, ipi);
bind_evtchn_to_cpu(evtchn, cpu);
/* Ready for use. */
@@ -812,8 +906,11 @@ void xen_irq_resume(void)
static struct irq_chip xen_dynamic_chip __read_mostly = {
.name = "xen-dyn",
+
+ .disable = disable_dynirq,
.mask = disable_dynirq,
.unmask = enable_dynirq,
+
.ack = ack_dynirq,
.set_affinity = set_affinity_irq,
.retrigger = retrigger_dynirq,
@@ -822,6 +919,10 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
void __init xen_init_IRQ(void)
{
int i;
+ size_t size = nr_cpu_ids * sizeof(struct cpu_evtchn_s);
+
+ cpu_evtchn_mask_p = alloc_bootmem(size);
+ BUG_ON(cpu_evtchn_mask_p == NULL);
init_evtchn_cpu_bindings();
@@ -829,9 +930,5 @@ void __init xen_init_IRQ(void)
for (i = 0; i < NR_EVENT_CHANNELS; i++)
mask_evtchn(i);
- /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
- for (i = 0; i < nr_irqs; i++)
- irq_bindcount[i] = 0;
-
irq_ctx_init(smp_processor_id());
}
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 9b91617b9582..3ccd348d112d 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -45,6 +45,13 @@ static int xen_suspend(void *data)
err);
return err;
}
+ err = sysdev_suspend(PMSG_SUSPEND);
+ if (err) {
+ printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
+ err);
+ device_power_up(PMSG_RESUME);
+ return err;
+ }
xen_mm_pin_all();
gnttab_suspend();
@@ -61,6 +68,7 @@ static int xen_suspend(void *data)
gnttab_resume();
xen_mm_unpin_all();
+ sysdev_resume();
device_power_up(PMSG_RESUME);
if (!*cancelled) {
@@ -100,7 +108,7 @@ static void do_suspend(void)
/* XXX use normal device tree? */
xenbus_suspend();
- err = stop_machine(xen_suspend, &cancelled, &cpumask_of_cpu(0));
+ err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
if (err) {
printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
goto out;
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c
index 875a4c59c594..a9592d981b10 100644
--- a/drivers/xen/xenfs/xenbus.c
+++ b/drivers/xen/xenfs/xenbus.c
@@ -291,7 +291,7 @@ static void watch_fired(struct xenbus_watch *watch,
static int xenbus_write_transaction(unsigned msg_type,
struct xenbus_file_priv *u)
{
- int rc, ret;
+ int rc;
void *reply;
struct xenbus_transaction_holder *trans = NULL;
LIST_HEAD(staging_q);
@@ -326,15 +326,14 @@ static int xenbus_write_transaction(unsigned msg_type,
}
mutex_lock(&u->reply_mutex);
- ret = queue_reply(&staging_q, &u->u.msg, sizeof(u->u.msg));
- if (!ret)
- ret = queue_reply(&staging_q, reply, u->u.msg.len);
- if (!ret) {
+ rc = queue_reply(&staging_q, &u->u.msg, sizeof(u->u.msg));
+ if (!rc)
+ rc = queue_reply(&staging_q, reply, u->u.msg.len);
+ if (!rc) {
list_splice_tail(&staging_q, &u->read_buffers);
wake_up(&u->read_waitq);
} else {
queue_cleanup(&staging_q);
- rc = ret;
}
mutex_unlock(&u->reply_mutex);
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index a1585d6f6486..d45fb34e2d23 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -140,7 +140,7 @@ static int __init zorro_init(void)
/* Initialize the Zorro bus */
INIT_LIST_HEAD(&zorro_bus.devices);
- strcpy(zorro_bus.dev.bus_id, "zorro");
+ dev_set_name(&zorro_bus.dev, "zorro");
error = device_register(&zorro_bus.dev);
if (error) {
pr_err("Zorro: Error registering zorro_bus\n");
@@ -167,7 +167,7 @@ static int __init zorro_init(void)
if (request_resource(zorro_find_parent_resource(z), &z->resource))
pr_err("Zorro: Address space collision on device %s %pR\n",
z->name, &z->resource);
- sprintf(z->dev.bus_id, "%02x", i);
+ dev_set_name(&z->dev, "%02x", i);
z->dev.parent = &zorro_bus.dev;
z->dev.bus = &zorro_bus_type;
error = device_register(&z->dev);