summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-12-13 09:28:43 +0100
committerTakashi Iwai <tiwai@suse.de>2010-12-13 09:28:43 +0100
commit20aeeb356ba2e8daa99b5942c528ae2b3ea28433 (patch)
treed2cebc7039954851998d592123899f5627def7a9 /drivers
parent07a9e2b2fbdda631eeff54e4b8ebcaaea71be538 (diff)
parent5b84ba26a9672e615897234fa5efd3eea2d6b295 (diff)
downloadlinux-20aeeb356ba2e8daa99b5942c528ae2b3ea28433.tar.bz2
Merge branch 'topic/workq-update' into topic/asoc
Conflicts: sound/soc/codecs/wm8350.c sound/soc/codecs/wm8753.c sound/soc/sh/fsi.c sound/soc/soc-core.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-scsi.c19
-rw-r--r--drivers/ata/sata_via.c9
-rw-r--r--drivers/base/power/main.c34
-rw-r--r--drivers/block/amiflop.c2
-rw-r--r--drivers/block/ataflop.c2
-rw-r--r--drivers/block/cciss.c3
-rw-r--r--drivers/block/cciss_scsi.c8
-rw-r--r--drivers/block/drbd/drbd_receiver.c1
-rw-r--r--drivers/block/drbd/drbd_worker.c1
-rw-r--r--drivers/block/rbd.c748
-rw-r--r--drivers/block/xen-blkfront.c55
-rw-r--r--drivers/char/agp/frontend.c1
-rw-r--r--drivers/char/amiserial.c1
-rw-r--r--drivers/char/briq_panel.c1
-rw-r--r--drivers/char/hpet.c1
-rw-r--r--drivers/char/hw_random/core.c1
-rw-r--r--drivers/char/istallion.c1
-rw-r--r--drivers/char/serial167.c1
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/stallion.c1
-rw-r--r--drivers/char/sx.c1
-rw-r--r--drivers/char/tpm/tpm_tis.c24
-rw-r--r--drivers/char/uv_mmtimer.c1
-rw-r--r--drivers/char/virtio_console.c37
-rw-r--r--drivers/dma/shdma.c1
-rw-r--r--drivers/edac/Makefile8
-rw-r--r--drivers/edac/mce_amd_inj.c2
-rw-r--r--drivers/firewire/net.c160
-rw-r--r--drivers/firewire/sbp2.c4
-rw-r--r--drivers/gpio/cs5535-gpio.c16
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c14
-rw-r--r--drivers/gpu/drm/drm_fops.c1
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c590
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c40
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c159
-rw-r--r--drivers/gpu/drm/i915/intel_display.c19
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c146
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c11
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c19
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c84
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c9
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c43
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c77
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h55
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c36
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.h19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c42
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c49
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ramht.c71
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sgdma.c14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c17
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_temp.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c7
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dfp.c13
-rw-r--r--drivers/gpu/drm/nouveau/nv04_pm.c9
-rw-r--r--drivers/gpu/drm/nouveau/nv50_calc.c16
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c4
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c35
-rw-r--r--drivers/gpu/drm/nouveau/nv50_fifo.c5
-rw-r--r--drivers/gpu/drm/nouveau/nv50_graph.c52
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c1
-rw-r--r--drivers/gpu/drm/radeon/atom.c1
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c31
-rw-r--r--drivers/gpu/drm/radeon/evergreen_blit_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c2
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c309
-rw-r--r--drivers/gpu/drm/radeon/r600_reg.h1
-rw-r--r--drivers/gpu/drm/radeon/r600d.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c13
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c15
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c52
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c356
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h5
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h7
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c2
-rw-r--r--drivers/gpu/drm/radeon/rv770.c4
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c11
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c14
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-egalax.c2
-rw-r--r--drivers/hid/hid-input.c21
-rw-r--r--drivers/hid/hid-tmff.c2
-rw-r--r--drivers/hid/hidraw.c1
-rw-r--r--drivers/hid/usbhid/hiddev.c1
-rw-r--r--drivers/hwmon/i5k_amb.c2
-rw-r--r--drivers/hwmon/lis3lv02d_i2c.c10
-rw-r--r--drivers/i2c/Kconfig3
-rw-r--r--drivers/i2c/algos/Kconfig14
-rw-r--r--drivers/infiniband/core/ud_header.c30
-rw-r--r--drivers/infiniband/core/uverbs_marshall.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c1
-rw-r--r--drivers/infiniband/hw/mlx4/main.c4
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c10
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c4
-rw-r--r--drivers/input/input.c3
-rw-r--r--drivers/input/serio/gscps2.c2
-rw-r--r--drivers/input/serio/serio_raw.c1
-rw-r--r--drivers/input/tablet/aiptek.c28
-rw-r--r--drivers/isdn/icn/icn.c7
-rw-r--r--drivers/leds/Kconfig50
-rw-r--r--drivers/leds/leds-lp5521.c50
-rw-r--r--drivers/leds/leds-lp5523.c44
-rw-r--r--drivers/leds/leds-ss4200.c1
-rw-r--r--drivers/macintosh/Kconfig1
-rw-r--r--drivers/md/md.c6
-rw-r--r--drivers/md/raid1.c1
-rw-r--r--drivers/media/common/tuners/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c1
-rw-r--r--drivers/media/dvb/frontends/Kconfig5
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c1
-rw-r--r--drivers/media/dvb/ngene/ngene-dvb.c1
-rw-r--r--drivers/media/dvb/ngene/ngene-i2c.c1
-rw-r--r--drivers/media/radio/radio-mr800.c1
-rw-r--r--drivers/media/radio/radio-si4713.c2
-rw-r--r--drivers/media/radio/si470x/radio-si470x.h1
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/au0828/au0828-cards.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c22
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c1
-rw-r--r--drivers/media/video/cafe_ccic.c3
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c8
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c4
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c4
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c1
-rw-r--r--drivers/media/video/cx88/cx88-cards.c9
-rw-r--r--drivers/media/video/cx88/cx88-video.c8
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c1
-rw-r--r--drivers/media/video/davinci/vpif_capture.c1
-rw-r--r--drivers/media/video/davinci/vpif_display.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c18
-rw-r--r--drivers/media/video/fsl-viu.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c22
-rw-r--r--drivers/media/video/mxb.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c6
-rw-r--r--drivers/media/video/pwc/pwc-if.c1
-rw-r--r--drivers/media/video/s2255drv.c1
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c1
-rw-r--r--drivers/media/video/saa7164/saa7164.h1
-rw-r--r--drivers/media/video/sh_vou.c2
-rw-r--r--drivers/media/video/soc_camera.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c6
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c1
-rw-r--r--drivers/media/video/v4l2-common.c15
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c1
-rw-r--r--drivers/media/video/via-camera.c2
-rw-r--r--drivers/media/video/vino.c4
-rw-r--r--drivers/media/video/zoran/zoran_card.c5
-rw-r--r--drivers/message/fusion/mptfc.c7
-rw-r--r--drivers/message/fusion/mptsas.c4
-rw-r--r--drivers/message/fusion/mptspi.c4
-rw-r--r--drivers/message/i2o/i2o_scsi.c6
-rw-r--r--drivers/misc/isl29020.c4
-rw-r--r--drivers/misc/sgi-xp/xpc_partition.c25
-rw-r--r--drivers/mmc/core/core.c2
-rw-r--r--drivers/mmc/core/mmc.c8
-rw-r--r--drivers/mmc/core/sdio.c51
-rw-r--r--drivers/mmc/core/sdio_bus.c33
-rw-r--r--drivers/mmc/host/omap_hsmmc.c2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c12
-rw-r--r--drivers/mmc/host/sdhci-pci.c31
-rw-r--r--drivers/mmc/host/sdhci-pxa.c4
-rw-r--r--drivers/mmc/host/sdhci.c54
-rw-r--r--drivers/mmc/host/sdhci.h9
-rw-r--r--drivers/mmc/host/ushc.c30
-rw-r--r--drivers/mtd/ubi/io.c37
-rw-r--r--drivers/mtd/ubi/scan.c20
-rw-r--r--drivers/net/3c59x.c6
-rw-r--r--drivers/net/8139cp.c10
-rw-r--r--drivers/net/Kconfig18
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/atl1c/atl1c_hw.c2
-rw-r--r--drivers/net/au1000_eth.c10
-rw-r--r--drivers/net/benet/be_main.c6
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c2
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/caif/caif_spi.c4
-rw-r--r--drivers/net/cxgb4vf/cxgb4vf_main.c73
-rw-r--r--drivers/net/cxgb4vf/t4vf_hw.c94
-rw-r--r--drivers/net/e1000/e1000_main.c12
-rw-r--r--drivers/net/ehea/ehea_main.c18
-rw-r--r--drivers/net/gianfar.c7
-rw-r--r--drivers/net/ipg.c6
-rw-r--r--drivers/net/irda/sh_sir.c2
-rw-r--r--drivers/net/mlx4/fw.c4
-rw-r--r--drivers/net/pch_gbe/pch_gbe_main.c6
-rw-r--r--drivers/net/pch_gbe/pch_gbe_param.c8
-rw-r--r--drivers/net/phy/marvell.c164
-rw-r--r--drivers/net/ppp_generic.c43
-rw-r--r--drivers/net/qlge/qlge_main.c6
-rw-r--r--drivers/net/r8169.c3
-rw-r--r--drivers/net/tile/Makefile10
-rw-r--r--drivers/net/tile/tilepro.c2406
-rw-r--r--drivers/net/ucc_geth.h3
-rw-r--r--drivers/net/usb/hso.c10
-rw-r--r--drivers/net/wan/x25_asy.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h8
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c4
-rw-r--r--drivers/net/wireless/b43/sdio.c1
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c1
-rw-r--r--drivers/parisc/dino.c1
-rw-r--r--drivers/parisc/eisa.c3
-rw-r--r--drivers/parisc/eisa_eeprom.c1
-rw-r--r--drivers/parisc/gsc.c3
-rw-r--r--drivers/parisc/iosapic.c8
-rw-r--r--drivers/parisc/led.c17
-rw-r--r--drivers/parisc/superio.c3
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/pci-sysfs.c2
-rw-r--r--drivers/pci/proc.c1
-rw-r--r--drivers/pci/quirks.c18
-rw-r--r--drivers/pcmcia/soc_common.c1
-rw-r--r--drivers/pnp/isapnp/proc.c1
-rw-r--r--drivers/regulator/core.c30
-rw-r--r--drivers/regulator/mc13783-regulator.c4
-rw-r--r--drivers/regulator/twl-regulator.c6
-rw-r--r--drivers/s390/block/dasd_eer.c1
-rw-r--r--drivers/s390/char/fs3270.c1
-rw-r--r--drivers/s390/char/tape_char.c1
-rw-r--r--drivers/s390/char/tape_core.c68
-rw-r--r--drivers/s390/char/vmlogrdr.c37
-rw-r--r--drivers/s390/char/vmur.c1
-rw-r--r--drivers/s390/cio/device.c11
-rw-r--r--drivers/s390/cio/qdio_thinint.c2
-rw-r--r--drivers/s390/crypto/zcrypt_api.c1
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c4
-rw-r--r--drivers/scsi/3w-9xxx.c4
-rw-r--r--drivers/scsi/3w-sas.c4
-rw-r--r--drivers/scsi/3w-xxxx.c4
-rw-r--r--drivers/scsi/53c700.c8
-rw-r--r--drivers/scsi/BusLogic.c3
-rw-r--r--drivers/scsi/BusLogic.h2
-rw-r--r--drivers/scsi/NCR5380.c3
-rw-r--r--drivers/scsi/NCR5380.h2
-rw-r--r--drivers/scsi/NCR53c406a.c4
-rw-r--r--drivers/scsi/a100u2w.c4
-rw-r--r--drivers/scsi/aacraid/linit.c4
-rw-r--r--drivers/scsi/advansys.c4
-rw-r--r--drivers/scsi/aha152x.c4
-rw-r--r--drivers/scsi/aha1542.c4
-rw-r--r--drivers/scsi/aha1542.h2
-rw-r--r--drivers/scsi/aha1740.c4
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c4
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c4
-rw-r--r--drivers/scsi/aic7xxx_old.c4
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c7
-rw-r--r--drivers/scsi/arm/acornscsi.c4
-rw-r--r--drivers/scsi/arm/fas216.c10
-rw-r--r--drivers/scsi/arm/fas216.h18
-rw-r--r--drivers/scsi/atari_NCR5380.c4
-rw-r--r--drivers/scsi/atari_scsi.c17
-rw-r--r--drivers/scsi/atp870u.c4
-rw-r--r--drivers/scsi/bfa/bfad_im.c7
-rw-r--r--drivers/scsi/dc395x.c3
-rw-r--r--drivers/scsi/dpt_i2o.c4
-rw-r--r--drivers/scsi/dpti.h2
-rw-r--r--drivers/scsi/dtc.h2
-rw-r--r--drivers/scsi/eata.c7
-rw-r--r--drivers/scsi/eata_pio.c4
-rw-r--r--drivers/scsi/esp_scsi.c4
-rw-r--r--drivers/scsi/fd_mcs.c4
-rw-r--r--drivers/scsi/fdomain.c4
-rw-r--r--drivers/scsi/fnic/fnic.h2
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c4
-rw-r--r--drivers/scsi/g_NCR5380.h2
-rw-r--r--drivers/scsi/gdth.c6
-rw-r--r--drivers/scsi/hpsa.c8
-rw-r--r--drivers/scsi/hptiop.c4
-rw-r--r--drivers/scsi/ibmmca.c6
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c4
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c4
-rw-r--r--drivers/scsi/imm.c4
-rw-r--r--drivers/scsi/in2000.c4
-rw-r--r--drivers/scsi/in2000.h2
-rw-r--r--drivers/scsi/initio.c4
-rw-r--r--drivers/scsi/ipr.c4
-rw-r--r--drivers/scsi/ips.c6
-rw-r--r--drivers/scsi/libfc/fc_fcp.c4
-rw-r--r--drivers/scsi/libiscsi.c4
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c4
-rw-r--r--drivers/scsi/mac53c94.c4
-rw-r--r--drivers/scsi/megaraid.c6
-rw-r--r--drivers/scsi/megaraid.h2
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c7
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c4
-rw-r--r--drivers/scsi/mesh.c4
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c4
-rw-r--r--drivers/scsi/ncr53c8xx.c4
-rw-r--r--drivers/scsi/nsp32.c7
-rw-r--r--drivers/scsi/pas16.h2
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c4
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h3
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c4
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h1
-rw-r--r--drivers/scsi/pmcraid.c4
-rw-r--r--drivers/scsi/ppa.c4
-rw-r--r--drivers/scsi/ps3rom.c4
-rw-r--r--drivers/scsi/qla1280.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c7
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c7
-rw-r--r--drivers/scsi/qlogicfas408.c4
-rw-r--r--drivers/scsi/qlogicfas408.h3
-rw-r--r--drivers/scsi/qlogicpti.c4
-rw-r--r--drivers/scsi/scsi.c18
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/scsi_error.c6
-rw-r--r--drivers/scsi/sd.c1
-rw-r--r--drivers/scsi/stex.c4
-rw-r--r--drivers/scsi/sun3_NCR5380.c4
-rw-r--r--drivers/scsi/sun3_scsi.h3
-rw-r--r--drivers/scsi/sym53c416.c4
-rw-r--r--drivers/scsi/sym53c416.h2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c4
-rw-r--r--drivers/scsi/t128.h3
-rw-r--r--drivers/scsi/tmscsim.c4
-rw-r--r--drivers/scsi/u14-34f.c6
-rw-r--r--drivers/scsi/ultrastor.c4
-rw-r--r--drivers/scsi/ultrastor.h3
-rw-r--r--drivers/scsi/vmw_pvscsi.c4
-rw-r--r--drivers/scsi/wd33c93.c6
-rw-r--r--drivers/scsi/wd33c93.h3
-rw-r--r--drivers/scsi/wd7000.c4
-rw-r--r--drivers/serial/8250.c2
-rw-r--r--drivers/serial/crisv10.c1
-rw-r--r--drivers/serial/mfd.c24
-rw-r--r--drivers/serial/serial_core.c1
-rw-r--r--drivers/sh/clk/core.c16
-rw-r--r--drivers/sh/clk/cpg.c7
-rw-r--r--drivers/spi/atmel_spi.c6
-rw-r--r--drivers/ssb/b43_pci_bridge.c1
-rw-r--r--drivers/staging/asus_oled/asus_oled.c8
-rw-r--r--drivers/staging/batman-adv/hard-interface.c19
-rw-r--r--drivers/staging/batman-adv/soft-interface.c14
-rw-r--r--drivers/staging/brcm80211/README8
-rw-r--r--drivers/staging/brcm80211/TODO2
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c4
-rw-r--r--drivers/staging/easycap/easycap.h2
-rw-r--r--drivers/staging/frontier/tranzport.c2
-rw-r--r--drivers/staging/go7007/go7007-driver.c2
-rw-r--r--drivers/staging/hv/storvsc_drv.c7
-rw-r--r--drivers/staging/iio/accel/adis16220_core.c2
-rw-r--r--drivers/staging/intel_sst/intel_sst_app_interface.c1
-rw-r--r--drivers/staging/intel_sst/intel_sst_stream_encoded.c2
-rw-r--r--drivers/staging/keucr/scsiglue.c4
-rw-r--r--drivers/staging/line6/control.c204
-rw-r--r--drivers/staging/line6/midi.c4
-rw-r--r--drivers/staging/line6/pcm.c4
-rw-r--r--drivers/staging/line6/pod.c32
-rw-r--r--drivers/staging/line6/toneport.c4
-rw-r--r--drivers/staging/line6/variax.c12
-rw-r--r--drivers/staging/quickstart/quickstart.c10
-rw-r--r--drivers/staging/rt2860/usb_main_dev.c1
-rw-r--r--drivers/staging/rtl8187se/r8185b_init.c30
-rw-r--r--drivers/staging/rtl8712/osdep_service.h1
-rw-r--r--drivers/staging/rtl8712/usb_halinit.c2
-rw-r--r--drivers/staging/samsung-laptop/samsung-laptop.c2
-rw-r--r--drivers/staging/speakup/buffers.c1
-rw-r--r--drivers/staging/speakup/fakekey.c1
-rw-r--r--drivers/staging/spectra/ffsport.c2
-rw-r--r--drivers/staging/stradis/Kconfig2
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c4
-rw-r--r--drivers/staging/udlfb/udlfb.c2
-rw-r--r--drivers/staging/winbond/sysdef.h3
-rw-r--r--drivers/staging/zram/zram_sysfs.c4
-rw-r--r--drivers/tty/sysrq.c169
-rw-r--r--drivers/tty/tty_io.c13
-rw-r--r--drivers/tty/tty_ldisc.c2
-rw-r--r--drivers/uio/uio.c2
-rw-r--r--drivers/uio/uio_cif.c2
-rw-r--r--drivers/uio/uio_netx.c2
-rw-r--r--drivers/usb/atm/ueagle-atm.c7
-rw-r--r--drivers/usb/core/devices.c1
-rw-r--r--drivers/usb/core/devio.c1
-rw-r--r--drivers/usb/core/file.c1
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/inode.c1
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c2
-rw-r--r--drivers/usb/gadget/f_fs.c1
-rw-r--r--drivers/usb/gadget/f_hid.c1
-rw-r--r--drivers/usb/host/ehci-dbg.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c10
-rw-r--r--drivers/usb/host/ehci-mem.c26
-rw-r--r--drivers/usb/host/ehci-pci.c25
-rw-r--r--drivers/usb/host/ehci-sched.c21
-rw-r--r--drivers/usb/host/ehci.h2
-rw-r--r--drivers/usb/host/isp1362-hcd.c3
-rw-r--r--drivers/usb/host/uhci-debug.c1
-rw-r--r--drivers/usb/host/xhci-hub.c7
-rw-r--r--drivers/usb/host/xhci-mem.c168
-rw-r--r--drivers/usb/host/xhci-ring.c1
-rw-r--r--drivers/usb/host/xhci.c91
-rw-r--r--drivers/usb/host/xhci.h31
-rw-r--r--drivers/usb/image/microtek.c6
-rw-r--r--drivers/usb/misc/cypress_cy7c63.c6
-rw-r--r--drivers/usb/misc/trancevibrator.c2
-rw-r--r--drivers/usb/misc/usbled.c2
-rw-r--r--drivers/usb/misc/usbsevseg.c10
-rw-r--r--drivers/usb/misc/yurex.c1
-rw-r--r--drivers/usb/mon/mon_bin.c1
-rw-r--r--drivers/usb/mon/mon_stat.c1
-rw-r--r--drivers/usb/musb/musb_core.c3
-rw-r--r--drivers/usb/musb/musb_gadget.c124
-rw-r--r--drivers/usb/otg/langwell_otg.c9
-rw-r--r--drivers/usb/serial/ftdi_sio.c2
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h4
-rw-r--r--drivers/usb/serial/usb-serial.c4
-rw-r--r--drivers/usb/storage/scsiglue.c4
-rw-r--r--drivers/usb/storage/sierra_ms.c2
-rw-r--r--drivers/usb/storage/uas.c4
-rw-r--r--drivers/vhost/net.c5
-rw-r--r--drivers/video/backlight/backlight.c12
-rw-r--r--drivers/video/console/vgacon.c1
-rw-r--r--drivers/video/da8xx-fb.c14
-rw-r--r--drivers/video/fbcmap.c69
-rw-r--r--drivers/video/geode/lxfb.h4
-rw-r--r--drivers/video/geode/lxfb_ops.c24
-rw-r--r--drivers/video/mx3fb.c4
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c4
-rw-r--r--drivers/video/sis/init.c685
-rw-r--r--drivers/video/sis/init.h63
-rw-r--r--drivers/video/sis/init301.c467
-rw-r--r--drivers/video/sis/init301.h43
-rw-r--r--drivers/video/sis/initextlfb.c7
-rw-r--r--drivers/video/sis/osdef.h133
-rw-r--r--drivers/video/sis/sis.h1
-rw-r--r--drivers/video/sis/sis_main.c30
-rw-r--r--drivers/video/sis/vgatypes.h11
-rw-r--r--drivers/video/sis/vstruct.h12
-rw-r--r--drivers/virtio/virtio.c6
-rw-r--r--drivers/virtio/virtio_ring.c3
-rw-r--r--drivers/watchdog/Kconfig3
-rw-r--r--drivers/watchdog/bcm63xx_wdt.c42
-rw-r--r--drivers/watchdog/gef_wdt.c1
-rw-r--r--drivers/watchdog/iTCO_wdt.c8
-rw-r--r--drivers/xen/Makefile5
-rw-r--r--drivers/xen/balloon.c42
-rw-r--r--drivers/xen/events.c122
-rw-r--r--drivers/xen/evtchn.c100
-rw-r--r--drivers/xen/manage.c1
-rw-r--r--drivers/xen/xenfs/privcmd.c14
-rw-r--r--drivers/xen/xenfs/super.c46
-rw-r--r--drivers/zorro/proc.c1
477 files changed, 7524 insertions, 3947 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 3f91c01c217f..66aa4bee80a6 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3166,8 +3166,8 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
/**
* ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device
+ * @shost: SCSI host of command to be sent
* @cmd: SCSI command to be sent
- * @done: Completion function, called when command is complete
*
* In some cases, this function translates SCSI commands into
* ATA taskfiles, and queues the taskfiles to be sent to
@@ -3177,37 +3177,36 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
* ATA and ATAPI devices appearing as SCSI devices.
*
* LOCKING:
- * Releases scsi-layer-held lock, and obtains host lock.
+ * ATA host lock
*
* RETURNS:
* Return value from __ata_scsi_queuecmd() if @cmd can be queued,
* 0 otherwise.
*/
-int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
{
struct ata_port *ap;
struct ata_device *dev;
struct scsi_device *scsidev = cmd->device;
- struct Scsi_Host *shost = scsidev->host;
int rc = 0;
+ unsigned long irq_flags;
ap = ata_shost_to_port(shost);
- spin_unlock(shost->host_lock);
- spin_lock(ap->lock);
+ spin_lock_irqsave(ap->lock, irq_flags);
ata_scsi_dump_cdb(ap, cmd);
dev = ata_scsi_find_dev(ap, scsidev);
if (likely(dev))
- rc = __ata_scsi_queuecmd(cmd, done, dev);
+ rc = __ata_scsi_queuecmd(cmd, cmd->scsi_done, dev);
else {
cmd->result = (DID_BAD_TARGET << 16);
- done(cmd);
+ cmd->scsi_done(cmd);
}
- spin_unlock(ap->lock);
- spin_lock(shost->host_lock);
+ spin_unlock_irqrestore(ap->lock, irq_flags);
+
return rc;
}
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index c21589986c69..8b677bbf2d37 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -538,7 +538,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
return 0;
}
-static void svia_configure(struct pci_dev *pdev)
+static void svia_configure(struct pci_dev *pdev, int board_id)
{
u8 tmp8;
@@ -577,7 +577,7 @@ static void svia_configure(struct pci_dev *pdev)
}
/*
- * vt6421 has problems talking to some drives. The following
+ * vt6420/1 has problems talking to some drives. The following
* is the fix from Joseph Chan <JosephChan@via.com.tw>.
*
* When host issues HOLD, device may send up to 20DW of data
@@ -596,8 +596,9 @@ static void svia_configure(struct pci_dev *pdev)
*
* https://bugzilla.kernel.org/show_bug.cgi?id=15173
* http://article.gmane.org/gmane.linux.ide/46352
+ * http://thread.gmane.org/gmane.linux.kernel/1062139
*/
- if (pdev->device == 0x3249) {
+ if (board_id == vt6420 || board_id == vt6421) {
pci_read_config_byte(pdev, 0x52, &tmp8);
tmp8 |= 1 << 2;
pci_write_config_byte(pdev, 0x52, tmp8);
@@ -652,7 +653,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- svia_configure(pdev);
+ svia_configure(pdev, board_id);
pci_set_master(pdev);
return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 31b526661ec4..ead3e79d6fcf 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -475,20 +475,33 @@ End:
*/
void dpm_resume_noirq(pm_message_t state)
{
- struct device *dev;
+ struct list_head list;
ktime_t starttime = ktime_get();
+ INIT_LIST_HEAD(&list);
mutex_lock(&dpm_list_mtx);
transition_started = false;
- list_for_each_entry(dev, &dpm_list, power.entry)
+ while (!list_empty(&dpm_list)) {
+ struct device *dev = to_device(dpm_list.next);
+
+ get_device(dev);
if (dev->power.status > DPM_OFF) {
int error;
dev->power.status = DPM_OFF;
+ mutex_unlock(&dpm_list_mtx);
+
error = device_resume_noirq(dev, state);
+
+ mutex_lock(&dpm_list_mtx);
if (error)
pm_dev_err(dev, state, " early", error);
}
+ if (!list_empty(&dev->power.entry))
+ list_move_tail(&dev->power.entry, &list);
+ put_device(dev);
+ }
+ list_splice(&list, &dpm_list);
mutex_unlock(&dpm_list_mtx);
dpm_show_time(starttime, state, "early");
resume_device_irqs();
@@ -789,20 +802,33 @@ End:
*/
int dpm_suspend_noirq(pm_message_t state)
{
- struct device *dev;
+ struct list_head list;
ktime_t starttime = ktime_get();
int error = 0;
+ INIT_LIST_HEAD(&list);
suspend_device_irqs();
mutex_lock(&dpm_list_mtx);
- list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
+ while (!list_empty(&dpm_list)) {
+ struct device *dev = to_device(dpm_list.prev);
+
+ get_device(dev);
+ mutex_unlock(&dpm_list_mtx);
+
error = device_suspend_noirq(dev, state);
+
+ mutex_lock(&dpm_list_mtx);
if (error) {
pm_dev_err(dev, state, " late", error);
+ put_device(dev);
break;
}
dev->power.status = DPM_OFF_IRQ;
+ if (!list_empty(&dev->power.entry))
+ list_move(&dev->power.entry, &list);
+ put_device(dev);
}
+ list_splice_tail(&list, &dpm_list);
mutex_unlock(&dpm_list_mtx);
if (error)
dpm_resume_noirq(resume_event(state));
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index a1725e6488d3..7888501ad9ee 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1341,7 +1341,7 @@ static struct request *set_next_request(void)
{
struct request_queue *q;
int cnt = FD_MAX_UNITS;
- struct request *rq;
+ struct request *rq = NULL;
/* Find next queue we can dispatch from */
fdc_queue = fdc_queue + 1;
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 4e4cc6c828cb..605a67e40bbf 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1399,7 +1399,7 @@ static struct request *set_next_request(void)
{
struct request_queue *q;
int old_pos = fdc_queue;
- struct request *rq;
+ struct request *rq = NULL;
do {
q = unit[fdc_queue].disk->queue;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index a67d0a611a8a..f291587d753e 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -66,6 +66,7 @@ MODULE_VERSION("3.6.26");
MODULE_LICENSE("GPL");
static DEFINE_MUTEX(cciss_mutex);
+static struct proc_dir_entry *proc_cciss;
#include "cciss_cmd.h"
#include "cciss.h"
@@ -363,8 +364,6 @@ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
#define ENG_GIG_FACTOR (ENG_GIG/512)
#define ENGAGE_SCSI "engage scsi"
-static struct proc_dir_entry *proc_cciss;
-
static void cciss_seq_show_header(struct seq_file *seq)
{
ctlr_info_t *h = seq->private;
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 575495f3c4b8..727d0225b7d0 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -62,8 +62,8 @@ static int cciss_scsi_proc_info(
int length, /* length of data in buffer */
int func); /* 0 == read, 1 == write */
-static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
- void (* done)(struct scsi_cmnd *));
+static int cciss_scsi_queue_command (struct Scsi_Host *h,
+ struct scsi_cmnd *cmd);
static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
static int cciss_eh_abort_handler(struct scsi_cmnd *);
@@ -1406,7 +1406,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c,
static int
-cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+cciss_scsi_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
ctlr_info_t *h;
int rc;
@@ -1504,6 +1504,8 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
return 0;
}
+static DEF_SCSI_QCMD(cciss_scsi_queue_command)
+
static void cciss_unregister_scsi(ctlr_info_t *h)
{
struct cciss_scsi_adapter_data_t *sa;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index d299fe9e78c8..89d8a7cc4054 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -36,7 +36,6 @@
#include <linux/memcontrol.h>
#include <linux/mm_inline.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/pkt_sched.h>
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index b0551ba7ad0c..47d223c2409c 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -26,7 +26,6 @@
#include <linux/module.h>
#include <linux/drbd.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/memcontrol.h>
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 6ec9d53806c5..008d4a00b50d 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -21,80 +21,9 @@
- Instructions for use
- --------------------
+ For usage instructions, please refer to:
- 1) Map a Linux block device to an existing rbd image.
-
- Usage: <mon ip addr> <options> <pool name> <rbd image name> [snap name]
-
- $ echo "192.168.0.1 name=admin rbd foo" > /sys/class/rbd/add
-
- The snapshot name can be "-" or omitted to map the image read/write.
-
- 2) List all active blkdev<->object mappings.
-
- In this example, we have performed step #1 twice, creating two blkdevs,
- mapped to two separate rados objects in the rados rbd pool
-
- $ cat /sys/class/rbd/list
- #id major client_name pool name snap KB
- 0 254 client4143 rbd foo - 1024000
-
- The columns, in order, are:
- - blkdev unique id
- - blkdev assigned major
- - rados client id
- - rados pool name
- - rados block device name
- - mapped snapshot ("-" if none)
- - device size in KB
-
-
- 3) Create a snapshot.
-
- Usage: <blkdev id> <snapname>
-
- $ echo "0 mysnap" > /sys/class/rbd/snap_create
-
-
- 4) Listing a snapshot.
-
- $ cat /sys/class/rbd/snaps_list
- #id snap KB
- 0 - 1024000 (*)
- 0 foo 1024000
-
- The columns, in order, are:
- - blkdev unique id
- - snapshot name, '-' means none (active read/write version)
- - size of device at time of snapshot
- - the (*) indicates this is the active version
-
- 5) Rollback to snapshot.
-
- Usage: <blkdev id> <snapname>
-
- $ echo "0 mysnap" > /sys/class/rbd/snap_rollback
-
-
- 6) Mapping an image using snapshot.
-
- A snapshot mapping is read-only. This is being done by passing
- snap=<snapname> to the options when adding a device.
-
- $ echo "192.168.0.1 name=admin,snap=mysnap rbd foo" > /sys/class/rbd/add
-
-
- 7) Remove an active blkdev<->rbd image mapping.
-
- In this example, we remove the mapping with blkdev unique id 1.
-
- $ echo 1 > /sys/class/rbd/remove
-
-
- NOTE: The actual creation and deletion of rados objects is outside the scope
- of this driver.
+ Documentation/ABI/testing/sysfs-bus-rbd
*/
@@ -163,6 +92,14 @@ struct rbd_request {
u64 len;
};
+struct rbd_snap {
+ struct device dev;
+ const char *name;
+ size_t size;
+ struct list_head node;
+ u64 id;
+};
+
/*
* a single device
*/
@@ -193,21 +130,60 @@ struct rbd_device {
int read_only;
struct list_head node;
+
+ /* list of snapshots */
+ struct list_head snaps;
+
+ /* sysfs related */
+ struct device dev;
+};
+
+static struct bus_type rbd_bus_type = {
+ .name = "rbd",
};
static spinlock_t node_lock; /* protects client get/put */
-static struct class *class_rbd; /* /sys/class/rbd */
static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */
static LIST_HEAD(rbd_dev_list); /* devices */
static LIST_HEAD(rbd_client_list); /* clients */
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
+static void rbd_dev_release(struct device *dev);
+static ssize_t rbd_snap_rollback(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size);
+static ssize_t rbd_snap_add(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count);
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+ struct rbd_snap *snap);;
+
+
+static struct rbd_device *dev_to_rbd(struct device *dev)
+{
+ return container_of(dev, struct rbd_device, dev);
+}
+
+static struct device *rbd_get_dev(struct rbd_device *rbd_dev)
+{
+ return get_device(&rbd_dev->dev);
+}
+
+static void rbd_put_dev(struct rbd_device *rbd_dev)
+{
+ put_device(&rbd_dev->dev);
+}
static int rbd_open(struct block_device *bdev, fmode_t mode)
{
struct gendisk *disk = bdev->bd_disk;
struct rbd_device *rbd_dev = disk->private_data;
+ rbd_get_dev(rbd_dev);
+
set_device_ro(bdev, rbd_dev->read_only);
if ((mode & FMODE_WRITE) && rbd_dev->read_only)
@@ -216,9 +192,19 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
return 0;
}
+static int rbd_release(struct gendisk *disk, fmode_t mode)
+{
+ struct rbd_device *rbd_dev = disk->private_data;
+
+ rbd_put_dev(rbd_dev);
+
+ return 0;
+}
+
static const struct block_device_operations rbd_bd_ops = {
.owner = THIS_MODULE,
.open = rbd_open,
+ .release = rbd_release,
};
/*
@@ -361,7 +347,6 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
int ret = -ENOMEM;
init_rwsem(&header->snap_rwsem);
-
header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
snap_count *
@@ -1256,10 +1241,20 @@ bad:
return -ERANGE;
}
+static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
+{
+ struct rbd_snap *snap;
+
+ while (!list_empty(&rbd_dev->snaps)) {
+ snap = list_first_entry(&rbd_dev->snaps, struct rbd_snap, node);
+ __rbd_remove_snap_dev(rbd_dev, snap);
+ }
+}
+
/*
* only read the first part of the ondisk header, without the snaps info
*/
-static int rbd_update_snaps(struct rbd_device *rbd_dev)
+static int __rbd_update_snaps(struct rbd_device *rbd_dev)
{
int ret;
struct rbd_image_header h;
@@ -1280,12 +1275,15 @@ static int rbd_update_snaps(struct rbd_device *rbd_dev)
rbd_dev->header.total_snaps = h.total_snaps;
rbd_dev->header.snapc = h.snapc;
rbd_dev->header.snap_names = h.snap_names;
+ rbd_dev->header.snap_names_len = h.snap_names_len;
rbd_dev->header.snap_sizes = h.snap_sizes;
rbd_dev->header.snapc->seq = snap_seq;
+ ret = __rbd_init_snaps_header(rbd_dev);
+
up_write(&rbd_dev->header.snap_rwsem);
- return 0;
+ return ret;
}
static int rbd_init_disk(struct rbd_device *rbd_dev)
@@ -1300,6 +1298,11 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
if (rc)
return rc;
+ /* no need to lock here, as rbd_dev is not registered yet */
+ rc = __rbd_init_snaps_header(rbd_dev);
+ if (rc)
+ return rc;
+
rc = rbd_header_set_snap(rbd_dev, rbd_dev->snap_name, &total_size);
if (rc)
return rc;
@@ -1343,54 +1346,360 @@ out:
return rc;
}
-/********************************************************************
- * /sys/class/rbd/
- * add map rados objects to blkdev
- * remove unmap rados objects
- * list show mappings
- *******************************************************************/
+/*
+ sysfs
+*/
+
+static ssize_t rbd_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%llu\n", (unsigned long long)rbd_dev->header.image_size);
+}
+
+static ssize_t rbd_major_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
-static void class_rbd_release(struct class *cls)
+ return sprintf(buf, "%d\n", rbd_dev->major);
+}
+
+static ssize_t rbd_client_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- kfree(cls);
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "client%lld\n", ceph_client_id(rbd_dev->client));
}
-static ssize_t class_rbd_list(struct class *c,
- struct class_attribute *attr,
- char *data)
+static ssize_t rbd_pool_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- int n = 0;
- struct list_head *tmp;
- int max = PAGE_SIZE;
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%s\n", rbd_dev->pool_name);
+}
+
+static ssize_t rbd_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%s\n", rbd_dev->obj);
+}
+
+static ssize_t rbd_snap_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+
+ return sprintf(buf, "%s\n", rbd_dev->snap_name);
+}
+
+static ssize_t rbd_image_refresh(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+ int rc;
+ int ret = size;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
- n += snprintf(data, max,
- "#id\tmajor\tclient_name\tpool\tname\tsnap\tKB\n");
+ rc = __rbd_update_snaps(rbd_dev);
+ if (rc < 0)
+ ret = rc;
- list_for_each(tmp, &rbd_dev_list) {
- struct rbd_device *rbd_dev;
+ mutex_unlock(&ctl_mutex);
+ return ret;
+}
- rbd_dev = list_entry(tmp, struct rbd_device, node);
- n += snprintf(data+n, max-n,
- "%d\t%d\tclient%lld\t%s\t%s\t%s\t%lld\n",
- rbd_dev->id,
- rbd_dev->major,
- ceph_client_id(rbd_dev->client),
- rbd_dev->pool_name,
- rbd_dev->obj, rbd_dev->snap_name,
- rbd_dev->header.image_size >> 10);
- if (n == max)
+static DEVICE_ATTR(size, S_IRUGO, rbd_size_show, NULL);
+static DEVICE_ATTR(major, S_IRUGO, rbd_major_show, NULL);
+static DEVICE_ATTR(client_id, S_IRUGO, rbd_client_id_show, NULL);
+static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL);
+static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
+static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
+static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
+static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
+static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback);
+
+static struct attribute *rbd_attrs[] = {
+ &dev_attr_size.attr,
+ &dev_attr_major.attr,
+ &dev_attr_client_id.attr,
+ &dev_attr_pool.attr,
+ &dev_attr_name.attr,
+ &dev_attr_current_snap.attr,
+ &dev_attr_refresh.attr,
+ &dev_attr_create_snap.attr,
+ &dev_attr_rollback_snap.attr,
+ NULL
+};
+
+static struct attribute_group rbd_attr_group = {
+ .attrs = rbd_attrs,
+};
+
+static const struct attribute_group *rbd_attr_groups[] = {
+ &rbd_attr_group,
+ NULL
+};
+
+static void rbd_sysfs_dev_release(struct device *dev)
+{
+}
+
+static struct device_type rbd_device_type = {
+ .name = "rbd",
+ .groups = rbd_attr_groups,
+ .release = rbd_sysfs_dev_release,
+};
+
+
+/*
+ sysfs - snapshots
+*/
+
+static ssize_t rbd_snap_size_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+ return sprintf(buf, "%lld\n", (long long)snap->size);
+}
+
+static ssize_t rbd_snap_id_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+ return sprintf(buf, "%lld\n", (long long)snap->id);
+}
+
+static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
+static DEVICE_ATTR(snap_id, S_IRUGO, rbd_snap_id_show, NULL);
+
+static struct attribute *rbd_snap_attrs[] = {
+ &dev_attr_snap_size.attr,
+ &dev_attr_snap_id.attr,
+ NULL,
+};
+
+static struct attribute_group rbd_snap_attr_group = {
+ .attrs = rbd_snap_attrs,
+};
+
+static void rbd_snap_dev_release(struct device *dev)
+{
+ struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+ kfree(snap->name);
+ kfree(snap);
+}
+
+static const struct attribute_group *rbd_snap_attr_groups[] = {
+ &rbd_snap_attr_group,
+ NULL
+};
+
+static struct device_type rbd_snap_device_type = {
+ .groups = rbd_snap_attr_groups,
+ .release = rbd_snap_dev_release,
+};
+
+static void __rbd_remove_snap_dev(struct rbd_device *rbd_dev,
+ struct rbd_snap *snap)
+{
+ list_del(&snap->node);
+ device_unregister(&snap->dev);
+}
+
+static int rbd_register_snap_dev(struct rbd_device *rbd_dev,
+ struct rbd_snap *snap,
+ struct device *parent)
+{
+ struct device *dev = &snap->dev;
+ int ret;
+
+ dev->type = &rbd_snap_device_type;
+ dev->parent = parent;
+ dev->release = rbd_snap_dev_release;
+ dev_set_name(dev, "snap_%s", snap->name);
+ ret = device_register(dev);
+
+ return ret;
+}
+
+static int __rbd_add_snap_dev(struct rbd_device *rbd_dev,
+ int i, const char *name,
+ struct rbd_snap **snapp)
+{
+ int ret;
+ struct rbd_snap *snap = kzalloc(sizeof(*snap), GFP_KERNEL);
+ if (!snap)
+ return -ENOMEM;
+ snap->name = kstrdup(name, GFP_KERNEL);
+ snap->size = rbd_dev->header.snap_sizes[i];
+ snap->id = rbd_dev->header.snapc->snaps[i];
+ if (device_is_registered(&rbd_dev->dev)) {
+ ret = rbd_register_snap_dev(rbd_dev, snap,
+ &rbd_dev->dev);
+ if (ret < 0)
+ goto err;
+ }
+ *snapp = snap;
+ return 0;
+err:
+ kfree(snap->name);
+ kfree(snap);
+ return ret;
+}
+
+/*
+ * search for the previous snap in a null delimited string list
+ */
+const char *rbd_prev_snap_name(const char *name, const char *start)
+{
+ if (name < start + 2)
+ return NULL;
+
+ name -= 2;
+ while (*name) {
+ if (name == start)
+ return start;
+ name--;
+ }
+ return name + 1;
+}
+
+/*
+ * compare the old list of snapshots that we have to what's in the header
+ * and update it accordingly. Note that the header holds the snapshots
+ * in a reverse order (from newest to oldest) and we need to go from
+ * older to new so that we don't get a duplicate snap name when
+ * doing the process (e.g., removed snapshot and recreated a new
+ * one with the same name.
+ */
+static int __rbd_init_snaps_header(struct rbd_device *rbd_dev)
+{
+ const char *name, *first_name;
+ int i = rbd_dev->header.total_snaps;
+ struct rbd_snap *snap, *old_snap = NULL;
+ int ret;
+ struct list_head *p, *n;
+
+ first_name = rbd_dev->header.snap_names;
+ name = first_name + rbd_dev->header.snap_names_len;
+
+ list_for_each_prev_safe(p, n, &rbd_dev->snaps) {
+ u64 cur_id;
+
+ old_snap = list_entry(p, struct rbd_snap, node);
+
+ if (i)
+ cur_id = rbd_dev->header.snapc->snaps[i - 1];
+
+ if (!i || old_snap->id < cur_id) {
+ /* old_snap->id was skipped, thus was removed */
+ __rbd_remove_snap_dev(rbd_dev, old_snap);
+ continue;
+ }
+ if (old_snap->id == cur_id) {
+ /* we have this snapshot already */
+ i--;
+ name = rbd_prev_snap_name(name, first_name);
+ continue;
+ }
+ for (; i > 0;
+ i--, name = rbd_prev_snap_name(name, first_name)) {
+ if (!name) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ cur_id = rbd_dev->header.snapc->snaps[i];
+ /* snapshot removal? handle it above */
+ if (cur_id >= old_snap->id)
+ break;
+ /* a new snapshot */
+ ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+ if (ret < 0)
+ return ret;
+
+ /* note that we add it backward so using n and not p */
+ list_add(&snap->node, n);
+ p = &snap->node;
+ }
+ }
+ /* we're done going over the old snap list, just add what's left */
+ for (; i > 0; i--) {
+ name = rbd_prev_snap_name(name, first_name);
+ if (!name) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ ret = __rbd_add_snap_dev(rbd_dev, i - 1, name, &snap);
+ if (ret < 0)
+ return ret;
+ list_add(&snap->node, &rbd_dev->snaps);
+ }
+
+ return 0;
+}
+
+
+static void rbd_root_dev_release(struct device *dev)
+{
+}
+
+static struct device rbd_root_dev = {
+ .init_name = "rbd",
+ .release = rbd_root_dev_release,
+};
+
+static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
+{
+ int ret = -ENOMEM;
+ struct device *dev;
+ struct rbd_snap *snap;
+
+ mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+ dev = &rbd_dev->dev;
+
+ dev->bus = &rbd_bus_type;
+ dev->type = &rbd_device_type;
+ dev->parent = &rbd_root_dev;
+ dev->release = rbd_dev_release;
+ dev_set_name(dev, "%d", rbd_dev->id);
+ ret = device_register(dev);
+ if (ret < 0)
+ goto done_free;
+
+ list_for_each_entry(snap, &rbd_dev->snaps, node) {
+ ret = rbd_register_snap_dev(rbd_dev, snap,
+ &rbd_dev->dev);
+ if (ret < 0)
break;
}
mutex_unlock(&ctl_mutex);
- return n;
+ return 0;
+done_free:
+ mutex_unlock(&ctl_mutex);
+ return ret;
}
-static ssize_t class_rbd_add(struct class *c,
- struct class_attribute *attr,
- const char *buf, size_t count)
+static void rbd_bus_del_dev(struct rbd_device *rbd_dev)
+{
+ device_unregister(&rbd_dev->dev);
+}
+
+static ssize_t rbd_add(struct bus_type *bus, const char *buf, size_t count)
{
struct ceph_osd_client *osdc;
struct rbd_device *rbd_dev;
@@ -1419,6 +1728,7 @@ static ssize_t class_rbd_add(struct class *c,
/* static rbd_device initialization */
spin_lock_init(&rbd_dev->lock);
INIT_LIST_HEAD(&rbd_dev->node);
+ INIT_LIST_HEAD(&rbd_dev->snaps);
/* generate unique id: find highest unique id, add one */
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1478,6 +1788,9 @@ static ssize_t class_rbd_add(struct class *c,
}
rbd_dev->major = irc;
+ rc = rbd_bus_add_dev(rbd_dev);
+ if (rc)
+ goto err_out_disk;
/* set up and announce blkdev mapping */
rc = rbd_init_disk(rbd_dev);
if (rc)
@@ -1487,6 +1800,8 @@ static ssize_t class_rbd_add(struct class *c,
err_out_blkdev:
unregister_blkdev(rbd_dev->major, rbd_dev->name);
+err_out_disk:
+ rbd_free_disk(rbd_dev);
err_out_client:
rbd_put_client(rbd_dev);
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
@@ -1518,35 +1833,10 @@ static struct rbd_device *__rbd_get_dev(unsigned long id)
return NULL;
}
-static ssize_t class_rbd_remove(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static void rbd_dev_release(struct device *dev)
{
- struct rbd_device *rbd_dev = NULL;
- int target_id, rc;
- unsigned long ul;
-
- rc = strict_strtoul(buf, 10, &ul);
- if (rc)
- return rc;
-
- /* convert to int; abort if we lost anything in the conversion */
- target_id = (int) ul;
- if (target_id != ul)
- return -EINVAL;
-
- /* remove object from list immediately */
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
- rbd_dev = __rbd_get_dev(target_id);
- if (rbd_dev)
- list_del_init(&rbd_dev->node);
-
- mutex_unlock(&ctl_mutex);
-
- if (!rbd_dev)
- return -ENOENT;
+ struct rbd_device *rbd_dev =
+ container_of(dev, struct rbd_device, dev);
rbd_put_client(rbd_dev);
@@ -1557,67 +1847,11 @@ static ssize_t class_rbd_remove(struct class *c,
/* release module ref */
module_put(THIS_MODULE);
-
- return count;
}
-static ssize_t class_rbd_snaps_list(struct class *c,
- struct class_attribute *attr,
- char *data)
-{
- struct rbd_device *rbd_dev = NULL;
- struct list_head *tmp;
- struct rbd_image_header *header;
- int i, n = 0, max = PAGE_SIZE;
- int ret;
-
- mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
- n += snprintf(data, max, "#id\tsnap\tKB\n");
-
- list_for_each(tmp, &rbd_dev_list) {
- char *names, *p;
- struct ceph_snap_context *snapc;
-
- rbd_dev = list_entry(tmp, struct rbd_device, node);
- header = &rbd_dev->header;
-
- down_read(&header->snap_rwsem);
-
- names = header->snap_names;
- snapc = header->snapc;
-
- n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
- rbd_dev->id, RBD_SNAP_HEAD_NAME,
- header->image_size >> 10,
- (!rbd_dev->cur_snap ? " (*)" : ""));
- if (n == max)
- break;
-
- p = names;
- for (i = 0; i < header->total_snaps; i++, p += strlen(p) + 1) {
- n += snprintf(data + n, max - n, "%d\t%s\t%lld%s\n",
- rbd_dev->id, p, header->snap_sizes[i] >> 10,
- (rbd_dev->cur_snap &&
- (snap_index(header, i) == rbd_dev->cur_snap) ?
- " (*)" : ""));
- if (n == max)
- break;
- }
-
- up_read(&header->snap_rwsem);
- }
-
-
- ret = n;
- mutex_unlock(&ctl_mutex);
- return ret;
-}
-
-static ssize_t class_rbd_snaps_refresh(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static ssize_t rbd_remove(struct bus_type *bus,
+ const char *buf,
+ size_t count)
{
struct rbd_device *rbd_dev = NULL;
int target_id, rc;
@@ -1641,95 +1875,70 @@ static ssize_t class_rbd_snaps_refresh(struct class *c,
goto done;
}
- rc = rbd_update_snaps(rbd_dev);
- if (rc < 0)
- ret = rc;
+ list_del_init(&rbd_dev->node);
+
+ __rbd_remove_all_snaps(rbd_dev);
+ rbd_bus_del_dev(rbd_dev);
done:
mutex_unlock(&ctl_mutex);
return ret;
}
-static ssize_t class_rbd_snap_create(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static ssize_t rbd_snap_add(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
{
- struct rbd_device *rbd_dev = NULL;
- int target_id, ret;
- char *name;
-
- name = kmalloc(RBD_MAX_SNAP_NAME_LEN + 1, GFP_KERNEL);
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+ int ret;
+ char *name = kmalloc(count + 1, GFP_KERNEL);
if (!name)
return -ENOMEM;
- /* parse snaps add command */
- if (sscanf(buf, "%d "
- "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
- &target_id,
- name) != 2) {
- ret = -EINVAL;
- goto done;
- }
+ snprintf(name, count, "%s", buf);
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
- rbd_dev = __rbd_get_dev(target_id);
- if (!rbd_dev) {
- ret = -ENOENT;
- goto done_unlock;
- }
-
ret = rbd_header_add_snap(rbd_dev,
name, GFP_KERNEL);
if (ret < 0)
goto done_unlock;
- ret = rbd_update_snaps(rbd_dev);
+ ret = __rbd_update_snaps(rbd_dev);
if (ret < 0)
goto done_unlock;
ret = count;
done_unlock:
mutex_unlock(&ctl_mutex);
-done:
kfree(name);
return ret;
}
-static ssize_t class_rbd_rollback(struct class *c,
- struct class_attribute *attr,
- const char *buf,
- size_t count)
+static ssize_t rbd_snap_rollback(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
{
- struct rbd_device *rbd_dev = NULL;
- int target_id, ret;
+ struct rbd_device *rbd_dev = dev_to_rbd(dev);
+ int ret;
u64 snapid;
- char snap_name[RBD_MAX_SNAP_NAME_LEN];
u64 cur_ofs;
- char *seg_name;
+ char *seg_name = NULL;
+ char *snap_name = kmalloc(count + 1, GFP_KERNEL);
+ ret = -ENOMEM;
+ if (!snap_name)
+ return ret;
/* parse snaps add command */
- if (sscanf(buf, "%d "
- "%" __stringify(RBD_MAX_SNAP_NAME_LEN) "s",
- &target_id,
- snap_name) != 2) {
- return -EINVAL;
- }
-
- ret = -ENOMEM;
+ snprintf(snap_name, count, "%s", buf);
seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
if (!seg_name)
- return ret;
+ goto done;
mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
- rbd_dev = __rbd_get_dev(target_id);
- if (!rbd_dev) {
- ret = -ENOENT;
- goto done_unlock;
- }
-
ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL);
if (ret < 0)
goto done_unlock;
@@ -1750,7 +1959,7 @@ static ssize_t class_rbd_rollback(struct class *c,
seg_name, ret);
}
- ret = rbd_update_snaps(rbd_dev);
+ ret = __rbd_update_snaps(rbd_dev);
if (ret < 0)
goto done_unlock;
@@ -1758,57 +1967,42 @@ static ssize_t class_rbd_rollback(struct class *c,
done_unlock:
mutex_unlock(&ctl_mutex);
+done:
kfree(seg_name);
+ kfree(snap_name);
return ret;
}
-static struct class_attribute class_rbd_attrs[] = {
- __ATTR(add, 0200, NULL, class_rbd_add),
- __ATTR(remove, 0200, NULL, class_rbd_remove),
- __ATTR(list, 0444, class_rbd_list, NULL),
- __ATTR(snaps_refresh, 0200, NULL, class_rbd_snaps_refresh),
- __ATTR(snap_create, 0200, NULL, class_rbd_snap_create),
- __ATTR(snaps_list, 0444, class_rbd_snaps_list, NULL),
- __ATTR(snap_rollback, 0200, NULL, class_rbd_rollback),
+static struct bus_attribute rbd_bus_attrs[] = {
+ __ATTR(add, S_IWUSR, NULL, rbd_add),
+ __ATTR(remove, S_IWUSR, NULL, rbd_remove),
__ATTR_NULL
};
/*
* create control files in sysfs
- * /sys/class/rbd/...
+ * /sys/bus/rbd/...
*/
static int rbd_sysfs_init(void)
{
- int ret = -ENOMEM;
+ int ret;
- class_rbd = kzalloc(sizeof(*class_rbd), GFP_KERNEL);
- if (!class_rbd)
- goto out;
+ rbd_bus_type.bus_attrs = rbd_bus_attrs;
- class_rbd->name = DRV_NAME;
- class_rbd->owner = THIS_MODULE;
- class_rbd->class_release = class_rbd_release;
- class_rbd->class_attrs = class_rbd_attrs;
+ ret = bus_register(&rbd_bus_type);
+ if (ret < 0)
+ return ret;
- ret = class_register(class_rbd);
- if (ret)
- goto out_class;
- return 0;
+ ret = device_register(&rbd_root_dev);
-out_class:
- kfree(class_rbd);
- class_rbd = NULL;
- pr_err(DRV_NAME ": failed to create class rbd\n");
-out:
return ret;
}
static void rbd_sysfs_cleanup(void)
{
- if (class_rbd)
- class_destroy(class_rbd);
- class_rbd = NULL;
+ device_unregister(&rbd_root_dev);
+ bus_unregister(&rbd_bus_type);
}
int __init rbd_init(void)
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 255035cfc88a..4f9e22f29138 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -65,7 +65,7 @@ enum blkif_state {
struct blk_shadow {
struct blkif_request req;
- unsigned long request;
+ struct request *request;
unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
@@ -136,7 +136,7 @@ static void add_id_to_freelist(struct blkfront_info *info,
unsigned long id)
{
info->shadow[id].req.id = info->shadow_free;
- info->shadow[id].request = 0;
+ info->shadow[id].request = NULL;
info->shadow_free = id;
}
@@ -245,14 +245,11 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
}
/*
- * blkif_queue_request
+ * Generate a Xen blkfront IO request from a blk layer request. Reads
+ * and writes are handled as expected. Since we lack a loose flush
+ * request, we map flushes into a full ordered barrier.
*
- * request block io
- *
- * id: for guest use only.
- * operation: BLKIF_OP_{READ,WRITE,PROBE}
- * buffer: buffer to read/write into. this should be a
- * virtual address in the guest os.
+ * @req: a request struct
*/
static int blkif_queue_request(struct request *req)
{
@@ -281,7 +278,7 @@ static int blkif_queue_request(struct request *req)
/* Fill out a communications ring structure. */
ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
id = get_id_from_freelist(info);
- info->shadow[id].request = (unsigned long)req;
+ info->shadow[id].request = req;
ring_req->id = id;
ring_req->sector_number = (blkif_sector_t)blk_rq_pos(req);
@@ -290,6 +287,18 @@ static int blkif_queue_request(struct request *req)
ring_req->operation = rq_data_dir(req) ?
BLKIF_OP_WRITE : BLKIF_OP_READ;
+ if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
+ /*
+ * Ideally we could just do an unordered
+ * flush-to-disk, but all we have is a full write
+ * barrier at the moment. However, a barrier write is
+ * a superset of FUA, so we can implement it the same
+ * way. (It's also a FLUSH+FUA, since it is
+ * guaranteed ordered WRT previous writes.)
+ */
+ ring_req->operation = BLKIF_OP_WRITE_BARRIER;
+ }
+
ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
@@ -634,7 +643,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
bret = RING_GET_RESPONSE(&info->ring, i);
id = bret->id;
- req = (struct request *)info->shadow[id].request;
+ req = info->shadow[id].request;
blkif_completion(&info->shadow[id]);
@@ -647,6 +656,16 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
info->gd->disk_name);
error = -EOPNOTSUPP;
+ }
+ if (unlikely(bret->status == BLKIF_RSP_ERROR &&
+ info->shadow[id].req.nr_segments == 0)) {
+ printk(KERN_WARNING "blkfront: %s: empty write barrier op failed\n",
+ info->gd->disk_name);
+ error = -EOPNOTSUPP;
+ }
+ if (unlikely(error)) {
+ if (error == -EOPNOTSUPP)
+ error = 0;
info->feature_flush = 0;
xlvbd_flush(info);
}
@@ -899,7 +918,7 @@ static int blkif_recover(struct blkfront_info *info)
/* Stage 3: Find pending requests and requeue them. */
for (i = 0; i < BLK_RING_SIZE; i++) {
/* Not in use? */
- if (copy[i].request == 0)
+ if (!copy[i].request)
continue;
/* Grab a request slot and copy shadow state into it. */
@@ -916,9 +935,7 @@ static int blkif_recover(struct blkfront_info *info)
req->seg[j].gref,
info->xbdev->otherend_id,
pfn_to_mfn(info->shadow[req->id].frame[j]),
- rq_data_dir(
- (struct request *)
- info->shadow[req->id].request));
+ rq_data_dir(info->shadow[req->id].request));
info->shadow[req->id].req = *req;
info->ring.req_prod_pvt++;
@@ -1067,14 +1084,8 @@ static void blkfront_connect(struct blkfront_info *info)
*/
info->feature_flush = 0;
- /*
- * The driver doesn't properly handled empty flushes, so
- * lets disable barrier support for now.
- */
-#if 0
if (!err && barrier)
- info->feature_flush = REQ_FLUSH;
-#endif
+ info->feature_flush = REQ_FLUSH | REQ_FUA;
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
if (err) {
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 43412c03969e..3cb4539a98b2 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -39,7 +39,6 @@
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include "agp.h"
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index c0bd6f472c52..6ee3348bc3e4 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -81,7 +81,6 @@ static char *serial_version = "4.30";
#include <linux/mm.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/platform_device.h>
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index f6718f05dad4..095ab90535ce 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/tty.h>
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 55b8667f739f..7066e801b9d3 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -14,7 +14,6 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/major.h>
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 788da05190cc..2016aad85203 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -37,7 +37,6 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 667abd23ad6a..7c6de4c92458 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -21,7 +21,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index f646725bd567..748c3b0ecd89 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -52,7 +52,6 @@
#include <linux/interrupt.h>
#include <linux/serial.h>
#include <linux/serialP.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 9f8495b4fc8f..a7616d226a49 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -87,7 +87,6 @@
#include <linux/tty_flip.h>
#include <linux/mm.h>
#include <linux/serial.h>
-#include <linux/smp_lock.h>
#include <linux/fcntl.h>
#include <linux/major.h>
#include <linux/delay.h>
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 4bef6ab83622..461a5a045517 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -40,7 +40,6 @@
#include <linux/stallion.h>
#include <linux/ioport.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/ctype.h>
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index e53f16865397..a786326cea2f 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -216,7 +216,6 @@
#include <linux/eisa.h>
#include <linux/pci.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/bitops.h>
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 1030f8420137..c17a305ecb28 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
+#include <linux/acpi.h>
#include "tpm.h"
#define TPM_HEADER_SIZE 10
@@ -78,6 +79,26 @@ enum tis_defaults {
static LIST_HEAD(tis_chips);
static DEFINE_SPINLOCK(tis_lock);
+#ifdef CONFIG_ACPI
+static int is_itpm(struct pnp_dev *dev)
+{
+ struct acpi_device *acpi = pnp_acpi_device(dev);
+ struct acpi_hardware_id *id;
+
+ list_for_each_entry(id, &acpi->pnp.ids, list) {
+ if (!strcmp("INTC0102", id->id))
+ return 1;
+ }
+
+ return 0;
+}
+#else
+static int is_itpm(struct pnp_dev *dev)
+{
+ return 0;
+}
+#endif
+
static int check_locality(struct tpm_chip *chip, int l)
{
if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
@@ -472,6 +493,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
"1.2 TPM (device-id 0x%X, rev-id %d)\n",
vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
+ if (is_itpm(to_pnp_dev(dev)))
+ itpm = 1;
+
if (itpm)
dev_info(dev, "Intel iTPM workaround enabled\n");
diff --git a/drivers/char/uv_mmtimer.c b/drivers/char/uv_mmtimer.c
index 493b47a0d511..956ebe2080a5 100644
--- a/drivers/char/uv_mmtimer.c
+++ b/drivers/char/uv_mmtimer.c
@@ -23,7 +23,6 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/math64.h>
-#include <linux/smp_lock.h>
#include <asm/genapic.h>
#include <asm/uv/uv_hub.h>
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 6c1b676643a9..896a2ced1d27 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1547,31 +1547,16 @@ static int init_vqs(struct ports_device *portdev)
nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;
vqs = kmalloc(nr_queues * sizeof(struct virtqueue *), GFP_KERNEL);
- if (!vqs) {
- err = -ENOMEM;
- goto fail;
- }
io_callbacks = kmalloc(nr_queues * sizeof(vq_callback_t *), GFP_KERNEL);
- if (!io_callbacks) {
- err = -ENOMEM;
- goto free_vqs;
- }
io_names = kmalloc(nr_queues * sizeof(char *), GFP_KERNEL);
- if (!io_names) {
- err = -ENOMEM;
- goto free_callbacks;
- }
portdev->in_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
GFP_KERNEL);
- if (!portdev->in_vqs) {
- err = -ENOMEM;
- goto free_names;
- }
portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *),
GFP_KERNEL);
- if (!portdev->out_vqs) {
+ if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs ||
+ !portdev->out_vqs) {
err = -ENOMEM;
- goto free_invqs;
+ goto free;
}
/*
@@ -1605,7 +1590,7 @@ static int init_vqs(struct ports_device *portdev)
io_callbacks,
(const char **)io_names);
if (err)
- goto free_outvqs;
+ goto free;
j = 0;
portdev->in_vqs[0] = vqs[0];
@@ -1621,23 +1606,19 @@ static int init_vqs(struct ports_device *portdev)
portdev->out_vqs[i] = vqs[j + 1];
}
}
- kfree(io_callbacks);
kfree(io_names);
+ kfree(io_callbacks);
kfree(vqs);
return 0;
-free_names:
- kfree(io_names);
-free_callbacks:
- kfree(io_callbacks);
-free_outvqs:
+free:
kfree(portdev->out_vqs);
-free_invqs:
kfree(portdev->in_vqs);
-free_vqs:
+ kfree(io_names);
+ kfree(io_callbacks);
kfree(vqs);
-fail:
+
return err;
}
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index eb6b54dbb806..85ffd5e38c50 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -1213,3 +1213,4 @@ module_exit(sh_dmae_exit);
MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>");
MODULE_DESCRIPTION("Renesas SH DMA Engine driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sh-dma-engine");
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index b3781399b38a..ba2898b3639b 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -10,16 +10,16 @@ obj-$(CONFIG_EDAC) := edac_stub.o
obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
obj-$(CONFIG_EDAC_MCE) += edac_mce.o
-edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
-edac_core-objs += edac_module.o edac_device_sysfs.o
+edac_core-y := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
+edac_core-y += edac_module.o edac_device_sysfs.o
ifdef CONFIG_PCI
-edac_core-objs += edac_pci.o edac_pci_sysfs.o
+edac_core-y += edac_pci.o edac_pci_sysfs.o
endif
obj-$(CONFIG_EDAC_MCE_INJ) += mce_amd_inj.o
-edac_mce_amd-objs := mce_amd.o
+edac_mce_amd-y := mce_amd.o
obj-$(CONFIG_EDAC_DECODE_MCE) += edac_mce_amd.o
obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o
diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c
index 8d0688f36d4c..39faded3cadd 100644
--- a/drivers/edac/mce_amd_inj.c
+++ b/drivers/edac/mce_amd_inj.c
@@ -139,7 +139,7 @@ static int __init edac_init_mce_inject(void)
return 0;
err_sysfs_create:
- while (i-- >= 0)
+ while (--i >= 0)
sysfs_remove_file(mce_kobj, &sysfs_attrs[i]->attr);
kobject_del(mce_kobj);
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 18fdd9703b48..1a467a91fb0b 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -7,6 +7,7 @@
*/
#include <linux/bug.h>
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firewire.h>
#include <linux/firewire-constants.h>
@@ -26,8 +27,14 @@
#include <asm/unaligned.h>
#include <net/arp.h>
-#define FWNET_MAX_FRAGMENTS 25 /* arbitrary limit */
-#define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16 * 1024 ? 4 : 2)
+/* rx limits */
+#define FWNET_MAX_FRAGMENTS 30 /* arbitrary, > TX queue depth */
+#define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16*1024 ? 4 : 2)
+
+/* tx limits */
+#define FWNET_MAX_QUEUED_DATAGRAMS 20 /* < 64 = number of tlabels */
+#define FWNET_MIN_QUEUED_DATAGRAMS 10 /* should keep AT DMA busy enough */
+#define FWNET_TX_QUEUE_LEN FWNET_MAX_QUEUED_DATAGRAMS /* ? */
#define IEEE1394_BROADCAST_CHANNEL 31
#define IEEE1394_ALL_NODES (0xffc0 | 0x003f)
@@ -169,15 +176,8 @@ struct fwnet_device {
struct fw_address_handler handler;
u64 local_fifo;
- /* List of packets to be sent */
- struct list_head packet_list;
- /*
- * List of packets that were broadcasted. When we get an ISO interrupt
- * one of them has been sent
- */
- struct list_head broadcasted_list;
- /* List of packets that have been sent but not yet acked */
- struct list_head sent_list;
+ /* Number of tx datagrams that have been queued but not yet acked */
+ int queued_datagrams;
struct list_head peer_list;
struct fw_card *card;
@@ -195,7 +195,7 @@ struct fwnet_peer {
unsigned pdg_size; /* pd_list size */
u16 datagram_label; /* outgoing datagram label */
- unsigned max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */
+ u16 max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */
int node_id;
int generation;
unsigned speed;
@@ -203,22 +203,18 @@ struct fwnet_peer {
/* This is our task struct. It's used for the packet complete callback. */
struct fwnet_packet_task {
- /*
- * ptask can actually be on dev->packet_list, dev->broadcasted_list,
- * or dev->sent_list depending on its current state.
- */
- struct list_head pt_link;
struct fw_transaction transaction;
struct rfc2734_header hdr;
struct sk_buff *skb;
struct fwnet_device *dev;
int outstanding_pkts;
- unsigned max_payload;
u64 fifo_addr;
u16 dest_node;
+ u16 max_payload;
u8 generation;
u8 speed;
+ u8 enqueued;
};
/*
@@ -650,8 +646,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
net->stats.rx_packets++;
net->stats.rx_bytes += skb->len;
}
- if (netif_queue_stopped(net))
- netif_wake_queue(net);
return 0;
@@ -660,8 +654,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
net->stats.rx_dropped++;
dev_kfree_skb_any(skb);
- if (netif_queue_stopped(net))
- netif_wake_queue(net);
return -ENOENT;
}
@@ -793,15 +785,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
* Datagram is not complete, we're done for the
* moment.
*/
- spin_unlock_irqrestore(&dev->lock, flags);
-
- return 0;
+ retval = 0;
fail:
spin_unlock_irqrestore(&dev->lock, flags);
- if (netif_queue_stopped(net))
- netif_wake_queue(net);
-
return retval;
}
@@ -901,11 +888,19 @@ static void fwnet_free_ptask(struct fwnet_packet_task *ptask)
kmem_cache_free(fwnet_packet_task_cache, ptask);
}
+/* Caller must hold dev->lock. */
+static void dec_queued_datagrams(struct fwnet_device *dev)
+{
+ if (--dev->queued_datagrams == FWNET_MIN_QUEUED_DATAGRAMS)
+ netif_wake_queue(dev->netdev);
+}
+
static int fwnet_send_packet(struct fwnet_packet_task *ptask);
static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
{
struct fwnet_device *dev = ptask->dev;
+ struct sk_buff *skb = ptask->skb;
unsigned long flags;
bool free;
@@ -914,10 +909,14 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
ptask->outstanding_pkts--;
/* Check whether we or the networking TX soft-IRQ is last user. */
- free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link));
+ free = (ptask->outstanding_pkts == 0 && ptask->enqueued);
+ if (free)
+ dec_queued_datagrams(dev);
- if (ptask->outstanding_pkts == 0)
- list_del(&ptask->pt_link);
+ if (ptask->outstanding_pkts == 0) {
+ dev->netdev->stats.tx_packets++;
+ dev->netdev->stats.tx_bytes += skb->len;
+ }
spin_unlock_irqrestore(&dev->lock, flags);
@@ -926,7 +925,6 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
u16 fg_off;
u16 datagram_label;
u16 lf;
- struct sk_buff *skb;
/* Update the ptask to point to the next fragment and send it */
lf = fwnet_get_hdr_lf(&ptask->hdr);
@@ -953,7 +951,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
datagram_label = fwnet_get_hdr_dgl(&ptask->hdr);
break;
}
- skb = ptask->skb;
+
skb_pull(skb, ptask->max_payload);
if (ptask->outstanding_pkts > 1) {
fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG,
@@ -970,6 +968,31 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
fwnet_free_ptask(ptask);
}
+static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask)
+{
+ struct fwnet_device *dev = ptask->dev;
+ unsigned long flags;
+ bool free;
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+ /* One fragment failed; don't try to send remaining fragments. */
+ ptask->outstanding_pkts = 0;
+
+ /* Check whether we or the networking TX soft-IRQ is last user. */
+ free = ptask->enqueued;
+ if (free)
+ dec_queued_datagrams(dev);
+
+ dev->netdev->stats.tx_dropped++;
+ dev->netdev->stats.tx_errors++;
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ if (free)
+ fwnet_free_ptask(ptask);
+}
+
static void fwnet_write_complete(struct fw_card *card, int rcode,
void *payload, size_t length, void *data)
{
@@ -977,11 +1000,12 @@ static void fwnet_write_complete(struct fw_card *card, int rcode,
ptask = data;
- if (rcode == RCODE_COMPLETE)
+ if (rcode == RCODE_COMPLETE) {
fwnet_transmit_packet_done(ptask);
- else
+ } else {
fw_error("fwnet_write_complete: failed: %x\n", rcode);
- /* ??? error recovery */
+ fwnet_transmit_packet_failed(ptask);
+ }
}
static int fwnet_send_packet(struct fwnet_packet_task *ptask)
@@ -1039,9 +1063,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
spin_lock_irqsave(&dev->lock, flags);
/* If the AT tasklet already ran, we may be last user. */
- free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+ free = (ptask->outstanding_pkts == 0 && !ptask->enqueued);
if (!free)
- list_add_tail(&ptask->pt_link, &dev->broadcasted_list);
+ ptask->enqueued = true;
+ else
+ dec_queued_datagrams(dev);
spin_unlock_irqrestore(&dev->lock, flags);
@@ -1056,9 +1082,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
spin_lock_irqsave(&dev->lock, flags);
/* If the AT tasklet already ran, we may be last user. */
- free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
+ free = (ptask->outstanding_pkts == 0 && !ptask->enqueued);
if (!free)
- list_add_tail(&ptask->pt_link, &dev->sent_list);
+ ptask->enqueued = true;
+ else
+ dec_queued_datagrams(dev);
spin_unlock_irqrestore(&dev->lock, flags);
@@ -1224,6 +1252,15 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
struct fwnet_peer *peer;
unsigned long flags;
+ spin_lock_irqsave(&dev->lock, flags);
+
+ /* Can this happen? */
+ if (netif_queue_stopped(dev->netdev)) {
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ return NETDEV_TX_BUSY;
+ }
+
ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC);
if (ptask == NULL)
goto fail;
@@ -1242,9 +1279,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
proto = hdr_buf.h_proto;
dg_size = skb->len;
- /* serialize access to peer, including peer->datagram_label */
- spin_lock_irqsave(&dev->lock, flags);
-
/*
* Set the transmission type for the packet. ARP packets and IP
* broadcast packets are sent via GASP.
@@ -1266,7 +1300,7 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid));
if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR)
- goto fail_unlock;
+ goto fail;
generation = peer->generation;
dest_node = peer->node_id;
@@ -1320,18 +1354,21 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
max_payload += RFC2374_FRAG_HDR_SIZE;
}
+ if (++dev->queued_datagrams == FWNET_MAX_QUEUED_DATAGRAMS)
+ netif_stop_queue(dev->netdev);
+
spin_unlock_irqrestore(&dev->lock, flags);
ptask->max_payload = max_payload;
- INIT_LIST_HEAD(&ptask->pt_link);
+ ptask->enqueued = 0;
fwnet_send_packet(ptask);
return NETDEV_TX_OK;
- fail_unlock:
- spin_unlock_irqrestore(&dev->lock, flags);
fail:
+ spin_unlock_irqrestore(&dev->lock, flags);
+
if (ptask)
kmem_cache_free(fwnet_packet_task_cache, ptask);
@@ -1377,7 +1414,7 @@ static void fwnet_init_dev(struct net_device *net)
net->addr_len = FWNET_ALEN;
net->hard_header_len = FWNET_HLEN;
net->type = ARPHRD_IEEE1394;
- net->tx_queue_len = 10;
+ net->tx_queue_len = FWNET_TX_QUEUE_LEN;
}
/* caller must hold fwnet_device_mutex */
@@ -1457,14 +1494,9 @@ static int fwnet_probe(struct device *_dev)
dev->broadcast_rcv_context = NULL;
dev->broadcast_xmt_max_payload = 0;
dev->broadcast_xmt_datagramlabel = 0;
-
dev->local_fifo = FWNET_NO_FIFO_ADDR;
-
- INIT_LIST_HEAD(&dev->packet_list);
- INIT_LIST_HEAD(&dev->broadcasted_list);
- INIT_LIST_HEAD(&dev->sent_list);
+ dev->queued_datagrams = 0;
INIT_LIST_HEAD(&dev->peer_list);
-
dev->card = card;
dev->netdev = net;
@@ -1522,7 +1554,7 @@ static int fwnet_remove(struct device *_dev)
struct fwnet_peer *peer = dev_get_drvdata(_dev);
struct fwnet_device *dev = peer->dev;
struct net_device *net;
- struct fwnet_packet_task *ptask, *pt_next;
+ int i;
mutex_lock(&fwnet_device_mutex);
@@ -1540,21 +1572,9 @@ static int fwnet_remove(struct device *_dev)
dev->card);
fw_iso_context_destroy(dev->broadcast_rcv_context);
}
- list_for_each_entry_safe(ptask, pt_next,
- &dev->packet_list, pt_link) {
- dev_kfree_skb_any(ptask->skb);
- kmem_cache_free(fwnet_packet_task_cache, ptask);
- }
- list_for_each_entry_safe(ptask, pt_next,
- &dev->broadcasted_list, pt_link) {
- dev_kfree_skb_any(ptask->skb);
- kmem_cache_free(fwnet_packet_task_cache, ptask);
- }
- list_for_each_entry_safe(ptask, pt_next,
- &dev->sent_list, pt_link) {
- dev_kfree_skb_any(ptask->skb);
- kmem_cache_free(fwnet_packet_task_cache, ptask);
- }
+ for (i = 0; dev->queued_datagrams && i < 5; i++)
+ ssleep(1);
+ WARN_ON(dev->queued_datagrams);
list_del(&dev->dev_link);
free_netdev(net);
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index bfae4b309791..afa576a75a8e 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1468,7 +1468,7 @@ static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
/* SCSI stack integration */
-static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+static int sbp2_scsi_queuecommand_lck(struct scsi_cmnd *cmd, scsi_done_fn_t done)
{
struct sbp2_logical_unit *lu = cmd->device->hostdata;
struct fw_device *device = target_device(lu->tgt);
@@ -1534,6 +1534,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
return retval;
}
+static DEF_SCSI_QCMD(sbp2_scsi_queuecommand)
+
static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
{
struct sbp2_logical_unit *lu = sdev->hostdata;
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
index e23c06893d19..599f6c9e0fbf 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/cs5535-gpio.c
@@ -56,6 +56,18 @@ static struct cs5535_gpio_chip {
* registers, see include/linux/cs5535.h.
*/
+static void errata_outl(u32 val, unsigned long addr)
+{
+ /*
+ * According to the CS5536 errata (#36), after suspend
+ * a write to the high bank GPIO register will clear all
+ * non-selected bits; the recommended workaround is a
+ * read-modify-write operation.
+ */
+ val |= inl(addr);
+ outl(val, addr);
+}
+
static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
unsigned int reg)
{
@@ -64,7 +76,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
outl(1 << offset, chip->base + reg);
else
/* high bank register */
- outl(1 << (offset - 16), chip->base + 0x80 + reg);
+ errata_outl(1 << (offset - 16), chip->base + 0x80 + reg);
}
void cs5535_gpio_set(unsigned offset, unsigned int reg)
@@ -86,7 +98,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
outl(1 << (offset + 16), chip->base + reg);
else
/* high bank register */
- outl(1 << offset, chip->base + 0x80 + reg);
+ errata_outl(1 << offset, chip->base + 0x80 + reg);
}
void cs5535_gpio_clear(unsigned offset, unsigned int reg)
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index f7af91cb273d..7ca59359fee2 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -471,6 +471,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
int count = 0, ro, fail = 0;
struct drm_crtc_helper_funcs *crtc_funcs;
int ret = 0;
+ int i;
DRM_DEBUG_KMS("\n");
@@ -666,6 +667,12 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if (ret != 0)
goto fail;
}
+ DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
+ for (i = 0; i < set->num_connectors; i++) {
+ DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
+ drm_get_connector_name(set->connectors[i]));
+ set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
+ }
kfree(save_connectors);
kfree(save_encoders);
@@ -841,7 +848,7 @@ static void output_poll_execute(struct work_struct *work)
struct delayed_work *delayed_work = to_delayed_work(work);
struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
struct drm_connector *connector;
- enum drm_connector_status old_status, status;
+ enum drm_connector_status old_status;
bool repoll = false, changed = false;
if (!drm_kms_helper_poll)
@@ -866,8 +873,9 @@ static void output_poll_execute(struct work_struct *work)
!(connector->polled & DRM_CONNECTOR_POLL_HPD))
continue;
- status = connector->funcs->detect(connector, false);
- if (old_status != status)
+ connector->status = connector->funcs->detect(connector, false);
+ DRM_DEBUG_KMS("connector status updated to %d\n", connector->status);
+ if (old_status != connector->status)
changed = true;
}
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index b744dad5c237..a39794bac04b 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -37,7 +37,6 @@
#include "drmP.h"
#include <linux/poll.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
/* from BKL pushdown: note that nothing else serializes idr_find() */
DEFINE_MUTEX(drm_global_mutex);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 80745f85902c..f737960712e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -150,7 +150,8 @@ static const struct intel_device_info intel_ironlake_d_info = {
static const struct intel_device_info intel_ironlake_m_info = {
.gen = 5, .is_mobile = 1,
- .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
+ .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1,
+ .has_fbc = 0, /* disabled due to buggy hardware */
.has_bsd_ring = 1,
};
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 90414ae86afc..409826da3099 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1045,6 +1045,8 @@ void i915_gem_clflush_object(struct drm_gem_object *obj);
int i915_gem_object_set_domain(struct drm_gem_object *obj,
uint32_t read_domains,
uint32_t write_domain);
+int i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj,
+ bool interruptible);
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,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ef188e391406..5e54821af996 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -38,8 +38,7 @@
static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj);
-static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
- bool pipelined);
+static int 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);
static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj,
@@ -547,6 +546,19 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_object *obj_priv;
int ret = 0;
+ if (args->size == 0)
+ return 0;
+
+ if (!access_ok(VERIFY_WRITE,
+ (char __user *)(uintptr_t)args->data_ptr,
+ args->size))
+ return -EFAULT;
+
+ ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr,
+ args->size);
+ if (ret)
+ return -EFAULT;
+
ret = i915_mutex_lock_interruptible(dev);
if (ret)
return ret;
@@ -564,23 +576,6 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
goto out;
}
- if (args->size == 0)
- goto out;
-
- if (!access_ok(VERIFY_WRITE,
- (char __user *)(uintptr_t)args->data_ptr,
- args->size)) {
- ret = -EFAULT;
- goto out;
- }
-
- ret = fault_in_pages_writeable((char __user *)(uintptr_t)args->data_ptr,
- args->size);
- if (ret) {
- ret = -EFAULT;
- goto out;
- }
-
ret = i915_gem_object_get_pages_or_evict(obj);
if (ret)
goto out;
@@ -981,7 +976,20 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_pwrite *args = data;
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
- int ret = 0;
+ int ret;
+
+ if (args->size == 0)
+ return 0;
+
+ if (!access_ok(VERIFY_READ,
+ (char __user *)(uintptr_t)args->data_ptr,
+ args->size))
+ return -EFAULT;
+
+ ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr,
+ args->size);
+ if (ret)
+ return -EFAULT;
ret = i915_mutex_lock_interruptible(dev);
if (ret)
@@ -994,30 +1002,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
}
obj_priv = to_intel_bo(obj);
-
/* Bounds check destination. */
if (args->offset > obj->size || args->size > obj->size - args->offset) {
ret = -EINVAL;
goto out;
}
- if (args->size == 0)
- goto out;
-
- if (!access_ok(VERIFY_READ,
- (char __user *)(uintptr_t)args->data_ptr,
- args->size)) {
- ret = -EFAULT;
- goto out;
- }
-
- ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr,
- args->size);
- if (ret) {
- ret = -EFAULT;
- goto out;
- }
-
/* We can only do the GTT pwrite on untiled buffers, as otherwise
* it would end up going through the fenced access, and we'll get
* different detiling behavior between reading and writing.
@@ -2603,7 +2593,7 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj,
if (reg->gpu) {
int ret;
- ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret)
return ret;
@@ -2751,8 +2741,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
/** Flushes any GPU write domain for the object if it's dirty. */
static int
-i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
- bool pipelined)
+i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
uint32_t old_write_domain;
@@ -2771,10 +2760,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj,
obj->read_domains,
old_write_domain);
- if (pipelined)
- return 0;
-
- return i915_gem_object_wait_rendering(obj, true);
+ return 0;
}
/** Flushes the GTT write domain for the object if it's dirty. */
@@ -2835,18 +2821,15 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
if (obj_priv->gtt_space == NULL)
return -EINVAL;
- ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret != 0)
return ret;
+ ret = i915_gem_object_wait_rendering(obj, true);
+ if (ret)
+ return ret;
i915_gem_object_flush_cpu_write_domain(obj);
- if (write) {
- ret = i915_gem_object_wait_rendering(obj, true);
- if (ret)
- return ret;
- }
-
old_write_domain = obj->write_domain;
old_read_domains = obj->read_domains;
@@ -2884,7 +2867,7 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj,
if (obj_priv->gtt_space == NULL)
return -EINVAL;
- ret = i915_gem_object_flush_gpu_write_domain(obj, true);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret)
return ret;
@@ -2907,6 +2890,20 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj,
return 0;
}
+int
+i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj,
+ bool interruptible)
+{
+ if (!obj->active)
+ return 0;
+
+ if (obj->base.write_domain & I915_GEM_GPU_DOMAINS)
+ i915_gem_flush_ring(obj->base.dev, NULL, obj->ring,
+ 0, obj->base.write_domain);
+
+ return i915_gem_object_wait_rendering(&obj->base, interruptible);
+}
+
/**
* Moves a single object to the CPU read, and possibly write domain.
*
@@ -2919,9 +2916,12 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
uint32_t old_write_domain, old_read_domains;
int ret;
- ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret != 0)
return ret;
+ ret = i915_gem_object_wait_rendering(obj, true);
+ if (ret)
+ return ret;
i915_gem_object_flush_gtt_write_domain(obj);
@@ -2930,12 +2930,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
*/
i915_gem_object_set_to_full_cpu_read_domain(obj);
- if (write) {
- ret = i915_gem_object_wait_rendering(obj, true);
- if (ret)
- return ret;
- }
-
old_write_domain = obj->write_domain;
old_read_domains = obj->read_domains;
@@ -3200,9 +3194,13 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
if (offset == 0 && size == obj->size)
return i915_gem_object_set_to_cpu_domain(obj, 0);
- ret = i915_gem_object_flush_gpu_write_domain(obj, false);
+ ret = i915_gem_object_flush_gpu_write_domain(obj);
if (ret != 0)
return ret;
+ ret = i915_gem_object_wait_rendering(obj, true);
+ if (ret)
+ return ret;
+
i915_gem_object_flush_gtt_write_domain(obj);
/* If we're already fully in the CPU read domain, we're done. */
@@ -3249,192 +3247,230 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
return 0;
}
-/**
- * Pin an object to the GTT and evaluate the relocations landing in it.
- */
static int
-i915_gem_execbuffer_relocate(struct drm_i915_gem_object *obj,
- struct drm_file *file_priv,
- struct drm_i915_gem_exec_object2 *entry)
+i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
+ struct drm_file *file_priv,
+ struct drm_i915_gem_exec_object2 *entry,
+ struct drm_i915_gem_relocation_entry *reloc)
{
struct drm_device *dev = obj->base.dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_relocation_entry __user *user_relocs;
- struct drm_gem_object *target_obj = NULL;
- uint32_t target_handle = 0;
- int i, ret = 0;
+ struct drm_gem_object *target_obj;
+ uint32_t target_offset;
+ int ret = -EINVAL;
- user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
- for (i = 0; i < entry->relocation_count; i++) {
- struct drm_i915_gem_relocation_entry reloc;
- uint32_t target_offset;
+ target_obj = drm_gem_object_lookup(dev, file_priv,
+ reloc->target_handle);
+ if (target_obj == NULL)
+ return -ENOENT;
- if (__copy_from_user_inatomic(&reloc,
- user_relocs+i,
- sizeof(reloc))) {
- ret = -EFAULT;
- break;
- }
+ target_offset = to_intel_bo(target_obj)->gtt_offset;
- if (reloc.target_handle != target_handle) {
- drm_gem_object_unreference(target_obj);
+#if WATCH_RELOC
+ DRM_INFO("%s: obj %p offset %08x target %d "
+ "read %08x write %08x gtt %08x "
+ "presumed %08x delta %08x\n",
+ __func__,
+ obj,
+ (int) reloc->offset,
+ (int) reloc->target_handle,
+ (int) reloc->read_domains,
+ (int) reloc->write_domain,
+ (int) target_offset,
+ (int) reloc->presumed_offset,
+ reloc->delta);
+#endif
- target_obj = drm_gem_object_lookup(dev, file_priv,
- reloc.target_handle);
- if (target_obj == NULL) {
- ret = -ENOENT;
- break;
- }
+ /* The target buffer should have appeared before us in the
+ * exec_object list, so it should have a GTT space bound by now.
+ */
+ if (target_offset == 0) {
+ DRM_ERROR("No GTT space found for object %d\n",
+ reloc->target_handle);
+ goto err;
+ }
- target_handle = reloc.target_handle;
- }
- target_offset = to_intel_bo(target_obj)->gtt_offset;
+ /* Validate that the target is in a valid r/w GPU domain */
+ if (reloc->write_domain & (reloc->write_domain - 1)) {
+ DRM_ERROR("reloc with multiple write domains: "
+ "obj %p target %d offset %d "
+ "read %08x write %08x",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->read_domains,
+ reloc->write_domain);
+ goto err;
+ }
+ if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+ reloc->read_domains & I915_GEM_DOMAIN_CPU) {
+ DRM_ERROR("reloc with read/write CPU domains: "
+ "obj %p target %d offset %d "
+ "read %08x write %08x",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->read_domains,
+ reloc->write_domain);
+ goto err;
+ }
+ if (reloc->write_domain && target_obj->pending_write_domain &&
+ reloc->write_domain != target_obj->pending_write_domain) {
+ DRM_ERROR("Write domain conflict: "
+ "obj %p target %d offset %d "
+ "new %08x old %08x\n",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->write_domain,
+ target_obj->pending_write_domain);
+ goto err;
+ }
-#if WATCH_RELOC
- DRM_INFO("%s: obj %p offset %08x target %d "
- "read %08x write %08x gtt %08x "
- "presumed %08x delta %08x\n",
- __func__,
- obj,
- (int) reloc.offset,
- (int) reloc.target_handle,
- (int) reloc.read_domains,
- (int) reloc.write_domain,
- (int) target_offset,
- (int) reloc.presumed_offset,
- reloc.delta);
-#endif
+ target_obj->pending_read_domains |= reloc->read_domains;
+ target_obj->pending_write_domain |= reloc->write_domain;
- /* The target buffer should have appeared before us in the
- * exec_object list, so it should have a GTT space bound by now.
- */
- if (target_offset == 0) {
- DRM_ERROR("No GTT space found for object %d\n",
- reloc.target_handle);
- ret = -EINVAL;
- break;
- }
+ /* If the relocation already has the right value in it, no
+ * more work needs to be done.
+ */
+ if (target_offset == reloc->presumed_offset)
+ goto out;
- /* Validate that the target is in a valid r/w GPU domain */
- if (reloc.write_domain & (reloc.write_domain - 1)) {
- DRM_ERROR("reloc with multiple write domains: "
- "obj %p target %d offset %d "
- "read %08x write %08x",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.read_domains,
- reloc.write_domain);
- ret = -EINVAL;
- break;
- }
- if (reloc.write_domain & I915_GEM_DOMAIN_CPU ||
- reloc.read_domains & I915_GEM_DOMAIN_CPU) {
- DRM_ERROR("reloc with read/write CPU domains: "
- "obj %p target %d offset %d "
- "read %08x write %08x",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.read_domains,
- reloc.write_domain);
- ret = -EINVAL;
- break;
- }
- if (reloc.write_domain && target_obj->pending_write_domain &&
- reloc.write_domain != target_obj->pending_write_domain) {
- DRM_ERROR("Write domain conflict: "
- "obj %p target %d offset %d "
- "new %08x old %08x\n",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.write_domain,
- target_obj->pending_write_domain);
- ret = -EINVAL;
- break;
- }
+ /* Check that the relocation address is valid... */
+ if (reloc->offset > obj->base.size - 4) {
+ DRM_ERROR("Relocation beyond object bounds: "
+ "obj %p target %d offset %d size %d.\n",
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ (int) obj->base.size);
+ goto err;
+ }
+ if (reloc->offset & 3) {
+ DRM_ERROR("Relocation not 4-byte aligned: "
+ "obj %p target %d offset %d.\n",
+ obj, reloc->target_handle,
+ (int) reloc->offset);
+ goto err;
+ }
- target_obj->pending_read_domains |= reloc.read_domains;
- target_obj->pending_write_domain |= reloc.write_domain;
+ /* and points to somewhere within the target object. */
+ if (reloc->delta >= target_obj->size) {
+ DRM_ERROR("Relocation beyond target object bounds: "
+ "obj %p target %d delta %d size %d.\n",
+ obj, reloc->target_handle,
+ (int) reloc->delta,
+ (int) target_obj->size);
+ goto err;
+ }
- /* If the relocation already has the right value in it, no
- * more work needs to be done.
- */
- if (target_offset == reloc.presumed_offset)
- continue;
+ reloc->delta += target_offset;
+ if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
+ uint32_t page_offset = reloc->offset & ~PAGE_MASK;
+ char *vaddr;
- /* Check that the relocation address is valid... */
- if (reloc.offset > obj->base.size - 4) {
- DRM_ERROR("Relocation beyond object bounds: "
- "obj %p target %d offset %d size %d.\n",
- obj, reloc.target_handle,
- (int) reloc.offset, (int) obj->base.size);
- ret = -EINVAL;
- break;
- }
- if (reloc.offset & 3) {
- DRM_ERROR("Relocation not 4-byte aligned: "
- "obj %p target %d offset %d.\n",
- obj, reloc.target_handle,
- (int) reloc.offset);
- ret = -EINVAL;
- break;
- }
+ vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]);
+ *(uint32_t *)(vaddr + page_offset) = reloc->delta;
+ kunmap_atomic(vaddr);
+ } else {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t __iomem *reloc_entry;
+ void __iomem *reloc_page;
- /* and points to somewhere within the target object. */
- if (reloc.delta >= target_obj->size) {
- DRM_ERROR("Relocation beyond target object bounds: "
- "obj %p target %d delta %d size %d.\n",
- obj, reloc.target_handle,
- (int) reloc.delta, (int) target_obj->size);
- ret = -EINVAL;
- break;
- }
+ ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
+ if (ret)
+ goto err;
- reloc.delta += target_offset;
- if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
- uint32_t page_offset = reloc.offset & ~PAGE_MASK;
- char *vaddr;
+ /* Map the page containing the relocation we're going to perform. */
+ reloc->offset += obj->gtt_offset;
+ reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
+ reloc->offset & PAGE_MASK);
+ reloc_entry = (uint32_t __iomem *)
+ (reloc_page + (reloc->offset & ~PAGE_MASK));
+ iowrite32(reloc->delta, reloc_entry);
+ io_mapping_unmap_atomic(reloc_page);
+ }
- vaddr = kmap_atomic(obj->pages[reloc.offset >> PAGE_SHIFT]);
- *(uint32_t *)(vaddr + page_offset) = reloc.delta;
- kunmap_atomic(vaddr);
- } else {
- uint32_t __iomem *reloc_entry;
- void __iomem *reloc_page;
+ /* and update the user's relocation entry */
+ reloc->presumed_offset = target_offset;
- ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1);
- if (ret)
- break;
+out:
+ ret = 0;
+err:
+ drm_gem_object_unreference(target_obj);
+ return ret;
+}
- /* Map the page containing the relocation we're going to perform. */
- reloc.offset += obj->gtt_offset;
- reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
- reloc.offset & PAGE_MASK);
- reloc_entry = (uint32_t __iomem *)
- (reloc_page + (reloc.offset & ~PAGE_MASK));
- iowrite32(reloc.delta, reloc_entry);
- io_mapping_unmap_atomic(reloc_page);
- }
+static int
+i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj,
+ struct drm_file *file_priv,
+ struct drm_i915_gem_exec_object2 *entry)
+{
+ struct drm_i915_gem_relocation_entry __user *user_relocs;
+ int i, ret;
+
+ user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr;
+ for (i = 0; i < entry->relocation_count; i++) {
+ struct drm_i915_gem_relocation_entry reloc;
+
+ if (__copy_from_user_inatomic(&reloc,
+ user_relocs+i,
+ sizeof(reloc)))
+ return -EFAULT;
+
+ ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc);
+ if (ret)
+ return ret;
- /* and update the user's relocation entry */
- reloc.presumed_offset = target_offset;
if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset,
- &reloc.presumed_offset,
- sizeof(reloc.presumed_offset))) {
- ret = -EFAULT;
- break;
- }
+ &reloc.presumed_offset,
+ sizeof(reloc.presumed_offset)))
+ return -EFAULT;
}
- drm_gem_object_unreference(target_obj);
- return ret;
+ return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,
+ struct drm_file *file_priv,
+ struct drm_i915_gem_exec_object2 *entry,
+ struct drm_i915_gem_relocation_entry *relocs)
+{
+ int i, ret;
+
+ for (i = 0; i < entry->relocation_count; i++) {
+ ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int
+i915_gem_execbuffer_relocate(struct drm_device *dev,
+ struct drm_file *file,
+ struct drm_gem_object **object_list,
+ struct drm_i915_gem_exec_object2 *exec_list,
+ int count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+ obj->base.pending_read_domains = 0;
+ obj->base.pending_write_domain = 0;
+ ret = i915_gem_execbuffer_relocate_object(obj, file,
+ &exec_list[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int
-i915_gem_execbuffer_pin(struct drm_device *dev,
- struct drm_file *file,
- struct drm_gem_object **object_list,
- struct drm_i915_gem_exec_object2 *exec_list,
- int count)
+i915_gem_execbuffer_reserve(struct drm_device *dev,
+ struct drm_file *file,
+ struct drm_gem_object **object_list,
+ struct drm_i915_gem_exec_object2 *exec_list,
+ int count)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i, retry;
@@ -3497,6 +3533,87 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
}
static int
+i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
+ struct drm_file *file,
+ struct drm_gem_object **object_list,
+ struct drm_i915_gem_exec_object2 *exec_list,
+ int count)
+{
+ struct drm_i915_gem_relocation_entry *reloc;
+ int i, total, ret;
+
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+ obj->in_execbuffer = false;
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
+ total = 0;
+ for (i = 0; i < count; i++)
+ total += exec_list[i].relocation_count;
+
+ reloc = drm_malloc_ab(total, sizeof(*reloc));
+ if (reloc == NULL) {
+ mutex_lock(&dev->struct_mutex);
+ return -ENOMEM;
+ }
+
+ total = 0;
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_relocation_entry __user *user_relocs;
+
+ user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+ if (copy_from_user(reloc+total, user_relocs,
+ exec_list[i].relocation_count *
+ sizeof(*reloc))) {
+ ret = -EFAULT;
+ mutex_lock(&dev->struct_mutex);
+ goto err;
+ }
+
+ total += exec_list[i].relocation_count;
+ }
+
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret) {
+ mutex_lock(&dev->struct_mutex);
+ goto err;
+ }
+
+ ret = i915_gem_execbuffer_reserve(dev, file,
+ object_list, exec_list,
+ count);
+ if (ret)
+ goto err;
+
+ total = 0;
+ for (i = 0; i < count; i++) {
+ struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
+ obj->base.pending_read_domains = 0;
+ obj->base.pending_write_domain = 0;
+ ret = i915_gem_execbuffer_relocate_object_slow(obj, file,
+ &exec_list[i],
+ reloc + total);
+ if (ret)
+ goto err;
+
+ total += exec_list[i].relocation_count;
+ }
+
+ /* Leave the user relocations as are, this is the painfully slow path,
+ * and we want to avoid the complication of dropping the lock whilst
+ * having buffers reserved in the aperture and so causing spurious
+ * ENOSPC for random operations.
+ */
+
+err:
+ drm_free_large(reloc);
+ return ret;
+}
+
+static int
i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
struct drm_file *file,
struct intel_ring_buffer *ring,
@@ -3625,8 +3742,15 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
for (i = 0; i < count; i++) {
char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr;
- size_t length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry);
+ int length; /* limited by fault_in_pages_readable() */
+ /* First check for malicious input causing overflow */
+ if (exec[i].relocation_count >
+ INT_MAX / sizeof(struct drm_i915_gem_relocation_entry))
+ return -EINVAL;
+
+ length = exec[i].relocation_count *
+ sizeof(struct drm_i915_gem_relocation_entry);
if (!access_ok(VERIFY_READ, ptr, length))
return -EFAULT;
@@ -3769,18 +3893,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}
/* Move the objects en-masse into the GTT, evicting if necessary. */
- ret = i915_gem_execbuffer_pin(dev, file,
- object_list, exec_list,
- args->buffer_count);
+ ret = i915_gem_execbuffer_reserve(dev, file,
+ object_list, exec_list,
+ args->buffer_count);
if (ret)
goto err;
/* The objects are in their final locations, apply the relocations. */
- for (i = 0; i < args->buffer_count; i++) {
- struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]);
- obj->base.pending_read_domains = 0;
- obj->base.pending_write_domain = 0;
- ret = i915_gem_execbuffer_relocate(obj, file, &exec_list[i]);
+ ret = i915_gem_execbuffer_relocate(dev, file,
+ object_list, exec_list,
+ args->buffer_count);
+ if (ret) {
+ if (ret == -EFAULT) {
+ ret = i915_gem_execbuffer_relocate_slow(dev, file,
+ object_list,
+ exec_list,
+ args->buffer_count);
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+ }
if (ret)
goto err;
}
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 454c064f8ef7..42729d25da58 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -239,6 +239,16 @@ static void i915_save_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
+ /* Cursor state */
+ dev_priv->saveCURACNTR = I915_READ(CURACNTR);
+ dev_priv->saveCURAPOS = I915_READ(CURAPOS);
+ dev_priv->saveCURABASE = I915_READ(CURABASE);
+ dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
+ dev_priv->saveCURBPOS = I915_READ(CURBPOS);
+ dev_priv->saveCURBBASE = I915_READ(CURBBASE);
+ if (IS_GEN2(dev))
+ dev_priv->saveCURSIZE = I915_READ(CURSIZE);
+
if (HAS_PCH_SPLIT(dev)) {
dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
@@ -529,6 +539,16 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
+ /* Cursor state */
+ I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
+ I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
+ I915_WRITE(CURABASE, dev_priv->saveCURABASE);
+ I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
+ I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
+ I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
+ if (IS_GEN2(dev))
+ I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
+
return;
}
@@ -543,16 +563,6 @@ void i915_save_display(struct drm_device *dev)
/* Don't save them in KMS mode */
i915_save_modeset_reg(dev);
- /* Cursor state */
- dev_priv->saveCURACNTR = I915_READ(CURACNTR);
- dev_priv->saveCURAPOS = I915_READ(CURAPOS);
- dev_priv->saveCURABASE = I915_READ(CURABASE);
- dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
- dev_priv->saveCURBPOS = I915_READ(CURBPOS);
- dev_priv->saveCURBBASE = I915_READ(CURBBASE);
- if (IS_GEN2(dev))
- dev_priv->saveCURSIZE = I915_READ(CURSIZE);
-
/* CRT state */
if (HAS_PCH_SPLIT(dev)) {
dev_priv->saveADPA = I915_READ(PCH_ADPA);
@@ -657,16 +667,6 @@ void i915_restore_display(struct drm_device *dev)
/* Don't restore them in KMS mode */
i915_restore_modeset_reg(dev);
- /* Cursor state */
- I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
- I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
- I915_WRITE(CURABASE, dev_priv->saveCURABASE);
- I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
- I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
- I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
- if (IS_GEN2(dev))
- I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
-
/* CRT state */
if (HAS_PCH_SPLIT(dev))
I915_WRITE(PCH_ADPA, dev_priv->saveADPA);
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index c55c77043357..8df574316063 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -34,6 +34,25 @@
#include "i915_drm.h"
#include "i915_drv.h"
+/* Here's the desired hotplug mode */
+#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \
+ ADPA_CRT_HOTPLUG_WARMUP_10MS | \
+ ADPA_CRT_HOTPLUG_SAMPLE_4S | \
+ ADPA_CRT_HOTPLUG_VOLTAGE_50 | \
+ ADPA_CRT_HOTPLUG_VOLREF_325MV | \
+ ADPA_CRT_HOTPLUG_ENABLE)
+
+struct intel_crt {
+ struct intel_encoder base;
+ bool force_hotplug_required;
+};
+
+static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
+{
+ return container_of(intel_attached_encoder(connector),
+ struct intel_crt, base);
+}
+
static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
@@ -129,7 +148,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
}
- adpa = 0;
+ adpa = ADPA_HOTPLUG_BITS;
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
adpa |= ADPA_HSYNC_ACTIVE_HIGH;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
@@ -157,53 +176,44 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
+ struct intel_crt *crt = intel_attached_crt(connector);
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 adpa, temp;
+ u32 adpa;
bool ret;
- bool turn_off_dac = false;
- temp = adpa = I915_READ(PCH_ADPA);
+ /* The first time through, trigger an explicit detection cycle */
+ if (crt->force_hotplug_required) {
+ bool turn_off_dac = HAS_PCH_SPLIT(dev);
+ u32 save_adpa;
- if (HAS_PCH_SPLIT(dev))
- turn_off_dac = true;
-
- adpa &= ~ADPA_CRT_HOTPLUG_MASK;
- if (turn_off_dac)
- adpa &= ~ADPA_DAC_ENABLE;
-
- /* disable HPD first */
- I915_WRITE(PCH_ADPA, adpa);
- (void)I915_READ(PCH_ADPA);
-
- adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
- ADPA_CRT_HOTPLUG_WARMUP_10MS |
- ADPA_CRT_HOTPLUG_SAMPLE_4S |
- ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */
- ADPA_CRT_HOTPLUG_VOLREF_325MV |
- ADPA_CRT_HOTPLUG_ENABLE |
- ADPA_CRT_HOTPLUG_FORCE_TRIGGER);
-
- DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa);
- I915_WRITE(PCH_ADPA, adpa);
-
- if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
- 1000))
- DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
-
- if (turn_off_dac) {
- /* Make sure hotplug is enabled */
- I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE);
- (void)I915_READ(PCH_ADPA);
+ crt->force_hotplug_required = 0;
+
+ save_adpa = adpa = I915_READ(PCH_ADPA);
+ DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa);
+
+ adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER;
+ if (turn_off_dac)
+ adpa &= ~ADPA_DAC_ENABLE;
+
+ I915_WRITE(PCH_ADPA, adpa);
+
+ if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0,
+ 1000))
+ DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER");
+
+ if (turn_off_dac) {
+ I915_WRITE(PCH_ADPA, save_adpa);
+ POSTING_READ(PCH_ADPA);
+ }
}
/* Check the status to see if both blue and green are on now */
adpa = I915_READ(PCH_ADPA);
- adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK;
- if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) ||
- (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO))
+ if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0)
ret = true;
else
ret = false;
+ DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret);
return ret;
}
@@ -277,13 +287,12 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus)
return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
}
-static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
+static bool intel_crt_detect_ddc(struct intel_crt *crt)
{
- struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
- struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+ struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
/* CRT should always be at 0, but check anyway */
- if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
+ if (crt->base.type != INTEL_OUTPUT_ANALOG)
return false;
if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) {
@@ -291,7 +300,7 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
return true;
}
- if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) {
+ if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
return true;
}
@@ -300,9 +309,9 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
}
static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt)
{
- struct drm_encoder *encoder = &intel_encoder->base;
+ struct drm_encoder *encoder = &crt->base.base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -434,7 +443,7 @@ static enum drm_connector_status
intel_crt_detect(struct drm_connector *connector, bool force)
{
struct drm_device *dev = connector->dev;
- struct intel_encoder *encoder = intel_attached_encoder(connector);
+ struct intel_crt *crt = intel_attached_crt(connector);
struct drm_crtc *crtc;
int dpms_mode;
enum drm_connector_status status;
@@ -443,28 +452,31 @@ intel_crt_detect(struct drm_connector *connector, bool force)
if (intel_crt_detect_hotplug(connector)) {
DRM_DEBUG_KMS("CRT detected via hotplug\n");
return connector_status_connected;
- } else
+ } else {
+ DRM_DEBUG_KMS("CRT not detected via hotplug\n");
return connector_status_disconnected;
+ }
}
- if (intel_crt_detect_ddc(&encoder->base))
+ if (intel_crt_detect_ddc(crt))
return connector_status_connected;
if (!force)
return connector->status;
/* for pre-945g platforms use load detect */
- if (encoder->base.crtc && encoder->base.crtc->enabled) {
- status = intel_crt_load_detect(encoder->base.crtc, encoder);
+ crtc = crt->base.base.crtc;
+ if (crtc && crtc->enabled) {
+ status = intel_crt_load_detect(crtc, crt);
} else {
- crtc = intel_get_load_detect_pipe(encoder, connector,
+ crtc = intel_get_load_detect_pipe(&crt->base, connector,
NULL, &dpms_mode);
if (crtc) {
- if (intel_crt_detect_ddc(&encoder->base))
+ if (intel_crt_detect_ddc(crt))
status = connector_status_connected;
else
- status = intel_crt_load_detect(crtc, encoder);
- intel_release_load_detect_pipe(encoder,
+ status = intel_crt_load_detect(crtc, crt);
+ intel_release_load_detect_pipe(&crt->base,
connector, dpms_mode);
} else
status = connector_status_unknown;
@@ -536,17 +548,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
- struct intel_encoder *intel_encoder;
+ struct intel_crt *crt;
struct intel_connector *intel_connector;
struct drm_i915_private *dev_priv = dev->dev_private;
- intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
- if (!intel_encoder)
+ crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
+ if (!crt)
return;
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
- kfree(intel_encoder);
+ kfree(crt);
return;
}
@@ -554,20 +566,20 @@ void intel_crt_init(struct drm_device *dev)
drm_connector_init(dev, &intel_connector->base,
&intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
- drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs,
+ drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs,
DRM_MODE_ENCODER_DAC);
- intel_connector_attach_encoder(intel_connector, intel_encoder);
+ intel_connector_attach_encoder(intel_connector, &crt->base);
- intel_encoder->type = INTEL_OUTPUT_ANALOG;
- intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
- (1 << INTEL_ANALOG_CLONE_BIT) |
- (1 << INTEL_SDVO_LVDS_CLONE_BIT);
- intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+ crt->base.type = INTEL_OUTPUT_ANALOG;
+ crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT |
+ 1 << INTEL_ANALOG_CLONE_BIT |
+ 1 << INTEL_SDVO_LVDS_CLONE_BIT);
+ crt->base.crtc_mask = (1 << 0) | (1 << 1);
connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;
- drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs);
+ drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs);
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
drm_sysfs_connector_add(connector);
@@ -577,5 +589,22 @@ void intel_crt_init(struct drm_device *dev)
else
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ /*
+ * Configure the automatic hotplug detection stuff
+ */
+ crt->force_hotplug_required = 0;
+ if (HAS_PCH_SPLIT(dev)) {
+ u32 adpa;
+
+ adpa = I915_READ(PCH_ADPA);
+ adpa &= ~ADPA_CRT_HOTPLUG_MASK;
+ adpa |= ADPA_HOTPLUG_BITS;
+ I915_WRITE(PCH_ADPA, adpa);
+ POSTING_READ(PCH_ADPA);
+
+ DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa);
+ crt->force_hotplug_required = 1;
+ }
+
dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 48d8fd686ea9..255b52ee0091 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1611,6 +1611,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
wait_event(dev_priv->pending_flip_queue,
atomic_read(&obj_priv->pending_flip) == 0);
+
+ /* Big Hammer, we also need to ensure that any pending
+ * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+ * current scanout is retired before unpinning the old
+ * framebuffer.
+ */
+ ret = i915_gem_object_flush_gpu(obj_priv, false);
+ if (ret) {
+ i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
}
ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
@@ -5324,9 +5336,14 @@ static void intel_setup_outputs(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *encoder;
bool dpd_is_edp = false;
+ bool has_lvds = false;
if (IS_MOBILE(dev) && !IS_I830(dev))
- intel_lvds_init(dev);
+ has_lvds = intel_lvds_init(dev);
+ if (!has_lvds && !HAS_PCH_SPLIT(dev)) {
+ /* disable the panel fitter on everything but LVDS */
+ I915_WRITE(PFIT_CONTROL, 0);
+ }
if (HAS_PCH_SPLIT(dev)) {
dpd_is_edp = intel_dpd_is_edp(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c8e005553310..300f64b4238b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -584,17 +584,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode->clock = dev_priv->panel_fixed_mode->clock;
}
- /* Just use VBT values for eDP */
- if (is_edp(intel_dp)) {
- intel_dp->lane_count = dev_priv->edp.lanes;
- intel_dp->link_bw = dev_priv->edp.rate;
- adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
- DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n",
- intel_dp->link_bw, intel_dp->lane_count,
- adjusted_mode->clock);
- return true;
- }
-
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
for (clock = 0; clock <= max_clock; clock++) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
@@ -613,6 +602,19 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
}
}
+ if (is_edp(intel_dp)) {
+ /* okay we failed just pick the highest */
+ intel_dp->lane_count = max_lane_count;
+ intel_dp->link_bw = bws[max_clock];
+ adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw);
+ DRM_DEBUG_KMS("Force picking display port link bw %02x lane "
+ "count %d clock %d\n",
+ intel_dp->link_bw, intel_dp->lane_count,
+ adjusted_mode->clock);
+
+ return true;
+ }
+
return false;
}
@@ -1087,21 +1089,11 @@ intel_get_adjust_train(struct intel_dp *intel_dp)
}
static uint32_t
-intel_dp_signal_levels(struct intel_dp *intel_dp)
+intel_dp_signal_levels(uint8_t train_set, int lane_count)
{
- struct drm_device *dev = intel_dp->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- uint32_t signal_levels = 0;
- u8 train_set = intel_dp->train_set[0];
- u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK;
- u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK;
+ uint32_t signal_levels = 0;
- if (is_edp(intel_dp)) {
- vswing = dev_priv->edp.vswing;
- preemphasis = dev_priv->edp.preemphasis;
- }
-
- switch (vswing) {
+ switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
case DP_TRAIN_VOLTAGE_SWING_400:
default:
signal_levels |= DP_VOLTAGE_0_4;
@@ -1116,7 +1108,7 @@ intel_dp_signal_levels(struct intel_dp *intel_dp)
signal_levels |= DP_VOLTAGE_1_2;
break;
}
- switch (preemphasis) {
+ switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
case DP_TRAIN_PRE_EMPHASIS_0:
default:
signal_levels |= DP_PRE_EMPHASIS_0;
@@ -1203,18 +1195,6 @@ intel_channel_eq_ok(struct intel_dp *intel_dp)
}
static bool
-intel_dp_aux_handshake_required(struct intel_dp *intel_dp)
-{
- struct drm_device *dev = intel_dp->base.base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (is_edp(intel_dp) && dev_priv->no_aux_handshake)
- return false;
-
- return true;
-}
-
-static bool
intel_dp_set_link_train(struct intel_dp *intel_dp,
uint32_t dp_reg_value,
uint8_t dp_train_pat)
@@ -1226,9 +1206,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
I915_WRITE(intel_dp->output_reg, dp_reg_value);
POSTING_READ(intel_dp->output_reg);
- if (!intel_dp_aux_handshake_required(intel_dp))
- return true;
-
intel_dp_aux_native_write_1(intel_dp,
DP_TRAINING_PATTERN_SET,
dp_train_pat);
@@ -1261,11 +1238,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
POSTING_READ(intel_dp->output_reg);
intel_wait_for_vblank(dev, intel_crtc->pipe);
- if (intel_dp_aux_handshake_required(intel_dp))
- /* Write the link configuration data */
- intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
- intel_dp->link_configuration,
- DP_LINK_CONFIGURATION_SIZE);
+ /* Write the link configuration data */
+ intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
+ intel_dp->link_configuration,
+ DP_LINK_CONFIGURATION_SIZE);
DP |= DP_PORT_EN;
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
@@ -1283,7 +1259,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
- signal_levels = intel_dp_signal_levels(intel_dp);
+ signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
@@ -1297,37 +1273,33 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
break;
/* Set training pattern 1 */
- udelay(500);
- if (intel_dp_aux_handshake_required(intel_dp)) {
+ udelay(100);
+ if (!intel_dp_get_link_status(intel_dp))
break;
- } else {
- if (!intel_dp_get_link_status(intel_dp))
- break;
- if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
- clock_recovery = true;
- break;
- }
+ if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
+ clock_recovery = true;
+ break;
+ }
- /* Check to see if we've tried the max voltage */
- for (i = 0; i < intel_dp->lane_count; i++)
- if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
- break;
- if (i == intel_dp->lane_count)
+ /* Check to see if we've tried the max voltage */
+ for (i = 0; i < intel_dp->lane_count; i++)
+ if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
+ if (i == intel_dp->lane_count)
+ break;
- /* Check to see if we've tried the same voltage 5 times */
- if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
- ++tries;
- if (tries == 5)
- break;
- } else
- tries = 0;
- voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+ /* Check to see if we've tried the same voltage 5 times */
+ if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+ ++tries;
+ if (tries == 5)
+ break;
+ } else
+ tries = 0;
+ voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
- /* Compute new intel_dp->train_set as requested by target */
- intel_get_adjust_train(intel_dp);
- }
+ /* Compute new intel_dp->train_set as requested by target */
+ intel_get_adjust_train(intel_dp);
}
intel_dp->DP = DP;
@@ -1354,7 +1326,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
} else {
- signal_levels = intel_dp_signal_levels(intel_dp);
+ signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count);
DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
}
@@ -1368,28 +1340,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
DP_TRAINING_PATTERN_2))
break;
- udelay(500);
-
- if (!intel_dp_aux_handshake_required(intel_dp)) {
+ udelay(400);
+ if (!intel_dp_get_link_status(intel_dp))
break;
- } else {
- if (!intel_dp_get_link_status(intel_dp))
- break;
- if (intel_channel_eq_ok(intel_dp)) {
- channel_eq = true;
- break;
- }
+ if (intel_channel_eq_ok(intel_dp)) {
+ channel_eq = true;
+ break;
+ }
- /* Try 5 times */
- if (tries > 5)
- break;
+ /* Try 5 times */
+ if (tries > 5)
+ break;
- /* Compute new intel_dp->train_set as requested by target */
- intel_get_adjust_train(intel_dp);
- ++tries;
- }
+ /* Compute new intel_dp->train_set as requested by target */
+ intel_get_adjust_train(intel_dp);
+ ++tries;
}
+
if (HAS_PCH_CPT(dev) && !is_edp(intel_dp))
reg = DP | DP_LINK_TRAIN_OFF_CPT;
else
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 21551fe74541..e52c6125bb1f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -237,7 +237,7 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
extern void intel_dvo_init(struct drm_device *dev);
extern void intel_tv_init(struct drm_device *dev);
extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
-extern void intel_lvds_init(struct drm_device *dev);
+extern bool intel_lvds_init(struct drm_device *dev);
extern void intel_dp_init(struct drm_device *dev, int dp_reg);
void
intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 2be4f728ed0c..3dba086e7eea 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -160,7 +160,7 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin)
};
struct intel_gpio *gpio;
- if (pin < 1 || pin > 7)
+ if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin])
return NULL;
gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL);
@@ -172,7 +172,8 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin)
gpio->reg += PCH_GPIOA - GPIOA;
gpio->dev_priv = dev_priv;
- snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO%c", "?BACDEF?"[pin]);
+ snprintf(gpio->adapter.name, sizeof(gpio->adapter.name),
+ "i915 GPIO%c", "?BACDE?F"[pin]);
gpio->adapter.owner = THIS_MODULE;
gpio->adapter.algo_data = &gpio->algo;
gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev;
@@ -349,7 +350,7 @@ int intel_setup_gmbus(struct drm_device *dev)
"panel",
"dpc",
"dpb",
- "reserved"
+ "reserved",
"dpd",
};
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -366,8 +367,8 @@ int intel_setup_gmbus(struct drm_device *dev)
bus->adapter.owner = THIS_MODULE;
bus->adapter.class = I2C_CLASS_DDC;
snprintf(bus->adapter.name,
- I2C_NAME_SIZE,
- "gmbus %s",
+ sizeof(bus->adapter.name),
+ "i915 gmbus %s",
names[i]);
bus->adapter.dev.parent = &dev->pdev->dev;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 4324a326f98e..f79327fc6653 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -837,7 +837,7 @@ static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin)
* Create the connector, register the LVDS DDC bus, and try to figure out what
* modes we can display on the LVDS panel (if present).
*/
-void intel_lvds_init(struct drm_device *dev)
+bool intel_lvds_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_lvds *intel_lvds;
@@ -853,37 +853,37 @@ void intel_lvds_init(struct drm_device *dev)
/* Skip init on machines we know falsely report LVDS */
if (dmi_check_system(intel_no_lvds))
- return;
+ return false;
pin = GMBUS_PORT_PANEL;
if (!lvds_is_present_in_vbt(dev, &pin)) {
DRM_DEBUG_KMS("LVDS is not present in VBT\n");
- return;
+ return false;
}
if (HAS_PCH_SPLIT(dev)) {
if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
- return;
+ return false;
if (dev_priv->edp.support) {
DRM_DEBUG_KMS("disable LVDS for eDP support\n");
- return;
+ return false;
}
}
if (!intel_lvds_ddc_probe(dev, pin)) {
DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n");
- return;
+ return false;
}
intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL);
if (!intel_lvds) {
- return;
+ return false;
}
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_lvds);
- return;
+ return false;
}
if (!HAS_PCH_SPLIT(dev)) {
@@ -1026,7 +1026,7 @@ out:
/* keep the LVDS connector */
dev_priv->int_lvds_connector = connector;
drm_sysfs_connector_add(connector);
- return;
+ return true;
failed:
DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
@@ -1034,4 +1034,5 @@ failed:
drm_encoder_cleanup(encoder);
kfree(intel_lvds);
kfree(intel_connector);
+ return false;
}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index de158b76bcd5..d97e6cb52d34 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -107,7 +107,8 @@ struct intel_sdvo {
* This is set if we treat the device as HDMI, instead of DVI.
*/
bool is_hdmi;
- bool has_audio;
+ bool has_hdmi_monitor;
+ bool has_hdmi_audio;
/**
* This is set if we detect output of sdvo device as LVDS and
@@ -1023,7 +1024,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
if (!intel_sdvo_set_target_input(intel_sdvo))
return;
- if (intel_sdvo->is_hdmi &&
+ if (intel_sdvo->has_hdmi_monitor &&
!intel_sdvo_set_avi_infoframe(intel_sdvo))
return;
@@ -1063,7 +1064,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
}
if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
- if (intel_sdvo->has_audio)
+ if (intel_sdvo->has_hdmi_audio)
sdvox |= SDVO_AUDIO_ENABLE;
if (INTEL_INFO(dev)->gen >= 4) {
@@ -1295,55 +1296,14 @@ intel_sdvo_get_edid(struct drm_connector *connector)
return drm_get_edid(connector, &sdvo->ddc);
}
-static struct drm_connector *
-intel_find_analog_connector(struct drm_device *dev)
-{
- struct drm_connector *connector;
- struct intel_sdvo *encoder;
-
- list_for_each_entry(encoder,
- &dev->mode_config.encoder_list,
- base.base.head) {
- if (encoder->base.type == INTEL_OUTPUT_ANALOG) {
- list_for_each_entry(connector,
- &dev->mode_config.connector_list,
- head) {
- if (&encoder->base ==
- intel_attached_encoder(connector))
- return connector;
- }
- }
- }
-
- return NULL;
-}
-
-static int
-intel_analog_is_connected(struct drm_device *dev)
-{
- struct drm_connector *analog_connector;
-
- analog_connector = intel_find_analog_connector(dev);
- if (!analog_connector)
- return false;
-
- if (analog_connector->funcs->detect(analog_connector, false) ==
- connector_status_disconnected)
- return false;
-
- return true;
-}
-
/* Mac mini hack -- use the same DDC as the analog connector */
static struct edid *
intel_sdvo_get_analog_edid(struct drm_connector *connector)
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
- if (!intel_analog_is_connected(connector->dev))
- return NULL;
-
- return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
+ return drm_get_edid(connector,
+ &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
}
enum drm_connector_status
@@ -1388,8 +1348,10 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
/* DDC bus is shared, match EDID to connector type */
if (edid->input & DRM_EDID_INPUT_DIGITAL) {
status = connector_status_connected;
- intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid);
- intel_sdvo->has_audio = drm_detect_monitor_audio(edid);
+ if (intel_sdvo->is_hdmi) {
+ intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
+ intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
+ }
}
connector->display_info.raw_edid = NULL;
kfree(edid);
@@ -1398,7 +1360,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
if (status == connector_status_connected) {
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
if (intel_sdvo_connector->force_audio)
- intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0;
+ intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0;
}
return status;
@@ -1415,10 +1377,12 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
if (!intel_sdvo_write_cmd(intel_sdvo,
SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0))
return connector_status_unknown;
- if (intel_sdvo->is_tv) {
- /* add 30ms delay when the output type is SDVO-TV */
+
+ /* add 30ms delay when the output type might be TV */
+ if (intel_sdvo->caps.output_flags &
+ (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0))
mdelay(30);
- }
+
if (!intel_sdvo_read_response(intel_sdvo, &response, 2))
return connector_status_unknown;
@@ -1472,8 +1436,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
edid = intel_sdvo_get_analog_edid(connector);
if (edid != NULL) {
- drm_mode_connector_update_edid_property(connector, edid);
- drm_add_edid_modes(connector, edid);
+ if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+ drm_mode_connector_update_edid_property(connector, edid);
+ drm_add_edid_modes(connector, edid);
+ }
connector->display_info.raw_edid = NULL;
kfree(edid);
}
@@ -1713,12 +1679,12 @@ intel_sdvo_set_property(struct drm_connector *connector,
intel_sdvo_connector->force_audio = val;
- if (val > 0 && intel_sdvo->has_audio)
+ if (val > 0 && intel_sdvo->has_hdmi_audio)
return 0;
- if (val < 0 && !intel_sdvo->has_audio)
+ if (val < 0 && !intel_sdvo->has_hdmi_audio)
return 0;
- intel_sdvo->has_audio = val > 0;
+ intel_sdvo->has_hdmi_audio = val > 0;
goto done;
}
@@ -2070,6 +2036,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_set_colorimetry(intel_sdvo,
SDVO_COLORIMETRY_RGB256);
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+
+ intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
intel_sdvo->is_hdmi = true;
}
intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
@@ -2077,8 +2045,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
- intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
-
return true;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index 406228f4a2a0..b14c81110575 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -31,6 +31,7 @@
*/
#include <linux/backlight.h>
+#include <linux/acpi.h>
#include "drmP.h"
#include "nouveau_drv.h"
@@ -136,6 +137,14 @@ int nouveau_backlight_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+#ifdef CONFIG_ACPI
+ if (acpi_video_backlight_support()) {
+ NV_INFO(dev, "ACPI backlight interface available, "
+ "not registering our own\n");
+ return 0;
+ }
+#endif
+
switch (dev_priv->card_type) {
case NV_40:
return nouveau_nv40_backlight_init(dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 5f21030a293b..b2293576f278 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -6829,7 +6829,7 @@ nouveau_bios_posted(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
unsigned htotal;
- if (dev_priv->chipset >= NV_50) {
+ if (dev_priv->card_type >= NV_50) {
if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
NVReadVgaCrtc(dev, 0, 0x1a) == 0)
return false;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 80353e2b8409..c41e1c200ef5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -143,8 +143,10 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
nvbo->no_vm = no_vm;
nvbo->tile_mode = tile_mode;
nvbo->tile_flags = tile_flags;
+ nvbo->bo.bdev = &dev_priv->ttm.bdev;
- nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size);
+ nouveau_bo_fixup_align(dev, tile_mode, nouveau_bo_tile_layout(nvbo),
+ &align, &size);
align >>= PAGE_SHIFT;
nouveau_bo_placement_set(nvbo, flags, 0);
@@ -176,6 +178,31 @@ set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
}
+static void
+set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
+{
+ struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
+
+ if (dev_priv->card_type == NV_10 &&
+ nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) {
+ /*
+ * Make sure that the color and depth buffers are handled
+ * by independent memory controller units. Up to a 9x
+ * speed up when alpha-blending and depth-test are enabled
+ * at the same time.
+ */
+ int vram_pages = dev_priv->vram_size >> PAGE_SHIFT;
+
+ if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) {
+ nvbo->placement.fpfn = vram_pages / 2;
+ nvbo->placement.lpfn = ~0;
+ } else {
+ nvbo->placement.fpfn = 0;
+ nvbo->placement.lpfn = vram_pages / 2;
+ }
+ }
+}
+
void
nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
{
@@ -190,6 +217,8 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
pl->busy_placement = nvbo->busy_placements;
set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
type | busy, flags);
+
+ set_placement_range(nvbo, type);
}
int
@@ -525,7 +554,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
stride = 16 * 4;
height = amount / stride;
- if (new_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) {
+ if (new_mem->mem_type == TTM_PL_VRAM &&
+ nouveau_bo_tile_layout(nvbo)) {
ret = RING_SPACE(chan, 8);
if (ret)
return ret;
@@ -546,7 +576,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
BEGIN_RING(chan, NvSubM2MF, 0x0200, 1);
OUT_RING (chan, 1);
}
- if (old_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) {
+ if (old_mem->mem_type == TTM_PL_VRAM &&
+ nouveau_bo_tile_layout(nvbo)) {
ret = RING_SPACE(chan, 8);
if (ret)
return ret;
@@ -753,7 +784,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
if (dev_priv->card_type == NV_50) {
ret = nv50_mem_vm_bind_linear(dev,
offset + dev_priv->vm_vram_base,
- new_mem->size, nvbo->tile_flags,
+ new_mem->size,
+ nouveau_bo_tile_layout(nvbo),
offset);
if (ret)
return ret;
@@ -894,7 +926,8 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
* nothing to do here.
*/
if (bo->mem.mem_type != TTM_PL_VRAM) {
- if (dev_priv->card_type < NV_50 || !nvbo->tile_flags)
+ if (dev_priv->card_type < NV_50 ||
+ !nouveau_bo_tile_layout(nvbo))
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 0871495096fa..52c356e9a3d1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -281,7 +281,7 @@ detect_analog:
nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
if (!nv_encoder && !nouveau_tv_disable)
nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
- if (nv_encoder) {
+ if (nv_encoder && force) {
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
struct drm_encoder_helper_funcs *helper =
encoder->helper_private;
@@ -641,11 +641,28 @@ nouveau_connector_get_modes(struct drm_connector *connector)
return ret;
}
+static unsigned
+get_tmds_link_bandwidth(struct drm_connector *connector)
+{
+ struct nouveau_connector *nv_connector = nouveau_connector(connector);
+ struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
+ struct dcb_entry *dcb = nv_connector->detected_encoder->dcb;
+
+ if (dcb->location != DCB_LOC_ON_CHIP ||
+ dev_priv->chipset >= 0x46)
+ return 165000;
+ else if (dev_priv->chipset >= 0x40)
+ return 155000;
+ else if (dev_priv->chipset >= 0x18)
+ return 135000;
+ else
+ return 112000;
+}
+
static int
nouveau_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
@@ -663,11 +680,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
max_clock = 400000;
break;
case OUTPUT_TMDS:
- if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
- !nv_encoder->dcb->duallink_possible)
- max_clock = 165000;
- else
- max_clock = 330000;
+ max_clock = get_tmds_link_bandwidth(connector);
+ if (nouveau_duallink && nv_encoder->dcb->duallink_possible)
+ max_clock *= 2;
break;
case OUTPUT_ANALOG:
max_clock = nv_encoder->dcb->crtconf.maxfreq;
@@ -709,44 +724,6 @@ nouveau_connector_best_encoder(struct drm_connector *connector)
return NULL;
}
-void
-nouveau_connector_set_polling(struct drm_connector *connector)
-{
- struct drm_device *dev = connector->dev;
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc;
- bool spare_crtc = false;
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- spare_crtc |= !crtc->enabled;
-
- connector->polled = 0;
-
- switch (connector->connector_type) {
- case DRM_MODE_CONNECTOR_VGA:
- case DRM_MODE_CONNECTOR_TV:
- if (dev_priv->card_type >= NV_50 ||
- (nv_gf4_disp_arch(dev) && spare_crtc))
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
- break;
-
- case DRM_MODE_CONNECTOR_DVII:
- case DRM_MODE_CONNECTOR_DVID:
- case DRM_MODE_CONNECTOR_HDMIA:
- case DRM_MODE_CONNECTOR_DisplayPort:
- case DRM_MODE_CONNECTOR_eDP:
- if (dev_priv->card_type >= NV_50)
- connector->polled = DRM_CONNECTOR_POLL_HPD;
- else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
- spare_crtc)
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
- break;
-
- default:
- break;
- }
-}
-
static const struct drm_connector_helper_funcs
nouveau_connector_helper_funcs = {
.get_modes = nouveau_connector_get_modes,
@@ -872,6 +849,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
dev->mode_config.scaling_mode_property,
nv_connector->scaling_mode);
}
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT;
/* fall-through */
case DCB_CONNECTOR_TV_0:
case DCB_CONNECTOR_TV_1:
@@ -888,11 +866,16 @@ nouveau_connector_create(struct drm_device *dev, int index)
dev->mode_config.dithering_mode_property,
nv_connector->use_dithering ?
DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
+
+ if (dcb->type != DCB_CONNECTOR_LVDS) {
+ if (dev_priv->card_type >= NV_50)
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
+ else
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ }
break;
}
- nouveau_connector_set_polling(connector);
-
drm_sysfs_connector_add(connector);
dcb->drm = connector;
return dcb->drm;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index c21ed6b16f88..711b1e9203af 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -52,9 +52,6 @@ static inline struct nouveau_connector *nouveau_connector(
struct drm_connector *
nouveau_connector_create(struct drm_device *, int index);
-void
-nouveau_connector_set_polling(struct drm_connector *);
-
int
nouveau_connector_bpp(struct drm_connector *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 3a07e580d27a..1c7db64c03bf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -100,6 +100,9 @@ struct nouveau_bo {
int pin_refcnt;
};
+#define nouveau_bo_tile_layout(nvbo) \
+ ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)
+
static inline struct nouveau_bo *
nouveau_bo(struct ttm_buffer_object *bo)
{
@@ -304,6 +307,7 @@ struct nouveau_fifo_engine {
void (*destroy_context)(struct nouveau_channel *);
int (*load_context)(struct nouveau_channel *);
int (*unload_context)(struct drm_device *);
+ void (*tlb_flush)(struct drm_device *dev);
};
struct nouveau_pgraph_object_method {
@@ -336,6 +340,7 @@ struct nouveau_pgraph_engine {
void (*destroy_context)(struct nouveau_channel *);
int (*load_context)(struct nouveau_channel *);
int (*unload_context)(struct drm_device *);
+ void (*tlb_flush)(struct drm_device *dev);
void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr,
uint32_t size, uint32_t pitch);
@@ -485,13 +490,13 @@ enum nv04_fp_display_regs {
};
struct nv04_crtc_reg {
- unsigned char MiscOutReg; /* */
+ unsigned char MiscOutReg;
uint8_t CRTC[0xa0];
uint8_t CR58[0x10];
uint8_t Sequencer[5];
uint8_t Graphics[9];
uint8_t Attribute[21];
- unsigned char DAC[768]; /* Internal Colorlookuptable */
+ unsigned char DAC[768];
/* PCRTC regs */
uint32_t fb_start;
@@ -539,43 +544,9 @@ struct nv04_output_reg {
};
struct nv04_mode_state {
- uint32_t bpp;
- uint32_t width;
- uint32_t height;
- uint32_t interlace;
- uint32_t repaint0;
- uint32_t repaint1;
- uint32_t screen;
- uint32_t scale;
- uint32_t dither;
- uint32_t extra;
- uint32_t fifo;
- uint32_t pixel;
- uint32_t horiz;
- int arbitration0;
- int arbitration1;
- uint32_t pll;
- uint32_t pllB;
- uint32_t vpll;
- uint32_t vpll2;
- uint32_t vpllB;
- uint32_t vpll2B;
+ struct nv04_crtc_reg crtc_reg[2];
uint32_t pllsel;
uint32_t sel_clk;
- uint32_t general;
- uint32_t crtcOwner;
- uint32_t head;
- uint32_t head2;
- uint32_t cursorConfig;
- uint32_t cursor0;
- uint32_t cursor1;
- uint32_t cursor2;
- uint32_t timingH;
- uint32_t timingV;
- uint32_t displayV;
- uint32_t crtcSync;
-
- struct nv04_crtc_reg crtc_reg[2];
};
enum nouveau_card_type {
@@ -613,6 +584,12 @@ struct drm_nouveau_private {
struct work_struct irq_work;
struct work_struct hpd_work;
+ struct {
+ spinlock_t lock;
+ uint32_t hpd0_bits;
+ uint32_t hpd1_bits;
+ } hpd_state;
+
struct list_head vbl_waiting;
struct {
@@ -1045,6 +1022,7 @@ extern int nv50_fifo_create_context(struct nouveau_channel *);
extern void nv50_fifo_destroy_context(struct nouveau_channel *);
extern int nv50_fifo_load_context(struct nouveau_channel *);
extern int nv50_fifo_unload_context(struct drm_device *);
+extern void nv50_fifo_tlb_flush(struct drm_device *dev);
/* nvc0_fifo.c */
extern int nvc0_fifo_init(struct drm_device *);
@@ -1122,6 +1100,8 @@ extern int nv50_graph_load_context(struct nouveau_channel *);
extern int nv50_graph_unload_context(struct drm_device *);
extern void nv50_graph_context_switch(struct drm_device *);
extern int nv50_grctx_init(struct nouveau_grctx *);
+extern void nv50_graph_tlb_flush(struct drm_device *dev);
+extern void nv86_graph_tlb_flush(struct drm_device *dev);
/* nvc0_graph.c */
extern int nvc0_graph_init(struct drm_device *);
@@ -1239,7 +1219,6 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val);
-extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *);
/* nouveau_fence.c */
struct nouveau_fence;
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 441b12420bb1..ab1bbfbf266e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -249,6 +249,7 @@ alloc_semaphore(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_semaphore *sema;
+ int ret;
if (!USE_SEMA(dev))
return NULL;
@@ -257,10 +258,14 @@ alloc_semaphore(struct drm_device *dev)
if (!sema)
goto fail;
+ ret = drm_mm_pre_get(&dev_priv->fence.heap);
+ if (ret)
+ goto fail;
+
spin_lock(&dev_priv->fence.lock);
sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0);
if (sema->mem)
- sema->mem = drm_mm_get_block(sema->mem, 4, 0);
+ sema->mem = drm_mm_get_block_atomic(sema->mem, 4, 0);
spin_unlock(&dev_priv->fence.lock);
if (!sema->mem)
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 5c4c929d7f74..9a1fdcf400c2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -107,23 +107,29 @@ nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep)
}
static bool
-nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) {
- switch (tile_flags) {
- case 0x0000:
- case 0x1800:
- case 0x2800:
- case 0x4800:
- case 0x7000:
- case 0x7400:
- case 0x7a00:
- case 0xe000:
- break;
- default:
- NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
- return false;
+nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->card_type >= NV_50) {
+ switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) {
+ case 0x0000:
+ case 0x1800:
+ case 0x2800:
+ case 0x4800:
+ case 0x7000:
+ case 0x7400:
+ case 0x7a00:
+ case 0xe000:
+ return true;
+ }
+ } else {
+ if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))
+ return true;
}
- return true;
+ NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags);
+ return false;
}
int
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
index bed669a54a2d..b9672a05c411 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
@@ -519,11 +519,11 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
struct pll_lims pll_lim;
struct nouveau_pll_vals pv;
- uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF;
+ enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0;
- if (get_pll_limits(dev, pllreg, &pll_lim))
+ if (get_pll_limits(dev, pll, &pll_lim))
return;
- nouveau_hw_get_pllvals(dev, pllreg, &pv);
+ nouveau_hw_get_pllvals(dev, pll, &pv);
if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
@@ -536,7 +536,7 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
pv.M1 = pll_lim.vco1.max_m;
pv.N1 = pll_lim.vco1.min_n;
pv.log2P = pll_lim.max_usable_log2p;
- nouveau_hw_setpll(dev, pllreg, &pv);
+ nouveau_hw_setpll(dev, pll_lim.reg, &pv);
}
/*
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h
index 869130f83602..2989090b9434 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.h
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.h
@@ -416,6 +416,25 @@ nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
}
static inline void
+nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ NVWriteCRTC(dev, head, NV_PCRTC_START, offset);
+
+ if (dev_priv->card_type == NV_04) {
+ /*
+ * Hilarious, the 24th bit doesn't want to stick to
+ * PCRTC_START...
+ */
+ int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX);
+
+ NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX,
+ (cre_heb & ~0x40) | ((offset >> 18) & 0x40));
+ }
+}
+
+static inline void
nv_show_cursor(struct drm_device *dev, int head, bool show)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
index fdd7e3de79c8..cb389d014326 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -256,7 +256,7 @@ nouveau_i2c_find(struct drm_device *dev, int index)
if (index >= DCB_MAX_NUM_I2C_ENTRIES)
return NULL;
- if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) {
+ if (dev_priv->card_type >= NV_50 && (i2c->entry & 0x00000100)) {
uint32_t reg = 0xe500, val;
if (i2c->port_type == 6) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index 6fd51a51c608..7bfd9e6c9d67 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -42,6 +42,13 @@
#include "nouveau_connector.h"
#include "nv50_display.h"
+static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
+
+static int nouveau_ratelimit(void)
+{
+ return __ratelimit(&nouveau_ratelimit_state);
+}
+
void
nouveau_irq_preinstall(struct drm_device *dev)
{
@@ -53,6 +60,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
if (dev_priv->card_type >= NV_50) {
INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
+ spin_lock_init(&dev_priv->hpd_state.lock);
INIT_LIST_HEAD(&dev_priv->vbl_waiting);
}
}
@@ -202,8 +210,8 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
}
if (status & NV_PFIFO_INTR_DMA_PUSHER) {
- u32 get = nv_rd32(dev, 0x003244);
- u32 put = nv_rd32(dev, 0x003240);
+ u32 dma_get = nv_rd32(dev, 0x003244);
+ u32 dma_put = nv_rd32(dev, 0x003240);
u32 push = nv_rd32(dev, 0x003220);
u32 state = nv_rd32(dev, 0x003228);
@@ -213,16 +221,18 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
u32 ib_get = nv_rd32(dev, 0x003334);
u32 ib_put = nv_rd32(dev, 0x003330);
- NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
+ if (nouveau_ratelimit())
+ NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x "
"Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x "
"State 0x%08x Push 0x%08x\n",
- chid, ho_get, get, ho_put, put, ib_get, ib_put,
- state, push);
+ chid, ho_get, dma_get, ho_put,
+ dma_put, ib_get, ib_put, state,
+ push);
/* METHOD_COUNT, in DMA_STATE on earlier chipsets */
nv_wr32(dev, 0x003364, 0x00000000);
- if (get != put || ho_get != ho_put) {
- nv_wr32(dev, 0x003244, put);
+ if (dma_get != dma_put || ho_get != ho_put) {
+ nv_wr32(dev, 0x003244, dma_put);
nv_wr32(dev, 0x003328, ho_put);
} else
if (ib_get != ib_put) {
@@ -231,10 +241,10 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
} else {
NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x "
"Put 0x%08x State 0x%08x Push 0x%08x\n",
- chid, get, put, state, push);
+ chid, dma_get, dma_put, state, push);
- if (get != put)
- nv_wr32(dev, 0x003244, put);
+ if (dma_get != dma_put)
+ nv_wr32(dev, 0x003244, dma_put);
}
nv_wr32(dev, 0x003228, 0x00000000);
@@ -266,8 +276,9 @@ nouveau_fifo_irq_handler(struct drm_device *dev)
}
if (status) {
- NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
- status, chid);
+ if (nouveau_ratelimit())
+ NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n",
+ status, chid);
nv_wr32(dev, NV03_PFIFO_INTR_0, status);
status = 0;
}
@@ -544,13 +555,6 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource)
nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap);
}
-static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
-
-static int nouveau_ratelimit(void)
-{
- return __ratelimit(&nouveau_ratelimit_state);
-}
-
static inline void
nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource)
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index a163c7c612e7..fe4a30dc4b42 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -33,9 +33,9 @@
#include "drmP.h"
#include "drm.h"
#include "drm_sarea.h"
-#include "nouveau_drv.h"
-#define MIN(a,b) a < b ? a : b
+#include "nouveau_drv.h"
+#include "nouveau_pm.h"
/*
* NV10-NV40 tiling helpers
@@ -175,11 +175,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
}
}
}
- dev_priv->engine.instmem.flush(dev);
- nv50_vm_flush(dev, 5);
- nv50_vm_flush(dev, 0);
- nv50_vm_flush(dev, 4);
+ dev_priv->engine.instmem.flush(dev);
+ dev_priv->engine.fifo.tlb_flush(dev);
+ dev_priv->engine.graph.tlb_flush(dev);
nv50_vm_flush(dev, 6);
return 0;
}
@@ -209,11 +208,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
pte++;
}
}
- dev_priv->engine.instmem.flush(dev);
- nv50_vm_flush(dev, 5);
- nv50_vm_flush(dev, 0);
- nv50_vm_flush(dev, 4);
+ dev_priv->engine.instmem.flush(dev);
+ dev_priv->engine.fifo.tlb_flush(dev);
+ dev_priv->engine.graph.tlb_flush(dev);
nv50_vm_flush(dev, 6);
}
@@ -653,6 +651,7 @@ nouveau_mem_gart_init(struct drm_device *dev)
void
nouveau_mem_timing_init(struct drm_device *dev)
{
+ /* cards < NVC0 only */
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
struct nouveau_pm_memtimings *memtimings = &pm->memtimings;
@@ -719,14 +718,14 @@ nouveau_mem_timing_init(struct drm_device *dev)
tUNK_19 = 1;
tUNK_20 = 0;
tUNK_21 = 0;
- switch (MIN(recordlen,21)) {
- case 21:
+ switch (min(recordlen, 22)) {
+ case 22:
tUNK_21 = entry[21];
- case 20:
+ case 21:
tUNK_20 = entry[20];
- case 19:
+ case 20:
tUNK_19 = entry[19];
- case 18:
+ case 19:
tUNK_18 = entry[18];
default:
tUNK_0 = entry[0];
@@ -756,24 +755,30 @@ nouveau_mem_timing_init(struct drm_device *dev)
timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
if(recordlen > 19) {
timing->reg_100228 += (tUNK_19 - 1) << 24;
- } else {
+ }/* I cannot back-up this else-statement right now
+ else {
timing->reg_100228 += tUNK_12 << 24;
- }
+ }*/
/* XXX: reg_10022c */
+ timing->reg_10022c = tUNK_2 - 1;
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
tUNK_13 << 8 | tUNK_13);
/* XXX: +6? */
timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC);
- if(tUNK_10 > tUNK_11) {
- timing->reg_100234 += tUNK_10 << 16;
- } else {
- timing->reg_100234 += tUNK_11 << 16;
+ timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
+
+ /* XXX; reg_100238, reg_10023c
+ * reg: 0x00??????
+ * reg_10023c:
+ * 0 for pre-NV50 cards
+ * 0x????0202 for NV50+ cards (empirical evidence) */
+ if(dev_priv->card_type >= NV_50) {
+ timing->reg_10023c = 0x202;
}
- /* XXX; reg_100238, reg_10023c */
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
timing->reg_100220, timing->reg_100224,
timing->reg_100228, timing->reg_10022c);
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index 896cf8634144..dd572adca02a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -129,7 +129,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
if (ramin == NULL) {
spin_unlock(&dev_priv->ramin_lock);
nouveau_gpuobj_ref(NULL, &gpuobj);
- return ret;
+ return -ENOMEM;
}
ramin = drm_mm_get_block_atomic(ramin, size, align);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 1c99c55d6d46..9f7b158f5825 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -284,6 +284,7 @@ nouveau_sysfs_fini(struct drm_device *dev)
}
}
+#ifdef CONFIG_HWMON
static ssize_t
nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
{
@@ -395,10 +396,12 @@ static struct attribute *hwmon_attributes[] = {
static const struct attribute_group hwmon_attrgroup = {
.attrs = hwmon_attributes,
};
+#endif
static int
nouveau_hwmon_init(struct drm_device *dev)
{
+#ifdef CONFIG_HWMON
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
struct device *hwmon_dev;
@@ -425,13 +428,14 @@ nouveau_hwmon_init(struct drm_device *dev)
}
pm->hwmon = hwmon_dev;
-
+#endif
return 0;
}
static void
nouveau_hwmon_fini(struct drm_device *dev)
{
+#ifdef CONFIG_HWMON
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
@@ -439,6 +443,7 @@ nouveau_hwmon_fini(struct drm_device *dev)
sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup);
hwmon_device_unregister(pm->hwmon);
}
+#endif
}
int
diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c
index 7f16697cc96c..2d8580927ca4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ramht.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c
@@ -153,26 +153,42 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle,
return -ENOMEM;
}
+static struct nouveau_ramht_entry *
+nouveau_ramht_remove_entry(struct nouveau_channel *chan, u32 handle)
+{
+ struct nouveau_ramht *ramht = chan ? chan->ramht : NULL;
+ struct nouveau_ramht_entry *entry;
+ unsigned long flags;
+
+ if (!ramht)
+ return NULL;
+
+ spin_lock_irqsave(&ramht->lock, flags);
+ list_for_each_entry(entry, &ramht->entries, head) {
+ if (entry->channel == chan &&
+ (!handle || entry->handle == handle)) {
+ list_del(&entry->head);
+ spin_unlock_irqrestore(&ramht->lock, flags);
+
+ return entry;
+ }
+ }
+ spin_unlock_irqrestore(&ramht->lock, flags);
+
+ return NULL;
+}
+
static void
-nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
+nouveau_ramht_remove_hash(struct nouveau_channel *chan, u32 handle)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
struct nouveau_gpuobj *ramht = chan->ramht->gpuobj;
- struct nouveau_ramht_entry *entry, *tmp;
+ unsigned long flags;
u32 co, ho;
- list_for_each_entry_safe(entry, tmp, &chan->ramht->entries, head) {
- if (entry->channel != chan || entry->handle != handle)
- continue;
-
- nouveau_gpuobj_ref(NULL, &entry->gpuobj);
- list_del(&entry->head);
- kfree(entry);
- break;
- }
-
+ spin_lock_irqsave(&chan->ramht->lock, flags);
co = ho = nouveau_ramht_hash_handle(chan, handle);
do {
if (nouveau_ramht_entry_valid(dev, ramht, co) &&
@@ -184,7 +200,7 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
nv_wo32(ramht, co + 0, 0x00000000);
nv_wo32(ramht, co + 4, 0x00000000);
instmem->flush(dev);
- return;
+ goto out;
}
co += 8;
@@ -194,17 +210,22 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle)
NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
chan->id, handle);
+out:
+ spin_unlock_irqrestore(&chan->ramht->lock, flags);
}
void
nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle)
{
- struct nouveau_ramht *ramht = chan->ramht;
- unsigned long flags;
+ struct nouveau_ramht_entry *entry;
- spin_lock_irqsave(&ramht->lock, flags);
- nouveau_ramht_remove_locked(chan, handle);
- spin_unlock_irqrestore(&ramht->lock, flags);
+ entry = nouveau_ramht_remove_entry(chan, handle);
+ if (!entry)
+ return;
+
+ nouveau_ramht_remove_hash(chan, entry->handle);
+ nouveau_gpuobj_ref(NULL, &entry->gpuobj);
+ kfree(entry);
}
struct nouveau_gpuobj *
@@ -265,23 +286,19 @@ void
nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr,
struct nouveau_channel *chan)
{
- struct nouveau_ramht_entry *entry, *tmp;
+ struct nouveau_ramht_entry *entry;
struct nouveau_ramht *ramht;
- unsigned long flags;
if (ref)
kref_get(&ref->refcount);
ramht = *ptr;
if (ramht) {
- spin_lock_irqsave(&ramht->lock, flags);
- list_for_each_entry_safe(entry, tmp, &ramht->entries, head) {
- if (entry->channel != chan)
- continue;
-
- nouveau_ramht_remove_locked(chan, entry->handle);
+ while ((entry = nouveau_ramht_remove_entry(chan, 0))) {
+ nouveau_ramht_remove_hash(chan, entry->handle);
+ nouveau_gpuobj_ref(NULL, &entry->gpuobj);
+ kfree(entry);
}
- spin_unlock_irqrestore(&ramht->lock, flags);
kref_put(&ramht->refcount, nouveau_ramht_del);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index 288bacac7e5a..d4ac97007038 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -120,8 +120,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
dev_priv->engine.instmem.flush(nvbe->dev);
if (dev_priv->card_type == NV_50) {
- nv50_vm_flush(dev, 5); /* PGRAPH */
- nv50_vm_flush(dev, 0); /* PFIFO */
+ dev_priv->engine.fifo.tlb_flush(dev);
+ dev_priv->engine.graph.tlb_flush(dev);
}
nvbe->bound = true;
@@ -162,8 +162,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
dev_priv->engine.instmem.flush(nvbe->dev);
if (dev_priv->card_type == NV_50) {
- nv50_vm_flush(dev, 5);
- nv50_vm_flush(dev, 0);
+ dev_priv->engine.fifo.tlb_flush(dev);
+ dev_priv->engine.graph.tlb_flush(dev);
}
nvbe->bound = false;
@@ -224,7 +224,11 @@ nouveau_sgdma_init(struct drm_device *dev)
int i, ret;
if (dev_priv->card_type < NV_50) {
- aper_size = (64 * 1024 * 1024);
+ if(dev_priv->ramin_rsvd_vram < 2 * 1024 * 1024)
+ aper_size = 64 * 1024 * 1024;
+ else
+ aper_size = 512 * 1024 * 1024;
+
obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4;
obj_size += 8; /* ctxdma header */
} else {
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index ed7757f14083..049f755567e5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -354,6 +354,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->graph.destroy_context = nv50_graph_destroy_context;
engine->graph.load_context = nv50_graph_load_context;
engine->graph.unload_context = nv50_graph_unload_context;
+ if (dev_priv->chipset != 0x86)
+ engine->graph.tlb_flush = nv50_graph_tlb_flush;
+ else {
+ /* from what i can see nvidia do this on every
+ * pre-NVA3 board except NVAC, but, we've only
+ * ever seen problems on NV86
+ */
+ engine->graph.tlb_flush = nv86_graph_tlb_flush;
+ }
engine->fifo.channels = 128;
engine->fifo.init = nv50_fifo_init;
engine->fifo.takedown = nv50_fifo_takedown;
@@ -365,6 +374,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.destroy_context = nv50_fifo_destroy_context;
engine->fifo.load_context = nv50_fifo_load_context;
engine->fifo.unload_context = nv50_fifo_unload_context;
+ engine->fifo.tlb_flush = nv50_fifo_tlb_flush;
engine->display.early_init = nv50_display_early_init;
engine->display.late_takedown = nv50_display_late_takedown;
engine->display.create = nv50_display_create;
@@ -1041,6 +1051,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
case NOUVEAU_GETPARAM_PTIMER_TIME:
getparam->value = dev_priv->engine.timer.read(dev);
break;
+ case NOUVEAU_GETPARAM_HAS_BO_USAGE:
+ getparam->value = 1;
+ break;
case NOUVEAU_GETPARAM_GRAPH_UNITS:
/* NV40 and NV50 versions are quite different, but register
* address is the same. User is supposed to know the card
@@ -1051,7 +1064,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
}
/* FALLTHRU */
default:
- NV_ERROR(dev, "unknown parameter %lld\n", getparam->param);
+ NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param);
return -EINVAL;
}
@@ -1066,7 +1079,7 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
switch (setparam->param) {
default:
- NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
+ NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c
index 16bbbf1eff63..7ecc4adc1e45 100644
--- a/drivers/gpu/drm/nouveau/nouveau_temp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_temp.c
@@ -191,7 +191,7 @@ nv40_temp_get(struct drm_device *dev)
int offset = sensor->offset_mult / sensor->offset_div;
int core_temp;
- if (dev_priv->chipset >= 0x50) {
+ if (dev_priv->card_type >= NV_50) {
core_temp = nv_rd32(dev, 0x20008);
} else {
core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff;
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index c71abc2a34d5..40e180741629 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -158,7 +158,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = crtc->dev;
- struct drm_connector *connector;
unsigned char seq1 = 0, crtc17 = 0;
unsigned char crtc1A;
@@ -213,10 +212,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
NVVgaSeqReset(dev, nv_crtc->index, false);
NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
-
- /* Update connector polling modes */
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- nouveau_connector_set_polling(connector);
}
static bool
@@ -831,7 +826,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
/* Update the framebuffer location. */
regp->fb_start = nv_crtc->fb.offset & ~3;
regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8);
- NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start);
+ nv_set_crtc_base(dev, nv_crtc->index, regp->fb_start);
/* Update the arbitration parameters. */
nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel,
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
index c936403b26e2..ef23550407b5 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -185,14 +185,15 @@ static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder,
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder);
- /* For internal panels and gpu scaling on DVI we need the native mode */
- if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
- if (!nv_connector->native_mode)
- return false;
+ if (!nv_connector->native_mode ||
+ nv_connector->scaling_mode == DRM_MODE_SCALE_NONE ||
+ mode->hdisplay > nv_connector->native_mode->hdisplay ||
+ mode->vdisplay > nv_connector->native_mode->vdisplay) {
+ nv_encoder->mode = *adjusted_mode;
+
+ } else {
nv_encoder->mode = *nv_connector->native_mode;
adjusted_mode->clock = nv_connector->native_mode->clock;
- } else {
- nv_encoder->mode = *adjusted_mode;
}
return true;
diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c
index 6a6eb697d38e..eb1c70dd82ed 100644
--- a/drivers/gpu/drm/nouveau/nv04_pm.c
+++ b/drivers/gpu/drm/nouveau/nv04_pm.c
@@ -76,6 +76,15 @@ nv04_pm_clock_set(struct drm_device *dev, void *pre_state)
reg += 4;
nouveau_hw_setpll(dev, reg, &state->calc);
+
+ if (dev_priv->card_type < NV_30 && reg == NV_PRAMDAC_MPLL_COEFF) {
+ if (dev_priv->card_type == NV_20)
+ nv_mask(dev, 0x1002c4, 0, 1 << 20);
+
+ /* Reset the DLLs */
+ nv_mask(dev, 0x1002c0, 0, 1 << 8);
+ }
+
kfree(state);
}
diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c
index 2cdc2bfe7179..de81151648f8 100644
--- a/drivers/gpu/drm/nouveau/nv50_calc.c
+++ b/drivers/gpu/drm/nouveau/nv50_calc.c
@@ -51,24 +51,28 @@ nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk,
int *N, int *fN, int *M, int *P)
{
fixed20_12 fb_div, a, b;
+ u32 refclk = pll->refclk / 10;
+ u32 max_vco_freq = pll->vco1.maxfreq / 10;
+ u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10;
+ clk /= 10;
- *P = pll->vco1.maxfreq / clk;
+ *P = max_vco_freq / clk;
if (*P > pll->max_p)
*P = pll->max_p;
if (*P < pll->min_p)
*P = pll->min_p;
- /* *M = ceil(refclk / pll->vco.max_inputfreq); */
- a.full = dfixed_const(pll->refclk);
- b.full = dfixed_const(pll->vco1.max_inputfreq);
+ /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */
+ a.full = dfixed_const(refclk + max_vco_inputfreq);
+ b.full = dfixed_const(max_vco_inputfreq);
a.full = dfixed_div(a, b);
- a.full = dfixed_ceil(a);
+ a.full = dfixed_floor(a);
*M = dfixed_trunc(a);
/* fb_div = (vco * *M) / refclk; */
fb_div.full = dfixed_const(clk * *P);
fb_div.full = dfixed_mul(fb_div, a);
- a.full = dfixed_const(pll->refclk);
+ a.full = dfixed_const(refclk);
fb_div.full = dfixed_div(fb_div, a);
/* *N = floor(fb_div); */
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 16380d52cd88..56476d0c6de8 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -546,7 +546,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
}
nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
- nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
+ nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo);
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) {
ret = RING_SPACE(evo, 2);
@@ -578,7 +578,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
fb->nvbo->tile_mode);
}
if (dev_priv->chipset == 0x50)
- OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format);
+ OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format);
else
OUT_RING(evo, format);
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 55c9663ef2bf..f624c611ddea 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1032,11 +1032,18 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
struct drm_connector *connector;
const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
uint32_t unplug_mask, plug_mask, change_mask;
- uint32_t hpd0, hpd1 = 0;
+ uint32_t hpd0, hpd1;
- hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
+ spin_lock_irq(&dev_priv->hpd_state.lock);
+ hpd0 = dev_priv->hpd_state.hpd0_bits;
+ dev_priv->hpd_state.hpd0_bits = 0;
+ hpd1 = dev_priv->hpd_state.hpd1_bits;
+ dev_priv->hpd_state.hpd1_bits = 0;
+ spin_unlock_irq(&dev_priv->hpd_state.lock);
+
+ hpd0 &= nv_rd32(dev, 0xe050);
if (dev_priv->chipset >= 0x90)
- hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070);
+ hpd1 &= nv_rd32(dev, 0xe070);
plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16);
unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000);
@@ -1078,10 +1085,6 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
}
- nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
- if (dev_priv->chipset >= 0x90)
- nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
-
drm_helper_hpd_irq_event(dev);
}
@@ -1092,8 +1095,22 @@ nv50_display_irq_handler(struct drm_device *dev)
uint32_t delayed = 0;
if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
- if (!work_pending(&dev_priv->hpd_work))
- queue_work(dev_priv->wq, &dev_priv->hpd_work);
+ uint32_t hpd0_bits, hpd1_bits = 0;
+
+ hpd0_bits = nv_rd32(dev, 0xe054);
+ nv_wr32(dev, 0xe054, hpd0_bits);
+
+ if (dev_priv->chipset >= 0x90) {
+ hpd1_bits = nv_rd32(dev, 0xe074);
+ nv_wr32(dev, 0xe074, hpd1_bits);
+ }
+
+ spin_lock(&dev_priv->hpd_state.lock);
+ dev_priv->hpd_state.hpd0_bits |= hpd0_bits;
+ dev_priv->hpd_state.hpd1_bits |= hpd1_bits;
+ spin_unlock(&dev_priv->hpd_state.lock);
+
+ queue_work(dev_priv->wq, &dev_priv->hpd_work);
}
while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
index a46a961102f3..1da65bd60c10 100644
--- a/drivers/gpu/drm/nouveau/nv50_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
@@ -464,3 +464,8 @@ nv50_fifo_unload_context(struct drm_device *dev)
return 0;
}
+void
+nv50_fifo_tlb_flush(struct drm_device *dev)
+{
+ nv50_vm_flush(dev, 5);
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index cbf5ae2f67d4..8b669d0af610 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -402,3 +402,55 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
{ 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
{}
};
+
+void
+nv50_graph_tlb_flush(struct drm_device *dev)
+{
+ nv50_vm_flush(dev, 0);
+}
+
+void
+nv86_graph_tlb_flush(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
+ bool idle, timeout = false;
+ unsigned long flags;
+ u64 start;
+ u32 tmp;
+
+ spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+ nv_mask(dev, 0x400500, 0x00000001, 0x00000000);
+
+ start = ptimer->read(dev);
+ do {
+ idle = true;
+
+ for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) {
+ if ((tmp & 7) == 1)
+ idle = false;
+ }
+
+ for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) {
+ if ((tmp & 7) == 1)
+ idle = false;
+ }
+
+ for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) {
+ if ((tmp & 7) == 1)
+ idle = false;
+ }
+ } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000));
+
+ if (timeout) {
+ NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: "
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380),
+ nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388));
+ }
+
+ nv50_vm_flush(dev, 0);
+
+ nv_mask(dev, 0x400500, 0x00000001, 0x00000001);
+ spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+}
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index a53fc974332b..b773229b7647 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -402,7 +402,6 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
}
dev_priv->engine.instmem.flush(dev);
- nv50_vm_flush(dev, 4);
nv50_vm_flush(dev, 6);
gpuobj->im_bound = 1;
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index 8e421f644a54..05efb5b9f13e 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -112,6 +112,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
base += 3;
break;
case ATOM_IIO_WRITE:
+ (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
base += 3;
break;
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 488c36c8f5e6..4dc5b4714c5a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1650,7 +1650,36 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
}
}
- rdev->config.evergreen.tile_config = gb_addr_config;
+ /* setup tiling info dword. gb_addr_config is not adequate since it does
+ * not have bank info, so create a custom tiling dword.
+ * bits 3:0 num_pipes
+ * bits 7:4 num_banks
+ * bits 11:8 group_size
+ * bits 15:12 row_size
+ */
+ rdev->config.evergreen.tile_config = 0;
+ switch (rdev->config.evergreen.max_tile_pipes) {
+ case 1:
+ default:
+ rdev->config.evergreen.tile_config |= (0 << 0);
+ break;
+ case 2:
+ rdev->config.evergreen.tile_config |= (1 << 0);
+ break;
+ case 4:
+ rdev->config.evergreen.tile_config |= (2 << 0);
+ break;
+ case 8:
+ rdev->config.evergreen.tile_config |= (3 << 0);
+ break;
+ }
+ rdev->config.evergreen.tile_config |=
+ ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
+ rdev->config.evergreen.tile_config |=
+ ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8;
+ rdev->config.evergreen.tile_config |=
+ ((gb_addr_config & 0x30000000) >> 28) << 12;
+
WREG32(GB_BACKEND_MAP, gb_backend_map);
WREG32(GB_ADDR_CONFIG, gb_addr_config);
WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index ac3b6dde23db..e0e590110dd4 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -459,7 +459,7 @@ int evergreen_blit_init(struct radeon_device *rdev)
obj_size += evergreen_ps_size * 4;
obj_size = ALIGN(obj_size, 256);
- r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+ r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
&rdev->r600_blit.shader_obj);
if (r) {
DRM_ERROR("evergreen failed to allocate shader\n");
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 0f806cc7dc75..a3552594ccc4 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2718,7 +2718,7 @@ static int r600_ih_ring_alloc(struct radeon_device *rdev)
/* Allocate ring buffer */
if (rdev->ih.ring_obj == NULL) {
r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
- true,
+ PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT,
&rdev->ih.ring_obj);
if (r) {
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index 8362974ef41a..86e5aa07f0db 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -501,7 +501,7 @@ int r600_blit_init(struct radeon_device *rdev)
obj_size += r6xx_ps_size * 4;
obj_size = ALIGN(obj_size, 256);
- r = radeon_bo_create(rdev, NULL, obj_size, true, RADEON_GEM_DOMAIN_VRAM,
+ r = radeon_bo_create(rdev, NULL, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
&rdev->r600_blit.shader_obj);
if (r) {
DRM_ERROR("r600 failed to allocate shader\n");
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 37cc2aa9f923..0f90fc3482ce 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -50,6 +50,7 @@ struct r600_cs_track {
u32 nsamples;
u32 cb_color_base_last[8];
struct radeon_bo *cb_color_bo[8];
+ u64 cb_color_bo_mc[8];
u32 cb_color_bo_offset[8];
struct radeon_bo *cb_color_frag_bo[8];
struct radeon_bo *cb_color_tile_bo[8];
@@ -67,6 +68,7 @@ struct r600_cs_track {
u32 db_depth_size;
u32 db_offset;
struct radeon_bo *db_bo;
+ u64 db_bo_mc;
};
static inline int r600_bpe_from_format(u32 *bpe, u32 format)
@@ -140,6 +142,68 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format)
return 0;
}
+struct array_mode_checker {
+ int array_mode;
+ u32 group_size;
+ u32 nbanks;
+ u32 npipes;
+ u32 nsamples;
+ u32 bpe;
+};
+
+/* returns alignment in pixels for pitch/height/depth and bytes for base */
+static inline int r600_get_array_mode_alignment(struct array_mode_checker *values,
+ u32 *pitch_align,
+ u32 *height_align,
+ u32 *depth_align,
+ u64 *base_align)
+{
+ u32 tile_width = 8;
+ u32 tile_height = 8;
+ u32 macro_tile_width = values->nbanks;
+ u32 macro_tile_height = values->npipes;
+ u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples;
+ u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes;
+
+ switch (values->array_mode) {
+ case ARRAY_LINEAR_GENERAL:
+ /* technically tile_width/_height for pitch/height */
+ *pitch_align = 1; /* tile_width */
+ *height_align = 1; /* tile_height */
+ *depth_align = 1;
+ *base_align = 1;
+ break;
+ case ARRAY_LINEAR_ALIGNED:
+ *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe));
+ *height_align = tile_height;
+ *depth_align = 1;
+ *base_align = values->group_size;
+ break;
+ case ARRAY_1D_TILED_THIN1:
+ *pitch_align = max((u32)tile_width,
+ (u32)(values->group_size /
+ (tile_height * values->bpe * values->nsamples)));
+ *height_align = tile_height;
+ *depth_align = 1;
+ *base_align = values->group_size;
+ break;
+ case ARRAY_2D_TILED_THIN1:
+ *pitch_align = max((u32)macro_tile_width,
+ (u32)(((values->group_size / tile_height) /
+ (values->bpe * values->nsamples)) *
+ values->nbanks)) * tile_width;
+ *height_align = macro_tile_height * tile_height;
+ *depth_align = 1;
+ *base_align = max(macro_tile_bytes,
+ (*pitch_align) * values->bpe * (*height_align) * values->nsamples);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void r600_cs_track_init(struct r600_cs_track *track)
{
int i;
@@ -153,10 +217,12 @@ static void r600_cs_track_init(struct r600_cs_track *track)
track->cb_color_info[i] = 0;
track->cb_color_bo[i] = NULL;
track->cb_color_bo_offset[i] = 0xFFFFFFFF;
+ track->cb_color_bo_mc[i] = 0xFFFFFFFF;
}
track->cb_target_mask = 0xFFFFFFFF;
track->cb_shader_mask = 0xFFFFFFFF;
track->db_bo = NULL;
+ track->db_bo_mc = 0xFFFFFFFF;
/* assume the biggest format and that htile is enabled */
track->db_depth_info = 7 | (1 << 25);
track->db_depth_view = 0xFFFFC000;
@@ -168,7 +234,10 @@ static void r600_cs_track_init(struct r600_cs_track *track)
static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
{
struct r600_cs_track *track = p->track;
- u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align;
+ u32 bpe = 0, slice_tile_max, size, tmp;
+ u32 height, height_align, pitch, pitch_align, depth_align;
+ u64 base_offset, base_align;
+ struct array_mode_checker array_check;
volatile u32 *ib = p->ib->ptr;
unsigned array_mode;
@@ -183,60 +252,40 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
i, track->cb_color_info[i]);
return -EINVAL;
}
- /* pitch is the number of 8x8 tiles per row */
- pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1;
+ /* pitch in pixels */
+ pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8;
slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1;
slice_tile_max *= 64;
- height = slice_tile_max / (pitch * 8);
+ height = slice_tile_max / pitch;
if (height > 8192)
height = 8192;
array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]);
+
+ base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i];
+ array_check.array_mode = array_mode;
+ array_check.group_size = track->group_size;
+ array_check.nbanks = track->nbanks;
+ array_check.npipes = track->npipes;
+ array_check.nsamples = track->nsamples;
+ array_check.bpe = bpe;
+ if (r600_get_array_mode_alignment(&array_check,
+ &pitch_align, &height_align, &depth_align, &base_align)) {
+ dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
+ G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i,
+ track->cb_color_info[i]);
+ return -EINVAL;
+ }
switch (array_mode) {
case V_0280A0_ARRAY_LINEAR_GENERAL:
- /* technically height & 0x7 */
break;
case V_0280A0_ARRAY_LINEAR_ALIGNED:
- pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
- if (!IS_ALIGNED(height, 8)) {
- dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
- __func__, __LINE__, height);
- return -EINVAL;
- }
break;
case V_0280A0_ARRAY_1D_TILED_THIN1:
- pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8;
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
/* avoid breaking userspace */
if (height > 7)
height &= ~0x7;
- if (!IS_ALIGNED(height, 8)) {
- dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
- __func__, __LINE__, height);
- return -EINVAL;
- }
break;
case V_0280A0_ARRAY_2D_TILED_THIN1:
- pitch_align = max((u32)track->nbanks,
- (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8;
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
- if (!IS_ALIGNED((height / 8), track->npipes)) {
- dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
- __func__, __LINE__, height);
- return -EINVAL;
- }
break;
default:
dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@@ -244,8 +293,24 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
track->cb_color_info[i]);
return -EINVAL;
}
+
+ if (!IS_ALIGNED(pitch, pitch_align)) {
+ dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n",
+ __func__, __LINE__, pitch);
+ return -EINVAL;
+ }
+ if (!IS_ALIGNED(height, height_align)) {
+ dev_warn(p->dev, "%s:%d cb height (%d) invalid\n",
+ __func__, __LINE__, height);
+ return -EINVAL;
+ }
+ if (!IS_ALIGNED(base_offset, base_align)) {
+ dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+ return -EINVAL;
+ }
+
/* check offset */
- tmp = height * pitch * 8 * bpe;
+ tmp = height * pitch * bpe;
if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
/* the initial DDX does bad things with the CB size occasionally */
@@ -260,15 +325,11 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
return -EINVAL;
}
}
- if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) {
- dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]);
- return -EINVAL;
- }
/* limit max tile */
- tmp = (height * pitch * 8) >> 6;
+ tmp = (height * pitch) >> 6;
if (tmp < slice_tile_max)
slice_tile_max = tmp;
- tmp = S_028060_PITCH_TILE_MAX(pitch - 1) |
+ tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |
S_028060_SLICE_TILE_MAX(slice_tile_max - 1);
ib[track->cb_color_size_idx[i]] = tmp;
return 0;
@@ -310,7 +371,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
/* Check depth buffer */
if (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
G_028800_Z_ENABLE(track->db_depth_control)) {
- u32 nviews, bpe, ntiles, pitch, pitch_align, height, size, slice_tile_max;
+ u32 nviews, bpe, ntiles, size, slice_tile_max;
+ u32 height, height_align, pitch, pitch_align, depth_align;
+ u64 base_offset, base_align;
+ struct array_mode_checker array_check;
+ int array_mode;
+
if (track->db_bo == NULL) {
dev_warn(p->dev, "z/stencil with no depth buffer\n");
return -EINVAL;
@@ -353,41 +419,34 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
} else {
size = radeon_bo_size(track->db_bo);
- pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1;
+ /* pitch in pixels */
+ pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
slice_tile_max *= 64;
- height = slice_tile_max / (pitch * 8);
+ height = slice_tile_max / pitch;
if (height > 8192)
height = 8192;
- switch (G_028010_ARRAY_MODE(track->db_depth_info)) {
+ base_offset = track->db_bo_mc + track->db_offset;
+ array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
+ array_check.array_mode = array_mode;
+ array_check.group_size = track->group_size;
+ array_check.nbanks = track->nbanks;
+ array_check.npipes = track->npipes;
+ array_check.nsamples = track->nsamples;
+ array_check.bpe = bpe;
+ if (r600_get_array_mode_alignment(&array_check,
+ &pitch_align, &height_align, &depth_align, &base_align)) {
+ dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
+ G_028010_ARRAY_MODE(track->db_depth_info),
+ track->db_depth_info);
+ return -EINVAL;
+ }
+ switch (array_mode) {
case V_028010_ARRAY_1D_TILED_THIN1:
- pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8);
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
/* don't break userspace */
height &= ~0x7;
- if (!IS_ALIGNED(height, 8)) {
- dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
- __func__, __LINE__, height);
- return -EINVAL;
- }
break;
case V_028010_ARRAY_2D_TILED_THIN1:
- pitch_align = max((u32)track->nbanks,
- (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
- if (!IS_ALIGNED((height / 8), track->npipes)) {
- dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
- __func__, __LINE__, height);
- return -EINVAL;
- }
break;
default:
dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
@@ -395,15 +454,27 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
track->db_depth_info);
return -EINVAL;
}
- if (!IS_ALIGNED(track->db_offset, track->group_size)) {
- dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset);
+
+ if (!IS_ALIGNED(pitch, pitch_align)) {
+ dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n",
+ __func__, __LINE__, pitch);
+ return -EINVAL;
+ }
+ if (!IS_ALIGNED(height, height_align)) {
+ dev_warn(p->dev, "%s:%d db height (%d) invalid\n",
+ __func__, __LINE__, height);
return -EINVAL;
}
+ if (!IS_ALIGNED(base_offset, base_align)) {
+ dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset);
+ return -EINVAL;
+ }
+
ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
tmp = ntiles * bpe * 64 * nviews;
if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
- dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n",
+ dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n",
track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
radeon_bo_size(track->db_bo));
return -EINVAL;
@@ -954,6 +1025,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
track->cb_color_base_last[tmp] = ib[idx];
track->cb_color_bo[tmp] = reloc->robj;
+ track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset;
break;
case DB_DEPTH_BASE:
r = r600_cs_packet_next_reloc(p, &reloc);
@@ -965,6 +1037,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
track->db_offset = radeon_get_ib_value(p, idx) << 8;
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
track->db_bo = reloc->robj;
+ track->db_bo_mc = reloc->lobj.gpu_offset;
break;
case DB_HTILE_DATA_BASE:
case SQ_PGM_START_FS:
@@ -1086,16 +1159,25 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
struct radeon_bo *texture,
struct radeon_bo *mipmap,
+ u64 base_offset,
+ u64 mip_offset,
u32 tiling_flags)
{
struct r600_cs_track *track = p->track;
u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0;
- u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align;
+ u32 word0, word1, l0_size, mipmap_size;
+ u32 height_align, pitch, pitch_align, depth_align;
+ u64 base_align;
+ struct array_mode_checker array_check;
/* on legacy kernel we don't perform advanced check */
if (p->rdev == NULL)
return 0;
+ /* convert to bytes */
+ base_offset <<= 8;
+ mip_offset <<= 8;
+
word0 = radeon_get_ib_value(p, idx + 0);
if (tiling_flags & RADEON_TILING_MACRO)
word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
@@ -1128,46 +1210,38 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i
return -EINVAL;
}
- pitch = G_038000_PITCH(word0) + 1;
- switch (G_038000_TILE_MODE(word0)) {
- case V_038000_ARRAY_LINEAR_GENERAL:
- pitch_align = 1;
- /* XXX check height align */
- break;
- case V_038000_ARRAY_LINEAR_ALIGNED:
- pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8;
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
- /* XXX check height align */
- break;
- case V_038000_ARRAY_1D_TILED_THIN1:
- pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8;
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
- /* XXX check height align */
- break;
- case V_038000_ARRAY_2D_TILED_THIN1:
- pitch_align = max((u32)track->nbanks,
- (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8;
- if (!IS_ALIGNED(pitch, pitch_align)) {
- dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
- __func__, __LINE__, pitch);
- return -EINVAL;
- }
- /* XXX check height align */
- break;
- default:
- dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
- G_038000_TILE_MODE(word0), word0);
+ /* pitch in texels */
+ pitch = (G_038000_PITCH(word0) + 1) * 8;
+ array_check.array_mode = G_038000_TILE_MODE(word0);
+ array_check.group_size = track->group_size;
+ array_check.nbanks = track->nbanks;
+ array_check.npipes = track->npipes;
+ array_check.nsamples = 1;
+ array_check.bpe = bpe;
+ if (r600_get_array_mode_alignment(&array_check,
+ &pitch_align, &height_align, &depth_align, &base_align)) {
+ dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
+ __func__, __LINE__, G_038000_TILE_MODE(word0));
+ return -EINVAL;
+ }
+
+ /* XXX check height as well... */
+
+ if (!IS_ALIGNED(pitch, pitch_align)) {
+ dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n",
+ __func__, __LINE__, pitch);
+ return -EINVAL;
+ }
+ if (!IS_ALIGNED(base_offset, base_align)) {
+ dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n",
+ __func__, __LINE__, base_offset);
+ return -EINVAL;
+ }
+ if (!IS_ALIGNED(mip_offset, base_align)) {
+ dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n",
+ __func__, __LINE__, mip_offset);
return -EINVAL;
}
- /* XXX check offset align */
word0 = radeon_get_ib_value(p, idx + 4);
word1 = radeon_get_ib_value(p, idx + 5);
@@ -1402,7 +1476,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
mipmap = reloc->robj;
r = r600_check_texture_resource(p, idx+(i*7)+1,
- texture, mipmap, reloc->lobj.tiling_flags);
+ texture, mipmap,
+ base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2),
+ mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3),
+ reloc->lobj.tiling_flags);
if (r)
return r;
ib[idx+1+(i*7)+2] += base_offset;
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h
index d84612ae47e0..33cda016b083 100644
--- a/drivers/gpu/drm/radeon/r600_reg.h
+++ b/drivers/gpu/drm/radeon/r600_reg.h
@@ -86,6 +86,7 @@
#define R600_HDP_NONSURFACE_BASE 0x2c04
#define R600_BUS_CNTL 0x5420
+# define R600_BIOS_ROM_DIS (1 << 1)
#define R600_CONFIG_CNTL 0x5424
#define R600_CONFIG_MEMSIZE 0x5428
#define R600_CONFIG_F0_BASE 0x542C
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 966a793e225b..bff4dc4f410f 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -51,6 +51,12 @@
#define PTE_READABLE (1 << 5)
#define PTE_WRITEABLE (1 << 6)
+/* tiling bits */
+#define ARRAY_LINEAR_GENERAL 0x00000000
+#define ARRAY_LINEAR_ALIGNED 0x00000001
+#define ARRAY_1D_TILED_THIN1 0x00000002
+#define ARRAY_2D_TILED_THIN1 0x00000004
+
/* Registers */
#define ARB_POP 0x2418
#define ENABLE_TC128 (1 << 30)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 73f600d39ad4..3a7095743d44 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1262,6 +1262,10 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
(rdev->family == CHIP_RS400) || \
(rdev->family == CHIP_RS480))
#define ASIC_IS_AVIVO(rdev) ((rdev->family >= CHIP_RS600))
+#define ASIC_IS_DCE2(rdev) ((rdev->family == CHIP_RS600) || \
+ (rdev->family == CHIP_RS690) || \
+ (rdev->family == CHIP_RS740) || \
+ (rdev->family >= CHIP_R600))
#define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
#define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
#define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 87ead090c7d5..bc5a2c3382d9 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -98,6 +98,14 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
}
}
+ /* some DCE3 boards have bad data for this entry */
+ if (ASIC_IS_DCE3(rdev)) {
+ if ((i == 4) &&
+ (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+ (gpio->sucI2cId.ucAccess == 0x94))
+ gpio->sucI2cId.ucAccess = 0x14;
+ }
+
if (gpio->sucI2cId.ucAccess == id) {
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
@@ -174,6 +182,14 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev)
}
}
+ /* some DCE3 boards have bad data for this entry */
+ if (ASIC_IS_DCE3(rdev)) {
+ if ((i == 4) &&
+ (gpio->usClkMaskRegisterIndex == 0x1fda) &&
+ (gpio->sucI2cId.ucAccess == 0x94))
+ gpio->sucI2cId.ucAccess = 0x14;
+ }
+
i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4;
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 7932dc4d6b90..c558685cc637 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -41,7 +41,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
size = bsize;
n = 1024;
- r = radeon_bo_create(rdev, NULL, size, true, sdomain, &sobj);
+ r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, sdomain, &sobj);
if (r) {
goto out_cleanup;
}
@@ -53,7 +53,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize,
if (r) {
goto out_cleanup;
}
- r = radeon_bo_create(rdev, NULL, size, true, ddomain, &dobj);
+ r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, ddomain, &dobj);
if (r) {
goto out_cleanup;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 654787ec43f4..8f2c7b50dcf5 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -130,6 +130,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
return true;
}
+
static bool r700_read_disabled_bios(struct radeon_device *rdev)
{
uint32_t viph_control;
@@ -143,7 +144,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
bool r;
viph_control = RREG32(RADEON_VIPH_CONTROL);
- bus_cntl = RREG32(RADEON_BUS_CNTL);
+ bus_cntl = RREG32(R600_BUS_CNTL);
d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -152,7 +153,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
/* disable VIP */
WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
/* enable the rom */
- WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+ WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
/* Disable VGA mode */
WREG32(AVIVO_D1VGA_CONTROL,
(d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -191,7 +192,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
cg_spll_status = RREG32(R600_CG_SPLL_STATUS);
}
WREG32(RADEON_VIPH_CONTROL, viph_control);
- WREG32(RADEON_BUS_CNTL, bus_cntl);
+ WREG32(R600_BUS_CNTL, bus_cntl);
WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
@@ -216,7 +217,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
bool r;
viph_control = RREG32(RADEON_VIPH_CONTROL);
- bus_cntl = RREG32(RADEON_BUS_CNTL);
+ bus_cntl = RREG32(R600_BUS_CNTL);
d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
@@ -231,7 +232,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
/* disable VIP */
WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
/* enable the rom */
- WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
+ WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
/* Disable VGA mode */
WREG32(AVIVO_D1VGA_CONTROL,
(d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
@@ -262,7 +263,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
/* restore regs */
WREG32(RADEON_VIPH_CONTROL, viph_control);
- WREG32(RADEON_BUS_CNTL, bus_cntl);
+ WREG32(R600_BUS_CNTL, bus_cntl);
WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 7b7ea269549c..137b8075f6e7 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -571,6 +571,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
}
if (clk_mask && data_mask) {
+ /* system specific masks */
i2c.mask_clk_mask = clk_mask;
i2c.mask_data_mask = data_mask;
i2c.a_clk_mask = clk_mask;
@@ -579,7 +580,19 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
i2c.en_data_mask = data_mask;
i2c.y_clk_mask = clk_mask;
i2c.y_data_mask = data_mask;
+ } else if ((ddc_line == RADEON_GPIOPAD_MASK) ||
+ (ddc_line == RADEON_MDGPIO_MASK)) {
+ /* default gpiopad masks */
+ i2c.mask_clk_mask = (0x20 << 8);
+ i2c.mask_data_mask = 0x80;
+ i2c.a_clk_mask = (0x20 << 8);
+ i2c.a_data_mask = 0x80;
+ i2c.en_clk_mask = (0x20 << 8);
+ i2c.en_data_mask = 0x80;
+ i2c.y_clk_mask = (0x20 << 8);
+ i2c.y_data_mask = 0x80;
} else {
+ /* default masks for ddc pads */
i2c.mask_clk_mask = RADEON_GPIO_EN_1;
i2c.mask_data_mask = RADEON_GPIO_EN_0;
i2c.a_clk_mask = RADEON_GPIO_A_1;
@@ -716,7 +729,7 @@ void radeon_combios_i2c_init(struct radeon_device *rdev)
clk = RBIOS8(offset + 3 + (i * 5) + 3);
data = RBIOS8(offset + 3 + (i * 5) + 4);
i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
- clk, data);
+ (1 << clk), (1 << data));
rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
break;
}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index fe6c74780f18..8afaf7a7459e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1008,9 +1008,21 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
static int radeon_dp_get_modes(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
int ret;
+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ if (!radeon_dig_connector->edp_on)
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_ON);
+ }
ret = radeon_ddc_get_modes(radeon_connector);
+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ if (!radeon_dig_connector->edp_on)
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_OFF);
+ }
+
return ret;
}
@@ -1029,8 +1041,14 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
/* eDP is always DP */
radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
+ if (!radeon_dig_connector->edp_on)
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_ON);
if (radeon_dp_getdpcd(radeon_connector))
ret = connector_status_connected;
+ if (!radeon_dig_connector->edp_on)
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_OFF);
} else {
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
@@ -1157,6 +1175,8 @@ radeon_add_atom_connector(struct drm_device *dev,
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVIA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1172,6 +1192,8 @@ radeon_add_atom_connector(struct drm_device *dev,
1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID:
@@ -1208,6 +1230,11 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.load_detect_property,
1);
}
+ connector->interlace_allowed = true;
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ connector->doublescan_allowed = true;
+ else
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_HDMIA:
case DRM_MODE_CONNECTOR_HDMIB:
@@ -1238,6 +1265,11 @@ radeon_add_atom_connector(struct drm_device *dev,
0);
}
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = true;
+ if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
+ connector->doublescan_allowed = true;
+ else
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_DisplayPort:
case DRM_MODE_CONNECTOR_eDP:
@@ -1275,6 +1307,9 @@ radeon_add_atom_connector(struct drm_device *dev,
rdev->mode_info.underscan_vborder_property,
0);
}
+ connector->interlace_allowed = true;
+ /* in theory with a DP to VGA converter... */
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Composite:
@@ -1290,6 +1325,8 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_atombios_get_tv_info(rdev));
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_LVDS:
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -1308,6 +1345,8 @@ radeon_add_atom_connector(struct drm_device *dev,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_FULLSCREEN);
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
}
@@ -1385,6 +1424,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVIA:
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -1400,6 +1441,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = true;
+ connector->doublescan_allowed = true;
break;
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID:
@@ -1417,6 +1460,11 @@ radeon_add_legacy_connector(struct drm_device *dev,
1);
}
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = true;
+ if (connector_type == DRM_MODE_CONNECTOR_DVII)
+ connector->doublescan_allowed = true;
+ else
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_SVIDEO:
case DRM_MODE_CONNECTOR_Composite:
@@ -1439,6 +1487,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
radeon_combios_get_tv_info(rdev));
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
case DRM_MODE_CONNECTOR_LVDS:
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
@@ -1452,6 +1502,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
dev->mode_config.scaling_mode_property,
DRM_MODE_SCALE_FULLSCREEN);
subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
break;
}
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 8adfedfe547f..d8ac1849180d 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -180,7 +180,7 @@ int radeon_wb_init(struct radeon_device *rdev)
int r;
if (rdev->wb.wb_obj == NULL) {
- r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
+ r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
if (r) {
dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index f678257c42e6..041943df966b 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -176,6 +176,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
return false;
}
}
+
void
radeon_link_encoder_connector(struct drm_device *dev)
{
@@ -228,6 +229,27 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
return NULL;
}
+struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_encoder *other_encoder;
+ struct radeon_encoder *other_radeon_encoder;
+
+ if (radeon_encoder->is_ext_encoder)
+ return NULL;
+
+ list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
+ if (other_encoder == encoder)
+ continue;
+ other_radeon_encoder = to_radeon_encoder(other_encoder);
+ if (other_radeon_encoder->is_ext_encoder &&
+ (radeon_encoder->devices & other_radeon_encoder->devices))
+ return other_encoder;
+ }
+ return NULL;
+}
+
void radeon_panel_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
@@ -426,52 +448,49 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
}
-void
-atombios_external_tmds_setup(struct drm_encoder *encoder, int action)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_device *rdev = dev->dev_private;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION args;
- int index = 0;
-
- memset(&args, 0, sizeof(args));
-
- index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
-
- args.sXTmdsEncoder.ucEnable = action;
-
- if (radeon_encoder->pixel_clock > 165000)
- args.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
-
- /*if (pScrn->rgbBits == 8)*/
- args.sXTmdsEncoder.ucMisc |= (1 << 1);
-
- atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
-}
+union dvo_encoder_control {
+ ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
+ DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
+ DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
+};
-static void
-atombios_ddia_setup(struct drm_encoder *encoder, int action)
+void
+atombios_dvo_setup(struct drm_encoder *encoder, int action)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- DVO_ENCODER_CONTROL_PS_ALLOCATION args;
- int index = 0;
+ union dvo_encoder_control args;
+ int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
memset(&args, 0, sizeof(args));
- index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
+ if (ASIC_IS_DCE3(rdev)) {
+ /* DCE3+ */
+ args.dvo_v3.ucAction = action;
+ args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ args.dvo_v3.ucDVOConfig = 0; /* XXX */
+ } else if (ASIC_IS_DCE2(rdev)) {
+ /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */
+ args.dvo.sDVOEncoder.ucAction = action;
+ args.dvo.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ /* DFP1, CRT1, TV1 depending on the type of port */
+ args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
+
+ if (radeon_encoder->pixel_clock > 165000)
+ args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
+ } else {
+ /* R4xx, R5xx */
+ args.ext_tmds.sXTmdsEncoder.ucEnable = action;
- args.sDVOEncoder.ucAction = action;
- args.sDVOEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ if (radeon_encoder->pixel_clock > 165000)
+ args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
- if (radeon_encoder->pixel_clock > 165000)
- args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
+ /*if (pScrn->rgbBits == 8)*/
+ args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
+ }
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-
}
union lvds_encoder_control {
@@ -532,14 +551,14 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if (dig->lcd_misc & ATOM_PANEL_MISC_DUAL)
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
if (dig->lcd_misc & ATOM_PANEL_MISC_888RGB)
- args.v1.ucMisc |= (1 << 1);
+ args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
} else {
if (dig->linkb)
args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
if (radeon_encoder->pixel_clock > 165000)
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
/*if (pScrn->rgbBits == 8) */
- args.v1.ucMisc |= (1 << 1);
+ args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
}
break;
case 2:
@@ -595,6 +614,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
int
atombios_get_encoder_mode(struct drm_encoder *encoder)
{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct drm_connector *connector;
@@ -602,9 +622,20 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
struct radeon_connector_atom_dig *dig_connector;
connector = radeon_get_connector_for_encoder(encoder);
- if (!connector)
- return 0;
-
+ if (!connector) {
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ return ATOM_ENCODER_MODE_DVI;
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+ default:
+ return ATOM_ENCODER_MODE_CRT;
+ }
+ }
radeon_connector = to_radeon_connector(connector);
switch (connector->connector_type) {
@@ -834,6 +865,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
memset(&args, 0, sizeof(args));
switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+ break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
@@ -978,6 +1012,105 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
+void
+atombios_set_edp_panel_power(struct drm_connector *connector, int action)
+{
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct drm_device *dev = radeon_connector->base.dev;
+ struct radeon_device *rdev = dev->dev_private;
+ union dig_transmitter_control args;
+ int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
+ uint8_t frev, crev;
+
+ if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)
+ return;
+
+ if (!ASIC_IS_DCE4(rdev))
+ return;
+
+ if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) ||
+ (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))
+ return;
+
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ return;
+
+ memset(&args, 0, sizeof(args));
+
+ args.v1.ucAction = action;
+
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+union external_encoder_control {
+ EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
+};
+
+static void
+atombios_external_encoder_setup(struct drm_encoder *encoder,
+ struct drm_encoder *ext_encoder,
+ int action)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ union external_encoder_control args;
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
+ u8 frev, crev;
+ int dp_clock = 0;
+ int dp_lane_count = 0;
+ int connector_object_id = 0;
+
+ if (connector) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct radeon_connector_atom_dig *dig_connector =
+ radeon_connector->con_priv;
+
+ dp_clock = dig_connector->dp_clock;
+ dp_lane_count = dig_connector->dp_lane_count;
+ connector_object_id =
+ (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+ }
+
+ memset(&args, 0, sizeof(args));
+
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+ return;
+
+ switch (frev) {
+ case 1:
+ /* no params on frev 1 */
+ break;
+ case 2:
+ switch (crev) {
+ case 1:
+ case 2:
+ args.v1.sDigEncoder.ucAction = action;
+ args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
+
+ if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
+ if (dp_clock == 270000)
+ args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+ args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
+ } else if (radeon_encoder->pixel_clock > 165000)
+ args.v1.sDigEncoder.ucLaneNum = 8;
+ else
+ args.v1.sDigEncoder.ucLaneNum = 4;
+ break;
+ default:
+ DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+ return;
+ }
+ break;
+ default:
+ DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
+ return;
+ }
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
static void
atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
{
@@ -1021,6 +1154,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
int index = 0;
bool is_dig = false;
@@ -1043,9 +1177,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_DDI:
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
break;
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ if (ASIC_IS_DCE3(rdev))
+ is_dig = true;
+ else
+ index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+ break;
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
break;
@@ -1082,34 +1221,85 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ if (connector &&
+ (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct radeon_connector_atom_dig *radeon_dig_connector =
+ radeon_connector->con_priv;
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_ON);
+ radeon_dig_connector->edp_on = true;
+ }
dp_link_train(encoder, connector);
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);
}
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+ if (connector &&
+ (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct radeon_connector_atom_dig *radeon_dig_connector =
+ radeon_connector->con_priv;
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_OFF);
+ radeon_dig_connector->edp_on = false;
+ }
}
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
break;
}
} else {
switch (mode) {
case DRM_MODE_DPMS_ON:
args.ucAction = ATOM_ENABLE;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+ args.ucAction = ATOM_LCD_BLON;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ }
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
args.ucAction = ATOM_DISABLE;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+ args.ucAction = ATOM_LCD_BLOFF;
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ }
break;
}
- atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
+
+ if (ext_encoder) {
+ int action;
+
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ default:
+ action = ATOM_ENABLE;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ action = ATOM_DISABLE;
+ break;
+ }
+ atombios_external_encoder_setup(encoder, ext_encoder, action);
+ }
+
radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
}
@@ -1242,7 +1432,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
break;
default:
DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
- break;
+ return;
}
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
@@ -1357,6 +1547,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
radeon_encoder->pixel_clock = adjusted_mode->clock;
@@ -1400,11 +1591,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
}
break;
case ENCODER_OBJECT_ID_INTERNAL_DDI:
- atombios_ddia_setup(encoder, ATOM_ENABLE);
- break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
- atombios_external_tmds_setup(encoder, ATOM_ENABLE);
+ atombios_dvo_setup(encoder, ATOM_ENABLE);
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1419,6 +1608,11 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
}
break;
}
+
+ if (ext_encoder) {
+ atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
+ }
+
atombios_apply_encoder_quirks(encoder, adjusted_mode);
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
@@ -1595,11 +1789,9 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
}
break;
case ENCODER_OBJECT_ID_INTERNAL_DDI:
- atombios_ddia_setup(encoder, ATOM_DISABLE);
- break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
- atombios_external_tmds_setup(encoder, ATOM_DISABLE);
+ atombios_dvo_setup(encoder, ATOM_DISABLE);
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
@@ -1621,6 +1813,53 @@ disable_done:
radeon_encoder->active_device = 0;
}
+/* these are handled by the primary encoders */
+static void radeon_atom_ext_prepare(struct drm_encoder *encoder)
+{
+
+}
+
+static void radeon_atom_ext_commit(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+
+}
+
+static void radeon_atom_ext_disable(struct drm_encoder *encoder)
+{
+
+}
+
+static void
+radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode)
+{
+
+}
+
+static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = {
+ .dpms = radeon_atom_ext_dpms,
+ .mode_fixup = radeon_atom_ext_mode_fixup,
+ .prepare = radeon_atom_ext_prepare,
+ .mode_set = radeon_atom_ext_mode_set,
+ .commit = radeon_atom_ext_commit,
+ .disable = radeon_atom_ext_disable,
+ /* no detect for TMDS/LVDS yet */
+};
+
static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
.dpms = radeon_atom_encoder_dpms,
.mode_fixup = radeon_atom_mode_fixup,
@@ -1730,6 +1969,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
radeon_encoder->devices = supported_device;
radeon_encoder->rmx_type = RMX_OFF;
radeon_encoder->underscan_type = UNDERSCAN_OFF;
+ radeon_encoder->is_ext_encoder = false;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
@@ -1771,6 +2011,9 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
radeon_encoder->rmx_type = RMX_FULL;
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
+ } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
+ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+ radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
} else {
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
@@ -1779,5 +2022,22 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
}
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
break;
+ case ENCODER_OBJECT_ID_SI170B:
+ case ENCODER_OBJECT_ID_CH7303:
+ case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
+ case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
+ case ENCODER_OBJECT_ID_TITFP513:
+ case ENCODER_OBJECT_ID_VT1623:
+ case ENCODER_OBJECT_ID_HDMI_SI1930:
+ /* these are handled by the primary encoders */
+ radeon_encoder->is_ext_encoder = true;
+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
+ else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
+ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+ else
+ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
+ drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs);
+ break;
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index e65b90317fab..65016117d95f 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -79,8 +79,8 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
if (rdev->gart.table.vram.robj == NULL) {
r = radeon_bo_create(rdev, NULL, rdev->gart.table_size,
- true, RADEON_GEM_DOMAIN_VRAM,
- &rdev->gart.table.vram.robj);
+ PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+ &rdev->gart.table.vram.robj);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index d1e595d91723..df95eb83dac6 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -67,7 +67,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
if (alignment < PAGE_SIZE) {
alignment = PAGE_SIZE;
}
- r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
+ r = radeon_bo_create(rdev, gobj, size, alignment, kernel, initial_domain, &robj);
if (r) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 0cfbba02c4d0..ded2a45bc95c 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -896,7 +896,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
((rdev->family <= CHIP_RS480) ||
((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) {
/* set the radeon hw i2c adapter */
- sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name);
+ snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+ "Radeon i2c hw bus %s", name);
i2c->adapter.algo = &radeon_i2c_algo;
ret = i2c_add_adapter(&i2c->adapter);
if (ret) {
@@ -905,7 +906,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
}
} else {
/* set the radeon bit adapter */
- sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name);
+ snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+ "Radeon i2c bit bus %s", name);
i2c->adapter.algo_data = &i2c->algo.bit;
i2c->algo.bit.pre_xfer = pre_xfer;
i2c->algo.bit.post_xfer = post_xfer;
@@ -946,6 +948,8 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->dev = dev;
+ snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+ "Radeon aux bus %s", name);
i2c_set_adapdata(&i2c->adapter, i2c);
i2c->adapter.algo_data = &i2c->algo.dp;
i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index 2f349a300195..465746bd51b7 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -76,7 +76,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
default:
DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
crtc);
- return EINVAL;
+ return -EINVAL;
}
} else {
switch (crtc) {
@@ -89,7 +89,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
default:
DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
crtc);
- return EINVAL;
+ return -EINVAL;
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 0b8397000f4c..59f834ba283d 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -670,7 +670,7 @@ static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder,
if (rdev->is_atom_bios) {
radeon_encoder->pixel_clock = adjusted_mode->clock;
- atombios_external_tmds_setup(encoder, ATOM_ENABLE);
+ atombios_dvo_setup(encoder, ATOM_ENABLE);
fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
} else {
fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 680f57644e86..e301c6f9e059 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -375,6 +375,7 @@ struct radeon_encoder {
int hdmi_config_offset;
int hdmi_audio_workaround;
int hdmi_buffer_status;
+ bool is_ext_encoder;
};
struct radeon_connector_atom_dig {
@@ -385,6 +386,7 @@ struct radeon_connector_atom_dig {
u8 dp_sink_type;
int dp_clock;
int dp_lane_count;
+ bool edp_on;
};
struct radeon_gpio_rec {
@@ -523,9 +525,10 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev
struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int bios_index, int with_tv);
struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index);
struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
-extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
+extern void atombios_dvo_setup(struct drm_encoder *encoder, int action);
extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
+extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action);
extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 8eb183466015..1d067743fee0 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -86,11 +86,12 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
}
int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
- unsigned long size, bool kernel, u32 domain,
- struct radeon_bo **bo_ptr)
+ unsigned long size, int byte_align, bool kernel, u32 domain,
+ struct radeon_bo **bo_ptr)
{
struct radeon_bo *bo;
enum ttm_bo_type type;
+ int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
int r;
if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
@@ -115,7 +116,7 @@ retry:
/* Kernel allocation are uninterruptible */
mutex_lock(&rdev->vram_mutex);
r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type,
- &bo->placement, 0, 0, !kernel, NULL, size,
+ &bo->placement, page_align, 0, !kernel, NULL, size,
&radeon_ttm_bo_destroy);
mutex_unlock(&rdev->vram_mutex);
if (unlikely(r != 0)) {
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index 3481bc7f6f58..d143702b244a 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -137,9 +137,10 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
}
extern int radeon_bo_create(struct radeon_device *rdev,
- struct drm_gem_object *gobj, unsigned long size,
- bool kernel, u32 domain,
- struct radeon_bo **bo_ptr);
+ struct drm_gem_object *gobj, unsigned long size,
+ int byte_align,
+ bool kernel, u32 domain,
+ struct radeon_bo **bo_ptr);
extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
extern void radeon_bo_kunmap(struct radeon_bo *bo);
extern void radeon_bo_unref(struct radeon_bo **bo);
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 6ea798ce8218..06e79822a2bf 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -176,8 +176,8 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib);
/* Allocate 1M object buffer */
r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
- true, RADEON_GEM_DOMAIN_GTT,
- &rdev->ib_pool.robj);
+ PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT,
+ &rdev->ib_pool.robj);
if (r) {
DRM_ERROR("radeon: failed to ib pool (%d).\n", r);
return r;
@@ -332,7 +332,7 @@ int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
rdev->cp.ring_size = ring_size;
/* Allocate ring buffer */
if (rdev->cp.ring_obj == NULL) {
- r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true,
+ r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT,
&rdev->cp.ring_obj);
if (r) {
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 313c96bc09da..5b44f652145c 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -52,7 +52,7 @@ void radeon_test_moves(struct radeon_device *rdev)
goto out_cleanup;
}
- r = radeon_bo_create(rdev, NULL, size, true, RADEON_GEM_DOMAIN_VRAM,
+ r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
&vram_obj);
if (r) {
DRM_ERROR("Failed to create VRAM object\n");
@@ -71,7 +71,7 @@ void radeon_test_moves(struct radeon_device *rdev)
void **gtt_start, **gtt_end;
void **vram_start, **vram_end;
- r = radeon_bo_create(rdev, NULL, size, true,
+ r = radeon_bo_create(rdev, NULL, size, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT, gtt_obj + i);
if (r) {
DRM_ERROR("Failed to create GTT object %d\n", i);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 01c2c736a1da..1272e4b6a1d4 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -529,7 +529,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
DRM_ERROR("Failed initializing VRAM heap.\n");
return r;
}
- r = radeon_bo_create(rdev, NULL, 256 * 1024, true,
+ r = radeon_bo_create(rdev, NULL, 256 * 1024, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_VRAM,
&rdev->stollen_vga_memory);
if (r) {
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 245374e2b778..4dfead8cee33 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -915,8 +915,8 @@ static int rv770_vram_scratch_init(struct radeon_device *rdev)
if (rdev->vram_scratch.robj == NULL) {
r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
- true, RADEON_GEM_DOMAIN_VRAM,
- &rdev->vram_scratch.robj);
+ PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+ &rdev->vram_scratch.robj);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 3ca77dc03915..148a322d8f5d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -224,6 +224,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
int ret;
while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
+ /**
+ * Deadlock avoidance for multi-bo reserving.
+ */
if (use_sequence && bo->seq_valid &&
(sequence - bo->val_seq < (1 << 31))) {
return -EAGAIN;
@@ -241,6 +244,14 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
}
if (use_sequence) {
+ /**
+ * Wake up waiters that may need to recheck for deadlock,
+ * if we decreased the sequence number.
+ */
+ if (unlikely((bo->val_seq - sequence < (1 << 31))
+ || !bo->seq_valid))
+ wake_up_all(&bo->event_queue);
+
bo->val_seq = sequence;
bo->seq_valid = true;
} else {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 36e129f0023f..5408b1b7996f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -862,7 +862,7 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
&vmw_vram_sys_placement, true,
&vmw_user_dmabuf_destroy);
if (unlikely(ret != 0))
- return ret;
+ goto out_no_dmabuf;
tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
@@ -870,19 +870,21 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
false,
ttm_buffer_type,
&vmw_user_dmabuf_release, NULL);
- if (unlikely(ret != 0)) {
- ttm_bo_unref(&tmp);
- } else {
+ if (unlikely(ret != 0))
+ goto out_no_base_object;
+ else {
rep->handle = vmw_user_bo->base.hash.key;
rep->map_handle = vmw_user_bo->dma.base.addr_space_offset;
rep->cur_gmr_id = vmw_user_bo->base.hash.key;
rep->cur_gmr_offset = 0;
}
- ttm_bo_unref(&tmp);
+out_no_base_object:
+ ttm_bo_unref(&tmp);
+out_no_dmabuf:
ttm_read_unlock(&vmaster->lock);
- return 0;
+ return ret;
}
int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 515345b11ac9..88cb04e7962b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1386,6 +1386,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
index 54b017ad258d..5a1b52e0eb85 100644
--- a/drivers/hid/hid-egalax.c
+++ b/drivers/hid/hid-egalax.c
@@ -221,7 +221,7 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
struct egalax_data *td;
struct hid_report *report;
- td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL);
+ td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
if (!td) {
dev_err(&hdev->dev, "cannot allocate eGalax data\n");
return -ENOMEM;
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index bb0b3659437b..d8d372bae3cc 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -174,7 +174,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
clear_bit(*old_keycode, dev->keybit);
set_bit(usage->code, dev->keybit);
- dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n",
+ dbg_hid("Assigned keycode %d to HID usage code %x\n",
usage->code, usage->hid);
/*
@@ -203,8 +203,8 @@ static int hidinput_setkeycode(struct input_dev *dev,
*
* as seen in the HID specification v1.11 6.2.2.7 Global Items.
*
- * Only exponent 1 length units are processed. Centimeters are converted to
- * inches. Degrees are converted to radians.
+ * Only exponent 1 length units are processed. Centimeters and inches are
+ * converted to millimeters. Degrees are converted to radians.
*/
static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
{
@@ -225,13 +225,16 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
*/
if (code == ABS_X || code == ABS_Y || code == ABS_Z) {
if (field->unit == 0x11) { /* If centimeters */
- /* Convert to inches */
- prev = logical_extents;
- logical_extents *= 254;
- if (logical_extents < prev)
+ /* Convert to millimeters */
+ unit_exponent += 1;
+ } else if (field->unit == 0x13) { /* If inches */
+ /* Convert to millimeters */
+ prev = physical_extents;
+ physical_extents *= 254;
+ if (physical_extents < prev)
return 0;
- unit_exponent += 2;
- } else if (field->unit != 0x13) { /* If not inches */
+ unit_exponent -= 1;
+ } else {
return 0;
}
} else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) {
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 15434c814793..25be4e1461bd 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -256,6 +256,8 @@ static const struct hid_device_id tm_devices[] = {
.driver_data = (unsigned long)ff_joystick },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */
.driver_data = (unsigned long)ff_joystick },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a), /* F430 Force Feedback Wheel */
+ .driver_data = (unsigned long)ff_joystick },
{ }
};
MODULE_DEVICE_TABLE(hid, tm_devices);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 8a4b32dca9f7..e1f07483691f 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -32,7 +32,6 @@
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/hidraw.h>
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index fedd88df9a18..984feb351a5a 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -29,7 +29,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/hid.h>
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index 937983407e2a..c4c40be0edbf 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -497,12 +497,14 @@ static unsigned long chipset_ids[] = {
0
};
+#ifdef MODULE
static struct pci_device_id i5k_amb_ids[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, i5k_amb_ids);
+#endif
static int __devinit i5k_amb_probe(struct platform_device *pdev)
{
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 9f4bae07f719..8853afce85ce 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -186,7 +186,7 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int lis3lv02d_i2c_suspend(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
@@ -213,12 +213,9 @@ static int lis3lv02d_i2c_resume(struct device *dev)
return 0;
}
-#else
-#define lis3lv02d_i2c_suspend NULL
-#define lis3lv02d_i2c_resume NULL
-#define lis3lv02d_i2c_shutdown NULL
-#endif
+#endif /* CONFIG_PM_SLEEP */
+#ifdef CONFIG_PM_RUNTIME
static int lis3_i2c_runtime_suspend(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
@@ -236,6 +233,7 @@ static int lis3_i2c_runtime_resume(struct device *dev)
lis3lv02d_poweron(lis3);
return 0;
}
+#endif /* CONFIG_PM_RUNTIME */
static const struct i2c_device_id lis3lv02d_id[] = {
{"lis3lv02d", 0 },
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index b923074b2cbe..30f06e956bfb 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -75,8 +75,7 @@ config I2C_HELPER_AUTO
In doubt, say Y.
config I2C_SMBUS
- tristate
- prompt "SMBus-specific protocols" if !I2C_HELPER_AUTO
+ tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO
help
Say Y here if you want support for SMBus extensions to the I2C
specification. At the moment, the only supported extension is
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index 3998dd620a03..f1cfe7e5508b 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -3,7 +3,7 @@
#
menu "I2C Algorithms"
- depends on !I2C_HELPER_AUTO
+ visible if !I2C_HELPER_AUTO
config I2C_ALGOBIT
tristate "I2C bit-banging interfaces"
@@ -15,15 +15,3 @@ config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces"
endmenu
-
-# In automatic configuration mode, we still have to define the
-# symbols to avoid unmet dependencies.
-
-if I2C_HELPER_AUTO
-config I2C_ALGOBIT
- tristate
-config I2C_ALGOPCF
- tristate
-config I2C_ALGOPCA
- tristate
-endif
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
index bb7e19280821..9b737ff133e2 100644
--- a/drivers/infiniband/core/ud_header.c
+++ b/drivers/infiniband/core/ud_header.c
@@ -278,36 +278,6 @@ void ib_ud_header_init(int payload_bytes,
EXPORT_SYMBOL(ib_ud_header_init);
/**
- * ib_lrh_header_pack - Pack LRH header struct into wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_pack() packs the LRH header structure @lrh into
- * wire format in the buffer @buf.
- */
-int ib_lrh_header_pack(struct ib_unpacked_lrh *lrh, void *buf)
-{
- ib_pack(lrh_table, ARRAY_SIZE(lrh_table), lrh, buf);
- return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_pack);
-
-/**
- * ib_lrh_header_unpack - Unpack LRH structure from wire format
- * @lrh:unpacked LRH header struct
- * @buf:Buffer to pack into
- *
- * ib_lrh_header_unpack() unpacks the LRH header structure from
- * wire format (in buf) into @lrh.
- */
-int ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh)
-{
- ib_unpack(lrh_table, ARRAY_SIZE(lrh_table), buf, lrh);
- return 0;
-}
-EXPORT_SYMBOL(ib_lrh_header_unpack);
-
-/**
* ib_ud_header_pack - Pack UD header struct into wire format
* @header:UD header struct
* @buf:Buffer to pack into
diff --git a/drivers/infiniband/core/uverbs_marshall.c b/drivers/infiniband/core/uverbs_marshall.c
index 5440da0e59b4..1b1146f87124 100644
--- a/drivers/infiniband/core/uverbs_marshall.c
+++ b/drivers/infiniband/core/uverbs_marshall.c
@@ -40,18 +40,21 @@ void ib_copy_ah_attr_to_user(struct ib_uverbs_ah_attr *dst,
dst->grh.sgid_index = src->grh.sgid_index;
dst->grh.hop_limit = src->grh.hop_limit;
dst->grh.traffic_class = src->grh.traffic_class;
+ memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved));
dst->dlid = src->dlid;
dst->sl = src->sl;
dst->src_path_bits = src->src_path_bits;
dst->static_rate = src->static_rate;
dst->is_global = src->ah_flags & IB_AH_GRH ? 1 : 0;
dst->port_num = src->port_num;
+ dst->reserved = 0;
}
EXPORT_SYMBOL(ib_copy_ah_attr_to_user);
void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
struct ib_qp_attr *src)
{
+ dst->qp_state = src->qp_state;
dst->cur_qp_state = src->cur_qp_state;
dst->path_mtu = src->path_mtu;
dst->path_mig_state = src->path_mig_state;
@@ -83,6 +86,7 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
dst->rnr_retry = src->rnr_retry;
dst->alt_port_num = src->alt_port_num;
dst->alt_timeout = src->alt_timeout;
+ memset(dst->reserved, 0, sizeof(dst->reserved));
}
EXPORT_SYMBOL(ib_copy_qp_attr_to_user);
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 6078992da3f0..9292a15ad7c4 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -40,7 +40,6 @@
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/jiffies.h>
-#include <linux/smp_lock.h>
#include <asm/pgtable.h>
#include "ipath_kernel.h"
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index bf3e20cd0298..30e09caf0da9 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -219,7 +219,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
struct net_device *ndev;
enum ib_mtu tmp;
- props->active_width = IB_WIDTH_4X;
+ props->active_width = IB_WIDTH_1X;
props->active_speed = 4;
props->port_cap_flags = IB_PORT_CM_SUP;
props->gid_tbl_len = to_mdev(ibdev)->dev->caps.gid_table_len[port];
@@ -242,7 +242,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
tmp = iboe_get_mtu(ndev->mtu);
props->active_mtu = tmp ? min(props->max_mtu, tmp) : IB_MTU_256;
- props->state = netif_running(ndev) && netif_oper_up(ndev) ?
+ props->state = (netif_running(ndev) && netif_carrier_ok(ndev)) ?
IB_PORT_ACTIVE : IB_PORT_DOWN;
props->phys_state = state_to_phys_state(props->state);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 9a7794ac34c1..2001f20a4361 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1816,6 +1816,11 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
ctrl->fence_size = (wr->send_flags & IB_SEND_FENCE ?
MLX4_WQE_CTRL_FENCE : 0) | size;
+ if (be16_to_cpu(vlan) < 0x1000) {
+ ctrl->ins_vlan = 1 << 6;
+ ctrl->vlan_tag = vlan;
+ }
+
/*
* Make sure descriptor is fully written before
* setting ownership bit (because HW can start
@@ -1831,11 +1836,6 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
(ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0) | blh;
- if (be16_to_cpu(vlan) < 0x1000) {
- ctrl->ins_vlan = 1 << 6;
- ctrl->vlan_tag = vlan;
- }
-
stamp = ind + qp->sq_spare_wqes;
ind += DIV_ROUND_UP(size * 16, 1U << qp->sq.wqe_shift);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index cfc1d65c4577..1e1e347a7715 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1123,7 +1123,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr)
}
}
-static int srp_queuecommand(struct scsi_cmnd *scmnd,
+static int srp_queuecommand_lck(struct scsi_cmnd *scmnd,
void (*done)(struct scsi_cmnd *))
{
struct srp_target_port *target = host_to_target(scmnd->device->host);
@@ -1196,6 +1196,8 @@ err:
return SCSI_MLQUEUE_HOST_BUSY;
}
+static DEF_SCSI_QCMD(srp_queuecommand)
+
static int srp_alloc_iu_bufs(struct srp_target_port *target)
{
int i;
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 7f26ca6ecf75..db409d6bd5d2 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -24,7 +24,6 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
-#include <linux/smp_lock.h>
#include "input-compat.h"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -753,7 +752,7 @@ static int input_default_setkeycode(struct input_dev *dev,
if (index >= dev->keycodemax)
return -EINVAL;
- if (dev->keycodesize < sizeof(dev->keycode) &&
+ if (dev->keycodesize < sizeof(ke->keycode) &&
(ke->keycode >> (dev->keycodesize * 8)))
return -EINVAL;
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 3c287dd879d3..4225f5d6b15f 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -358,7 +358,7 @@ static int __devinit gscps2_probe(struct parisc_device *dev)
gscps2_reset(ps2port);
ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
- snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
+ snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s",
(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
serio->id.type = SERIO_8042;
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index cd82bb125915..b7ba4597f7f0 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/serio.h>
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index 57b25b84d1fc..0a619c558bfb 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const
}
static DEVICE_ATTR(pointer_mode,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletPointerMode, store_tabletPointerMode);
/***********************************************************************
@@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co
}
static DEVICE_ATTR(coordinate_mode,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletCoordinateMode, store_tabletCoordinateMode);
/***********************************************************************
@@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch
}
static DEVICE_ATTR(tool_mode,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletToolMode, store_tabletToolMode);
/***********************************************************************
@@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char
}
static DEVICE_ATTR(xtilt,
- S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt);
+ S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt);
/***********************************************************************
* support routines for the 'ytilt' file. Note that this file
@@ -1261,7 +1261,7 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char
}
static DEVICE_ATTR(ytilt,
- S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt);
+ S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt);
/***********************************************************************
* support routines for the 'jitter' file. Note that this file
@@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const
}
static DEVICE_ATTR(jitter,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletJitterDelay, store_tabletJitterDelay);
/***********************************************************************
@@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(delay,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletProgrammableDelay, store_tabletProgrammableDelay);
/***********************************************************************
@@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const
}
static DEVICE_ATTR(stylus_upper,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletStylusUpper, store_tabletStylusUpper);
/***********************************************************************
@@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const
}
static DEVICE_ATTR(stylus_lower,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletStylusLower, store_tabletStylusLower);
/***********************************************************************
@@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c
}
static DEVICE_ATTR(mouse_left,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletMouseLeft, store_tabletMouseLeft);
/***********************************************************************
@@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const
}
static DEVICE_ATTR(mouse_middle,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletMouseMiddle, store_tabletMouseMiddle);
/***********************************************************************
@@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const
}
static DEVICE_ATTR(mouse_right,
- S_IRUGO | S_IWUGO,
+ S_IRUGO | S_IWUSR,
show_tabletMouseRight, store_tabletMouseRight);
/***********************************************************************
@@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char
}
static DEVICE_ATTR(wheel,
- S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel);
+ S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel);
/***********************************************************************
* support routines for the 'execute' file. Note that this file
@@ -1600,7 +1600,7 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha
}
static DEVICE_ATTR(execute,
- S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute);
+ S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute);
/***********************************************************************
* support routines for the 'odm_code' file. Note that this file
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 2e847a90bad0..f2b5bab5e6a1 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -1627,7 +1627,7 @@ __setup("icn=", icn_setup);
static int __init icn_init(void)
{
char *p;
- char rev[10];
+ char rev[20];
memset(&dev, 0, sizeof(icn_dev));
dev.memaddr = (membase & 0x0ffc000);
@@ -1637,9 +1637,10 @@ static int __init icn_init(void)
spin_lock_init(&dev.devlock);
if ((p = strchr(revision, ':'))) {
- strcpy(rev, p + 1);
+ strncpy(rev, p + 1, 20);
p = strchr(rev, '$');
- *p = 0;
+ if (p)
+ *p = 0;
} else
strcpy(rev, " ??? ");
printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 77b8fd20cd90..6f190f4cdbc0 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -7,20 +7,20 @@ menuconfig NEW_LEDS
This is not related to standard keyboard LEDs which are controlled
via the input system.
-if NEW_LEDS
-
config LEDS_CLASS
bool "LED Class Support"
+ depends on NEW_LEDS
help
This option enables the led sysfs class in /sys/class/leds. You'll
need this to do anything useful with LEDs. If unsure, say N.
-if LEDS_CLASS
+if NEW_LEDS
comment "LED drivers"
config LEDS_88PM860X
tristate "LED Support for Marvell 88PM860x PMIC"
+ depends on LEDS_CLASS
depends on MFD_88PM860X
help
This option enables support for on-chip LED drivers found on Marvell
@@ -28,6 +28,7 @@ config LEDS_88PM860X
config LEDS_ATMEL_PWM
tristate "LED Support using Atmel PWM outputs"
+ depends on LEDS_CLASS
depends on ATMEL_PWM
help
This option enables support for LEDs driven using outputs
@@ -35,6 +36,7 @@ config LEDS_ATMEL_PWM
config LEDS_LOCOMO
tristate "LED Support for Locomo device"
+ depends on LEDS_CLASS
depends on SHARP_LOCOMO
help
This option enables support for the LEDs on Sharp Locomo.
@@ -42,6 +44,7 @@ config LEDS_LOCOMO
config LEDS_MIKROTIK_RB532
tristate "LED Support for Mikrotik Routerboard 532"
+ depends on LEDS_CLASS
depends on MIKROTIK_RB532
help
This option enables support for the so called "User LED" of
@@ -49,6 +52,7 @@ config LEDS_MIKROTIK_RB532
config LEDS_S3C24XX
tristate "LED Support for Samsung S3C24XX GPIO LEDs"
+ depends on LEDS_CLASS
depends on ARCH_S3C2410
help
This option enables support for LEDs connected to GPIO lines
@@ -56,12 +60,14 @@ config LEDS_S3C24XX
config LEDS_AMS_DELTA
tristate "LED Support for the Amstrad Delta (E3)"
+ depends on LEDS_CLASS
depends on MACH_AMS_DELTA
help
This option enables support for the LEDs on Amstrad Delta (E3).
config LEDS_NET48XX
tristate "LED Support for Soekris net48xx series Error LED"
+ depends on LEDS_CLASS
depends on SCx200_GPIO
help
This option enables support for the Soekris net4801 and net4826 error
@@ -79,18 +85,21 @@ config LEDS_NET5501
config LEDS_FSG
tristate "LED Support for the Freecom FSG-3"
+ depends on LEDS_CLASS
depends on MACH_FSG
help
This option enables support for the LEDs on the Freecom FSG-3.
config LEDS_WRAP
tristate "LED Support for the WRAP series LEDs"
+ depends on LEDS_CLASS
depends on SCx200_GPIO
help
This option enables support for the PCEngines WRAP programmable LEDs.
config LEDS_ALIX2
tristate "LED Support for ALIX.2 and ALIX.3 series"
+ depends on LEDS_CLASS
depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
help
This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
@@ -98,12 +107,14 @@ config LEDS_ALIX2
config LEDS_H1940
tristate "LED Support for iPAQ H1940 device"
+ depends on LEDS_CLASS
depends on ARCH_H1940
help
This option enables support for the LEDs on the h1940.
config LEDS_COBALT_QUBE
tristate "LED Support for the Cobalt Qube series front LED"
+ depends on LEDS_CLASS
depends on MIPS_COBALT
help
This option enables support for the front LED on Cobalt Qube series
@@ -117,6 +128,7 @@ config LEDS_COBALT_RAQ
config LEDS_SUNFIRE
tristate "LED support for SunFire servers."
+ depends on LEDS_CLASS
depends on SPARC64
select LEDS_TRIGGERS
help
@@ -125,6 +137,7 @@ config LEDS_SUNFIRE
config LEDS_HP6XX
tristate "LED Support for the HP Jornada 6xx"
+ depends on LEDS_CLASS
depends on SH_HP6XX
help
This option enables LED support for the handheld
@@ -132,6 +145,7 @@ config LEDS_HP6XX
config LEDS_PCA9532
tristate "LED driver for PCA9532 dimmer"
+ depends on LEDS_CLASS
depends on I2C && INPUT && EXPERIMENTAL
help
This option enables support for NXP pca9532
@@ -140,6 +154,7 @@ config LEDS_PCA9532
config LEDS_GPIO
tristate "LED Support for GPIO connected LEDs"
+ depends on LEDS_CLASS
depends on GENERIC_GPIO
help
This option enables support for the LEDs connected to GPIO
@@ -167,6 +182,7 @@ config LEDS_GPIO_OF
config LEDS_LP3944
tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
+ depends on LEDS_CLASS
depends on I2C
help
This option enables support for LEDs connected to the National
@@ -196,6 +212,7 @@ config LEDS_LP5523
config LEDS_CLEVO_MAIL
tristate "Mail LED on Clevo notebook"
+ depends on LEDS_CLASS
depends on X86 && SERIO_I8042 && DMI
help
This driver makes the mail LED accessible from userspace
@@ -226,6 +243,7 @@ config LEDS_CLEVO_MAIL
config LEDS_PCA955X
tristate "LED Support for PCA955x I2C chips"
+ depends on LEDS_CLASS
depends on I2C
help
This option enables support for LEDs connected to PCA955x
@@ -234,6 +252,7 @@ config LEDS_PCA955X
config LEDS_WM831X_STATUS
tristate "LED support for status LEDs on WM831x PMICs"
+ depends on LEDS_CLASS
depends on MFD_WM831X
help
This option enables support for the status LEDs of the WM831x
@@ -241,6 +260,7 @@ config LEDS_WM831X_STATUS
config LEDS_WM8350
tristate "LED Support for WM8350 AudioPlus PMIC"
+ depends on LEDS_CLASS
depends on MFD_WM8350
help
This option enables support for LEDs driven by the Wolfson
@@ -248,6 +268,7 @@ config LEDS_WM8350
config LEDS_DA903X
tristate "LED Support for DA9030/DA9034 PMIC"
+ depends on LEDS_CLASS
depends on PMIC_DA903X
help
This option enables support for on-chip LED drivers found
@@ -255,6 +276,7 @@ config LEDS_DA903X
config LEDS_DAC124S085
tristate "LED Support for DAC124S085 SPI DAC"
+ depends on LEDS_CLASS
depends on SPI
help
This option enables support for DAC124S085 SPI DAC from NatSemi,
@@ -262,18 +284,21 @@ config LEDS_DAC124S085
config LEDS_PWM
tristate "PWM driven LED Support"
+ depends on LEDS_CLASS
depends on HAVE_PWM
help
This option enables support for pwm driven LEDs
config LEDS_REGULATOR
tristate "REGULATOR driven LED support"
+ depends on LEDS_CLASS
depends on REGULATOR
help
This option enables support for regulator driven LEDs.
config LEDS_BD2802
tristate "LED driver for BD2802 RGB LED"
+ depends on LEDS_CLASS
depends on I2C
help
This option enables support for BD2802GU RGB LED driver chips
@@ -281,6 +306,7 @@ config LEDS_BD2802
config LEDS_INTEL_SS4200
tristate "LED driver for Intel NAS SS4200 series"
+ depends on LEDS_CLASS
depends on PCI && DMI
help
This option enables support for the Intel SS4200 series of
@@ -290,6 +316,7 @@ config LEDS_INTEL_SS4200
config LEDS_LT3593
tristate "LED driver for LT3593 controllers"
+ depends on LEDS_CLASS
depends on GENERIC_GPIO
help
This option enables support for LEDs driven by a Linear Technology
@@ -298,6 +325,7 @@ config LEDS_LT3593
config LEDS_ADP5520
tristate "LED Support for ADP5520/ADP5501 PMIC"
+ depends on LEDS_CLASS
depends on PMIC_ADP5520
help
This option enables support for on-chip LED drivers found
@@ -308,6 +336,7 @@ config LEDS_ADP5520
config LEDS_DELL_NETBOOKS
tristate "External LED on Dell Business Netbooks"
+ depends on LEDS_CLASS
depends on X86 && ACPI_WMI
help
This adds support for the Latitude 2100 and similar
@@ -315,6 +344,7 @@ config LEDS_DELL_NETBOOKS
config LEDS_MC13783
tristate "LED Support for MC13783 PMIC"
+ depends on LEDS_CLASS
depends on MFD_MC13783
help
This option enable support for on-chip LED drivers found
@@ -322,6 +352,7 @@ config LEDS_MC13783
config LEDS_NS2
tristate "LED support for Network Space v2 GPIO LEDs"
+ depends on LEDS_CLASS
depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
default y
help
@@ -340,17 +371,17 @@ config LEDS_NETXBIG
config LEDS_TRIGGERS
bool "LED Trigger support"
+ depends on LEDS_CLASS
help
This option enables trigger support for the leds class.
These triggers allow kernel events to drive the LEDs and can
be configured via sysfs. If unsure, say Y.
-if LEDS_TRIGGERS
-
comment "LED Triggers"
config LEDS_TRIGGER_TIMER
tristate "LED Timer Trigger"
+ depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled by a programmable timer
via sysfs. Some LED hardware can be programmed to start
@@ -362,12 +393,14 @@ config LEDS_TRIGGER_TIMER
config LEDS_TRIGGER_IDE_DISK
bool "LED IDE Disk Trigger"
depends on IDE_GD_ATA
+ depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled by IDE disk activity.
If unsure, say Y.
config LEDS_TRIGGER_HEARTBEAT
tristate "LED Heartbeat Trigger"
+ depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled by a CPU load average.
The flash frequency is a hyperbolic function of the 1-minute
@@ -376,6 +409,7 @@ config LEDS_TRIGGER_HEARTBEAT
config LEDS_TRIGGER_BACKLIGHT
tristate "LED backlight Trigger"
+ depends on LEDS_TRIGGERS
help
This allows LEDs to be controlled as a backlight device: they
turn off and on when the display is blanked and unblanked.
@@ -384,6 +418,7 @@ config LEDS_TRIGGER_BACKLIGHT
config LEDS_TRIGGER_GPIO
tristate "LED GPIO Trigger"
+ depends on LEDS_TRIGGERS
depends on GPIOLIB
help
This allows LEDs to be controlled by gpio events. It's good
@@ -396,6 +431,7 @@ config LEDS_TRIGGER_GPIO
config LEDS_TRIGGER_DEFAULT_ON
tristate "LED Default ON Trigger"
+ depends on LEDS_TRIGGERS
help
This allows LEDs to be initialised in the ON state.
If unsure, say Y.
@@ -403,8 +439,4 @@ config LEDS_TRIGGER_DEFAULT_ON
comment "iptables trigger is under Netfilter config (LED target)"
depends on LEDS_TRIGGERS
-endif # LEDS_TRIGGERS
-
-endif # LEDS_CLASS
-
endif # NEW_LEDS
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 3782f31f06d2..33facd0c45d1 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -125,11 +125,22 @@ struct lp5521_chip {
u8 num_leds;
};
-#define cdev_to_led(c) container_of(c, struct lp5521_led, cdev)
-#define engine_to_lp5521(eng) container_of((eng), struct lp5521_chip, \
- engines[(eng)->id - 1])
-#define led_to_lp5521(led) container_of((led), struct lp5521_chip, \
- leds[(led)->id])
+static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev)
+{
+ return container_of(cdev, struct lp5521_led, cdev);
+}
+
+static inline struct lp5521_chip *engine_to_lp5521(struct lp5521_engine *engine)
+{
+ return container_of(engine, struct lp5521_chip,
+ engines[engine->id - 1]);
+}
+
+static inline struct lp5521_chip *led_to_lp5521(struct lp5521_led *led)
+{
+ return container_of(led, struct lp5521_chip,
+ leds[led->id]);
+}
static void lp5521_led_brightness_work(struct work_struct *work);
@@ -185,14 +196,17 @@ static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
/* move current engine to direct mode and remember the state */
ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT);
- usleep_range(1000, 10000);
+ /* Mode change requires min 500 us delay. 1 - 2 ms with margin */
+ usleep_range(1000, 2000);
ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode);
/* For loading, all the engines to load mode */
lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
- usleep_range(1000, 10000);
+ /* Mode change requires min 500 us delay. 1 - 2 ms with margin */
+ usleep_range(1000, 2000);
lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
- usleep_range(1000, 10000);
+ /* Mode change requires min 500 us delay. 1 - 2 ms with margin */
+ usleep_range(1000, 2000);
addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE;
i2c_smbus_write_i2c_block_data(client,
@@ -231,10 +245,6 @@ static int lp5521_configure(struct i2c_client *client,
lp5521_init_engine(chip, attr_group);
- lp5521_write(client, LP5521_REG_RESET, 0xff);
-
- usleep_range(10000, 20000);
-
/* Set all PWMs to direct control mode */
ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
@@ -251,8 +261,8 @@ static int lp5521_configure(struct i2c_client *client,
ret |= lp5521_write(client, LP5521_REG_ENABLE,
LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
LP5521_EXEC_RUN);
- /* enable takes 500us */
- usleep_range(500, 20000);
+ /* enable takes 500us. 1 - 2 ms leaves some margin */
+ usleep_range(1000, 2000);
return ret;
}
@@ -305,7 +315,8 @@ static int lp5521_detect(struct i2c_client *client)
LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
if (ret)
return ret;
- usleep_range(1000, 10000);
+ /* enable takes 500us. 1 - 2 ms leaves some margin */
+ usleep_range(1000, 2000);
ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
if (ret)
return ret;
@@ -693,11 +704,16 @@ static int lp5521_probe(struct i2c_client *client,
if (pdata->enable) {
pdata->enable(0);
- usleep_range(1000, 10000);
+ usleep_range(1000, 2000); /* Keep enable down at least 1ms */
pdata->enable(1);
- usleep_range(1000, 10000); /* Spec says min 500us */
+ usleep_range(1000, 2000); /* 500us abs min. */
}
+ lp5521_write(client, LP5521_REG_RESET, 0xff);
+ usleep_range(10000, 20000); /*
+ * Exact value is not available. 10 - 20ms
+ * appears to be enough for reset.
+ */
ret = lp5521_detect(client);
if (ret) {
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 1e11fcc08b28..0cc4ead2fd8b 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -134,15 +134,18 @@ struct lp5523_chip {
u8 num_leds;
};
-#define cdev_to_led(c) container_of(c, struct lp5523_led, cdev)
+static inline struct lp5523_led *cdev_to_led(struct led_classdev *cdev)
+{
+ return container_of(cdev, struct lp5523_led, cdev);
+}
-static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
+static inline struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
{
return container_of(engine, struct lp5523_chip,
engines[engine->id - 1]);
}
-static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
+static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
{
return container_of(led, struct lp5523_chip,
leds[led->id]);
@@ -200,13 +203,9 @@ static int lp5523_configure(struct i2c_client *client)
{ 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
};
- lp5523_write(client, LP5523_REG_RESET, 0xff);
-
- usleep_range(10000, 100000);
-
ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
- /* Chip startup time after reset is 500 us */
- usleep_range(1000, 10000);
+ /* Chip startup time is 500 us, 1 - 2 ms gives some margin */
+ usleep_range(1000, 2000);
ret |= lp5523_write(client, LP5523_REG_CONFIG,
LP5523_AUTO_INC | LP5523_PWR_SAVE |
@@ -243,8 +242,8 @@ static int lp5523_configure(struct i2c_client *client)
return -1;
}
- /* Wait 3ms and check the engine status */
- usleep_range(3000, 20000);
+ /* Let the programs run for couple of ms and check the engine status */
+ usleep_range(3000, 6000);
lp5523_read(client, LP5523_REG_STATUS, &status);
status &= LP5523_ENG_STATUS_MASK;
@@ -449,10 +448,10 @@ static ssize_t lp5523_selftest(struct device *dev,
/* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */
lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL,
LP5523_EN_LEDTEST | 16);
- usleep_range(3000, 10000);
+ usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */
ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
if (!(status & LP5523_LEDTEST_DONE))
- usleep_range(3000, 10000);
+ usleep_range(3000, 6000); /* Was not ready. Wait little bit */
ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd);
vdd--; /* There may be some fluctuation in measurement */
@@ -468,16 +467,16 @@ static ssize_t lp5523_selftest(struct device *dev,
chip->pdata->led_config[i].led_current);
lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff);
- /* let current stabilize 2ms before measurements start */
- usleep_range(2000, 10000);
+ /* let current stabilize 2 - 4ms before measurements start */
+ usleep_range(2000, 4000);
lp5523_write(chip->client,
LP5523_REG_LED_TEST_CTRL,
LP5523_EN_LEDTEST | i);
- /* ledtest takes 2.7ms */
- usleep_range(3000, 10000);
+ /* ADC conversion time is 2.7 ms typically */
+ usleep_range(3000, 6000);
ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
if (!(status & LP5523_LEDTEST_DONE))
- usleep_range(3000, 10000);
+ usleep_range(3000, 6000);/* Was not ready. Wait. */
ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc);
if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
@@ -930,11 +929,16 @@ static int lp5523_probe(struct i2c_client *client,
if (pdata->enable) {
pdata->enable(0);
- usleep_range(1000, 10000);
+ usleep_range(1000, 2000); /* Keep enable down at least 1ms */
pdata->enable(1);
- usleep_range(1000, 10000); /* Spec says min 500us */
+ usleep_range(1000, 2000); /* 500us abs min. */
}
+ lp5523_write(client, LP5523_REG_RESET, 0xff);
+ usleep_range(10000, 20000); /*
+ * Exact value is not available. 10 - 20ms
+ * appears to be enough for reset.
+ */
ret = lp5523_detect(client);
if (ret)
goto fail2;
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index a688293abd0b..614ebebaaa28 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -102,6 +102,7 @@ static struct dmi_system_id __initdata nas_led_whitelist[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00")
}
},
+ {}
};
/*
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 3d7355ff7308..fa51af11c6f1 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -102,6 +102,7 @@ config ADB_PMU_LED
config ADB_PMU_LED_IDE
bool "Use front LED as IDE LED by default"
depends on ADB_PMU_LED
+ depends on LEDS_CLASS
select LEDS_TRIGGERS
select LEDS_TRIGGER_IDE_DISK
help
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 324a3663fcda..84c46a161927 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1337,7 +1337,7 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
rdev->sb_page);
md_super_wait(rdev->mddev);
- return num_sectors / 2; /* kB for sysfs */
+ return num_sectors;
}
@@ -1704,7 +1704,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
rdev->sb_page);
md_super_wait(rdev->mddev);
- return num_sectors / 2; /* kB for sysfs */
+ return num_sectors;
}
static struct super_type super_types[] = {
@@ -4338,6 +4338,8 @@ static int md_alloc(dev_t dev, char *name)
if (mddev->kobj.sd &&
sysfs_create_group(&mddev->kobj, &md_bitmap_group))
printk(KERN_DEBUG "pointless warning\n");
+
+ blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA);
abort:
mutex_unlock(&disks_mutex);
if (!error && mddev->kobj.sd) {
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 45f8324196ec..845cf95b612c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1161,6 +1161,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
* is not possible.
*/
if (!test_bit(Faulty, &rdev->flags) &&
+ !mddev->recovery_disabled &&
mddev->degraded < conf->raid_disks) {
err = -EBUSY;
goto abort;
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 2385e6cca635..78b089526e02 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -31,7 +31,7 @@ config MEDIA_TUNER
select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
-menuconfig MEDIA_TUNER_CUSTOMISE
+config MEDIA_TUNER_CUSTOMISE
bool "Customize analog and hybrid tuner modules to build"
depends on MEDIA_TUNER
default y if EMBEDDED
@@ -44,7 +44,8 @@ menuconfig MEDIA_TUNER_CUSTOMISE
If unsure say N.
-if MEDIA_TUNER_CUSTOMISE
+menu "Customize TV tuners"
+ visible if MEDIA_TUNER_CUSTOMISE
config MEDIA_TUNER_SIMPLE
tristate "Simple tuner support"
@@ -185,5 +186,4 @@ config MEDIA_TUNER_TDA18218
default m if MEDIA_TUNER_CUSTOMISE
help
NXP TDA18218 silicon tuner driver.
-
-endif # MEDIA_TUNER_CUSTOMISE
+endmenu
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 4d0646da6087..7ea517b7e186 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -36,7 +36,6 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include "dvb_ca_en50221.h"
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 1589d5a5cb46..cad6634610ea 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -36,7 +36,6 @@
#include <linux/list.h>
#include <linux/freezer.h>
#include <linux/jiffies.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <asm/processor.h>
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index e9062b08a485..96b27016670e 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -12,9 +12,8 @@ config DVB_FE_CUSTOMISE
If unsure say N.
-if DVB_FE_CUSTOMISE
-
menu "Customise DVB Frontends"
+ visible if DVB_FE_CUSTOMISE
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@@ -619,5 +618,3 @@ config DVB_DUMMY_FE
tristate "Dummy frontend driver"
default n
endmenu
-
-endif
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index 4caeb163a666..3a7ef71087be 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -34,7 +34,6 @@
#include <linux/io.h>
#include <asm/div64.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/byteorder/generic.h>
#include <linux/firmware.h>
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c
index 48f980b21d66..3832e5983c19 100644
--- a/drivers/media/dvb/ngene/ngene-dvb.c
+++ b/drivers/media/dvb/ngene/ngene-dvb.c
@@ -35,7 +35,6 @@
#include <linux/io.h>
#include <asm/div64.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/byteorder/generic.h>
#include <linux/firmware.h>
diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c
index c3ae956714e7..d28554f8ce99 100644
--- a/drivers/media/dvb/ngene/ngene-i2c.c
+++ b/drivers/media/dvb/ngene/ngene-i2c.c
@@ -37,7 +37,6 @@
#include <asm/div64.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/byteorder/generic.h>
#include <linux/firmware.h>
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index b540e8072e92..e6b2d085a449 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -58,7 +58,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/input.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 6a435786b63d..03829e6818bd 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -291,7 +291,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
goto unregister_v4l2_dev;
}
- sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, NULL,
+ sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter,
pdata->subdev_board_info, NULL);
if (!sd) {
dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
index ea12782359a0..b9914d7a0c9f 100644
--- a/drivers/media/radio/si470x/radio-si470x.h
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -31,7 +31,6 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/input.h>
#include <linux/version.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index ac16e815e275..6830d2848bd7 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -112,7 +112,7 @@ config VIDEO_IR_I2C
#
menu "Encoders/decoders and other helper chips"
- depends on !VIDEO_HELPER_CHIPS_AUTO
+ visible if !VIDEO_HELPER_CHIPS_AUTO
comment "Audio decoders"
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 0453816d4ec3..01be89fa5c78 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev)
be abstracted out if we ever need to support a different
demod) */
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "au8522", 0x8e >> 1, NULL);
+ "au8522", 0x8e >> 1, NULL);
if (sd == NULL)
printk(KERN_ERR "analog subdev registration failed\n");
}
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev)
if (dev->board.tuner_type != TUNER_ABSENT) {
/* Load the tuner module, which does the attach */
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->board.tuner_addr, NULL);
+ "tuner", dev->board.tuner_addr, NULL);
if (sd == NULL)
printk(KERN_ERR "tuner subdev registration fail\n");
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 87d8b006ef77..49efcf660ba6 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3529,7 +3529,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "saa6588", 0, addrs);
+ &btv->c.i2c_adap, "saa6588", 0, addrs);
btv->has_saa6588 = (sd != NULL);
}
@@ -3554,7 +3554,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
};
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "msp3400", 0, addrs);
+ &btv->c.i2c_adap, "msp3400", 0, addrs);
if (btv->sd_msp34xx)
return;
goto no_audio;
@@ -3568,7 +3568,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
};
if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+ &btv->c.i2c_adap, "tda7432", 0, addrs))
return;
goto no_audio;
}
@@ -3576,7 +3576,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
case 3: {
/* The user specified that we should probe for tvaudio */
btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+ &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
if (btv->sd_tvaudio)
return;
goto no_audio;
@@ -3596,11 +3596,11 @@ void __devinit bttv_init_card2(struct bttv *btv)
found is really something else (e.g. a tea6300). */
if (!bttv_tvcards[btv->c.type].no_msp34xx) {
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "msp3400",
+ &btv->c.i2c_adap, "msp3400",
0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
} else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "msp3400",
+ &btv->c.i2c_adap, "msp3400",
0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
}
@@ -3616,13 +3616,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
};
if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tda7432", 0, addrs))
+ &btv->c.i2c_adap, "tda7432", 0, addrs))
return;
}
/* Now see if we can find one of the tvaudio devices. */
btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tvaudio", 0, tvaudio_addrs());
+ &btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
if (btv->sd_tvaudio)
return;
@@ -3646,13 +3646,13 @@ void __devinit bttv_init_tuner(struct bttv *btv)
/* Load tuner module before issuing tuner config call! */
if (bttv_tvcards[btv->c.type].has_radio)
v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tuner",
+ &btv->c.i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tuner",
+ &btv->c.i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
- &btv->c.i2c_adap, NULL, "tuner",
+ &btv->c.i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 3da6e80e1041..a529619e51f6 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -42,7 +42,6 @@
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kdev_t.h>
#include "bttvp.h"
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 7bc36670071a..260c666ce931 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -2066,8 +2066,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam->sensor_addr = 0x42;
cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter,
- "ov7670", "ov7670", 0, &sensor_cfg, cam->sensor_addr,
- NULL);
+ "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL);
if (cam->sensor == NULL) {
ret = -ENODEV;
goto out_smbus;
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index a09caf883170..e71a026f3419 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -122,15 +122,15 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
if (hw == CX18_HW_TUNER) {
/* special tuner group handling */
sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, NULL, type, 0, cx->card_i2c->radio);
+ adap, type, 0, cx->card_i2c->radio);
if (sd != NULL)
sd->grp_id = hw;
sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, NULL, type, 0, cx->card_i2c->demod);
+ adap, type, 0, cx->card_i2c->demod);
if (sd != NULL)
sd->grp_id = hw;
sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
- adap, NULL, type, 0, cx->card_i2c->tv);
+ adap, type, 0, cx->card_i2c->tv);
if (sd != NULL)
sd->grp_id = hw;
return sd != NULL ? 0 : -1;
@@ -144,7 +144,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
return -1;
/* It's an I2C device other than an analog tuner or IR chip */
- sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, NULL, type, hw_addrs[idx],
+ sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, type, hw_addrs[idx],
NULL);
if (sd != NULL)
sd->grp_id = hw;
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 56c2d8195ac6..2c78d188bb06 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -560,7 +560,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
if (dev->board.decoder == CX231XX_AVDECODER) {
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[0].i2c_adap,
- NULL, "cx25840", 0x88 >> 1, NULL);
+ "cx25840", 0x88 >> 1, NULL);
if (dev->sd_cx25840 == NULL)
cx231xx_info("cx25840 subdev registration failure\n");
cx25840_call(dev, core, load_fw);
@@ -571,7 +571,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
if (dev->board.tuner_type != TUNER_ABSENT) {
dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
- NULL, "tuner",
+ "tuner",
dev->tuner_addr, NULL);
if (dev->sd_tuner == NULL)
cx231xx_info("tuner subdev registration failure\n");
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index db054004e462..8861309268b1 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -1247,7 +1247,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200:
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[2].i2c_adap,
- NULL, "cx25840", 0x88 >> 1, NULL);
+ "cx25840", 0x88 >> 1, NULL);
if (dev->sd_cx25840) {
dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE;
v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 3cc9f462d08d..8b2fb8a4375c 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1507,10 +1507,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
if (dev->tuner_addr)
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[1].i2c_adap,
- NULL, "tuner", dev->tuner_addr, NULL);
+ "tuner", dev->tuner_addr, NULL);
else
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_bus[1].i2c_adap, NULL,
+ &dev->i2c_bus[1].i2c_adap,
"tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
if (sd) {
struct tuner_setup tun_setup;
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 417d1d5c73c4..d7c94848249e 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -33,7 +33,6 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware.h>
-#include <linux/smp_lock.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/cx2341x.h>
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index b26fcba8600c..9b9e169cce90 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -3515,19 +3515,18 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
later code configures a tea5767.
*/
v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- NULL, "tuner",
- 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
if (has_demod)
v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap, NULL, "tuner",
+ &core->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (core->board.tuner_addr == ADDR_UNSET) {
v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap, NULL, "tuner",
+ &core->i2c_adap, "tuner",
0, has_demod ? tv_addrs + 4 : tv_addrs);
} else {
v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- NULL, "tuner", core->board.tuner_addr, NULL);
+ "tuner", core->board.tuner_addr, NULL);
}
}
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index d2f159daa8b5..62cea9549404 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -31,7 +31,6 @@
#include <linux/kmod.h>
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -1896,14 +1895,13 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
if (core->board.audio_chip == V4L2_IDENT_WM8775)
v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
- NULL, "wm8775", 0x36 >> 1, NULL);
+ "wm8775", 0x36 >> 1, NULL);
if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
/* This probes for a tda9874 as is used on some
Pixelview Ultra boards. */
- v4l2_i2c_new_subdev(&core->v4l2_dev,
- &core->i2c_adap,
- NULL, "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
+ v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
+ "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
}
switch (core->boardnr) {
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index d8e38cc4ec40..7333a9bb2549 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -1986,7 +1986,6 @@ static __init int vpfe_probe(struct platform_device *pdev)
vpfe_dev->sd[i] =
v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
i2c_adap,
- NULL,
&sdinfo->board_info,
NULL);
if (vpfe_dev->sd[i]) {
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
index 6ac6acd16352..193abab6b355 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -2013,7 +2013,6 @@ static __init int vpif_probe(struct platform_device *pdev)
vpif_obj.sd[i] =
v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
i2c_adap,
- NULL,
&subdevdata->board_info,
NULL);
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 685f6a6ee603..412c65d54fe1 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -1553,7 +1553,7 @@ static __init int vpif_probe(struct platform_device *pdev)
for (i = 0; i < subdev_count; i++) {
vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
- i2c_adap, NULL,
+ i2c_adap,
&subdevdata[i].board_info,
NULL);
if (!vpif_obj.sd[i]) {
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 54859233f311..f7e9168157a5 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -2554,39 +2554,39 @@ void em28xx_card_setup(struct em28xx *dev)
/* request some modules */
if (dev->board.has_msp34xx)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "msp3400", 0, msp3400_addrs);
+ "msp3400", 0, msp3400_addrs);
if (dev->board.decoder == EM28XX_SAA711X)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "saa7115_auto", 0, saa711x_addrs);
+ "saa7115_auto", 0, saa711x_addrs);
if (dev->board.decoder == EM28XX_TVP5150)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tvp5150", 0, tvp5150_addrs);
+ "tvp5150", 0, tvp5150_addrs);
if (dev->em28xx_sensor == EM28XX_MT9V011) {
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "mt9v011", 0, mt9v011_addrs);
+ &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs);
v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
}
if (dev->board.adecoder == EM28XX_TVAUDIO)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tvaudio", dev->board.tvaudio_addr, NULL);
+ "tvaudio", dev->board.tvaudio_addr, NULL);
if (dev->board.tuner_type != TUNER_ABSENT) {
int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
if (dev->board.radio.type)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->board.radio_addr, NULL);
+ "tuner", dev->board.radio_addr, NULL);
if (has_demod)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
if (dev->tuner_addr == 0) {
enum v4l2_i2c_tuner_type type =
@@ -2594,14 +2594,14 @@ void em28xx_card_setup(struct em28xx *dev)
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(type));
if (sd)
dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
} else {
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->tuner_addr, NULL);
+ "tuner", dev->tuner_addr, NULL);
}
}
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
index 9a075d83dd1f..b8faff2dd711 100644
--- a/drivers/media/video/fsl-viu.c
+++ b/drivers/media/video/fsl-viu.c
@@ -1486,7 +1486,7 @@ static int __devinit viu_of_probe(struct platform_device *op,
ad = i2c_get_adapter(0);
viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
- NULL, "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
+ "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
viu_dev->vidq.timeout.function = viu_vid_timeout;
viu_dev->vidq.timeout.data = (unsigned long)viu_dev;
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9e8039ac909e..665191c9b407 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -239,19 +239,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
return -1;
if (hw == IVTV_HW_TUNER) {
/* special tuner handling */
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type,
- 0, itv->card_i2c->radio);
+ sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+ itv->card_i2c->radio);
if (sd)
sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type,
- 0, itv->card_i2c->demod);
+ sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+ itv->card_i2c->demod);
if (sd)
sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type,
- 0, itv->card_i2c->tv);
+ sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
+ itv->card_i2c->tv);
if (sd)
sd->grp_id = 1 << idx;
return sd ? 0 : -1;
@@ -267,17 +264,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
/* It's an I2C device other than an analog tuner or IR chip */
if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type, 0, I2C_ADDRS(hw_addrs[idx]));
+ adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
} else if (hw == IVTV_HW_CX25840) {
struct cx25840_platform_data pdata;
pdata.pvr150_workaround = itv->pvr150_workaround;
sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev,
- adap, NULL, type, 0, &pdata, hw_addrs[idx],
- NULL);
+ adap, type, 0, &pdata, hw_addrs[idx], NULL);
} else {
sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, NULL, type, hw_addrs[idx], NULL);
+ adap, type, hw_addrs[idx], NULL);
}
if (sd)
sd->grp_id = 1 << idx;
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 94ba698d0ad4..4e8fd965f151 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -185,17 +185,17 @@ static int mxb_probe(struct saa7146_dev *dev)
}
mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "saa7111", I2C_SAA7111A, NULL);
+ "saa7111", I2C_SAA7111A, NULL);
mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tea6420", I2C_TEA6420_1, NULL);
+ "tea6420", I2C_TEA6420_1, NULL);
mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tea6420", I2C_TEA6420_2, NULL);
+ "tea6420", I2C_TEA6420_2, NULL);
mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tea6415c", I2C_TEA6415C, NULL);
+ "tea6415c", I2C_TEA6415C, NULL);
mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tda9840", I2C_TDA9840, NULL);
+ "tda9840", I2C_TDA9840, NULL);
mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
- NULL, "tuner", I2C_TUNER, NULL);
+ "tuner", I2C_TUNER, NULL);
/* check if all devices are present */
if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index bef202752cc8..66ad516bdfd9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2088,16 +2088,14 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
" Setting up with specified i2c address 0x%x",
mid, i2caddr[0]);
sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
- NULL, fname,
- i2caddr[0], NULL);
+ fname, i2caddr[0], NULL);
} else {
pvr2_trace(PVR2_TRACE_INIT,
"Module ID %u:"
" Setting up with address probe list",
mid);
sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
- NULL, fname,
- 0, i2caddr);
+ fname, 0, i2caddr);
}
if (!sd) {
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index e62beb4efdb4..f3dc89da4c4e 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -62,7 +62,6 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
#include <linux/usb/input.h>
#endif
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index f5a46c458717..a845753665c1 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -49,7 +49,6 @@
#include <linux/videodev2.h>
#include <linux/version.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <media/videobuf-vmalloc.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index e8f13d3e2df1..1b93207c89e8 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -44,7 +44,7 @@ static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
return ERR_PTR(-ENOMEM);
sd = v4l2_i2c_new_subdev_board(&vid_cap->v4l2_dev, i2c_adap,
- MODULE_NAME, isp_info->board_info, NULL);
+ isp_info->board_info, NULL);
if (!sd) {
v4l2_err(&vid_cap->v4l2_dev, "failed to acquire subdev\n");
return NULL;
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 0911cb580e18..1d4d0a49ea52 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -7551,22 +7551,22 @@ int saa7134_board_init2(struct saa7134_dev *dev)
so we do not need to probe for a radio tuner device. */
if (dev->radio_type != UNSET)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
dev->radio_addr, NULL);
if (has_demod)
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, 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_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
0, v4l2_i2c_tuner_addrs(type));
} else {
v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "tuner",
+ &dev->i2c_adap, "tuner",
dev->tuner_addr, NULL);
}
}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 764d7d219fed..756a27812260 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -991,7 +991,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
if (card_is_empress(dev)) {
struct v4l2_subdev *sd =
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "saa6752hs",
+ "saa6752hs",
saa7134_boards[dev->board].empress_addr, NULL);
if (sd)
@@ -1002,7 +1002,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
struct v4l2_subdev *sd;
sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
- &dev->i2c_adap, NULL, "saa6588",
+ &dev->i2c_adap, "saa6588",
0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
if (sd) {
printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 1467a30a434f..b890aafe7d64 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -21,7 +21,6 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include "saa7134-reg.h"
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
index 1d9c5cbbbc52..041ae8e20f68 100644
--- a/drivers/media/video/saa7164/saa7164.h
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -58,7 +58,6 @@
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
#include <media/videobuf-dvb.h>
-#include <linux/smp_lock.h>
#include <dvb_demux.h>
#include <dvb_frontend.h>
#include <dvb_net.h>
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
index 0f4906136b8f..4e5a8cf76ded 100644
--- a/drivers/media/video/sh_vou.c
+++ b/drivers/media/video/sh_vou.c
@@ -1406,7 +1406,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
goto ereset;
subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap,
- NULL, vou_pdata->board_info, NULL);
+ vou_pdata->board_info, NULL);
if (!subdev) {
ret = -ENOMEM;
goto ei2cnd;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 43848a751d11..335120c2021b 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -896,7 +896,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
icl->board_info->platform_data = icd;
subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
- NULL, icl->board_info, NULL);
+ icl->board_info, NULL);
if (!subdev)
goto ei2cnd;
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index e3bbae26e3ce..81dd53bb5267 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -251,7 +251,7 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
hit-and-miss. */
mdelay(10);
v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap, NULL,
+ &usbvision->i2c_adap,
"saa7115_auto", 0, saa711x_addrs);
break;
}
@@ -261,14 +261,14 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
struct tuner_setup tun_setup;
sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap, NULL,
+ &usbvision->i2c_adap,
"tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
/* depending on whether we found a demod or not, select
the tuner type. */
type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
- &usbvision->i2c_adap, NULL,
+ &usbvision->i2c_adap,
"tuner", 0, v4l2_i2c_tuner_addrs(type));
if (sd == NULL)
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index db6b828594f5..011c0c386995 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -50,7 +50,6 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/vmalloc.h>
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 9294282b5add..b5eb1f3950b1 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -368,18 +368,15 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
/* Load an i2c sub-device. */
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter, const char *module_name,
- struct i2c_board_info *info, const unsigned short *probe_addrs)
+ struct i2c_adapter *adapter, struct i2c_board_info *info,
+ const unsigned short *probe_addrs)
{
struct v4l2_subdev *sd = NULL;
struct i2c_client *client;
BUG_ON(!v4l2_dev);
- if (module_name)
- request_module(module_name);
- else
- request_module(I2C_MODULE_PREFIX "%s", info->type);
+ request_module(I2C_MODULE_PREFIX "%s", info->type);
/* Create the i2c client */
if (info->addr == 0 && probe_addrs)
@@ -432,8 +429,7 @@ error:
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
- struct i2c_adapter *adapter,
- const char *module_name, const char *client_type,
+ struct i2c_adapter *adapter, const char *client_type,
int irq, void *platform_data,
u8 addr, const unsigned short *probe_addrs)
{
@@ -447,8 +443,7 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
info.irq = irq;
info.platform_data = platform_data;
- return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, module_name,
- &info, probe_addrs);
+ return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg);
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 86294ed35c9b..e30e8dfb6205 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -18,7 +18,6 @@
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <media/v4l2-ioctl.h>
#ifdef CONFIG_COMPAT
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 02a21bccae18..9eda7cc03121 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -1360,7 +1360,7 @@ static __devinit int viacam_probe(struct platform_device *pdev)
*/
sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, sensor_adapter,
- "ov7670", "ov7670", 0x42 >> 1, NULL);
+ "ov7670", 0x42 >> 1, NULL);
if (cam->sensor == NULL) {
dev_err(&pdev->dev, "Unable to find the sensor!\n");
ret = -ENODEV;
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index e5e005dc1554..7e7eec48f8b1 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -4334,10 +4334,10 @@ static int __init vino_module_init(void)
vino_drvdata->decoder =
v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
- NULL, "saa7191", 0, I2C_ADDRS(0x45));
+ "saa7191", 0, I2C_ADDRS(0x45));
vino_drvdata->camera =
v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
- NULL, "indycam", 0, I2C_ADDRS(0x2b));
+ "indycam", 0, I2C_ADDRS(0x2b));
dprintk("init complete!\n");
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 7e6d62467eaa..e520abf9f4c3 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1343,13 +1343,12 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
}
zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
- &zr->i2c_adapter, NULL, zr->card.i2c_decoder,
+ &zr->i2c_adapter, zr->card.i2c_decoder,
0, zr->card.addrs_decoder);
if (zr->card.i2c_encoder)
zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
- &zr->i2c_adapter,
- NULL, zr->card.i2c_encoder,
+ &zr->i2c_adapter, zr->card.i2c_encoder,
0, zr->card.addrs_encoder);
dprintk(2,
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index e15220ff52fc..d784c36707c0 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -97,8 +97,7 @@ static u8 mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptfc_target_alloc(struct scsi_target *starget);
static int mptfc_slave_alloc(struct scsi_device *sdev);
-static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
- void (*done)(struct scsi_cmnd *));
+static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
static void mptfc_target_destroy(struct scsi_target *starget);
static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
static void __devexit mptfc_remove(struct pci_dev *pdev);
@@ -650,7 +649,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
}
static int
-mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
struct mptfc_rport_info *ri;
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
@@ -681,6 +680,8 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return mptscsih_qcmd(SCpnt,done);
}
+static DEF_SCSI_QCMD(mptfc_qcmd)
+
/*
* mptfc_display_port_link_speed - displaying link speed
* @ioc: Pointer to MPT_ADAPTER structure
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 83a5115f0251..d48c2c6058e1 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1889,7 +1889,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
}
static int
-mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
MPT_SCSI_HOST *hd;
MPT_ADAPTER *ioc;
@@ -1913,6 +1913,8 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return mptscsih_qcmd(SCpnt,done);
}
+static DEF_SCSI_QCMD(mptsas_qcmd)
+
/**
* mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
* if the device under question is currently in the
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 0e2803155ae2..6d9568d2ec59 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -780,7 +780,7 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
}
static int
-mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+mptspi_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host);
VirtDevice *vdevice = SCpnt->device->hostdata;
@@ -805,6 +805,8 @@ mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return mptscsih_qcmd(SCpnt,done);
}
+static DEF_SCSI_QCMD(mptspi_qcmd)
+
static void mptspi_slave_destroy(struct scsi_device *sdev)
{
struct scsi_target *starget = scsi_target(sdev);
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index ea6b2197da8a..97bdf82ec905 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -506,7 +506,7 @@ static struct i2o_driver i2o_scsi_driver = {
* Locks: takes the controller lock on error path only
*/
-static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
+static int i2o_scsi_queuecommand_lck(struct scsi_cmnd *SCpnt,
void (*done) (struct scsi_cmnd *))
{
struct i2o_controller *c;
@@ -688,7 +688,9 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
exit:
return rc;
-};
+}
+
+static DEF_SCSI_QCMD(i2o_scsi_queuecommand)
/**
* i2o_scsi_abort - abort a running command
diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c
index ca47e6285075..307aada5fffe 100644
--- a/drivers/misc/isl29020.c
+++ b/drivers/misc/isl29020.c
@@ -183,9 +183,7 @@ static int isl29020_probe(struct i2c_client *client,
static int isl29020_remove(struct i2c_client *client)
{
- struct als_data *data = i2c_get_clientdata(client);
sysfs_remove_group(&client->dev.kobj, &m_als_gr);
- kfree(data);
return 0;
}
@@ -245,6 +243,6 @@ static void __exit sensor_isl29020_exit(void)
module_init(sensor_isl29020_init);
module_exit(sensor_isl29020_exit);
-MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com>");
MODULE_DESCRIPTION("Intersil isl29020 ALS Driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index d551f09ccb79..6956f7e7d439 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -439,18 +439,23 @@ xpc_discovery(void)
* nodes that can comprise an access protection grouping. The access
* protection is in regards to memory, IOI and IPI.
*/
- max_regions = 64;
region_size = xp_region_size;
- switch (region_size) {
- case 128:
- max_regions *= 2;
- case 64:
- max_regions *= 2;
- case 32:
- max_regions *= 2;
- region_size = 16;
- DBUG_ON(!is_shub2());
+ if (is_uv())
+ max_regions = 256;
+ else {
+ max_regions = 64;
+
+ switch (region_size) {
+ case 128:
+ max_regions *= 2;
+ case 64:
+ max_regions *= 2;
+ case 32:
+ max_regions *= 2;
+ region_size = 16;
+ DBUG_ON(!is_shub2());
+ }
}
for (region = 0; region < max_regions; region++) {
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8f86d702e46e..31ae07a36576 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host)
if (host->caps & MMC_CAP_DISABLE)
cancel_delayed_work(&host->disable);
- cancel_delayed_work(&host->detect);
+ cancel_delayed_work_sync(&host->detect);
mmc_flush_scheduled_work();
/* clear pm flags now and let card drivers set them as needed */
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 995261f7fd70..77f93c3b8808 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
struct mmc_card *oldcard)
{
struct mmc_card *card;
- int err, ddr = MMC_SDR_MODE;
+ int err, ddr = 0;
u32 cid[4];
unsigned int max_dtr;
@@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
1 << bus_width, ddr);
err = 0;
} else {
- mmc_card_set_ddr_mode(card);
+ if (ddr)
+ mmc_card_set_ddr_mode(card);
+ else
+ ddr = MMC_SDR_MODE;
+
mmc_set_bus_width_ddr(card->host, bus_width, ddr);
}
}
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index c3ad1058cd31..efef5f94ac42 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host)
BUG_ON(!host->card);
/* Make sure card is powered before detecting it */
- err = pm_runtime_get_sync(&host->card->dev);
- if (err < 0)
- goto out;
+ if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+ err = pm_runtime_get_sync(&host->card->dev);
+ if (err < 0)
+ goto out;
+ }
mmc_claim_host(host);
@@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_host *host)
mmc_release_host(host);
+ /*
+ * Tell PM core it's OK to power off the card now.
+ *
+ * The _sync variant is used in order to ensure that the card
+ * is left powered off in case an error occurred, and the card
+ * is going to be removed.
+ *
+ * Since there is no specific reason to believe a new user
+ * is about to show up at this point, the _sync variant is
+ * desirable anyway.
+ */
+ if (host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_put_sync(&host->card->dev);
+
out:
if (err) {
mmc_sdio_remove(host);
@@ -568,9 +584,6 @@ out:
mmc_detach_bus(host);
mmc_release_host(host);
}
-
- /* Tell PM core that we're done */
- pm_runtime_put(&host->card->dev);
}
/*
@@ -718,16 +731,21 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
card = host->card;
/*
- * Let runtime PM core know our card is active
+ * Enable runtime PM only if supported by host+card+board
*/
- err = pm_runtime_set_active(&card->dev);
- if (err)
- goto remove;
+ if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+ /*
+ * Let runtime PM core know our card is active
+ */
+ err = pm_runtime_set_active(&card->dev);
+ if (err)
+ goto remove;
- /*
- * Enable runtime PM for this card
- */
- pm_runtime_enable(&card->dev);
+ /*
+ * Enable runtime PM for this card
+ */
+ pm_runtime_enable(&card->dev);
+ }
/*
* The number of functions on the card is encoded inside
@@ -745,9 +763,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
goto remove;
/*
- * Enable Runtime PM for this func
+ * Enable Runtime PM for this func (if supported)
*/
- pm_runtime_enable(&card->sdio_func[i]->dev);
+ if (host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_enable(&card->sdio_func[i]->dev);
}
mmc_release_host(host);
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 2716c7ab6bbf..203da443e339 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -17,6 +17,7 @@
#include <linux/pm_runtime.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
#include <linux/mmc/sdio_func.h>
#include "sdio_cis.h"
@@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev)
* it should call pm_runtime_put_noidle() in its probe routine and
* pm_runtime_get_noresume() in its remove routine.
*/
- ret = pm_runtime_get_sync(dev);
- if (ret < 0)
- goto out;
+ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ goto out;
+ }
/* Set the default block size so the driver is sure it's something
* sensible. */
@@ -151,7 +154,8 @@ static int sdio_bus_probe(struct device *dev)
return 0;
disable_runtimepm:
- pm_runtime_put_noidle(dev);
+ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_put_noidle(dev);
out:
return ret;
}
@@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev)
{
struct sdio_driver *drv = to_sdio_driver(dev->driver);
struct sdio_func *func = dev_to_sdio_func(dev);
- int ret;
+ int ret = 0;
/* Make sure card is powered before invoking ->remove() */
- ret = pm_runtime_get_sync(dev);
- if (ret < 0)
- goto out;
+ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ goto out;
+ }
drv->remove(func);
@@ -178,10 +184,12 @@ static int sdio_bus_remove(struct device *dev)
}
/* First, undo the increment made directly above */
- pm_runtime_put_noidle(dev);
+ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_put_noidle(dev);
/* Then undo the runtime PM settings in sdio_bus_probe() */
- pm_runtime_put_noidle(dev);
+ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_put_noidle(dev);
out:
return ret;
@@ -191,6 +199,8 @@ out:
static int sdio_bus_pm_prepare(struct device *dev)
{
+ struct sdio_func *func = dev_to_sdio_func(dev);
+
/*
* Resume an SDIO device which was suspended at run time at this
* point, in order to allow standard SDIO suspend/resume paths
@@ -212,7 +222,8 @@ static int sdio_bus_pm_prepare(struct device *dev)
* since there is little point in failing system suspend if a
* device can't be resumed.
*/
- pm_runtime_resume(dev);
+ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_resume(dev);
return 0;
}
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 82a1079bbdc7..5d46021cbb57 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
* Monitor a 0->1 transition first
*/
if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
- while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit))
+ while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
&& (i++ < limit))
cpu_relax();
}
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 2e9cca19c90b..9b82910b9dbb 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -17,6 +17,7 @@
#include <linux/clk.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h>
+#include <mach/hardware.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
@@ -112,6 +113,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
clk_enable(clk);
pltfm_host->clk = clk;
+ if (cpu_is_mx35() || cpu_is_mx51())
+ host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+
+ /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */
+ if (cpu_is_mx25() || cpu_is_mx35())
+ host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+
return 0;
}
@@ -133,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = {
};
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK
- | SDHCI_QUIRK_BROKEN_ADMA,
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,
/* ADMA has issues. Might be fixable */
- /* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */
.ops = &sdhci_esdhc_ops,
.init = esdhc_pltfm_init,
.exit = esdhc_pltfm_exit,
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 55746bac2f44..3d9c2460d437 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = {
* ADMA operation is disabled for Moorestown platform due to
* hardware bugs.
*/
-static int mrst_hc1_probe(struct sdhci_pci_chip *chip)
+static int mrst_hc_probe(struct sdhci_pci_chip *chip)
{
/*
- * slots number is fixed here for MRST as SDIO3 is never used and has
- * hardware bugs.
+ * slots number is fixed here for MRST as SDIO3/5 are never used and
+ * have hardware bugs.
*/
chip->num_slots = 1;
return 0;
@@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
.quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
};
-static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1 = {
+static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
.quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
- .probe = mrst_hc1_probe,
+ .probe = mrst_hc_probe,
};
static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
@@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
.device = PCI_DEVICE_ID_INTEL_MRST_SD1,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
- .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
+ },
+
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_MRST_SD2,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
},
{
@@ -637,6 +645,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{
struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot;
+ mmc_pm_flag_t slot_pm_flags;
mmc_pm_flag_t pm_flags = 0;
int i, ret;
@@ -657,7 +666,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
return ret;
}
- pm_flags |= slot->host->mmc->pm_flags;
+ slot_pm_flags = slot->host->mmc->pm_flags;
+ if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
+ sdhci_enable_irq_wakeups(slot->host);
+
+ pm_flags |= slot_pm_flags;
}
if (chip->fixes && chip->fixes->suspend) {
@@ -671,8 +684,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev);
if (pm_flags & MMC_PM_KEEP_POWER) {
- if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
+ if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) {
+ pci_pme_active(pdev, true);
pci_enable_wake(pdev, PCI_D3hot, 1);
+ }
pci_set_power_state(pdev, PCI_D3hot);
} else {
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c
index fc406ac5d193..5a61208cbc66 100644
--- a/drivers/mmc/host/sdhci-pxa.c
+++ b/drivers/mmc/host/sdhci-pxa.c
@@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
if (pdata->quirks)
host->quirks |= pdata->quirks;
+ /* If slot design supports 8 bit data, indicate this to MMC. */
+ if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
+ host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+
ret = sdhci_add_host(host);
if (ret) {
dev_err(&pdev->dev, "failed to add host\n");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 782c0ee3c925..a25db426c910 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1185,17 +1185,31 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->ops->platform_send_init_74_clocks)
host->ops->platform_send_init_74_clocks(host, ios->power_mode);
- ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
-
- if (ios->bus_width == MMC_BUS_WIDTH_8)
- ctrl |= SDHCI_CTRL_8BITBUS;
- else
- ctrl &= ~SDHCI_CTRL_8BITBUS;
+ /*
+ * If your platform has 8-bit width support but is not a v3 controller,
+ * or if it requires special setup code, you should implement that in
+ * platform_8bit_width().
+ */
+ if (host->ops->platform_8bit_width)
+ host->ops->platform_8bit_width(host, ios->bus_width);
+ else {
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+ if (ios->bus_width == MMC_BUS_WIDTH_8) {
+ ctrl &= ~SDHCI_CTRL_4BITBUS;
+ if (host->version >= SDHCI_SPEC_300)
+ ctrl |= SDHCI_CTRL_8BITBUS;
+ } else {
+ if (host->version >= SDHCI_SPEC_300)
+ ctrl &= ~SDHCI_CTRL_8BITBUS;
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ ctrl |= SDHCI_CTRL_4BITBUS;
+ else
+ ctrl &= ~SDHCI_CTRL_4BITBUS;
+ }
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+ }
- if (ios->bus_width == MMC_BUS_WIDTH_4)
- ctrl |= SDHCI_CTRL_4BITBUS;
- else
- ctrl &= ~SDHCI_CTRL_4BITBUS;
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if ((ios->timing == MMC_TIMING_SD_HS ||
ios->timing == MMC_TIMING_MMC_HS)
@@ -1681,6 +1695,16 @@ int sdhci_resume_host(struct sdhci_host *host)
EXPORT_SYMBOL_GPL(sdhci_resume_host);
+void sdhci_enable_irq_wakeups(struct sdhci_host *host)
+{
+ u8 val;
+ val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
+ val |= SDHCI_WAKE_ON_INT;
+ sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
+}
+
+EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
+
#endif /* CONFIG_PM */
/*****************************************************************************\
@@ -1845,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
else
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
+
mmc->f_max = host->max_clk;
mmc->caps |= MMC_CAP_SDIO_IRQ;
+ /*
+ * A controller may support 8-bit width, but the board itself
+ * might not have the pins brought out. Boards that support
+ * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in
+ * their platform code before calling sdhci_add_host(), and we
+ * won't assume 8-bit width for hosts without that CAP.
+ */
if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
- mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
+ mmc->caps |= MMC_CAP_4_BIT_DATA;
if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index b7b8a3b28b01..e42d7f00c060 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -76,7 +76,7 @@
#define SDHCI_CTRL_ADMA1 0x08
#define SDHCI_CTRL_ADMA32 0x10
#define SDHCI_CTRL_ADMA64 0x18
-#define SDHCI_CTRL_8BITBUS 0x20
+#define SDHCI_CTRL_8BITBUS 0x20
#define SDHCI_POWER_CONTROL 0x29
#define SDHCI_POWER_ON 0x01
@@ -87,6 +87,9 @@
#define SDHCI_BLOCK_GAP_CONTROL 0x2A
#define SDHCI_WAKE_UP_CONTROL 0x2B
+#define SDHCI_WAKE_ON_INT 0x01
+#define SDHCI_WAKE_ON_INSERT 0x02
+#define SDHCI_WAKE_ON_REMOVE 0x04
#define SDHCI_CLOCK_CONTROL 0x2C
#define SDHCI_DIVIDER_SHIFT 8
@@ -152,6 +155,7 @@
#define SDHCI_CLOCK_BASE_SHIFT 8
#define SDHCI_MAX_BLOCK_MASK 0x00030000
#define SDHCI_MAX_BLOCK_SHIFT 16
+#define SDHCI_CAN_DO_8BIT 0x00040000
#define SDHCI_CAN_DO_ADMA2 0x00080000
#define SDHCI_CAN_DO_ADMA1 0x00100000
#define SDHCI_CAN_DO_HISPD 0x00200000
@@ -212,6 +216,8 @@ struct sdhci_ops {
unsigned int (*get_max_clock)(struct sdhci_host *host);
unsigned int (*get_min_clock)(struct sdhci_host *host);
unsigned int (*get_timeout_clock)(struct sdhci_host *host);
+ int (*platform_8bit_width)(struct sdhci_host *host,
+ int width);
void (*platform_send_init_74_clocks)(struct sdhci_host *host,
u8 power_mode);
unsigned int (*get_ro)(struct sdhci_host *host);
@@ -317,6 +323,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
#ifdef CONFIG_PM
extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
extern int sdhci_resume_host(struct sdhci_host *host);
+extern void sdhci_enable_irq_wakeups(struct sdhci_host *host);
#endif
#endif /* __SDHCI_HW_H */
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c
index b4ead4a13c98..f8f65df9b017 100644
--- a/drivers/mmc/host/ushc.c
+++ b/drivers/mmc/host/ushc.c
@@ -425,7 +425,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct mmc_host *mmc;
struct ushc_data *ushc;
- int ret = -ENOMEM;
+ int ret;
mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
if (mmc == NULL)
@@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
mmc->max_blk_count = 511;
ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (ushc->int_urb == NULL)
+ if (ushc->int_urb == NULL) {
+ ret = -ENOMEM;
goto err;
+ }
ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL);
- if (ushc->int_data == NULL)
+ if (ushc->int_data == NULL) {
+ ret = -ENOMEM;
goto err;
+ }
usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,
usb_rcvintpipe(usb_dev,
intf->cur_altsetting->endpoint[0].desc.bEndpointAddress),
@@ -475,11 +479,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
intf->cur_altsetting->endpoint[0].desc.bInterval);
ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (ushc->cbw_urb == NULL)
+ if (ushc->cbw_urb == NULL) {
+ ret = -ENOMEM;
goto err;
+ }
ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
- if (ushc->cbw == NULL)
+ if (ushc->cbw == NULL) {
+ ret = -ENOMEM;
goto err;
+ }
ushc->cbw->signature = USHC_CBW_SIGNATURE;
usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2),
@@ -487,15 +495,21 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
cbw_callback, ushc);
ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (ushc->data_urb == NULL)
+ if (ushc->data_urb == NULL) {
+ ret = -ENOMEM;
goto err;
+ }
ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (ushc->csw_urb == NULL)
+ if (ushc->csw_urb == NULL) {
+ ret = -ENOMEM;
goto err;
+ }
ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
- if (ushc->csw == NULL)
+ if (ushc->csw == NULL) {
+ ret = -ENOMEM;
goto err;
+ }
usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),
ushc->csw, sizeof(struct ushc_csw),
csw_callback, ushc);
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index c2960ac9f39c..811775aa8ee8 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -482,10 +482,17 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
uint32_t data = 0;
struct ubi_vid_hdr vid_hdr;
- addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
+ /*
+ * It is important to first invalidate the EC header, and then the VID
+ * header. Otherwise a power cut may lead to valid EC header and
+ * invalid VID header, in which case UBI will treat this PEB as
+ * corrupted and will try to preserve it, and print scary warnings (see
+ * the header comment in scan.c for more information).
+ */
+ addr = (loff_t)pnum * ubi->peb_size;
err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
if (!err) {
- addr -= ubi->vid_hdr_aloffset;
+ addr += ubi->vid_hdr_aloffset;
err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
(void *)&data);
if (!err)
@@ -494,18 +501,24 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
/*
* We failed to write to the media. This was observed with Spansion
- * S29GL512N NOR flash. Most probably the eraseblock erasure was
- * interrupted at a very inappropriate moment, so it became unwritable.
- * In this case we probably anyway have garbage in this PEB.
+ * S29GL512N NOR flash. Most probably the previously eraseblock erasure
+ * was interrupted at a very inappropriate moment, so it became
+ * unwritable. In this case we probably anyway have garbage in this
+ * PEB.
*/
err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
- if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
- /*
- * The VID header is corrupted, so we can safely erase this
- * PEB and not afraid that it will be treated as a valid PEB in
- * case of an unclean reboot.
- */
- return 0;
+ if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) {
+ struct ubi_ec_hdr ec_hdr;
+
+ err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
+ if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR)
+ /*
+ * Both VID and EC headers are corrupted, so we can
+ * safely erase this PEB and not afraid that it will be
+ * treated as a valid PEB in case of an unclean reboot.
+ */
+ return 0;
+ }
/*
* The PEB contains a valid VID header, but we cannot invalidate it.
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 3c631863bf40..79ca304fc4db 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -787,16 +787,15 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
* erased, so it became unstable and corrupted, and should be
* erased.
*/
- return 0;
+ err = 0;
+ goto out_unlock;
}
if (err)
- return err;
+ goto out_unlock;
- if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size)) {
- mutex_unlock(&ubi->buf_mutex);
- return 0;
- }
+ if (ubi_check_pattern(ubi->peb_buf1, 0xFF, ubi->leb_size))
+ goto out_unlock;
ubi_err("PEB %d contains corrupted VID header, and the data does not "
"contain all 0xFF, this may be a non-UBI PEB or a severe VID "
@@ -806,8 +805,11 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr,
pnum, ubi->leb_start, ubi->leb_size);
ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
ubi->peb_buf1, ubi->leb_size, 1);
+ err = 1;
+
+out_unlock:
mutex_unlock(&ubi->buf_mutex);
- return 1;
+ return err;
}
/**
@@ -951,6 +953,10 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
* impossible to distinguish it from a PEB which just
* contains garbage because of a power cut during erase
* operation. So we just schedule this PEB for erasure.
+ *
+ * Besides, in case of NOR flash, we deliberatly
+ * corrupt both headers because NOR flash erasure is
+ * slow and can start from the end.
*/
err = 0;
else
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index e1da258bbfb7..0a92436f0538 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -699,7 +699,8 @@ DEFINE_WINDOW_IO(32)
#define DEVICE_PCI(dev) NULL
#endif
-#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
+#define VORTEX_PCI(vp) \
+ ((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL))
#ifdef CONFIG_EISA
#define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
@@ -707,7 +708,8 @@ DEFINE_WINDOW_IO(32)
#define DEVICE_EISA(dev) NULL
#endif
-#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)
+#define VORTEX_EISA(vp) \
+ ((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL))
/* The action to take with a media selection timer tick.
Note that we deviate from the 3Com order by checking 10base2 before AUI.
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index ac422cd332ea..dd16e83933a2 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -490,13 +490,11 @@ static inline unsigned int cp_rx_csum_ok (u32 status)
{
unsigned int protocol = (status >> 16) & 0x3;
- if (likely((protocol == RxProtoTCP) && (!(status & TCPFail))))
+ if (((protocol == RxProtoTCP) && !(status & TCPFail)) ||
+ ((protocol == RxProtoUDP) && !(status & UDPFail)))
return 1;
- else if ((protocol == RxProtoUDP) && (!(status & UDPFail)))
- return 1;
- else if ((protocol == RxProtoIP) && (!(status & IPFail)))
- return 1;
- return 0;
+ else
+ return 0;
}
static int cp_rx_poll(struct napi_struct *napi, int budget)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f6668cdaac85..4f1755bddf6b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2543,10 +2543,10 @@ config PCH_GBE
depends on PCI
select MII
---help---
- This is a gigabit ethernet driver for Topcliff PCH.
- Topcliff PCH is the platform controller hub that is used in Intel's
+ This is a gigabit ethernet driver for EG20T PCH.
+ EG20T PCH is the platform controller hub that is used in Intel's
general embedded platform.
- Topcliff PCH has Gigabit Ethernet interface.
+ EG20T PCH has Gigabit Ethernet interface.
Using this interface, it is able to access system devices connected
to Gigabit Ethernet.
This driver enables Gigabit Ethernet function.
@@ -2945,6 +2945,18 @@ source "drivers/s390/net/Kconfig"
source "drivers/net/caif/Kconfig"
+config TILE_NET
+ tristate "Tilera GBE/XGBE network driver support"
+ depends on TILE
+ default y
+ select CRC32
+ help
+ This is a standard Linux network device driver for the
+ on-chip Tilera Gigabit Ethernet and XAUI interfaces.
+
+ To compile this driver as a module, choose M here: the module
+ will be called tile_net.
+
config XEN_NETDEV_FRONTEND
tristate "Xen network device frontend driver"
depends on XEN
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 652fc6b98039..b90738d13994 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -301,3 +301,4 @@ obj-$(CONFIG_CAIF) += caif/
obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
obj-$(CONFIG_PCH_GBE) += pch_gbe/
+obj-$(CONFIG_TILE_NET) += tile/
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c
index 919080b2c3a5..1bf672009948 100644
--- a/drivers/net/atl1c/atl1c_hw.c
+++ b/drivers/net/atl1c/atl1c_hw.c
@@ -82,7 +82,7 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw)
addr[0] = addr[1] = 0;
AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
if (atl1c_check_eeprom_exist(hw)) {
- if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) {
+ if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
/* Enable OTP CLK */
if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
otp_ctrl_data |= OTP_CTRL_CLK_EN;
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 43489f89c142..53eff9ba6e95 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -155,10 +155,10 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
spin_lock_irqsave(&aup->lock, flags);
if (force_reset || (!aup->mac_enabled)) {
- writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
+ writel(MAC_EN_CLOCK_ENABLE, aup->enable);
au_sync_delay(2);
writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
- | MAC_EN_CLOCK_ENABLE), &aup->enable);
+ | MAC_EN_CLOCK_ENABLE), aup->enable);
au_sync_delay(2);
aup->mac_enabled = 1;
@@ -503,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
au1000_hard_stop(dev);
- writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
+ writel(MAC_EN_CLOCK_ENABLE, aup->enable);
au_sync_delay(2);
- writel(0, &aup->enable);
+ writel(0, aup->enable);
au_sync_delay(2);
aup->tx_full = 0;
@@ -1119,7 +1119,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
/* set a random MAC now in case platform_data doesn't provide one */
random_ether_addr(dev->dev_addr);
- writel(0, &aup->enable);
+ writel(0, aup->enable);
aup->mac_enabled = 0;
pd = pdev->dev.platform_data;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index c36cd2ffbadc..93354eee2cfd 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -2458,6 +2458,12 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
int status, i = 0, num_imgs = 0;
const u8 *p;
+ if (!netif_running(adapter->netdev)) {
+ dev_err(&adapter->pdev->dev,
+ "Firmware load not allowed (interface is down)\n");
+ return -EPERM;
+ }
+
strcpy(fw_file, func);
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index e9ad16f00b56..9709b8569666 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -9064,7 +9064,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
default:
pr_err("Unknown board_type (%ld), aborting\n",
ent->driver_data);
- return ENODEV;
+ return -ENODEV;
}
cid_count += CNIC_CONTEXT_USE;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index bdb68a600382..71a169740d05 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -878,8 +878,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev)
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
if (in_dev) {
+ read_lock(&in_dev->mc_list_lock);
for (im = in_dev->mc_list; im; im = im->next)
ip_mc_rejoin_group(im);
+ read_unlock(&in_dev->mc_list_lock);
}
rcu_read_unlock();
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index 8b4cea57a6c5..20da1996d354 100644
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -635,8 +635,8 @@ int cfspi_spi_probe(struct platform_device *pdev)
ndev = alloc_netdev(sizeof(struct cfspi),
"cfspi%d", cfspi_setup);
- if (!dev)
- return -ENODEV;
+ if (!ndev)
+ return -ENOMEM;
cfspi = netdev_priv(ndev);
netif_stop_queue(ndev);
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index c3449bbc585a..d887a76cd39d 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -816,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev)
}
/*
- * Collect up to maxaddrs worth of a netdevice's unicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
*/
-static inline int collect_netdev_uc_list_addrs(const struct net_device *dev,
- const u8 **addr,
- unsigned int maxaddrs)
+static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev,
+ const u8 **addr,
+ unsigned int offset,
+ unsigned int maxaddrs)
{
+ unsigned int index = 0;
unsigned int naddr = 0;
const struct netdev_hw_addr *ha;
- for_each_dev_addr(dev, ha) {
- addr[naddr++] = ha->addr;
- if (naddr >= maxaddrs)
- break;
- }
+ for_each_dev_addr(dev, ha)
+ if (index++ >= offset) {
+ addr[naddr++] = ha->addr;
+ if (naddr >= maxaddrs)
+ break;
+ }
return naddr;
}
/*
- * Collect up to maxaddrs worth of a netdevice's multicast addresses into an
- * array of addrss pointers and return the number collected.
+ * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting
+ * at a specified offset within the list, into an array of addrss pointers and
+ * return the number collected.
*/
-static inline int collect_netdev_mc_list_addrs(const struct net_device *dev,
- const u8 **addr,
- unsigned int maxaddrs)
+static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev,
+ const u8 **addr,
+ unsigned int offset,
+ unsigned int maxaddrs)
{
+ unsigned int index = 0;
unsigned int naddr = 0;
const struct netdev_hw_addr *ha;
- netdev_for_each_mc_addr(ha, dev) {
- addr[naddr++] = ha->addr;
- if (naddr >= maxaddrs)
- break;
- }
+ netdev_for_each_mc_addr(ha, dev)
+ if (index++ >= offset) {
+ addr[naddr++] = ha->addr;
+ if (naddr >= maxaddrs)
+ break;
+ }
return naddr;
}
@@ -862,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
u64 mhash = 0;
u64 uhash = 0;
bool free = true;
- u16 filt_idx[7];
+ unsigned int offset, naddr;
const u8 *addr[7];
- int ret, naddr = 0;
+ int ret;
const struct port_info *pi = netdev_priv(dev);
/* first do the secondary unicast addresses */
- naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr));
- if (naddr > 0) {
+ for (offset = 0; ; offset += naddr) {
+ naddr = collect_netdev_uc_list_addrs(dev, addr, offset,
+ ARRAY_SIZE(addr));
+ if (naddr == 0)
+ break;
+
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
- naddr, addr, filt_idx, &uhash, sleep);
+ naddr, addr, NULL, &uhash, sleep);
if (ret < 0)
return ret;
@@ -879,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
}
/* next set up the multicast addresses */
- naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr));
- if (naddr > 0) {
+ for (offset = 0; ; offset += naddr) {
+ naddr = collect_netdev_mc_list_addrs(dev, addr, offset,
+ ARRAY_SIZE(addr));
+ if (naddr == 0)
+ break;
+
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
- naddr, addr, filt_idx, &mhash, sleep);
+ naddr, addr, NULL, &mhash, sleep);
if (ret < 0)
return ret;
+ free = false;
}
return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,
diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c
index e306c20dfaee..19520afe1a12 100644
--- a/drivers/net/cxgb4vf/t4vf_hw.c
+++ b/drivers/net/cxgb4vf/t4vf_hw.c
@@ -1014,48 +1014,72 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
unsigned int naddr, const u8 **addr, u16 *idx,
u64 *hash, bool sleep_ok)
{
- int i, ret;
+ int offset, ret = 0;
+ unsigned nfilters = 0;
+ unsigned int rem = naddr;
struct fw_vi_mac_cmd cmd, rpl;
- struct fw_vi_mac_exact *p;
- size_t len16;
- if (naddr > ARRAY_SIZE(cmd.u.exact))
+ if (naddr > FW_CLS_TCAM_NUM_ENTRIES)
return -EINVAL;
- len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
- u.exact[naddr]), 16);
- memset(&cmd, 0, sizeof(cmd));
- cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
- FW_CMD_REQUEST |
- FW_CMD_WRITE |
- (free ? FW_CMD_EXEC : 0) |
- FW_VI_MAC_CMD_VIID(viid));
- cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
- FW_CMD_LEN16(len16));
+ for (offset = 0; offset < naddr; /**/) {
+ unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
+ ? rem
+ : ARRAY_SIZE(cmd.u.exact));
+ size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
+ u.exact[fw_naddr]), 16);
+ struct fw_vi_mac_exact *p;
+ int i;
- for (i = 0, p = cmd.u.exact; i < naddr; i++, p++) {
- p->valid_to_idx =
- cpu_to_be16(FW_VI_MAC_CMD_VALID |
- FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
- memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
- }
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
+ FW_CMD_REQUEST |
+ FW_CMD_WRITE |
+ (free ? FW_CMD_EXEC : 0) |
+ FW_VI_MAC_CMD_VIID(viid));
+ cmd.freemacs_to_len16 =
+ cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
+ FW_CMD_LEN16(len16));
+
+ for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
+ p->valid_to_idx = cpu_to_be16(
+ FW_VI_MAC_CMD_VALID |
+ FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
+ memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
+ }
+
+
+ ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
+ sleep_ok);
+ if (ret && ret != -ENOMEM)
+ break;
- ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, sleep_ok);
- if (ret)
- return ret;
-
- for (i = 0, p = rpl.u.exact; i < naddr; i++, p++) {
- u16 index = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx));
-
- if (idx)
- idx[i] = (index >= FW_CLS_TCAM_NUM_ENTRIES
- ? 0xffff
- : index);
- if (index < FW_CLS_TCAM_NUM_ENTRIES)
- ret++;
- else if (hash)
- *hash |= (1 << hash_mac_addr(addr[i]));
+ for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
+ u16 index = FW_VI_MAC_CMD_IDX_GET(
+ be16_to_cpu(p->valid_to_idx));
+
+ if (idx)
+ idx[offset+i] =
+ (index >= FW_CLS_TCAM_NUM_ENTRIES
+ ? 0xffff
+ : index);
+ if (index < FW_CLS_TCAM_NUM_ENTRIES)
+ nfilters++;
+ else if (hash)
+ *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
+ }
+
+ free = false;
+ offset += fw_naddr;
+ rem -= fw_naddr;
}
+
+ /*
+ * If there were no errors or we merely ran out of room in our MAC
+ * address arena, return the number of filters actually written.
+ */
+ if (ret == 0 || ret == -ENOMEM)
+ ret = nfilters;
return ret;
}
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 4686c3983fc3..4d62f7bfa036 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.21-k6-NAPI"
+#define DRV_VERSION "7.3.21-k8-NAPI"
const char e1000_driver_version[] = DRV_VERSION;
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
@@ -485,9 +485,6 @@ void e1000_down(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev;
u32 rctl, tctl;
- /* signal that we're down so the interrupt handler does not
- * reschedule our watchdog timer */
- set_bit(__E1000_DOWN, &adapter->flags);
/* disable receives in the hardware */
rctl = er32(RCTL);
@@ -508,6 +505,13 @@ void e1000_down(struct e1000_adapter *adapter)
e1000_irq_disable(adapter);
+ /*
+ * Setting DOWN must be after irq_disable to prevent
+ * a screaming interrupt. Setting DOWN also prevents
+ * timers and tasks from rescheduling.
+ */
+ set_bit(__E1000_DOWN, &adapter->flags);
+
del_timer_sync(&adapter->tx_fifo_stall_timer);
del_timer_sync(&adapter->watchdog_timer);
del_timer_sync(&adapter->phy_info_timer);
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 182b2a7be8dc..3d0af08483a1 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -400,6 +400,7 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
skb_arr_rq1[index] = netdev_alloc_skb(dev,
EHEA_L_PKT_SIZE);
if (!skb_arr_rq1[index]) {
+ ehea_info("Unable to allocate enough skb in the array\n");
pr->rq1_skba.os_skbs = fill_wqes - i;
break;
}
@@ -422,13 +423,20 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
struct net_device *dev = pr->port->netdev;
int i;
- for (i = 0; i < pr->rq1_skba.len; i++) {
+ if (nr_rq1a > pr->rq1_skba.len) {
+ ehea_error("NR_RQ1A bigger than skb array len\n");
+ return;
+ }
+
+ for (i = 0; i < nr_rq1a; i++) {
skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
- if (!skb_arr_rq1[i])
+ if (!skb_arr_rq1[i]) {
+ ehea_info("No enough memory to allocate skb array\n");
break;
+ }
}
/* Ring doorbell */
- ehea_update_rq1a(pr->qp, nr_rq1a);
+ ehea_update_rq1a(pr->qp, i);
}
static int ehea_refill_rq_def(struct ehea_port_res *pr,
@@ -735,8 +743,10 @@ static int ehea_proc_rwqes(struct net_device *dev,
skb = netdev_alloc_skb(dev,
EHEA_L_PKT_SIZE);
- if (!skb)
+ if (!skb) {
+ ehea_info("Not enough memory to allocate skb\n");
break;
+ }
}
skb_copy_to_linear_data(skb, ((char *)cqe) + 64,
cqe->num_bytes_transfered - 4);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 49e4ce1246a7..d1bec6269173 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -577,11 +577,10 @@ static int gfar_parse_group(struct device_node *np,
irq_of_parse_and_map(np, 1);
priv->gfargrp[priv->num_grps].interruptError =
irq_of_parse_and_map(np,2);
- if (priv->gfargrp[priv->num_grps].interruptTransmit < 0 ||
- priv->gfargrp[priv->num_grps].interruptReceive < 0 ||
- priv->gfargrp[priv->num_grps].interruptError < 0) {
+ if (priv->gfargrp[priv->num_grps].interruptTransmit == NO_IRQ ||
+ priv->gfargrp[priv->num_grps].interruptReceive == NO_IRQ ||
+ priv->gfargrp[priv->num_grps].interruptError == NO_IRQ)
return -EINVAL;
- }
}
priv->gfargrp[priv->num_grps].grp_id = priv->num_grps;
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index dc0198092343..aa93655c3aa7 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -88,16 +88,14 @@ static const char *ipg_brand_name[] = {
"IC PLUS IP1000 1000/100/10 based NIC",
"Sundance Technology ST2021 based NIC",
"Tamarack Microelectronics TC9020/9021 based NIC",
- "Tamarack Microelectronics TC9020/9021 based NIC",
"D-Link NIC IP1000A"
};
static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = {
{ PCI_VDEVICE(SUNDANCE, 0x1023), 0 },
{ PCI_VDEVICE(SUNDANCE, 0x2021), 1 },
- { PCI_VDEVICE(SUNDANCE, 0x1021), 2 },
- { PCI_VDEVICE(DLINK, 0x9021), 3 },
- { PCI_VDEVICE(DLINK, 0x4020), 4 },
+ { PCI_VDEVICE(DLINK, 0x9021), 2 },
+ { PCI_VDEVICE(DLINK, 0x4020), 3 },
{ 0, }
};
diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c
index 00b38bccd6d0..52a7c86af663 100644
--- a/drivers/net/irda/sh_sir.c
+++ b/drivers/net/irda/sh_sir.c
@@ -258,7 +258,7 @@ static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate)
/* Baud Rate Error Correction x 10000 */
u32 rate_err_array[] = {
- 0000, 0625, 1250, 1875,
+ 0, 625, 1250, 1875,
2500, 3125, 3750, 4375,
5000, 5625, 6250, 6875,
7500, 8125, 8750, 9375,
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index b68eee2414c2..7a7e18ba278a 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -289,6 +289,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET);
dev_cap->bf_reg_size = 1 << (field & 0x1f);
MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET);
+ if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size)) {
+ mlx4_warn(dev, "firmware bug: log2 # of blue flame regs is invalid (%d), forcing 3\n", field & 0x1f);
+ field = 3;
+ }
dev_cap->bf_regs_per_page = 1 << (field & 0x3f);
mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n",
dev_cap->bf_reg_size, dev_cap->bf_regs_per_page);
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index 472056b47440..03a1d280105f 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999 - 2010 Intel Corporation.
- * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
*
* This code was derived from the Intel e1000e Linux driver.
*
@@ -2464,8 +2464,8 @@ static void __exit pch_gbe_exit_module(void)
module_init(pch_gbe_init_module);
module_exit(pch_gbe_exit_module);
-MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver");
-MODULE_AUTHOR("OKI semiconductor, <masa-korg@dsn.okisemi.com>");
+MODULE_DESCRIPTION("EG20T PCH Gigabit ethernet Driver");
+MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id);
diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c
index 2510146fc560..ef0996a0eaaa 100644
--- a/drivers/net/pch_gbe/pch_gbe_param.c
+++ b/drivers/net/pch_gbe/pch_gbe_param.c
@@ -434,8 +434,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
.err = "using default of "
__MODULE_STRING(PCH_GBE_DEFAULT_TXD),
.def = PCH_GBE_DEFAULT_TXD,
- .arg = { .r = { .min = PCH_GBE_MIN_TXD } },
- .arg = { .r = { .max = PCH_GBE_MAX_TXD } }
+ .arg = { .r = { .min = PCH_GBE_MIN_TXD,
+ .max = PCH_GBE_MAX_TXD } }
};
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
tx_ring->count = TxDescriptors;
@@ -450,8 +450,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
.err = "using default of "
__MODULE_STRING(PCH_GBE_DEFAULT_RXD),
.def = PCH_GBE_DEFAULT_RXD,
- .arg = { .r = { .min = PCH_GBE_MIN_RXD } },
- .arg = { .r = { .max = PCH_GBE_MAX_RXD } }
+ .arg = { .r = { .min = PCH_GBE_MIN_RXD,
+ .max = PCH_GBE_MAX_RXD } }
};
struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
rx_ring->count = RxDescriptors;
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index f0bd1a1aba3a..e8b9c53c304b 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -30,11 +30,14 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/marvell_phy.h>
+#include <linux/of.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#define MII_MARVELL_PHY_PAGE 22
+
#define MII_M1011_IEVENT 0x13
#define MII_M1011_IEVENT_CLEAR 0x0000
@@ -80,7 +83,6 @@
#define MII_88E1121_PHY_LED_CTRL 16
#define MII_88E1121_PHY_LED_PAGE 3
#define MII_88E1121_PHY_LED_DEF 0x0030
-#define MII_88E1121_PHY_PAGE 22
#define MII_M1011_PHY_STATUS 0x11
#define MII_M1011_PHY_STATUS_1000 0x8000
@@ -186,13 +188,94 @@ static int marvell_config_aneg(struct phy_device *phydev)
return 0;
}
+#ifdef CONFIG_OF_MDIO
+/*
+ * Set and/or override some configuration registers based on the
+ * marvell,reg-init property stored in the of_node for the phydev.
+ *
+ * marvell,reg-init = <reg-page reg mask value>,...;
+ *
+ * There may be one or more sets of <reg-page reg mask value>:
+ *
+ * reg-page: which register bank to use.
+ * reg: the register.
+ * mask: if non-zero, ANDed with existing register value.
+ * value: ORed with the masked value and written to the regiser.
+ *
+ */
+static int marvell_of_reg_init(struct phy_device *phydev)
+{
+ const __be32 *paddr;
+ int len, i, saved_page, current_page, page_changed, ret;
+
+ if (!phydev->dev.of_node)
+ return 0;
+
+ paddr = of_get_property(phydev->dev.of_node, "marvell,reg-init", &len);
+ if (!paddr || len < (4 * sizeof(*paddr)))
+ return 0;
+
+ saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE);
+ if (saved_page < 0)
+ return saved_page;
+ page_changed = 0;
+ current_page = saved_page;
+
+ ret = 0;
+ len /= sizeof(*paddr);
+ for (i = 0; i < len - 3; i += 4) {
+ u16 reg_page = be32_to_cpup(paddr + i);
+ u16 reg = be32_to_cpup(paddr + i + 1);
+ u16 mask = be32_to_cpup(paddr + i + 2);
+ u16 val_bits = be32_to_cpup(paddr + i + 3);
+ int val;
+
+ if (reg_page != current_page) {
+ current_page = reg_page;
+ page_changed = 1;
+ ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page);
+ if (ret < 0)
+ goto err;
+ }
+
+ val = 0;
+ if (mask) {
+ val = phy_read(phydev, reg);
+ if (val < 0) {
+ ret = val;
+ goto err;
+ }
+ val &= mask;
+ }
+ val |= val_bits;
+
+ ret = phy_write(phydev, reg, val);
+ if (ret < 0)
+ goto err;
+
+ }
+err:
+ if (page_changed) {
+ i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page);
+ if (ret == 0)
+ ret = i;
+ }
+ return ret;
+}
+#else
+static int marvell_of_reg_init(struct phy_device *phydev)
+{
+ return 0;
+}
+#endif /* CONFIG_OF_MDIO */
+
static int m88e1121_config_aneg(struct phy_device *phydev)
{
int err, oldpage, mscr;
- oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
+ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
- err = phy_write(phydev, MII_88E1121_PHY_PAGE,
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
MII_88E1121_PHY_MSCR_PAGE);
if (err < 0)
return err;
@@ -218,7 +301,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
return err;
}
- phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
+ phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
err = phy_write(phydev, MII_BMCR, BMCR_RESET);
if (err < 0)
@@ -229,11 +312,11 @@ static int m88e1121_config_aneg(struct phy_device *phydev)
if (err < 0)
return err;
- oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
+ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
- phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
+ phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF);
- phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
+ phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
err = genphy_config_aneg(phydev);
@@ -244,9 +327,9 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
{
int err, oldpage, mscr;
- oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
+ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
- err = phy_write(phydev, MII_88E1121_PHY_PAGE,
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
MII_88E1121_PHY_MSCR_PAGE);
if (err < 0)
return err;
@@ -258,7 +341,7 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
if (err < 0)
return err;
- err = phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
if (err < 0)
return err;
@@ -368,6 +451,9 @@ static int m88e1111_config_init(struct phy_device *phydev)
return err;
}
+ err = marvell_of_reg_init(phydev);
+ if (err < 0)
+ return err;
err = phy_write(phydev, MII_BMCR, BMCR_RESET);
if (err < 0)
@@ -398,7 +484,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
int err;
/* Change address */
- err = phy_write(phydev, 0x16, 0x0002);
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
if (err < 0)
return err;
@@ -408,7 +494,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
return err;
/* Change address */
- err = phy_write(phydev, 0x16, 0x0003);
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003);
if (err < 0)
return err;
@@ -420,8 +506,42 @@ static int m88e1118_config_init(struct phy_device *phydev)
if (err < 0)
return err;
+ err = marvell_of_reg_init(phydev);
+ if (err < 0)
+ return err;
+
/* Reset address */
- err = phy_write(phydev, 0x16, 0x0);
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
+ if (err < 0)
+ return err;
+
+ err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int m88e1149_config_init(struct phy_device *phydev)
+{
+ int err;
+
+ /* Change address */
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
+ if (err < 0)
+ return err;
+
+ /* Enable 1000 Mbit */
+ err = phy_write(phydev, 0x15, 0x1048);
+ if (err < 0)
+ return err;
+
+ err = marvell_of_reg_init(phydev);
+ if (err < 0)
+ return err;
+
+ /* Reset address */
+ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
if (err < 0)
return err;
@@ -491,6 +611,10 @@ static int m88e1145_config_init(struct phy_device *phydev)
}
}
+ err = marvell_of_reg_init(phydev);
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -685,6 +809,19 @@ static struct phy_driver marvell_drivers[] = {
.driver = { .owner = THIS_MODULE },
},
{
+ .phy_id = MARVELL_PHY_ID_88E1149R,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E1149R",
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &m88e1149_config_init,
+ .config_aneg = &m88e1118_config_aneg,
+ .read_status = &genphy_read_status,
+ .ack_interrupt = &marvell_ack_interrupt,
+ .config_intr = &marvell_config_intr,
+ .driver = { .owner = THIS_MODULE },
+ },
+ {
.phy_id = MARVELL_PHY_ID_88E1240,
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "Marvell 88E1240",
@@ -735,6 +872,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = {
{ 0x01410e10, 0xfffffff0 },
{ 0x01410cb0, 0xfffffff0 },
{ 0x01410cd0, 0xfffffff0 },
+ { 0x01410e50, 0xfffffff0 },
{ 0x01410e30, 0xfffffff0 },
{ 0x01410e90, 0xfffffff0 },
{ }
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 09cf56d0416a..39659976a1ac 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2584,16 +2584,16 @@ ppp_create_interface(struct net *net, int unit, int *retp)
*/
dev_net_set(dev, net);
- ret = -EEXIST;
mutex_lock(&pn->all_ppp_mutex);
if (unit < 0) {
unit = unit_get(&pn->units_idr, ppp);
if (unit < 0) {
- *retp = unit;
+ ret = unit;
goto out2;
}
} else {
+ ret = -EEXIST;
if (unit_find(&pn->units_idr, unit))
goto out2; /* unit already exists */
/*
@@ -2668,10 +2668,10 @@ static void ppp_shutdown_interface(struct ppp *ppp)
ppp->closing = 1;
ppp_unlock(ppp);
unregister_netdev(ppp->dev);
+ unit_put(&pn->units_idr, ppp->file.index);
} else
ppp_unlock(ppp);
- unit_put(&pn->units_idr, ppp->file.index);
ppp->file.dead = 1;
ppp->owner = NULL;
wake_up_interruptible(&ppp->file.rwait);
@@ -2859,8 +2859,7 @@ static void __exit ppp_cleanup(void)
* by holding all_ppp_mutex
*/
-/* associate pointer with specified number */
-static int unit_set(struct idr *p, void *ptr, int n)
+static int __unit_alloc(struct idr *p, void *ptr, int n)
{
int unit, err;
@@ -2871,10 +2870,24 @@ again:
}
err = idr_get_new_above(p, ptr, n, &unit);
- if (err == -EAGAIN)
- goto again;
+ if (err < 0) {
+ if (err == -EAGAIN)
+ goto again;
+ return err;
+ }
+
+ return unit;
+}
+
+/* associate pointer with specified number */
+static int unit_set(struct idr *p, void *ptr, int n)
+{
+ int unit;
- if (unit != n) {
+ unit = __unit_alloc(p, ptr, n);
+ if (unit < 0)
+ return unit;
+ else if (unit != n) {
idr_remove(p, unit);
return -EINVAL;
}
@@ -2885,19 +2898,7 @@ again:
/* get new free unit number and associate pointer with it */
static int unit_get(struct idr *p, void *ptr)
{
- int unit, err;
-
-again:
- if (!idr_pre_get(p, GFP_KERNEL)) {
- printk(KERN_ERR "PPP: No free memory for idr\n");
- return -ENOMEM;
- }
-
- err = idr_get_new_above(p, ptr, 0, &unit);
- if (err == -EAGAIN)
- goto again;
-
- return unit;
+ return __unit_alloc(p, ptr, 0);
}
/* put unit number back to a pool */
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index c30e0fe55a31..528eaef5308f 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -62,15 +62,15 @@ static const u32 default_msg =
/* NETIF_MSG_PKTDATA | */
NETIF_MSG_HW | NETIF_MSG_WOL | 0;
-static int debug = 0x00007fff; /* defaults above */
-module_param(debug, int, 0);
+static int debug = -1; /* defaults above */
+module_param(debug, int, 0664);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
#define MSIX_IRQ 0
#define MSI_IRQ 1
#define LEG_IRQ 2
static int qlge_irq_type = MSIX_IRQ;
-module_param(qlge_irq_type, int, MSIX_IRQ);
+module_param(qlge_irq_type, int, 0664);
MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
static int qlge_mpi_coredump;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 4c4d16905efb..7d33ef4bcb4a 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -4440,8 +4440,7 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1)
u32 status = opts1 & RxProtoMask;
if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
- ((status == RxProtoUDP) && !(opts1 & UDPFail)) ||
- ((status == RxProtoIP) && !(opts1 & IPFail)))
+ ((status == RxProtoUDP) && !(opts1 & UDPFail)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb_checksum_none_assert(skb);
diff --git a/drivers/net/tile/Makefile b/drivers/net/tile/Makefile
new file mode 100644
index 000000000000..f634f142cab4
--- /dev/null
+++ b/drivers/net/tile/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the TILE on-chip networking support.
+#
+
+obj-$(CONFIG_TILE_NET) += tile_net.o
+ifdef CONFIG_TILEGX
+tile_net-objs := tilegx.o mpipe.o iorpc_mpipe.o dma_queue.o
+else
+tile_net-objs := tilepro.o
+endif
diff --git a/drivers/net/tile/tilepro.c b/drivers/net/tile/tilepro.c
new file mode 100644
index 000000000000..0e6bac5ec65b
--- /dev/null
+++ b/drivers/net/tile/tilepro.c
@@ -0,0 +1,2406 @@
+/*
+ * Copyright 2010 Tilera 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, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/slab.h> /* kmalloc() */
+#include <linux/errno.h> /* error codes */
+#include <linux/types.h> /* size_t */
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/netdevice.h> /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/skbuff.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/hugetlb.h>
+#include <linux/in6.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <asm/checksum.h>
+#include <asm/homecache.h>
+
+#include <hv/drv_xgbe_intf.h>
+#include <hv/drv_xgbe_impl.h>
+#include <hv/hypervisor.h>
+#include <hv/netio_intf.h>
+
+/* For TSO */
+#include <linux/ip.h>
+#include <linux/tcp.h>
+
+
+/* There is no singlethread_cpu, so schedule work on the current cpu. */
+#define singlethread_cpu -1
+
+
+/*
+ * First, "tile_net_init_module()" initializes all four "devices" which
+ * can be used by linux.
+ *
+ * Then, "ifconfig DEVICE up" calls "tile_net_open()", which analyzes
+ * the network cpus, then uses "tile_net_open_aux()" to initialize
+ * LIPP/LEPP, and then uses "tile_net_open_inner()" to register all
+ * the tiles, provide buffers to LIPP, allow ingress to start, and
+ * turn on hypervisor interrupt handling (and NAPI) on all tiles.
+ *
+ * If registration fails due to the link being down, then "retry_work"
+ * is used to keep calling "tile_net_open_inner()" until it succeeds.
+ *
+ * If "ifconfig DEVICE down" is called, it uses "tile_net_stop()" to
+ * stop egress, drain the LIPP buffers, unregister all the tiles, stop
+ * LIPP/LEPP, and wipe the LEPP queue.
+ *
+ * We start out with the ingress interrupt enabled on each CPU. When
+ * this interrupt fires, we disable it, and call "napi_schedule()".
+ * This will cause "tile_net_poll()" to be called, which will pull
+ * packets from the netio queue, filtering them out, or passing them
+ * to "netif_receive_skb()". If our budget is exhausted, we will
+ * return, knowing we will be called again later. Otherwise, we
+ * reenable the ingress interrupt, and call "napi_complete()".
+ *
+ *
+ * NOTE: The use of "native_driver" ensures that EPP exists, and that
+ * "epp_sendv" is legal, and that "LIPP" is being used.
+ *
+ * NOTE: Failing to free completions for an arbitrarily long time
+ * (which is defined to be illegal) does in fact cause bizarre
+ * problems. The "egress_timer" helps prevent this from happening.
+ *
+ * NOTE: The egress code can be interrupted by the interrupt handler.
+ */
+
+
+/* HACK: Allow use of "jumbo" packets. */
+/* This should be 1500 if "jumbo" is not set in LIPP. */
+/* This should be at most 10226 (10240 - 14) if "jumbo" is set in LIPP. */
+/* ISSUE: This has not been thoroughly tested (except at 1500). */
+#define TILE_NET_MTU 1500
+
+/* HACK: Define to support GSO. */
+/* ISSUE: This may actually hurt performance of the TCP blaster. */
+/* #define TILE_NET_GSO */
+
+/* Define this to collapse "duplicate" acks. */
+/* #define IGNORE_DUP_ACKS */
+
+/* HACK: Define this to verify incoming packets. */
+/* #define TILE_NET_VERIFY_INGRESS */
+
+/* Use 3000 to enable the Linux Traffic Control (QoS) layer, else 0. */
+#define TILE_NET_TX_QUEUE_LEN 0
+
+/* Define to dump packets (prints out the whole packet on tx and rx). */
+/* #define TILE_NET_DUMP_PACKETS */
+
+/* Define to enable debug spew (all PDEBUG's are enabled). */
+/* #define TILE_NET_DEBUG */
+
+
+/* Define to activate paranoia checks. */
+/* #define TILE_NET_PARANOIA */
+
+/* Default transmit lockup timeout period, in jiffies. */
+#define TILE_NET_TIMEOUT (5 * HZ)
+
+/* Default retry interval for bringing up the NetIO interface, in jiffies. */
+#define TILE_NET_RETRY_INTERVAL (5 * HZ)
+
+/* Number of ports (xgbe0, xgbe1, gbe0, gbe1). */
+#define TILE_NET_DEVS 4
+
+
+
+/* Paranoia. */
+#if NET_IP_ALIGN != LIPP_PACKET_PADDING
+#error "NET_IP_ALIGN must match LIPP_PACKET_PADDING."
+#endif
+
+
+/* Debug print. */
+#ifdef TILE_NET_DEBUG
+#define PDEBUG(fmt, args...) net_printk(fmt, ## args)
+#else
+#define PDEBUG(fmt, args...)
+#endif
+
+
+MODULE_AUTHOR("Tilera");
+MODULE_LICENSE("GPL");
+
+
+#define IS_MULTICAST(mac_addr) \
+ (((u8 *)(mac_addr))[0] & 0x01)
+
+#define IS_BROADCAST(mac_addr) \
+ (((u16 *)(mac_addr))[0] == 0xffff)
+
+
+/*
+ * Queue of incoming packets for a specific cpu and device.
+ *
+ * Includes a pointer to the "system" data, and the actual "user" data.
+ */
+struct tile_netio_queue {
+ netio_queue_impl_t *__system_part;
+ netio_queue_user_impl_t __user_part;
+
+};
+
+
+/*
+ * Statistics counters for a specific cpu and device.
+ */
+struct tile_net_stats_t {
+ u32 rx_packets;
+ u32 rx_bytes;
+ u32 tx_packets;
+ u32 tx_bytes;
+};
+
+
+/*
+ * Info for a specific cpu and device.
+ *
+ * ISSUE: There is a "dev" pointer in "napi" as well.
+ */
+struct tile_net_cpu {
+ /* The NAPI struct. */
+ struct napi_struct napi;
+ /* Packet queue. */
+ struct tile_netio_queue queue;
+ /* Statistics. */
+ struct tile_net_stats_t stats;
+ /* ISSUE: Is this needed? */
+ bool napi_enabled;
+ /* True if this tile has succcessfully registered with the IPP. */
+ bool registered;
+ /* True if the link was down last time we tried to register. */
+ bool link_down;
+ /* True if "egress_timer" is scheduled. */
+ bool egress_timer_scheduled;
+ /* Number of small sk_buffs which must still be provided. */
+ unsigned int num_needed_small_buffers;
+ /* Number of large sk_buffs which must still be provided. */
+ unsigned int num_needed_large_buffers;
+ /* A timer for handling egress completions. */
+ struct timer_list egress_timer;
+};
+
+
+/*
+ * Info for a specific device.
+ */
+struct tile_net_priv {
+ /* Our network device. */
+ struct net_device *dev;
+ /* The actual egress queue. */
+ lepp_queue_t *epp_queue;
+ /* Protects "epp_queue->cmd_tail" and "epp_queue->comp_tail" */
+ spinlock_t cmd_lock;
+ /* Protects "epp_queue->comp_head". */
+ spinlock_t comp_lock;
+ /* The hypervisor handle for this interface. */
+ int hv_devhdl;
+ /* The intr bit mask that IDs this device. */
+ u32 intr_id;
+ /* True iff "tile_net_open_aux()" has succeeded. */
+ int partly_opened;
+ /* True iff "tile_net_open_inner()" has succeeded. */
+ int fully_opened;
+ /* Effective network cpus. */
+ struct cpumask network_cpus_map;
+ /* Number of network cpus. */
+ int network_cpus_count;
+ /* Credits per network cpu. */
+ int network_cpus_credits;
+ /* Network stats. */
+ struct net_device_stats stats;
+ /* For NetIO bringup retries. */
+ struct delayed_work retry_work;
+ /* Quick access to per cpu data. */
+ struct tile_net_cpu *cpu[NR_CPUS];
+};
+
+
+/*
+ * The actual devices (xgbe0, xgbe1, gbe0, gbe1).
+ */
+static struct net_device *tile_net_devs[TILE_NET_DEVS];
+
+/*
+ * The "tile_net_cpu" structures for each device.
+ */
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe0);
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_xgbe1);
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe0);
+static DEFINE_PER_CPU(struct tile_net_cpu, hv_gbe1);
+
+
+/*
+ * True if "network_cpus" was specified.
+ */
+static bool network_cpus_used;
+
+/*
+ * The actual cpus in "network_cpus".
+ */
+static struct cpumask network_cpus_map;
+
+
+
+#ifdef TILE_NET_DEBUG
+/*
+ * printk with extra stuff.
+ *
+ * We print the CPU we're running in brackets.
+ */
+static void net_printk(char *fmt, ...)
+{
+ int i;
+ int len;
+ va_list args;
+ static char buf[256];
+
+ len = sprintf(buf, "tile_net[%2.2d]: ", smp_processor_id());
+ va_start(args, fmt);
+ i = vscnprintf(buf + len, sizeof(buf) - len - 1, fmt, args);
+ va_end(args);
+ buf[255] = '\0';
+ pr_notice(buf);
+}
+#endif
+
+
+#ifdef TILE_NET_DUMP_PACKETS
+/*
+ * Dump a packet.
+ */
+static void dump_packet(unsigned char *data, unsigned long length, char *s)
+{
+ unsigned long i;
+ static unsigned int count;
+
+ pr_info("dump_packet(data %p, length 0x%lx s %s count 0x%x)\n",
+ data, length, s, count++);
+
+ pr_info("\n");
+
+ for (i = 0; i < length; i++) {
+ if ((i & 0xf) == 0)
+ sprintf(buf, "%8.8lx:", i);
+ sprintf(buf + strlen(buf), " %2.2x", data[i]);
+ if ((i & 0xf) == 0xf || i == length - 1)
+ pr_info("%s\n", buf);
+ }
+}
+#endif
+
+
+/*
+ * Provide support for the __netio_fastio1() swint
+ * (see <hv/drv_xgbe_intf.h> for how it is used).
+ *
+ * The fastio swint2 call may clobber all the caller-saved registers.
+ * It rarely clobbers memory, but we allow for the possibility in
+ * the signature just to be on the safe side.
+ *
+ * Also, gcc doesn't seem to allow an input operand to be
+ * clobbered, so we fake it with dummy outputs.
+ *
+ * This function can't be static because of the way it is declared
+ * in the netio header.
+ */
+inline int __netio_fastio1(u32 fastio_index, u32 arg0)
+{
+ long result, clobber_r1, clobber_r10;
+ asm volatile("swint2"
+ : "=R00" (result),
+ "=R01" (clobber_r1), "=R10" (clobber_r10)
+ : "R10" (fastio_index), "R01" (arg0)
+ : "memory", "r2", "r3", "r4",
+ "r5", "r6", "r7", "r8", "r9",
+ "r11", "r12", "r13", "r14",
+ "r15", "r16", "r17", "r18", "r19",
+ "r20", "r21", "r22", "r23", "r24",
+ "r25", "r26", "r27", "r28", "r29");
+ return result;
+}
+
+
+/*
+ * Provide a linux buffer to LIPP.
+ */
+static void tile_net_provide_linux_buffer(struct tile_net_cpu *info,
+ void *va, bool small)
+{
+ struct tile_netio_queue *queue = &info->queue;
+
+ /* Convert "va" and "small" to "linux_buffer_t". */
+ unsigned int buffer = ((unsigned int)(__pa(va) >> 7) << 1) + small;
+
+ __netio_fastio_free_buffer(queue->__user_part.__fastio_index, buffer);
+}
+
+
+/*
+ * Provide a linux buffer for LIPP.
+ */
+static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info,
+ bool small)
+{
+ /* ISSUE: What should we use here? */
+ unsigned int large_size = NET_IP_ALIGN + TILE_NET_MTU + 100;
+
+ /* Round up to ensure to avoid "false sharing" with last cache line. */
+ unsigned int buffer_size =
+ (((small ? LIPP_SMALL_PACKET_SIZE : large_size) +
+ CHIP_L2_LINE_SIZE() - 1) & -CHIP_L2_LINE_SIZE());
+
+ /*
+ * ISSUE: Since CPAs are 38 bits, and we can only encode the
+ * high 31 bits in a "linux_buffer_t", the low 7 bits must be
+ * zero, and thus, we must align the actual "va" mod 128.
+ */
+ const unsigned long align = 128;
+
+ struct sk_buff *skb;
+ void *va;
+
+ struct sk_buff **skb_ptr;
+
+ /* Note that "dev_alloc_skb()" adds NET_SKB_PAD more bytes, */
+ /* and also "reserves" that many bytes. */
+ /* ISSUE: Can we "share" the NET_SKB_PAD bytes with "skb_ptr"? */
+ int len = sizeof(*skb_ptr) + align + buffer_size;
+
+ while (1) {
+
+ /* Allocate (or fail). */
+ skb = dev_alloc_skb(len);
+ if (skb == NULL)
+ return false;
+
+ /* Make room for a back-pointer to 'skb'. */
+ skb_reserve(skb, sizeof(*skb_ptr));
+
+ /* Make sure we are aligned. */
+ skb_reserve(skb, -(long)skb->data & (align - 1));
+
+ /* This address is given to IPP. */
+ va = skb->data;
+
+ if (small)
+ break;
+
+ /* ISSUE: This has never been observed! */
+ /* Large buffers must not span a huge page. */
+ if (((((long)va & ~HPAGE_MASK) + 1535) & HPAGE_MASK) == 0)
+ break;
+ pr_err("Leaking unaligned linux buffer at %p.\n", va);
+ }
+
+ /* Skip two bytes to satisfy LIPP assumptions. */
+ /* Note that this aligns IP on a 16 byte boundary. */
+ /* ISSUE: Do this when the packet arrives? */
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ /* Save a back-pointer to 'skb'. */
+ skb_ptr = va - sizeof(*skb_ptr);
+ *skb_ptr = skb;
+
+ /* Invalidate the packet buffer. */
+ if (!hash_default)
+ __inv_buffer(skb->data, buffer_size);
+
+ /* Make sure "skb_ptr" has been flushed. */
+ __insn_mf();
+
+#ifdef TILE_NET_PARANOIA
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (hash_default) {
+ HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)va);
+ if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3)
+ panic("Non-coherent ingress buffer!");
+ }
+#endif
+#endif
+
+ /* Provide the new buffer. */
+ tile_net_provide_linux_buffer(info, va, small);
+
+ return true;
+}
+
+
+/*
+ * Provide linux buffers for LIPP.
+ */
+static void tile_net_provide_needed_buffers(struct tile_net_cpu *info)
+{
+ while (info->num_needed_small_buffers != 0) {
+ if (!tile_net_provide_needed_buffer(info, true))
+ goto oops;
+ info->num_needed_small_buffers--;
+ }
+
+ while (info->num_needed_large_buffers != 0) {
+ if (!tile_net_provide_needed_buffer(info, false))
+ goto oops;
+ info->num_needed_large_buffers--;
+ }
+
+ return;
+
+oops:
+
+ /* Add a description to the page allocation failure dump. */
+ pr_notice("Could not provide a linux buffer to LIPP.\n");
+}
+
+
+/*
+ * Grab some LEPP completions, and store them in "comps", of size
+ * "comps_size", and return the number of completions which were
+ * stored, so the caller can free them.
+ *
+ * If "pending" is not NULL, it will be set to true if there might
+ * still be some pending completions caused by this tile, else false.
+ */
+static unsigned int tile_net_lepp_grab_comps(struct net_device *dev,
+ struct sk_buff *comps[],
+ unsigned int comps_size,
+ bool *pending)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+
+ lepp_queue_t *eq = priv->epp_queue;
+
+ unsigned int n = 0;
+
+ unsigned int comp_head;
+ unsigned int comp_busy;
+ unsigned int comp_tail;
+
+ spin_lock(&priv->comp_lock);
+
+ comp_head = eq->comp_head;
+ comp_busy = eq->comp_busy;
+ comp_tail = eq->comp_tail;
+
+ while (comp_head != comp_busy && n < comps_size) {
+ comps[n++] = eq->comps[comp_head];
+ LEPP_QINC(comp_head);
+ }
+
+ if (pending != NULL)
+ *pending = (comp_head != comp_tail);
+
+ eq->comp_head = comp_head;
+
+ spin_unlock(&priv->comp_lock);
+
+ return n;
+}
+
+
+/*
+ * Make sure the egress timer is scheduled.
+ *
+ * Note that we use "schedule if not scheduled" logic instead of the more
+ * obvious "reschedule" logic, because "reschedule" is fairly expensive.
+ */
+static void tile_net_schedule_egress_timer(struct tile_net_cpu *info)
+{
+ if (!info->egress_timer_scheduled) {
+ mod_timer_pinned(&info->egress_timer, jiffies + 1);
+ info->egress_timer_scheduled = true;
+ }
+}
+
+
+/*
+ * The "function" for "info->egress_timer".
+ *
+ * This timer will reschedule itself as long as there are any pending
+ * completions expected (on behalf of any tile).
+ *
+ * ISSUE: Realistically, will the timer ever stop scheduling itself?
+ *
+ * ISSUE: This timer is almost never actually needed, so just use a global
+ * timer that can run on any tile.
+ *
+ * ISSUE: Maybe instead track number of expected completions, and free
+ * only that many, resetting to zero if "pending" is ever false.
+ */
+static void tile_net_handle_egress_timer(unsigned long arg)
+{
+ struct tile_net_cpu *info = (struct tile_net_cpu *)arg;
+ struct net_device *dev = info->napi.dev;
+
+ struct sk_buff *olds[32];
+ unsigned int wanted = 32;
+ unsigned int i, nolds = 0;
+ bool pending;
+
+ /* The timer is no longer scheduled. */
+ info->egress_timer_scheduled = false;
+
+ nolds = tile_net_lepp_grab_comps(dev, olds, wanted, &pending);
+
+ for (i = 0; i < nolds; i++)
+ kfree_skb(olds[i]);
+
+ /* Reschedule timer if needed. */
+ if (pending)
+ tile_net_schedule_egress_timer(info);
+}
+
+
+#ifdef IGNORE_DUP_ACKS
+
+/*
+ * Help detect "duplicate" ACKs. These are sequential packets (for a
+ * given flow) which are exactly 66 bytes long, sharing everything but
+ * ID=2@0x12, Hsum=2@0x18, Ack=4@0x2a, WinSize=2@0x30, Csum=2@0x32,
+ * Tstamps=10@0x38. The ID's are +1, the Hsum's are -1, the Ack's are
+ * +N, and the Tstamps are usually identical.
+ *
+ * NOTE: Apparently truly duplicate acks (with identical "ack" values),
+ * should not be collapsed, as they are used for some kind of flow control.
+ */
+static bool is_dup_ack(char *s1, char *s2, unsigned int len)
+{
+ int i;
+
+ unsigned long long ignorable = 0;
+
+ /* Identification. */
+ ignorable |= (1ULL << 0x12);
+ ignorable |= (1ULL << 0x13);
+
+ /* Header checksum. */
+ ignorable |= (1ULL << 0x18);
+ ignorable |= (1ULL << 0x19);
+
+ /* ACK. */
+ ignorable |= (1ULL << 0x2a);
+ ignorable |= (1ULL << 0x2b);
+ ignorable |= (1ULL << 0x2c);
+ ignorable |= (1ULL << 0x2d);
+
+ /* WinSize. */
+ ignorable |= (1ULL << 0x30);
+ ignorable |= (1ULL << 0x31);
+
+ /* Checksum. */
+ ignorable |= (1ULL << 0x32);
+ ignorable |= (1ULL << 0x33);
+
+ for (i = 0; i < len; i++, ignorable >>= 1) {
+
+ if ((ignorable & 1) || (s1[i] == s2[i]))
+ continue;
+
+#ifdef TILE_NET_DEBUG
+ /* HACK: Mention non-timestamp diffs. */
+ if (i < 0x38 && i != 0x2f &&
+ net_ratelimit())
+ pr_info("Diff at 0x%x\n", i);
+#endif
+
+ return false;
+ }
+
+#ifdef TILE_NET_NO_SUPPRESS_DUP_ACKS
+ /* HACK: Do not suppress truly duplicate ACKs. */
+ /* ISSUE: Is this actually necessary or helpful? */
+ if (s1[0x2a] == s2[0x2a] &&
+ s1[0x2b] == s2[0x2b] &&
+ s1[0x2c] == s2[0x2c] &&
+ s1[0x2d] == s2[0x2d]) {
+ return false;
+ }
+#endif
+
+ return true;
+}
+
+#endif
+
+
+
+/*
+ * Like "tile_net_handle_packets()", but just discard packets.
+ */
+static void tile_net_discard_packets(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+ struct tile_netio_queue *queue = &info->queue;
+ netio_queue_impl_t *qsp = queue->__system_part;
+ netio_queue_user_impl_t *qup = &queue->__user_part;
+
+ while (qup->__packet_receive_read !=
+ qsp->__packet_receive_queue.__packet_write) {
+
+ int index = qup->__packet_receive_read;
+
+ int index2_aux = index + sizeof(netio_pkt_t);
+ int index2 =
+ ((index2_aux ==
+ qsp->__packet_receive_queue.__last_packet_plus_one) ?
+ 0 : index2_aux);
+
+ netio_pkt_t *pkt = (netio_pkt_t *)
+ ((unsigned long) &qsp[1] + index);
+
+ /* Extract the "linux_buffer_t". */
+ unsigned int buffer = pkt->__packet.word;
+
+ /* Convert "linux_buffer_t" to "va". */
+ void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+
+ /* Acquire the associated "skb". */
+ struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+ struct sk_buff *skb = *skb_ptr;
+
+ kfree_skb(skb);
+
+ /* Consume this packet. */
+ qup->__packet_receive_read = index2;
+ }
+}
+
+
+/*
+ * Handle the next packet. Return true if "processed", false if "filtered".
+ */
+static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)
+{
+ struct net_device *dev = info->napi.dev;
+
+ struct tile_netio_queue *queue = &info->queue;
+ netio_queue_impl_t *qsp = queue->__system_part;
+ netio_queue_user_impl_t *qup = &queue->__user_part;
+ struct tile_net_stats_t *stats = &info->stats;
+
+ int filter;
+
+ int index2_aux = index + sizeof(netio_pkt_t);
+ int index2 =
+ ((index2_aux ==
+ qsp->__packet_receive_queue.__last_packet_plus_one) ?
+ 0 : index2_aux);
+
+ netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long) &qsp[1] + index);
+
+ netio_pkt_metadata_t *metadata = NETIO_PKT_METADATA(pkt);
+
+ /* Extract the packet size. */
+ unsigned long len =
+ (NETIO_PKT_CUSTOM_LENGTH(pkt) +
+ NET_IP_ALIGN - NETIO_PACKET_PADDING);
+
+ /* Extract the "linux_buffer_t". */
+ unsigned int buffer = pkt->__packet.word;
+
+ /* Extract "small" (vs "large"). */
+ bool small = ((buffer & 1) != 0);
+
+ /* Convert "linux_buffer_t" to "va". */
+ void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+
+ /* Extract the packet data pointer. */
+ /* Compare to "NETIO_PKT_CUSTOM_DATA(pkt)". */
+ unsigned char *buf = va + NET_IP_ALIGN;
+
+#ifdef IGNORE_DUP_ACKS
+
+ static int other;
+ static int final;
+ static int keep;
+ static int skip;
+
+#endif
+
+ /* Invalidate the packet buffer. */
+ if (!hash_default)
+ __inv_buffer(buf, len);
+
+ /* ISSUE: Is this needed? */
+ dev->last_rx = jiffies;
+
+#ifdef TILE_NET_DUMP_PACKETS
+ dump_packet(buf, len, "rx");
+#endif /* TILE_NET_DUMP_PACKETS */
+
+#ifdef TILE_NET_VERIFY_INGRESS
+ if (!NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt) &&
+ NETIO_PKT_L4_CSUM_CALCULATED_M(metadata, pkt)) {
+ /*
+ * FIXME: This complains about UDP packets
+ * with a "zero" checksum (bug 6624).
+ */
+#ifdef TILE_NET_PANIC_ON_BAD
+ dump_packet(buf, len, "rx");
+ panic("Bad L4 checksum.");
+#else
+ pr_warning("Bad L4 checksum on %d byte packet.\n", len);
+#endif
+ }
+ if (!NETIO_PKT_L3_CSUM_CORRECT_M(metadata, pkt) &&
+ NETIO_PKT_L3_CSUM_CALCULATED_M(metadata, pkt)) {
+ dump_packet(buf, len, "rx");
+ panic("Bad L3 checksum.");
+ }
+ switch (NETIO_PKT_STATUS_M(metadata, pkt)) {
+ case NETIO_PKT_STATUS_OVERSIZE:
+ if (len >= 64) {
+ dump_packet(buf, len, "rx");
+ panic("Unexpected OVERSIZE.");
+ }
+ break;
+ case NETIO_PKT_STATUS_BAD:
+#ifdef TILE_NET_PANIC_ON_BAD
+ dump_packet(buf, len, "rx");
+ panic("Unexpected BAD packet.");
+#else
+ pr_warning("Unexpected BAD %d byte packet.\n", len);
+#endif
+ }
+#endif
+
+ filter = 0;
+
+ if (!(dev->flags & IFF_UP)) {
+ /* Filter packets received before we're up. */
+ filter = 1;
+ } else if (!(dev->flags & IFF_PROMISC)) {
+ /*
+ * FIXME: Implement HW multicast filter.
+ */
+ if (!IS_MULTICAST(buf) && !IS_BROADCAST(buf)) {
+ /* Filter packets not for our address. */
+ const u8 *mine = dev->dev_addr;
+ filter = compare_ether_addr(mine, buf);
+ }
+ }
+
+#ifdef IGNORE_DUP_ACKS
+
+ if (len != 66) {
+ /* FIXME: Must check "is_tcp_ack(buf, len)" somehow. */
+
+ other++;
+
+ } else if (index2 ==
+ qsp->__packet_receive_queue.__packet_write) {
+
+ final++;
+
+ } else {
+
+ netio_pkt_t *pkt2 = (netio_pkt_t *)
+ ((unsigned long) &qsp[1] + index2);
+
+ netio_pkt_metadata_t *metadata2 =
+ NETIO_PKT_METADATA(pkt2);
+
+ /* Extract the packet size. */
+ unsigned long len2 =
+ (NETIO_PKT_CUSTOM_LENGTH(pkt2) +
+ NET_IP_ALIGN - NETIO_PACKET_PADDING);
+
+ if (len2 == 66 &&
+ NETIO_PKT_FLOW_HASH_M(metadata, pkt) ==
+ NETIO_PKT_FLOW_HASH_M(metadata2, pkt2)) {
+
+ /* Extract the "linux_buffer_t". */
+ unsigned int buffer2 = pkt2->__packet.word;
+
+ /* Convert "linux_buffer_t" to "va". */
+ void *va2 =
+ __va((phys_addr_t)(buffer2 >> 1) << 7);
+
+ /* Extract the packet data pointer. */
+ /* Compare to "NETIO_PKT_CUSTOM_DATA(pkt)". */
+ unsigned char *buf2 = va2 + NET_IP_ALIGN;
+
+ /* Invalidate the packet buffer. */
+ if (!hash_default)
+ __inv_buffer(buf2, len2);
+
+ if (is_dup_ack(buf, buf2, len)) {
+ skip++;
+ filter = 1;
+ } else {
+ keep++;
+ }
+ }
+ }
+
+ if (net_ratelimit())
+ pr_info("Other %d Final %d Keep %d Skip %d.\n",
+ other, final, keep, skip);
+
+#endif
+
+ if (filter) {
+
+ /* ISSUE: Update "drop" statistics? */
+
+ tile_net_provide_linux_buffer(info, va, small);
+
+ } else {
+
+ /* Acquire the associated "skb". */
+ struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+ struct sk_buff *skb = *skb_ptr;
+
+ /* Paranoia. */
+ if (skb->data != buf)
+ panic("Corrupt linux buffer from LIPP! "
+ "VA=%p, skb=%p, skb->data=%p\n",
+ va, skb, skb->data);
+
+ /* Encode the actual packet length. */
+ skb_put(skb, len);
+
+ /* NOTE: This call also sets "skb->dev = dev". */
+ skb->protocol = eth_type_trans(skb, dev);
+
+ /* ISSUE: Discard corrupt packets? */
+ /* ISSUE: Discard packets with bad checksums? */
+
+ /* Avoid recomputing TCP/UDP checksums. */
+ if (NETIO_PKT_L4_CSUM_CORRECT_M(metadata, pkt))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ netif_receive_skb(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += len;
+
+ if (small)
+ info->num_needed_small_buffers++;
+ else
+ info->num_needed_large_buffers++;
+ }
+
+ /* Return four credits after every fourth packet. */
+ if (--qup->__receive_credit_remaining == 0) {
+ u32 interval = qup->__receive_credit_interval;
+ qup->__receive_credit_remaining = interval;
+ __netio_fastio_return_credits(qup->__fastio_index, interval);
+ }
+
+ /* Consume this packet. */
+ qup->__packet_receive_read = index2;
+
+ return !filter;
+}
+
+
+/*
+ * Handle some packets for the given device on the current CPU.
+ *
+ * ISSUE: The "rotting packet" race condition occurs if a packet
+ * arrives after the queue appears to be empty, and before the
+ * hypervisor interrupt is re-enabled.
+ */
+static int tile_net_poll(struct napi_struct *napi, int budget)
+{
+ struct net_device *dev = napi->dev;
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+ struct tile_netio_queue *queue = &info->queue;
+ netio_queue_impl_t *qsp = queue->__system_part;
+ netio_queue_user_impl_t *qup = &queue->__user_part;
+
+ unsigned int work = 0;
+
+ while (1) {
+ int index = qup->__packet_receive_read;
+ if (index == qsp->__packet_receive_queue.__packet_write)
+ break;
+
+ if (tile_net_poll_aux(info, index)) {
+ if (++work >= budget)
+ goto done;
+ }
+ }
+
+ napi_complete(&info->napi);
+
+ /* Re-enable hypervisor interrupts. */
+ enable_percpu_irq(priv->intr_id);
+
+ /* HACK: Avoid the "rotting packet" problem. */
+ if (qup->__packet_receive_read !=
+ qsp->__packet_receive_queue.__packet_write)
+ napi_schedule(&info->napi);
+
+ /* ISSUE: Handle completions? */
+
+done:
+
+ tile_net_provide_needed_buffers(info);
+
+ return work;
+}
+
+
+/*
+ * Handle an ingress interrupt for the given device on the current cpu.
+ */
+static irqreturn_t tile_net_handle_ingress_interrupt(int irq, void *dev_ptr)
+{
+ struct net_device *dev = (struct net_device *)dev_ptr;
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+ /* Disable hypervisor interrupt. */
+ disable_percpu_irq(priv->intr_id);
+
+ napi_schedule(&info->napi);
+
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * One time initialization per interface.
+ */
+static int tile_net_open_aux(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+
+ int ret;
+ int dummy;
+ unsigned int epp_lotar;
+
+ /*
+ * Find out where EPP memory should be homed.
+ */
+ ret = hv_dev_pread(priv->hv_devhdl, 0,
+ (HV_VirtAddr)&epp_lotar, sizeof(epp_lotar),
+ NETIO_EPP_SHM_OFF);
+ if (ret < 0) {
+ pr_err("could not read epp_shm_queue lotar.\n");
+ return -EIO;
+ }
+
+ /*
+ * Home the page on the EPP.
+ */
+ {
+ int epp_home = hv_lotar_to_cpu(epp_lotar);
+ struct page *page = virt_to_page(priv->epp_queue);
+ homecache_change_page_home(page, 0, epp_home);
+ }
+
+ /*
+ * Register the EPP shared memory queue.
+ */
+ {
+ netio_ipp_address_t ea = {
+ .va = 0,
+ .pa = __pa(priv->epp_queue),
+ .pte = hv_pte(0),
+ .size = PAGE_SIZE,
+ };
+ ea.pte = hv_pte_set_lotar(ea.pte, epp_lotar);
+ ea.pte = hv_pte_set_mode(ea.pte, HV_PTE_MODE_CACHE_TILE_L3);
+ ret = hv_dev_pwrite(priv->hv_devhdl, 0,
+ (HV_VirtAddr)&ea,
+ sizeof(ea),
+ NETIO_EPP_SHM_OFF);
+ if (ret < 0)
+ return -EIO;
+ }
+
+ /*
+ * Start LIPP/LEPP.
+ */
+ if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+ sizeof(dummy), NETIO_IPP_START_SHIM_OFF) < 0) {
+ pr_warning("Failed to start LIPP/LEPP.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Register with hypervisor on each CPU.
+ *
+ * Strangely, this function does important things even if it "fails",
+ * which is especially common if the link is not up yet. Hopefully
+ * these things are all "harmless" if done twice!
+ */
+static void tile_net_register(void *dev_ptr)
+{
+ struct net_device *dev = (struct net_device *)dev_ptr;
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info;
+
+ struct tile_netio_queue *queue;
+
+ /* Only network cpus can receive packets. */
+ int queue_id =
+ cpumask_test_cpu(my_cpu, &priv->network_cpus_map) ? 0 : 255;
+
+ netio_input_config_t config = {
+ .flags = 0,
+ .num_receive_packets = priv->network_cpus_credits,
+ .queue_id = queue_id
+ };
+
+ int ret = 0;
+ netio_queue_impl_t *queuep;
+
+ PDEBUG("tile_net_register(queue_id %d)\n", queue_id);
+
+ if (!strcmp(dev->name, "xgbe0"))
+ info = &__get_cpu_var(hv_xgbe0);
+ else if (!strcmp(dev->name, "xgbe1"))
+ info = &__get_cpu_var(hv_xgbe1);
+ else if (!strcmp(dev->name, "gbe0"))
+ info = &__get_cpu_var(hv_gbe0);
+ else if (!strcmp(dev->name, "gbe1"))
+ info = &__get_cpu_var(hv_gbe1);
+ else
+ BUG();
+
+ /* Initialize the egress timer. */
+ init_timer(&info->egress_timer);
+ info->egress_timer.data = (long)info;
+ info->egress_timer.function = tile_net_handle_egress_timer;
+
+ priv->cpu[my_cpu] = info;
+
+ /*
+ * Register ourselves with the IPP.
+ */
+ ret = hv_dev_pwrite(priv->hv_devhdl, 0,
+ (HV_VirtAddr)&config,
+ sizeof(netio_input_config_t),
+ NETIO_IPP_INPUT_REGISTER_OFF);
+ PDEBUG("hv_dev_pwrite(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n",
+ ret);
+ if (ret < 0) {
+ printk(KERN_DEBUG "hv_dev_pwrite NETIO_IPP_INPUT_REGISTER_OFF"
+ " failure %d\n", ret);
+ info->link_down = (ret == NETIO_LINK_DOWN);
+ return;
+ }
+
+ /*
+ * Get the pointer to our queue's system part.
+ */
+
+ ret = hv_dev_pread(priv->hv_devhdl, 0,
+ (HV_VirtAddr)&queuep,
+ sizeof(netio_queue_impl_t *),
+ NETIO_IPP_INPUT_REGISTER_OFF);
+ PDEBUG("hv_dev_pread(NETIO_IPP_INPUT_REGISTER_OFF) returned %d\n",
+ ret);
+ PDEBUG("queuep %p\n", queuep);
+ if (ret <= 0) {
+ /* ISSUE: Shouldn't this be a fatal error? */
+ pr_err("hv_dev_pread NETIO_IPP_INPUT_REGISTER_OFF failure\n");
+ return;
+ }
+
+ queue = &info->queue;
+
+ queue->__system_part = queuep;
+
+ memset(&queue->__user_part, 0, sizeof(netio_queue_user_impl_t));
+
+ /* This is traditionally "config.num_receive_packets / 2". */
+ queue->__user_part.__receive_credit_interval = 4;
+ queue->__user_part.__receive_credit_remaining =
+ queue->__user_part.__receive_credit_interval;
+
+ /*
+ * Get a fastio index from the hypervisor.
+ * ISSUE: Shouldn't this check the result?
+ */
+ ret = hv_dev_pread(priv->hv_devhdl, 0,
+ (HV_VirtAddr)&queue->__user_part.__fastio_index,
+ sizeof(queue->__user_part.__fastio_index),
+ NETIO_IPP_GET_FASTIO_OFF);
+ PDEBUG("hv_dev_pread(NETIO_IPP_GET_FASTIO_OFF) returned %d\n", ret);
+
+ netif_napi_add(dev, &info->napi, tile_net_poll, 64);
+
+ /* Now we are registered. */
+ info->registered = true;
+}
+
+
+/*
+ * Unregister with hypervisor on each CPU.
+ */
+static void tile_net_unregister(void *dev_ptr)
+{
+ struct net_device *dev = (struct net_device *)dev_ptr;
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+ int ret = 0;
+ int dummy = 0;
+
+ /* Do nothing if never registered. */
+ if (info == NULL)
+ return;
+
+ /* Do nothing if already unregistered. */
+ if (!info->registered)
+ return;
+
+ /*
+ * Unregister ourselves with LIPP.
+ */
+ ret = hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+ sizeof(dummy), NETIO_IPP_INPUT_UNREGISTER_OFF);
+ PDEBUG("hv_dev_pwrite(NETIO_IPP_INPUT_UNREGISTER_OFF) returned %d\n",
+ ret);
+ if (ret < 0) {
+ /* FIXME: Just panic? */
+ pr_err("hv_dev_pwrite NETIO_IPP_INPUT_UNREGISTER_OFF"
+ " failure %d\n", ret);
+ }
+
+ /*
+ * Discard all packets still in our NetIO queue. Hopefully,
+ * once the unregister call is complete, there will be no
+ * packets still in flight on the IDN.
+ */
+ tile_net_discard_packets(dev);
+
+ /* Reset state. */
+ info->num_needed_small_buffers = 0;
+ info->num_needed_large_buffers = 0;
+
+ /* Cancel egress timer. */
+ del_timer(&info->egress_timer);
+ info->egress_timer_scheduled = false;
+
+ netif_napi_del(&info->napi);
+
+ /* Now we are unregistered. */
+ info->registered = false;
+}
+
+
+/*
+ * Helper function for "tile_net_stop()".
+ *
+ * Also used to handle registration failure in "tile_net_open_inner()",
+ * when "fully_opened" is known to be false, and the various extra
+ * steps in "tile_net_stop()" are not necessary. ISSUE: It might be
+ * simpler if we could just call "tile_net_stop()" anyway.
+ */
+static void tile_net_stop_aux(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+
+ int dummy = 0;
+
+ /* Unregister all tiles, so LIPP will stop delivering packets. */
+ on_each_cpu(tile_net_unregister, (void *)dev, 1);
+
+ /* Stop LIPP/LEPP. */
+ if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+ sizeof(dummy), NETIO_IPP_STOP_SHIM_OFF) < 0)
+ panic("Failed to stop LIPP/LEPP!\n");
+
+ priv->partly_opened = 0;
+}
+
+
+/*
+ * Disable ingress interrupts for the given device on the current cpu.
+ */
+static void tile_net_disable_intr(void *dev_ptr)
+{
+ struct net_device *dev = (struct net_device *)dev_ptr;
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+ /* Disable hypervisor interrupt. */
+ disable_percpu_irq(priv->intr_id);
+
+ /* Disable NAPI if needed. */
+ if (info != NULL && info->napi_enabled) {
+ napi_disable(&info->napi);
+ info->napi_enabled = false;
+ }
+}
+
+
+/*
+ * Enable ingress interrupts for the given device on the current cpu.
+ */
+static void tile_net_enable_intr(void *dev_ptr)
+{
+ struct net_device *dev = (struct net_device *)dev_ptr;
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+
+ /* Enable hypervisor interrupt. */
+ enable_percpu_irq(priv->intr_id);
+
+ /* Enable NAPI. */
+ napi_enable(&info->napi);
+ info->napi_enabled = true;
+}
+
+
+/*
+ * tile_net_open_inner does most of the work of bringing up the interface.
+ * It's called from tile_net_open(), and also from tile_net_retry_open().
+ * The return value is 0 if the interface was brought up, < 0 if
+ * tile_net_open() should return the return value as an error, and > 0 if
+ * tile_net_open() should return success and schedule a work item to
+ * periodically retry the bringup.
+ */
+static int tile_net_open_inner(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info;
+ struct tile_netio_queue *queue;
+ unsigned int irq;
+ int i;
+
+ /*
+ * First try to register just on the local CPU, and handle any
+ * semi-expected "link down" failure specially. Note that we
+ * do NOT call "tile_net_stop_aux()", unlike below.
+ */
+ tile_net_register(dev);
+ info = priv->cpu[my_cpu];
+ if (!info->registered) {
+ if (info->link_down)
+ return 1;
+ return -EAGAIN;
+ }
+
+ /*
+ * Now register everywhere else. If any registration fails,
+ * even for "link down" (which might not be possible), we
+ * clean up using "tile_net_stop_aux()".
+ */
+ smp_call_function(tile_net_register, (void *)dev, 1);
+ for_each_online_cpu(i) {
+ if (!priv->cpu[i]->registered) {
+ tile_net_stop_aux(dev);
+ return -EAGAIN;
+ }
+ }
+
+ queue = &info->queue;
+
+ /*
+ * Set the device intr bit mask.
+ * The tile_net_register above sets per tile __intr_id.
+ */
+ priv->intr_id = queue->__system_part->__intr_id;
+ BUG_ON(!priv->intr_id);
+
+ /*
+ * Register the device interrupt handler.
+ * The __ffs() function returns the index into the interrupt handler
+ * table from the interrupt bit mask which should have one bit
+ * and one bit only set.
+ */
+ irq = __ffs(priv->intr_id);
+ tile_irq_activate(irq, TILE_IRQ_PERCPU);
+ BUG_ON(request_irq(irq, tile_net_handle_ingress_interrupt,
+ 0, dev->name, (void *)dev) != 0);
+
+ /* ISSUE: How could "priv->fully_opened" ever be "true" here? */
+
+ if (!priv->fully_opened) {
+
+ int dummy = 0;
+
+ /* Allocate initial buffers. */
+
+ int max_buffers =
+ priv->network_cpus_count * priv->network_cpus_credits;
+
+ info->num_needed_small_buffers =
+ min(LIPP_SMALL_BUFFERS, max_buffers);
+
+ info->num_needed_large_buffers =
+ min(LIPP_LARGE_BUFFERS, max_buffers);
+
+ tile_net_provide_needed_buffers(info);
+
+ if (info->num_needed_small_buffers != 0 ||
+ info->num_needed_large_buffers != 0)
+ panic("Insufficient memory for buffer stack!");
+
+ /* Start LIPP/LEPP and activate "ingress" at the shim. */
+ if (hv_dev_pwrite(priv->hv_devhdl, 0, (HV_VirtAddr)&dummy,
+ sizeof(dummy), NETIO_IPP_INPUT_INIT_OFF) < 0)
+ panic("Failed to activate the LIPP Shim!\n");
+
+ priv->fully_opened = 1;
+ }
+
+ /* On each tile, enable the hypervisor to trigger interrupts. */
+ /* ISSUE: Do this before starting LIPP/LEPP? */
+ on_each_cpu(tile_net_enable_intr, (void *)dev, 1);
+
+ /* Start our transmit queue. */
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+
+/*
+ * Called periodically to retry bringing up the NetIO interface,
+ * if it doesn't come up cleanly during tile_net_open().
+ */
+static void tile_net_open_retry(struct work_struct *w)
+{
+ struct delayed_work *dw =
+ container_of(w, struct delayed_work, work);
+
+ struct tile_net_priv *priv =
+ container_of(dw, struct tile_net_priv, retry_work);
+
+ /*
+ * Try to bring the NetIO interface up. If it fails, reschedule
+ * ourselves to try again later; otherwise, tell Linux we now have
+ * a working link. ISSUE: What if the return value is negative?
+ */
+ if (tile_net_open_inner(priv->dev))
+ schedule_delayed_work_on(singlethread_cpu, &priv->retry_work,
+ TILE_NET_RETRY_INTERVAL);
+ else
+ netif_carrier_on(priv->dev);
+}
+
+
+/*
+ * Called when a network interface is made active.
+ *
+ * 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.
+ *
+ * If the actual link is not available yet, then we tell Linux that
+ * we have no carrier, and we keep checking until the link comes up.
+ */
+static int tile_net_open(struct net_device *dev)
+{
+ int ret = 0;
+ struct tile_net_priv *priv = netdev_priv(dev);
+
+ /*
+ * We rely on priv->partly_opened to tell us if this is the
+ * first time this interface is being brought up. If it is
+ * set, the IPP was already initialized and should not be
+ * initialized again.
+ */
+ if (!priv->partly_opened) {
+
+ int count;
+ int credits;
+
+ /* Initialize LIPP/LEPP, and start the Shim. */
+ ret = tile_net_open_aux(dev);
+ if (ret < 0) {
+ pr_err("tile_net_open_aux failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Analyze the network cpus. */
+
+ if (network_cpus_used)
+ cpumask_copy(&priv->network_cpus_map,
+ &network_cpus_map);
+ else
+ cpumask_copy(&priv->network_cpus_map, cpu_online_mask);
+
+
+ count = cpumask_weight(&priv->network_cpus_map);
+
+ /* Limit credits to available buffers, and apply min. */
+ credits = max(16, (LIPP_LARGE_BUFFERS / count) & ~1);
+
+ /* Apply "GBE" max limit. */
+ /* ISSUE: Use higher limit for XGBE? */
+ credits = min(NETIO_MAX_RECEIVE_PKTS, credits);
+
+ priv->network_cpus_count = count;
+ priv->network_cpus_credits = credits;
+
+#ifdef TILE_NET_DEBUG
+ pr_info("Using %d network cpus, with %d credits each\n",
+ priv->network_cpus_count, priv->network_cpus_credits);
+#endif
+
+ priv->partly_opened = 1;
+ }
+
+ /*
+ * Attempt to bring up the link.
+ */
+ ret = tile_net_open_inner(dev);
+ if (ret <= 0) {
+ if (ret == 0)
+ netif_carrier_on(dev);
+ return ret;
+ }
+
+ /*
+ * We were unable to bring up the NetIO interface, but we want to
+ * try again in a little bit. Tell Linux that we have no carrier
+ * so it doesn't try to use the interface before the link comes up
+ * and then remember to try again later.
+ */
+ netif_carrier_off(dev);
+ schedule_delayed_work_on(singlethread_cpu, &priv->retry_work,
+ TILE_NET_RETRY_INTERVAL);
+
+ return 0;
+}
+
+
+/*
+ * Disables a network interface.
+ *
+ * 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.
+ *
+ * ISSUE: Can this can be called while "tile_net_poll()" is running?
+ */
+static int tile_net_stop(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+
+ bool pending = true;
+
+ PDEBUG("tile_net_stop()\n");
+
+ /* ISSUE: Only needed if not yet fully open. */
+ cancel_delayed_work_sync(&priv->retry_work);
+
+ /* Can't transmit any more. */
+ netif_stop_queue(dev);
+
+ /*
+ * Disable hypervisor interrupts on each tile.
+ */
+ on_each_cpu(tile_net_disable_intr, (void *)dev, 1);
+
+ /*
+ * Unregister the interrupt handler.
+ * The __ffs() function returns the index into the interrupt handler
+ * table from the interrupt bit mask which should have one bit
+ * and one bit only set.
+ */
+ if (priv->intr_id)
+ free_irq(__ffs(priv->intr_id), dev);
+
+ /*
+ * Drain all the LIPP buffers.
+ */
+
+ while (true) {
+ int buffer;
+
+ /* NOTE: This should never fail. */
+ if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&buffer,
+ sizeof(buffer), NETIO_IPP_DRAIN_OFF) < 0)
+ break;
+
+ /* Stop when done. */
+ if (buffer == 0)
+ break;
+
+ {
+ /* Convert "linux_buffer_t" to "va". */
+ void *va = __va((phys_addr_t)(buffer >> 1) << 7);
+
+ /* Acquire the associated "skb". */
+ struct sk_buff **skb_ptr = va - sizeof(*skb_ptr);
+ struct sk_buff *skb = *skb_ptr;
+
+ kfree_skb(skb);
+ }
+ }
+
+ /* Stop LIPP/LEPP. */
+ tile_net_stop_aux(dev);
+
+
+ priv->fully_opened = 0;
+
+
+ /*
+ * XXX: ISSUE: It appears that, in practice anyway, by the
+ * time we get here, there are no pending completions.
+ */
+ while (pending) {
+
+ struct sk_buff *olds[32];
+ unsigned int wanted = 32;
+ unsigned int i, nolds = 0;
+
+ nolds = tile_net_lepp_grab_comps(dev, olds,
+ wanted, &pending);
+
+ /* ISSUE: We have never actually seen this debug spew. */
+ if (nolds != 0)
+ pr_info("During tile_net_stop(), grabbed %d comps.\n",
+ nolds);
+
+ for (i = 0; i < nolds; i++)
+ kfree_skb(olds[i]);
+ }
+
+
+ /* Wipe the EPP queue. */
+ memset(priv->epp_queue, 0, sizeof(lepp_queue_t));
+
+ /* Evict the EPP queue. */
+ finv_buffer(priv->epp_queue, PAGE_SIZE);
+
+ return 0;
+}
+
+
+/*
+ * Prepare the "frags" info for the resulting LEPP command.
+ *
+ * If needed, flush the memory used by the frags.
+ */
+static unsigned int tile_net_tx_frags(lepp_frag_t *frags,
+ struct sk_buff *skb,
+ void *b_data, unsigned int b_len)
+{
+ unsigned int i, n = 0;
+
+ struct skb_shared_info *sh = skb_shinfo(skb);
+
+ phys_addr_t cpa;
+
+ if (b_len != 0) {
+
+ if (!hash_default)
+ finv_buffer_remote(b_data, b_len);
+
+ cpa = __pa(b_data);
+ frags[n].cpa_lo = cpa;
+ frags[n].cpa_hi = cpa >> 32;
+ frags[n].length = b_len;
+ frags[n].hash_for_home = hash_default;
+ n++;
+ }
+
+ for (i = 0; i < sh->nr_frags; i++) {
+
+ skb_frag_t *f = &sh->frags[i];
+ unsigned long pfn = page_to_pfn(f->page);
+
+ /* FIXME: Compute "hash_for_home" properly. */
+ /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */
+ int hash_for_home = hash_default;
+
+ /* FIXME: Hmmm. */
+ if (!hash_default) {
+ void *va = pfn_to_kaddr(pfn) + f->page_offset;
+ BUG_ON(PageHighMem(f->page));
+ finv_buffer_remote(va, f->size);
+ }
+
+ cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset;
+ frags[n].cpa_lo = cpa;
+ frags[n].cpa_hi = cpa >> 32;
+ frags[n].length = f->size;
+ frags[n].hash_for_home = hash_for_home;
+ n++;
+ }
+
+ return n;
+}
+
+
+/*
+ * This function takes "skb", consisting of a header template and a
+ * payload, and hands it to LEPP, to emit as one or more segments,
+ * each consisting of a possibly modified header, plus a piece of the
+ * payload, via a process known as "tcp segmentation offload".
+ *
+ * Usually, "data" will contain the header template, of size "sh_len",
+ * and "sh->frags" will contain "skb->data_len" bytes of payload, and
+ * there will be "sh->gso_segs" segments.
+ *
+ * Sometimes, if "sendfile()" requires copying, we will be called with
+ * "data" containing the header and payload, with "frags" being empty.
+ *
+ * In theory, "sh->nr_frags" could be 3, but in practice, it seems
+ * that this will never actually happen.
+ *
+ * See "emulate_large_send_offload()" for some reference code, which
+ * does not handle checksumming.
+ *
+ * ISSUE: How do we make sure that high memory DMA does not migrate?
+ */
+static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+ struct tile_net_stats_t *stats = &info->stats;
+
+ struct skb_shared_info *sh = skb_shinfo(skb);
+
+ unsigned char *data = skb->data;
+
+ /* The ip header follows the ethernet header. */
+ struct iphdr *ih = ip_hdr(skb);
+ unsigned int ih_len = ih->ihl * 4;
+
+ /* Note that "nh == ih", by definition. */
+ unsigned char *nh = skb_network_header(skb);
+ unsigned int eh_len = nh - data;
+
+ /* The tcp header follows the ip header. */
+ struct tcphdr *th = (struct tcphdr *)(nh + ih_len);
+ unsigned int th_len = th->doff * 4;
+
+ /* The total number of header bytes. */
+ /* NOTE: This may be less than skb_headlen(skb). */
+ unsigned int sh_len = eh_len + ih_len + th_len;
+
+ /* The number of payload bytes at "skb->data + sh_len". */
+ /* This is non-zero for sendfile() without HIGHDMA. */
+ unsigned int b_len = skb_headlen(skb) - sh_len;
+
+ /* The total number of payload bytes. */
+ unsigned int d_len = b_len + skb->data_len;
+
+ /* The maximum payload size. */
+ unsigned int p_len = sh->gso_size;
+
+ /* The total number of segments. */
+ unsigned int num_segs = sh->gso_segs;
+
+ /* The temporary copy of the command. */
+ u32 cmd_body[(LEPP_MAX_CMD_SIZE + 3) / 4];
+ lepp_tso_cmd_t *cmd = (lepp_tso_cmd_t *)cmd_body;
+
+ /* Analyze the "frags". */
+ unsigned int num_frags =
+ tile_net_tx_frags(cmd->frags, skb, data + sh_len, b_len);
+
+ /* The size of the command, including frags and header. */
+ size_t cmd_size = LEPP_TSO_CMD_SIZE(num_frags, sh_len);
+
+ /* The command header. */
+ lepp_tso_cmd_t cmd_init = {
+ .tso = true,
+ .header_size = sh_len,
+ .ip_offset = eh_len,
+ .tcp_offset = eh_len + ih_len,
+ .payload_size = p_len,
+ .num_frags = num_frags,
+ };
+
+ unsigned long irqflags;
+
+ lepp_queue_t *eq = priv->epp_queue;
+
+ struct sk_buff *olds[4];
+ unsigned int wanted = 4;
+ unsigned int i, nolds = 0;
+
+ unsigned int cmd_head, cmd_tail, cmd_next;
+ unsigned int comp_tail;
+
+ unsigned int free_slots;
+
+
+ /* Paranoia. */
+ BUG_ON(skb->protocol != htons(ETH_P_IP));
+ BUG_ON(ih->protocol != IPPROTO_TCP);
+ BUG_ON(skb->ip_summed != CHECKSUM_PARTIAL);
+ BUG_ON(num_frags > LEPP_MAX_FRAGS);
+ /*--BUG_ON(num_segs != (d_len + (p_len - 1)) / p_len); */
+ BUG_ON(num_segs <= 1);
+
+
+ /* Finish preparing the command. */
+
+ /* Copy the command header. */
+ *cmd = cmd_init;
+
+ /* Copy the "header". */
+ memcpy(&cmd->frags[num_frags], data, sh_len);
+
+
+ /* Prefetch and wait, to minimize time spent holding the spinlock. */
+ prefetch_L1(&eq->comp_tail);
+ prefetch_L1(&eq->cmd_tail);
+ mb();
+
+
+ /* Enqueue the command. */
+
+ spin_lock_irqsave(&priv->cmd_lock, irqflags);
+
+ /*
+ * Handle completions if needed to make room.
+ * HACK: Spin until there is sufficient room.
+ */
+ free_slots = lepp_num_free_comp_slots(eq);
+ if (free_slots < 1) {
+spin:
+ nolds += tile_net_lepp_grab_comps(dev, olds + nolds,
+ wanted - nolds, NULL);
+ if (lepp_num_free_comp_slots(eq) < 1)
+ goto spin;
+ }
+
+ cmd_head = eq->cmd_head;
+ cmd_tail = eq->cmd_tail;
+
+ /* NOTE: The "gotos" below are untested. */
+
+ /* Prepare to advance, detecting full queue. */
+ cmd_next = cmd_tail + cmd_size;
+ if (cmd_tail < cmd_head && cmd_next >= cmd_head)
+ goto spin;
+ if (cmd_next > LEPP_CMD_LIMIT) {
+ cmd_next = 0;
+ if (cmd_next == cmd_head)
+ goto spin;
+ }
+
+ /* Copy the command. */
+ memcpy(&eq->cmds[cmd_tail], cmd, cmd_size);
+
+ /* Advance. */
+ cmd_tail = cmd_next;
+
+ /* Record "skb" for eventual freeing. */
+ comp_tail = eq->comp_tail;
+ eq->comps[comp_tail] = skb;
+ LEPP_QINC(comp_tail);
+ eq->comp_tail = comp_tail;
+
+ /* Flush before allowing LEPP to handle the command. */
+ __insn_mf();
+
+ eq->cmd_tail = cmd_tail;
+
+ spin_unlock_irqrestore(&priv->cmd_lock, irqflags);
+
+ if (nolds == 0)
+ nolds = tile_net_lepp_grab_comps(dev, olds, wanted, NULL);
+
+ /* Handle completions. */
+ for (i = 0; i < nolds; i++)
+ kfree_skb(olds[i]);
+
+ /* Update stats. */
+ stats->tx_packets += num_segs;
+ stats->tx_bytes += (num_segs * sh_len) + d_len;
+
+ /* Make sure the egress timer is scheduled. */
+ tile_net_schedule_egress_timer(info);
+
+ return NETDEV_TX_OK;
+}
+
+
+/*
+ * Transmit a packet (called by the kernel via "hard_start_xmit" hook).
+ */
+static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+ int my_cpu = smp_processor_id();
+ struct tile_net_cpu *info = priv->cpu[my_cpu];
+ struct tile_net_stats_t *stats = &info->stats;
+
+ unsigned long irqflags;
+
+ struct skb_shared_info *sh = skb_shinfo(skb);
+
+ unsigned int len = skb->len;
+ unsigned char *data = skb->data;
+
+ unsigned int csum_start = skb->csum_start - skb_headroom(skb);
+
+ lepp_frag_t frags[LEPP_MAX_FRAGS];
+
+ unsigned int num_frags;
+
+ lepp_queue_t *eq = priv->epp_queue;
+
+ struct sk_buff *olds[4];
+ unsigned int wanted = 4;
+ unsigned int i, nolds = 0;
+
+ unsigned int cmd_size = sizeof(lepp_cmd_t);
+
+ unsigned int cmd_head, cmd_tail, cmd_next;
+ unsigned int comp_tail;
+
+ lepp_cmd_t cmds[LEPP_MAX_FRAGS];
+
+ unsigned int free_slots;
+
+
+ /*
+ * This is paranoia, since we think that if the link doesn't come
+ * up, telling Linux we have no carrier will keep it from trying
+ * to transmit. If it does, though, we can't execute this routine,
+ * since data structures we depend on aren't set up yet.
+ */
+ if (!info->registered)
+ return NETDEV_TX_BUSY;
+
+
+ /* Save the timestamp. */
+ dev->trans_start = jiffies;
+
+
+#ifdef TILE_NET_PARANOIA
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (hash_default) {
+ HV_PTE pte = *virt_to_pte(current->mm, (unsigned long)data);
+ if (hv_pte_get_mode(pte) != HV_PTE_MODE_CACHE_HASH_L3)
+ panic("Non-coherent egress buffer!");
+ }
+#endif
+#endif
+
+
+#ifdef TILE_NET_DUMP_PACKETS
+ /* ISSUE: Does not dump the "frags". */
+ dump_packet(data, skb_headlen(skb), "tx");
+#endif /* TILE_NET_DUMP_PACKETS */
+
+
+ if (sh->gso_size != 0)
+ return tile_net_tx_tso(skb, dev);
+
+
+ /* Prepare the commands. */
+
+ num_frags = tile_net_tx_frags(frags, skb, data, skb_headlen(skb));
+
+ for (i = 0; i < num_frags; i++) {
+
+ bool final = (i == num_frags - 1);
+
+ lepp_cmd_t cmd = {
+ .cpa_lo = frags[i].cpa_lo,
+ .cpa_hi = frags[i].cpa_hi,
+ .length = frags[i].length,
+ .hash_for_home = frags[i].hash_for_home,
+ .send_completion = final,
+ .end_of_packet = final
+ };
+
+ if (i == 0 && skb->ip_summed == CHECKSUM_PARTIAL) {
+ cmd.compute_checksum = 1;
+ cmd.checksum_data.bits.start_byte = csum_start;
+ cmd.checksum_data.bits.count = len - csum_start;
+ cmd.checksum_data.bits.destination_byte =
+ csum_start + skb->csum_offset;
+ }
+
+ cmds[i] = cmd;
+ }
+
+
+ /* Prefetch and wait, to minimize time spent holding the spinlock. */
+ prefetch_L1(&eq->comp_tail);
+ prefetch_L1(&eq->cmd_tail);
+ mb();
+
+
+ /* Enqueue the commands. */
+
+ spin_lock_irqsave(&priv->cmd_lock, irqflags);
+
+ /*
+ * Handle completions if needed to make room.
+ * HACK: Spin until there is sufficient room.
+ */
+ free_slots = lepp_num_free_comp_slots(eq);
+ if (free_slots < 1) {
+spin:
+ nolds += tile_net_lepp_grab_comps(dev, olds + nolds,
+ wanted - nolds, NULL);
+ if (lepp_num_free_comp_slots(eq) < 1)
+ goto spin;
+ }
+
+ cmd_head = eq->cmd_head;
+ cmd_tail = eq->cmd_tail;
+
+ /* NOTE: The "gotos" below are untested. */
+
+ /* Copy the commands, or fail. */
+ for (i = 0; i < num_frags; i++) {
+
+ /* Prepare to advance, detecting full queue. */
+ cmd_next = cmd_tail + cmd_size;
+ if (cmd_tail < cmd_head && cmd_next >= cmd_head)
+ goto spin;
+ if (cmd_next > LEPP_CMD_LIMIT) {
+ cmd_next = 0;
+ if (cmd_next == cmd_head)
+ goto spin;
+ }
+
+ /* Copy the command. */
+ *(lepp_cmd_t *)&eq->cmds[cmd_tail] = cmds[i];
+
+ /* Advance. */
+ cmd_tail = cmd_next;
+ }
+
+ /* Record "skb" for eventual freeing. */
+ comp_tail = eq->comp_tail;
+ eq->comps[comp_tail] = skb;
+ LEPP_QINC(comp_tail);
+ eq->comp_tail = comp_tail;
+
+ /* Flush before allowing LEPP to handle the command. */
+ __insn_mf();
+
+ eq->cmd_tail = cmd_tail;
+
+ spin_unlock_irqrestore(&priv->cmd_lock, irqflags);
+
+ if (nolds == 0)
+ nolds = tile_net_lepp_grab_comps(dev, olds, wanted, NULL);
+
+ /* Handle completions. */
+ for (i = 0; i < nolds; i++)
+ kfree_skb(olds[i]);
+
+ /* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */
+ stats->tx_packets++;
+ stats->tx_bytes += ((len >= ETH_ZLEN) ? len : ETH_ZLEN);
+
+ /* Make sure the egress timer is scheduled. */
+ tile_net_schedule_egress_timer(info);
+
+ return NETDEV_TX_OK;
+}
+
+
+/*
+ * Deal with a transmit timeout.
+ */
+static void tile_net_tx_timeout(struct net_device *dev)
+{
+ PDEBUG("tile_net_tx_timeout()\n");
+ PDEBUG("Transmit timeout at %ld, latency %ld\n", jiffies,
+ jiffies - dev->trans_start);
+
+ /* XXX: ISSUE: This doesn't seem useful for us. */
+ netif_wake_queue(dev);
+}
+
+
+/*
+ * Ioctl commands.
+ */
+static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ return -EOPNOTSUPP;
+}
+
+
+/*
+ * Get System Network Statistics.
+ *
+ * Returns the address of the device statistics structure.
+ */
+static struct net_device_stats *tile_net_get_stats(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+ u32 rx_packets = 0;
+ u32 tx_packets = 0;
+ u32 rx_bytes = 0;
+ u32 tx_bytes = 0;
+ int i;
+
+ for_each_online_cpu(i) {
+ if (priv->cpu[i]) {
+ rx_packets += priv->cpu[i]->stats.rx_packets;
+ rx_bytes += priv->cpu[i]->stats.rx_bytes;
+ tx_packets += priv->cpu[i]->stats.tx_packets;
+ tx_bytes += priv->cpu[i]->stats.tx_bytes;
+ }
+ }
+
+ priv->stats.rx_packets = rx_packets;
+ priv->stats.rx_bytes = rx_bytes;
+ priv->stats.tx_packets = tx_packets;
+ priv->stats.tx_bytes = tx_bytes;
+
+ return &priv->stats;
+}
+
+
+/*
+ * Change the "mtu".
+ *
+ * The "change_mtu" method is usually not needed.
+ * If you need it, it must be like this.
+ */
+static int tile_net_change_mtu(struct net_device *dev, int new_mtu)
+{
+ PDEBUG("tile_net_change_mtu()\n");
+
+ /* Check ranges. */
+ if ((new_mtu < 68) || (new_mtu > 1500))
+ return -EINVAL;
+
+ /* Accept the value. */
+ dev->mtu = new_mtu;
+
+ return 0;
+}
+
+
+/*
+ * Change the Ethernet Address of the NIC.
+ *
+ * The hypervisor driver does not support changing MAC address. However,
+ * the IPP does not do anything with the MAC address, so the address which
+ * gets used on outgoing packets, and which is accepted on incoming packets,
+ * is completely up to the NetIO program or kernel driver which is actually
+ * handling them.
+ *
+ * Returns 0 on success, negative on failure.
+ */
+static int tile_net_set_mac_address(struct net_device *dev, void *p)
+{
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
+ /* ISSUE: Note that "dev_addr" is now a pointer. */
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ return 0;
+}
+
+
+/*
+ * Obtain the MAC address from the hypervisor.
+ * This must be done before opening the device.
+ */
+static int tile_net_get_mac(struct net_device *dev)
+{
+ struct tile_net_priv *priv = netdev_priv(dev);
+
+ char hv_dev_name[32];
+ int len;
+
+ __netio_getset_offset_t offset = { .word = NETIO_IPP_PARAM_OFF };
+
+ int ret;
+
+ /* For example, "xgbe0". */
+ strcpy(hv_dev_name, dev->name);
+ len = strlen(hv_dev_name);
+
+ /* For example, "xgbe/0". */
+ hv_dev_name[len] = hv_dev_name[len - 1];
+ hv_dev_name[len - 1] = '/';
+ len++;
+
+ /* For example, "xgbe/0/native_hash". */
+ strcpy(hv_dev_name + len, hash_default ? "/native_hash" : "/native");
+
+ /* Get the hypervisor handle for this device. */
+ priv->hv_devhdl = hv_dev_open((HV_VirtAddr)hv_dev_name, 0);
+ PDEBUG("hv_dev_open(%s) returned %d %p\n",
+ hv_dev_name, priv->hv_devhdl, &priv->hv_devhdl);
+ if (priv->hv_devhdl < 0) {
+ if (priv->hv_devhdl == HV_ENODEV)
+ printk(KERN_DEBUG "Ignoring unconfigured device %s\n",
+ hv_dev_name);
+ else
+ printk(KERN_DEBUG "hv_dev_open(%s) returned %d\n",
+ hv_dev_name, priv->hv_devhdl);
+ return -1;
+ }
+
+ /*
+ * Read the hardware address from the hypervisor.
+ * ISSUE: Note that "dev_addr" is now a pointer.
+ */
+ offset.bits.class = NETIO_PARAM;
+ offset.bits.addr = NETIO_PARAM_MAC;
+ ret = hv_dev_pread(priv->hv_devhdl, 0,
+ (HV_VirtAddr)dev->dev_addr, dev->addr_len,
+ offset.word);
+ PDEBUG("hv_dev_pread(NETIO_PARAM_MAC) returned %d\n", ret);
+ if (ret <= 0) {
+ printk(KERN_DEBUG "hv_dev_pread(NETIO_PARAM_MAC) %s failed\n",
+ dev->name);
+ /*
+ * Since the device is configured by the hypervisor but we
+ * can't get its MAC address, we are most likely running
+ * the simulator, so let's generate a random MAC address.
+ */
+ random_ether_addr(dev->dev_addr);
+ }
+
+ return 0;
+}
+
+
+static struct net_device_ops tile_net_ops = {
+ .ndo_open = tile_net_open,
+ .ndo_stop = tile_net_stop,
+ .ndo_start_xmit = tile_net_tx,
+ .ndo_do_ioctl = tile_net_ioctl,
+ .ndo_get_stats = tile_net_get_stats,
+ .ndo_change_mtu = tile_net_change_mtu,
+ .ndo_tx_timeout = tile_net_tx_timeout,
+ .ndo_set_mac_address = tile_net_set_mac_address
+};
+
+
+/*
+ * The setup function.
+ *
+ * This uses ether_setup() to assign various fields in dev, including
+ * setting IFF_BROADCAST and IFF_MULTICAST, then sets some extra fields.
+ */
+static void tile_net_setup(struct net_device *dev)
+{
+ PDEBUG("tile_net_setup()\n");
+
+ ether_setup(dev);
+
+ dev->netdev_ops = &tile_net_ops;
+
+ dev->watchdog_timeo = TILE_NET_TIMEOUT;
+
+ /* We want lockless xmit. */
+ dev->features |= NETIF_F_LLTX;
+
+ /* We support hardware tx checksums. */
+ dev->features |= NETIF_F_HW_CSUM;
+
+ /* We support scatter/gather. */
+ dev->features |= NETIF_F_SG;
+
+ /* We support TSO. */
+ dev->features |= NETIF_F_TSO;
+
+#ifdef TILE_NET_GSO
+ /* We support GSO. */
+ dev->features |= NETIF_F_GSO;
+#endif
+
+ if (hash_default)
+ dev->features |= NETIF_F_HIGHDMA;
+
+ /* ISSUE: We should support NETIF_F_UFO. */
+
+ dev->tx_queue_len = TILE_NET_TX_QUEUE_LEN;
+
+ dev->mtu = TILE_NET_MTU;
+}
+
+
+/*
+ * Allocate the device structure, register the device, and obtain the
+ * MAC address from the hypervisor.
+ */
+static struct net_device *tile_net_dev_init(const char *name)
+{
+ int ret;
+ struct net_device *dev;
+ struct tile_net_priv *priv;
+ struct page *page;
+
+ /*
+ * Allocate the device structure. This allocates "priv", calls
+ * tile_net_setup(), and saves "name". Normally, "name" is a
+ * template, instantiated by register_netdev(), but not for us.
+ */
+ dev = alloc_netdev(sizeof(*priv), name, tile_net_setup);
+ if (!dev) {
+ pr_err("alloc_netdev(%s) failed\n", name);
+ return NULL;
+ }
+
+ priv = netdev_priv(dev);
+
+ /* Initialize "priv". */
+
+ memset(priv, 0, sizeof(*priv));
+
+ /* Save "dev" for "tile_net_open_retry()". */
+ priv->dev = dev;
+
+ INIT_DELAYED_WORK(&priv->retry_work, tile_net_open_retry);
+
+ spin_lock_init(&priv->cmd_lock);
+ spin_lock_init(&priv->comp_lock);
+
+ /* Allocate "epp_queue". */
+ BUG_ON(get_order(sizeof(lepp_queue_t)) != 0);
+ page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
+ if (!page) {
+ free_netdev(dev);
+ return NULL;
+ }
+ priv->epp_queue = page_address(page);
+
+ /* Register the network device. */
+ ret = register_netdev(dev);
+ if (ret) {
+ pr_err("register_netdev %s failed %d\n", dev->name, ret);
+ free_page((unsigned long)priv->epp_queue);
+ free_netdev(dev);
+ return NULL;
+ }
+
+ /* Get the MAC address. */
+ ret = tile_net_get_mac(dev);
+ if (ret < 0) {
+ unregister_netdev(dev);
+ free_page((unsigned long)priv->epp_queue);
+ free_netdev(dev);
+ return NULL;
+ }
+
+ return dev;
+}
+
+
+/*
+ * Module cleanup.
+ */
+static void tile_net_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < TILE_NET_DEVS; i++) {
+ if (tile_net_devs[i]) {
+ struct net_device *dev = tile_net_devs[i];
+ struct tile_net_priv *priv = netdev_priv(dev);
+ unregister_netdev(dev);
+ finv_buffer(priv->epp_queue, PAGE_SIZE);
+ free_page((unsigned long)priv->epp_queue);
+ free_netdev(dev);
+ }
+ }
+}
+
+
+/*
+ * Module initialization.
+ */
+static int tile_net_init_module(void)
+{
+ pr_info("Tilera IPP Net Driver\n");
+
+ tile_net_devs[0] = tile_net_dev_init("xgbe0");
+ tile_net_devs[1] = tile_net_dev_init("xgbe1");
+ tile_net_devs[2] = tile_net_dev_init("gbe0");
+ tile_net_devs[3] = tile_net_dev_init("gbe1");
+
+ return 0;
+}
+
+
+#ifndef MODULE
+/*
+ * The "network_cpus" boot argument specifies the cpus that are dedicated
+ * to handle ingress packets.
+ *
+ * The parameter should be in the form "network_cpus=m-n[,x-y]", where
+ * m, n, x, y are integer numbers that represent the cpus that can be
+ * neither a dedicated cpu nor a dataplane cpu.
+ */
+static int __init network_cpus_setup(char *str)
+{
+ int rc = cpulist_parse_crop(str, &network_cpus_map);
+ if (rc != 0) {
+ pr_warning("network_cpus=%s: malformed cpu list\n",
+ str);
+ } else {
+
+ /* Remove dedicated cpus. */
+ cpumask_and(&network_cpus_map, &network_cpus_map,
+ cpu_possible_mask);
+
+
+ if (cpumask_empty(&network_cpus_map)) {
+ pr_warning("Ignoring network_cpus='%s'.\n",
+ str);
+ } else {
+ char buf[1024];
+ cpulist_scnprintf(buf, sizeof(buf), &network_cpus_map);
+ pr_info("Linux network CPUs: %s\n", buf);
+ network_cpus_used = true;
+ }
+ }
+
+ return 0;
+}
+__setup("network_cpus=", network_cpus_setup);
+#endif
+
+
+module_init(tile_net_init_module);
+module_exit(tile_net_cleanup);
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 05a95586f3c5..055b87ab4f07 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -899,7 +899,8 @@ struct ucc_geth_hardware_statistics {
#define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size
*/
#define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */
-#define UCC_GETH_UTFTT_INIT 512
+#define UCC_GETH_UTFTT_INIT 256 /* 1/2 utfs
+ due to errata */
/* Gigabit Ethernet (1000 Mbps) */
#define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual
FIFO size */
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index b154a94de03e..62e9e8dc8190 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -2994,12 +2994,14 @@ static int hso_probe(struct usb_interface *interface,
case HSO_INTF_BULK:
/* It's a regular bulk interface */
- if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) &&
- !disable_net)
- hso_dev = hso_create_net_device(interface, port_spec);
- else
+ if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
+ if (!disable_net)
+ hso_dev =
+ hso_create_net_device(interface, port_spec);
+ } else {
hso_dev =
hso_create_bulk_serial_device(interface, port_spec);
+ }
if (!hso_dev)
goto exit;
break;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index d81ad8397885..24297b274cd4 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -498,7 +498,6 @@ norbuff:
static int x25_asy_close(struct net_device *dev)
{
struct x25_asy *sl = netdev_priv(dev);
- int err;
spin_lock(&sl->lock);
if (sl->tty)
@@ -507,10 +506,6 @@ static int x25_asy_close(struct net_device *dev)
netif_stop_queue(dev);
sl->rcount = 0;
sl->xleft = 0;
- err = lapb_unregister(dev);
- if (err != LAPB_OK)
- printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
- err);
spin_unlock(&sl->lock);
return 0;
}
@@ -582,7 +577,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
if (err)
return err;
/* Done. We have linked the TTY line to a channel. */
- return sl->dev->base_addr;
+ return 0;
}
@@ -595,6 +590,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
static void x25_asy_close_tty(struct tty_struct *tty)
{
struct x25_asy *sl = tty->disc_data;
+ int err;
/* First make sure we're connected. */
if (!sl || sl->magic != X25_ASY_MAGIC)
@@ -605,6 +601,11 @@ static void x25_asy_close_tty(struct tty_struct *tty)
dev_close(sl->dev);
rtnl_unlock();
+ err = lapb_unregister(sl->dev);
+ if (err != LAPB_OK)
+ printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
+ err);
+
tty->disc_data = NULL;
sl->tty = NULL;
x25_asy_free(sl);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 966b9496a9dd..195406db3bd8 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -37,7 +37,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
int addr, eep_start_loc;
eep_data = (u16 *)eep;
- if (ah->hw_version.devid == 0x7015)
+ if (AR9287_HTC_DEVID(ah))
eep_start_loc = AR9287_HTC_EEP_START_LOC;
else
eep_start_loc = AR9287_EEP_START_LOC;
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index f7ec31b4ddd3..dfb6560dab92 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -36,8 +36,13 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
{ USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */
+ { USB_DEVICE(0x13D3, 0x3348) }, /* Azurewave */
+ { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */
+ { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
{ USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */
+ { USB_DEVICE(0x040D, 0x3801) }, /* VIA */
+ { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */
{ },
};
@@ -806,6 +811,8 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
case 0x7010:
case 0x7015:
case 0x9018:
+ case 0xA704:
+ case 0x1200:
firm_offset = AR7010_FIRMWARE_TEXT;
break;
default:
@@ -928,6 +935,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
case 0x7010:
case 0x7015:
case 0x9018:
+ case 0xA704:
+ case 0x1200:
if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
hif_dev->fw_name = FIRMWARE_AR7010_1_1;
else
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 3d7b97f1b3ae..7c8a38d04561 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -249,6 +249,8 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid)
case 0x7010:
case 0x7015:
case 0x9018:
+ case 0xA704:
+ case 0x1200:
priv->htc->credits = 45;
break;
default:
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 3d19b5bc937f..29d80ca78393 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -121,7 +121,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
tx_hdr.data_type = ATH9K_HTC_NORMAL;
}
- if (ieee80211_is_data(fc)) {
+ if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
}
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 6a0d99eff404..92bc5c5f4876 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -817,8 +817,6 @@ void ath9k_deinit_device(struct ath_softc *sc)
ath9k_ps_wakeup(sc);
- pm_qos_remove_request(&ath9k_pm_qos_req);
-
wiphy_rfkill_stop_polling(sc->hw->wiphy);
ath_deinit_leds(sc);
@@ -832,6 +830,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
}
ieee80211_unregister_hw(hw);
+ pm_qos_remove_request(&ath9k_pm_qos_req);
ath_rx_cleanup(sc);
ath_tx_cleanup(sc);
ath9k_deinit_softc(sc);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c76ea53c20ce..1a62e351ec77 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc)
bool stopped;
spin_lock_bh(&sc->rx.rxbuflock);
- ath9k_hw_stoppcurecv(ah);
+ ath9k_hw_abortpcurecv(ah);
ath9k_hw_setrxfilter(ah, 0);
stopped = ath9k_hw_stopdmarecv(ah);
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index fa05b711e5cd..dddf579aacf1 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -866,7 +866,13 @@
#define AR_DEVID_7010(_ah) \
(((_ah)->hw_version.devid == 0x7010) || \
((_ah)->hw_version.devid == 0x7015) || \
- ((_ah)->hw_version.devid == 0x9018))
+ ((_ah)->hw_version.devid == 0x9018) || \
+ ((_ah)->hw_version.devid == 0xA704) || \
+ ((_ah)->hw_version.devid == 0x1200))
+
+#define AR9287_HTC_DEVID(_ah) \
+ (((_ah)->hw_version.devid == 0x7015) || \
+ ((_ah)->hw_version.devid == 0x1200))
#define AR_RADIO_SREV_MAJOR 0xf0
#define AR_RAD5133_SREV_MAJOR 0xc0
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 980ae70ea424..a314c2c2bfbe 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -647,7 +647,7 @@ init:
}
unlock:
- if (err && (vif_id != -1)) {
+ if (err && (vif_id >= 0)) {
vif_priv->active = false;
bitmap_release_region(&ar->vif_bitmap, vif_id, 0);
ar->vifs--;
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 3317039cd28f..7504ed14c725 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -553,12 +553,12 @@ static int carl9170_usb_flush(struct ar9170 *ar)
usb_free_urb(urb);
}
- ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ);
+ ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, 1000);
if (ret == 0)
err = -ETIMEDOUT;
/* lets wait a while until the tx - queues are dried out */
- ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ);
+ ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, 1000);
if (ret == 0)
err = -ETIMEDOUT;
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c
index 9a55338d957f..09e2dfd7b175 100644
--- a/drivers/net/wireless/b43/sdio.c
+++ b/drivers/net/wireless/b43/sdio.c
@@ -163,6 +163,7 @@ static int b43_sdio_probe(struct sdio_func *func,
err_free_ssb:
kfree(sdio);
err_disable_func:
+ sdio_claim_host(func);
sdio_disable_func(func);
err_release_host:
sdio_release_host(func);
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index a38a7bd25f19..b9aedf18a046 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -57,7 +57,6 @@
#include <linux/fcntl.h>
#include <linux/spinlock.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/timer.h>
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index d9f51485beee..9383063d2b16 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -349,7 +349,6 @@ static struct irq_chip dino_interrupt_type = {
.name = "GSC-PCI",
.unmask = dino_unmask_irq,
.mask = dino_mask_irq,
- .ack = no_ack_irq,
};
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 1211974f55aa..e860038b0b84 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -186,7 +186,6 @@ static struct irq_chip eisa_interrupt_type = {
.name = "EISA",
.unmask = eisa_unmask_irq,
.mask = eisa_mask_irq,
- .ack = no_ack_irq,
};
static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
@@ -340,7 +339,7 @@ static int __init eisa_probe(struct parisc_device *dev)
setup_irq(2, &irq2_action);
for (i = 0; i < 16; i++) {
set_irq_chip_and_handler(i, &eisa_interrupt_type,
- handle_level_irq);
+ handle_simple_irq);
}
EISA_bus = 1;
diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c
index cce00ed81f37..af212c6a6158 100644
--- a/drivers/parisc/eisa_eeprom.c
+++ b/drivers/parisc/eisa_eeprom.c
@@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index e605298e3aee..772b1939ac21 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -143,7 +143,6 @@ static struct irq_chip gsc_asic_interrupt_type = {
.name = "GSC-ASIC",
.unmask = gsc_asic_unmask_irq,
.mask = gsc_asic_mask_irq,
- .ack = no_ack_irq,
};
int gsc_assign_irq(struct irq_chip *type, void *data)
@@ -153,7 +152,7 @@ int gsc_assign_irq(struct irq_chip *type, void *data)
if (irq > GSC_IRQ_MAX)
return NO_IRQ;
- set_irq_chip_and_handler(irq, type, handle_level_irq);
+ set_irq_chip_and_handler(irq, type, handle_simple_irq);
set_irq_chip_data(irq, data);
return irq++;
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index a3120a09c43d..0327894bf235 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -669,6 +669,13 @@ printk("\n");
DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", irq,
vi->eoi_addr, vi->eoi_data);
iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+}
+
+static void iosapic_eoi_irq(unsigned int irq)
+{
+ struct vector_info *vi = get_irq_chip_data(irq);
+
+ iosapic_eoi(vi->eoi_addr, vi->eoi_data);
cpu_eoi_irq(irq);
}
@@ -705,6 +712,7 @@ static struct irq_chip iosapic_interrupt_type = {
.unmask = iosapic_unmask_irq,
.mask = iosapic_mask_irq,
.ack = cpu_ack_irq,
+ .eoi = iosapic_eoi_irq,
#ifdef CONFIG_SMP
.set_affinity = iosapic_set_affinity_irq,
#endif
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 2350e8a86eef..f2f501e5b6a0 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -64,6 +64,7 @@ static unsigned int led_diskio __read_mostly = 1;
static unsigned int led_lanrxtx __read_mostly = 1;
static char lcd_text[32] __read_mostly;
static char lcd_text_default[32] __read_mostly;
+static int lcd_no_led_support __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */
static struct workqueue_struct *led_wq;
@@ -115,7 +116,7 @@ lcd_info __attribute__((aligned(8))) __read_mostly =
.lcd_width = 16,
.lcd_cmd_reg_addr = KITTYHAWK_LCD_CMD,
.lcd_data_reg_addr = KITTYHAWK_LCD_DATA,
- .min_cmd_delay = 40,
+ .min_cmd_delay = 80,
.reset_cmd1 = 0x80,
.reset_cmd2 = 0xc0,
};
@@ -135,6 +136,9 @@ static int start_task(void)
/* Display the default text now */
if (led_type == LED_HASLCD) lcd_print( lcd_text_default );
+ /* KittyHawk has no LED support on its LCD */
+ if (lcd_no_led_support) return 0;
+
/* Create the work queue and queue the LED task */
led_wq = create_singlethread_workqueue("led_wq");
queue_delayed_work(led_wq, &led_task, 0);
@@ -248,9 +252,13 @@ static int __init led_create_procfs(void)
proc_pdc_root = proc_mkdir("pdc", 0);
if (!proc_pdc_root) return -1;
- ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
- &led_proc_fops, (void *)LED_NOLCD); /* LED */
- if (!ent) return -1;
+
+ if (!lcd_no_led_support)
+ {
+ ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
+ &led_proc_fops, (void *)LED_NOLCD); /* LED */
+ if (!ent) return -1;
+ }
if (led_type == LED_HASLCD)
{
@@ -692,6 +700,7 @@ int __init led_init(void)
case 0x58B: /* KittyHawk DC2 100 (K200) */
printk(KERN_INFO "%s: KittyHawk-Machine (hversion 0x%x) found, "
"LED detection skipped.\n", __FILE__, CPU_HVERSION);
+ lcd_no_led_support = 1;
goto found; /* use the preinitialized values of lcd_info */
}
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 0846dafdfff1..28241532c0fd 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -323,7 +323,6 @@ static struct irq_chip superio_interrupt_type = {
.name = SUPERIO,
.unmask = superio_unmask_irq,
.mask = superio_mask_irq,
- .ack = no_ack_irq,
};
#ifdef DEBUG_SUPERIO_INIT
@@ -354,7 +353,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
#endif
for (i = 0; i < 16; i++) {
- set_irq_chip_and_handler(i, &superio_interrupt_type, handle_level_irq);
+ set_irq_chip_and_handler(i, &superio_interrupt_type, handle_simple_irq);
}
/*
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index f01e344cf4bd..98e6fdf34d30 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
obj-$(CONFIG_X86_VISWS) += setup-irq.o
obj-$(CONFIG_MN10300) += setup-bus.o
obj-$(CONFIG_MICROBLAZE) += setup-bus.o
+obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o
#
# ACPI Related PCI FW Functions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 95712a375cd5..63d5042f2079 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -715,7 +715,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
start = vma->vm_pgoff;
size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
- pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
+ pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
if (start >= pci_start && start < pci_start + size &&
start + nr <= pci_start + size)
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index ea00647f4732..27911b55c2a5 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/capability.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index f5c63fe9db5c..6f9350cabbd5 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2136,6 +2136,24 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
quirk_unhide_mch_dev6);
+#ifdef CONFIG_TILE
+/*
+ * The Tilera TILEmpower platform needs to set the link speed
+ * to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed
+ * setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe
+ * capability register of the PEX8624 PCIe switch. The switch
+ * supports link speed auto negotiation, but falsely sets
+ * the link speed to 5GT/s.
+ */
+static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev)
+{
+ if (tile_plx_gen1) {
+ pci_write_config_dword(dev, 0x98, 0x1);
+ mdelay(50);
+ }
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
+#endif /* CONFIG_TILE */
#ifdef CONFIG_PCI_MSI
/* Some chipsets do not support MSI. We cannot easily rely on setting
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 3753fd0722e7..2fe8cb8e95cd 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -70,6 +70,7 @@ void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
va_end(args);
}
}
+EXPORT_SYMBOL(soc_pcmcia_debug);
#endif
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c
index e73ebefdf3e0..315b3112aca8 100644
--- a/drivers/pnp/isapnp/proc.c
+++ b/drivers/pnp/isapnp/proc.c
@@ -21,7 +21,6 @@
#include <linux/isapnp.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
extern struct pnp_protocol isapnp_protocol;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f1d10c974cd4..ba521f0f0fac 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -911,7 +911,7 @@ out:
}
/**
- * set_consumer_device_supply: Bind a regulator to a symbolic supply
+ * set_consumer_device_supply - Bind a regulator to a symbolic supply
* @rdev: regulator source
* @consumer_dev: device the supply applies to
* @consumer_dev_name: dev_name() string for device supply applies to
@@ -1052,7 +1052,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
printk(KERN_WARNING
"%s: could not add device link %s err %d\n",
__func__, dev->kobj.name, err);
- device_remove_file(dev, &regulator->dev_attr);
goto link_name_err;
}
}
@@ -1268,13 +1267,17 @@ static int _regulator_enable(struct regulator_dev *rdev)
{
int ret, delay;
- /* do we need to enable the supply regulator first */
- if (rdev->supply) {
- ret = _regulator_enable(rdev->supply);
- if (ret < 0) {
- printk(KERN_ERR "%s: failed to enable %s: %d\n",
- __func__, rdev_get_name(rdev), ret);
- return ret;
+ if (rdev->use_count == 0) {
+ /* do we need to enable the supply regulator first */
+ if (rdev->supply) {
+ mutex_lock(&rdev->supply->mutex);
+ ret = _regulator_enable(rdev->supply);
+ mutex_unlock(&rdev->supply->mutex);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: failed to enable %s: %d\n",
+ __func__, rdev_get_name(rdev), ret);
+ return ret;
+ }
}
}
@@ -1313,10 +1316,12 @@ static int _regulator_enable(struct regulator_dev *rdev)
if (ret < 0)
return ret;
- if (delay >= 1000)
+ if (delay >= 1000) {
mdelay(delay / 1000);
- else if (delay)
+ udelay(delay % 1000);
+ } else if (delay) {
udelay(delay);
+ }
} else if (ret < 0) {
printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n",
@@ -1359,6 +1364,7 @@ static int _regulator_disable(struct regulator_dev *rdev,
struct regulator_dev **supply_rdev_ptr)
{
int ret = 0;
+ *supply_rdev_ptr = NULL;
if (WARN(rdev->use_count <= 0,
"unbalanced disables for %s\n",
@@ -2346,6 +2352,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
if (init_data->supply_regulator && init_data->supply_regulator_dev) {
dev_err(dev,
"Supply regulator specified by both name and dev\n");
+ ret = -EINVAL;
goto scrub;
}
@@ -2364,6 +2371,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
if (!found) {
dev_err(dev, "Failed to find supply %s\n",
init_data->supply_regulator);
+ ret = -ENODEV;
goto scrub;
}
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index 4597d508a229..ecd99f59dba8 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -465,8 +465,8 @@ static struct regulator_ops mc13783_fixed_regulator_ops = {
.get_voltage = mc13783_fixed_regulator_get_voltage,
};
-int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
- u32 val)
+static int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
+ u32 val)
{
struct mc13783 *mc13783 = priv->mc13783;
int ret;
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 7e5892efc437..a57262a4fa6c 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -219,12 +219,12 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
return -EACCES;
status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
- message >> 8, 0x15 /* PB_WORD_MSB */ );
- if (status >= 0)
+ message >> 8, TWL4030_PM_MASTER_PB_WORD_MSB);
+ if (status < 0)
return status;
return twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
- message, 0x16 /* PB_WORD_LSB */ );
+ message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB);
}
/*----------------------------------------------------------------------*/
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index c71d89dba302..83b4615a3b62 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -17,7 +17,6 @@
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/mutex.h>
-#include <linux/smp_lock.h>
#include <linux/err.h>
#include <linux/slab.h>
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index eb28fb01a38a..f6489eb7e976 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -14,7 +14,6 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <asm/compat.h>
#include <asm/ccwdev.h>
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 883e2db02bd3..e090a307fdee 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -17,7 +17,6 @@
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/mtio.h>
-#include <linux/smp_lock.h>
#include <linux/compat.h>
#include <asm/uaccess.h>
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 6c408670e08d..b3a3e8e8656e 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -209,29 +209,79 @@ tape_state_set(struct tape_device *device, enum tape_state newstate)
wake_up(&device->state_change_wq);
}
+struct tape_med_state_work_data {
+ struct tape_device *device;
+ enum tape_medium_state state;
+ struct work_struct work;
+};
+
+static void
+tape_med_state_work_handler(struct work_struct *work)
+{
+ static char env_state_loaded[] = "MEDIUM_STATE=LOADED";
+ static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED";
+ struct tape_med_state_work_data *p =
+ container_of(work, struct tape_med_state_work_data, work);
+ struct tape_device *device = p->device;
+ char *envp[] = { NULL, NULL };
+
+ switch (p->state) {
+ case MS_UNLOADED:
+ pr_info("%s: The tape cartridge has been successfully "
+ "unloaded\n", dev_name(&device->cdev->dev));
+ envp[0] = env_state_unloaded;
+ kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
+ break;
+ case MS_LOADED:
+ pr_info("%s: A tape cartridge has been mounted\n",
+ dev_name(&device->cdev->dev));
+ envp[0] = env_state_loaded;
+ kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
+ break;
+ default:
+ break;
+ }
+ tape_put_device(device);
+ kfree(p);
+}
+
+static void
+tape_med_state_work(struct tape_device *device, enum tape_medium_state state)
+{
+ struct tape_med_state_work_data *p;
+
+ p = kzalloc(sizeof(*p), GFP_ATOMIC);
+ if (p) {
+ INIT_WORK(&p->work, tape_med_state_work_handler);
+ p->device = tape_get_device(device);
+ p->state = state;
+ schedule_work(&p->work);
+ }
+}
+
void
tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
{
- if (device->medium_state == newstate)
+ enum tape_medium_state oldstate;
+
+ oldstate = device->medium_state;
+ if (oldstate == newstate)
return;
+ device->medium_state = newstate;
switch(newstate){
case MS_UNLOADED:
device->tape_generic_status |= GMT_DR_OPEN(~0);
- if (device->medium_state == MS_LOADED)
- pr_info("%s: The tape cartridge has been successfully "
- "unloaded\n", dev_name(&device->cdev->dev));
+ if (oldstate == MS_LOADED)
+ tape_med_state_work(device, MS_UNLOADED);
break;
case MS_LOADED:
device->tape_generic_status &= ~GMT_DR_OPEN(~0);
- if (device->medium_state == MS_UNLOADED)
- pr_info("%s: A tape cartridge has been mounted\n",
- dev_name(&device->cdev->dev));
+ if (oldstate == MS_UNLOADED)
+ tape_med_state_work(device, MS_LOADED);
break;
default:
- // print nothing
break;
}
- device->medium_state = newstate;
wake_up(&device->state_change_wq);
}
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 9f661426e4a1..c837d7419a6a 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -30,7 +30,6 @@
#include <linux/kmod.h>
#include <linux/cdev.h>
#include <linux/device.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
MODULE_AUTHOR
@@ -249,27 +248,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
char cp_command[80];
char cp_response[160];
char *onoff, *qid_string;
+ int rc;
- memset(cp_command, 0x00, sizeof(cp_command));
- memset(cp_response, 0x00, sizeof(cp_response));
-
- onoff = ((action == 1) ? "ON" : "OFF");
+ onoff = ((action == 1) ? "ON" : "OFF");
qid_string = ((recording_class_AB == 1) ? " QID * " : "");
- /*
+ /*
* The recording commands needs to be called with option QID
* for guests that have previlege classes A or B.
* Purging has to be done as separate step, because recording
* can't be switched on as long as records are on the queue.
* Doing both at the same time doesn't work.
*/
-
- if (purge) {
+ if (purge && (action == 1)) {
+ memset(cp_command, 0x00, sizeof(cp_command));
+ memset(cp_response, 0x00, sizeof(cp_response));
snprintf(cp_command, sizeof(cp_command),
"RECORDING %s PURGE %s",
logptr->recording_name,
qid_string);
-
cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
}
@@ -279,19 +276,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
logptr->recording_name,
onoff,
qid_string);
-
cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
/* The recording command will usually answer with 'Command complete'
* on success, but when the specific service was never connected
* before then there might be an additional informational message
* 'HCPCRC8072I Recording entry not found' before the
- * 'Command complete'. So I use strstr rather then the strncmp.
+ * 'Command complete'. So I use strstr rather then the strncmp.
*/
if (strstr(cp_response,"Command complete"))
- return 0;
+ rc = 0;
else
- return -EIO;
+ rc = -EIO;
+ /*
+ * If we turn recording off, we have to purge any remaining records
+ * afterwards, as a large number of queued records may impact z/VM
+ * performance.
+ */
+ if (purge && (action == 0)) {
+ memset(cp_command, 0x00, sizeof(cp_command));
+ memset(cp_response, 0x00, sizeof(cp_response));
+ snprintf(cp_command, sizeof(cp_command),
+ "RECORDING %s PURGE %s",
+ logptr->recording_name,
+ qid_string);
+ cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
+ }
+ return rc;
}
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 1de672f21037..f7e4ae6bf15a 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -13,7 +13,6 @@
#include <linux/cdev.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/cio.h>
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 2ff8a22d4257..e8391b89eff4 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1455,7 +1455,16 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
break;
case IO_SCH_UNREG_ATTACH:
case IO_SCH_UNREG:
- if (cdev)
+ if (!cdev)
+ break;
+ if (cdev->private->state == DEV_STATE_SENSE_ID) {
+ /*
+ * Note: delayed work triggered by this event
+ * and repeated calls to sch_event are synchronized
+ * by the above check for work_pending(cdev).
+ */
+ dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
+ } else
ccw_device_set_notoper(cdev);
break;
case IO_SCH_NOP:
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 752dbee06af5..5d9c66627b6e 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -292,8 +292,8 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
return;
/* reset adapter interrupt indicators */
- put_indicator(irq_ptr->dsci);
set_subchannel_ind(irq_ptr, 1);
+ put_indicator(irq_ptr->dsci);
}
void __exit tiqdio_unregister_thinints(void)
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index f5221749d180..7fca9c10ffcf 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -35,7 +35,6 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/compat.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 50286d8707f3..6bd2dbc4c316 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -76,7 +76,7 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
scpnt->scsi_done(scpnt);
}
-static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
+static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
void (*done) (struct scsi_cmnd *))
{
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
@@ -127,6 +127,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
return ret;
}
+static DEF_SCSI_QCMD(zfcp_scsi_queuecommand)
+
static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
{
struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fcf08b3f52c1..b7bd5b0cc7aa 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1765,7 +1765,7 @@ out:
} /* End twa_scsi_eh_reset() */
/* This is the main scsi queue function to handle scsi opcodes */
-static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
int request_id, retval;
TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
@@ -1812,6 +1812,8 @@ out:
return retval;
} /* End twa_scsi_queue() */
+static DEF_SCSI_QCMD(twa_scsi_queue)
+
/* This function hands scsi cdb's to the firmware */
static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg)
{
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index 6a95d111d207..13e39e1fdfe2 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -1501,7 +1501,7 @@ out:
} /* End twl_scsi_eh_reset() */
/* This is the main scsi queue function to handle scsi opcodes */
-static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
int request_id, retval;
TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
@@ -1536,6 +1536,8 @@ out:
return retval;
} /* End twl_scsi_queue() */
+static DEF_SCSI_QCMD(twl_scsi_queue)
+
/* This function tells the controller to shut down */
static void __twl_shutdown(TW_Device_Extension *tw_dev)
{
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index b1125341f4c8..7fe96ff60c58 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1947,7 +1947,7 @@ static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int r
} /* End tw_scsiop_test_unit_ready_complete() */
/* This is the main scsi queue function to handle scsi opcodes */
-static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
unsigned char *command = SCpnt->cmnd;
int request_id = 0;
@@ -2023,6 +2023,8 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
return retval;
} /* End tw_scsi_queue() */
+static DEF_SCSI_QCMD(tw_scsi_queue)
+
/* This function is the interrupt service routine */
static irqreturn_t tw_interrupt(int irq, void *dev_instance)
{
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 89fc1c8af86b..f672491774eb 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -167,7 +167,7 @@ MODULE_LICENSE("GPL");
#include "53c700_d.h"
-STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+STATIC int NCR_700_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *);
STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
@@ -1749,8 +1749,8 @@ NCR_700_intr(int irq, void *dev_id)
return IRQ_RETVAL(handled);
}
-STATIC int
-NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
+static int
+NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
{
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
@@ -1904,6 +1904,8 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
return 0;
}
+STATIC DEF_SCSI_QCMD(NCR_700_queuecommand)
+
STATIC int
NCR_700_abort(struct scsi_cmnd * SCp)
{
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index fc0b4b81d552..f66c33b9ab41 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -2807,7 +2807,7 @@ static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
Outgoing Mailbox for execution by the associated Host Adapter.
*/
-static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
+static int BusLogic_QueueCommand_lck(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
{
struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
@@ -2994,6 +2994,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
return 0;
}
+static DEF_SCSI_QCMD(BusLogic_QueueCommand)
#if 0
/*
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
index 73f237a1ed94..649fcb31f26d 100644
--- a/drivers/scsi/BusLogic.h
+++ b/drivers/scsi/BusLogic.h
@@ -1319,7 +1319,7 @@ static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T Co
*/
static const char *BusLogic_DriverInfo(struct Scsi_Host *);
-static int BusLogic_QueueCommand(struct scsi_cmnd *, void (*CompletionRoutine) (struct scsi_cmnd *));
+static int BusLogic_QueueCommand(struct Scsi_Host *h, struct scsi_cmnd *);
static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device *, sector_t, int *);
static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int);
static int BusLogic_SlaveConfigure(struct scsi_device *);
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 5d2f148889ad..9a5629f94f95 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -952,7 +952,7 @@ static void NCR5380_exit(struct Scsi_Host *instance)
* Locks: host lock taken by caller
*/
-static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -1021,6 +1021,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(NCR5380_queue_command)
/**
* NCR5380_main - NCR state machines
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index bdc468c9e1d9..fd40a32b1f6f 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -313,7 +313,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
#endif
static int NCR5380_abort(Scsi_Cmnd * cmd);
static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
-static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
+static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
char *buffer, char **start, off_t offset, int length, int inout);
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 6961f78742ae..c91888a0a23c 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -693,7 +693,7 @@ static void wait_intr(void)
}
#endif
-static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int NCR53c406a_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
{
int i;
@@ -726,6 +726,8 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(NCR53c406a_queue)
+
static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
{
DEB(printk("NCR53c406a_reset called\n"));
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index dbbc601948e5..dc5ac6e528c4 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -911,7 +911,7 @@ static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struc
* queue the command down to the controller
*/
-static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
+static int inia100_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
{
struct orc_scb *scb;
struct orc_host *host; /* Point to Host adapter control block */
@@ -930,6 +930,8 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
return 0;
}
+static DEF_SCSI_QCMD(inia100_queue)
+
/*****************************************************************************
Function name : inia100_abort
Description : Abort a queued command.
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 29c0ed1cf507..2c93d9496d62 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -248,7 +248,7 @@ static struct aac_driver_ident aac_drivers[] = {
* TODO: unify with aac_scsi_cmd().
*/
-static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct Scsi_Host *host = cmd->device->host;
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
@@ -267,6 +267,8 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
return (aac_scsi_cmd(cmd) ? FAILED : 0);
}
+static DEF_SCSI_QCMD(aac_queuecommand)
+
/**
* aac_info - Returns the host adapter name
* @shost: Scsi host to report on
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 0ec3da6f3e12..081c6de92bc5 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -9500,7 +9500,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
* in the 'scp' result field.
*/
static int
-advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
+advansys_queuecommand_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
{
struct Scsi_Host *shost = scp->device->host;
int asc_res, result = 0;
@@ -9525,6 +9525,8 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
return result;
}
+static DEF_SCSI_QCMD(advansys_queuecommand)
+
static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
{
PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 8eab8587ff21..c5169f01c1cd 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1056,7 +1056,7 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
* queue a command
*
*/
-static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int aha152x_queue_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
#if 0
if(*SCpnt->cmnd == REQUEST_SENSE) {
@@ -1070,6 +1070,8 @@ static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
return aha152x_internal_queue(SCpnt, NULL, 0, done);
}
+static DEF_SCSI_QCMD(aha152x_queue)
+
/*
*
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 4f785f254c1f..195823a51aab 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -558,7 +558,7 @@ static void aha1542_intr_handle(struct Scsi_Host *shost)
};
}
-static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int aha1542_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
{
unchar ahacmd = CMD_START_SCSI;
unchar direction;
@@ -718,6 +718,8 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(aha1542_queuecommand)
+
/* Initialize mailboxes */
static void setup_mailboxes(int bse, struct Scsi_Host *shpnt)
{
diff --git a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h
index 1db538552d56..b871d2b57f93 100644
--- a/drivers/scsi/aha1542.h
+++ b/drivers/scsi/aha1542.h
@@ -132,7 +132,7 @@ struct ccb { /* Command Control Block 5.3 */
};
static int aha1542_detect(struct scsi_host_template *);
-static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int aha1542_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
static int aha1542_bus_reset(Scsi_Cmnd * SCpnt);
static int aha1542_dev_reset(Scsi_Cmnd * SCpnt);
static int aha1542_host_reset(Scsi_Cmnd * SCpnt);
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index 0107a4cc3331..d058f1ab82b5 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -331,7 +331,7 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
return IRQ_RETVAL(handled);
}
-static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
+static int aha1740_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
unchar direction;
unchar *cmd = (unchar *) SCpnt->cmnd;
@@ -503,6 +503,8 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(aha1740_queuecommand)
+
/* Query the board for its irq_level and irq_type. Nothing else matters
in enhanced mode on an EISA bus. */
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 88ad8482ef59..25d066624476 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -573,7 +573,7 @@ ahd_linux_info(struct Scsi_Host *host)
* Queue an SCB to the controller.
*/
static int
-ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
+ahd_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
{
struct ahd_softc *ahd;
struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
@@ -588,6 +588,8 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
return rtn;
}
+static DEF_SCSI_QCMD(ahd_linux_queue)
+
static struct scsi_target **
ahd_linux_target_in_softc(struct scsi_target *starget)
{
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index aeea7a61478e..4a359bb307c6 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -528,7 +528,7 @@ ahc_linux_info(struct Scsi_Host *host)
* Queue an SCB to the controller.
*/
static int
-ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
+ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
{
struct ahc_softc *ahc;
struct ahc_linux_device *dev = scsi_transport_device_data(cmd->device);
@@ -548,6 +548,8 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
return rtn;
}
+static DEF_SCSI_QCMD(ahc_linux_queue)
+
static inline struct scsi_target **
ahc_linux_target_in_softc(struct scsi_target *starget)
{
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index aee73fafccc8..4ff60a08df0f 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -10234,7 +10234,7 @@ static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
* Description:
* Queue a SCB to the controller.
*-F*************************************************************************/
-static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
+static int aic7xxx_queue_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
{
struct aic7xxx_host *p;
struct aic7xxx_scb *scb;
@@ -10292,6 +10292,8 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
return (0);
}
+static DEF_SCSI_QCMD(aic7xxx_queue)
+
/*+F*************************************************************************
* Function:
* aic7xxx_bus_device_reset
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 05a78e515a24..17e3df4f016f 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -85,8 +85,7 @@ static int arcmsr_abort(struct scsi_cmnd *);
static int arcmsr_bus_reset(struct scsi_cmnd *);
static int arcmsr_bios_param(struct scsi_device *sdev,
struct block_device *bdev, sector_t capacity, int *info);
-static int arcmsr_queue_command(struct scsi_cmnd *cmd,
- void (*done) (struct scsi_cmnd *));
+static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static int arcmsr_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
static void arcmsr_remove(struct pci_dev *pdev);
@@ -2081,7 +2080,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
}
}
-static int arcmsr_queue_command(struct scsi_cmnd *cmd,
+static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
void (* done)(struct scsi_cmnd *))
{
struct Scsi_Host *host = cmd->device->host;
@@ -2124,6 +2123,8 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(arcmsr_queue_command)
+
static bool arcmsr_get_hba_config(struct AdapterControlBlock *acb)
{
struct MessageUnit_A __iomem *reg = acb->pmuA;
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index 918ccf818757..ec166726b314 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -2511,7 +2511,7 @@ acornscsi_intr(int irq, void *dev_id)
* done - function called on completion, with pointer to command descriptor
* Returns : 0, or < 0 on error.
*/
-int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
+static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{
AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
@@ -2561,6 +2561,8 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
return 0;
}
+DEF_SCSI_QCMD(acornscsi_queuecmd)
+
/*
* Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
* Purpose : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 9e71ac611146..2b2ce21e227e 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2198,7 +2198,7 @@ no_command:
* Returns: 0 on success, else error.
* Notes: io_request_lock is held, interrupts are disabled.
*/
-int fas216_queue_command(struct scsi_cmnd *SCpnt,
+static int fas216_queue_command_lck(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{
FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
@@ -2240,6 +2240,8 @@ int fas216_queue_command(struct scsi_cmnd *SCpnt,
return result;
}
+DEF_SCSI_QCMD(fas216_queue_command)
+
/**
* fas216_internal_done - trigger restart of a waiting thread in fas216_noqueue_command
* @SCpnt: Command to wake
@@ -2263,7 +2265,7 @@ static void fas216_internal_done(struct scsi_cmnd *SCpnt)
* Returns: scsi result code.
* Notes: io_request_lock is held, interrupts are disabled.
*/
-int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
+static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{
FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
@@ -2277,7 +2279,7 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
BUG_ON(info->scsi.irq != NO_IRQ);
info->internal_done = 0;
- fas216_queue_command(SCpnt, fas216_internal_done);
+ fas216_queue_command_lck(SCpnt, fas216_internal_done);
/*
* This wastes time, since we can't return until the command is
@@ -2310,6 +2312,8 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
return 0;
}
+DEF_SCSI_QCMD(fas216_noqueue_command)
+
/*
* Error handler timeout function. Indicate that we timed out,
* and wake up any error handler process so it can continue.
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
index b65f4cf0eec9..f30f8d659dc4 100644
--- a/drivers/scsi/arm/fas216.h
+++ b/drivers/scsi/arm/fas216.h
@@ -331,23 +331,21 @@ extern int fas216_init (struct Scsi_Host *instance);
*/
extern int fas216_add (struct Scsi_Host *instance, struct device *dev);
-/* Function: int fas216_queue_command(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+/* Function: int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt)
* Purpose : queue a command for adapter to process.
- * Params : SCpnt - Command to queue
- * done - done function to call once command is complete
+ * Params : h - host adapter
+ * : SCpnt - Command to queue
* Returns : 0 - success, else error
*/
-extern int fas216_queue_command(struct scsi_cmnd *,
- void (*done)(struct scsi_cmnd *));
+extern int fas216_queue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt);
-/* Function: int fas216_noqueue_command(istruct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+/* Function: int fas216_noqueue_command(struct Scsi_Host *h, struct scsi_cmnd *SCpnt)
* Purpose : queue a command for adapter to process, and process it to completion.
- * Params : SCpnt - Command to queue
- * done - done function to call once command is complete
+ * Params : h - host adapter
+ * : SCpnt - Command to queue
* Returns : 0 - success, else error
*/
-extern int fas216_noqueue_command(struct scsi_cmnd *,
- void (*done)(struct scsi_cmnd *));
+extern int fas216_noqueue_command(struct Scsi_Host *, struct scsi_cmnd *);
/* Function: irqreturn_t fas216_intr (FAS216_Info *info)
* Purpose : handle interrupts from the interface to progress a command
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 158ebc3644d8..88b2928b4d3b 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -910,7 +910,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
*
*/
-static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int NCR5380_queue_command_lck(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
{
SETUP_HOSTDATA(cmd->device->host);
Scsi_Cmnd *tmp;
@@ -1022,6 +1022,8 @@ static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(NCR5380_queue_command)
+
/*
* Function : NCR5380_main (void)
*
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index ad7a23aef0ec..3e8658e2f154 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -572,23 +572,6 @@ static void falcon_get_lock(void)
}
-/* This is the wrapper function for NCR5380_queue_command(). It just
- * tries to get the lock on the ST-DMA (see above) and then calls the
- * original function.
- */
-
-#if 0
-int atari_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
-{
- /* falcon_get_lock();
- * ++guenther: moved to NCR5380_queue_command() to prevent
- * race condition, see there for an explanation.
- */
- return NCR5380_queue_command(cmd, done);
-}
-#endif
-
-
int __init atari_scsi_detect(struct scsi_host_template *host)
{
static int called = 0;
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index ab5bdda6903e..76029d570beb 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -605,7 +605,7 @@ handled:
*
* Queue a command to the ATP queue. Called with the host lock held.
*/
-static int atp870u_queuecommand(struct scsi_cmnd * req_p,
+static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
void (*done) (struct scsi_cmnd *))
{
unsigned char c;
@@ -694,6 +694,8 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
return 0;
}
+static DEF_SCSI_QCMD(atp870u_queuecommand)
+
/**
* send_s870 - send a command to the controller
* @host: host
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 8daa716739d1..8ca967dee66d 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -30,8 +30,7 @@ DEFINE_IDR(bfad_im_port_index);
struct scsi_transport_template *bfad_im_scsi_transport_template;
struct scsi_transport_template *bfad_im_scsi_vport_transport_template;
static void bfad_im_itnim_work_handler(struct work_struct *work);
-static int bfad_im_queuecommand(struct scsi_cmnd *cmnd,
- void (*done)(struct scsi_cmnd *));
+static int bfad_im_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmnd);
static int bfad_im_slave_alloc(struct scsi_device *sdev);
static void bfad_im_fc_rport_add(struct bfad_im_port_s *im_port,
struct bfad_itnim_s *itnim);
@@ -1120,7 +1119,7 @@ bfad_im_itnim_work_handler(struct work_struct *work)
* Scsi_Host template entry, queue a SCSI command to the BFAD.
*/
static int
-bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+bfad_im_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
{
struct bfad_im_port_s *im_port =
(struct bfad_im_port_s *) cmnd->device->host->hostdata[0];
@@ -1187,6 +1186,8 @@ out_fail_cmd:
return 0;
}
+static DEF_SCSI_QCMD(bfad_im_queuecommand)
+
void
bfad_os_rport_online_wait(struct bfad_s *bfad)
{
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 54f50b07dac7..8f1b5c8bf903 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1080,7 +1080,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
* and is expected to be held on return.
*
**/
-static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct DeviceCtlBlk *dcb;
struct ScsiReqBlk *srb;
@@ -1154,6 +1154,7 @@ complete:
return 0;
}
+static DEF_SCSI_QCMD(dc395x_queue_command)
/*
* Return the disk geometry for the given SCSI device.
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 23dec0063385..cffcb108ac96 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -423,7 +423,7 @@ static int adpt_slave_configure(struct scsi_device * device)
return 0;
}
-static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
+static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
{
adpt_hba* pHba = NULL;
struct adpt_device* pDev = NULL; /* dpt per device information */
@@ -491,6 +491,8 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
return adpt_scsi_to_i2o(pHba, cmd, pDev);
}
+static DEF_SCSI_QCMD(adpt_queue)
+
static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
sector_t capacity, int geom[])
{
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 337746d46043..beded716f93f 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -29,7 +29,7 @@
*/
static int adpt_detect(struct scsi_host_template * sht);
-static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *));
+static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd);
static int adpt_abort(struct scsi_cmnd * cmd);
static int adpt_reset(struct scsi_cmnd* cmd);
static int adpt_release(struct Scsi_Host *host);
diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h
index 0b205f8c7326..cdc621204b66 100644
--- a/drivers/scsi/dtc.h
+++ b/drivers/scsi/dtc.h
@@ -36,7 +36,7 @@ static int dtc_abort(Scsi_Cmnd *);
static int dtc_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
static int dtc_detect(struct scsi_host_template *);
-static int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int dtc_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int dtc_bus_reset(Scsi_Cmnd *);
#ifndef CMD_PER_LUN
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index d1c31378f6da..53925ac178fd 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -505,8 +505,7 @@
static int eata2x_detect(struct scsi_host_template *);
static int eata2x_release(struct Scsi_Host *);
-static int eata2x_queuecommand(struct scsi_cmnd *,
- void (*done) (struct scsi_cmnd *));
+static int eata2x_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
static int eata2x_eh_abort(struct scsi_cmnd *);
static int eata2x_eh_host_reset(struct scsi_cmnd *);
static int eata2x_bios_param(struct scsi_device *, struct block_device *,
@@ -1758,7 +1757,7 @@ static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha)
}
-static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
+static int eata2x_queuecommand_lck(struct scsi_cmnd *SCpnt,
void (*done) (struct scsi_cmnd *))
{
struct Scsi_Host *shost = SCpnt->device->host;
@@ -1843,6 +1842,8 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
return 0;
}
+static DEF_SCSI_QCMD(eata2x_queuecommand)
+
static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
{
struct Scsi_Host *shost = SCarg->device->host;
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 60886c19065e..4a9641e69f54 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -335,7 +335,7 @@ static inline unsigned int eata_pio_send_command(unsigned long base, unsigned ch
return 0;
}
-static int eata_pio_queue(struct scsi_cmnd *cmd,
+static int eata_pio_queue_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
unsigned int x, y;
@@ -438,6 +438,8 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(eata_pio_queue)
+
static int eata_pio_abort(struct scsi_cmnd *cmd)
{
unsigned int loop = 100;
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index e2bc779f86c1..57558523c1b8 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -916,7 +916,7 @@ static void esp_event_queue_full(struct esp *esp, struct esp_cmd_entry *ent)
scsi_track_queue_full(dev, lp->num_tagged - 1);
}
-static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int esp_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct scsi_device *dev = cmd->device;
struct esp *esp = shost_priv(dev->host);
@@ -941,6 +941,8 @@ static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
return 0;
}
+static DEF_SCSI_QCMD(esp_queuecommand)
+
static int esp_check_gross_error(struct esp *esp)
{
if (esp->sreg & ESP_STAT_SPAM) {
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index 2ad95aa8f585..a2c6135d337e 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -1072,7 +1072,7 @@ static int fd_mcs_release(struct Scsi_Host *shpnt)
return 0;
}
-static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int fd_mcs_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
{
struct Scsi_Host *shpnt = SCpnt->device->host;
@@ -1122,6 +1122,8 @@ static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(fd_mcs_queue)
+
#if DEBUG_ABORT || DEBUG_RESET
static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
{
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index e296bcc57d5c..69b7aa54f43f 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1419,7 +1419,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
+static int fdomain_16x0_queue_lck(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{
if (in_command) {
@@ -1469,6 +1469,8 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
return 0;
}
+static DEF_SCSI_QCMD(fdomain_16x0_queue)
+
#if DEBUG_ABORT
static void print_info(struct scsi_cmnd *SCpnt)
{
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index cbb20b13b228..92f185081e62 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -246,7 +246,7 @@ void fnic_set_port_id(struct fc_lport *, u32, struct fc_frame *);
void fnic_update_mac(struct fc_lport *, u8 *new);
void fnic_update_mac_locked(struct fnic *, u8 *new);
-int fnic_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+int fnic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
int fnic_abort_cmd(struct scsi_cmnd *);
int fnic_device_reset(struct scsi_cmnd *);
int fnic_host_reset(struct scsi_cmnd *);
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 198cbab3e894..22d02404d15f 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -349,7 +349,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic,
* Routine to send a scsi cdb
* Called with host_lock held and interrupts disabled.
*/
-int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
{
struct fc_lport *lp;
struct fc_rport *rport;
@@ -457,6 +457,8 @@ out:
return ret;
}
+DEF_SCSI_QCMD(fnic_queuecommand)
+
/*
* fnic_fcpio_fw_reset_cmpl_handler
* Routine to handle fw reset completion
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
index 921764c9ab24..1bcdb7beb77b 100644
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -46,7 +46,7 @@
static int generic_NCR5380_abort(Scsi_Cmnd *);
static int generic_NCR5380_detect(struct scsi_host_template *);
static int generic_NCR5380_release_resources(struct Scsi_Host *);
-static int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int generic_NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int generic_NCR5380_bus_reset(Scsi_Cmnd *);
static const char* generic_NCR5380_info(struct Scsi_Host *);
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 841101846b88..76365700e2d5 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -185,7 +185,7 @@ static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg);
static void gdth_flush(gdth_ha_str *ha);
-static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
+static int gdth_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
struct gdth_cmndinfo *cmndinfo);
static void gdth_scsi_done(struct scsi_cmnd *scp);
@@ -4004,7 +4004,7 @@ static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,se
}
-static int gdth_queuecommand(struct scsi_cmnd *scp,
+static int gdth_queuecommand_lck(struct scsi_cmnd *scp,
void (*done)(struct scsi_cmnd *))
{
gdth_ha_str *ha = shost_priv(scp->device->host);
@@ -4022,6 +4022,8 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
return __gdth_queuecommand(ha, scp, cmndinfo);
}
+static DEF_SCSI_QCMD(gdth_queuecommand)
+
static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
struct gdth_cmndinfo *cmndinfo)
{
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index c5d0606ad097..b2fb2b2a6e70 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -31,7 +31,6 @@
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/compat.h>
#include <linux/blktrace_api.h>
#include <linux/uaccess.h>
@@ -143,8 +142,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
void *buff, size_t size, u8 page_code, unsigned char *scsi3addr,
int cmd_type);
-static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *));
+static int hpsa_scsi_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static void hpsa_scan_start(struct Scsi_Host *);
static int hpsa_scan_finished(struct Scsi_Host *sh,
unsigned long elapsed_time);
@@ -1926,7 +1924,7 @@ sglist_finished:
}
-static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
+static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct ctlr_info *h;
@@ -2020,6 +2018,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(hpsa_scsi_queue_command)
+
static void hpsa_scan_start(struct Scsi_Host *sh)
{
struct ctlr_info *h = shost_to_hba(sh);
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 0729f150b33a..10b65556937b 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -751,7 +751,7 @@ static void hptiop_post_req_mv(struct hptiop_hba *hba,
MVIOP_MU_QUEUE_ADDR_HOST_BIT | size_bit, hba);
}
-static int hptiop_queuecommand(struct scsi_cmnd *scp,
+static int hptiop_queuecommand_lck(struct scsi_cmnd *scp,
void (*done)(struct scsi_cmnd *))
{
struct Scsi_Host *host = scp->device->host;
@@ -819,6 +819,8 @@ cmd_done:
return 0;
}
+static DEF_SCSI_QCMD(hptiop_queuecommand)
+
static const char *hptiop_info(struct Scsi_Host *host)
{
return driver_name_long;
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 9a4b69d4f4eb..67fc8ffd52e6 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -39,7 +39,7 @@
#include <scsi/scsi_host.h>
/* Common forward declarations for all Linux-versions: */
-static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+static int ibmmca_queuecommand (struct Scsi_Host *, struct scsi_cmnd *);
static int ibmmca_abort (Scsi_Cmnd *);
static int ibmmca_host_reset (Scsi_Cmnd *);
static int ibmmca_biosparam (struct scsi_device *, struct block_device *, sector_t, int *);
@@ -1691,7 +1691,7 @@ static int __devexit ibmmca_remove(struct device *dev)
}
/* The following routine is the SCSI command queue for the midlevel driver */
-static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int ibmmca_queuecommand_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{
unsigned int ldn;
unsigned int scsi_cmd;
@@ -1996,6 +1996,8 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(ibmmca_queuecommand)
+
static int __ibmmca_abort(Scsi_Cmnd * cmd)
{
/* Abort does not work, as the adapter never generates an interrupt on
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 00d08b25425f..57cad7e20caa 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1606,7 +1606,7 @@ static inline int ibmvfc_host_chkready(struct ibmvfc_host *vhost)
* Returns:
* 0 on success / other on failure
**/
-static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
+static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
void (*done) (struct scsi_cmnd *))
{
struct ibmvfc_host *vhost = shost_priv(cmnd->device->host);
@@ -1672,6 +1672,8 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
return 0;
}
+static DEF_SCSI_QCMD(ibmvfc_queuecommand)
+
/**
* ibmvfc_sync_completion - Signal that a synchronous command has completed
* @evt: ibmvfc event struct
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 67f78a470f5f..041958453e2a 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -713,7 +713,7 @@ static inline u16 lun_from_dev(struct scsi_device *dev)
* @cmd: struct scsi_cmnd to be executed
* @done: Callback function to be called when cmd is completed
*/
-static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
+static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd,
void (*done) (struct scsi_cmnd *))
{
struct srp_cmd *srp_cmd;
@@ -766,6 +766,8 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
return ibmvscsi_send_srp_event(evt_struct, hostdata, 0);
}
+static DEF_SCSI_QCMD(ibmvscsi_queuecommand)
+
/* ------------------------------------------------------------
* Routines for driver initialization
*/
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 4734ab0b3ff6..99aa0e5699bc 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -926,7 +926,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
return 0;
}
-static int imm_queuecommand(struct scsi_cmnd *cmd,
+static int imm_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
imm_struct *dev = imm_dev(cmd->device->host);
@@ -949,6 +949,8 @@ static int imm_queuecommand(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(imm_queuecommand)
+
/*
* Apparently the disk->capacity attribute is off by 1 sector
* for all disk drives. We add the one here, but it should really
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index 52bdc6df6b92..6568aab745a0 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -334,7 +334,7 @@ static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
static void in2000_execute(struct Scsi_Host *instance);
-static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+static int in2000_queuecommand_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
{
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
@@ -431,6 +431,8 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(in2000_queuecommand)
+
/*
diff --git a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h
index 0fb8b06b8392..5821e1fbce08 100644
--- a/drivers/scsi/in2000.h
+++ b/drivers/scsi/in2000.h
@@ -396,7 +396,7 @@ struct IN2000_hostdata {
flags)
static int in2000_detect(struct scsi_host_template *) in2000__INIT;
-static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int in2000_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
static int in2000_abort(Scsi_Cmnd *);
static void in2000_setup(char *, int *) in2000__INIT;
static int in2000_biosparam(struct scsi_device *, struct block_device *,
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index 108797761b95..9627d062e16b 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2639,7 +2639,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
* will cause the mid layer to call us again later with the command)
*/
-static int i91u_queuecommand(struct scsi_cmnd *cmd,
+static int i91u_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata;
@@ -2656,6 +2656,8 @@ static int i91u_queuecommand(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(i91u_queuecommand)
+
/**
* i91u_bus_reset - reset the SCSI bus
* @cmnd: Command block we want to trigger the reset for
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index fa60d7df44be..5bbaee597e88 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5709,7 +5709,7 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd)
* SCSI_MLQUEUE_DEVICE_BUSY if device is busy
* SCSI_MLQUEUE_HOST_BUSY if host is busy
**/
-static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
+static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
void (*done) (struct scsi_cmnd *))
{
struct ipr_ioa_cfg *ioa_cfg;
@@ -5792,6 +5792,8 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
return 0;
}
+static DEF_SCSI_QCMD(ipr_queuecommand)
+
/**
* ipr_ioctl - IOCTL handler
* @sdev: scsi device struct
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index f83a116955f2..b2511acd39bd 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -232,7 +232,7 @@ static int ips_detect(struct scsi_host_template *);
static int ips_release(struct Scsi_Host *);
static int ips_eh_abort(struct scsi_cmnd *);
static int ips_eh_reset(struct scsi_cmnd *);
-static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
+static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *);
static const char *ips_info(struct Scsi_Host *);
static irqreturn_t do_ipsintr(int, void *);
static int ips_hainit(ips_ha_t *);
@@ -1046,7 +1046,7 @@ static int ips_eh_reset(struct scsi_cmnd *SC)
/* Linux obtains io_request_lock before calling this function */
/* */
/****************************************************************************/
-static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
+static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
{
ips_ha_t *ha;
ips_passthru_t *pt;
@@ -1137,6 +1137,8 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
return (0);
}
+static DEF_SCSI_QCMD(ips_queue)
+
/****************************************************************************/
/* */
/* Routine Name: ips_biosparam */
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index e340373b509b..2924363d142b 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1753,7 +1753,7 @@ static inline int fc_fcp_lport_queue_ready(struct fc_lport *lport)
* This is the i/o strategy routine, called by the SCSI layer. This routine
* is called with the host_lock held.
*/
-int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
+static int fc_queuecommand_lck(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
{
struct fc_lport *lport;
struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
@@ -1851,6 +1851,8 @@ out:
spin_lock_irq(lport->host->host_lock);
return rc;
}
+
+DEF_SCSI_QCMD(fc_queuecommand)
EXPORT_SYMBOL(fc_queuecommand);
/**
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 633e09036357..c15fde808c33 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1599,7 +1599,7 @@ enum {
FAILURE_SESSION_NOT_READY,
};
-int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
+static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
{
struct iscsi_cls_session *cls_session;
struct Scsi_Host *host;
@@ -1736,6 +1736,8 @@ fault:
spin_lock(host->host_lock);
return 0;
}
+
+DEF_SCSI_QCMD(iscsi_queuecommand)
EXPORT_SYMBOL_GPL(iscsi_queuecommand);
int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 55f09e92ab59..29251fabecc6 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -189,7 +189,7 @@ int sas_queue_up(struct sas_task *task)
* Note: XXX: Remove the host unlock/lock pair when SCSI Core can
* call us without holding an IRQ spinlock...
*/
-int sas_queuecommand(struct scsi_cmnd *cmd,
+static int sas_queuecommand_lck(struct scsi_cmnd *cmd,
void (*scsi_done)(struct scsi_cmnd *))
__releases(host->host_lock)
__acquires(dev->sata_dev.ap->lock)
@@ -254,6 +254,8 @@ out:
return res;
}
+DEF_SCSI_QCMD(sas_queuecommand)
+
static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
{
struct sas_task *task = TO_SAS_TASK(cmd);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index f64b65a770b8..581837b3c71a 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2899,7 +2899,7 @@ void lpfc_poll_timeout(unsigned long ptr)
* SCSI_MLQUEUE_HOST_BUSY - Block all devices served by this host temporarily.
**/
static int
-lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
{
struct Scsi_Host *shost = cmnd->device->host;
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
@@ -3060,6 +3060,8 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(lpfc_queuecommand)
+
/**
* lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
* @cmnd: Pointer to scsi_cmnd data structure.
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 3ddb4dc62d5d..6c42dff0f4d3 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -66,7 +66,7 @@ static void cmd_done(struct fsc_state *, int result);
static void set_dma_cmds(struct fsc_state *, struct scsi_cmnd *);
-static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int mac53c94_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct fsc_state *state;
@@ -99,6 +99,8 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *
return 0;
}
+static DEF_SCSI_QCMD(mac53c94_queue)
+
static int mac53c94_host_reset(struct scsi_cmnd *cmd)
{
struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 7ceb5cf12c6b..9aa048525eb2 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -366,7 +366,7 @@ mega_runpendq(adapter_t *adapter)
* The command queuing entry point for the mid-layer.
*/
static int
-megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
+megaraid_queue_lck(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
{
adapter_t *adapter;
scb_t *scb;
@@ -409,6 +409,8 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
return busy;
}
+static DEF_SCSI_QCMD(megaraid_queue)
+
/**
* mega_allocate_scb()
* @adapter - pointer to our soft state
@@ -4456,7 +4458,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
scb->idx = CMDID_INT_CMDS;
- megaraid_queue(scmd, mega_internal_done);
+ megaraid_queue_lck(scmd, mega_internal_done);
wait_for_completion(&adapter->int_waitq);
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 2b4a048cadf1..f5644745e24e 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -987,7 +987,7 @@ static int mega_query_adapter(adapter_t *);
static int issue_scb(adapter_t *, scb_t *);
static int mega_setup_mailbox(adapter_t *);
-static int megaraid_queue (Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+static int megaraid_queue (struct Scsi_Host *, struct scsi_cmnd *);
static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *);
static void __mega_runpendq(adapter_t *);
static int issue_scb_block(adapter_t *, u_char *);
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index a7810a106b37..5708cb27d078 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -113,8 +113,7 @@ static int megaraid_mbox_fire_sync_cmd(adapter_t *);
static void megaraid_mbox_display_scb(adapter_t *, scb_t *);
static void megaraid_mbox_setup_device_map(adapter_t *);
-static int megaraid_queue_command(struct scsi_cmnd *,
- void (*)(struct scsi_cmnd *));
+static int megaraid_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static scb_t *megaraid_mbox_build_cmd(adapter_t *, struct scsi_cmnd *, int *);
static void megaraid_mbox_runpendq(adapter_t *, scb_t *);
static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *,
@@ -1484,7 +1483,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb)
* Queue entry point for mailbox based controllers.
*/
static int
-megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
+megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
{
adapter_t *adapter;
scb_t *scb;
@@ -1513,6 +1512,8 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
return if_busy;
}
+static DEF_SCSI_QCMD(megaraid_queue_command)
+
/**
* megaraid_mbox_build_cmd - transform the mid-layer scsi commands
* @adapter : controller's soft state
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index eb29d5085131..7451bc096a01 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -1334,7 +1334,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance)
* @done: Callback entry point
*/
static int
-megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
+megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
{
u32 frame_count;
struct megasas_cmd *cmd;
@@ -1417,6 +1417,8 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(megasas_queue_command)
+
static struct megasas_instance *megasas_lookup_instance(u16 host_no)
{
int i;
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 1f784fde2510..197aa1b3f0f3 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1627,7 +1627,7 @@ static void cmd_complete(struct mesh_state *ms)
* Called by midlayer with host locked to queue a new
* request
*/
-static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int mesh_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct mesh_state *ms;
@@ -1648,6 +1648,8 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(mesh_queue)
+
/*
* Called to handle interrupts, either call by the interrupt
* handler (do_mesh_interrupt) or by other functions in
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 16e99b686354..1a96a00418a4 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -3315,7 +3315,7 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
* SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
*/
static int
-_scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
+_scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
{
struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
struct MPT2SAS_DEVICE *sas_device_priv_data;
@@ -3441,6 +3441,8 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
return SCSI_MLQUEUE_HOST_BUSY;
}
+static DEF_SCSI_QCMD(_scsih_qcmd)
+
/**
* _scsih_normalize_sense - normalize descriptor and fixed format sense data
* @sense_buffer: sense data returned by target
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index d013a2aa2fd5..46cc3825638d 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -8029,7 +8029,7 @@ static int ncr53c8xx_slave_configure(struct scsi_device *device)
return 0;
}
-static int ncr53c8xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+static int ncr53c8xx_queue_command_lck (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
unsigned long flags;
@@ -8068,6 +8068,8 @@ printk("ncr53c8xx : command successfully queued\n");
return sts;
}
+static DEF_SCSI_QCMD(ncr53c8xx_queue_command)
+
irqreturn_t ncr53c8xx_intr(int irq, void *dev_id)
{
unsigned long flags;
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 4c1e54545200..6b8b021400f8 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -196,8 +196,7 @@ static void __exit exit_nsp32 (void);
static int nsp32_proc_info (struct Scsi_Host *, char *, char **, off_t, int, int);
static int nsp32_detect (struct pci_dev *pdev);
-static int nsp32_queuecommand(struct scsi_cmnd *,
- void (*done)(struct scsi_cmnd *));
+static int nsp32_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
static const char *nsp32_info (struct Scsi_Host *);
static int nsp32_release (struct Scsi_Host *);
@@ -909,7 +908,7 @@ static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt)
return TRUE;
}
-static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
nsp32_target *target;
@@ -1050,6 +1049,8 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
return 0;
}
+static DEF_SCSI_QCMD(nsp32_queuecommand)
+
/* initialize asic */
static int nsp32hw_init(nsp32_hw_data *data)
{
diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h
index 8dc5b1a5f5da..a04281cace2e 100644
--- a/drivers/scsi/pas16.h
+++ b/drivers/scsi/pas16.h
@@ -118,7 +118,7 @@ static int pas16_abort(Scsi_Cmnd *);
static int pas16_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
static int pas16_detect(struct scsi_host_template *);
-static int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int pas16_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int pas16_bus_reset(Scsi_Cmnd *);
#ifndef CMD_PER_LUN
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 9326c2c14880..be3f33d31a99 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -184,7 +184,7 @@ static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
SCpnt->scsi_done(SCpnt);
}
-static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
+static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{
#ifdef NSP_DEBUG
@@ -264,6 +264,8 @@ static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
return 0;
}
+static DEF_SCSI_QCMD(nsp_queuecommand)
+
/*
* setup PIO FIFO transfer mode and enable/disable to data out
*/
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index d68c9f267c5e..7fc9a9d0a448 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -299,8 +299,7 @@ static int nsp_proc_info (
off_t offset,
int length,
int inout);
-static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
- void (* done)(struct scsi_cmnd *SCpnt));
+static int nsp_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *SCpnt);
/* Error handler */
/*static int nsp_eh_abort (struct scsi_cmnd *SCpnt);*/
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 0ae27cb5cd6f..8552296edaa1 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -547,7 +547,7 @@ SYM53C500_info(struct Scsi_Host *SChost)
}
static int
-SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
int i;
int port_base = SCpnt->device->host->io_port;
@@ -583,6 +583,8 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(SYM53C500_queue)
+
static int
SYM53C500_host_reset(struct scsi_cmnd *SCpnt)
{
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 8e38ca8cd101..7f064f9ca828 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -50,7 +50,6 @@
#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <scsi/libsas.h>
#include <scsi/scsi_tcq.h>
#include <scsi/sas_ata.h>
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index cf89091e4c3d..5e76a624cb08 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -3478,7 +3478,7 @@ static int pmcraid_copy_sglist(
* SCSI_MLQUEUE_DEVICE_BUSY if device is busy
* SCSI_MLQUEUE_HOST_BUSY if host is busy
*/
-static int pmcraid_queuecommand(
+static int pmcraid_queuecommand_lck(
struct scsi_cmnd *scsi_cmd,
void (*done) (struct scsi_cmnd *)
)
@@ -3584,6 +3584,8 @@ static int pmcraid_queuecommand(
return rc;
}
+static DEF_SCSI_QCMD(pmcraid_queuecommand)
+
/**
* pmcraid_open -char node "open" entry, allowed only users with admin access
*/
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 7bc2d796e403..d164c9639361 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -798,7 +798,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
return 0;
}
-static int ppa_queuecommand(struct scsi_cmnd *cmd,
+static int ppa_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done) (struct scsi_cmnd *))
{
ppa_struct *dev = ppa_dev(cmd->device->host);
@@ -821,6 +821,8 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(ppa_queuecommand)
+
/*
* Apparently the disk->capacity attribute is off by 1 sector
* for all disk drives. We add the one here, but it should really
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index 92ffbb510498..cd178b9e40cd 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -211,7 +211,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
return 0;
}
-static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
+static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct ps3rom_private *priv = shost_priv(cmd->device->host);
@@ -260,6 +260,8 @@ static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(ps3rom_queuecommand)
+
static int decode_lv1_status(u64 status, unsigned char *sense_key,
unsigned char *asc, unsigned char *ascq)
{
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index b8166ecfd0e3..5dec684bf010 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -727,7 +727,7 @@ qla1280_info(struct Scsi_Host *host)
* context which is a big NO! NO!.
**************************************************************************/
static int
-qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
+qla1280_queuecommand_lck(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
{
struct Scsi_Host *host = cmd->device->host;
struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
@@ -756,6 +756,8 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
return status;
}
+static DEF_SCSI_QCMD(qla1280_queuecommand)
+
enum action {
ABORT_COMMAND,
DEVICE_RESET,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1830e6e97315..1644eabaafeb 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -179,8 +179,7 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
static void qla2xxx_scan_start(struct Scsi_Host *);
static void qla2xxx_slave_destroy(struct scsi_device *);
-static int qla2xxx_queuecommand(struct scsi_cmnd *cmd,
- void (*fn)(struct scsi_cmnd *));
+static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static int qla2xxx_eh_abort(struct scsi_cmnd *);
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
@@ -535,7 +534,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
}
static int
-qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
@@ -609,6 +608,8 @@ qc24_fail_command:
return 0;
}
+static DEF_SCSI_QCMD(qla2xxx_queuecommand)
+
/*
* qla2x00_eh_wait_on_command
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index f4cd846abf6d..0d48fb4d1044 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -79,8 +79,7 @@ static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc);
/*
* SCSI host template entry points
*/
-static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
- void (*done) (struct scsi_cmnd *));
+static int qla4xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static int qla4xxx_eh_abort(struct scsi_cmnd *cmd);
static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd);
@@ -464,7 +463,7 @@ void qla4xxx_srb_compl(struct kref *ref)
* completion handling). Unfortunely, it sometimes calls the scheduler
* in interrupt context which is a big NO! NO!.
**/
-static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
+static int qla4xxx_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
@@ -538,6 +537,8 @@ qc_fail_command:
return 0;
}
+static DEF_SCSI_QCMD(qla4xxx_queuecommand)
+
/**
* qla4xxx_mem_free - frees memory allocated to adapter
* @ha: Pointer to host adapter structure.
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 1ad51552d6b1..c3a9151ca823 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -439,7 +439,7 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id)
* Queued command
*/
-int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
+static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done) (struct scsi_cmnd *))
{
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
@@ -459,6 +459,8 @@ int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
return 0;
}
+DEF_SCSI_QCMD(qlogicfas408_queuecommand)
+
/*
* Return bios parameters
*/
diff --git a/drivers/scsi/qlogicfas408.h b/drivers/scsi/qlogicfas408.h
index 260626427a32..2f6c0a166200 100644
--- a/drivers/scsi/qlogicfas408.h
+++ b/drivers/scsi/qlogicfas408.h
@@ -103,8 +103,7 @@ struct qlogicfas408_priv {
#define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0])
irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id);
-int qlogicfas408_queuecommand(struct scsi_cmnd * cmd,
- void (*done) (struct scsi_cmnd *));
+int qlogicfas408_queuecommand(struct Scsi_Host *h, struct scsi_cmnd * cmd);
int qlogicfas408_biosparam(struct scsi_device * disk,
struct block_device *dev,
sector_t capacity, int ip[]);
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index f8c561cf751e..664c9572d0c9 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1003,7 +1003,7 @@ static int qlogicpti_slave_configure(struct scsi_device *sdev)
*
* "This code must fly." -davem
*/
-static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *))
+static int qlogicpti_queuecommand_lck(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *))
{
struct Scsi_Host *host = Cmnd->device->host;
struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
@@ -1052,6 +1052,8 @@ toss_command:
return 1;
}
+static DEF_SCSI_QCMD(qlogicpti_queuecommand)
+
static int qlogicpti_return_status(struct Status_Entry *sts, int id)
{
int host_status = DID_ERROR;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 348fba0a8976..2aeb2e9c4d3b 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -634,12 +634,13 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
* Description: a serial number identifies a request for error recovery
* and debugging purposes. Protected by the Host_Lock of host.
*/
-static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
{
cmd->serial_number = host->cmd_serial_number++;
if (cmd->serial_number == 0)
cmd->serial_number = host->cmd_serial_number++;
}
+EXPORT_SYMBOL(scsi_cmd_get_serial);
/**
* scsi_dispatch_command - Dispatch a command to the low-level driver.
@@ -651,7 +652,6 @@ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd
int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
{
struct Scsi_Host *host = cmd->device->host;
- unsigned long flags = 0;
unsigned long timeout;
int rtn = 0;
@@ -737,23 +737,15 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
goto out;
}
- spin_lock_irqsave(host->host_lock, flags);
- /*
- * AK: unlikely race here: for some reason the timer could
- * expire before the serial number is set up below.
- *
- * TODO: kill serial or move to blk layer
- */
- scsi_cmd_get_serial(host, cmd);
-
if (unlikely(host->shost_state == SHOST_DEL)) {
cmd->result = (DID_NO_CONNECT << 16);
scsi_done(cmd);
} else {
trace_scsi_dispatch_cmd_start(cmd);
- rtn = host->hostt->queuecommand(cmd, scsi_done);
+ cmd->scsi_done = scsi_done;
+ rtn = host->hostt->queuecommand(host, cmd);
}
- spin_unlock_irqrestore(host->host_lock, flags);
+
if (rtn) {
trace_scsi_dispatch_cmd_error(cmd, rtn);
if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 2c36bae3bd4b..2f1f9b079b10 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3538,7 +3538,7 @@ static void sdebug_remove_adapter(void)
}
static
-int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
+int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
{
unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
int len, k;
@@ -3884,6 +3884,8 @@ write:
(delay_override ? 0 : scsi_debug_delay));
}
+static DEF_SCSI_QCMD(scsi_debug_queuecommand)
+
static struct scsi_host_template sdebug_driver_template = {
.proc_info = scsi_debug_proc_info,
.proc_name = sdebug_proc_name,
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index f3cf924a2cd9..824b8fc03ce5 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -773,17 +773,15 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
struct Scsi_Host *shost = sdev->host;
DECLARE_COMPLETION_ONSTACK(done);
unsigned long timeleft;
- unsigned long flags;
struct scsi_eh_save ses;
int rtn;
scsi_eh_prep_cmnd(scmd, &ses, cmnd, cmnd_size, sense_bytes);
shost->eh_action = &done;
- spin_lock_irqsave(shost->host_lock, flags);
scsi_log_send(scmd);
- shost->hostt->queuecommand(scmd, scsi_eh_done);
- spin_unlock_irqrestore(shost->host_lock, flags);
+ scmd->scsi_done = scsi_eh_done;
+ shost->hostt->queuecommand(shost, scmd);
timeleft = wait_for_completion_timeout(&done, timeout);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b9ab3a590e4b..956496182c80 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -46,7 +46,6 @@
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/string_helpers.h>
#include <linux/async.h>
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 9c73dbda3bbb..606215e54b88 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -572,7 +572,7 @@ stex_slave_destroy(struct scsi_device *sdev)
}
static int
-stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
+stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct st_hba *hba;
struct Scsi_Host *host;
@@ -698,6 +698,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(stex_queuecommand)
+
static void stex_scsi_done(struct st_ccb *ccb)
{
struct scsi_cmnd *cmd = ccb->cmd;
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 713620ed70d9..4f0e5485ffde 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -908,7 +908,7 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags)
*/
/* Only make static if a wrapper function is used */
-static int NCR5380_queue_command(struct scsi_cmnd *cmd,
+static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
SETUP_HOSTDATA(cmd->device->host);
@@ -1019,6 +1019,8 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(NCR5380_queue_command)
+
/*
* Function : NCR5380_main (void)
*
diff --git a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h
index b29a9d661ca4..bcefd8458e65 100644
--- a/drivers/scsi/sun3_scsi.h
+++ b/drivers/scsi/sun3_scsi.h
@@ -51,8 +51,7 @@ static int sun3scsi_abort(struct scsi_cmnd *);
static int sun3scsi_detect (struct scsi_host_template *);
static const char *sun3scsi_info (struct Scsi_Host *);
static int sun3scsi_bus_reset(struct scsi_cmnd *);
-static int sun3scsi_queue_command(struct scsi_cmnd *,
- void (*done)(struct scsi_cmnd *));
+static int sun3scsi_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int sun3scsi_release (struct Scsi_Host *);
#ifndef CMD_PER_LUN
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index e5c369bb568f..190107ae120b 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -734,7 +734,7 @@ const char *sym53c416_info(struct Scsi_Host *SChost)
return info;
}
-int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+static int sym53c416_queuecommand_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
int base;
unsigned long flags = 0;
@@ -761,6 +761,8 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
return 0;
}
+DEF_SCSI_QCMD(sym53c416_queuecommand)
+
static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
{
int base;
diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
index 77860d0748ff..387de5d80a70 100644
--- a/drivers/scsi/sym53c416.h
+++ b/drivers/scsi/sym53c416.h
@@ -25,7 +25,7 @@
static int sym53c416_detect(struct scsi_host_template *);
static const char *sym53c416_info(struct Scsi_Host *);
static int sym53c416_release(struct Scsi_Host *);
-static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int sym53c416_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
static int sym53c416_host_reset(Scsi_Cmnd *);
static int sym53c416_bios_param(struct scsi_device *, struct block_device *,
sector_t, int *);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 8b955b534a36..6b97ded9d45d 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -505,7 +505,7 @@ void sym_log_bus_error(struct Scsi_Host *shost)
* queuecommand method. Entered with the host adapter lock held and
* interrupts disabled.
*/
-static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
+static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct sym_hcb *np = SYM_SOFTC_PTR(cmd);
@@ -536,6 +536,8 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
return 0;
}
+static DEF_SCSI_QCMD(sym53c8xx_queue_command)
+
/*
* Linux entry point of the interrupt handler.
*/
diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h
index 76a069b7ac0b..ada1115079c9 100644
--- a/drivers/scsi/t128.h
+++ b/drivers/scsi/t128.h
@@ -96,8 +96,7 @@ static int t128_abort(struct scsi_cmnd *);
static int t128_biosparam(struct scsi_device *, struct block_device *,
sector_t, int*);
static int t128_detect(struct scsi_host_template *);
-static int t128_queue_command(struct scsi_cmnd *,
- void (*done)(struct scsi_cmnd *));
+static int t128_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
static int t128_bus_reset(struct scsi_cmnd *);
#ifndef CMD_PER_LUN
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 27866b0adfeb..a124a28f2ccb 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -1883,7 +1883,7 @@ dc390_ScsiRstDetect( struct dc390_acb* pACB )
return;
}
-static int DC390_queuecommand(struct scsi_cmnd *cmd,
+static int DC390_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct scsi_device *sdev = cmd->device;
@@ -1944,6 +1944,8 @@ static int DC390_queuecommand(struct scsi_cmnd *cmd,
return SCSI_MLQUEUE_DEVICE_BUSY;
}
+static DEF_SCSI_QCMD(DC390_queuecommand)
+
static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
{
struct pci_dev *pdev;
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index 5d9fdeeb2315..edfc5da8be4c 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -433,7 +433,7 @@
static int u14_34f_detect(struct scsi_host_template *);
static int u14_34f_release(struct Scsi_Host *);
-static int u14_34f_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+static int u14_34f_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
static int u14_34f_eh_abort(struct scsi_cmnd *);
static int u14_34f_eh_host_reset(struct scsi_cmnd *);
static int u14_34f_bios_param(struct scsi_device *, struct block_device *,
@@ -1248,7 +1248,7 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
}
-static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
+static int u14_34f_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
unsigned int i, j, k;
struct mscp *cpp;
@@ -1329,6 +1329,8 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
return 0;
}
+static DEF_SCSI_QCMD(u14_34f_queuecommand)
+
static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) {
unsigned int i, j;
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index 27aa40f3980e..0571ef9639cb 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -700,7 +700,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
mscp->transfer_data_length = transfer_length;
}
-static int ultrastor_queuecommand(struct scsi_cmnd *SCpnt,
+static int ultrastor_queuecommand_lck(struct scsi_cmnd *SCpnt,
void (*done) (struct scsi_cmnd *))
{
struct mscp *my_mscp;
@@ -825,6 +825,8 @@ retry:
return 0;
}
+static DEF_SCSI_QCMD(ultrastor_queuecommand)
+
/* This code must deal with 2 cases:
1. The command has not been written to the OGM. In this case, set
diff --git a/drivers/scsi/ultrastor.h b/drivers/scsi/ultrastor.h
index a692905f95f7..165c18b5cf5f 100644
--- a/drivers/scsi/ultrastor.h
+++ b/drivers/scsi/ultrastor.h
@@ -15,8 +15,7 @@
static int ultrastor_detect(struct scsi_host_template *);
static const char *ultrastor_info(struct Scsi_Host *shpnt);
-static int ultrastor_queuecommand(struct scsi_cmnd *,
- void (*done)(struct scsi_cmnd *));
+static int ultrastor_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
static int ultrastor_abort(struct scsi_cmnd *);
static int ultrastor_host_reset(struct scsi_cmnd *);
static int ultrastor_biosparam(struct scsi_device *, struct block_device *,
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 26894459c37f..a18996d24466 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -690,7 +690,7 @@ static int pvscsi_queue_ring(struct pvscsi_adapter *adapter,
return 0;
}
-static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int pvscsi_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct Scsi_Host *host = cmd->device->host;
struct pvscsi_adapter *adapter = shost_priv(host);
@@ -719,6 +719,8 @@ static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(pvscsi_queue)
+
static int pvscsi_abort(struct scsi_cmnd *cmd)
{
struct pvscsi_adapter *adapter = shost_priv(cmd->device->host);
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index b701bf2cc187..5f697e0bd009 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -371,8 +371,8 @@ calc_sync_msg(unsigned int period, unsigned int offset, unsigned int fast,
msg[1] = offset;
}
-int
-wd33c93_queuecommand(struct scsi_cmnd *cmd,
+static int
+wd33c93_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *))
{
struct WD33C93_hostdata *hostdata;
@@ -468,6 +468,8 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
return 0;
}
+DEF_SCSI_QCMD(wd33c93_queuecommand)
+
/*
* This routine attempts to start a scsi command. If the host_card is
* already connected, we give up immediately. Otherwise, look through
diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h
index 1ed5f3bf388e..3b463d7304dc 100644
--- a/drivers/scsi/wd33c93.h
+++ b/drivers/scsi/wd33c93.h
@@ -343,8 +343,7 @@ struct WD33C93_hostdata {
void wd33c93_init (struct Scsi_Host *instance, const wd33c93_regs regs,
dma_setup_t setup, dma_stop_t stop, int clock_freq);
int wd33c93_abort (struct scsi_cmnd *cmd);
-int wd33c93_queuecommand (struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *));
+int wd33c93_queuecommand (struct Scsi_Host *h, struct scsi_cmnd *cmd);
void wd33c93_intr (struct Scsi_Host *instance);
int wd33c93_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
int wd33c93_host_reset (struct scsi_cmnd *);
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 333580bf37c5..db451ae0a368 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1082,7 +1082,7 @@ static irqreturn_t wd7000_intr(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
+static int wd7000_queuecommand_lck(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *))
{
Scb *scb;
@@ -1139,6 +1139,8 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
return 0;
}
+static DEF_SCSI_QCMD(wd7000_queuecommand)
+
static int wd7000_diagnostics(Adapter * host, int code)
{
static IcbDiag icb = { ICB_OP_DIAGNOSTICS };
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 4d8e14b7aa93..09a550860dcf 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2872,7 +2872,7 @@ static struct console serial8250_console = {
.device = uart_console_device,
.setup = serial8250_console_setup,
.early_setup = serial8250_console_early_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1,
.data = &serial8250_reg,
};
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index fa62578fcd20..bcc31f2140ac 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -18,7 +18,6 @@ static char *serial_version = "$Revision: 1.25 $";
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/major.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c
index 5fc699e929dc..d40010a22ecd 100644
--- a/drivers/serial/mfd.c
+++ b/drivers/serial/mfd.c
@@ -900,8 +900,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned char cval, fcr = 0;
unsigned long flags;
unsigned int baud, quot;
- u32 mul = 0x3600;
- u32 ps = 0x10;
+ u32 ps, mul;
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -943,31 +942,24 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
quot = 1;
+ ps = 0x10;
+ mul = 0x3600;
switch (baud) {
case 3500000:
mul = 0x3345;
ps = 0xC;
break;
- case 3000000:
- mul = 0x2EE0;
- break;
- case 2500000:
- mul = 0x2710;
- break;
- case 2000000:
- mul = 0x1F40;
- break;
case 1843200:
mul = 0x2400;
break;
+ case 3000000:
+ case 2500000:
+ case 2000000:
case 1500000:
- mul = 0x1770;
- break;
case 1000000:
- mul = 0xFA0;
- break;
case 500000:
- mul = 0x7D0;
+ /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */
+ mul = baud / 500000 * 0x9C4;
break;
default:
/* Use uart_get_divisor to get quot for other baud rates */
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index c4ea14670d44..9ffa5bee44ab 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -29,7 +29,6 @@
#include <linux/console.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/serial.h> /* for serial_state and serial_icounter_struct */
#include <linux/serial_core.h>
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c
index cb12a8e1466b..3f5e387ed564 100644
--- a/drivers/sh/clk/core.c
+++ b/drivers/sh/clk/core.c
@@ -418,8 +418,11 @@ int clk_register(struct clk *clk)
list_add(&clk->sibling, &root_clks);
list_add(&clk->node, &clock_list);
+
+#ifdef CONFIG_SH_CLK_CPG_LEGACY
if (clk->ops && clk->ops->init)
clk->ops->init(clk);
+#endif
out_unlock:
mutex_unlock(&clock_list_sem);
@@ -455,19 +458,13 @@ EXPORT_SYMBOL_GPL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
- return clk_set_rate_ex(clk, rate, 0);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
-{
int ret = -EOPNOTSUPP;
unsigned long flags;
spin_lock_irqsave(&clock_lock, flags);
if (likely(clk->ops && clk->ops->set_rate)) {
- ret = clk->ops->set_rate(clk, rate, algo_id);
+ ret = clk->ops->set_rate(clk, rate);
if (ret != 0)
goto out_unlock;
} else {
@@ -485,7 +482,7 @@ out_unlock:
return ret;
}
-EXPORT_SYMBOL_GPL(clk_set_rate_ex);
+EXPORT_SYMBOL_GPL(clk_set_rate);
int clk_set_parent(struct clk *clk, struct clk *parent)
{
@@ -653,8 +650,7 @@ static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
clkp->ops->set_parent(clkp,
clkp->parent);
if (likely(clkp->ops->set_rate))
- clkp->ops->set_rate(clkp,
- rate, NO_CHANGE);
+ clkp->ops->set_rate(clkp, rate);
else if (likely(clkp->ops->recalc))
clkp->rate = clkp->ops->recalc(clkp);
}
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 3aea5f0ceb09..6172335ae323 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -110,8 +110,7 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
return 0;
}
-static int sh_clk_div6_set_rate(struct clk *clk,
- unsigned long rate, int algo_id)
+static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
{
unsigned long value;
int idx;
@@ -132,7 +131,7 @@ static int sh_clk_div6_enable(struct clk *clk)
unsigned long value;
int ret;
- ret = sh_clk_div6_set_rate(clk, clk->rate, 0);
+ ret = sh_clk_div6_set_rate(clk, clk->rate);
if (ret == 0) {
value = __raw_readl(clk->enable_reg);
value &= ~0x100; /* clear stop bit to enable clock */
@@ -253,7 +252,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
return 0;
}
-static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
{
struct clk_div4_table *d4t = clk->priv;
unsigned long value;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 154529aacc03..a067046c9da2 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -352,8 +352,12 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer)
xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS;
if (xfer->tx_buf) {
+ /* tx_buf is a const void* where we need a void * for the dma
+ * mapping */
+ void *nonconst_tx = (void *)xfer->tx_buf;
+
xfer->tx_dma = dma_map_single(dev,
- (void *) xfer->tx_buf, xfer->len,
+ nonconst_tx, xfer->len,
DMA_TO_DEVICE);
if (dma_mapping_error(dev, xfer->tx_dma))
return -ENOMEM;
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c
index ef9c6a04ad8f..744d3f6e4709 100644
--- a/drivers/ssb/b43_pci_bridge.c
+++ b/drivers/ssb/b43_pci_bridge.c
@@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC, 0x4318) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 8c95d8c2a4f4..016c6f7f8630 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -620,13 +620,13 @@ static ssize_t class_set_picture(struct device *device,
#define ASUS_OLED_DEVICE_ATTR(_file) dev_attr_asus_oled_##_file
-static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(asus_oled_enabled, S_IWUSR | S_IRUGO,
get_enabled, set_enabled);
-static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
+static DEVICE_ATTR(asus_oled_picture, S_IWUSR , NULL, set_picture);
-static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(enabled, S_IWUSR | S_IRUGO,
class_get_enabled, class_set_enabled);
-static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
+static DEVICE_ATTR(picture, S_IWUSR, NULL, class_set_picture);
static int asus_oled_probe(struct usb_interface *interface,
const struct usb_device_id *id)
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index b68a7e5173be..d85de82f941a 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -463,9 +463,6 @@ static void hardif_remove_interface(struct batman_if *batman_if)
return;
batman_if->if_status = IF_TO_BE_REMOVED;
-
- /* caller must take if_list_lock */
- list_del_rcu(&batman_if->list);
synchronize_rcu();
sysfs_del_hardif(&batman_if->hardif_obj);
hardif_put(batman_if);
@@ -474,13 +471,21 @@ static void hardif_remove_interface(struct batman_if *batman_if)
void hardif_remove_interfaces(void)
{
struct batman_if *batman_if, *batman_if_tmp;
+ struct list_head if_queue;
+
+ INIT_LIST_HEAD(&if_queue);
- rtnl_lock();
spin_lock(&if_list_lock);
list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) {
- hardif_remove_interface(batman_if);
+ list_del_rcu(&batman_if->list);
+ list_add_tail(&batman_if->list, &if_queue);
}
spin_unlock(&if_list_lock);
+
+ rtnl_lock();
+ list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) {
+ hardif_remove_interface(batman_if);
+ }
rtnl_unlock();
}
@@ -507,8 +512,10 @@ static int hard_if_event(struct notifier_block *this,
break;
case NETDEV_UNREGISTER:
spin_lock(&if_list_lock);
- hardif_remove_interface(batman_if);
+ list_del_rcu(&batman_if->list);
spin_unlock(&if_list_lock);
+
+ hardif_remove_interface(batman_if);
break;
case NETDEV_CHANGEMTU:
if (batman_if->soft_iface)
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
index 3904db9ce7b1..0e996181daf7 100644
--- a/drivers/staging/batman-adv/soft-interface.c
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -194,14 +194,15 @@ void interface_rx(struct net_device *soft_iface,
struct bat_priv *priv = netdev_priv(soft_iface);
/* check if enough space is available for pulling, and pull */
- if (!pskb_may_pull(skb, hdr_size)) {
- kfree_skb(skb);
- return;
- }
+ if (!pskb_may_pull(skb, hdr_size))
+ goto dropped;
+
skb_pull_rcsum(skb, hdr_size);
/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
/* skb->dev & skb->pkt_type are set here */
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ goto dropped;
skb->protocol = eth_type_trans(skb, soft_iface);
/* should not be neccesary anymore as we use skb_pull_rcsum()
@@ -216,6 +217,11 @@ void interface_rx(struct net_device *soft_iface,
soft_iface->last_rx = jiffies;
netif_rx(skb);
+ return;
+
+dropped:
+ kfree_skb(skb);
+ return;
}
#ifdef HAVE_NET_DEVICE_OPS
diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README
index c8f1cf1b4409..a27bb0b4f581 100644
--- a/drivers/staging/brcm80211/README
+++ b/drivers/staging/brcm80211/README
@@ -88,7 +88,9 @@ with the driver.
Contact Info:
=============
-Brett Rudley brudley@broadcom.com
-Henry Ptasinski henryp@broadcom.com
-Dowan Kim dowan@broadcom.com
+Brett Rudley brudley@broadcom.com
+Henry Ptasinski henryp@broadcom.com
+Dowan Kim dowan@broadcom.com
+Roland Vossen rvossen@broadcom.com
+Arend van Spriel arend@broadcom.com
diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO
index dbf904184899..24ebadbe4241 100644
--- a/drivers/staging/brcm80211/TODO
+++ b/drivers/staging/brcm80211/TODO
@@ -46,4 +46,6 @@ Contact
Brett Rudley <brudley@broadcom.com>
Henry Ptasinski <henryp@broadcom.com>
Dowan Kim <dowan@broadcom.com>
+Roland Vossen <rvossen@broadcom.com>
+Arend van Spriel <arend@broadcom.com>
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 1f177a67ff11..de784ff08caa 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -2295,8 +2295,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
usbduxsub_tmp->inBuffer = NULL;
kfree(usbduxsub_tmp->insnBuffer);
usbduxsub_tmp->insnBuffer = NULL;
- kfree(usbduxsub_tmp->inBuffer);
- usbduxsub_tmp->inBuffer = NULL;
+ kfree(usbduxsub_tmp->outBuffer);
+ usbduxsub_tmp->outBuffer = NULL;
kfree(usbduxsub_tmp->dac_commands);
usbduxsub_tmp->dac_commands = NULL;
kfree(usbduxsub_tmp->dux_commands);
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h
index f3c827eb0abe..884263b2775d 100644
--- a/drivers/staging/easycap/easycap.h
+++ b/drivers/staging/easycap/easycap.h
@@ -75,9 +75,9 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/kref.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/uaccess.h>
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index a145a15cfdb3..8894ab14f167 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -204,7 +204,7 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
t->value = temp; \
return count; \
} \
- static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+ static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value);
show_int(enable);
show_int(offline);
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index b3f42f37a313..48d4e483d8a4 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -199,7 +199,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
struct go7007 *go = i2c_get_adapdata(adapter);
struct v4l2_device *v4l2_dev = &go->v4l2_dev;
- if (v4l2_i2c_new_subdev(v4l2_dev, adapter, NULL, type, addr, NULL))
+ if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL))
return 0;
printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type);
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 41d9acf4cd61..6f8d67d0d64f 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -72,8 +72,7 @@ struct storvsc_driver_context {
/* Static decl */
static int storvsc_probe(struct device *dev);
-static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
- void (*done)(struct scsi_cmnd *));
+static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd);
static int storvsc_device_alloc(struct scsi_device *);
static int storvsc_device_configure(struct scsi_device *);
static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd);
@@ -595,7 +594,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
/*
* storvsc_queuecommand - Initiate command processing
*/
-static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
+static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
void (*done)(struct scsi_cmnd *))
{
int ret;
@@ -783,6 +782,8 @@ retry_request:
return ret;
}
+static DEF_SCSI_QCMD(storvsc_queuecommand)
+
static int storvsc_merge_bvec(struct request_queue *q,
struct bvec_merge_data *bmd, struct bio_vec *bvec)
{
diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c
index c86d1498737d..1c1e98aee2d9 100644
--- a/drivers/staging/iio/accel/adis16220_core.c
+++ b/drivers/staging/iio/accel/adis16220_core.c
@@ -507,7 +507,7 @@ static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
adis16220_write_reset, 0);
#define IIO_DEV_ATTR_CAPTURE(_store) \
- IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0)
+ IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0)
static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture);
diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c
index 9618c7997461..991440015e92 100644
--- a/drivers/staging/intel_sst/intel_sst_app_interface.c
+++ b/drivers/staging/intel_sst/intel_sst_app_interface.c
@@ -34,7 +34,6 @@
#include <linux/uaccess.h>
#include <linux/firmware.h>
#include <linux/ioctl.h>
-#include <linux/smp_lock.h>
#ifdef CONFIG_MRST_RAR_HANDLER
#include <linux/rar_register.h>
#include "../../../drivers/staging/memrar/memrar.h"
diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c
index fbae39fda5c0..5c455608b024 100644
--- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c
+++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c
@@ -1269,7 +1269,7 @@ finish:
dbufs->output_bytes_produced = total_output;
str_info->status = str_info->prev;
str_info->prev = STREAM_DECODE;
- str_info->decode_ibuf = NULL;
kfree(str_info->decode_ibuf);
+ str_info->decode_ibuf = NULL;
return retval;
}
diff --git a/drivers/staging/keucr/scsiglue.c b/drivers/staging/keucr/scsiglue.c
index a2671404f7ac..da4f42af3838 100644
--- a/drivers/staging/keucr/scsiglue.c
+++ b/drivers/staging/keucr/scsiglue.c
@@ -87,7 +87,7 @@ static int slave_configure(struct scsi_device *sdev)
/* This is always called with scsi_lock(host) held */
//----- queuecommand() ---------------------
-static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
+static int queuecommand_lck(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
{
struct us_data *us = host_to_us(srb->device->host);
@@ -117,6 +117,8 @@ static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
return 0;
}
+static DEF_SCSI_QCMD(queuecommand)
+
/***********************************************************************
* Error handling functions
***********************************************************************/
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
index 040e25ca6d33..67e23b6e2d35 100644
--- a/drivers/staging/line6/control.c
+++ b/drivers/staging/line6/control.c
@@ -266,210 +266,210 @@ VARIAX_PARAM_R(float, mix2);
VARIAX_PARAM_R(float, mix1);
VARIAX_PARAM_R(int, pickup_wiring);
-static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
-static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position,
+static DEVICE_ATTR(tweak, S_IWUSR | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUSR | S_IRUGO, pod_get_wah_position,
pod_set_wah_position);
-static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_gain, S_IWUSR | S_IRUGO,
pod_get_compression_gain, pod_set_compression_gain);
-static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(vol_pedal_position, S_IWUSR | S_IRUGO,
pod_get_vol_pedal_position, pod_set_vol_pedal_position);
-static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(compression_threshold, S_IWUSR | S_IRUGO,
pod_get_compression_threshold,
pod_set_compression_threshold);
-static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
-static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup,
+static DEVICE_ATTR(pan, S_IWUSR | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUSR | S_IRUGO, pod_get_amp_model_setup,
pod_set_amp_model_setup);
-static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model,
+static DEVICE_ATTR(amp_model, S_IWUSR | S_IRUGO, pod_get_amp_model,
pod_set_amp_model);
-static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
-static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
-static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
-static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
-static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
-static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid,
+static DEVICE_ATTR(drive, S_IWUSR | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUSR | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUSR | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUSR | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUSR | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUSR | S_IRUGO, pod_get_highmid,
pod_set_highmid);
-static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol,
+static DEVICE_ATTR(chan_vol, S_IWUSR | S_IRUGO, pod_get_chan_vol,
pod_set_chan_vol);
-static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix,
+static DEVICE_ATTR(reverb_mix, S_IWUSR | S_IRUGO, pod_get_reverb_mix,
pod_set_reverb_mix);
-static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup,
+static DEVICE_ATTR(effect_setup, S_IWUSR | S_IRUGO, pod_get_effect_setup,
pod_set_effect_setup);
-static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_1_frequency, S_IWUSR | S_IRUGO,
pod_get_band_1_frequency, pod_set_band_1_frequency);
-static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence,
+static DEVICE_ATTR(presence, S_IWUSR | S_IRUGO, pod_get_presence,
pod_set_presence);
-static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(treble__bass, treble, S_IWUSR | S_IRUGO,
pod_get_treble__bass, pod_set_treble__bass);
-static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(noise_gate_enable, S_IWUSR | S_IRUGO,
pod_get_noise_gate_enable, pod_set_noise_gate_enable);
-static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold,
+static DEVICE_ATTR(gate_threshold, S_IWUSR | S_IRUGO, pod_get_gate_threshold,
pod_set_gate_threshold);
-static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time,
+static DEVICE_ATTR(gate_decay_time, S_IWUSR | S_IRUGO, pod_get_gate_decay_time,
pod_set_gate_decay_time);
-static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable,
+static DEVICE_ATTR(stomp_enable, S_IWUSR | S_IRUGO, pod_get_stomp_enable,
pod_set_stomp_enable);
-static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable,
+static DEVICE_ATTR(comp_enable, S_IWUSR | S_IRUGO, pod_get_comp_enable,
pod_set_comp_enable);
-static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time,
+static DEVICE_ATTR(stomp_time, S_IWUSR | S_IRUGO, pod_get_stomp_time,
pod_set_stomp_time);
-static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable,
+static DEVICE_ATTR(delay_enable, S_IWUSR | S_IRUGO, pod_get_delay_enable,
pod_set_delay_enable);
-static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1,
+static DEVICE_ATTR(mod_param_1, S_IWUSR | S_IRUGO, pod_get_mod_param_1,
pod_set_mod_param_1);
-static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1,
+static DEVICE_ATTR(delay_param_1, S_IWUSR | S_IRUGO, pod_get_delay_param_1,
pod_set_delay_param_1);
-static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUSR | S_IRUGO,
pod_get_delay_param_1_note_value,
pod_set_delay_param_1_note_value);
-static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUSR | S_IRUGO,
pod_get_band_2_frequency__bass,
pod_set_band_2_frequency__bass);
-static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2,
+static DEVICE_ATTR(delay_param_2, S_IWUSR | S_IRUGO, pod_get_delay_param_2,
pod_set_delay_param_2);
-static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_volume_mix, S_IWUSR | S_IRUGO,
pod_get_delay_volume_mix, pod_set_delay_volume_mix);
-static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3,
+static DEVICE_ATTR(delay_param_3, S_IWUSR | S_IRUGO, pod_get_delay_param_3,
pod_set_delay_param_3);
-static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable,
+static DEVICE_ATTR(reverb_enable, S_IWUSR | S_IRUGO, pod_get_reverb_enable,
pod_set_reverb_enable);
-static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type,
+static DEVICE_ATTR(reverb_type, S_IWUSR | S_IRUGO, pod_get_reverb_type,
pod_set_reverb_type);
-static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay,
+static DEVICE_ATTR(reverb_decay, S_IWUSR | S_IRUGO, pod_get_reverb_decay,
pod_set_reverb_decay);
-static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone,
+static DEVICE_ATTR(reverb_tone, S_IWUSR | S_IRUGO, pod_get_reverb_tone,
pod_set_reverb_tone);
-static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(reverb_pre_delay, S_IWUSR | S_IRUGO,
pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
-static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post,
+static DEVICE_ATTR(reverb_pre_post, S_IWUSR | S_IRUGO, pod_get_reverb_pre_post,
pod_set_reverb_pre_post);
-static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_2_frequency, S_IWUSR | S_IRUGO,
pod_get_band_2_frequency, pod_set_band_2_frequency);
-static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUSR | S_IRUGO,
pod_get_band_3_frequency__bass,
pod_set_band_3_frequency__bass);
-static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable,
+static DEVICE_ATTR(wah_enable, S_IWUSR | S_IRUGO, pod_get_wah_enable,
pod_set_wah_enable);
-static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_lo_cut, S_IWUSR | S_IRUGO,
pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
-static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUSR | S_IRUGO,
pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
-static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUSR | S_IRUGO,
pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
-static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post,
+static DEVICE_ATTR(eq_pre_post, S_IWUSR | S_IRUGO, pod_get_eq_pre_post,
pod_set_eq_pre_post);
-static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post,
+static DEVICE_ATTR(volume_pre_post, S_IWUSR | S_IRUGO, pod_get_volume_pre_post,
pod_set_volume_pre_post);
-static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model,
+static DEVICE_ATTR(di_model, S_IWUSR | S_IRUGO, pod_get_di_model,
pod_set_di_model);
-static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay,
+static DEVICE_ATTR(di_delay, S_IWUSR | S_IRUGO, pod_get_di_delay,
pod_set_di_delay);
-static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable,
+static DEVICE_ATTR(mod_enable, S_IWUSR | S_IRUGO, pod_get_mod_enable,
pod_set_mod_enable);
-static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUSR | S_IRUGO,
pod_get_mod_param_1_note_value,
pod_set_mod_param_1_note_value);
-static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2,
+static DEVICE_ATTR(mod_param_2, S_IWUSR | S_IRUGO, pod_get_mod_param_2,
pod_set_mod_param_2);
-static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3,
+static DEVICE_ATTR(mod_param_3, S_IWUSR | S_IRUGO, pod_get_mod_param_3,
pod_set_mod_param_3);
-static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4,
+static DEVICE_ATTR(mod_param_4, S_IWUSR | S_IRUGO, pod_get_mod_param_4,
pod_set_mod_param_4);
-static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5,
+static DEVICE_ATTR(mod_param_5, S_IWUSR | S_IRUGO, pod_get_mod_param_5,
pod_set_mod_param_5);
-static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix,
+static DEVICE_ATTR(mod_volume_mix, S_IWUSR | S_IRUGO, pod_get_mod_volume_mix,
pod_set_mod_volume_mix);
-static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post,
+static DEVICE_ATTR(mod_pre_post, S_IWUSR | S_IRUGO, pod_get_mod_pre_post,
pod_set_mod_pre_post);
-static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(modulation_model, S_IWUSR | S_IRUGO,
pod_get_modulation_model, pod_set_modulation_model);
-static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_3_frequency, S_IWUSR | S_IRUGO,
pod_get_band_3_frequency, pod_set_band_3_frequency);
-static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUSR | S_IRUGO,
pod_get_band_4_frequency__bass,
pod_set_band_4_frequency__bass);
-static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUSR | S_IRUGO,
pod_get_mod_param_1_double_precision,
pod_set_mod_param_1_double_precision);
-static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUSR | S_IRUGO,
pod_get_delay_param_1_double_precision,
pod_set_delay_param_1_double_precision);
-static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable,
+static DEVICE_ATTR(eq_enable, S_IWUSR | S_IRUGO, pod_get_eq_enable,
pod_set_eq_enable);
-static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
-static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tap, S_IWUSR | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUSR | S_IRUGO,
pod_get_volume_tweak_pedal_assign,
pod_set_volume_tweak_pedal_assign);
-static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_5_frequency, S_IWUSR | S_IRUGO,
pod_get_band_5_frequency, pod_set_band_5_frequency);
-static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
-static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection,
+static DEVICE_ATTR(tuner, S_IWUSR | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUSR | S_IRUGO, pod_get_mic_selection,
pod_set_mic_selection);
-static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model,
+static DEVICE_ATTR(cabinet_model, S_IWUSR | S_IRUGO, pod_get_cabinet_model,
pod_set_cabinet_model);
-static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model,
+static DEVICE_ATTR(stomp_model, S_IWUSR | S_IRUGO, pod_get_stomp_model,
pod_set_stomp_model);
-static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel,
+static DEVICE_ATTR(roomlevel, S_IWUSR | S_IRUGO, pod_get_roomlevel,
pod_set_roomlevel);
-static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_4_frequency, S_IWUSR | S_IRUGO,
pod_get_band_4_frequency, pod_set_band_4_frequency);
-static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(band_6_frequency, S_IWUSR | S_IRUGO,
pod_get_band_6_frequency, pod_set_band_6_frequency);
-static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUSR | S_IRUGO,
pod_get_stomp_param_1_note_value,
pod_set_stomp_param_1_note_value);
-static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2,
+static DEVICE_ATTR(stomp_param_2, S_IWUSR | S_IRUGO, pod_get_stomp_param_2,
pod_set_stomp_param_2);
-static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3,
+static DEVICE_ATTR(stomp_param_3, S_IWUSR | S_IRUGO, pod_get_stomp_param_3,
pod_set_stomp_param_3);
-static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4,
+static DEVICE_ATTR(stomp_param_4, S_IWUSR | S_IRUGO, pod_get_stomp_param_4,
pod_set_stomp_param_4);
-static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5,
+static DEVICE_ATTR(stomp_param_5, S_IWUSR | S_IRUGO, pod_get_stomp_param_5,
pod_set_stomp_param_5);
-static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6,
+static DEVICE_ATTR(stomp_param_6, S_IWUSR | S_IRUGO, pod_get_stomp_param_6,
pod_set_stomp_param_6);
-static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(amp_switch_select, S_IWUSR | S_IRUGO,
pod_get_amp_switch_select, pod_set_amp_switch_select);
-static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4,
+static DEVICE_ATTR(delay_param_4, S_IWUSR | S_IRUGO, pod_get_delay_param_4,
pod_set_delay_param_4);
-static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5,
+static DEVICE_ATTR(delay_param_5, S_IWUSR | S_IRUGO, pod_get_delay_param_5,
pod_set_delay_param_5);
-static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post,
+static DEVICE_ATTR(delay_pre_post, S_IWUSR | S_IRUGO, pod_get_delay_pre_post,
pod_set_delay_pre_post);
-static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model,
+static DEVICE_ATTR(delay_model, S_IWUSR | S_IRUGO, pod_get_delay_model,
pod_set_delay_model);
-static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(delay_verb_model, S_IWUSR | S_IRUGO,
pod_get_delay_verb_model, pod_set_delay_verb_model);
-static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb,
+static DEVICE_ATTR(tempo_msb, S_IWUSR | S_IRUGO, pod_get_tempo_msb,
pod_set_tempo_msb);
-static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb,
+static DEVICE_ATTR(tempo_lsb, S_IWUSR | S_IRUGO, pod_get_tempo_lsb,
pod_set_tempo_lsb);
-static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model,
+static DEVICE_ATTR(wah_model, S_IWUSR | S_IRUGO, pod_get_wah_model,
pod_set_wah_model);
-static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume,
+static DEVICE_ATTR(bypass_volume, S_IWUSR | S_IRUGO, pod_get_bypass_volume,
pod_set_bypass_volume);
-static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off,
+static DEVICE_ATTR(fx_loop_on_off, S_IWUSR | S_IRUGO, pod_get_fx_loop_on_off,
pod_set_fx_loop_on_off);
-static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(tweak_param_select, S_IWUSR | S_IRUGO,
pod_get_tweak_param_select, pod_set_tweak_param_select);
-static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage,
+static DEVICE_ATTR(amp1_engage, S_IWUSR | S_IRUGO, pod_get_amp1_engage,
pod_set_amp1_engage);
-static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain,
+static DEVICE_ATTR(band_1_gain, S_IWUSR | S_IRUGO, pod_get_band_1_gain,
pod_set_band_1_gain);
-static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUSR | S_IRUGO,
pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
-static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain,
+static DEVICE_ATTR(band_2_gain, S_IWUSR | S_IRUGO, pod_get_band_2_gain,
pod_set_band_2_gain);
-static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUSR | S_IRUGO,
pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
-static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain,
+static DEVICE_ATTR(band_3_gain, S_IWUSR | S_IRUGO, pod_get_band_3_gain,
pod_set_band_3_gain);
-static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUSR | S_IRUGO,
pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
-static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUSR | S_IRUGO,
pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
-static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain,
+static DEVICE_ATTR(band_4_gain, S_IWUSR | S_IRUGO, pod_get_band_4_gain,
pod_set_band_4_gain);
-static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUSR | S_IRUGO,
pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable,
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index 4304dfe6c166..ab67e889d2c4 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -350,9 +350,9 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
return count;
}
-static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_transmit, S_IWUSR | S_IRUGO,
midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
-static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_mask_receive, S_IWUSR | S_IRUGO,
midi_get_midi_mask_receive, midi_set_midi_mask_receive);
/* MIDI device destructor */
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index e54770e34d2e..b9c55f9eb501 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -79,9 +79,9 @@ static ssize_t pcm_set_impulse_period(struct device *dev,
return count;
}
-static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume,
+static DEVICE_ATTR(impulse_volume, S_IWUSR | S_IRUGO, pcm_get_impulse_volume,
pcm_set_impulse_volume);
-static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period,
+static DEVICE_ATTR(impulse_period, S_IWUSR | S_IRUGO, pcm_get_impulse_period,
pcm_set_impulse_period);
#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index 22e2cedcacf7..d9b30212585c 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -1051,48 +1051,48 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
#undef GET_SYSTEM_PARAM
/* POD special files: */
-static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel,
+static DEVICE_ATTR(channel, S_IWUSR | S_IRUGO, pod_get_channel,
pod_set_channel);
static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
-static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
-static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf,
+static DEVICE_ATTR(dump, S_IWUSR | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUSR | S_IRUGO, pod_get_dump_buf,
pod_set_dump_buf);
-static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO,
pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level,
+static DEVICE_ATTR(monitor_level, S_IWUSR | S_IRUGO, pod_get_monitor_level,
pod_set_monitor_level);
static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
-static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUSR, line6_nop_read,
pod_set_retrieve_amp_setup);
-static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read,
pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read,
pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing,
+static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing,
pod_set_routing);
static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read,
pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read,
pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read,
+static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read,
pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq,
+static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq,
pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute,
+static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute,
pod_set_tuner_mute);
static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
#ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
#endif
/* control info callback */
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index 6a10b0f9749a..879e6992bbc6 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -154,9 +154,9 @@ static ssize_t toneport_set_led_green(struct device *dev,
return count;
}
-static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_red, S_IWUSR | S_IRUGO, line6_nop_read,
toneport_set_led_red);
-static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read,
+static DEVICE_ATTR(led_green, S_IWUSR | S_IRUGO, line6_nop_read,
toneport_set_led_green);
static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index 894eee7f2317..81241cdf1be9 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -549,21 +549,21 @@ static ssize_t variax_set_raw2(struct device *dev,
#endif
/* Variax workbench special files: */
-static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model,
+static DEVICE_ATTR(model, S_IWUSR | S_IRUGO, variax_get_model,
variax_set_model);
-static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume,
+static DEVICE_ATTR(volume, S_IWUSR | S_IRUGO, variax_get_volume,
variax_set_volume);
-static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(tone, S_IWUSR | S_IRUGO, variax_get_tone, variax_set_tone);
static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
-static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active,
+static DEVICE_ATTR(active, S_IWUSR | S_IRUGO, variax_get_active,
variax_set_active);
static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
#ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
-static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUSR, line6_nop_read, variax_set_raw2);
#endif
/*
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c
index d746715d3d89..d83bec876d2e 100644
--- a/drivers/staging/quickstart/quickstart.c
+++ b/drivers/staging/quickstart/quickstart.c
@@ -355,7 +355,6 @@ static int quickstart_acpi_remove(struct acpi_device *device, int type)
static void quickstart_exit(void)
{
input_unregister_device(quickstart_input);
- input_free_device(quickstart_input);
device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
device_remove_file(&pf_device->dev, &dev_attr_buttons);
@@ -375,6 +374,7 @@ static int __init quickstart_init_input(void)
{
struct quickstart_btn **ptr = &quickstart_data.btn_lst;
int count;
+ int ret;
quickstart_input = input_allocate_device();
@@ -391,7 +391,13 @@ static int __init quickstart_init_input(void)
ptr = &((*ptr)->next);
}
- return input_register_device(quickstart_input);
+ ret = input_register_device(quickstart_input);
+ if (ret) {
+ input_free_device(quickstart_input);
+ return ret;
+ }
+
+ return 0;
}
static int __init quickstart_init(void)
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
index ddacfc6c4861..cd15daae5412 100644
--- a/drivers/staging/rt2860/usb_main_dev.c
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -182,6 +182,7 @@ struct usb_device_id rtusb_usb_id[] = {
{USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */
{USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */
{USB_DEVICE(0x2019, 0xED14)}, /* Planex Communications, Inc. */
+ {USB_DEVICE(0x0411, 0x015D)}, /* Buffalo Airstation WLI-UC-GN */
{} /* Terminating entry */
};
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
index 46000d72f4c4..3bdf9b31cc4e 100644
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -264,8 +264,12 @@ HwHSSIThreeWire(
udelay(10);
}
- if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
- panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
+ if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
+ printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
+ " %#X RE|WE bits are not clear!!\n", u1bTmp);
+ dump_stack();
+ return 0;
+ }
/* RTL8187S HSSI Read/Write Function */
u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
@@ -298,13 +302,23 @@ HwHSSIThreeWire(
int idx;
int ByteCnt = nDataBufBitCnt / 8;
/* printk("%d\n",nDataBufBitCnt); */
- if ((nDataBufBitCnt % 8) != 0)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
- nDataBufBitCnt);
+ if ((nDataBufBitCnt % 8) != 0) {
+ printk(KERN_ERR "rtl8187se: "
+ "HwThreeWire(): nDataBufBitCnt(%d)"
+ " should be multiple of 8!!!\n",
+ nDataBufBitCnt);
+ dump_stack();
+ nDataBufBitCnt += 8;
+ nDataBufBitCnt &= ~7;
+ }
- if (nDataBufBitCnt > 64)
- panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
- nDataBufBitCnt);
+ if (nDataBufBitCnt > 64) {
+ printk(KERN_ERR "rtl8187se: HwThreeWire():"
+ " nDataBufBitCnt(%d) should <= 64!!!\n",
+ nDataBufBitCnt);
+ dump_stack();
+ nDataBufBitCnt = 64;
+ }
for (idx = 0; idx < ByteCnt; idx++)
write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index d1674cd282dc..831d81e0e429 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kref.h>
-#include <linux/smp_lock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/usb.h>
diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c
index f6569dce3012..0e9483bbabe1 100644
--- a/drivers/staging/rtl8712/usb_halinit.c
+++ b/drivers/staging/rtl8712/usb_halinit.c
@@ -37,7 +37,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter)
{
u8 val8 = 0;
u8 ret = _SUCCESS;
- u8 PollingCnt = 20;
+ int PollingCnt = 20;
struct registry_priv *pregistrypriv = &padapter->registrypriv;
if (pregistrypriv->chip_version == RTL8712_FPGA) {
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c
index eb44b60e1eb5..ac2bf11e1119 100644
--- a/drivers/staging/samsung-laptop/samsung-laptop.c
+++ b/drivers/staging/samsung-laptop/samsung-laptop.c
@@ -356,7 +356,7 @@ static ssize_t set_silent_state(struct device *dev,
}
return count;
}
-static DEVICE_ATTR(silent, S_IWUGO | S_IRUGO,
+static DEVICE_ATTR(silent, S_IWUSR | S_IRUGO,
get_silent_state, set_silent_state);
diff --git a/drivers/staging/speakup/buffers.c b/drivers/staging/speakup/buffers.c
index b7b60d5e8660..a2db956edd54 100644
--- a/drivers/staging/speakup/buffers.c
+++ b/drivers/staging/speakup/buffers.c
@@ -1,5 +1,4 @@
#include <linux/console.h>
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/wait.h>
diff --git a/drivers/staging/speakup/fakekey.c b/drivers/staging/speakup/fakekey.c
index adb93f21c0d6..65b231178f05 100644
--- a/drivers/staging/speakup/fakekey.c
+++ b/drivers/staging/speakup/fakekey.c
@@ -62,7 +62,6 @@ void speakup_remove_virtual_keyboard(void)
{
if (virt_keyboard != NULL) {
input_unregister_device(virt_keyboard);
- input_free_device(virt_keyboard);
virt_keyboard = NULL;
}
}
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c
index c7932da03c56..63a9d0adf32d 100644
--- a/drivers/staging/spectra/ffsport.c
+++ b/drivers/staging/spectra/ffsport.c
@@ -656,7 +656,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
/* Here we force report 512 byte hardware sector size to Kernel */
blk_queue_logical_block_size(dev->queue, 512);
- blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
+ blk_queue_flush(dev->queue, REQ_FLUSH);
dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
if (IS_ERR(dev->thread)) {
diff --git a/drivers/staging/stradis/Kconfig b/drivers/staging/stradis/Kconfig
index 92e891141896..02f0fc504cf5 100644
--- a/drivers/staging/stradis/Kconfig
+++ b/drivers/staging/stradis/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_STRADIS
tristate "Stradis 4:2:2 MPEG-2 video driver (DEPRECATED)"
- depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS
+ depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && VIRT_TO_BUS && BKL
help
Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
driver for PCI. There is a product page at
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 664e6038090d..b143258f094a 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -545,7 +545,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
/* Load tuner module */
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tuner", dev->tuner_addr, NULL);
+ "tuner", dev->tuner_addr, NULL);
memset(&tun_setup, 0, sizeof(tun_setup));
tun_setup.type = dev->tuner_type;
@@ -683,7 +683,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
if (dev->caps.has_tda9874)
v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
- NULL, "tvaudio", I2C_ADDR_TDA9874, NULL);
+ "tvaudio", I2C_ADDR_TDA9874, NULL);
/* register and initialize V4L2 */
rc = tm6000_v4l2_register(dev);
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c
index fed25105970a..b7ac16005265 100644
--- a/drivers/staging/udlfb/udlfb.c
+++ b/drivers/staging/udlfb/udlfb.c
@@ -1441,7 +1441,7 @@ static struct device_attribute fb_device_attrs[] = {
__ATTR_RO(metrics_bytes_identical),
__ATTR_RO(metrics_bytes_sent),
__ATTR_RO(metrics_cpu_kcycles_used),
- __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
+ __ATTR(metrics_reset, S_IWUSR, NULL, metrics_reset_store),
};
/*
diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h
index 9195adf98e14..d0d71f69bc8c 100644
--- a/drivers/staging/winbond/sysdef.h
+++ b/drivers/staging/winbond/sysdef.h
@@ -2,6 +2,9 @@
#ifndef SYS_DEF_H
#define SYS_DEF_H
+
+#include <linux/delay.h>
+
#define WB_LINUX
#define WB_LINUX_WPA_PSK
diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c
index 6c574a994d11..6b3cf00b0ff4 100644
--- a/drivers/staging/zram/zram_sysfs.c
+++ b/drivers/staging/zram/zram_sysfs.c
@@ -189,10 +189,10 @@ static ssize_t mem_used_total_show(struct device *dev,
return sprintf(buf, "%llu\n", val);
}
-static DEVICE_ATTR(disksize, S_IRUGO | S_IWUGO,
+static DEVICE_ATTR(disksize, S_IRUGO | S_IWUSR,
disksize_show, disksize_store);
static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL);
-static DEVICE_ATTR(reset, S_IWUGO, NULL, reset_store);
+static DEVICE_ATTR(reset, S_IWUSR, NULL, reset_store);
static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL);
static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL);
static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL);
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index eaa5d3efa79d..c556ed9db13d 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -554,7 +554,7 @@ EXPORT_SYMBOL(handle_sysrq);
#ifdef CONFIG_INPUT
/* Simple translation table for the SysRq keys */
-static const unsigned char sysrq_xlate[KEY_MAX + 1] =
+static const unsigned char sysrq_xlate[KEY_CNT] =
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
@@ -563,53 +563,129 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] =
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
"\r\000/"; /* 0x60 - 0x6f */
-static bool sysrq_down;
-static int sysrq_alt_use;
-static int sysrq_alt;
-static DEFINE_SPINLOCK(sysrq_event_lock);
+struct sysrq_state {
+ struct input_handle handle;
+ struct work_struct reinject_work;
+ unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
+ unsigned int alt;
+ unsigned int alt_use;
+ bool active;
+ bool need_reinject;
+};
+
+static void sysrq_reinject_alt_sysrq(struct work_struct *work)
+{
+ struct sysrq_state *sysrq =
+ container_of(work, struct sysrq_state, reinject_work);
+ struct input_handle *handle = &sysrq->handle;
+ unsigned int alt_code = sysrq->alt_use;
+
+ if (sysrq->need_reinject) {
+ /* Simulate press and release of Alt + SysRq */
+ input_inject_event(handle, EV_KEY, alt_code, 1);
+ input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
+ input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+
+ input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
+ input_inject_event(handle, EV_KEY, alt_code, 0);
+ input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+ }
+}
-static bool sysrq_filter(struct input_handle *handle, unsigned int type,
- unsigned int code, int value)
+static bool sysrq_filter(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
{
+ struct sysrq_state *sysrq = handle->private;
+ bool was_active = sysrq->active;
bool suppress;
- /* We are called with interrupts disabled, just take the lock */
- spin_lock(&sysrq_event_lock);
+ switch (type) {
- if (type != EV_KEY)
- goto out;
+ case EV_SYN:
+ suppress = false;
+ break;
- switch (code) {
+ case EV_KEY:
+ switch (code) {
- case KEY_LEFTALT:
- case KEY_RIGHTALT:
- if (value)
- sysrq_alt = code;
- else {
- if (sysrq_down && code == sysrq_alt_use)
- sysrq_down = false;
+ case KEY_LEFTALT:
+ case KEY_RIGHTALT:
+ if (!value) {
+ /* One of ALTs is being released */
+ if (sysrq->active && code == sysrq->alt_use)
+ sysrq->active = false;
- sysrq_alt = 0;
+ sysrq->alt = KEY_RESERVED;
+
+ } else if (value != 2) {
+ sysrq->alt = code;
+ sysrq->need_reinject = false;
+ }
+ break;
+
+ case KEY_SYSRQ:
+ if (value == 1 && sysrq->alt != KEY_RESERVED) {
+ sysrq->active = true;
+ sysrq->alt_use = sysrq->alt;
+ /*
+ * If nothing else will be pressed we'll need
+ * to * re-inject Alt-SysRq keysroke.
+ */
+ sysrq->need_reinject = true;
+ }
+
+ /*
+ * Pretend that sysrq was never pressed at all. This
+ * is needed to properly handle KGDB which will try
+ * to release all keys after exiting debugger. If we
+ * do not clear key bit it KGDB will end up sending
+ * release events for Alt and SysRq, potentially
+ * triggering print screen function.
+ */
+ if (sysrq->active)
+ clear_bit(KEY_SYSRQ, handle->dev->key);
+
+ break;
+
+ default:
+ if (sysrq->active && value && value != 2) {
+ sysrq->need_reinject = false;
+ __handle_sysrq(sysrq_xlate[code], true);
+ }
+ break;
}
- break;
- case KEY_SYSRQ:
- if (value == 1 && sysrq_alt) {
- sysrq_down = true;
- sysrq_alt_use = sysrq_alt;
+ suppress = sysrq->active;
+
+ if (!sysrq->active) {
+ /*
+ * If we are not suppressing key presses keep track of
+ * keyboard state so we can release keys that have been
+ * pressed before entering SysRq mode.
+ */
+ if (value)
+ set_bit(code, sysrq->key_down);
+ else
+ clear_bit(code, sysrq->key_down);
+
+ if (was_active)
+ schedule_work(&sysrq->reinject_work);
+
+ } else if (value == 0 &&
+ test_and_clear_bit(code, sysrq->key_down)) {
+ /*
+ * Pass on release events for keys that was pressed before
+ * entering SysRq mode.
+ */
+ suppress = false;
}
break;
default:
- if (sysrq_down && value && value != 2)
- __handle_sysrq(sysrq_xlate[code], true);
+ suppress = sysrq->active;
break;
}
-out:
- suppress = sysrq_down;
- spin_unlock(&sysrq_event_lock);
-
return suppress;
}
@@ -617,28 +693,28 @@ static int sysrq_connect(struct input_handler *handler,
struct input_dev *dev,
const struct input_device_id *id)
{
- struct input_handle *handle;
+ struct sysrq_state *sysrq;
int error;
- sysrq_down = false;
- sysrq_alt = 0;
-
- handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
- if (!handle)
+ sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL);
+ if (!sysrq)
return -ENOMEM;
- handle->dev = dev;
- handle->handler = handler;
- handle->name = "sysrq";
+ INIT_WORK(&sysrq->reinject_work, sysrq_reinject_alt_sysrq);
+
+ sysrq->handle.dev = dev;
+ sysrq->handle.handler = handler;
+ sysrq->handle.name = "sysrq";
+ sysrq->handle.private = sysrq;
- error = input_register_handle(handle);
+ error = input_register_handle(&sysrq->handle);
if (error) {
pr_err("Failed to register input sysrq handler, error %d\n",
error);
goto err_free;
}
- error = input_open_device(handle);
+ error = input_open_device(&sysrq->handle);
if (error) {
pr_err("Failed to open input device, error %d\n", error);
goto err_unregister;
@@ -647,17 +723,20 @@ static int sysrq_connect(struct input_handler *handler,
return 0;
err_unregister:
- input_unregister_handle(handle);
+ input_unregister_handle(&sysrq->handle);
err_free:
- kfree(handle);
+ kfree(sysrq);
return error;
}
static void sysrq_disconnect(struct input_handle *handle)
{
+ struct sysrq_state *sysrq = handle->private;
+
input_close_device(handle);
+ cancel_work_sync(&sysrq->reinject_work);
input_unregister_handle(handle);
- kfree(handle);
+ kfree(sysrq);
}
/*
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index c05c5af5aa04..35480dd57a30 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty)
tty_lock();
+ /* some functions below drop BTM, so we need this bit */
+ set_bit(TTY_HUPPING, &tty->flags);
+
/* inuse_filps is protected by the single tty lock,
this really needs to change if we want to flush the
workqueue with the lock held */
@@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty)
}
spin_unlock(&tty_files_lock);
+ /*
+ * it drops BTM and thus races with reopen
+ * we protect the race by TTY_HUPPING
+ */
tty_ldisc_hangup(tty);
read_lock(&tasklist_lock);
@@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty)
tty->session = NULL;
tty->pgrp = NULL;
tty->ctrl_status = 0;
- set_bit(TTY_HUPPED, &tty->flags);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
/* Account for the p->signal references we killed */
@@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty)
* can't yet guarantee all that.
*/
set_bit(TTY_HUPPED, &tty->flags);
+ clear_bit(TTY_HUPPING, &tty->flags);
tty_ldisc_enable(tty);
tty_unlock();
@@ -1310,7 +1317,9 @@ static int tty_reopen(struct tty_struct *tty)
{
struct tty_driver *driver = tty->driver;
- if (test_bit(TTY_CLOSING, &tty->flags))
+ if (test_bit(TTY_CLOSING, &tty->flags) ||
+ test_bit(TTY_HUPPING, &tty->flags) ||
+ test_bit(TTY_LDISC_CHANGING, &tty->flags))
return -EIO;
if (driver->type == TTY_DRIVER_TYPE_PTY &&
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index d8e96b005023..4214d58276f7 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
/* BTM here locks versus a hangup event */
WARN_ON(!tty_locked());
ret = ld->ops->open(tty);
+ if (ret)
+ clear_bit(TTY_LDISC_OPEN, &tty->flags);
return ret;
}
return 0;
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index a858d2b87b94..51fe1795d5a8 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -3,7 +3,7 @@
*
* Copyright(C) 2005, Benedikt Spranger <b.spranger@linutronix.de>
* Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
- * Copyright(C) 2006, Hans J. Koch <hjk@linutronix.de>
+ * Copyright(C) 2006, Hans J. Koch <hjk@hansjkoch.de>
* Copyright(C) 2006, Greg Kroah-Hartman <greg@kroah.com>
*
* Userspace IO
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
index a8ea2f19a0cc..a84a451159ed 100644
--- a/drivers/uio/uio_cif.c
+++ b/drivers/uio/uio_cif.c
@@ -1,7 +1,7 @@
/*
* UIO Hilscher CIF card driver
*
- * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
* Original code (C) 2005 Benedikt Spranger <b.spranger@linutronix.de>
*
* Licensed under GPL version 2 only.
diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c
index 5a18e9f7b836..5ffdb483b015 100644
--- a/drivers/uio/uio_netx.c
+++ b/drivers/uio/uio_netx.c
@@ -2,7 +2,7 @@
* UIO driver for Hilscher NetX based fieldbus cards (cifX, comX).
* See http://www.hilscher.com for details.
*
- * (C) 2007 Hans J. Koch <hjk@linutronix.de>
+ * (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
* (C) 2008 Manuel Traut <manut@linutronix.de>
*
* Licensed under GPL version 2 only.
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index ea071a5b6eee..44447f54942f 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -2301,7 +2301,7 @@ out:
return ret;
}
-static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);
+static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot);
static ssize_t read_human_status(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -2364,8 +2364,7 @@ out:
return ret;
}
-static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO,
- read_human_status, NULL);
+static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL);
static ssize_t read_delin(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -2397,7 +2396,7 @@ out:
return ret;
}
-static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);
+static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL);
#define UEA_ATTR(name, reset) \
\
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index ddb4dc980923..a3d2e2399655 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -54,7 +54,6 @@
#include <linux/gfp.h>
#include <linux/poll.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/usbdevice_fs.h>
#include <linux/usb/hcd.h>
#include <linux/mutex.h>
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 045bb4b823e1..a7131ad630f9 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -37,7 +37,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/signal.h>
#include <linux/poll.h>
#include <linux/module.h>
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 9fe34fb78ef1..cf6a5423de09 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -19,7 +19,6 @@
#include <linux/errno.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include "usb.h"
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 61800f77dac8..ced846ac4141 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
*/
if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+ if (hcd->self.uses_pio_for_control)
+ return ret;
if (hcd->self.uses_dma) {
urb->setup_dma = dma_map_single(
hcd->self.controller,
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 9819a4cc3b26..b690aa35df9a 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -39,7 +39,6 @@
#include <linux/parser.h>
#include <linux/notifier.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/usb/hcd.h>
#include <asm/byteorder.h>
#include "usb.h"
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index b5e20e873cba..717ff653fa23 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -2017,7 +2017,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
}
} else {
/* gpio_request fail so use -EINVAL for gpio_is_valid */
- ubc->vbus_pin = -EINVAL;
+ udc->vbus_pin = -EINVAL;
}
}
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 4a830df4fc31..484c5ba5450e 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -30,7 +30,6 @@
#include <linux/blkdev.h>
#include <linux/pagemap.h>
#include <asm/unaligned.h>
-#include <linux/smp_lock.h>
#include <linux/usb/composite.h>
#include <linux/usb/functionfs.h>
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 4f891eddd060..598e7e2ab80c 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -25,7 +25,6 @@
#include <linux/cdev.h>
#include <linux/mutex.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/uaccess.h>
#include <linux/wait.h>
#include <linux/usb/g_hid.h>
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 86afdc73322f..6e2599661b5b 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -1067,7 +1067,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci)
&debug_registers_fops))
goto file_error;
- if (!debugfs_create_file("lpm", S_IRUGO|S_IWUGO, ehci->debug_dir, bus,
+ if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus,
&debug_lpm_fops))
goto file_error;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 502a7e6fef42..e9062806d4a2 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1063,10 +1063,11 @@ rescan:
tmp && tmp != qh;
tmp = tmp->qh_next.qh)
continue;
- /* periodic qh self-unlinks on empty */
- if (!tmp)
- goto nogood;
- unlink_async (ehci, qh);
+ /* periodic qh self-unlinks on empty, and a COMPLETING qh
+ * may already be unlinked.
+ */
+ if (tmp)
+ unlink_async(ehci, qh);
/* FALL THROUGH */
case QH_STATE_UNLINK: /* wait for hw to finish? */
case QH_STATE_UNLINK_WAIT:
@@ -1083,7 +1084,6 @@ idle_timeout:
}
/* else FALL THROUGH */
default:
-nogood:
/* caller was supposed to have unlinked any requests;
* that's not our job. just leak this memory.
*/
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index d36e4e75e08d..12f70c302b0b 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -141,6 +141,10 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci)
qh_put (ehci->async);
ehci->async = NULL;
+ if (ehci->dummy)
+ qh_put(ehci->dummy);
+ ehci->dummy = NULL;
+
/* DMA consistent memory and pools */
if (ehci->qtd_pool)
dma_pool_destroy (ehci->qtd_pool);
@@ -227,8 +231,26 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
if (ehci->periodic == NULL) {
goto fail;
}
- for (i = 0; i < ehci->periodic_size; i++)
- ehci->periodic [i] = EHCI_LIST_END(ehci);
+
+ if (ehci->use_dummy_qh) {
+ struct ehci_qh_hw *hw;
+ ehci->dummy = ehci_qh_alloc(ehci, flags);
+ if (!ehci->dummy)
+ goto fail;
+
+ hw = ehci->dummy->hw;
+ hw->hw_next = EHCI_LIST_END(ehci);
+ hw->hw_qtd_next = EHCI_LIST_END(ehci);
+ hw->hw_alt_next = EHCI_LIST_END(ehci);
+ hw->hw_token &= ~QTD_STS_ACTIVE;
+ ehci->dummy->hw = hw;
+
+ for (i = 0; i < ehci->periodic_size; i++)
+ ehci->periodic[i] = ehci->dummy->qh_dma;
+ } else {
+ for (i = 0; i < ehci->periodic_size; i++)
+ ehci->periodic[i] = EHCI_LIST_END(ehci);
+ }
/* software shadow of hardware table */
ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index a1e8d273103f..655f3c9f88bf 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -103,6 +103,19 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
if (retval)
return retval;
+ if ((pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x7808) ||
+ (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x4396)) {
+ /* EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may
+ * read/write memory space which does not belong to it when
+ * there is NULL pointer with T-bit set to 1 in the frame list
+ * table. To avoid the issue, the frame list link pointer
+ * should always contain a valid pointer to a inactive qh.
+ */
+ ehci->use_dummy_qh = 1;
+ ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI "
+ "dummy qh workaround\n");
+ }
+
/* data structure init */
retval = ehci_init(hcd);
if (retval)
@@ -148,6 +161,18 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
if (pdev->revision < 0xa4)
ehci->no_selective_suspend = 1;
break;
+
+ /* MCP89 chips on the MacBookAir3,1 give EPROTO when
+ * fetching device descriptors unless LPM is disabled.
+ * There are also intermittent problems enumerating
+ * devices with PPCD enabled.
+ */
+ case 0x0d9d:
+ ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
+ ehci->has_lpm = 0;
+ ehci->has_ppcd = 0;
+ ehci->command &= ~CMD_PPCEE;
+ break;
}
break;
case PCI_VENDOR_ID_VIA:
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index a92526d6e5ae..d9f78eb26572 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -98,7 +98,14 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
*/
*prev_p = *periodic_next_shadow(ehci, &here,
Q_NEXT_TYPE(ehci, *hw_p));
- *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p));
+
+ if (!ehci->use_dummy_qh ||
+ *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p))
+ != EHCI_LIST_END(ehci))
+ *hw_p = *shadow_next_periodic(ehci, &here,
+ Q_NEXT_TYPE(ehci, *hw_p));
+ else
+ *hw_p = ehci->dummy->qh_dma;
}
/* how many of the uframe's 125 usecs are allocated? */
@@ -2335,7 +2342,11 @@ restart:
* pointer for much longer, if at all.
*/
*q_p = q.itd->itd_next;
- *hw_p = q.itd->hw_next;
+ if (!ehci->use_dummy_qh ||
+ q.itd->hw_next != EHCI_LIST_END(ehci))
+ *hw_p = q.itd->hw_next;
+ else
+ *hw_p = ehci->dummy->qh_dma;
type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
wmb();
modified = itd_complete (ehci, q.itd);
@@ -2368,7 +2379,11 @@ restart:
* URB completion.
*/
*q_p = q.sitd->sitd_next;
- *hw_p = q.sitd->hw_next;
+ if (!ehci->use_dummy_qh ||
+ q.sitd->hw_next != EHCI_LIST_END(ehci))
+ *hw_p = q.sitd->hw_next;
+ else
+ *hw_p = ehci->dummy->qh_dma;
type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
wmb();
modified = sitd_complete (ehci, q.sitd);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index bde823f704e9..ba8eab366b82 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -73,6 +73,7 @@ struct ehci_hcd { /* one per controller */
/* async schedule support */
struct ehci_qh *async;
+ struct ehci_qh *dummy; /* For AMD quirk use */
struct ehci_qh *reclaim;
unsigned scanning : 1;
@@ -131,6 +132,7 @@ struct ehci_hcd { /* one per controller */
unsigned need_io_watchdog:1;
unsigned broken_periodic:1;
unsigned fs_i_thresh:1; /* Intel iso scheduling */
+ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 8196fa11fec4..43a39eb56cc6 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -70,7 +70,6 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/list.h>
@@ -2684,7 +2683,7 @@ static int __devexit isp1362_remove(struct platform_device *pdev)
return 0;
}
-static int __init isp1362_probe(struct platform_device *pdev)
+static int __devinit isp1362_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct isp1362_hcd *isp1362_hcd;
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 6e7fb5f38db6..ee60cd3ea642 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
-#include <linux/smp_lock.h>
#include <asm/io.h>
#include "uhci-hcd.h"
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index fef5a1f9d483..5d963e350494 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -229,6 +229,13 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id)
static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex,
u32 __iomem *addr, u32 port_status)
{
+ /* Don't allow the USB core to disable SuperSpeed ports. */
+ if (xhci->port_array[wIndex] == 0x03) {
+ xhci_dbg(xhci, "Ignoring request to disable "
+ "SuperSpeed port.\n");
+ return;
+ }
+
/* Write 1 to disable the port */
xhci_writel(xhci, port_status | PORT_PE, addr);
port_status = xhci_readl(xhci, addr);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 202770676da3..0fae58ef8afe 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
if (udev->speed == USB_SPEED_SUPER)
return ep->ss_ep_comp.wBytesPerInterval;
- max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+ max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
/* A 0 in max burst means 1 transfer per ESIT */
return max_packet * (max_burst + 1);
@@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
/* Fall through */
case USB_SPEED_FULL:
case USB_SPEED_LOW:
- max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+ max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize);
ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
break;
default:
@@ -1443,6 +1443,13 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->dcbaa = NULL;
scratchpad_free(xhci);
+
+ xhci->num_usb2_ports = 0;
+ xhci->num_usb3_ports = 0;
+ kfree(xhci->usb2_ports);
+ kfree(xhci->usb3_ports);
+ kfree(xhci->port_array);
+
xhci->page_size = 0;
xhci->page_shift = 0;
xhci->bus_suspended = 0;
@@ -1627,6 +1634,161 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
&xhci->ir_set->erst_dequeue);
}
+static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
+ u32 __iomem *addr, u8 major_revision)
+{
+ u32 temp, port_offset, port_count;
+ int i;
+
+ if (major_revision > 0x03) {
+ xhci_warn(xhci, "Ignoring unknown port speed, "
+ "Ext Cap %p, revision = 0x%x\n",
+ addr, major_revision);
+ /* Ignoring port protocol we can't understand. FIXME */
+ return;
+ }
+
+ /* Port offset and count in the third dword, see section 7.2 */
+ temp = xhci_readl(xhci, addr + 2);
+ port_offset = XHCI_EXT_PORT_OFF(temp);
+ port_count = XHCI_EXT_PORT_COUNT(temp);
+ xhci_dbg(xhci, "Ext Cap %p, port offset = %u, "
+ "count = %u, revision = 0x%x\n",
+ addr, port_offset, port_count, major_revision);
+ /* Port count includes the current port offset */
+ if (port_offset == 0 || (port_offset + port_count - 1) > num_ports)
+ /* WTF? "Valid values are ‘1’ to MaxPorts" */
+ return;
+ port_offset--;
+ for (i = port_offset; i < (port_offset + port_count); i++) {
+ /* Duplicate entry. Ignore the port if the revisions differ. */
+ if (xhci->port_array[i] != 0) {
+ xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
+ " port %u\n", addr, i);
+ xhci_warn(xhci, "Port was marked as USB %u, "
+ "duplicated as USB %u\n",
+ xhci->port_array[i], major_revision);
+ /* Only adjust the roothub port counts if we haven't
+ * found a similar duplicate.
+ */
+ if (xhci->port_array[i] != major_revision &&
+ xhci->port_array[i] != (u8) -1) {
+ if (xhci->port_array[i] == 0x03)
+ xhci->num_usb3_ports--;
+ else
+ xhci->num_usb2_ports--;
+ xhci->port_array[i] = (u8) -1;
+ }
+ /* FIXME: Should we disable the port? */
+ }
+ xhci->port_array[i] = major_revision;
+ if (major_revision == 0x03)
+ xhci->num_usb3_ports++;
+ else
+ xhci->num_usb2_ports++;
+ }
+ /* FIXME: Should we disable ports not in the Extended Capabilities? */
+}
+
+/*
+ * Scan the Extended Capabilities for the "Supported Protocol Capabilities" that
+ * specify what speeds each port is supposed to be. We can't count on the port
+ * speed bits in the PORTSC register being correct until a device is connected,
+ * but we need to set up the two fake roothubs with the correct number of USB
+ * 3.0 and USB 2.0 ports at host controller initialization time.
+ */
+static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
+{
+ u32 __iomem *addr;
+ u32 offset;
+ unsigned int num_ports;
+ int i, port_index;
+
+ addr = &xhci->cap_regs->hcc_params;
+ offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
+ if (offset == 0) {
+ xhci_err(xhci, "No Extended Capability registers, "
+ "unable to set up roothub.\n");
+ return -ENODEV;
+ }
+
+ num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
+ xhci->port_array = kzalloc(sizeof(*xhci->port_array)*num_ports, flags);
+ if (!xhci->port_array)
+ return -ENOMEM;
+
+ /*
+ * For whatever reason, the first capability offset is from the
+ * capability register base, not from the HCCPARAMS register.
+ * See section 5.3.6 for offset calculation.
+ */
+ addr = &xhci->cap_regs->hc_capbase + offset;
+ while (1) {
+ u32 cap_id;
+
+ cap_id = xhci_readl(xhci, addr);
+ if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
+ xhci_add_in_port(xhci, num_ports, addr,
+ (u8) XHCI_EXT_PORT_MAJOR(cap_id));
+ offset = XHCI_EXT_CAPS_NEXT(cap_id);
+ if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports)
+ == num_ports)
+ break;
+ /*
+ * Once you're into the Extended Capabilities, the offset is
+ * always relative to the register holding the offset.
+ */
+ addr += offset;
+ }
+
+ if (xhci->num_usb2_ports == 0 && xhci->num_usb3_ports == 0) {
+ xhci_warn(xhci, "No ports on the roothubs?\n");
+ return -ENODEV;
+ }
+ xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n",
+ xhci->num_usb2_ports, xhci->num_usb3_ports);
+ /*
+ * Note we could have all USB 3.0 ports, or all USB 2.0 ports.
+ * Not sure how the USB core will handle a hub with no ports...
+ */
+ if (xhci->num_usb2_ports) {
+ xhci->usb2_ports = kmalloc(sizeof(*xhci->usb2_ports)*
+ xhci->num_usb2_ports, flags);
+ if (!xhci->usb2_ports)
+ return -ENOMEM;
+
+ port_index = 0;
+ for (i = 0; i < num_ports; i++)
+ if (xhci->port_array[i] != 0x03) {
+ xhci->usb2_ports[port_index] =
+ &xhci->op_regs->port_status_base +
+ NUM_PORT_REGS*i;
+ xhci_dbg(xhci, "USB 2.0 port at index %u, "
+ "addr = %p\n", i,
+ xhci->usb2_ports[port_index]);
+ port_index++;
+ }
+ }
+ if (xhci->num_usb3_ports) {
+ xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)*
+ xhci->num_usb3_ports, flags);
+ if (!xhci->usb3_ports)
+ return -ENOMEM;
+
+ port_index = 0;
+ for (i = 0; i < num_ports; i++)
+ if (xhci->port_array[i] == 0x03) {
+ xhci->usb3_ports[port_index] =
+ &xhci->op_regs->port_status_base +
+ NUM_PORT_REGS*i;
+ xhci_dbg(xhci, "USB 3.0 port at index %u, "
+ "addr = %p\n", i,
+ xhci->usb3_ports[port_index]);
+ port_index++;
+ }
+ }
+ return 0;
+}
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
{
@@ -1809,6 +1971,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
if (scratchpad_alloc(xhci, flags))
goto fail;
+ if (xhci_setup_port_arrays(xhci, flags))
+ goto fail;
return 0;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9f3115e729b1..df558f6f84e3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2104,7 +2104,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
if (!(status & STS_EINT)) {
spin_unlock(&xhci->lock);
- xhci_warn(xhci, "Spurious interrupt.\n");
return IRQ_NONE;
}
xhci_dbg(xhci, "op reg status = %08x\n", status);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 5d7d4e951ea4..45e4a3108cc3 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -577,6 +577,65 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
}
+static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
+{
+ u64 val_64;
+
+ /* step 2: initialize command ring buffer */
+ val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+ val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
+ (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
+ xhci->cmd_ring->dequeue) &
+ (u64) ~CMD_RING_RSVD_BITS) |
+ xhci->cmd_ring->cycle_state;
+ xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n",
+ (long unsigned long) val_64);
+ xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
+}
+
+/*
+ * The whole command ring must be cleared to zero when we suspend the host.
+ *
+ * The host doesn't save the command ring pointer in the suspend well, so we
+ * need to re-program it on resume. Unfortunately, the pointer must be 64-byte
+ * aligned, because of the reserved bits in the command ring dequeue pointer
+ * register. Therefore, we can't just set the dequeue pointer back in the
+ * middle of the ring (TRBs are 16-byte aligned).
+ */
+static void xhci_clear_command_ring(struct xhci_hcd *xhci)
+{
+ struct xhci_ring *ring;
+ struct xhci_segment *seg;
+
+ ring = xhci->cmd_ring;
+ seg = ring->deq_seg;
+ do {
+ memset(seg->trbs, 0, SEGMENT_SIZE);
+ seg = seg->next;
+ } while (seg != ring->deq_seg);
+
+ /* Reset the software enqueue and dequeue pointers */
+ ring->deq_seg = ring->first_seg;
+ ring->dequeue = ring->first_seg->trbs;
+ ring->enq_seg = ring->deq_seg;
+ ring->enqueue = ring->dequeue;
+
+ /*
+ * Ring is now zeroed, so the HW should look for change of ownership
+ * when the cycle bit is set to 1.
+ */
+ ring->cycle_state = 1;
+
+ /*
+ * Reset the hardware dequeue pointer.
+ * Yes, this will need to be re-written after resume, but we're paranoid
+ * and want to make sure the hardware doesn't access bogus memory
+ * because, say, the BIOS or an SMI started the host without changing
+ * the command ring pointers.
+ */
+ xhci_set_cmd_ring_deq(xhci);
+}
+
/*
* Stop HC (not bus-specific)
*
@@ -604,6 +663,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT;
}
+ xhci_clear_command_ring(xhci);
/* step 3: save registers */
xhci_save_registers(xhci);
@@ -635,7 +695,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
u32 command, temp = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci);
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
- u64 val_64;
int old_state, retval;
old_state = hcd->state;
@@ -648,15 +707,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
/* step 1: restore register */
xhci_restore_registers(xhci);
/* step 2: initialize command ring buffer */
- val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
- val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
- (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
- xhci->cmd_ring->dequeue) &
- (u64) ~CMD_RING_RSVD_BITS) |
- xhci->cmd_ring->cycle_state;
- xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n",
- (long unsigned long) val_64);
- xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
+ xhci_set_cmd_ring_deq(xhci);
/* step 3: restore state and start state*/
/* step 3: set CRS flag */
command = xhci_readl(xhci, &xhci->op_regs->command);
@@ -714,6 +765,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
return retval;
}
+ spin_unlock_irq(&xhci->lock);
/* Re-setup MSI-X */
if (hcd->irq)
free_irq(hcd->irq, hcd);
@@ -736,6 +788,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
hcd->irq = pdev->irq;
}
+ spin_lock_irq(&xhci->lock);
/* step 4: set Run/Stop bit */
command = xhci_readl(xhci, &xhci->op_regs->command);
command |= CMD_RUN;
@@ -1496,6 +1549,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
cmd_completion = command->completion;
cmd_status = &command->status;
command->command_trb = xhci->cmd_ring->enqueue;
+
+ /* Enqueue pointer can be left pointing to the link TRB,
+ * we must handle that
+ */
+ if ((command->command_trb->link.control & TRB_TYPE_BITMASK)
+ == TRB_TYPE(TRB_LINK))
+ command->command_trb =
+ xhci->cmd_ring->enq_seg->next->trbs;
+
list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
} else {
in_ctx = virt_dev->in_ctx;
@@ -2219,6 +2281,15 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
/* Attempt to submit the Reset Device command to the command ring */
spin_lock_irqsave(&xhci->lock, flags);
reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
+
+ /* Enqueue pointer can be left pointing to the link TRB,
+ * we must handle that
+ */
+ if ((reset_device_cmd->command_trb->link.control & TRB_TYPE_BITMASK)
+ == TRB_TYPE(TRB_LINK))
+ reset_device_cmd->command_trb =
+ xhci->cmd_ring->enq_seg->next->trbs;
+
list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
ret = xhci_queue_reset_device(xhci, slot_id);
if (ret) {
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 93d3bf4d213c..170c367112d2 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -454,6 +454,24 @@ struct xhci_doorbell_array {
/**
+ * struct xhci_protocol_caps
+ * @revision: major revision, minor revision, capability ID,
+ * and next capability pointer.
+ * @name_string: Four ASCII characters to say which spec this xHC
+ * follows, typically "USB ".
+ * @port_info: Port offset, count, and protocol-defined information.
+ */
+struct xhci_protocol_caps {
+ u32 revision;
+ u32 name_string;
+ u32 port_info;
+};
+
+#define XHCI_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff)
+#define XHCI_EXT_PORT_OFF(x) ((x) & 0xff)
+#define XHCI_EXT_PORT_COUNT(x) (((x) >> 8) & 0xff)
+
+/**
* struct xhci_container_ctx
* @type: Type of context. Used to calculated offsets to contained contexts.
* @size: Size of the context data
@@ -621,6 +639,11 @@ struct xhci_ep_ctx {
#define MAX_PACKET_MASK (0xffff << 16)
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
+/* Get max packet size from ep desc. Bit 10..0 specify the max packet size.
+ * USB2.0 spec 9.6.6.
+ */
+#define GET_MAX_PACKET(p) ((p) & 0x7ff)
+
/* tx_info bitmasks */
#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff)
#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16)
@@ -1235,6 +1258,14 @@ struct xhci_hcd {
u32 suspended_ports[8]; /* which ports are
suspended */
unsigned long resume_done[MAX_HC_PORTS];
+ /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */
+ u8 *port_array;
+ /* Array of pointers to USB 3.0 PORTSC registers */
+ u32 __iomem **usb3_ports;
+ unsigned int num_usb3_ports;
+ /* Array of pointers to USB 2.0 PORTSC registers */
+ u32 __iomem **usb2_ports;
+ unsigned int num_usb2_ports;
};
/* For testing purposes */
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 5a47805d9580..c90c89dc0003 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -364,7 +364,7 @@ static int mts_scsi_host_reset(struct scsi_cmnd *srb)
}
static int
-mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback);
+mts_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *srb);
static void mts_transfer_cleanup( struct urb *transfer );
static void mts_do_sg(struct urb * transfer);
@@ -573,7 +573,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
static int
-mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
+mts_scsi_queuecommand_lck(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
{
struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
int err = 0;
@@ -626,6 +626,8 @@ out:
return err;
}
+static DEF_SCSI_QCMD(mts_scsi_queuecommand)
+
static struct scsi_host_template mts_scsi_host_template = {
.module = THIS_MODULE,
.name = "microtekX6",
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c
index 2f43c57743c9..9251773ecef4 100644
--- a/drivers/usb/misc/cypress_cy7c63.c
+++ b/drivers/usb/misc/cypress_cy7c63.c
@@ -196,11 +196,9 @@ static ssize_t get_port1_handler(struct device *dev,
return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1);
}
-static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO,
- get_port0_handler, set_port0_handler);
+static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR, get_port0_handler, set_port0_handler);
-static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO,
- get_port1_handler, set_port1_handler);
+static DEVICE_ATTR(port1, S_IRUGO | S_IWUSR, get_port1_handler, set_port1_handler);
static int cypress_probe(struct usb_interface *interface,
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
index d77aba46ae85..f63776a48e2a 100644
--- a/drivers/usb/misc/trancevibrator.c
+++ b/drivers/usb/misc/trancevibrator.c
@@ -86,7 +86,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
return count;
}
-static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed);
+static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed);
static int tv_probe(struct usb_interface *interface,
const struct usb_device_id *id)
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index 63da2c3c838f..c96f51de1696 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -94,7 +94,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
change_color(led); \
return count; \
} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value);
show_set(blue);
show_set(red);
show_set(green);
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
index de8ef945b536..417b8f207e8b 100644
--- a/drivers/usb/misc/usbsevseg.c
+++ b/drivers/usb/misc/usbsevseg.c
@@ -192,7 +192,7 @@ static ssize_t set_attr_##name(struct device *dev, \
\
return count; \
} \
-static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name);
+static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name);
static ssize_t show_attr_text(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -223,7 +223,7 @@ static ssize_t set_attr_text(struct device *dev,
return count;
}
-static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text);
+static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text);
static ssize_t show_attr_decimals(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -272,8 +272,7 @@ static ssize_t set_attr_decimals(struct device *dev,
return count;
}
-static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO,
- show_attr_decimals, set_attr_decimals);
+static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals);
static ssize_t show_attr_textmode(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -319,8 +318,7 @@ static ssize_t set_attr_textmode(struct device *dev,
return -EINVAL;
}
-static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO,
- show_attr_textmode, set_attr_textmode);
+static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode);
MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered);
diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index 719c6180b31f..ac5bfd619e62 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -536,6 +536,7 @@ static const struct file_operations yurex_fops = {
.open = yurex_open,
.release = yurex_release,
.fasync = yurex_fasync,
+ .llseek = default_llseek,
};
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 44cb37b5a4dc..c436e1e2c3b6 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -15,7 +15,6 @@
#include <linux/poll.h>
#include <linux/compat.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c
index 8ec94f15a738..e5ce42bd316e 100644
--- a/drivers/usb/mon/mon_stat.c
+++ b/drivers/usb/mon/mon_stat.c
@@ -11,7 +11,6 @@
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include "usb_mon.h"
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index e6669fc3b804..99beebce8550 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2116,12 +2116,15 @@ bad_config:
* Otherwise, wait till the gadget driver hooks up.
*/
if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
+ struct usb_hcd *hcd = musb_to_hcd(musb);
+
MUSB_HST_MODE(musb);
musb->xceiv->default_a = 1;
musb->xceiv->state = OTG_STATE_A_IDLE;
status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
+ hcd->self.uses_pio_for_control = 1;
DBG(1, "%s mode, status %d, devctl %02x %c\n",
"HOST", status,
musb_readb(musb->mregs, MUSB_DEVCTL),
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 36cfd060dbe5..9d6ade82b9f2 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -92,6 +92,59 @@
/* ----------------------------------------------------------------------- */
+/* Maps the buffer to dma */
+
+static inline void map_dma_buffer(struct musb_request *request,
+ struct musb *musb)
+{
+ if (request->request.dma == DMA_ADDR_INVALID) {
+ request->request.dma = dma_map_single(
+ musb->controller,
+ request->request.buf,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ request->mapped = 1;
+ } else {
+ dma_sync_single_for_device(musb->controller,
+ request->request.dma,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ request->mapped = 0;
+ }
+}
+
+/* Unmap the buffer from dma and maps it back to cpu */
+static inline void unmap_dma_buffer(struct musb_request *request,
+ struct musb *musb)
+{
+ if (request->request.dma == DMA_ADDR_INVALID) {
+ DBG(20, "not unmapping a never mapped buffer\n");
+ return;
+ }
+ if (request->mapped) {
+ dma_unmap_single(musb->controller,
+ request->request.dma,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ request->request.dma = DMA_ADDR_INVALID;
+ request->mapped = 0;
+ } else {
+ dma_sync_single_for_cpu(musb->controller,
+ request->request.dma,
+ request->request.length,
+ request->tx
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+
+ }
+}
+
/*
* Immediately complete a request.
*
@@ -119,24 +172,8 @@ __acquires(ep->musb->lock)
ep->busy = 1;
spin_unlock(&musb->lock);
- if (is_dma_capable()) {
- if (req->mapped) {
- dma_unmap_single(musb->controller,
- req->request.dma,
- req->request.length,
- req->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- req->request.dma = DMA_ADDR_INVALID;
- req->mapped = 0;
- } else if (req->request.dma != DMA_ADDR_INVALID)
- dma_sync_single_for_cpu(musb->controller,
- req->request.dma,
- req->request.length,
- req->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- }
+ if (is_dma_capable() && ep->dma)
+ unmap_dma_buffer(req, musb);
if (request->status == 0)
DBG(5, "%s done request %p, %d/%d\n",
ep->end_point.name, request,
@@ -395,6 +432,13 @@ static void txstate(struct musb *musb, struct musb_request *req)
#endif
if (!use_dma) {
+ /*
+ * Unmap the dma buffer back to cpu if dma channel
+ * programming fails
+ */
+ if (is_dma_capable() && musb_ep->dma)
+ unmap_dma_buffer(req, musb);
+
musb_write_fifo(musb_ep->hw_ep, fifo_count,
(u8 *) (request->buf + request->actual));
request->actual += fifo_count;
@@ -713,6 +757,21 @@ static void rxstate(struct musb *musb, struct musb_request *req)
return;
}
#endif
+ /*
+ * Unmap the dma buffer back to cpu if dma channel
+ * programming fails. This buffer is mapped if the
+ * channel allocation is successful
+ */
+ if (is_dma_capable() && musb_ep->dma) {
+ unmap_dma_buffer(req, musb);
+
+ /*
+ * Clear DMAENAB and AUTOCLEAR for the
+ * PIO mode transfer
+ */
+ csr &= ~(MUSB_RXCSR_DMAENAB | MUSB_RXCSR_AUTOCLEAR);
+ musb_writew(epio, MUSB_RXCSR, csr);
+ }
musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
(request->buf + request->actual));
@@ -837,7 +896,9 @@ void musb_g_rx(struct musb *musb, u8 epnum)
if (!request)
return;
}
+#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
exit:
+#endif
/* Analyze request */
rxstate(musb, to_musb_request(request));
}
@@ -1150,26 +1211,9 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
request->epnum = musb_ep->current_epnum;
request->tx = musb_ep->is_in;
- if (is_dma_capable() && musb_ep->dma) {
- if (request->request.dma == DMA_ADDR_INVALID) {
- request->request.dma = dma_map_single(
- musb->controller,
- request->request.buf,
- request->request.length,
- request->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- request->mapped = 1;
- } else {
- dma_sync_single_for_device(musb->controller,
- request->request.dma,
- request->request.length,
- request->tx
- ? DMA_TO_DEVICE
- : DMA_FROM_DEVICE);
- request->mapped = 0;
- }
- } else
+ if (is_dma_capable() && musb_ep->dma)
+ map_dma_buffer(request, musb);
+ else
request->mapped = 0;
spin_lock_irqsave(&musb->lock, lockflags);
@@ -1789,6 +1833,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
spin_unlock_irqrestore(&musb->lock, flags);
if (is_otg_enabled(musb)) {
+ struct usb_hcd *hcd = musb_to_hcd(musb);
+
DBG(3, "OTG startup...\n");
/* REVISIT: funcall to other code, which also
@@ -1803,6 +1849,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
musb->gadget_driver = NULL;
musb->g.dev.driver = NULL;
spin_unlock_irqrestore(&musb->lock, flags);
+ } else {
+ hcd->self.uses_pio_for_control = 1;
}
}
}
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
index bdc3ea66be69..9fea48264fa2 100644
--- a/drivers/usb/otg/langwell_otg.c
+++ b/drivers/usb/otg/langwell_otg.c
@@ -1896,7 +1896,7 @@ set_a_bus_req(struct device *dev, struct device_attribute *attr,
}
return count;
}
-static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req);
+static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req);
static ssize_t
get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
@@ -1942,8 +1942,7 @@ set_a_bus_drop(struct device *dev, struct device_attribute *attr,
}
return count;
}
-static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO,
- get_a_bus_drop, set_a_bus_drop);
+static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop);
static ssize_t
get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
@@ -1988,7 +1987,7 @@ set_b_bus_req(struct device *dev, struct device_attribute *attr,
}
return count;
}
-static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req);
+static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req);
static ssize_t
set_a_clr_err(struct device *dev, struct device_attribute *attr,
@@ -2012,7 +2011,7 @@ set_a_clr_err(struct device *dev, struct device_attribute *attr,
}
return count;
}
-static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err);
+static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err);
static struct attribute *inputs_attrs[] = {
&dev_attr_a_bus_req.attr,
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 76f8b3556672..6a50965e23f2 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -201,6 +201,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
+ { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
@@ -696,6 +697,7 @@ static struct usb_device_id id_table_combined [] = {
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) },
+ { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 263f62551197..1286f1e23d8c 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -114,6 +114,9 @@
/* Lenz LI-USB Computer Interface. */
#define FTDI_LENZ_LIUSB_PID 0xD780
+/* Vardaan Enterprises Serial Interface VEUSB422R3 */
+#define FTDI_VARDAAN_PID 0xF070
+
/*
* Xsens Technologies BV products (http://www.xsens.com).
*/
@@ -721,6 +724,7 @@
*/
#define RTSYSTEMS_VID 0x2100 /* Vendor ID */
#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */
+#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */
/*
* Bayer Ascensia Contour blood glucose meter USB-converter cable.
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index e64da74bdcc5..6954de50c0ff 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -21,7 +21,6 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
@@ -52,6 +51,7 @@ static struct usb_driver usb_serial_driver = {
.suspend = usb_serial_suspend,
.resume = usb_serial_resume,
.no_dynamic_id = 1,
+ .supports_autosuspend = 1,
};
/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
@@ -1344,6 +1344,8 @@ int usb_serial_register(struct usb_serial_driver *driver)
return -ENODEV;
fixup_generic(driver);
+ if (driver->usb_driver)
+ driver->usb_driver->supports_autosuspend = 1;
if (!driver->description)
driver->description = driver->driver.name;
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index a688b1e686ea..689ee1fb702a 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -285,7 +285,7 @@ static int slave_configure(struct scsi_device *sdev)
/* queue a command */
/* This is always called with scsi_lock(host) held */
-static int queuecommand(struct scsi_cmnd *srb,
+static int queuecommand_lck(struct scsi_cmnd *srb,
void (*done)(struct scsi_cmnd *))
{
struct us_data *us = host_to_us(srb->device->host);
@@ -315,6 +315,8 @@ static int queuecommand(struct scsi_cmnd *srb,
return 0;
}
+static DEF_SCSI_QCMD(queuecommand)
+
/***********************************************************************
* Error handling functions
***********************************************************************/
diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c
index 57fc2f532cab..ceba512f84d0 100644
--- a/drivers/usb/storage/sierra_ms.c
+++ b/drivers/usb/storage/sierra_ms.c
@@ -121,7 +121,7 @@ static ssize_t show_truinst(struct device *dev, struct device_attribute *attr,
}
return result;
}
-static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL);
+static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL);
int sierra_ms_init(struct us_data *us)
{
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index d1268191acbd..339fac3949df 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -430,7 +430,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
return 0;
}
-static int uas_queuecommand(struct scsi_cmnd *cmnd,
+static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
void (*done)(struct scsi_cmnd *))
{
struct scsi_device *sdev = cmnd->device;
@@ -488,6 +488,8 @@ static int uas_queuecommand(struct scsi_cmnd *cmnd,
return 0;
}
+static DEF_SCSI_QCMD(uas_queuecommand)
+
static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
{
struct scsi_device *sdev = cmnd->device;
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 4b4da5b86ff9..f442668a1e52 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -129,8 +129,9 @@ static void handle_tx(struct vhost_net *net)
size_t hdr_size;
struct socket *sock;
- sock = rcu_dereference_check(vq->private_data,
- lockdep_is_held(&vq->mutex));
+ /* TODO: check that we are running from vhost_worker?
+ * Not sure it's worth it, it's straight-forward enough. */
+ sock = rcu_dereference_check(vq->private_data, 1);
if (!sock)
return;
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index e207810bba3c..08703299ef61 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -197,12 +197,12 @@ static int backlight_suspend(struct device *dev, pm_message_t state)
{
struct backlight_device *bd = to_backlight_device(dev);
- if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
- mutex_lock(&bd->ops_lock);
+ mutex_lock(&bd->ops_lock);
+ if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
bd->props.state |= BL_CORE_SUSPENDED;
backlight_update_status(bd);
- mutex_unlock(&bd->ops_lock);
}
+ mutex_unlock(&bd->ops_lock);
return 0;
}
@@ -211,12 +211,12 @@ static int backlight_resume(struct device *dev)
{
struct backlight_device *bd = to_backlight_device(dev);
- if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
- mutex_lock(&bd->ops_lock);
+ mutex_lock(&bd->ops_lock);
+ if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
bd->props.state &= ~BL_CORE_SUSPENDED;
backlight_update_status(bd);
- mutex_unlock(&bd->ops_lock);
}
+ mutex_unlock(&bd->ops_lock);
return 0;
}
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 54e32c513610..915448ec75bf 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -47,7 +47,6 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/screen_info.h>
-#include <linux/smp_lock.h>
#include <video/vga.h>
#include <asm/io.h>
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index cad7d45c8bac..c265aed09e04 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1029,10 +1029,6 @@ static int __init fb_probe(struct platform_device *device)
goto err_release_pl_mem;
}
- ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
- if (ret)
- goto err_release_pl_mem;
-
/* Initialize par */
da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp;
@@ -1060,7 +1056,7 @@ static int __init fb_probe(struct platform_device *device)
ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
if (ret)
- goto err_free_irq;
+ goto err_release_pl_mem;
da8xx_fb_info->cmap.len = par->palette_sz;
/* initialize var_screeninfo */
@@ -1088,8 +1084,13 @@ static int __init fb_probe(struct platform_device *device)
goto err_cpu_freq;
}
#endif
+
+ ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par);
+ if (ret)
+ goto irq_freq;
return 0;
+irq_freq:
#ifdef CONFIG_CPU_FREQ
err_cpu_freq:
unregister_framebuffer(da8xx_fb_info);
@@ -1098,9 +1099,6 @@ err_cpu_freq:
err_dealloc_cmap:
fb_dealloc_cmap(&da8xx_fb_info->cmap);
-err_free_irq:
- free_irq(par->irq, par);
-
err_release_pl_mem:
dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base,
par->p_palette_base);
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index f53b9f1d6aba..5c3960da755a 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -80,6 +80,7 @@ static const struct fb_cmap default_16_colors = {
* @cmap: frame buffer colormap structure
* @len: length of @cmap
* @transp: boolean, 1 if there is transparency, 0 otherwise
+ * @flags: flags for kmalloc memory allocation
*
* Allocates memory for a colormap @cmap. @len is the
* number of entries in the palette.
@@ -88,34 +89,48 @@ static const struct fb_cmap default_16_colors = {
*
*/
-int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags)
{
- int size = len*sizeof(u16);
-
- if (cmap->len != len) {
- fb_dealloc_cmap(cmap);
- if (!len)
- return 0;
- if (!(cmap->red = kmalloc(size, GFP_ATOMIC)))
- goto fail;
- if (!(cmap->green = kmalloc(size, GFP_ATOMIC)))
- goto fail;
- if (!(cmap->blue = kmalloc(size, GFP_ATOMIC)))
- goto fail;
- if (transp) {
- if (!(cmap->transp = kmalloc(size, GFP_ATOMIC)))
+ int size = len * sizeof(u16);
+ int ret = -ENOMEM;
+
+ if (cmap->len != len) {
+ fb_dealloc_cmap(cmap);
+ if (!len)
+ return 0;
+
+ cmap->red = kmalloc(size, flags);
+ if (!cmap->red)
+ goto fail;
+ cmap->green = kmalloc(size, flags);
+ if (!cmap->green)
+ goto fail;
+ cmap->blue = kmalloc(size, flags);
+ if (!cmap->blue)
+ goto fail;
+ if (transp) {
+ cmap->transp = kmalloc(size, flags);
+ if (!cmap->transp)
+ goto fail;
+ } else {
+ cmap->transp = NULL;
+ }
+ }
+ cmap->start = 0;
+ cmap->len = len;
+ ret = fb_copy_cmap(fb_default_cmap(len), cmap);
+ if (ret)
goto fail;
- } else
- cmap->transp = NULL;
- }
- cmap->start = 0;
- cmap->len = len;
- fb_copy_cmap(fb_default_cmap(len), cmap);
- return 0;
+ return 0;
fail:
- fb_dealloc_cmap(cmap);
- return -ENOMEM;
+ fb_dealloc_cmap(cmap);
+ return ret;
+}
+
+int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
+{
+ return fb_alloc_cmap_gfp(cmap, len, transp, GFP_ATOMIC);
}
/**
@@ -250,8 +265,12 @@ 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 (size < 0 || size < cmap->len)
+ return -E2BIG;
+
memset(&umap, 0, sizeof(struct fb_cmap));
- rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
+ rc = fb_alloc_cmap_gfp(&umap, cmap->len, cmap->transp != NULL,
+ GFP_KERNEL);
if (rc)
return rc;
if (copy_from_user(umap.red, cmap->red, size) ||
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h
index e4c4d89b7860..be8ccb47ebe0 100644
--- a/drivers/video/geode/lxfb.h
+++ b/drivers/video/geode/lxfb.h
@@ -22,6 +22,7 @@
#define DC_HFILT_COUNT 0x100
#define DC_VFILT_COUNT 0x100
#define VP_COEFF_SIZE 0x1000
+#define VP_PAL_COUNT 0x100
#define OUTPUT_CRT 0x01
#define OUTPUT_PANEL 0x02
@@ -48,7 +49,8 @@ struct lxfb_par {
uint64_t vp[VP_REG_COUNT];
uint64_t fp[FP_REG_COUNT];
- uint32_t pal[DC_PAL_COUNT];
+ uint32_t dc_pal[DC_PAL_COUNT];
+ uint32_t vp_pal[VP_PAL_COUNT];
uint32_t hcoeff[DC_HFILT_COUNT * 2];
uint32_t vcoeff[DC_VFILT_COUNT];
uint32_t vp_coeff[VP_COEFF_SIZE / 4];
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c
index bc35a95e59d4..79e9abc72b83 100644
--- a/drivers/video/geode/lxfb_ops.c
+++ b/drivers/video/geode/lxfb_ops.c
@@ -276,10 +276,10 @@ static void lx_graphics_enable(struct fb_info *info)
write_fp(par, FP_PT1, 0);
temp = FP_PT2_SCRC;
- if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
temp |= FP_PT2_HSP;
- if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
temp |= FP_PT2_VSP;
write_fp(par, FP_PT2, temp);
@@ -610,10 +610,15 @@ static void lx_save_regs(struct lxfb_par *par)
memcpy(par->vp, par->vp_regs, sizeof(par->vp));
memcpy(par->fp, par->vp_regs + VP_FP_START, sizeof(par->fp));
- /* save the palette */
+ /* save the display controller palette */
write_dc(par, DC_PAL_ADDRESS, 0);
- for (i = 0; i < ARRAY_SIZE(par->pal); i++)
- par->pal[i] = read_dc(par, DC_PAL_DATA);
+ for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+ par->dc_pal[i] = read_dc(par, DC_PAL_DATA);
+
+ /* save the video processor palette */
+ write_vp(par, VP_PAR, 0);
+ for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+ par->vp_pal[i] = read_vp(par, VP_PDR);
/* save the horizontal filter coefficients */
filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -706,8 +711,8 @@ static void lx_restore_display_ctlr(struct lxfb_par *par)
/* restore the palette */
write_dc(par, DC_PAL_ADDRESS, 0);
- for (i = 0; i < ARRAY_SIZE(par->pal); i++)
- write_dc(par, DC_PAL_DATA, par->pal[i]);
+ for (i = 0; i < ARRAY_SIZE(par->dc_pal); i++)
+ write_dc(par, DC_PAL_DATA, par->dc_pal[i]);
/* restore the horizontal filter coefficients */
filt = par->dc[DC_IRQ_FILT_CTL] | DC_IRQ_FILT_CTL_H_FILT_SEL;
@@ -751,6 +756,11 @@ static void lx_restore_video_proc(struct lxfb_par *par)
}
}
+ /* restore video processor palette */
+ write_vp(par, VP_PAR, 0);
+ for (i = 0; i < ARRAY_SIZE(par->vp_pal); i++)
+ write_vp(par, VP_PDR, par->vp_pal[i]);
+
/* restore video coeff ram */
memcpy(par->vp_regs + VP_VCR, par->vp_coeff, sizeof(par->vp_coeff));
}
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 7cfc170bce19..ca0f6be9d12e 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -27,6 +27,7 @@
#include <linux/clk.h>
#include <linux/mutex.h>
+#include <mach/dma.h>
#include <mach/hardware.h>
#include <mach/ipu.h>
#include <mach/mx3fb.h>
@@ -1420,6 +1421,9 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
struct device *dev;
struct mx3fb_platform_data *mx3fb_pdata;
+ if (!imx_dma_is_ipu(chan))
+ return false;
+
if (!rq)
return false;
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 9b1364723c65..b02d97a879d6 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -860,7 +860,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
/* Couldn't reconfigure, hopefully, can continue as before */
return;
- info->fix.line_length = mode2.xres * (ch->cfg.bpp / 8);
+ info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8);
/*
* fb_set_var() calls the notifier change internally, only if
@@ -868,7 +868,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
* user event, we have to call the chain ourselves.
*/
event.info = info;
- event.data = &mode2;
+ event.data = &mode1;
fb_notifier_call_chain(evnt, &event);
}
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
index c311ad3c3687..31137adc8fba 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/sis/init.c
@@ -62,11 +62,11 @@
#include "init.h"
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
#include "300vtbl.h"
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
#include "310vtbl.h"
#endif
@@ -78,7 +78,7 @@
/* POINTER INITIALIZATION */
/*********************************************/
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static void
InitCommonPointer(struct SiS_Private *SiS_Pr)
{
@@ -160,7 +160,7 @@ InitCommonPointer(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static void
InitTo300Pointer(struct SiS_Private *SiS_Pr)
{
@@ -237,7 +237,7 @@ InitTo300Pointer(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void
InitTo310Pointer(struct SiS_Private *SiS_Pr)
{
@@ -321,13 +321,13 @@ bool
SiSInitPtr(struct SiS_Private *SiS_Pr)
{
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
InitTo300Pointer(SiS_Pr);
#else
return false;
#endif
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
InitTo310Pointer(SiS_Pr);
#else
return false;
@@ -340,9 +340,7 @@ SiSInitPtr(struct SiS_Private *SiS_Pr)
/* HELPER: Get ModeID */
/*********************************************/
-#ifndef SIS_XORG_XF86
static
-#endif
unsigned short
SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
int Depth, bool FSTN, int LCDwidth, int LCDheight)
@@ -884,51 +882,51 @@ SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispl
void
SiS_SetReg(SISIOADDRESS port, unsigned short index, unsigned short data)
{
- OutPortByte(port, index);
- OutPortByte(port + 1, data);
+ outb((u8)index, port);
+ outb((u8)data, port + 1);
}
void
SiS_SetRegByte(SISIOADDRESS port, unsigned short data)
{
- OutPortByte(port, data);
+ outb((u8)data, port);
}
void
SiS_SetRegShort(SISIOADDRESS port, unsigned short data)
{
- OutPortWord(port, data);
+ outw((u16)data, port);
}
void
SiS_SetRegLong(SISIOADDRESS port, unsigned int data)
{
- OutPortLong(port, data);
+ outl((u32)data, port);
}
unsigned char
SiS_GetReg(SISIOADDRESS port, unsigned short index)
{
- OutPortByte(port, index);
- return(InPortByte(port + 1));
+ outb((u8)index, port);
+ return inb(port + 1);
}
unsigned char
SiS_GetRegByte(SISIOADDRESS port)
{
- return(InPortByte(port));
+ return inb(port);
}
unsigned short
SiS_GetRegShort(SISIOADDRESS port)
{
- return(InPortWord(port));
+ return inw(port);
}
unsigned int
SiS_GetRegLong(SISIOADDRESS port)
{
- return(InPortLong(port));
+ return inl(port);
}
void
@@ -1089,7 +1087,7 @@ static void
SiSInitPCIetc(struct SiS_Private *SiS_Pr)
{
switch(SiS_Pr->ChipType) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
case SIS_300:
case SIS_540:
case SIS_630:
@@ -1108,7 +1106,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr)
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
break;
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
case SIS_315H:
case SIS_315:
case SIS_315PRO:
@@ -1152,9 +1150,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr)
/* HELPER: SetLVDSetc */
/*********************************************/
-#ifdef SIS_LINUX_KERNEL
static
-#endif
void
SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
{
@@ -1174,7 +1170,7 @@ SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
if((temp == 1) || (temp == 2)) return;
switch(SiS_Pr->ChipType) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
case SIS_540:
case SIS_630:
case SIS_730:
@@ -1188,7 +1184,7 @@ SiSSetLVDSetc(struct SiS_Private *SiS_Pr)
}
break;
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
case SIS_550:
case SIS_650:
case SIS_740:
@@ -1420,9 +1416,7 @@ SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr)
/* HELPER: GetVBType */
/*********************************************/
-#ifdef SIS_LINUX_KERNEL
static
-#endif
void
SiS_GetVBType(struct SiS_Private *SiS_Pr)
{
@@ -1487,7 +1481,6 @@ SiS_GetVBType(struct SiS_Private *SiS_Pr)
/* HELPER: Check RAM size */
/*********************************************/
-#ifdef SIS_LINUX_KERNEL
static bool
SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex)
@@ -1501,13 +1494,12 @@ SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
if(AdapterMemSize < memorysize) return false;
return true;
}
-#endif
/*********************************************/
/* HELPER: Get DRAM type */
/*********************************************/
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static unsigned char
SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
{
@@ -1574,7 +1566,6 @@ SiS_GetMCLK(struct SiS_Private *SiS_Pr)
/* HELPER: ClearBuffer */
/*********************************************/
-#ifdef SIS_LINUX_KERNEL
static void
SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
@@ -1587,7 +1578,7 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(SiS_Pr->SiS_ModeType >= ModeEGA) {
if(ModeNo > 0x13) {
- SiS_SetMemory(memaddr, memsize, 0);
+ memset_io(memaddr, 0, memsize);
} else {
pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]);
@@ -1596,10 +1587,9 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
pBuffer = (unsigned short SISIOMEMTYPE *)memaddr;
for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]);
} else {
- SiS_SetMemory(memaddr, 0x8000, 0);
+ memset_io(memaddr, 0, 0x8000);
}
}
-#endif
/*********************************************/
/* HELPER: SearchModeID */
@@ -2132,7 +2122,7 @@ SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType == XGI_20) {
SiS_SetReg(SiS_Pr->SiS_P3d4,0x04,crt1data[4] - 1);
if(!(temp = crt1data[5] & 0x1f)) {
@@ -2215,7 +2205,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2c,clkb);
if(SiS_Pr->ChipType >= SIS_315H) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
if(SiS_Pr->ChipType == XGI_20) {
unsigned short mf = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
@@ -2236,7 +2226,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
/* FIFO */
/*********************************************/
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
void
SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
unsigned short *idx2)
@@ -2506,11 +2496,7 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
/* Write foreground and background queue */
-#ifdef SIS_LINUX_KERNEL
templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
-#else
- templ = pciReadLong(0x00000000, 0x50);
-#endif
if(SiS_Pr->ChipType == SIS_730) {
@@ -2530,13 +2516,8 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
}
-#ifdef SIS_LINUX_KERNEL
sisfb_write_nbridge_pci_dword(SiS_Pr, 0x50, templ);
templ = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xA0);
-#else
- pciWriteLong(0x00000000, 0x50, templ);
- templ = pciReadLong(0x00000000, 0xA0);
-#endif
/* GUI grant timer (PCI config 0xA3) */
if(SiS_Pr->ChipType == SIS_730) {
@@ -2552,15 +2533,11 @@ SiS_SetCRT1FIFO_630(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
}
-#ifdef SIS_LINUX_KERNEL
sisfb_write_nbridge_pci_dword(SiS_Pr, 0xA0, templ);
-#else
- pciWriteLong(0x00000000, 0xA0, templ);
-#endif
}
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void
SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
@@ -2612,7 +2589,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
}
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(VCLK > 150) data |= 0x80;
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data);
@@ -2621,7 +2598,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data);
#endif
} else if(SiS_Pr->ChipType < XGI_20) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(VCLK >= 166) data |= 0x0c;
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
@@ -2630,7 +2607,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
}
#endif
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(VCLK >= 200) data |= 0x0c;
if(SiS_Pr->ChipType == XGI_20) data &= ~0x04;
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
@@ -2675,7 +2652,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex, unsigned short RRTI)
{
unsigned short data, infoflag = 0, modeflag, resindex;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned short data2, data3;
#endif
@@ -2736,7 +2713,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,data);
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xfb);
}
@@ -2826,7 +2803,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_SetVCLKState(SiS_Pr, ModeNo, RRTI, ModeIdIndex);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) ||
(SiS_Pr->ChipType == XGI_40)) {
if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
@@ -2845,7 +2822,7 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
#endif
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void
SiS_SetupDualChip(struct SiS_Private *SiS_Pr)
{
@@ -2999,11 +2976,6 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
SiS_Pr->SiS_SelectCRT2Rate = 0;
SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-#ifdef SIS_XORG_XF86
- xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
- SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
-#endif
-
if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
@@ -3028,7 +3000,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
}
switch(SiS_Pr->ChipType) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
case SIS_300:
SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo, RefreshRateTableIndex);
break;
@@ -3039,7 +3011,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
break;
#endif
default:
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType == XGI_20) {
unsigned char sr2b = 0, sr2c = 0;
switch(ModeNo) {
@@ -3062,7 +3034,7 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
SiS_SetCRT1ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType == XGI_40) {
SiS_SetupDualChip(SiS_Pr);
}
@@ -3070,11 +3042,9 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sho
SiS_LoadDAC(SiS_Pr, ModeNo, ModeIdIndex);
-#ifdef SIS_LINUX_KERNEL
if(SiS_Pr->SiS_flag_clearbuffer) {
SiS_ClearBuffer(SiS_Pr, ModeNo);
}
-#endif
if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
SiS_WaitRetrace1(SiS_Pr);
@@ -3104,7 +3074,7 @@ SiS_InitVB(struct SiS_Private *SiS_Pr)
static void
SiS_ResetVB(struct SiS_Private *SiS_Pr)
{
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned short temp;
@@ -3139,7 +3109,7 @@ SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
* which locks CRT2 in some way to CRT1 timing. Disable
* this here.
*/
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if((IS_SIS651) || (IS_SISM650) ||
SiS_Pr->ChipType == SIS_340 ||
SiS_Pr->ChipType == XGI_40) {
@@ -3160,7 +3130,7 @@ SiS_StrangeStuff(struct SiS_Private *SiS_Pr)
static void
SiS_Handle760(struct SiS_Private *SiS_Pr)
{
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned int somebase;
unsigned char temp1, temp2, temp3;
@@ -3170,11 +3140,7 @@ SiS_Handle760(struct SiS_Private *SiS_Pr)
(!(SiS_Pr->SiS_SysFlags & SF_760UMA)) )
return;
-#ifdef SIS_LINUX_KERNEL
somebase = sisfb_read_mio_pci_word(SiS_Pr, 0x74);
-#else
- somebase = pciReadWord(0x00001000, 0x74);
-#endif
somebase &= 0xffff;
if(somebase == 0) return;
@@ -3190,105 +3156,34 @@ SiS_Handle760(struct SiS_Private *SiS_Pr)
temp2 = 0x0b;
}
-#ifdef SIS_LINUX_KERNEL
sisfb_write_nbridge_pci_byte(SiS_Pr, 0x7e, temp1);
sisfb_write_nbridge_pci_byte(SiS_Pr, 0x8d, temp2);
-#else
- pciWriteByte(0x00000000, 0x7e, temp1);
- pciWriteByte(0x00000000, 0x8d, temp2);
-#endif
SiS_SetRegByte((somebase + 0x85), temp3);
#endif
}
/*********************************************/
-/* X.org/XFree86: SET SCREEN PITCH */
-/*********************************************/
-
-#ifdef SIS_XORG_XF86
-static void
-SiS_SetPitchCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
-{
- SISPtr pSiS = SISPTR(pScrn);
- unsigned short HDisplay = pSiS->scrnPitch >> 3;
-
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,(HDisplay & 0xFF));
- SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,(HDisplay >> 8));
-}
-
-static void
-SiS_SetPitchCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
-{
- SISPtr pSiS = SISPTR(pScrn);
- unsigned short HDisplay = pSiS->scrnPitch2 >> 3;
-
- /* Unlock CRT2 */
- if(pSiS->VGAEngine == SIS_315_VGA)
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
- else
- SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
-
- SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,(HDisplay & 0xFF));
- SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0xF0,(HDisplay >> 8));
-}
-
-static void
-SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
-{
- SISPtr pSiS = SISPTR(pScrn);
- bool isslavemode = false;
-
- if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) &&
- ( ((pSiS->VGAEngine == SIS_300_VGA) &&
- (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
- ((pSiS->VGAEngine == SIS_315_VGA) &&
- (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
- isslavemode = true;
- }
-
- /* We need to set pitch for CRT1 if bridge is in slave mode, too */
- if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) {
- SiS_SetPitchCRT1(SiS_Pr, pScrn);
- }
- /* We must not set the pitch for CRT2 if bridge is in slave mode */
- if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) {
- SiS_SetPitchCRT2(SiS_Pr, pScrn);
- }
-}
-#endif
-
-/*********************************************/
/* SiSSetMode() */
/*********************************************/
-#ifdef SIS_XORG_XF86
-/* We need pScrn for setting the pitch correctly */
-bool
-SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, bool dosetpitch)
-#else
bool
SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
-#endif
{
SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
unsigned short RealModeNo, ModeIdIndex;
unsigned char backupreg = 0;
-#ifdef SIS_LINUX_KERNEL
unsigned short KeepLockReg;
SiS_Pr->UseCustomMode = false;
SiS_Pr->CRT1UsesCustomMode = false;
-#endif
SiS_Pr->SiS_flag_clearbuffer = 0;
if(SiS_Pr->UseCustomMode) {
ModeNo = 0xfe;
} else {
-#ifdef SIS_LINUX_KERNEL
if(!(ModeNo & 0x80)) SiS_Pr->SiS_flag_clearbuffer = 1;
-#endif
ModeNo &= 0x7f;
}
@@ -3301,13 +3196,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_GetSysFlags(SiS_Pr);
SiS_Pr->SiS_VGAINFO = 0x11;
-#if defined(SIS_XORG_XF86) && (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__))
- if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-#endif
-#ifdef SIS_LINUX_KERNEL
KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
-#endif
SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
SiSInitPCIetc(SiS_Pr);
@@ -3344,12 +3234,10 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
SiS_SetLowModeTest(SiS_Pr, ModeNo);
-#ifdef SIS_LINUX_KERNEL
/* Check memory size (kernel framebuffer driver only) */
if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
return false;
}
-#endif
SiS_OpenCRTC(SiS_Pr);
@@ -3384,7 +3272,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_DisplayOn(SiS_Pr);
SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
if(!(SiS_IsDualEdge(SiS_Pr))) {
@@ -3396,7 +3284,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
if(SiS_Pr->ChipType >= SIS_315H) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(!SiS_Pr->SiS_ROMNew) {
if(SiS_IsVAMode(SiS_Pr)) {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
@@ -3424,424 +3312,16 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
}
}
-#ifdef SIS_XORG_XF86
- if(pScrn) {
- /* SetPitch: Adapt to virtual size & position */
- if((ModeNo > 0x13) && (dosetpitch)) {
- SiS_SetPitch(SiS_Pr, pScrn);
- }
-
- /* Backup/Set ModeNo in BIOS scratch area */
- SiS_GetSetModeID(pScrn, ModeNo);
- }
-#endif
-
SiS_CloseCRTC(SiS_Pr);
SiS_Handle760(SiS_Pr);
-#ifdef SIS_LINUX_KERNEL
/* We never lock registers in XF86 */
if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
-#endif
return true;
}
-/*********************************************/
-/* X.org/XFree86: SiSBIOSSetMode() */
-/* for non-Dual-Head mode */
-/*********************************************/
-
-#ifdef SIS_XORG_XF86
-bool
-SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, bool IsCustom)
-{
- SISPtr pSiS = SISPTR(pScrn);
- unsigned short ModeNo = 0;
-
- SiS_Pr->UseCustomMode = false;
-
- if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
- SiS_Pr->CHDisplay,
- (mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
- (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
- SiS_Pr->CVDisplay)));
-
- } else {
-
- /* Don't need vbflags here; checks done earlier */
- ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
- if(!ModeNo) return false;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
-
- }
-
- return(SiSSetMode(SiS_Pr, pScrn, ModeNo, true));
-}
-
-/*********************************************/
-/* X.org/XFree86: SiSBIOSSetModeCRT2() */
-/* for Dual-Head modes */
-/*********************************************/
-
-bool
-SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, bool IsCustom)
-{
- SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
- SISPtr pSiS = SISPTR(pScrn);
-#ifdef SISDUALHEAD
- SISEntPtr pSiSEnt = pSiS->entityPrivate;
-#endif
- unsigned short ModeIdIndex;
- unsigned short ModeNo = 0;
- unsigned char backupreg = 0;
-
- SiS_Pr->UseCustomMode = false;
-
- /* Remember: Custom modes for CRT2 are ONLY supported
- * -) on the 30x/B/C, and
- * -) if CRT2 is LCD or VGA, or CRT1 is LCDA
- */
-
- if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-
- ModeNo = 0xfe;
-
- } else {
-
- ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
- if(!ModeNo) return false;
-
- }
-
- SiSRegInit(SiS_Pr, BaseAddr);
- SiSInitPtr(SiS_Pr);
- SiS_GetSysFlags(SiS_Pr);
-#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
- SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-#else
- SiS_Pr->SiS_VGAINFO = 0x11;
-#endif
-
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
-
- SiSInitPCIetc(SiS_Pr);
- SiSSetLVDSetc(SiS_Pr);
- SiSDetermineROMUsage(SiS_Pr);
-
- /* Save mode info so we can set it from within SetMode for CRT1 */
-#ifdef SISDUALHEAD
- if(pSiS->DualHeadMode) {
- pSiSEnt->CRT2ModeNo = ModeNo;
- pSiSEnt->CRT2DMode = mode;
- pSiSEnt->CRT2IsCustom = IsCustom;
- pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
- pSiSEnt->CRT2CR35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
-#if 0
- /* We can't set CRT2 mode before CRT1 mode is set - says who...? */
- if(pSiSEnt->CRT1ModeNo == -1) {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "Setting CRT2 mode delayed until after setting CRT1 mode\n");
- return true;
- }
-#endif
- pSiSEnt->CRT2ModeSet = true;
- }
-#endif
-
- if(SiS_Pr->UseCustomMode) {
-
- unsigned short temptemp = SiS_Pr->CVDisplay;
-
- if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
- else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "Setting custom mode %dx%d on CRT2\n",
- SiS_Pr->CHDisplay, temptemp);
-
- } else {
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "Setting standard mode 0x%x on CRT2\n", ModeNo);
-
- }
-
- SiS_UnLockCRT2(SiS_Pr);
-
- if(!SiS_Pr->UseCustomMode) {
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
- } else {
- ModeIdIndex = 0;
- }
-
- SiS_GetVBType(SiS_Pr);
-
- SiS_InitVB(SiS_Pr);
- if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
- if(SiS_Pr->ChipType >= SIS_315H) {
- SiS_ResetVB(SiS_Pr);
- SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
- SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x00,0x0c);
- backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- } else {
- backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- }
- }
-
- /* Get VB information (connectors, connected devices) */
- if(!SiS_Pr->UseCustomMode) {
- SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 1);
- } else {
- /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
- SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
- }
- SiS_SetYPbPr(SiS_Pr);
- SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
- SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
- SiS_SetLowModeTest(SiS_Pr, ModeNo);
-
- SiS_ResetSegmentRegisters(SiS_Pr);
-
- /* Set mode on CRT2 */
- if( (SiS_Pr->SiS_VBType & VB_SISVB) ||
- (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
- (SiS_Pr->SiS_IF_DEF_CH70xx != 0) ||
- (SiS_Pr->SiS_IF_DEF_TRUMPION != 0) ) {
- SiS_SetCRT2Group(SiS_Pr, ModeNo);
- }
-
- SiS_StrangeStuff(SiS_Pr);
-
- SiS_DisplayOn(SiS_Pr);
- SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
-
- if(SiS_Pr->ChipType >= SIS_315H) {
- if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- if(!(SiS_IsDualEdge(SiS_Pr))) {
- SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
- }
- }
- }
-
- if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
- if(SiS_Pr->ChipType >= SIS_315H) {
- if(!SiS_Pr->SiS_ROMNew) {
- if(SiS_IsVAMode(SiS_Pr)) {
- SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
- } else {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
- }
- }
-
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
-
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD) {
- SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
- }
- } else if((SiS_Pr->ChipType == SIS_630) ||
- (SiS_Pr->ChipType == SIS_730)) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
- }
- }
-
- /* SetPitch: Adapt to virtual size & position */
- SiS_SetPitchCRT2(SiS_Pr, pScrn);
-
- SiS_Handle760(SiS_Pr);
-
- return true;
-}
-
-/*********************************************/
-/* X.org/XFree86: SiSBIOSSetModeCRT1() */
-/* for Dual-Head modes */
-/*********************************************/
-
-bool
-SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, bool IsCustom)
-{
- SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
- SISPtr pSiS = SISPTR(pScrn);
- unsigned short ModeIdIndex, ModeNo = 0;
- unsigned char backupreg = 0;
-#ifdef SISDUALHEAD
- SISEntPtr pSiSEnt = pSiS->entityPrivate;
- unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
- bool backupcustom;
-#endif
-
- SiS_Pr->UseCustomMode = false;
-
- if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-
- unsigned short temptemp = SiS_Pr->CVDisplay;
-
- if(SiS_Pr->CModeFlag & DoubleScanMode) temptemp >>= 1;
- else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "Setting custom mode %dx%d on CRT1\n",
- SiS_Pr->CHDisplay, temptemp);
- ModeNo = 0xfe;
-
- } else {
-
- ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */
- if(!ModeNo) return false;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "Setting standard mode 0x%x on CRT1\n", ModeNo);
- }
-
- SiSInitPtr(SiS_Pr);
- SiSRegInit(SiS_Pr, BaseAddr);
- SiS_GetSysFlags(SiS_Pr);
-#if defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__) || defined(__amd64__) || defined(__x86_64__)
- SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-#else
- SiS_Pr->SiS_VGAINFO = 0x11;
-#endif
-
- SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
-
- SiSInitPCIetc(SiS_Pr);
- SiSSetLVDSetc(SiS_Pr);
- SiSDetermineROMUsage(SiS_Pr);
-
- SiS_UnLockCRT2(SiS_Pr);
-
- if(!SiS_Pr->UseCustomMode) {
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
- } else {
- ModeIdIndex = 0;
- }
-
- /* Determine VBType */
- SiS_GetVBType(SiS_Pr);
-
- SiS_InitVB(SiS_Pr);
- if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
- if(SiS_Pr->ChipType >= SIS_315H) {
- backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- } else {
- backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- }
- }
-
- /* Get VB information (connectors, connected devices) */
- /* (We don't care if the current mode is a CRT2 mode) */
- SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, 0);
- SiS_SetYPbPr(SiS_Pr);
- SiS_SetTVMode(SiS_Pr, ModeNo, ModeIdIndex);
- SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex);
- SiS_SetLowModeTest(SiS_Pr, ModeNo);
-
- SiS_OpenCRTC(SiS_Pr);
-
- /* Set mode on CRT1 */
- SiS_SetCRT1Group(SiS_Pr, ModeNo, ModeIdIndex);
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_SetCRT2Group(SiS_Pr, ModeNo);
- }
-
- /* SetPitch: Adapt to virtual size & position */
- SiS_SetPitchCRT1(SiS_Pr, pScrn);
-
- SiS_HandleCRT1(SiS_Pr);
-
- SiS_StrangeStuff(SiS_Pr);
-
- SiS_CloseCRTC(SiS_Pr);
-
-#ifdef SISDUALHEAD
- if(pSiS->DualHeadMode) {
- pSiSEnt->CRT1ModeNo = ModeNo;
- pSiSEnt->CRT1DMode = mode;
- }
-#endif
-
- if(SiS_Pr->UseCustomMode) {
- SiS_Pr->CRT1UsesCustomMode = true;
- SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
- SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
- } else {
- SiS_Pr->CRT1UsesCustomMode = false;
- }
-
- /* Reset CRT2 if changing mode on CRT1 */
-#ifdef SISDUALHEAD
- if(pSiS->DualHeadMode) {
- if(pSiSEnt->CRT2ModeNo != -1) {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "(Re-)Setting mode for CRT2\n");
- backupcustom = SiS_Pr->UseCustomMode;
- backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
- backupcr35 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
- backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- /* Backup LUT-enable */
- if(pSiSEnt->CRT2ModeSet) {
- backupp40d = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0d) & 0x08;
- }
- }
- if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,pSiSEnt->CRT2CR35);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
- }
-
- SiSBIOSSetModeCRT2(SiS_Pr, pSiSEnt->pScrn_1,
- pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
-
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupcr35);
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
- if(SiS_Pr->SiS_VBType & VB_SISVB) {
- SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0d, ~0x08, backupp40d);
- }
- SiS_Pr->UseCustomMode = backupcustom;
- }
- }
-#endif
-
- /* Warning: From here, the custom mode entries in SiS_Pr are
- * possibly overwritten
- */
-
- SiS_DisplayOn(SiS_Pr);
- SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
-
- if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
- if(SiS_Pr->ChipType >= SIS_315H) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
- } else if((SiS_Pr->ChipType == SIS_630) ||
- (SiS_Pr->ChipType == SIS_730)) {
- SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
- }
- }
-
- SiS_Handle760(SiS_Pr);
-
- /* Backup/Set ModeNo in BIOS scratch area */
- SiS_GetSetModeID(pScrn,ModeNo);
-
- return true;
-}
-#endif /* Linux_XF86 */
-
#ifndef GETBITSTR
#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
#define GENMASK(mask) BITMASK(1?mask,0?mask)
@@ -3927,7 +3407,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_Pr->CVBlankStart = SiS_Pr->SiS_VGAVDE;
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
tempbx = SiS_Pr->SiS_VGAHT;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
tempbx = SiS_Pr->PanelHT;
@@ -3936,7 +3416,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
remaining = tempbx % 8;
#endif
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
/* OK for LCDA, LVDS */
tempbx = SiS_Pr->PanelHT - SiS_Pr->PanelXRes;
tempax = SiS_Pr->SiS_VGAHDE; /* not /2 ! */
@@ -3950,7 +3430,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_Pr->CHTotal = SiS_Pr->CHBlankEnd = tempbx;
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_VGAHDE == SiS_Pr->PanelXRes) {
SiS_Pr->CHSyncStart = SiS_Pr->SiS_VGAHDE + ((SiS_Pr->PanelHRS + 1) & ~1);
SiS_Pr->CHSyncEnd = SiS_Pr->CHSyncStart + SiS_Pr->PanelHRE;
@@ -3982,7 +3462,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
}
#endif
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
tempax = VGAHDE;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
tempbx = SiS_Pr->PanelXRes;
@@ -4001,7 +3481,7 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
tempax = SiS_Pr->PanelYRes;
} else if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
/* Stupid hack for 640x400/320x200 */
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
if((tempax + tempbx) == 438) tempbx += 16;
@@ -4054,36 +3534,12 @@ SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
if(modeflag & DoubleScanMode) tempax |= 0x80;
SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0x5F,tempax);
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
- SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
- SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
- SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
- xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
- SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
- SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
- SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
- xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
- SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
- SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
- SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
- xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
-#endif
-#endif
}
void
SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
int xres, int yres,
-#ifdef SIS_XORG_XF86
- DisplayModePtr current
-#endif
-#ifdef SIS_LINUX_KERNEL
struct fb_var_screeninfo *var, bool writeres
-#endif
)
{
unsigned short HRE, HBE, HRS, HBS, HDE, HT;
@@ -4127,25 +3583,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
D = B - F - C;
-#ifdef SIS_XORG_XF86
- current->HDisplay = (E * 8);
- current->HSyncStart = (E * 8) + (F * 8);
- current->HSyncEnd = (E * 8) + (F * 8) + (C * 8);
- current->HTotal = (E * 8) + (F * 8) + (C * 8) + (D * 8);
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO,
- "H: A %d B %d C %d D %d E %d F %d HT %d HDE %d HRS %d HBS %d HBE %d HRE %d\n",
- A, B, C, D, E, F, HT, HDE, HRS, HBS, HBE, HRE);
-#else
- (void)VBS; (void)HBS; (void)A;
-#endif
-#endif
-#ifdef SIS_LINUX_KERNEL
if(writeres) var->xres = xres = E * 8;
var->left_margin = D * 8;
var->right_margin = F * 8;
var->hsync_len = C * 8;
-#endif
/* Vertical */
sr_data = crdata[13];
@@ -4192,30 +3633,10 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
D = B - F - C;
-#ifdef SIS_XORG_XF86
- current->VDisplay = VDE + 1;
- current->VSyncStart = VRS + 1;
- current->VSyncEnd = ((VRS & ~0x1f) | VRE) + 1;
- if(VRE <= (VRS & 0x1f)) current->VSyncEnd += 32;
- current->VTotal = E + D + C + F;
-#if 0
- current->VDisplay = E;
- current->VSyncStart = E + D;
- current->VSyncEnd = E + D + C;
- current->VTotal = E + D + C + F;
-#endif
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO,
- "V: A %d B %d C %d D %d E %d F %d VT %d VDE %d VRS %d VBS %d VBE %d VRE %d\n",
- A, B, C, D, E, F, VT, VDE, VRS, VBS, VBE, VRE);
-#endif
-#endif
-#ifdef SIS_LINUX_KERNEL
if(writeres) var->yres = yres = E;
var->upper_margin = D;
var->lower_margin = F;
var->vsync_len = C;
-#endif
if((xres == 320) && ((yres == 200) || (yres == 240))) {
/* Terrible hack, but correct CRTC data for
@@ -4224,17 +3645,9 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
* a negative D. The CRT controller does not
* seem to like correcting HRE to 50)
*/
-#ifdef SIS_XORG_XF86
- current->HDisplay = 320;
- current->HSyncStart = 328;
- current->HSyncEnd = 376;
- current->HTotal = 400;
-#endif
-#ifdef SIS_LINUX_KERNEL
var->left_margin = (400 - 376);
var->right_margin = (328 - 320);
var->hsync_len = (376 - 328);
-#endif
}
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index b96005c39c67..ee8ed3c203da 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -53,21 +53,8 @@
#ifndef _INIT_H_
#define _INIT_H_
-#include "osdef.h"
#include "initdef.h"
-#ifdef SIS_XORG_XF86
-#include "sis.h"
-#define SIS_NEED_inSISREG
-#define SIS_NEED_inSISREGW
-#define SIS_NEED_inSISREGL
-#define SIS_NEED_outSISREG
-#define SIS_NEED_outSISREGW
-#define SIS_NEED_outSISREGL
-#include "sis_regs.h"
-#endif
-
-#ifdef SIS_LINUX_KERNEL
#include "vgatypes.h"
#include "vstruct.h"
#ifdef SIS_CP
@@ -78,7 +65,6 @@
#include <linux/fb.h>
#include "sis.h"
#include <video/sisfb.h>
-#endif
/* Mode numbers */
static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
@@ -286,7 +272,7 @@ static const struct SiS_ModeResInfo_S SiS_ModeResInfo[] =
{ 1280, 854, 8,16} /* 0x22 */
};
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static const struct SiS_StandTable_S SiS_StandTable[]=
{
/* 0x00: MD_0_200 */
@@ -1521,10 +1507,6 @@ static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] =
};
bool SiSInitPtr(struct SiS_Private *SiS_Pr);
-#ifdef SIS_XORG_XF86
-unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
- int Depth, bool FSTN, int LCDwith, int LCDheight);
-#endif
unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
int VDisplay, int Depth, bool FSTN,
unsigned short CustomT, int LCDwith, int LCDheight,
@@ -1550,17 +1532,11 @@ void SiS_SetRegOR(SISIOADDRESS Port,unsigned short Index, unsigned short DataOR
void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-#ifndef SIS_LINUX_KERNEL
-void SiSSetLVDSetc(struct SiS_Private *SiS_Pr);
-#endif
void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex);
bool SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
-#ifndef SIS_LINUX_KERNEL
-void SiS_GetVBType(struct SiS_Private *SiS_Pr);
-#endif
bool SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
unsigned short *ModeIdIndex);
@@ -1572,37 +1548,19 @@ unsigned short SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short Mode
unsigned short ModeIdIndex);
unsigned short SiS_GetOffset(struct SiS_Private *SiS_Pr,unsigned short ModeNo,
unsigned short ModeIdIndex, unsigned short RRTI);
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *idx1,
unsigned short *idx2);
unsigned short SiS_GetFIFOThresholdB300(unsigned short idx1, unsigned short idx2);
unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
#endif
void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
-#ifdef SIS_XORG_XF86
-bool SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo,
- bool dosetpitch);
-bool SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, bool IsCustom);
-bool SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, bool IsCustom);
-bool SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, bool IsCustom);
-#endif
-#ifdef SIS_LINUX_KERNEL
bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
-#endif
void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex);
-#ifdef SIS_XORG_XF86
-void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
- int yres, DisplayModePtr current);
-#endif
-#ifdef SIS_LINUX_KERNEL
void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
int yres, struct fb_var_screeninfo *var, bool writeres);
-#endif
/* From init301.c: */
extern void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
@@ -1626,29 +1584,16 @@ extern unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short
extern bool SiS_IsVAMode(struct SiS_Private *);
extern bool SiS_IsDualEdge(struct SiS_Private *);
-#ifdef SIS_XORG_XF86
-/* From other modules: */
-extern unsigned short SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode,
- unsigned int VBFlags);
-extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, unsigned short offset,
- unsigned char value);
-extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
-extern unsigned short SiS_GetModeNumber(ScrnInfoPtr pScrn, DisplayModePtr mode,
- unsigned int VBFlags);
-#endif
-
-#ifdef SIS_LINUX_KERNEL
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
extern void sisfb_write_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg,
unsigned int val);
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
extern void sisfb_write_nbridge_pci_byte(struct SiS_Private *SiS_Pr, int reg,
unsigned char val);
extern unsigned int sisfb_read_mio_pci_word(struct SiS_Private *SiS_Pr, int reg);
#endif
-#endif
#endif
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index da33d801c22e..9fa66fd4052a 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -75,11 +75,11 @@
#include "init301.h"
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
#include "oem300.h"
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
#include "oem310.h"
#endif
@@ -87,9 +87,7 @@
#define SiS_I2CDELAYSHORT 150
static unsigned short SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr);
-#ifdef SIS_LINUX_KERNEL
static void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
-#endif
/*********************************************/
/* HELPER: Lock/Unlock CRT2 */
@@ -106,9 +104,7 @@ SiS_UnLockCRT2(struct SiS_Private *SiS_Pr)
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
}
-#ifdef SIS_LINUX_KERNEL
static
-#endif
void
SiS_LockCRT2(struct SiS_Private *SiS_Pr)
{
@@ -138,7 +134,7 @@ SiS_SetRegSR11ANDOR(struct SiS_Private *SiS_Pr, unsigned short DataAND, unsigned
/* HELPER: Get Pointer to LCD structure */
/*********************************************/
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static unsigned char *
GetLCDStructPtr661(struct SiS_Private *SiS_Pr)
{
@@ -404,7 +400,7 @@ SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
/* HELPER: GET SOME DATA FROM BIOS ROM */
/*********************************************/
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static bool
SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
{
@@ -449,7 +445,7 @@ SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
}
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static void
SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
@@ -457,7 +453,7 @@ SiS_GenericDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void
SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
@@ -467,7 +463,7 @@ SiS_LongDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
}
#endif
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static void
SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
{
@@ -480,14 +476,14 @@ SiS_ShortDelay(struct SiS_Private *SiS_Pr, unsigned short delay)
static void
SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
{
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned short PanelID, DelayIndex, Delay=0;
#endif
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -513,11 +509,11 @@ SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
}
SiS_ShortDelay(SiS_Pr, Delay);
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if((SiS_Pr->ChipType >= SIS_661) ||
(SiS_Pr->ChipType <= SIS_315PRO) ||
@@ -579,12 +575,12 @@ SiS_PanelDelay(struct SiS_Private *SiS_Pr, unsigned short DelayTime)
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
}
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void
SiS_PanelDelayLoop(struct SiS_Private *SiS_Pr, unsigned short DelayTime, unsigned short DelayLoop)
{
@@ -613,7 +609,7 @@ SiS_WaitRetrace1(struct SiS_Private *SiS_Pr)
while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
}
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
static void
SiS_WaitRetrace2(struct SiS_Private *SiS_Pr, unsigned short reg)
{
@@ -630,7 +626,7 @@ static void
SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
{
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
}
@@ -641,7 +637,7 @@ SiS_WaitVBRetrace(struct SiS_Private *SiS_Pr)
}
#endif
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
SiS_WaitRetrace1(SiS_Pr);
} else {
@@ -686,7 +682,7 @@ SiS_VBLongWait(struct SiS_Private *SiS_Pr)
/* HELPER: MISC */
/*********************************************/
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static bool
SiS_Is301B(struct SiS_Private *SiS_Pr)
{
@@ -708,7 +704,7 @@ SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
bool
SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
{
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
@@ -721,7 +717,7 @@ SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
bool
SiS_IsVAMode(struct SiS_Private *SiS_Pr)
{
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned short flag;
if(SiS_Pr->ChipType >= SIS_315H) {
@@ -732,7 +728,7 @@ SiS_IsVAMode(struct SiS_Private *SiS_Pr)
return false;
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
{
@@ -745,7 +741,7 @@ SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
static bool
SiS_IsDualLink(struct SiS_Private *SiS_Pr)
{
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
if((SiS_CRT2IsLCD(SiS_Pr)) ||
(SiS_IsVAMode(SiS_Pr))) {
@@ -756,7 +752,7 @@ SiS_IsDualLink(struct SiS_Private *SiS_Pr)
return false;
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_TVEnabled(struct SiS_Private *SiS_Pr)
{
@@ -768,7 +764,7 @@ SiS_TVEnabled(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
{
@@ -777,7 +773,7 @@ SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
{
@@ -788,7 +784,7 @@ SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
{
@@ -804,7 +800,7 @@ SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
{
@@ -816,7 +812,7 @@ SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsChScart(struct SiS_Private *SiS_Pr)
{
@@ -828,7 +824,7 @@ SiS_IsChScart(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
{
@@ -848,7 +844,7 @@ SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static bool
SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
{
@@ -914,7 +910,7 @@ SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
/*********************************************/
/* Setup general purpose IO for Chrontel communication */
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
void
SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
{
@@ -923,11 +919,7 @@ SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo)
if(!(SiS_Pr->SiS_ChSW)) return;
-#ifdef SIS_LINUX_KERNEL
acpibase = sisfb_read_lpc_pci_dword(SiS_Pr, 0x74);
-#else
- acpibase = pciReadLong(0x00000800, 0x74);
-#endif
acpibase &= 0xFFFF;
if(!acpibase) return;
temp = SiS_GetRegShort((acpibase + 0x3c)); /* ACPI register 0x3c: GP Event 1 I/O mode select */
@@ -969,7 +961,7 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
tempax &= (DriverMode | LoadDACFlag | SetNotSimuMode | SetPALTV);
tempbx |= tempax;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_VBType & VB_SISLCDA) {
if(ModeNo == 0x03) {
@@ -1019,7 +1011,7 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
}
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
if(!(SiS_Pr->SiS_VBType & VB_SISVGA2)) {
tempbx &= ~(SetCRT2ToRAMDAC);
@@ -1154,24 +1146,16 @@ SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
SiS_Pr->SiS_VBInfo = tempbx;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->ChipType == SIS_630) {
SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
}
#endif
-#ifdef SIS_LINUX_KERNEL
#if 0
printk(KERN_DEBUG "sisfb: (init301: VBInfo= 0x%04x, SetFlag=0x%04x)\n",
SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
#endif
-#endif
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_PROBED, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
- SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
-#endif
-#endif
}
/*********************************************/
@@ -1415,12 +1399,6 @@ SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
}
SiS_Pr->SiS_VBInfo &= ~SetPALTV;
-
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "(init301: TVMode %x, VBInfo %x)\n", SiS_Pr->SiS_TVMode, SiS_Pr->SiS_VBInfo);
-#endif
-#endif
}
/*********************************************/
@@ -1443,22 +1421,10 @@ SiS_GetBIOSLCDResInfo(struct SiS_Private *SiS_Pr)
static void
SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
{
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned char *ROMAddr;
unsigned short temp;
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Paneldata driver: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
- SiS_Pr->PanelHT, SiS_Pr->PanelVT,
- SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
- SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
- SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
- SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
- SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
-#endif
-#endif
-
if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
SiS_Pr->SiS_NeedRomModeData = true;
@@ -1480,18 +1446,6 @@ SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
SiS_Pr->SiS_VCLKData[VCLK_CUSTOM_315].SR2C =
SiS_Pr->SiS_VBVCLKData[VCLK_CUSTOM_315].Part4_B = ROMAddr[20];
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Paneldata BIOS: [%d %d] [H %d %d] [V %d %d] [C %d 0x%02x 0x%02x]\n",
- SiS_Pr->PanelHT, SiS_Pr->PanelVT,
- SiS_Pr->PanelHRS, SiS_Pr->PanelHRE,
- SiS_Pr->PanelVRS, SiS_Pr->PanelVRE,
- SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].CLOCK,
- SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_A,
- SiS_Pr->SiS_VBVCLKData[SiS_Pr->PanelVCLKIdx315].Part4_B);
-#endif
-#endif
-
}
#endif
}
@@ -1517,13 +1471,13 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
{
unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
bool panelcanscale = false;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
static const unsigned char SiS300SeriesLCDRes[] =
{ 0, 1, 2, 3, 7, 4, 5, 8,
0, 0, 10, 0, 0, 0, 0, 15 };
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned char *myptr = NULL;
#endif
@@ -1562,7 +1516,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
}
temp &= 0x0f;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->ChipType < SIS_315H) {
/* Very old BIOSes only know 7 sizes (NetVista 2179, 1.01g) */
if(SiS_Pr->SiS_VBType & VB_SIS301) {
@@ -1574,7 +1528,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
#endif
/* Translate to our internal types */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType == SIS_550) {
if (temp == Panel310_1152x768) temp = Panel_320x240_2; /* Verified working */
else if(temp == Panel310_320x240_2) temp = Panel_320x240_2;
@@ -1597,7 +1551,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
SiS_Pr->SiS_LCDResInfo = temp;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
@@ -1639,7 +1593,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
/* Dual link, Pass 1:1 BIOS default, etc. */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_661) {
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
if(temp & 0x08) SiS_Pr->SiS_LCDInfo |= LCDPass11;
@@ -2076,7 +2030,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
}
}
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
if(SiS_Pr->SiS_CustomT == CUT_PANEL848 || SiS_Pr->SiS_CustomT == CUT_PANEL856) {
SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20; /* neg h/v sync, RGB24(D0 = 0) */
@@ -2186,17 +2140,10 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
SiS_Pr->SiS_SetFlag |= LCDVESATiming;
}
-#ifdef SIS_LINUX_KERNEL
#if 0
printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
#endif
-#endif
-#ifdef SIS_XORG_XF86
- xf86DrvMsgVerb(0, X_PROBED, 4,
- "(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
- SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
-#endif
}
/*********************************************/
@@ -2359,7 +2306,7 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
VCLKIndex = SiS_Pr->PanelVCLKIdx315;
}
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
/* Special Timing: Barco iQ Pro R series */
if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) VCLKIndex = 0x44;
@@ -2410,12 +2357,6 @@ SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
-#endif
-#endif
-
return VCLKIndex;
}
@@ -2428,10 +2369,10 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
{
unsigned short i, j, modeflag, tempah=0;
short tempcl;
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
unsigned short tempbl;
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned short tempah2, tempbl2;
#endif
@@ -2454,7 +2395,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* ---- 300 series ---- */
+#ifdef CONFIG_FB_SIS_300 /* ---- 300 series ---- */
/* For 301BDH: (with LCD via LVDS) */
if(SiS_Pr->SiS_VBType & VB_NoLCD) {
@@ -2477,11 +2418,11 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0xA0;
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* ------- 315/330 series ------ */
+#ifdef CONFIG_FB_SIS_315 /* ------- 315/330 series ------ */
if(ModeNo > 0x13) {
tempcl -= ModeVGA;
@@ -2494,7 +2435,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) tempah ^= 0x50;
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
}
@@ -2503,7 +2444,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
if(SiS_Pr->ChipType < SIS_315H) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);
} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -2584,7 +2525,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
if(SiS_Pr->ChipType >= SIS_315H) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
/* LVDS can only be slave in 8bpp modes */
tempah = 0x80;
if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
@@ -2604,7 +2545,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
} else {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
tempah = 0;
if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
tempah |= 0x02;
@@ -2626,7 +2567,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
if(SiS_Pr->ChipType >= SIS_315H) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
/* unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); */
/* The following is nearly unpreditable and varies from machine
@@ -2718,11 +2659,11 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
} else if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
@@ -2745,7 +2686,7 @@ SiS_SetCRT2ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
} else { /* LVDS */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
@@ -2931,7 +2872,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
}
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
@@ -3036,7 +2977,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
case Panel_1280x1024: tempbx = 24; break;
case Panel_1400x1050: tempbx = 26; break;
case Panel_1600x1200: tempbx = 28; break;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
case Panel_Barco1366: tempbx = 80; break;
#endif
}
@@ -3053,7 +2994,7 @@ SiS_GetCRT2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
if(SiS_Pr->SiS_LCDInfo & LCDPass11) tempbx = 30;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
tempbx = 82;
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
@@ -3189,7 +3130,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
if((SiS_Pr->SiS_VBType & VB_SISVB) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
SiS_CalcPanelLinkTiming(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
SiS_CalcLCDACRT1Timing(SiS_Pr, ModeNo, ModeIdIndex);
#endif
@@ -3214,7 +3155,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
case 16: LVDSData = SiS_Pr->SiS_LVDS800x600Data_1; break;
case 18: LVDSData = SiS_Pr->SiS_LVDS1024x600Data_1; break;
case 20: LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1; break;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
case 80: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1; break;
case 81: LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2; break;
case 82: LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1; break;
@@ -3248,7 +3189,7 @@ SiS_GetCRT2DataLVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
(SiS_Pr->SiS_SetFlag & SetDOSMode) ) {
SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
if(ResIndex < 0x08) {
SiS_Pr->SiS_HDE = 1280;
@@ -3270,7 +3211,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
unsigned short resinfo, CRT2Index, ResIndex;
const struct SiS_LCDData *LCDPtr = NULL;
const struct SiS_TVData *TVPtr = NULL;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
short resinfo661;
#endif
@@ -3283,7 +3224,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
resinfo661 = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].ROMMODEIDX661;
if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
(SiS_Pr->SiS_SetFlag & LCDVESATiming) &&
@@ -3460,7 +3401,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
SiS_Pr->SiS_RVBHCMAX = ROMAddr[romptr];
SiS_Pr->SiS_RVBHCFACT = ROMAddr[romptr+1];
SiS_Pr->SiS_VGAHT = ROMAddr[romptr+2] | ((ROMAddr[romptr+3] & 0x0f) << 8);
@@ -3520,19 +3461,13 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
case Panel_1680x1050 :
case Panel_1680x1050 + 32: LCDPtr = SiS_Pr->SiS_LCD1680x1050Data; break;
case 100 : LCDPtr = SiS_Pr->SiS_NoScaleData; break;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
case 200 : LCDPtr = SiS310_ExtCompaq1280x1024Data; break;
case 201 : LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data; break;
#endif
default : LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data; break;
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
-#endif
-#endif
-
SiS_Pr->SiS_RVBHCMAX = (LCDPtr+ResIndex)->RVBHCMAX;
SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
SiS_Pr->SiS_VGAHT = (LCDPtr+ResIndex)->VGAHT;
@@ -3624,7 +3559,7 @@ SiS_GetLVDSDesPtr(struct SiS_Private *SiS_Pr)
{
const struct SiS_LVDSDes *PanelDesPtr = NULL;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
if(SiS_Pr->ChipType < SIS_315H) {
@@ -3696,7 +3631,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
if((SiS_Pr->SiS_VBType & VB_SIS30xBLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
/* non-pass 1:1 only, see above */
if(SiS_Pr->SiS_VGAHDE != SiS_Pr->PanelXRes) {
@@ -3771,7 +3706,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
} else {
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
switch(SiS_Pr->SiS_LCDResInfo) {
case Panel_800x600:
if(SiS_Pr->SiS_VGAVDE == SiS_Pr->PanelYRes) {
@@ -3816,7 +3751,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
}
#endif
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
switch(SiS_Pr->SiS_LCDResInfo) {
case Panel_1024x768:
case Panel_1280x1024:
@@ -3844,7 +3779,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
if(SiS_Pr->ChipType < SIS_315H) {
if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) SiS_Pr->SiS_LCDHDES = 480;
if(SiS_Pr->SiS_LCDResInfo == Panel_1400x1050) SiS_Pr->SiS_LCDHDES = 804;
if(SiS_Pr->SiS_LCDResInfo == Panel_1600x1200) SiS_Pr->SiS_LCDHDES = 704;
@@ -3866,7 +3801,7 @@ SiS_GetLVDSDesData(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
/* DISABLE VIDEO BRIDGE */
/*********************************************/
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static int
SiS_HandlePWD(struct SiS_Private *SiS_Pr)
{
@@ -3891,11 +3826,6 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr)
ret = 1;
}
SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x27,0x7f,temp);
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, 0, "Setting PWD %x\n", temp);
-#endif
-#endif
}
#endif
return ret;
@@ -3909,7 +3839,7 @@ SiS_HandlePWD(struct SiS_Private *SiS_Pr)
void
SiS_DisableBridge(struct SiS_Private *SiS_Pr)
{
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned short tempah, pushax=0, modenum;
#endif
unsigned short temp=0;
@@ -3920,7 +3850,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* 300 series */
+#ifdef CONFIG_FB_SIS_300 /* 300 series */
if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
@@ -3953,11 +3883,11 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
}
}
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* 315 series */
+#ifdef CONFIG_FB_SIS_315 /* 315 series */
int didpwd = 0;
bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
@@ -4081,14 +4011,14 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
}
} else { /* ============ For 301 ================ */
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(!(SiS_CR36BIOSWord23b(SiS_Pr))) {
SiS_SetRegSR11ANDOR(SiS_Pr,0xF7,0x08);
SiS_PanelDelay(SiS_Pr, 3);
@@ -4111,7 +4041,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
} else {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF); /* disable CRT2 */
if( (!(SiS_CRT2IsLCD(SiS_Pr))) ||
(!(SiS_CR36BIOSWord23d(SiS_Pr))) ) {
@@ -4127,7 +4057,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* 300 series */
+#ifdef CONFIG_FB_SIS_300 /* 300 series */
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
SiS_SetCH700x(SiS_Pr,0x0E,0x09);
@@ -4171,11 +4101,11 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
SiS_SetRegSR11ANDOR(SiS_Pr,0xFB,0x04);
}
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* 315 series */
+#ifdef CONFIG_FB_SIS_315 /* 315 series */
if(!(SiS_IsNotM650orLater(SiS_Pr))) {
/*if(SiS_Pr->ChipType < SIS_340) { */ /* XGI needs this */
@@ -4288,7 +4218,7 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
}
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
} /* 315 series */
@@ -4304,14 +4234,12 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
* from outside the context of a mode switch!
* MUST call getVBType before calling this
*/
-#ifdef SIS_LINUX_KERNEL
static
-#endif
void
SiS_EnableBridge(struct SiS_Private *SiS_Pr)
{
unsigned short temp=0, tempah;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned short temp1, pushax=0;
bool delaylong = false;
#endif
@@ -4322,7 +4250,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* 300 series */
+#ifdef CONFIG_FB_SIS_300 /* 300 series */
if(SiS_CRT2IsLCD(SiS_Pr)) {
if(SiS_Pr->SiS_VBType & VB_SISLVDS) {
@@ -4385,11 +4313,11 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
}
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* 315 series */
+#ifdef CONFIG_FB_SIS_315 /* 315 series */
#ifdef SET_EMI
unsigned char r30=0, r31=0, r32=0, r33=0, cr36=0;
@@ -4688,7 +4616,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
}
@@ -4739,7 +4667,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* 300 series */
+#ifdef CONFIG_FB_SIS_300 /* 300 series */
if(SiS_CRT2IsLCD(SiS_Pr)) {
if(SiS_Pr->ChipType == SIS_730) {
@@ -4783,11 +4711,11 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
}
}
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* 315 series */
+#ifdef CONFIG_FB_SIS_315 /* 315 series */
if(!(SiS_IsNotM650orLater(SiS_Pr))) {
/*if(SiS_Pr->ChipType < SIS_340) {*/ /* XGI needs this */
@@ -4881,7 +4809,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
}
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
} /* 310 series */
@@ -4971,7 +4899,7 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* ---- 300 series --- */
+#ifdef CONFIG_FB_SIS_300 /* ---- 300 series --- */
if(SiS_Pr->SiS_VBType & VB_SIS30xBLV) { /* 630 - 301B(-DH) */
@@ -5000,11 +4928,11 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
}
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* ------- 315 series ------ */
+#ifdef CONFIG_FB_SIS_315 /* ------- 315 series ------ */
if(SiS_Pr->SiS_VBType & VB_SISLVDS) { /* 315 - LVDS */
@@ -5076,13 +5004,13 @@ SiS_SetCRT2Sync(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
}
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
}
}
}
/* Set CRT2 FIFO on 300/540/630/730 */
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static void
SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
{
@@ -5154,13 +5082,8 @@ SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
} else {
-#ifdef SIS_LINUX_KERNEL
pci50 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0x50);
pciA0 = sisfb_read_nbridge_pci_dword(SiS_Pr, 0xa0);
-#else
- pci50 = pciReadLong(0x00000000, 0x50);
- pciA0 = pciReadLong(0x00000000, 0xA0);
-#endif
if(SiS_Pr->ChipType == SIS_730) {
@@ -5262,7 +5185,7 @@ SiS_SetCRT2FIFO_300(struct SiS_Private *SiS_Pr,unsigned short ModeNo)
#endif
/* Set CRT2 FIFO on 315/330 series */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void
SiS_SetCRT2FIFO_310(struct SiS_Private *SiS_Pr)
{
@@ -5420,27 +5343,6 @@ SiS_SetGroup1_301(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned sho
temp = SiS_GetRegByte((SiS_Pr->SiS_P3ca+0x02));
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp); /* ? */
-
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "%d %d %d %d %d %d %d %d (%d %d %d %d)\n",
- SiS_Pr->CHDisplay, SiS_Pr->CHSyncStart, SiS_Pr->CHSyncEnd, SiS_Pr->CHTotal,
- SiS_Pr->CVDisplay, SiS_Pr->CVSyncStart, SiS_Pr->CVSyncEnd, SiS_Pr->CVTotal,
- SiS_Pr->CHBlankStart, SiS_Pr->CHBlankEnd, SiS_Pr->CVBlankStart, SiS_Pr->CVBlankEnd);
-
- xf86DrvMsg(0, X_INFO, " {{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- SiS_Pr->CCRT1CRTC[0], SiS_Pr->CCRT1CRTC[1],
- SiS_Pr->CCRT1CRTC[2], SiS_Pr->CCRT1CRTC[3],
- SiS_Pr->CCRT1CRTC[4], SiS_Pr->CCRT1CRTC[5],
- SiS_Pr->CCRT1CRTC[6], SiS_Pr->CCRT1CRTC[7]);
- xf86DrvMsg(0, X_INFO, " 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\n",
- SiS_Pr->CCRT1CRTC[8], SiS_Pr->CCRT1CRTC[9],
- SiS_Pr->CCRT1CRTC[10], SiS_Pr->CCRT1CRTC[11],
- SiS_Pr->CCRT1CRTC[12], SiS_Pr->CCRT1CRTC[13],
- SiS_Pr->CCRT1CRTC[14], SiS_Pr->CCRT1CRTC[15]);
- xf86DrvMsg(0, X_INFO, " 0x%02x}},\n", SiS_Pr->CCRT1CRTC[16]);
-#endif
-#endif
}
/* Setup panel link
@@ -5455,17 +5357,17 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
unsigned short push2, tempax, tempbx, tempcx, temp;
unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
bool islvds = false, issis = false, chkdclkfirst = false;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
unsigned short crt2crtc = 0;
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned short pushcx;
#endif
if(ModeNo <= 0x13) {
modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
#endif
} else if(SiS_Pr->UseCustomMode) {
@@ -5473,7 +5375,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
} else {
modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
#endif
}
@@ -5494,7 +5396,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
}
}
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
if(IS_SIS330) {
SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);
@@ -5744,7 +5646,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* 300 series */
+#ifdef CONFIG_FB_SIS_300 /* 300 series */
tempeax = SiS_Pr->SiS_VGAVDE << 6;
temp = (tempeax % (unsigned int)SiS_Pr->SiS_VDE);
tempeax = tempeax / (unsigned int)SiS_Pr->SiS_VDE;
@@ -5755,11 +5657,11 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
temp = (unsigned short)(tempeax & 0x00FF);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp); /* BPLVCFACT */
tempvcfact = temp;
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* 315 series */
+#ifdef CONFIG_FB_SIS_315 /* 315 series */
tempeax = SiS_Pr->SiS_VGAVDE << 18;
tempebx = SiS_Pr->SiS_VDE;
temp = (tempeax % tempebx);
@@ -5845,7 +5747,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
temp = (unsigned short)(tempecx & 0x00FF);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
if((islvds) || (SiS_Pr->SiS_VBInfo & VB_SISLVDS)) {
@@ -5863,7 +5765,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
}
#endif
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->SiS_IF_DEF_TRUMPION) {
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned char *trumpdata;
@@ -5899,7 +5801,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
@@ -5999,7 +5901,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
}
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
}
/* Set Part 1 */
@@ -6007,12 +5909,12 @@ static void
SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex)
{
-#if defined(SIS300) || defined(SIS315H)
+#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
#endif
unsigned short temp=0, tempax=0, tempbx=0, tempcx=0, bridgeadd=0;
unsigned short pushbx=0, CRT1Index=0, modeflag, resinfo=0;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned short tempbl=0;
#endif
@@ -6038,11 +5940,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
if(SiS_Pr->ChipType < SIS_315H ) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo);
#endif
} else {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
SiS_SetCRT2FIFO_310(SiS_Pr);
#endif
}
@@ -6051,7 +5953,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
if(SiS_Pr->ChipType < SIS_315H ) {
-#ifdef SIS300 /* ------------- 300 series --------------*/
+#ifdef CONFIG_FB_SIS_300 /* ------------- 300 series --------------*/
temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp); /* CRT2 Horizontal Total */
@@ -6070,11 +5972,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
bridgeadd = 12;
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* ------------------- 315/330 series --------------- */
+#ifdef CONFIG_FB_SIS_315 /* ------------------- 315/330 series --------------- */
tempcx = SiS_Pr->SiS_VGAHT; /* BTVGA2HT 0x08,0x09 */
if(modeflag & HalfDCLK) {
@@ -6125,7 +6027,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
}
}
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
} /* 315/330 series */
@@ -6256,7 +6158,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
if(SiS_Pr->ChipType < SIS_315H) {
-#ifdef SIS300 /* ---------- 300 series -------------- */
+#ifdef CONFIG_FB_SIS_300 /* ---------- 300 series -------------- */
if(SiS_Pr->SiS_VBType & VB_SISVB) {
temp = 0x20;
@@ -6310,11 +6212,11 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x3C,temp); /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
-#endif /* SIS300 */
+#endif /* CONFIG_FB_SIS_300 */
} else {
-#ifdef SIS315H /* --------------- 315/330 series ---------------*/
+#ifdef CONFIG_FB_SIS_315 /* --------------- 315/330 series ---------------*/
if(SiS_Pr->ChipType < SIS_661) {
@@ -6349,7 +6251,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
if(modeflag & HalfDCLK) tempax |= 0x40;
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
-#endif /* SIS315H */
+#endif /* CONFIG_FB_SIS_315 */
}
@@ -6381,7 +6283,7 @@ SiS_SetGroup1(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
/* SET PART 2 REGISTER GROUP */
/*********************************************/
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static unsigned char *
SiS_GetGroup2CLVXPtr(struct SiS_Private *SiS_Pr, int tabletype)
{
@@ -6478,7 +6380,7 @@ SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned sh
}
#endif
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static void
SiS_Group2LCDSpecial(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short crt2crtc)
{
@@ -6690,7 +6592,7 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
unsigned int longtemp, PhaseIndex;
bool newtvphase;
const unsigned char *TimingPoint;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned short resindex, CRT2Index;
const struct SiS_Part2PortTbl *CRT2Part2Ptr = NULL;
@@ -7069,7 +6971,7 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
&CRT2Index, &resindex)) {
switch(CRT2Index) {
@@ -7130,12 +7032,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
/* Non-expanding: lcdvdes = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
-#endif
-#endif
-
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,tempcx); /* lcdvdes */
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,tempbx); /* lcdvdee */
@@ -7184,12 +7080,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
tempbx = SiS_Pr->CVSyncStart;
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
-#endif
-#endif
-
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,tempbx); /* lcdvrs */
temp = (tempbx >> 4) & 0xF0;
@@ -7201,15 +7091,9 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
temp |= (SiS_Pr->CVSyncEnd & 0x0f);
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
-#endif
-#endif
-
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
SiS_Group2LCDSpecial(SiS_Pr, ModeNo, crt2crtc);
#endif
@@ -7245,12 +7129,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
tempax >>= 1;
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
-#endif
-#endif
-
tempbx += bridgeoffset;
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,tempbx); /* lcdhdee */
@@ -7276,12 +7154,6 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
tempbx += bridgeoffset;
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
-#endif
-#endif
-
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,tempbx); /* lcdhrs */
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,((tempbx >> 4) & 0xf0));
@@ -7300,20 +7172,14 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
tempbx += bridgeoffset;
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
-#endif
-#endif
-
SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,tempbx); /* lcdhre */
SiS_SetGroup2_Tail(SiS_Pr, ModeNo);
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
SiS_Set300Part2Regs(SiS_Pr, ModeIdIndex, RefreshRateTableIndex, ModeNo);
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
} /* CRT2-LCD from table */
#endif
}
@@ -7382,7 +7248,7 @@ SiS_SetGroup3(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
/* SET PART 4 REGISTER GROUP */
/*********************************************/
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
#if 0
static void
SiS_ShiftXPos(struct SiS_Private *SiS_Pr, int shift)
@@ -8011,7 +7877,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
/* Chrontel 7005 - I assume that it does not come with a 315 series chip */
@@ -8124,7 +7990,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
/* Chrontel 7019 - assumed that it does not come with a 300 series chip */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
unsigned short temp;
@@ -8175,7 +8041,7 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
}
-#ifdef SIS315H /* ----------- 315 series only ---------- */
+#ifdef CONFIG_FB_SIS_315 /* ----------- 315 series only ---------- */
void
SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr)
@@ -8657,7 +8523,7 @@ SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
bool
SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
#endif
unsigned short ModeIdIndex, RefreshRateTableIndex;
@@ -8703,16 +8569,6 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
- xf86DrvMsg(0, X_INFO, "(init301: HDE 0x%03x VDE 0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
- xf86DrvMsg(0, X_INFO, "(init301: VGAHDE 0x%03x VGAVDE 0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
- xf86DrvMsg(0, X_INFO, "(init301: HT 0x%03x VT 0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
- xf86DrvMsg(0, X_INFO, "(init301: VGAHT 0x%03x VGAVT 0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
-#endif
-#endif
-
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
}
@@ -8722,12 +8578,12 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
SiS_SetGroup2_C_ELV(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
#endif
SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex);
SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
SiS_SetGroup4_C_ELV(SiS_Pr, ModeNo, ModeIdIndex);
#endif
SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex);
@@ -8758,7 +8614,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
SiS_SetCH701xForLCD(SiS_Pr);
#endif
}
@@ -8771,7 +8627,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
}
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
if(SiS_Pr->ChipType < SIS_315H) {
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
if(SiS_Pr->SiS_UseOEM) {
@@ -8794,7 +8650,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
}
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
if(SiS_Pr->ChipType >= SIS_315H) {
if(SiS_Pr->SiS_SetFlag & LowModeTests) {
if(SiS_Pr->ChipType < SIS_661) {
@@ -8873,7 +8729,7 @@ SiS_SetupDDCN(struct SiS_Private *SiS_Pr)
}
}
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static unsigned char *
SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
{
@@ -8923,11 +8779,6 @@ SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
if(!dataptr) return false;
}
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
-#endif
-#endif
return true;
}
#endif
@@ -9002,9 +8853,7 @@ SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
SiS_SetChReg(SiS_Pr, reg, val, 0);
}
-#ifdef SIS_LINUX_KERNEL
static
-#endif
void
SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val)
{
@@ -9091,9 +8940,7 @@ SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempbx)
/* Read from Chrontel 70xx */
/* Parameter is [Register no (S7-S0)] */
-#ifdef SIS_LINUX_KERNEL
static
-#endif
unsigned short
SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempbx)
{
@@ -9114,9 +8961,7 @@ SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
}
/* Our own DDC functions */
-#ifndef SIS_XORG_XF86
static
-#endif
unsigned short
SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
@@ -9224,12 +9069,6 @@ SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
SiS_SetupDDCN(SiS_Pr);
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
- SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
-#endif
-#endif
return 0;
}
@@ -9292,11 +9131,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
SiS_SetSwitchDDC2(SiS_Pr);
if(SiS_PrepareDDC(SiS_Pr)) {
SiS_SetStop(SiS_Pr);
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
-#endif
-#endif
return 0xFFFF;
}
mask = 0xf0;
@@ -9310,11 +9144,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
} else {
failed = true;
ret = 0xFFFF;
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
-#endif
-#endif
}
}
if(!failed) {
@@ -9324,11 +9153,6 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
if(temp == value) ret = 0;
else {
ret = 0xFFFF;
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
-#endif
-#endif
if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
if(temp == 0x30) ret = 0;
}
@@ -9338,9 +9162,7 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
return ret;
}
-#ifndef SIS_XORG_XF86
static
-#endif
unsigned short
SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
{
@@ -9357,9 +9179,7 @@ SiS_ProbeDDC(struct SiS_Private *SiS_Pr)
return flag;
}
-#ifndef SIS_XORG_XF86
static
-#endif
unsigned short
SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype, unsigned char *buffer)
{
@@ -9606,11 +9426,6 @@ SiS_SetSCLKHigh(struct SiS_Private *SiS_Pr)
temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
} while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
if (!watchdog) {
-#ifdef SIS_XORG_XF86
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
-#endif
-#endif
return 0xFFFF;
}
SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
@@ -9641,7 +9456,7 @@ SiS_CheckACK(struct SiS_Private *SiS_Pr)
/* =============== SiS 315/330 O.E.M. ================= */
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static unsigned short
GetRAMDACromptr(struct SiS_Private *SiS_Pr)
@@ -10829,7 +10644,7 @@ SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
/* ================= SiS 300 O.E.M. ================== */
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static void
SetOEMLCDData2(struct SiS_Private *SiS_Pr, unsigned short ModeNo,unsigned short ModeIdIndex,
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index 51d99222375d..e1fd31d0fddf 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -53,15 +53,8 @@
#ifndef _INIT301_H_
#define _INIT301_H_
-#include "osdef.h"
#include "initdef.h"
-#ifdef SIS_XORG_XF86
-#include "sis.h"
-#include "sis_regs.h"
-#endif
-
-#ifdef SIS_LINUX_KERNEL
#include "vgatypes.h"
#include "vstruct.h"
#ifdef SIS_CP
@@ -72,7 +65,6 @@
#include <linux/fb.h>
#include "sis.h"
#include <video/sisfb.h>
-#endif
static const unsigned char SiS_YPbPrTable[3][64] = {
{
@@ -237,7 +229,7 @@ static const unsigned char SiS_Part2CLVX_6[] = { /* 1080i */
0xFF,0xFF,
};
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
/* 661 et al LCD data structure (2.03.00) */
static const unsigned char SiS_LCDStruct661[] = {
/* 1024x768 */
@@ -279,7 +271,7 @@ static const unsigned char SiS_LCDStruct661[] = {
};
#endif
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static unsigned char SiS300_TrumpionData[14][80] = {
{ 0x02,0x0A,0x0A,0x01,0x04,0x01,0x00,0x03,0x0D,0x00,0x0D,0x10,0x7F,0x00,0x80,0x02,
0x20,0x03,0x0B,0x00,0x90,0x01,0xC1,0x01,0x60,0x0C,0x30,0x10,0x00,0x00,0x04,0x23,
@@ -356,9 +348,6 @@ static unsigned char SiS300_TrumpionData[14][80] = {
#endif
void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
-#ifndef SIS_LINUX_KERNEL
-void SiS_LockCRT2(struct SiS_Private *SiS_Pr);
-#endif
void SiS_EnableCRT2(struct SiS_Private *SiS_Pr);
unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
@@ -375,9 +364,6 @@ unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo
unsigned short RefreshRateTableIndex);
unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex);
void SiS_DisableBridge(struct SiS_Private *SiS_Pr);
-#ifndef SIS_LINUX_KERNEL
-void SiS_EnableBridge(struct SiS_Private *SiS_Pr);
-#endif
bool SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
@@ -386,13 +372,9 @@ void SiS_SetCH700x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned cha
unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
void SiS_SetCH701x(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
unsigned short SiS_GetCH701x(struct SiS_Private *SiS_Pr, unsigned short tempax);
-#ifndef SIS_LINUX_KERNEL
-void SiS_SetCH70xx(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val);
-unsigned short SiS_GetCH70xx(struct SiS_Private *SiS_Pr, unsigned short tempax);
-#endif
void SiS_SetCH70xxANDOR(struct SiS_Private *SiS_Pr, unsigned short reg,
unsigned char orval,unsigned short andval);
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void SiS_Chrontel701xOn(struct SiS_Private *SiS_Pr);
static void SiS_Chrontel701xOff(struct SiS_Private *SiS_Pr);
static void SiS_ChrontelInitTVVSync(struct SiS_Private *SiS_Pr);
@@ -401,7 +383,7 @@ void SiS_Chrontel701xBLOn(struct SiS_Private *SiS_Pr);
void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
#endif /* 315 */
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
#endif
@@ -412,21 +394,12 @@ unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, i
unsigned short adaptnum, unsigned short DDCdatatype,
unsigned char *buffer, unsigned int VBFlags2);
-#ifdef SIS_XORG_XF86
-unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
- int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
- bool checkcr32, unsigned int VBFlags2);
-unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
-unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
- unsigned char *buffer);
-#else
static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
bool checkcr32, unsigned int VBFlags2);
static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
unsigned char *buffer);
-#endif
static void SiS_SetSwitchDDC2(struct SiS_Private *SiS_Pr);
static unsigned short SiS_SetStart(struct SiS_Private *SiS_Pr);
static unsigned short SiS_SetStop(struct SiS_Private *SiS_Pr);
@@ -441,13 +414,13 @@ static unsigned short SiS_PrepareDDC(struct SiS_Private *SiS_Pr);
static void SiS_SendACK(struct SiS_Private *SiS_Pr, unsigned short yesno);
static unsigned short SiS_DoProbeDDC(struct SiS_Private *SiS_Pr);
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
static void SiS_OEM300Setting(struct SiS_Private *SiS_Pr,
unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefTabindex);
static void SetOEMLCDData2(struct SiS_Private *SiS_Pr,
unsigned short ModeNo, unsigned short ModeIdIndex,unsigned short RefTableIndex);
#endif
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
static void SiS_OEM310Setting(struct SiS_Private *SiS_Pr,
unsigned short ModeNo,unsigned short ModeIdIndex, unsigned short RRTI);
static void SiS_OEM661Setting(struct SiS_Private *SiS_Pr,
@@ -482,15 +455,13 @@ extern void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short M
extern void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
extern unsigned short SiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
extern unsigned short SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide);
-#ifdef SIS300
+#ifdef CONFIG_FB_SIS_300
extern void SiS_GetFIFOThresholdIndex300(struct SiS_Private *SiS_Pr, unsigned short *tempbx,
unsigned short *tempcl);
extern unsigned short SiS_GetFIFOThresholdB300(unsigned short tempbx, unsigned short tempcl);
extern unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned short index);
-#ifdef SIS_LINUX_KERNEL
extern unsigned int sisfb_read_nbridge_pci_dword(struct SiS_Private *SiS_Pr, int reg);
extern unsigned int sisfb_read_lpc_pci_dword(struct SiS_Private *SiS_Pr, int reg);
#endif
-#endif
#endif
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index 99c04a4855d1..9dec64da4015 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -25,7 +25,6 @@
* Author: Thomas Winischhofer <thomas@winischhofer.net>
*/
-#include "osdef.h"
#include "initdef.h"
#include "vgatypes.h"
#include "vstruct.h"
@@ -59,7 +58,7 @@ sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
if(rateindex > 0) rateindex--;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
switch(ModeNo) {
case 0x5a: ModeNo = 0x50; break;
case 0x5b: ModeNo = 0x56;
@@ -103,7 +102,7 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
if(rateindex > 0) rateindex--;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
switch(ModeNo) {
case 0x5a: ModeNo = 0x50; break;
case 0x5b: ModeNo = 0x56;
@@ -187,7 +186,7 @@ sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *ht
if(rateindex > 0) rateindex--;
-#ifdef SIS315H
+#ifdef CONFIG_FB_SIS_315
switch(ModeNo) {
case 0x5a: ModeNo = 0x50; break;
case 0x5b: ModeNo = 0x56;
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
deleted file mode 100644
index 6ff8f988a1a7..000000000000
--- a/drivers/video/sis/osdef.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* $XFree86$ */
-/* $XdotOrg$ */
-/*
- * OS depending defines
- *
- * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
- *
- * If distributed as part of the Linux kernel, the following license terms
- * apply:
- *
- * * 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 named 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
- *
- * Otherwise, the following license terms apply:
- *
- * * Redistribution and use in source and binary forms, with or without
- * * modification, are permitted provided that the following conditions
- * * are met:
- * * 1) Redistributions of source code must retain the above copyright
- * * notice, this list of conditions and the following disclaimer.
- * * 2) Redistributions in binary form must reproduce the above copyright
- * * notice, this list of conditions and the following disclaimer in the
- * * documentation and/or other materials provided with the distribution.
- * * 3) The name of the author may not be used to endorse or promote products
- * * derived from this software without specific prior written permission.
- * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Author: Thomas Winischhofer <thomas@winischhofer.net>
- * Silicon Integrated Systems, Inc. (used by permission)
- *
- */
-
-#ifndef _SIS_OSDEF_H_
-#define _SIS_OSDEF_H_
-
-/* The choices are: */
-#define SIS_LINUX_KERNEL /* Linux kernel framebuffer */
-#undef SIS_XORG_XF86 /* XFree86/X.org */
-
-#ifdef OutPortByte
-#undef OutPortByte
-#endif
-
-#ifdef OutPortWord
-#undef OutPortWord
-#endif
-
-#ifdef OutPortLong
-#undef OutPortLong
-#endif
-
-#ifdef InPortByte
-#undef InPortByte
-#endif
-
-#ifdef InPortWord
-#undef InPortWord
-#endif
-
-#ifdef InPortLong
-#undef InPortLong
-#endif
-
-/**********************************************************************/
-/* LINUX KERNEL */
-/**********************************************************************/
-
-#ifdef SIS_LINUX_KERNEL
-
-#ifdef CONFIG_FB_SIS_300
-#define SIS300
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-#define SIS315H
-#endif
-
-#if !defined(SIS300) && !defined(SIS315H)
-#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
-#warning sisfb will not work!
-#endif
-
-#define OutPortByte(p,v) outb((u8)(v),(SISIOADDRESS)(p))
-#define OutPortWord(p,v) outw((u16)(v),(SISIOADDRESS)(p))
-#define OutPortLong(p,v) outl((u32)(v),(SISIOADDRESS)(p))
-#define InPortByte(p) inb((SISIOADDRESS)(p))
-#define InPortWord(p) inw((SISIOADDRESS)(p))
-#define InPortLong(p) inl((SISIOADDRESS)(p))
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset_io(MemoryAddress, value, MemorySize)
-
-#endif /* LINUX_KERNEL */
-
-/**********************************************************************/
-/* XFree86/X.org */
-/**********************************************************************/
-
-#ifdef SIS_XORG_XF86
-
-#define SIS300
-#define SIS315H
-
-#define OutPortByte(p,v) outSISREG((IOADDRESS)(p),(CARD8)(v))
-#define OutPortWord(p,v) outSISREGW((IOADDRESS)(p),(CARD16)(v))
-#define OutPortLong(p,v) outSISREGL((IOADDRESS)(p),(CARD32)(v))
-#define InPortByte(p) inSISREG((IOADDRESS)(p))
-#define InPortWord(p) inSISREGW((IOADDRESS)(p))
-#define InPortLong(p) inSISREGL((IOADDRESS)(p))
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
-
-#endif /* XF86 */
-
-#endif /* _OSDEF_H_ */
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index 7c5710e3fb56..80d89d37c414 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -24,7 +24,6 @@
#ifndef _SIS_H_
#define _SIS_H_
-#include "osdef.h"
#include <video/sisfb.h>
#include "vgatypes.h"
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 3dde12b0ab06..7e3370f115b6 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -60,6 +60,11 @@
#include "sis.h"
#include "sis_main.h"
+#if !defined(CONFIG_FB_SIS_300) && !defined(CONFIG_FB_SIS_315)
+#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
+#warning sisfb will not work!
+#endif
+
static void sisfb_handle_command(struct sis_video_info *ivideo,
struct sisfb_cmd *sisfb_command);
@@ -4114,14 +4119,6 @@ sisfb_find_rom(struct pci_dev *pdev)
if(sisfb_check_rom(rom_base, ivideo)) {
if((myrombase = vmalloc(65536))) {
-
- /* Work around bug in pci/rom.c: Folks forgot to check
- * whether the size retrieved from the BIOS image eventually
- * is larger than the mapped size
- */
- if(pci_resource_len(pdev, PCI_ROM_RESOURCE) < romsize)
- romsize = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-
memcpy_fromio(myrombase, rom_base,
(romsize > 65536) ? 65536 : romsize);
}
@@ -4155,23 +4152,6 @@ sisfb_find_rom(struct pci_dev *pdev)
}
-#else
-
- pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &temp);
- pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
- (ivideo->video_base & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
-
- rom_base = ioremap(ivideo->video_base, 65536);
- if(rom_base) {
- if(sisfb_check_rom(rom_base, ivideo)) {
- if((myrombase = vmalloc(65536)))
- memcpy_fromio(myrombase, rom_base, 65536);
- }
- iounmap(rom_base);
- }
-
- pci_write_config_dword(pdev, PCI_ROM_ADDRESS, temp);
-
#endif
return myrombase;
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 81a22eaabfde..12c0dfaf2518 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -55,21 +55,10 @@
#define SISIOMEMTYPE
-#ifdef SIS_LINUX_KERNEL
typedef unsigned long SISIOADDRESS;
#include <linux/types.h> /* Need __iomem */
#undef SISIOMEMTYPE
#define SISIOMEMTYPE __iomem
-#endif
-
-#ifdef SIS_XORG_XF86
-#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
-typedef unsigned long IOADDRESS;
-typedef unsigned long SISIOADDRESS;
-#else
-typedef IOADDRESS SISIOADDRESS;
-#endif
-#endif
typedef enum _SIS_CHIP_TYPE {
SIS_VGALegacy = 0,
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
index bef4aae388d0..ea94d214dcff 100644
--- a/drivers/video/sis/vstruct.h
+++ b/drivers/video/sis/vstruct.h
@@ -233,24 +233,15 @@ struct SiS_Private
{
unsigned char ChipType;
unsigned char ChipRevision;
-#ifdef SIS_XORG_XF86
- PCITAG PciTag;
-#endif
-#ifdef SIS_LINUX_KERNEL
void *ivideo;
-#endif
unsigned char *VirtualRomBase;
bool UseROM;
-#ifdef SIS_LINUX_KERNEL
unsigned char SISIOMEMTYPE *VideoMemoryAddress;
unsigned int VideoMemorySize;
-#endif
SISIOADDRESS IOAddress;
SISIOADDRESS IOAddress2; /* For dual chip XGI volari */
-#ifdef SIS_LINUX_KERNEL
SISIOADDRESS RelIO;
-#endif
SISIOADDRESS SiS_P3c4;
SISIOADDRESS SiS_P3d4;
SISIOADDRESS SiS_P3c0;
@@ -280,9 +271,6 @@ struct SiS_Private
unsigned short SiS_IF_DEF_FSTN;
unsigned short SiS_SysFlags;
unsigned char SiS_VGAINFO;
-#ifdef SIS_XORG_XF86
- unsigned short SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
-#endif
bool SiS_UseROM;
bool SiS_ROMNew;
bool SiS_XGIROM;
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 3a43ebf83a49..efb35aa8309a 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -9,19 +9,19 @@ static ssize_t device_show(struct device *_d,
struct device_attribute *attr, char *buf)
{
struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
- return sprintf(buf, "%hu", dev->id.device);
+ return sprintf(buf, "0x%04x\n", dev->id.device);
}
static ssize_t vendor_show(struct device *_d,
struct device_attribute *attr, char *buf)
{
struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
- return sprintf(buf, "%hu", dev->id.vendor);
+ return sprintf(buf, "0x%04x\n", dev->id.vendor);
}
static ssize_t status_show(struct device *_d,
struct device_attribute *attr, char *buf)
{
struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
- return sprintf(buf, "0x%08x", dev->config->get_status(dev));
+ return sprintf(buf, "0x%08x\n", dev->config->get_status(dev));
}
static ssize_t modalias_show(struct device *_d,
struct device_attribute *attr, char *buf)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 1475ed6b575f..cc2f73e03475 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -230,9 +230,6 @@ add_head:
pr_debug("Added buffer head %i to %p\n", head, vq);
END_USE(vq);
- /* If we're indirect, we can fit many (assuming not OOM). */
- if (vq->indirect)
- return vq->num_free ? vq->vring.num : 0;
return vq->num_free;
}
EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4a291045ebac..a5ad77ef4266 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -558,6 +558,9 @@ config IT8712F_WDT
This is the driver for the built-in watchdog timer on the IT8712F
Super I/0 chipset used on many motherboards.
+ If the driver does not work, then make sure that the game port in
+ the BIOS is enabled.
+
To compile this driver as a module, choose M here: the
module will be called it8712f_wdt.
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index a1debc89356b..3c5045a206dd 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -18,7 +18,6 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/reboot.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/watchdog.h>
@@ -220,14 +219,6 @@ static long bcm63xx_wdt_ioctl(struct file *file, unsigned int cmd,
}
}
-static int bcm63xx_wdt_notify_sys(struct notifier_block *this,
- unsigned long code, void *unused)
-{
- if (code == SYS_DOWN || code == SYS_HALT)
- bcm63xx_wdt_pause();
- return NOTIFY_DONE;
-}
-
static const struct file_operations bcm63xx_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -243,12 +234,8 @@ static struct miscdevice bcm63xx_wdt_miscdev = {
.fops = &bcm63xx_wdt_fops,
};
-static struct notifier_block bcm63xx_wdt_notifier = {
- .notifier_call = bcm63xx_wdt_notify_sys,
-};
-
-static int bcm63xx_wdt_probe(struct platform_device *pdev)
+static int __devinit bcm63xx_wdt_probe(struct platform_device *pdev)
{
int ret;
struct resource *r;
@@ -280,16 +267,10 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
wdt_time);
}
- ret = register_reboot_notifier(&bcm63xx_wdt_notifier);
- if (ret) {
- dev_err(&pdev->dev, "failed to register reboot_notifier\n");
- goto unregister_timer;
- }
-
ret = misc_register(&bcm63xx_wdt_miscdev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to register watchdog device\n");
- goto unregister_reboot_notifier;
+ goto unregister_timer;
}
dev_info(&pdev->dev, " started, timer margin: %d sec\n",
@@ -297,8 +278,6 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
return 0;
-unregister_reboot_notifier:
- unregister_reboot_notifier(&bcm63xx_wdt_notifier);
unregister_timer:
bcm63xx_timer_unregister(TIMER_WDT_ID);
unmap:
@@ -306,25 +285,28 @@ unmap:
return ret;
}
-static int bcm63xx_wdt_remove(struct platform_device *pdev)
+static int __devexit bcm63xx_wdt_remove(struct platform_device *pdev)
{
if (!nowayout)
bcm63xx_wdt_pause();
misc_deregister(&bcm63xx_wdt_miscdev);
-
- iounmap(bcm63xx_wdt_device.regs);
-
- unregister_reboot_notifier(&bcm63xx_wdt_notifier);
bcm63xx_timer_unregister(TIMER_WDT_ID);
-
+ iounmap(bcm63xx_wdt_device.regs);
return 0;
}
+static void bcm63xx_wdt_shutdown(struct platform_device *pdev)
+{
+ bcm63xx_wdt_pause();
+}
+
static struct platform_driver bcm63xx_wdt = {
.probe = bcm63xx_wdt_probe,
- .remove = bcm63xx_wdt_remove,
+ .remove = __devexit_p(bcm63xx_wdt_remove),
+ .shutdown = bcm63xx_wdt_shutdown,
.driver = {
+ .owner = THIS_MODULE,
.name = "bcm63xx-wdt",
}
};
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index 9c21d19043a6..f6bd6f10fcec 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
+#include <linux/fs.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/io.h>
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index f7e90fe47b71..b8838d2c67a6 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -32,6 +32,7 @@
* document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH)
* document number 320066-003, 320257-008: EP80597 (IICH)
* document number TBD : Cougar Point (CPT)
+ * document number TBD : Patsburg (PBG)
*/
/*
@@ -146,7 +147,8 @@ enum iTCO_chipsets {
TCO_CPT29, /* Cougar Point */
TCO_CPT30, /* Cougar Point */
TCO_CPT31, /* Cougar Point */
- TCO_PBG, /* Patsburg */
+ TCO_PBG1, /* Patsburg */
+ TCO_PBG2, /* Patsburg */
};
static struct {
@@ -235,6 +237,7 @@ static struct {
{"Cougar Point", 2},
{"Cougar Point", 2},
{"Patsburg", 2},
+ {"Patsburg", 2},
{NULL, 0}
};
@@ -350,7 +353,8 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
{ ITCO_PCI_DEVICE(0x1c5d, TCO_CPT29)},
{ ITCO_PCI_DEVICE(0x1c5e, TCO_CPT30)},
{ ITCO_PCI_DEVICE(0x1c5f, TCO_CPT31)},
- { ITCO_PCI_DEVICE(0x1d40, TCO_PBG)},
+ { ITCO_PCI_DEVICE(0x1d40, TCO_PBG1)},
+ { ITCO_PCI_DEVICE(0x1d41, TCO_PBG2)},
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index eb8a78d77d9d..533a199e7a3f 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -8,9 +8,12 @@ obj-$(CONFIG_BLOCK) += biomerge.o
obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
obj-$(CONFIG_XEN_BALLOON) += balloon.o
-obj-$(CONFIG_XEN_DEV_EVTCHN) += evtchn.o
+obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o
obj-$(CONFIG_XENFS) += xenfs/
obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o
obj-$(CONFIG_XEN_DOM0) += pci.o
+
+xen-evtchn-y := evtchn.o
+
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 500290b150bb..43f9f02c7db0 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -50,6 +50,7 @@
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/tlb.h>
+#include <asm/e820.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
@@ -119,7 +120,7 @@ static void scrub_page(struct page *page)
}
/* balloon_append: add the given page to the balloon. */
-static void balloon_append(struct page *page)
+static void __balloon_append(struct page *page)
{
/* Lowmem is re-populated first, so highmem pages go at list tail. */
if (PageHighMem(page)) {
@@ -130,7 +131,11 @@ static void balloon_append(struct page *page)
list_add(&page->lru, &ballooned_pages);
balloon_stats.balloon_low++;
}
+}
+static void balloon_append(struct page *page)
+{
+ __balloon_append(page);
totalram_pages--;
}
@@ -191,7 +196,7 @@ static unsigned long current_target(void)
static int increase_reservation(unsigned long nr_pages)
{
- unsigned long pfn, i, flags;
+ unsigned long pfn, i;
struct page *page;
long rc;
struct xen_memory_reservation reservation = {
@@ -203,8 +208,6 @@ static int increase_reservation(unsigned long nr_pages)
if (nr_pages > ARRAY_SIZE(frame_list))
nr_pages = ARRAY_SIZE(frame_list);
- spin_lock_irqsave(&xen_reservation_lock, flags);
-
page = balloon_first_page();
for (i = 0; i < nr_pages; i++) {
BUG_ON(page == NULL);
@@ -247,14 +250,12 @@ static int increase_reservation(unsigned long nr_pages)
balloon_stats.current_pages += rc;
out:
- spin_unlock_irqrestore(&xen_reservation_lock, flags);
-
return rc < 0 ? rc : rc != nr_pages;
}
static int decrease_reservation(unsigned long nr_pages)
{
- unsigned long pfn, i, flags;
+ unsigned long pfn, i;
struct page *page;
int need_sleep = 0;
int ret;
@@ -292,8 +293,6 @@ static int decrease_reservation(unsigned long nr_pages)
kmap_flush_unused();
flush_tlb_all();
- spin_lock_irqsave(&xen_reservation_lock, flags);
-
/* No more mappings: invalidate P2M and add to balloon. */
for (i = 0; i < nr_pages; i++) {
pfn = mfn_to_pfn(frame_list[i]);
@@ -308,8 +307,6 @@ static int decrease_reservation(unsigned long nr_pages)
balloon_stats.current_pages -= nr_pages;
- spin_unlock_irqrestore(&xen_reservation_lock, flags);
-
return need_sleep;
}
@@ -395,7 +392,7 @@ static struct notifier_block xenstore_notifier;
static int __init balloon_init(void)
{
- unsigned long pfn;
+ unsigned long pfn, extra_pfn_end;
struct page *page;
if (!xen_pv_domain())
@@ -415,11 +412,24 @@ static int __init balloon_init(void)
register_balloon(&balloon_sysdev);
- /* Initialise the balloon with excess memory space. */
- for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
+ /*
+ * Initialise the balloon with excess memory space. We need
+ * to make sure we don't add memory which doesn't exist or
+ * logically exist. The E820 map can be trimmed to be smaller
+ * than the amount of physical memory due to the mem= command
+ * line parameter. And if this is a 32-bit non-HIGHMEM kernel
+ * on a system with memory which requires highmem to access,
+ * don't try to use it.
+ */
+ extra_pfn_end = min(min(max_pfn, e820_end_of_ram_pfn()),
+ (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size));
+ for (pfn = PFN_UP(xen_extra_mem_start);
+ pfn < extra_pfn_end;
+ pfn++) {
page = pfn_to_page(pfn);
- if (!PageReserved(page))
- balloon_append(page);
+ /* totalram_pages doesn't include the boot-time
+ balloon extension, so don't subtract from it. */
+ __balloon_append(page);
}
target_watch.callback = watch_target;
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 321a0c8346e5..31af0ac31a98 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -105,7 +105,6 @@ struct irq_info
static struct irq_info *irq_info;
static int *pirq_to_irq;
-static int nr_pirqs;
static int *evtchn_to_irq;
struct cpu_evtchn_s {
@@ -278,17 +277,17 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu));
#endif
- __clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq)));
- __set_bit(chn, cpu_evtchn_mask(cpu));
+ clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq)));
+ set_bit(chn, cpu_evtchn_mask(cpu));
irq_info[irq].cpu = cpu;
}
static void init_evtchn_cpu_bindings(void)
{
+ int i;
#ifdef CONFIG_SMP
struct irq_desc *desc;
- int i;
/* By default all event channels notify CPU#0. */
for_each_irq_desc(i, desc) {
@@ -296,7 +295,10 @@ static void init_evtchn_cpu_bindings(void)
}
#endif
- memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s));
+ for_each_possible_cpu(i)
+ memset(cpu_evtchn_mask(i),
+ (i == 0) ? ~0 : 0, sizeof(struct cpu_evtchn_s));
+
}
static inline void clear_evtchn(int port)
@@ -382,12 +384,17 @@ static int get_nr_hw_irqs(void)
return ret;
}
-/* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs
- * succeeded otherwise nr_pirqs won't hold the right value */
-static int find_unbound_pirq(void)
+static int find_unbound_pirq(int type)
{
- int i;
- for (i = nr_pirqs-1; i >= 0; i--) {
+ int rc, i;
+ struct physdev_get_free_pirq op_get_free_pirq;
+ op_get_free_pirq.type = type;
+
+ rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
+ if (!rc)
+ return op_get_free_pirq.pirq;
+
+ for (i = 0; i < nr_irqs; i++) {
if (pirq_to_irq[i] < 0)
return i;
}
@@ -420,7 +427,7 @@ static int find_unbound_irq(void)
if (irq == start)
goto no_irqs;
- res = irq_alloc_desc_at(irq, 0);
+ res = irq_alloc_desc_at(irq, -1);
if (WARN_ON(res != irq))
return -1;
@@ -608,10 +615,10 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
spin_lock(&irq_mapping_update_lock);
- if ((pirq > nr_pirqs) || (gsi > nr_irqs)) {
+ if ((pirq > nr_irqs) || (gsi > nr_irqs)) {
printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n",
- pirq > nr_pirqs ? "nr_pirqs" :"",
- gsi > nr_irqs ? "nr_irqs" : "");
+ pirq > nr_irqs ? "pirq" :"",
+ gsi > nr_irqs ? "gsi" : "");
goto out;
}
@@ -627,7 +634,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
xen_pv_domain())) {
irq = gsi;
- irq_alloc_desc_at(irq, 0);
+ irq_alloc_desc_at(irq, -1);
} else
irq = find_unbound_irq();
@@ -661,17 +668,21 @@ out:
#include <linux/msi.h>
#include "../pci/msi.h"
-void xen_allocate_pirq_msi(char *name, int *irq, int *pirq)
+void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc)
{
spin_lock(&irq_mapping_update_lock);
- *irq = find_unbound_irq();
- if (*irq == -1)
- goto out;
+ if (alloc & XEN_ALLOC_IRQ) {
+ *irq = find_unbound_irq();
+ if (*irq == -1)
+ goto out;
+ }
- *pirq = find_unbound_pirq();
- if (*pirq == -1)
- goto out;
+ if (alloc & XEN_ALLOC_PIRQ) {
+ *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI);
+ if (*pirq == -1)
+ goto out;
+ }
set_irq_chip_and_handler_name(*irq, &xen_pirq_chip,
handle_level_irq, name);
@@ -752,13 +763,14 @@ int xen_destroy_irq(int irq)
goto out;
if (xen_initial_domain()) {
- unmap_irq.pirq = info->u.pirq.gsi;
+ unmap_irq.pirq = info->u.pirq.pirq;
unmap_irq.domid = DOMID_SELF;
rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
if (rc) {
printk(KERN_WARNING "unmap irq failed %d\n", rc);
goto out;
}
+ pirq_to_irq[info->u.pirq.pirq] = -1;
}
irq_info[irq] = mk_unbound_info();
@@ -779,6 +791,11 @@ int xen_gsi_from_irq(unsigned irq)
return gsi_from_irq(irq);
}
+int xen_irq_from_pirq(unsigned pirq)
+{
+ return pirq_to_irq[pirq];
+}
+
int bind_evtchn_to_irq(unsigned int evtchn)
{
int irq;
@@ -1276,6 +1293,42 @@ static int retrigger_dynirq(unsigned int irq)
return ret;
}
+static void restore_cpu_pirqs(void)
+{
+ int pirq, rc, irq, gsi;
+ struct physdev_map_pirq map_irq;
+
+ for (pirq = 0; pirq < nr_irqs; pirq++) {
+ irq = pirq_to_irq[pirq];
+ if (irq == -1)
+ continue;
+
+ /* save/restore of PT devices doesn't work, so at this point the
+ * only devices present are GSI based emulated devices */
+ gsi = gsi_from_irq(irq);
+ if (!gsi)
+ continue;
+
+ map_irq.domid = DOMID_SELF;
+ map_irq.type = MAP_PIRQ_TYPE_GSI;
+ map_irq.index = gsi;
+ map_irq.pirq = pirq;
+
+ rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+ if (rc) {
+ printk(KERN_WARNING "xen map irq failed gsi=%d irq=%d pirq=%d rc=%d\n",
+ gsi, irq, pirq, rc);
+ irq_info[irq] = mk_unbound_info();
+ pirq_to_irq[pirq] = -1;
+ continue;
+ }
+
+ printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
+
+ startup_pirq(irq);
+ }
+}
+
static void restore_cpu_virqs(unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
@@ -1419,6 +1472,8 @@ void xen_irq_resume(void)
unmask_evtchn(evtchn);
}
+
+ restore_cpu_pirqs();
}
static struct irq_chip xen_dynamic_chip __read_mostly = {
@@ -1503,26 +1558,17 @@ void xen_callback_vector(void) {}
void __init xen_init_IRQ(void)
{
- int i, rc;
- struct physdev_nr_pirqs op_nr_pirqs;
+ int i;
cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
GFP_KERNEL);
irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL);
- rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs);
- if (rc < 0) {
- nr_pirqs = nr_irqs;
- if (rc != -ENOSYS)
- printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc);
- } else {
- if (xen_pv_domain() && !xen_initial_domain())
- nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs);
- else
- nr_pirqs = op_nr_pirqs.nr_pirqs;
- }
- pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL);
- for (i = 0; i < nr_pirqs; i++)
+ /* We are using nr_irqs as the maximum number of pirq available but
+ * that number is actually chosen by Xen and we don't know exactly
+ * what it is. Be careful choosing high pirq numbers. */
+ pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL);
+ for (i = 0; i < nr_irqs; i++)
pirq_to_irq[i] = -1;
evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index fec6ba3c08a8..ef11daf0cafe 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -69,20 +69,51 @@ struct per_user_data {
const char *name;
};
-/* Who's bound to each port? */
-static struct per_user_data *port_user[NR_EVENT_CHANNELS];
+/*
+ * Who's bound to each port? This is logically an array of struct
+ * per_user_data *, but we encode the current enabled-state in bit 0.
+ */
+static unsigned long *port_user;
static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */
-irqreturn_t evtchn_interrupt(int irq, void *data)
+static inline struct per_user_data *get_port_user(unsigned port)
+{
+ return (struct per_user_data *)(port_user[port] & ~1);
+}
+
+static inline void set_port_user(unsigned port, struct per_user_data *u)
+{
+ port_user[port] = (unsigned long)u;
+}
+
+static inline bool get_port_enabled(unsigned port)
+{
+ return port_user[port] & 1;
+}
+
+static inline void set_port_enabled(unsigned port, bool enabled)
+{
+ if (enabled)
+ port_user[port] |= 1;
+ else
+ port_user[port] &= ~1;
+}
+
+static irqreturn_t evtchn_interrupt(int irq, void *data)
{
unsigned int port = (unsigned long)data;
struct per_user_data *u;
spin_lock(&port_user_lock);
- u = port_user[port];
+ u = get_port_user(port);
+
+ WARN(!get_port_enabled(port),
+ "Interrupt for port %d, but apparently not enabled; per-user %p\n",
+ port, u);
disable_irq_nosync(irq);
+ set_port_enabled(port, false);
if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
@@ -92,9 +123,8 @@ irqreturn_t evtchn_interrupt(int irq, void *data)
kill_fasync(&u->evtchn_async_queue,
SIGIO, POLL_IN);
}
- } else {
+ } else
u->ring_overflow = 1;
- }
spin_unlock(&port_user_lock);
@@ -198,9 +228,18 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf,
goto out;
spin_lock_irq(&port_user_lock);
- for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
- if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
- enable_irq(irq_from_evtchn(kbuf[i]));
+
+ for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) {
+ unsigned port = kbuf[i];
+
+ if (port < NR_EVENT_CHANNELS &&
+ get_port_user(port) == u &&
+ !get_port_enabled(port)) {
+ set_port_enabled(port, true);
+ enable_irq(irq_from_evtchn(port));
+ }
+ }
+
spin_unlock_irq(&port_user_lock);
rc = count;
@@ -222,8 +261,9 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port)
* interrupt handler yet, and our caller has already
* serialized bind operations.)
*/
- BUG_ON(port_user[port] != NULL);
- port_user[port] = u;
+ BUG_ON(get_port_user(port) != NULL);
+ set_port_user(port, u);
+ set_port_enabled(port, true); /* start enabled */
rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED,
u->name, (void *)(unsigned long)port);
@@ -239,10 +279,7 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port)
unbind_from_irqhandler(irq, (void *)(unsigned long)port);
- /* make sure we unbind the irq handler before clearing the port */
- barrier();
-
- port_user[port] = NULL;
+ set_port_user(port, NULL);
}
static long evtchn_ioctl(struct file *file,
@@ -333,15 +370,17 @@ static long evtchn_ioctl(struct file *file,
spin_lock_irq(&port_user_lock);
rc = -ENOTCONN;
- if (port_user[unbind.port] != u) {
+ if (get_port_user(unbind.port) != u) {
spin_unlock_irq(&port_user_lock);
break;
}
- evtchn_unbind_from_user(u, unbind.port);
+ disable_irq(irq_from_evtchn(unbind.port));
spin_unlock_irq(&port_user_lock);
+ evtchn_unbind_from_user(u, unbind.port);
+
rc = 0;
break;
}
@@ -355,7 +394,7 @@ static long evtchn_ioctl(struct file *file,
if (notify.port >= NR_EVENT_CHANNELS) {
rc = -EINVAL;
- } else if (port_user[notify.port] != u) {
+ } else if (get_port_user(notify.port) != u) {
rc = -ENOTCONN;
} else {
notify_remote_via_evtchn(notify.port);
@@ -431,7 +470,7 @@ static int evtchn_open(struct inode *inode, struct file *filp)
filp->private_data = u;
- return 0;
+ return nonseekable_open(inode, filp);;
}
static int evtchn_release(struct inode *inode, struct file *filp)
@@ -444,14 +483,21 @@ static int evtchn_release(struct inode *inode, struct file *filp)
free_page((unsigned long)u->ring);
for (i = 0; i < NR_EVENT_CHANNELS; i++) {
- if (port_user[i] != u)
+ if (get_port_user(i) != u)
continue;
- evtchn_unbind_from_user(port_user[i], i);
+ disable_irq(irq_from_evtchn(i));
}
spin_unlock_irq(&port_user_lock);
+ for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+ if (get_port_user(i) != u)
+ continue;
+
+ evtchn_unbind_from_user(get_port_user(i), i);
+ }
+
kfree(u->name);
kfree(u);
@@ -467,12 +513,12 @@ static const struct file_operations evtchn_fops = {
.fasync = evtchn_fasync,
.open = evtchn_open,
.release = evtchn_release,
- .llseek = noop_llseek,
+ .llseek = no_llseek,
};
static struct miscdevice evtchn_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
- .name = "evtchn",
+ .name = "xen/evtchn",
.fops = &evtchn_fops,
};
static int __init evtchn_init(void)
@@ -482,8 +528,11 @@ static int __init evtchn_init(void)
if (!xen_domain())
return -ENODEV;
+ port_user = kcalloc(NR_EVENT_CHANNELS, sizeof(*port_user), GFP_KERNEL);
+ if (port_user == NULL)
+ return -ENOMEM;
+
spin_lock_init(&port_user_lock);
- memset(port_user, 0, sizeof(port_user));
/* Create '/dev/misc/evtchn'. */
err = misc_register(&evtchn_miscdev);
@@ -499,6 +548,9 @@ static int __init evtchn_init(void)
static void __exit evtchn_cleanup(void)
{
+ kfree(port_user);
+ port_user = NULL;
+
misc_deregister(&evtchn_miscdev);
}
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index ef9c7db52077..db8c4c4ac880 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -49,6 +49,7 @@ static int xen_hvm_suspend(void *data)
if (!*cancelled) {
xen_irq_resume();
+ xen_console_resume();
xen_timer_resume();
}
diff --git a/drivers/xen/xenfs/privcmd.c b/drivers/xen/xenfs/privcmd.c
index f80be7f6eb95..dbd3b16fd131 100644
--- a/drivers/xen/xenfs/privcmd.c
+++ b/drivers/xen/xenfs/privcmd.c
@@ -15,7 +15,6 @@
#include <linux/mman.h>
#include <linux/uaccess.h>
#include <linux/swap.h>
-#include <linux/smp_lock.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/seq_file.h>
@@ -266,9 +265,7 @@ static int mmap_return_errors(void *data, void *state)
xen_pfn_t *mfnp = data;
struct mmap_batch_state *st = state;
- put_user(*mfnp, st->user++);
-
- return 0;
+ return put_user(*mfnp, st->user++);
}
static struct vm_operations_struct privcmd_vm_ops;
@@ -323,10 +320,8 @@ static long privcmd_ioctl_mmap_batch(void __user *udata)
up_write(&mm->mmap_sem);
if (state.err > 0) {
- ret = 0;
-
state.user = m.arr;
- traverse_pages(m.num, sizeof(xen_pfn_t),
+ ret = traverse_pages(m.num, sizeof(xen_pfn_t),
&pagelist,
mmap_return_errors, &state);
}
@@ -384,8 +379,9 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
if (xen_feature(XENFEAT_auto_translated_physmap))
return -ENOSYS;
- /* DONTCOPY is essential for Xen as copy_page_range is broken. */
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+ /* DONTCOPY is essential for Xen because copy_page_range doesn't know
+ * how to recreate these mappings */
+ vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
vma->vm_ops = &privcmd_vm_ops;
vma->vm_private_data = NULL;
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
index f6339d11d59c..1aa389719846 100644
--- a/drivers/xen/xenfs/super.c
+++ b/drivers/xen/xenfs/super.c
@@ -12,8 +12,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/magic.h>
-#include <linux/mm.h>
-#include <linux/backing-dev.h>
#include <xen/xen.h>
@@ -24,28 +22,12 @@
MODULE_DESCRIPTION("Xen filesystem");
MODULE_LICENSE("GPL");
-static int xenfs_set_page_dirty(struct page *page)
-{
- return !TestSetPageDirty(page);
-}
-
-static const struct address_space_operations xenfs_aops = {
- .set_page_dirty = xenfs_set_page_dirty,
-};
-
-static struct backing_dev_info xenfs_backing_dev_info = {
- .ra_pages = 0, /* No readahead */
- .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
-};
-
static struct inode *xenfs_make_inode(struct super_block *sb, int mode)
{
struct inode *ret = new_inode(sb);
if (ret) {
ret->i_mode = mode;
- ret->i_mapping->a_ops = &xenfs_aops;
- ret->i_mapping->backing_dev_info = &xenfs_backing_dev_info;
ret->i_uid = ret->i_gid = 0;
ret->i_blocks = 0;
ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
@@ -121,9 +103,9 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent)
return rc;
}
-static int xenfs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name,
- void *data)
+static struct dentry *xenfs_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name,
+ void *data)
{
return mount_single(fs_type, flags, data, xenfs_fill_super);
}
@@ -137,25 +119,11 @@ static struct file_system_type xenfs_type = {
static int __init xenfs_init(void)
{
- int err;
- if (!xen_domain()) {
- printk(KERN_INFO "xenfs: not registering filesystem on non-xen platform\n");
- return 0;
- }
-
- err = register_filesystem(&xenfs_type);
- if (err) {
- printk(KERN_ERR "xenfs: Unable to register filesystem!\n");
- goto out;
- }
-
- err = bdi_init(&xenfs_backing_dev_info);
- if (err)
- unregister_filesystem(&xenfs_type);
-
- out:
+ if (xen_domain())
+ return register_filesystem(&xenfs_type);
- return err;
+ printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n");
+ return 0;
}
static void __exit xenfs_exit(void)
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index cafc50454292..e0c84725d3e9 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -13,7 +13,6 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/amigahw.h>
#include <asm/setup.h>