aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/asus_acpi.c2
-rw-r--r--drivers/acpi/numa.c2
-rw-r--r--drivers/acpi/osl.c118
-rw-r--r--drivers/acpi/tables/tbinstal.c8
-rw-r--r--drivers/acpi/thermal.c13
-rw-r--r--drivers/acpi/toshiba_acpi.c2
-rw-r--r--drivers/acpi/utilities/utcopy.c120
-rw-r--r--drivers/acpi/utilities/uteval.c28
-rw-r--r--drivers/acpi/utilities/utobject.c42
-rw-r--r--drivers/acpi/utilities/utxface.c4
-rw-r--r--drivers/ata/ahci.c24
-rw-r--r--drivers/ata/ata_piix.c1
-rw-r--r--drivers/ata/libata-core.c80
-rw-r--r--drivers/ata/libata-scsi.c72
-rw-r--r--drivers/ata/libata-sff.c37
-rw-r--r--drivers/ata/pata_artop.c2
-rw-r--r--drivers/ata/pata_hpt37x.c27
-rw-r--r--drivers/ata/pata_hpt3x2n.c4
-rw-r--r--drivers/ata/pata_isapnp.c1
-rw-r--r--drivers/ata/pata_it821x.c3
-rw-r--r--drivers/ata/pata_scc.c46
-rw-r--r--drivers/ata/pata_sis.c46
-rw-r--r--drivers/ata/pata_via.c50
-rw-r--r--drivers/ata/sata_mv.c44
-rw-r--r--drivers/ata/sata_promise.c11
-rw-r--r--drivers/ata/sata_sis.c2
-rw-r--r--drivers/ata/sata_via.c3
-rw-r--r--drivers/atm/firestream.c15
-rw-r--r--drivers/atm/idt77252.c27
-rw-r--r--drivers/atm/idt77252.h4
-rw-r--r--drivers/auxdisplay/Kconfig4
-rw-r--r--drivers/auxdisplay/cfag12864bfb.c8
-rw-r--r--drivers/base/class.c59
-rw-r--r--drivers/base/core.c10
-rw-r--r--drivers/base/dd.c13
-rw-r--r--drivers/base/firmware_class.c4
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/block/loop.c100
-rw-r--r--drivers/bluetooth/hci_usb.c16
-rw-r--r--drivers/cdrom/mcdx.c2
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/agp/agp.h6
-rw-r--r--drivers/char/agp/intel-agp.c579
-rw-r--r--drivers/char/cyclades.c1
-rw-r--r--drivers/char/drm/Kconfig2
-rw-r--r--drivers/char/drm/drm_drawable.c41
-rw-r--r--drivers/char/drm/drm_pciids.h7
-rw-r--r--drivers/char/drm/i915_irq.c2
-rw-r--r--drivers/char/n_tty.c1
-rw-r--r--drivers/char/random.c67
-rw-r--r--drivers/char/stallion.c81
-rw-r--r--drivers/char/tty_io.c3
-rw-r--r--drivers/char/watchdog/Kconfig7
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/ixp2000_wdt.c2
-rw-r--r--drivers/char/watchdog/ks8695_wdt.c308
-rw-r--r--drivers/crypto/geode-aes.c12
-rw-r--r--drivers/crypto/geode-aes.h3
-rw-r--r--drivers/firewire/Kconfig14
-rw-r--r--drivers/firewire/Makefile12
-rw-r--r--drivers/firewire/fw-card.c5
-rw-r--r--drivers/firewire/fw-cdev.c19
-rw-r--r--drivers/firewire/fw-device.h1
-rw-r--r--drivers/firewire/fw-ohci.c188
-rw-r--r--drivers/firewire/fw-sbp2.c53
-rw-r--r--drivers/hwmon/Kconfig2
-rw-r--r--drivers/hwmon/applesmc.c17
-rw-r--r--drivers/hwmon/coretemp.c32
-rw-r--r--drivers/hwmon/ds1621.c8
-rw-r--r--drivers/hwmon/hwmon-vid.c4
-rw-r--r--drivers/hwmon/w83627hf.c4
-rw-r--r--drivers/i2c/busses/i2c-pxa.c23
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c3
-rw-r--r--drivers/i2c/busses/i2c-tiny-usb.c2
-rw-r--r--drivers/i2c/i2c-core.c5
-rw-r--r--drivers/ide/ide-disk.c12
-rw-r--r--drivers/ide/ide-dma.c4
-rw-r--r--drivers/ide/ide-probe.c12
-rw-r--r--drivers/ide/ide-proc.c2
-rw-r--r--drivers/ide/ide.c9
-rw-r--r--drivers/ide/pci/amd74xx.c12
-rw-r--r--drivers/ide/pci/atiixp.c1
-rw-r--r--drivers/ide/pci/generic.c37
-rw-r--r--drivers/ide/pci/hpt366.c8
-rw-r--r--drivers/ide/pci/it821x.c34
-rw-r--r--drivers/ide/pci/serverworks.c57
-rw-r--r--drivers/ieee1394/eth1394.c91
-rw-r--r--drivers/ieee1394/eth1394.h4
-rw-r--r--drivers/ieee1394/nodemgr.c7
-rw-r--r--drivers/ieee1394/nodemgr.h1
-rw-r--r--drivers/ieee1394/raw1394.c8
-rw-r--r--drivers/ieee1394/sbp2.c32
-rw-r--r--drivers/infiniband/core/cm.c25
-rw-r--r--drivers/infiniband/core/cma.c4
-rw-r--r--drivers/infiniband/hw/amso1100/c2.c2
-rw-r--r--drivers/infiniband/hw/ehca/hcp_if.c2
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c92
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c77
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c31
-rw-r--r--drivers/input/Kconfig13
-rw-r--r--drivers/input/Makefile1
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/input/input-polldev.c (renamed from drivers/input/misc/input-polldev.c)5
-rw-r--r--drivers/input/joydev.c2
-rw-r--r--drivers/input/joystick/db9.c2
-rw-r--r--drivers/input/joystick/iforce/iforce-main.c4
-rw-r--r--drivers/input/joystick/iforce/iforce-packets.c10
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c5
-rw-r--r--drivers/input/keyboard/pxa27x_keyboard.c6
-rw-r--r--drivers/input/misc/Kconfig11
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/mouse/Kconfig2
-rw-r--r--drivers/input/mouse/alps.c58
-rw-r--r--drivers/input/mouse/logips2pp.c1
-rw-r--r--drivers/input/mousedev.c2
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h18
-rw-r--r--drivers/input/serio/sa1111ps2.c4
-rw-r--r--drivers/input/touchscreen/Kconfig8
-rw-r--r--drivers/input/touchscreen/ads7846.c3
-rw-r--r--drivers/input/touchscreen/hp680_ts_input.c7
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c4
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c44
-rw-r--r--drivers/input/tsdev.c2
-rw-r--r--drivers/isdn/Kconfig9
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.c16
-rw-r--r--drivers/isdn/hardware/eicon/diva_didd.c2
-rw-r--r--drivers/isdn/hardware/eicon/divasfunc.c4
-rw-r--r--drivers/isdn/hardware/eicon/message.c13
-rw-r--r--drivers/isdn/hisax/config.c2
-rw-r--r--drivers/isdn/hisax/hfc_usb.c43
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c6
-rw-r--r--drivers/isdn/hisax/st5481_init.c7
-rw-r--r--drivers/isdn/hisax/st5481_usb.c1
-rw-r--r--drivers/isdn/i4l/isdn_tty.c3
-rw-r--r--drivers/kvm/vmx.c2
-rw-r--r--drivers/macintosh/Kconfig3
-rw-r--r--drivers/macintosh/adbhid.c16
-rw-r--r--drivers/md/bitmap.c17
-rw-r--r--drivers/md/linear.c10
-rw-r--r--drivers/md/md.c20
-rw-r--r--drivers/md/raid0.c3
-rw-r--r--drivers/media/common/Kconfig1
-rw-r--r--drivers/media/dvb/b2c2/Makefile7
-rw-r--r--drivers/media/dvb/bt8xx/dst.c3
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c15
-rw-r--r--drivers/media/dvb/frontends/tda10086.c21
-rw-r--r--drivers/media/dvb/frontends/tda826x.c4
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/cafe_ccic-regs.h6
-rw-r--r--drivers/media/video/cafe_ccic.c18
-rw-r--r--drivers/media/video/em28xx/Kconfig3
-rw-r--r--drivers/media/video/ivtv/Kconfig2
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h24
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c16
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c57
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c204
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c31
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h39
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h2
-rw-r--r--drivers/media/video/ov7670.c21
-rw-r--r--drivers/media/video/saa7111.c49
-rw-r--r--drivers/media/video/tuner-simple.c10
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c82
-rw-r--r--drivers/media/video/usbvision/usbvision.h1
-rw-r--r--drivers/message/fusion/mptbase.h2
-rw-r--r--drivers/message/fusion/mptscsih.c8
-rw-r--r--drivers/message/i2o/driver.c26
-rw-r--r--drivers/mfd/ucb1x00-ts.c18
-rw-r--r--drivers/misc/phantom.c29
-rw-r--r--drivers/misc/thinkpad_acpi.c17
-rw-r--r--drivers/misc/thinkpad_acpi.h6
-rw-r--r--drivers/misc/tifm_7xx1.c2
-rw-r--r--drivers/mmc/card/block.c18
-rw-r--r--drivers/mmc/card/queue.c35
-rw-r--r--drivers/mmc/card/queue.h8
-rw-r--r--drivers/mmc/core/sd.c41
-rw-r--r--drivers/mmc/host/at91_mci.c5
-rw-r--r--drivers/mmc/host/au1xmmc.c3
-rw-r--r--drivers/mmc/host/omap.c24
-rw-r--r--drivers/mtd/Makefile3
-rw-r--r--drivers/mtd/devices/pmc551.c2
-rw-r--r--drivers/mtd/maps/uclinux.c5
-rw-r--r--drivers/mtd/mtdsuper.c232
-rw-r--r--drivers/mtd/nand/autcpu12.c2
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c6
-rw-r--r--drivers/net/8139cp.c17
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/acenic.c21
-rw-r--r--drivers/net/acenic.h1
-rw-r--r--drivers/net/amd8111e.c13
-rw-r--r--drivers/net/amd8111e.h2
-rw-r--r--drivers/net/arcnet/Kconfig17
-rw-r--r--drivers/net/atl1/atl1_main.c33
-rw-r--r--drivers/net/bnx2.c75
-rw-r--r--drivers/net/bnx2.h1
-rw-r--r--drivers/net/cassini.c5
-rw-r--r--drivers/net/chelsio/cxgb2.c10
-rw-r--r--drivers/net/chelsio/suni1x10gexp_regs.h2
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c6
-rw-r--r--drivers/net/defxx.c1
-rw-r--r--drivers/net/e100.c72
-rw-r--r--drivers/net/e1000/e1000_main.c20
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c14
-rw-r--r--drivers/net/fec_8xx/fec_main.c2
-rw-r--r--drivers/net/forcedeth.c10
-rw-r--r--drivers/net/gianfar.c16
-rw-r--r--drivers/net/hp100.c2
-rw-r--r--drivers/net/ibmveth.c80
-rw-r--r--drivers/net/meth.c68
-rw-r--r--drivers/net/mlx4/alloc.c2
-rw-r--r--drivers/net/mlx4/cq.c2
-rw-r--r--drivers/net/mlx4/eq.c4
-rw-r--r--drivers/net/mlx4/fw.c27
-rw-r--r--drivers/net/mlx4/intf.c3
-rw-r--r--drivers/net/mlx4/main.c2
-rw-r--r--drivers/net/mlx4/mr.c8
-rw-r--r--drivers/net/myri10ge/myri10ge.c30
-rw-r--r--drivers/net/netxen/netxen_nic.h48
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c8
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c12
-rw-r--r--drivers/net/netxen/netxen_nic_init.c44
-rw-r--r--drivers/net/netxen/netxen_nic_isr.c24
-rw-r--r--drivers/net/netxen/netxen_nic_main.c9
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c8
-rw-r--r--drivers/net/ns83820.c12
-rw-r--r--drivers/net/phy/fixed.c4
-rw-r--r--drivers/net/phy/marvell.c62
-rw-r--r--drivers/net/ppp_mppe.c10
-rwxr-xr-xdrivers/net/qla3xxx.c2
-rw-r--r--drivers/net/r8169.c11
-rw-r--r--drivers/net/s2io.c12
-rw-r--r--drivers/net/skfp/smt.c2
-rw-r--r--drivers/net/sky2.c37
-rw-r--r--drivers/net/sky2.h24
-rw-r--r--drivers/net/smc91x.h5
-rw-r--r--drivers/net/spider_net.c46
-rw-r--r--drivers/net/tg3.c21
-rw-r--r--drivers/net/tokenring/Kconfig33
-rw-r--r--drivers/net/typhoon.c11
-rw-r--r--drivers/net/ucc_geth.c3
-rw-r--r--drivers/net/ucc_geth_mii.c2
-rw-r--r--drivers/net/usb/Kconfig4
-rw-r--r--drivers/net/usb/asix.c4
-rw-r--r--drivers/net/usb/cdc_ether.c16
-rw-r--r--drivers/net/usb/rndis_host.c1
-rw-r--r--drivers/net/usb/usbnet.c25
-rw-r--r--drivers/net/usb/usbnet.h1
-rw-r--r--drivers/net/via-velocity.c2
-rw-r--r--drivers/net/wireless/Kconfig19
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c13
-rw-r--r--drivers/net/wireless/libertas/11d.c152
-rw-r--r--drivers/net/wireless/libertas/11d.h6
-rw-r--r--drivers/net/wireless/libertas/Makefile4
-rw-r--r--drivers/net/wireless/libertas/README52
-rw-r--r--drivers/net/wireless/libertas/assoc.c358
-rw-r--r--drivers/net/wireless/libertas/assoc.h10
-rw-r--r--drivers/net/wireless/libertas/cmd.c559
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c376
-rw-r--r--drivers/net/wireless/libertas/debugfs.c432
-rw-r--r--drivers/net/wireless/libertas/decl.h22
-rw-r--r--drivers/net/wireless/libertas/defs.h101
-rw-r--r--drivers/net/wireless/libertas/dev.h99
-rw-r--r--drivers/net/wireless/libertas/ethtool.c55
-rw-r--r--drivers/net/wireless/libertas/fw.c121
-rw-r--r--drivers/net/wireless/libertas/fw.h13
-rw-r--r--drivers/net/wireless/libertas/host.h17
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h392
-rw-r--r--drivers/net/wireless/libertas/if_bootcmd.c6
-rw-r--r--drivers/net/wireless/libertas/if_usb.c448
-rw-r--r--drivers/net/wireless/libertas/if_usb.h32
-rw-r--r--drivers/net/wireless/libertas/ioctl.c286
-rw-r--r--drivers/net/wireless/libertas/join.c464
-rw-r--r--drivers/net/wireless/libertas/join.h13
-rw-r--r--drivers/net/wireless/libertas/main.c690
-rw-r--r--drivers/net/wireless/libertas/rx.c86
-rw-r--r--drivers/net/wireless/libertas/sbi.h40
-rw-r--r--drivers/net/wireless/libertas/scan.c1529
-rw-r--r--drivers/net/wireless/libertas/scan.h81
-rw-r--r--drivers/net/wireless/libertas/thread.h8
-rw-r--r--drivers/net/wireless/libertas/tx.c74
-rw-r--r--drivers/net/wireless/libertas/types.h63
-rw-r--r--drivers/net/wireless/libertas/wext.c778
-rw-r--r--drivers/net/wireless/libertas/wext.h13
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c5
-rw-r--r--drivers/pci/msi.c12
-rw-r--r--drivers/pci/quirks.c20
-rw-r--r--drivers/pci/search.c3
-rw-r--r--drivers/pcmcia/at91_cf.c13
-rw-r--r--drivers/rtc/rtc-cmos.c13
-rw-r--r--drivers/s390/block/dasd_eer.c16
-rw-r--r--drivers/s390/char/raw3270.c10
-rw-r--r--drivers/s390/cio/device.c49
-rw-r--r--drivers/s390/cio/device_fsm.c6
-rw-r--r--drivers/s390/scsi/zfcp_aux.c1
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c5
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c40
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c3
-rw-r--r--drivers/sbus/char/flash.c1
-rw-r--r--drivers/scsi/Kconfig16
-rw-r--r--drivers/scsi/Makefile5
-rw-r--r--drivers/scsi/NCR5380.c2
-rw-r--r--drivers/scsi/aacraid/aachba.c15
-rw-r--r--drivers/scsi/aacraid/aacraid.h3
-rw-r--r--drivers/scsi/aacraid/linit.c22
-rw-r--r--drivers/scsi/aacraid/rx.c8
-rw-r--r--drivers/scsi/aacraid/sa.c9
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c2
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_gram.y1
-rw-r--r--drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_tmf.c14
-rw-r--r--drivers/scsi/atari_NCR5380.c44
-rw-r--r--drivers/scsi/ipr.c7
-rw-r--r--drivers/scsi/jazz_esp.c429
-rw-r--r--drivers/scsi/libsrp.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c67
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h14
-rw-r--r--drivers/scsi/pluto.c18
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_scan.c9
-rw-r--r--drivers/scsi/sd.c18
-rw-r--r--drivers/scsi/stex.c90
-rw-r--r--drivers/serial/amba-pl010.c3
-rw-r--r--drivers/serial/amba-pl011.c3
-rw-r--r--drivers/serial/serial_ks8695.c2
-rw-r--r--drivers/serial/suncore.c6
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/spi/atmel_spi.c8
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c25
-rw-r--r--drivers/spi/omap_uwire.c4
-rw-r--r--drivers/spi/spi.c2
-rw-r--r--drivers/spi/spi_imx.c3
-rw-r--r--drivers/spi/spidev.c13
-rw-r--r--drivers/tc/zs.c2
-rw-r--r--drivers/usb/atm/cxacru.c52
-rw-r--r--drivers/usb/class/usblp.c7
-rw-r--r--drivers/usb/core/Kconfig22
-rw-r--r--drivers/usb/core/config.c52
-rw-r--r--drivers/usb/core/driver.c18
-rw-r--r--drivers/usb/core/hcd.c8
-rw-r--r--drivers/usb/core/hub.c53
-rw-r--r--drivers/usb/core/message.c9
-rw-r--r--drivers/usb/core/sysfs.c7
-rw-r--r--drivers/usb/core/usb.c10
-rw-r--r--drivers/usb/gadget/epautoconf.c2
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c8
-rw-r--r--drivers/usb/gadget/inode.c8
-rw-r--r--drivers/usb/gadget/net2280.c6
-rw-r--r--drivers/usb/gadget/omap_udc.c6
-rw-r--r--drivers/usb/gadget/rndis.c35
-rw-r--r--drivers/usb/host/ehci-fsl.c13
-rw-r--r--drivers/usb/host/ehci-fsl.h1
-rw-r--r--drivers/usb/host/ohci-hub.c2
-rw-r--r--drivers/usb/host/ohci-pci.c2
-rw-r--r--drivers/usb/host/pci-quirks.c9
-rw-r--r--drivers/usb/host/u132-hcd.c12
-rw-r--r--drivers/usb/misc/auerswald.c10
-rw-r--r--drivers/usb/misc/ftdi-elan.c12
-rw-r--r--drivers/usb/misc/ldusb.c35
-rw-r--r--drivers/usb/serial/ark3116.c3
-rw-r--r--drivers/usb/serial/ftdi_sio.c40
-rw-r--r--drivers/usb/serial/ftdi_sio.h12
-rw-r--r--drivers/usb/serial/mos7840.c5
-rw-r--r--drivers/usb/serial/omninet.c2
-rw-r--r--drivers/usb/serial/option.c1
-rw-r--r--drivers/usb/serial/sierra.c2
-rw-r--r--drivers/usb/storage/onetouch.c9
-rw-r--r--drivers/usb/storage/unusual_devs.h27
-rw-r--r--drivers/video/Kconfig183
-rw-r--r--drivers/video/arkfb.c3
-rw-r--r--drivers/video/console/Makefile2
-rw-r--r--drivers/video/console/fbcon.h1
-rw-r--r--drivers/video/ffb.c4
-rw-r--r--drivers/video/imxfb.c24
-rw-r--r--drivers/video/neofb.c30
-rw-r--r--drivers/video/pm2fb.c17
-rw-r--r--drivers/video/pm3fb.c335
-rw-r--r--drivers/video/ps3fb.c8
-rw-r--r--drivers/video/skeletonfb.c31
-rw-r--r--drivers/video/sunxvr2500.c17
-rw-r--r--drivers/video/sunxvr500.c6
-rw-r--r--drivers/video/vt8623fb.c3
-rw-r--r--drivers/video/w100fb.c14
392 files changed, 8580 insertions, 6816 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index b770deab968..6d7d4157e04 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1357,7 +1357,7 @@ static struct backlight_ops asus_backlight_data = {
.update_status = set_brightness_status,
};
-static void __exit asus_acpi_exit(void)
+static void asus_acpi_exit(void)
{
if (asus_backlight_device)
backlight_device_unregister(asus_backlight_device);
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index a2efae8a4c4..0c9f15c54e8 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -59,7 +59,7 @@ int node_to_pxm(int node)
return node_to_pxm_map[node];
}
-int __cpuinit acpi_map_pxm_to_node(int pxm)
+int acpi_map_pxm_to_node(int pxm)
{
int node = pxm_to_node_map[pxm];
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index b998340e23d..58ceb18ec99 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -33,6 +33,7 @@
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/delay.h>
+#include <linux/dmi.h>
#include <linux/workqueue.h>
#include <linux/nmi.h>
#include <linux/acpi.h>
@@ -73,6 +74,21 @@ static void *acpi_irq_context;
static struct workqueue_struct *kacpid_wq;
static struct workqueue_struct *kacpi_notify_wq;
+#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
+static char osi_additional_string[OSI_STRING_LENGTH_MAX];
+
+#define OSI_LINUX_ENABLED
+#ifdef OSI_LINUX_ENABLED
+int osi_linux = 1; /* enable _OSI(Linux) by default */
+#else
+int osi_linux; /* disable _OSI(Linux) by default */
+#endif
+
+
+#ifdef CONFIG_DMI
+static struct __initdata dmi_system_id acpi_osl_dmi_table[];
+#endif
+
static void __init acpi_request_region (struct acpi_generic_address *addr,
unsigned int length, char *desc)
{
@@ -121,8 +137,9 @@ static int __init acpi_reserve_resources(void)
}
device_initcall(acpi_reserve_resources);
-acpi_status acpi_os_initialize(void)
+acpi_status __init acpi_os_initialize(void)
{
+ dmi_check_system(acpi_osl_dmi_table);
return AE_OK;
}
@@ -960,20 +977,38 @@ static int __init acpi_os_name_setup(char *str)
__setup("acpi_os_name=", acpi_os_name_setup);
+static void enable_osi_linux(int enable) {
+
+ if (osi_linux != enable)
+ printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
+ enable ? "En": "Dis");
+
+ osi_linux = enable;
+ return;
+}
+
/*
- * _OSI control
+ * Modify the list of "OS Interfaces" reported to BIOS via _OSI
+ *
* empty string disables _OSI
- * TBD additional string adds to _OSI
+ * string starting with '!' disables that string
+ * otherwise string is added to list, augmenting built-in strings
*/
static int __init acpi_osi_setup(char *str)
{
if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
- } else {
- /* TBD */
- printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n",
- str);
+ } else if (*str == '!') {
+ if (acpi_osi_invalidate(++str) == AE_OK)
+ printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+ } else if (!strcmp("!Linux", str)) {
+ enable_osi_linux(0);
+ } else if (!strcmp("Linux", str)) {
+ enable_osi_linux(1);
+ } else if (*osi_additional_string == '\0') {
+ strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
+ printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
}
return 1;
@@ -1143,11 +1178,28 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
acpi_status
acpi_os_validate_interface (char *interface)
{
-
- return AE_SUPPORT;
+ if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
+ return AE_OK;
+ if (!strcmp("Linux", interface)) {
+ printk(KERN_WARNING PREFIX
+ "System BIOS is requesting _OSI(Linux)\n");
+#ifdef OSI_LINUX_ENABLED
+ printk(KERN_WARNING PREFIX
+ "Please test with \"acpi_osi=!Linux\"\n"
+ "Please send dmidecode "
+ "to linux-acpi@vger.kernel.org\n");
+#else
+ printk(KERN_WARNING PREFIX
+ "If \"acpi_osi=Linux\" works better,\n"
+ "Please send dmidecode "
+ "to linux-acpi@vger.kernel.org\n");
+#endif
+ if(osi_linux)
+ return AE_OK;
+ }
+ return AE_SUPPORT;
}
-
/******************************************************************************
*
* FUNCTION: acpi_os_validate_address
@@ -1174,5 +1226,51 @@ acpi_os_validate_address (
return AE_OK;
}
+#ifdef CONFIG_DMI
+#ifdef OSI_LINUX_ENABLED
+static int dmi_osi_not_linux(struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident);
+ enable_osi_linux(0);
+ return 0;
+}
+#else
+static int dmi_osi_linux(struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident);
+ enable_osi_linux(1);
+ return 0;
+}
+#endif
+
+static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
+#ifdef OSI_LINUX_ENABLED
+ /*
+ * Boxes that need NOT _OSI(Linux)
+ */
+ {
+ .callback = dmi_osi_not_linux,
+ .ident = "Toshiba Satellite P100",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"),
+ },
+ },
+#else
+ /*
+ * Boxes that need _OSI(Linux)
+ */
+ {
+ .callback = dmi_osi_linux,
+ .ident = "Intel Napa CRB",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+ DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"),
+ },
+ },
+#endif
+ {}
+};
+#endif /* CONFIG_DMI */
#endif
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 0e7b121a99c..3bc0c67a928 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -123,14 +123,14 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
}
}
- /* The table must be either an SSDT or a PSDT */
+ /* The table must be either an SSDT or a PSDT or an OEMx */
if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
&&
- (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)))
- {
+ (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
+ && (strncmp(table_desc->pointer->signature, "OEM", 3))) {
ACPI_ERROR((AE_INFO,
- "Table has invalid signature [%4.4s], must be SSDT or PSDT",
+ "Table has invalid signature [%4.4s], must be SSDT, PSDT or OEMx",
table_desc->pointer->signature));
return_ACPI_STATUS(AE_BAD_SIGNATURE);
}
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 1ada017d01e..194ecfe8b36 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -827,6 +827,7 @@ static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_thermal *tz = seq->private;
+ struct acpi_device *device;
int i = 0;
int j = 0;
@@ -849,9 +850,8 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
tz->trips.passive.tc1, tz->trips.passive.tc2,
tz->trips.passive.tsp);
for (j = 0; j < tz->trips.passive.devices.count; j++) {
-
- seq_printf(seq, "0x%p ",
- tz->trips.passive.devices.handles[j]);
+ acpi_bus_get_device(tz->trips.passive.devices.handles[j], &device);
+ seq_printf(seq, "%4.4s ", acpi_device_bid(device));
}
seq_puts(seq, "\n");
}
@@ -862,9 +862,10 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
seq_printf(seq, "active[%d]: %ld C: devices=",
i,
KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
- for (j = 0; j < tz->trips.active[i].devices.count; j++)
- seq_printf(seq, "0x%p ",
- tz->trips.active[i].devices.handles[j]);
+ for (j = 0; j < tz->trips.active[i].devices.count; j++){
+ acpi_bus_get_device(tz->trips.active[i].devices.handles[j], &device);
+ seq_printf(seq, "%4.4s ", acpi_device_bid(device));
+ }
seq_puts(seq, "\n");
}
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 3906d47b978..1cfbecb0ac1 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -538,7 +538,7 @@ static struct backlight_ops toshiba_backlight_data = {
.update_status = set_lcd_status,
};
-static void __exit toshiba_acpi_exit(void)
+static void toshiba_acpi_exit(void)
{
if (toshiba_backlight_device)
backlight_device_unregister(toshiba_backlight_device);
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 4c1e00874df..879eaa10d3a 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -68,6 +68,10 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
union acpi_operand_object **return_obj);
static acpi_status
+acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
+ union acpi_operand_object **internal_object);
+
+static acpi_status
acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
union acpi_operand_object *dest_desc);
@@ -518,77 +522,73 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
return_ACPI_STATUS(AE_NO_MEMORY);
}
-#ifdef ACPI_FUTURE_IMPLEMENTATION
-/* Code to convert packages that are parameters to control methods */
-
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_epackage_to_ipackage
*
- * PARAMETERS: *internal_object - Pointer to the object we are returning
- * *Buffer - Where the object is returned
- * *space_used - Where the length of the object is returned
+ * PARAMETERS: external_object - The external object to be converted
+ * internal_object - Where the internal object is returned
*
* RETURN: Status
*
- * DESCRIPTION: This function is called to place a package object in a user
- * buffer. A package object by definition contains other objects.
- *
- * The buffer is assumed to have sufficient space for the object.
- * The caller must have verified the buffer length needed using the
- * acpi_ut_get_object_size function before calling this function.
+ * DESCRIPTION: Copy an external package object to an internal package.
+ * Handles nested packages.
*
******************************************************************************/
static acpi_status
-acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object,
- u8 * buffer, u32 * space_used)
+acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
+ union acpi_operand_object **internal_object)
{
- u8 *free_space;
- union acpi_object *external_object;
- u32 length = 0;
- u32 this_index;
- u32 object_space = 0;
- union acpi_operand_object *this_internal_obj;
- union acpi_object *this_external_obj;
+ acpi_status status = AE_OK;
+ union acpi_operand_object *package_object;
+ union acpi_operand_object **package_elements;
+ acpi_native_uint i;
ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
- /*
- * First package at head of the buffer
- */
- external_object = (union acpi_object *)buffer;
+ /* Create the package object */
- /*
- * Free space begins right after the first package
- */
- free_space = buffer + sizeof(union acpi_object);
+ package_object =
+ acpi_ut_create_package_object(external_object->package.count);
+ if (!package_object) {
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
- external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
- external_object->package.count = internal_object->package.count;
- external_object->package.elements = (union acpi_object *)free_space;
+ package_elements = package_object->package.elements;
/*
- * Build an array of ACPI_OBJECTS in the buffer
- * and move the free space past it
+ * Recursive implementation. Probably ok, since nested external packages
+ * as parameters should be very rare.
*/
- free_space +=
- external_object->package.count * sizeof(union acpi_object);
+ for (i = 0; i < external_object->package.count; i++) {
+ status =
+ acpi_ut_copy_eobject_to_iobject(&external_object->package.
+ elements[i],
+ &package_elements[i]);
+ if (ACPI_FAILURE(status)) {
- /* Call walk_package */
+ /* Truncate package and delete it */
-}
+ package_object->package.count = i;
+ package_elements[i] = NULL;
+ acpi_ut_remove_reference(package_object);
+ return_ACPI_STATUS(status);
+ }
+ }
-#endif /* Future implementation */
+ *internal_object = package_object;
+ return_ACPI_STATUS(status);
+}
/*******************************************************************************
*
* FUNCTION: acpi_ut_copy_eobject_to_iobject
*
- * PARAMETERS: *internal_object - The external object to be converted
- * *buffer_ptr - Where the internal object is returned
+ * PARAMETERS: external_object - The external object to be converted
+ * internal_object - Where the internal object is returned
*
- * RETURN: Status - the status of the call
+ * RETURN: Status - the status of the call
*
* DESCRIPTION: Converts an external object to an internal object.
*
@@ -603,16 +603,10 @@ acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
if (external_object->type == ACPI_TYPE_PACKAGE) {
- /*
- * Packages as external input to control methods are not supported,
- */
- ACPI_ERROR((AE_INFO,
- "Packages as parameters not implemented!"));
-
- return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
- }
-
- else {
+ status =
+ acpi_ut_copy_epackage_to_ipackage(external_object,
+ internal_object);
+ } else {
/*
* Build a simple object (no nested objects)
*/
@@ -803,33 +797,19 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type,
* Create and build the package object
*/
target_object =
- acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
+ acpi_ut_create_package_object(source_object->package.count);
if (!target_object) {
return (AE_NO_MEMORY);
}
- target_object->package.count = source_object->package.count;
target_object->common.flags = source_object->common.flags;
- /*
- * Create the object array
- */
- target_object->package.elements =
- ACPI_ALLOCATE_ZEROED(((acpi_size) source_object->package.
- count + 1) * sizeof(void *));
- if (!target_object->package.elements) {
- status = AE_NO_MEMORY;
- goto error_exit;
- }
+ /* Pass the new package object back to the package walk routine */
- /*
- * Pass the new package object back to the package walk routine
- */
state->pkg.this_target_obj = target_object;
- /*
- * Store the object pointer in the parent package object
- */
+ /* Store the object pointer in the parent package object */
+
*this_target_ptr = target_object;
break;
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 13d5879cd98..8ec6f8e4813 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -59,10 +59,9 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
/*
* Strings supported by the _OSI predefined (internal) method.
*/
-static const char *acpi_interfaces_supported[] = {
+static char *acpi_interfaces_supported[] = {
/* Operating System Vendor Strings */
- "Linux",
"Windows 2000",
"Windows 2001",
"Windows 2001 SP0",
@@ -158,6 +157,31 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
/*******************************************************************************
*
+ * FUNCTION: acpi_osi_invalidate
+ *
+ * PARAMETERS: interface_string
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: invalidate string in pre-defiend _OSI string list
+ *
+ ******************************************************************************/
+
+acpi_status acpi_osi_invalidate(char *interface)
+{
+ int i;
+
+ for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
+ if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
+ *acpi_interfaces_supported[i] = '\0';
+ return AE_OK;
+ }
+ }
+ return AE_NOT_FOUND;
+}
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ut_evaluate_object
*
* PARAMETERS: prefix_node - Starting node
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index 4696124759e..db0b9bac794 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -146,6 +146,48 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
/*******************************************************************************
*
+ * FUNCTION: acpi_ut_create_package_object
+ *
+ * PARAMETERS: Count - Number of package elements
+ *
+ * RETURN: Pointer to a new Package object, null on failure
+ *
+ * DESCRIPTION: Create a fully initialized package object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *acpi_ut_create_package_object(u32 count)
+{
+ union acpi_operand_object *package_desc;
+ union acpi_operand_object **package_elements;
+
+ ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count);
+
+ /* Create a new Package object */
+
+ package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
+ if (!package_desc) {
+ return_PTR(NULL);
+ }
+
+ /*
+ * Create the element array. Count+1 allows the array to be null
+ * terminated.
+ */
+ package_elements = ACPI_ALLOCATE_ZEROED((acpi_size)
+ (count + 1) * sizeof(void *));
+ if (!package_elements) {
+ ACPI_FREE(package_desc);
+ return_PTR(NULL);
+ }
+
+ package_desc->package.count = count;
+ package_desc->package.elements = package_elements;
+ return_PTR(package_desc);
+}
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ut_create_buffer_object
*
* PARAMETERS: buffer_size - Size of buffer to be created
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index e9a57806cd3..2d496918b3c 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -61,7 +61,7 @@ ACPI_MODULE_NAME("utxface")
* called, so any early initialization belongs here.
*
******************************************************************************/
-acpi_status acpi_initialize_subsystem(void)
+acpi_status __init acpi_initialize_subsystem(void)
{
acpi_status status;
@@ -108,8 +108,6 @@ acpi_status acpi_initialize_subsystem(void)
return_ACPI_STATUS(status);
}
-ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem)
-
/*******************************************************************************
*
* FUNCTION: acpi_enable_subsystem
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 7baeaffefe7..545f330e59a 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -426,6 +426,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */
{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */
+ { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci }, /* MCP73 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci }, /* MCP77 */
+ { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci }, /* MCP77 */
/* SiS */
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 0458811010f..9c07b88631b 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -578,6 +578,7 @@ static const struct ich_laptop ich_laptop[] = {
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
{ 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
{ 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
+ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
/* end marker */
{ 0, }
};
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index a6de57e0204..047eabd7536 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1727,7 +1727,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
/* sanity check */
rc = -EINVAL;
- reason = "device reports illegal type";
+ reason = "device reports invalid type";
if (class == ATA_DEV_ATA) {
if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
@@ -1900,6 +1900,13 @@ int ata_dev_configure(struct ata_device *dev)
if (ata_msg_probe(ap))
ata_dump_id(id);
+ /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
+ ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
+ sizeof(fwrevbuf));
+
+ ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
+ sizeof(modelbuf));
+
/* ATA-specific feature tests */
if (dev->class == ATA_DEV_ATA) {
if (ata_id_is_cfa(id)) {
@@ -1914,13 +1921,6 @@ int ata_dev_configure(struct ata_device *dev)
dev->n_sectors = ata_id_n_sectors(id);
- /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
- ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
- sizeof(fwrevbuf));
-
- ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
- sizeof(modelbuf));
-
if (dev->id[59] & 0x100)
dev->multi_count = dev->id[59] & 0xff;
@@ -2009,7 +2009,9 @@ int ata_dev_configure(struct ata_device *dev)
/* print device info to dmesg */
if (ata_msg_drv(ap) && print_info)
- ata_dev_printk(dev, KERN_INFO, "ATAPI, max %s%s\n",
+ ata_dev_printk(dev, KERN_INFO,
+ "ATAPI: %s, %s, max %s%s\n",
+ modelbuf, fwrevbuf,
ata_mode_string(xfer_mask),
cdb_intr_string);
}
@@ -3022,7 +3024,7 @@ int ata_wait_ready(struct ata_port *ap, unsigned long deadline)
if (!(status & ATA_BUSY))
return 0;
- if (status == 0xff)
+ if (!ata_port_online(ap) && status == 0xff)
return -ENODEV;
if (time_after(now, deadline))
return -EBUSY;
@@ -3059,22 +3061,28 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
}
}
- /* if device 1 was found in ata_devchk, wait for
- * register access, then wait for BSY to clear
+ /* if device 1 was found in ata_devchk, wait for register
+ * access briefly, then wait for BSY to clear.
*/
- while (dev1) {
- u8 nsect, lbal;
+ if (dev1) {
+ int i;
ap->ops->dev_select(ap, 1);
- nsect = ioread8(ioaddr->nsect_addr);
- lbal = ioread8(ioaddr->lbal_addr);
- if ((nsect == 1) && (lbal == 1))
- break;
- if (time_after(jiffies, deadline))
- return -EBUSY;
- msleep(50); /* give drive a breather */
- }
- if (dev1) {
+
+ /* Wait for register access. Some ATAPI devices fail
+ * to set nsect/lbal after reset, so don't waste too
+ * much time on it. We're gonna wait for !BSY anyway.
+ */
+ for (i = 0; i < 2; i++) {
+ u8 nsect, lbal;
+
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
+ if ((nsect == 1) && (lbal == 1))
+ break;
+ msleep(50); /* give drive a breather */
+ }
+
rc = ata_wait_ready(ap, deadline);
if (rc) {
if (rc != -ENODEV)
@@ -3368,7 +3376,7 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
*/
if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) {
rc = ata_wait_ready(ap, deadline);
- if (rc) {
+ if (rc && rc != -ENODEV) {
ata_port_printk(ap, KERN_WARNING, "device not ready "
"(errno=%d), forcing hardreset\n", rc);
ehc->i.action |= ATA_EH_HARDRESET;
@@ -3769,6 +3777,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
{ "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
{ "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
+ { "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */
/* Weird ATAPI devices */
{ "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 |
@@ -3783,6 +3792,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
/* NCQ is broken */
{ "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ },
+ { "Maxtor 6B200M0", "BANC1B10", ATA_HORKAGE_NONCQ },
/* NCQ hard hangs device under heavier load, needs hard power cycle */
{ "Maxtor 6B250S0", "BANC1B70", ATA_HORKAGE_NONCQ },
/* Blacklist entries taken from Silicon Image 3124/3132
@@ -3790,6 +3800,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
+ /* Drives which do spurious command completion */
+ { "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, },
/* Devices with NCQ limits */
@@ -3932,10 +3944,13 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
/* set up set-features taskfile */
DPRINTK("set features - xfer mode\n");
+ /* Some controllers and ATAPI devices show flaky interrupt
+ * behavior after setting xfer mode. Use polling instead.
+ */
ata_tf_init(dev, &tf);
tf.command = ATA_CMD_SET_FEATURES;
tf.feature = SETFEATURES_XFER;
- tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_POLLING;
tf.protocol = ATA_PROT_NODATA;
tf.nsect = dev->xfer_mode;
@@ -5413,14 +5428,6 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
}
}
- /* Some controllers show flaky interrupt behavior after
- * setting xfer mode. Use polling instead.
- */
- if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
- qc->tf.feature == SETFEATURES_XFER) &&
- (ap->flags & ATA_FLAG_SETXFER_POLLING))
- qc->tf.flags |= ATA_TFLAG_POLLING;
-
/* select the device */
ata_dev_select(ap, qc->dev->devno, 1, 0);
@@ -6317,7 +6324,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* init sata_spd_limit to the current value */
if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
int spd = (scontrol >> 4) & 0xf;
- ap->hw_sata_spd_limit &= (1 << spd) - 1;
+ if (spd)
+ ap->hw_sata_spd_limit &= (1 << spd) - 1;
}
ap->sata_spd_limit = ap->hw_sata_spd_limit;
@@ -6437,6 +6445,9 @@ int ata_host_activate(struct ata_host *host, int irq,
if (rc)
devm_free_irq(host->dev, irq, host);
+ /* Used to print device info at probe */
+ host->irq = irq;
+
return rc;
}
@@ -6822,6 +6833,7 @@ EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
+EXPORT_SYMBOL_GPL(ata_sff_port_start);
EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_data_xfer);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 242c43eef80..c228df298bd 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1050,14 +1050,15 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc)
static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
- u32 len = 0;
+ u32 len;
VPRINTK("six-byte command\n");
+ lba |= ((u64)(cdb[1] & 0x1f)) << 16;
lba |= ((u64)cdb[2]) << 8;
lba |= ((u64)cdb[3]);
- len |= ((u32)cdb[4]);
+ len = cdb[4];
*plba = lba;
*plen = len;
@@ -1362,12 +1363,22 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
* cache
*/
- if (ap->ops->error_handler &&
- !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) &&
- ((qc->tf.feature == SETFEATURES_WC_ON) ||
- (qc->tf.feature == SETFEATURES_WC_OFF))) {
- ap->eh_info.action |= ATA_EH_REVALIDATE;
- ata_port_schedule_eh(ap);
+ if (ap->ops->error_handler && !need_sense) {
+ switch (qc->tf.command) {
+ case ATA_CMD_SET_FEATURES:
+ if ((qc->tf.feature == SETFEATURES_WC_ON) ||
+ (qc->tf.feature == SETFEATURES_WC_OFF)) {
+ ap->eh_info.action |= ATA_EH_REVALIDATE;
+ ata_port_schedule_eh(ap);
+ }
+ break;
+
+ case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
+ case ATA_CMD_SET_MULTI: /* multi_count changed */
+ ap->eh_info.action |= ATA_EH_REVALIDATE;
+ ata_port_schedule_eh(ap);
+ break;
+ }
}
/* For ATA pass thru (SAT) commands, generate a sense block if
@@ -2505,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1)
return ATA_PROT_NODATA;
case 6: /* DMA */
+ case 10: /* UDMA Data-in */
+ case 11: /* UDMA Data-Out */
return ATA_PROT_DMA;
case 4: /* PIO Data-in */
case 5: /* PIO Data-out */
return ATA_PROT_PIO;
- case 10: /* Device Reset */
case 0: /* Hard Reset */
case 1: /* SRST */
- case 2: /* Bus Idle */
- case 7: /* Packet */
- case 8: /* DMA Queued */
- case 9: /* Device Diagnostic */
- case 11: /* UDMA Data-in */
- case 12: /* UDMA Data-Out */
- case 13: /* FPDMA */
+ case 8: /* Device Diagnostic */
+ case 9: /* Device Reset */
+ case 7: /* DMA Queued */
+ case 12: /* FPDMA */
+ case 15: /* Return Response Info */
default: /* Reserved */
break;
}
@@ -2551,10 +2561,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
goto invalid_fld;
- if (cdb[1] & 0xe0)
- /* PIO multi not supported yet */
- goto invalid_fld;
-
/*
* 12 and 16 byte CDBs use different offsets to
* provide the various register values.
@@ -2599,12 +2605,26 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
tf->device = cdb[8];
tf->command = cdb[9];
}
- /*
- * If slave is possible, enforce correct master/slave bit
- */
- if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
- tf->device = qc->dev->devno ?
- tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+ /* enforce correct master/slave bit */
+ tf->device = dev->devno ?
+ tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
+
+ /* sanity check for pio multi commands */
+ if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf))
+ goto invalid_fld;
+
+ if (is_multi_taskfile(tf)) {
+ unsigned int multi_count = 1 << (cdb[1] >> 5);
+
+ /* compare the passed through multi_count
+ * with the cached multi_count of libata
+ */
+ if (multi_count != dev->multi_count)
+ ata_dev_printk(dev, KERN_WARNING,
+ "invalid multi_count %u ignored\n",
+ multi_count);
+ }
/* READ/WRITE LONG use a non-standard sect_size */
qc->sect_size = ATA_SECT_SIZE;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index e35d13466c6..ce84805ba5f 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -80,25 +80,25 @@ u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
- u8 host_stat, post_stat, status;
+ u8 host_stat = 0, post_stat = 0, status;
status = ata_busy_wait(ap, bits, 1000);
if (status & bits)
if (ata_msg_err(ap))
printk(KERN_ERR "abnormal status 0x%X\n", status);
- /* get controller status; clear intr, err bits */
- host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
- ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-
- post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ if (ap->ioaddr.bmdma_addr) {
+ /* get controller status; clear intr, err bits */
+ host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+ ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ }
if (ata_msg_intr(ap))
printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
__FUNCTION__,
host_stat, post_stat, status);
-
return status;
}
@@ -516,6 +516,27 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
ata_bmdma_stop(qc);
}
+/**
+ * ata_sff_port_start - Set port up for dma.
+ * @ap: Port to initialize
+ *
+ * Called just after data structures for each port are
+ * initialized. Allocates space for PRD table if the device
+ * is DMA capable SFF.
+ *
+ * May be used as the port_start() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+
+int ata_sff_port_start(struct ata_port *ap)
+{
+ if (ap->ioaddr.bmdma_addr)
+ return ata_port_start(ap);
+ return 0;
+}
+
#ifdef CONFIG_PCI
static int ata_resources_present(struct pci_dev *pdev, int port)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 7b4810c171b..03b6ddd2abd 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -97,7 +97,7 @@ static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline)
* artop6260_cable_detect - identify cable type
* @ap: Port
*
- * Identify the cable type for the ARTOp interface in question
+ * Identify the cable type for the ARTOP interface in question
*/
static int artop6260_cable_detect(struct ata_port *ap)
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index a54c17433ee..6446735a46e 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -26,7 +26,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.6.5"
+#define DRV_VERSION "0.6.6"
struct hpt_clock {
u8 xfer_speed;
@@ -931,15 +931,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x7f,
.port_ops = &hpt372_port_ops
};
- /* HPT371, 372 and friends - UDMA100 at 50MHz clock */
- static const struct ata_port_info info_hpt372_50 = {
- .sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x3f,
- .port_ops = &hpt372_port_ops
- };
/* HPT374 - UDMA133 */
static const struct ata_port_info info_hpt374 = {
.sht = &hpt37x_sht,
@@ -1098,17 +1089,21 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
* use a 50MHz DPLL by choice
*/
unsigned int f_low, f_high;
- int adjust;
+ int dpll, adjust;
- clock_slot = 2;
+ /* Compute DPLL */
+ dpll = 2;
if (port->udma_mask & 0xE0)
- clock_slot = 3;
+ dpll = 3;
- f_low = (MHz[clock_slot] * chip_table->base) / 192;
+ f_low = (MHz[clock_slot] * 48) / MHz[dpll];
f_high = f_low + 2;
+ if (clock_slot > 1)
+ f_high += 2;
/* Select the DPLL clock. */
pci_write_config_byte(dev, 0x5b, 0x21);
+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
for(adjust = 0; adjust < 8; adjust++) {
if (hpt37x_calibrate_dpll(dev))
@@ -1124,12 +1119,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
return -ENODEV;
}
- if (clock_slot == 3)
+ if (dpll == 3)
private_data = (void *)hpt37x_timings_66;
else
private_data = (void *)hpt37x_timings_50;
- printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
+ printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]);
} else {
private_data = (void *)chip_table->clocks[clock_slot];
/*
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index f25154aed75..e947433cb37 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -521,8 +521,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* 371N if rev > 1 */
break;
case PCI_DEVICE_ID_TTI_HPT372:
- /* 372N if rev >= 1*/
- if (class_rev == 0)
+ /* 372N if rev >= 2*/
+ if (class_rev < 2)
return -ENODEV;
break;
case PCI_DEVICE_ID_TTI_HPT302:
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 1f647b64820..5525518204e 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -77,7 +77,6 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
struct ata_host *host;
struct ata_port *ap;
void __iomem *cmd_addr, *ctl_addr;
- int rc;
if (pnp_port_valid(idev, 0) == 0)
return -ENODEV;
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index ff9a6fd3665..b3456d7a592 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -1,5 +1,5 @@
/*
- * ata-it821x.c - IT821x PATA for new ATA layer
+ * pata_it821x.c - IT821x PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
@@ -65,7 +65,6 @@
*
* TODO
* - ATAPI and other speed filtering
- * - Command filter in smart mode
* - RAID configuration ioctls
*/
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index aa138d211b0..61502bc7bf1 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -489,23 +489,26 @@ static unsigned int scc_devchk (struct ata_port *ap,
* Note: Original code is ata_bus_post_reset().
*/
-static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
+static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int dev0 = devmask & (1 << 0);
unsigned int dev1 = devmask & (1 << 1);
- unsigned long timeout;
+ int rc;
/* if device 0 was found in ata_devchk, wait for its
* BSY bit to clear
*/
- if (dev0)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ if (dev0) {
+ rc = ata_wait_ready(ap, deadline);
+ if (rc && rc != -ENODEV)
+ return rc;
+ }
/* if device 1 was found in ata_devchk, wait for
* register access, then wait for BSY to clear
*/
- timeout = jiffies + ATA_TMOUT_BOOT;
while (dev1) {
u8 nsect, lbal;
@@ -514,14 +517,15 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
lbal = in_be32(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
- if (time_after(jiffies, timeout)) {
- dev1 = 0;
- break;
- }
+ if (time_after(jiffies, deadline))
+ return -EBUSY;
msleep(50); /* give drive a breather */
}
- if (dev1)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ if (dev1) {
+ rc = ata_wait_ready(ap, deadline);
+ if (rc && rc != -ENODEV)
+ return rc;
+ }
/* is all this really necessary? */
ap->ops->dev_select(ap, 0);
@@ -529,6 +533,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
ap->ops->dev_select(ap, 1);
if (dev0)
ap->ops->dev_select(ap, 0);
+
+ return 0;
}
/**
@@ -537,8 +543,8 @@ static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
* Note: Original code is ata_bus_softreset().
*/
-static unsigned int scc_bus_softreset (struct ata_port *ap,
- unsigned int devmask)
+static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -570,7 +576,7 @@ static unsigned int scc_bus_softreset (struct ata_port *ap,
if (scc_check_status(ap) == 0xFF)
return 0;
- scc_bus_post_reset(ap, devmask);
+ scc_bus_post_reset(ap, devmask, deadline);
return 0;
}
@@ -579,11 +585,13 @@ static unsigned int scc_bus_softreset (struct ata_port *ap,
* scc_std_softreset - reset host port via ATA SRST
* @ap: port to reset
* @classes: resulting classes of attached devices
+ * @deadline: deadline jiffies for the operation
*
* Note: Original code is ata_std_softreset().
*/
-static int scc_std_softreset (struct ata_port *ap, unsigned int *classes)
+static int scc_std_softreset (struct ata_port *ap, unsigned int *classes,
+ unsigned long deadline)
{
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
unsigned int devmask = 0, err_mask;
@@ -607,7 +615,7 @@ static int scc_std_softreset (struct ata_port *ap, unsigned int *classes)
/* issue bus reset */
DPRINTK("about to softreset, devmask=%x\n", devmask);
- err_mask = scc_bus_softreset(ap, devmask);
+ err_mask = scc_bus_softreset(ap, devmask, deadline);
if (err_mask) {
ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
err_mask);
@@ -676,10 +684,11 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
if (reg & INTSTS_BMSINT) {
unsigned int classes;
+ unsigned long deadline = jiffies + ATA_TMOUT_BOOT;
printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
/* TBD: SW reset */
- scc_std_softreset(ap, &classes);
+ scc_std_softreset(ap, &classes, deadline);
continue;
}
@@ -862,9 +871,10 @@ static void scc_bmdma_freeze (struct ata_port *ap)
/**
* scc_pata_prereset - prepare for reset
* @ap: ATA port to be reset
+ * @deadline: deadline jiffies for the operation
*/
-static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline)
+static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline)
{
ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap, deadline);
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index f2231267e01..ec3ae937501 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -73,14 +73,14 @@ static int sis_short_ata40(struct pci_dev *dev)
}
/**
- * sis_port_base - return PCI configuration base for dev
+ * sis_old_port_base - return PCI configuration base for dev
* @adev: device
*
* Returns the base of the PCI configuration registers for this port
* number.
*/
-static int sis_port_base(struct ata_device *adev)
+static int sis_old_port_base(struct ata_device *adev)
{
return 0x40 + (4 * adev->ap->port_no) + (2 * adev->devno);
}
@@ -211,7 +211,7 @@ static void sis_set_fifo(struct ata_port *ap, struct ata_device *adev)
static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int port = sis_port_base(adev);
+ int port = sis_old_port_base(adev);
u8 t1, t2;
int speed = adev->pio_mode - XFER_PIO_0;
@@ -248,7 +248,7 @@ static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int port = sis_port_base(adev);
+ int port = sis_old_port_base(adev);
int speed = adev->pio_mode - XFER_PIO_0;
const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
@@ -328,7 +328,7 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
+ int drive_pci = sis_old_port_base(adev);
u16 timing;
const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -367,7 +367,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
+ int drive_pci = sis_old_port_base(adev);
u16 timing;
const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -378,12 +378,12 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
if (adev->dma_mode < XFER_UDMA_0) {
/* bits 3-0 hold recovery timing bits 8-10 active timing and
the higer bits are dependant on the device, bit 15 udma */
- timing &= ~ 0x870F;
+ timing &= ~0x870F;
timing |= mwdma_bits[speed];
} else {
/* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
speed = adev->dma_mode - XFER_UDMA_0;
- timing &= ~0x6000;
+ timing &= ~0xF000;
timing |= udma_bits[speed];
}
pci_write_config_word(pdev, drive_pci, timing);
@@ -405,22 +405,22 @@ static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
- u16 timing;
+ int drive_pci = sis_old_port_base(adev);
+ u8 timing;
- const u16 udma_bits[] = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+ const u8 udma_bits[] = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81};
- pci_read_config_word(pdev, drive_pci, &timing);
+ pci_read_config_byte(pdev, drive_pci + 1, &timing);
if (adev->dma_mode < XFER_UDMA_0) {
/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
} else {
- /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+ /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
speed = adev->dma_mode - XFER_UDMA_0;
- timing &= ~0x0F00;
+ timing &= ~0x8F;
timing |= udma_bits[speed];
}
- pci_write_config_word(pdev, drive_pci, timing);
+ pci_write_config_byte(pdev, drive_pci + 1, timing);
}
/**
@@ -440,22 +440,22 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
- u16 timing;
-
- static const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+ int drive_pci = sis_old_port_base(adev);
+ u8 timing;
+ /* Low 4 bits are timing */
+ static const u8 udma_bits[] = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81};
- pci_read_config_word(pdev, drive_pci, &timing);
+ pci_read_config_byte(pdev, drive_pci + 1, &timing);
if (adev->dma_mode < XFER_UDMA_0) {
/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
} else {
- /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+ /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
speed = adev->dma_mode - XFER_UDMA_0;
- timing &= ~0x0F00;
+ timing &= ~0x8F;
timing |= udma_bits[speed];
}
- pci_write_config_word(pdev, drive_pci, timing);
+ pci_write_config_byte(pdev, drive_pci + 1, timing);
}
/**
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index e4c71f76bd5..63eca299c62 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -60,6 +60,7 @@
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <linux/dmi.h>
#define DRV_NAME "pata_via"
#define DRV_VERSION "0.3.1"
@@ -122,6 +123,31 @@ static const struct via_isa_bridge {
{ NULL }
};
+
+/*
+ * Cable special cases
+ */
+
+static struct dmi_system_id cable_dmi_table[] = {
+ {
+ .ident = "Acer Ferrari 3400",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
+ DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
+ },
+ },
+ { }
+};
+
+static int via_cable_override(struct pci_dev *pdev)
+{
+ /* Systems by DMI */
+ if (dmi_check_system(cable_dmi_table))
+ return 1;
+ return 0;
+}
+
+
/**
* via_cable_detect - cable detection
* @ap: ATA port
@@ -139,6 +165,9 @@ static int via_cable_detect(struct ata_port *ap) {
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 ata66;
+ if (via_cable_override(pdev))
+ return ATA_CBL_PATA40_SHORT;
+
/* Early chips are 40 wire */
if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
return ATA_CBL_PATA40;
@@ -423,7 +452,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Early VIA without UDMA support */
static const struct ata_port_info via_mwdma_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &via_port_ops
@@ -431,7 +460,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Ditto with IRQ masking required */
static const struct ata_port_info via_mwdma_info_borked = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &via_port_ops_noirq,
@@ -439,7 +468,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 33 devices (and borked 66) */
static const struct ata_port_info via_udma33_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x7,
@@ -448,7 +477,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 66 devices */
static const struct ata_port_info via_udma66_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x1f,
@@ -457,7 +486,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* VIA UDMA 100 devices */
static const struct ata_port_info via_udma100_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x3f,
@@ -466,7 +495,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* UDMA133 with bad AST (All current 133) */
static const struct ata_port_info via_udma133_info = {
.sht = &via_sht,
- .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+ .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x7f, /* FIXME: should check north bridge */
@@ -592,10 +621,11 @@ static int via_reinit_one(struct pci_dev *pdev)
#endif
static const struct pci_device_id via[] = {
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), },
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
+ { PCI_VDEVICE(VIA, 0x0571), },
+ { PCI_VDEVICE(VIA, 0x0581), },
+ { PCI_VDEVICE(VIA, 0x1571), },
+ { PCI_VDEVICE(VIA, 0x3164), },
+ { PCI_VDEVICE(VIA, 0x5324), },
{ },
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 705a020e159..c957e6e54ba 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -21,6 +21,50 @@
*
*/
+/*
+ sata_mv TODO list:
+
+ 1) Needs a full errata audit for all chipsets. I implemented most
+ of the errata workarounds found in the Marvell vendor driver, but
+ I distinctly remember a couple workarounds (one related to PCI-X)
+ are still needed.
+
+ 2) Convert to LibATA new EH. Required for hotplug, NCQ, and sane
+ probing/error handling in general. MUST HAVE.
+
+ 3) Add hotplug support (easy, once new-EH support appears)
+
+ 4) Add NCQ support (easy to intermediate, once new-EH support appears)
+
+ 5) Investigate problems with PCI Message Signalled Interrupts (MSI).
+
+ 6) Add port multiplier support (intermediate)
+
+ 7) Test and verify 3.0 Gbps support
+
+ 8) Develop a low-power-consumption strategy, and implement it.
+
+ 9) [Experiment, low priority] See if ATAPI can be supported using
+ "unknown FIS" or "vendor-specific FIS" support, or something creative
+ like that.
+
+ 10) [Experiment, low priority] Investigate interrupt coalescing.
+ Quite often, especially with PCI Message Signalled Interrupts (MSI),
+ the overhead reduced by interrupt mitigation is quite often not
+ worth the latency cost.
+
+ 11) [Experiment, Marvell value added] Is it possible to use target
+ mode to cross-connect two Linux boxes with Marvell cards? If so,
+ creating LibATA target mode support would be very interesting.
+
+ Target mode, for those without docs, is the ability to directly
+ connect two SATA controllers.
+
+ 13) Verify that 7042 is fully supported. I only have a 6042.
+
+*/
+
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 3a7d9b5332a..6dc0b011a6b 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -297,7 +297,7 @@ static const struct ata_port_info pdc_port_info[] = {
/* board_2057x_pata */
{
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
PDC_FLAG_GEN_II,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -784,9 +784,12 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
break;
/*FALLTHROUGH*/
+ case ATA_PROT_NODATA:
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ break;
+ /*FALLTHROUGH*/
case ATA_PROT_ATAPI_DMA:
case ATA_PROT_DMA:
- case ATA_PROT_NODATA:
pdc_packet_start(qc);
return 0;
@@ -800,7 +803,7 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
- tf->protocol == ATA_PROT_NODATA);
+ tf->protocol == ATA_PROT_ATAPI_DMA);
ata_tf_load(ap, tf);
}
@@ -808,7 +811,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON (tf->protocol == ATA_PROT_DMA ||
- tf->protocol == ATA_PROT_NODATA);
+ tf->protocol == ATA_PROT_ATAPI_DMA);
ata_exec_command(ap, tf);
}
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 51d9251b089..221099d1d08 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -255,7 +255,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
struct ata_port_info pi = sis_port_info;
- const struct ata_port_info *ppi[] = { &pi, NULL };
+ const struct ata_port_info *ppi[] = { &pi, &pi };
struct ata_host *host;
u32 genctl, val;
u8 pmr;
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 01bba26d8d1..e8b90e7b42d 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -85,6 +85,9 @@ static const struct pci_device_id svia_pci_tbl[] = {
{ PCI_VDEVICE(VIA, 0x0591), vt6420 },
{ PCI_VDEVICE(VIA, 0x3149), vt6420 },
{ PCI_VDEVICE(VIA, 0x3249), vt6421 },
+ { PCI_VDEVICE(VIA, 0x5287), vt6420 },
+ { PCI_VDEVICE(VIA, 0x5372), vt6420 },
+ { PCI_VDEVICE(VIA, 0x7372), vt6420 },
{ } /* terminate list */
};
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 9c67df5ccfa..7f6d02ce1b5 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1475,6 +1475,7 @@ static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
struct FS_BPENTRY *qe, *ne;
struct sk_buff *skb;
int n = 0;
+ u32 qe_tmp;
fs_dprintk (FS_DEBUG_QUEUE, "Topping off queue at %x (%d-%d/%d)\n",
fp->offset, read_fs (dev, FP_CNT (fp->offset)), fp->n,
@@ -1502,10 +1503,16 @@ static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
ne->skb = skb;
ne->fp = fp;
- qe = (struct FS_BPENTRY *) (read_fs (dev, FP_EA(fp->offset)));
- fs_dprintk (FS_DEBUG_QUEUE, "link at %p\n", qe);
- if (qe) {
- qe = bus_to_virt ((long) qe);
+ /*
+ * FIXME: following code encodes and decodes
+ * machine pointers (could be 64-bit) into a
+ * 32-bit register.
+ */
+
+ qe_tmp = read_fs (dev, FP_EA(fp->offset));
+ fs_dprintk (FS_DEBUG_QUEUE, "link at %x\n", qe_tmp);
+ if (qe_tmp) {
+ qe = bus_to_virt ((long) qe_tmp);
qe->next = virt_to_bus(ne);
qe->flags &= ~FP_FLAGS_EPI;
} else
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 057efbc55d3..3800bc0cb2e 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -47,7 +47,8 @@ static char const rcsid[] =
#include <linux/bitops.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -2435,7 +2436,7 @@ idt77252_open(struct atm_vcc *vcc)
set_bit(ATM_VF_ADDR, &vcc->flags);
- down(&card->mutex);
+ mutex_lock(&card->mutex);
OPRINTK("%s: opening vpi.vci: %d.%d\n", card->name, vpi, vci);
@@ -2446,7 +2447,7 @@ idt77252_open(struct atm_vcc *vcc)
break;
default:
printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return -EPROTONOSUPPORT;
}
@@ -2455,7 +2456,7 @@ idt77252_open(struct atm_vcc *vcc)
card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
if (!card->vcs[index]) {
printk("%s: can't alloc vc in open()\n", card->name);
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return -ENOMEM;
}
card->vcs[index]->card = card;
@@ -2484,14 +2485,14 @@ idt77252_open(struct atm_vcc *vcc)
if (inuse) {
printk("%s: %s vci already in use.\n", card->name,
inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return -EADDRINUSE;
}
if (vcc->qos.txtp.traffic_class != ATM_NONE) {
error = idt77252_init_tx(card, vc, vcc, &vcc->qos);
if (error) {
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return error;
}
}
@@ -2499,14 +2500,14 @@ idt77252_open(struct atm_vcc *vcc)
if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
error = idt77252_init_rx(card, vc, vcc, &vcc->qos);
if (error) {
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return error;
}
}
set_bit(ATM_VF_READY, &vcc->flags);
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return 0;
}
@@ -2520,7 +2521,7 @@ idt77252_close(struct atm_vcc *vcc)
unsigned long addr;
unsigned long timeout;
- down(&card->mutex);
+ mutex_lock(&card->mutex);
IPRINTK("%s: idt77252_close: vc = %d (%d.%d)\n",
card->name, vc->index, vcc->vpi, vcc->vci);
@@ -2591,7 +2592,7 @@ done:
free_scq(card, vc->scq);
}
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
}
static int
@@ -2602,7 +2603,7 @@ idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
struct vc_map *vc = vcc->dev_data;
int error = 0;
- down(&card->mutex);
+ mutex_lock(&card->mutex);
if (qos->txtp.traffic_class != ATM_NONE) {
if (!test_bit(VCF_TX, &vc->flags)) {
@@ -2648,7 +2649,7 @@ idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
set_bit(ATM_VF_HASQOS, &vcc->flags);
out:
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return error;
}
@@ -3709,7 +3710,7 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
membase = pci_resource_start(pcidev, 1);
srambase = pci_resource_start(pcidev, 2);
- init_MUTEX(&card->mutex);
+ mutex_init(&card->mutex);
spin_lock_init(&card->cmd_lock);
spin_lock_init(&card->tst_lock);
diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h
index 544b3973829..6f2b4a5875f 100644
--- a/drivers/atm/idt77252.h
+++ b/drivers/atm/idt77252.h
@@ -37,7 +37,7 @@
#include <linux/ptrace.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
-
+#include <linux/mutex.h>
/*****************************************************************************/
/* */
@@ -359,7 +359,7 @@ struct idt77252_dev
unsigned long srambase; /* SAR's sram base address */
void __iomem *fbq[4]; /* FBQ fill addresses */
- struct semaphore mutex;
+ struct mutex mutex;
spinlock_t cmd_lock; /* for r/w utility/sram */
unsigned long softstat;
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index 2e18a63ead3..ea4fe3e48f3 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -68,6 +68,10 @@ config CFAG12864B
depends on X86
depends on FB
depends on KS0108
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
default n
---help---
If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series,
diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c
index 66fafbb1d08..307c190699e 100644
--- a/drivers/auxdisplay/cfag12864bfb.c
+++ b/drivers/auxdisplay/cfag12864bfb.c
@@ -73,9 +73,11 @@ static int cfag12864bfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
static struct fb_ops cfag12864bfb_ops = {
.owner = THIS_MODULE,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_read = fb_sys_read,
+ .fb_write = fb_sys_write,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
.fb_mmap = cfag12864bfb_mmap,
};
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 20c4ea6eb50..8c506dbe391 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -369,36 +369,6 @@ char *make_class_name(const char *name, struct kobject *kobj)
return class_name;
}
-static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index,
- char *buffer, int buffer_size,
- int *cur_len,
- struct class_device *class_dev)
-{
- struct device *dev = class_dev->dev;
- char *path;
-
- if (!dev)
- return 0;
-
- /* add device, backing this class device (deprecated) */
- path = kobject_get_path(&dev->kobj, GFP_KERNEL);
-
- add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size,
- cur_len, "PHYSDEVPATH=%s", path);
- kfree(path);
-
- if (dev->bus)
- add_uevent_var(envp, num_envp, cur_index,
- buffer, buffer_size, cur_len,
- "PHYSDEVBUS=%s", dev->bus->name);
-
- if (dev->driver)
- add_uevent_var(envp, num_envp, cur_index,
- buffer, buffer_size, cur_len,
- "PHYSDEVDRIVER=%s", dev->driver->name);
- return 0;
-}
-
static int make_deprecated_class_device_links(struct class_device *class_dev)
{
char *class_name;
@@ -430,11 +400,6 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev)
kfree(class_name);
}
#else
-static inline int deprecated_class_uevent(char **envp, int num_envp,
- int *cur_index, char *buffer,
- int buffer_size, int *cur_len,
- struct class_device *class_dev)
-{ return 0; }
static inline int make_deprecated_class_device_links(struct class_device *cd)
{ return 0; }
static void remove_deprecated_class_device_links(struct class_device *cd)
@@ -445,15 +410,13 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct class_device *class_dev = to_class_dev(kobj);
+ struct device *dev = class_dev->dev;
int i = 0;
int length = 0;
int retval = 0;
pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
- deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size,
- &length, class_dev);
-
if (MAJOR(class_dev->devt)) {
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
@@ -464,6 +427,26 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
"MINOR=%u", MINOR(class_dev->devt));
}
+ if (dev) {
+ const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
+ if (path) {
+ add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVPATH=%s", path);
+ kfree(path);
+ }
+
+ if (dev->bus)
+ add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVBUS=%s", dev->bus->name);
+
+ if (dev->driver)
+ add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVDRIVER=%s", dev->driver->name);
+ }
+
/* terminate, set to next free slot, shrink available space */
envp[i] = NULL;
envp = &envp[i];
diff --git a/drivers/base/core.c b/drivers/base/core.c
index b78fc1e6826..dd40d78a023 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -180,10 +180,12 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
const char *path;
path = kobject_get_path(&parent->kobj, GFP_KERNEL);
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVPATH=%s", path);
- kfree(path);
+ if (path) {
+ add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PHYSDEVPATH=%s", path);
+ kfree(path);
+ }
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 92428e55b0c..b0088b0efec 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -207,19 +207,6 @@ static int __device_attach(struct device_driver * drv, void * data)
return driver_probe_device(drv, dev);
}
-static int device_probe_drivers(void *data)
-{
- struct device *dev = data;
- int ret = 0;
-
- if (dev->bus) {
- down(&dev->sem);
- ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
- up(&dev->sem);
- }
- return ret;
-}
-
/**
* device_attach - try to attach device to a driver.
* @dev: device.
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 97ab5bd1c4d..89a5f4a5491 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -1,7 +1,7 @@
/*
* firmware_class.c - Multi purpose firmware loading support
*
- * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ * Copyright (c) 2003 Manuel Estrada Sainz
*
* Please see Documentation/firmware_class/ for more information.
*
@@ -23,7 +23,7 @@
#define to_dev(obj) container_of(obj, struct device, kobj)
-MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
+MODULE_AUTHOR("Manuel Estrada Sainz");
MODULE_DESCRIPTION("Multi purpose firmware loading support");
MODULE_LICENSE("GPL");
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 3587cb43437..fe088045dd0 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -670,7 +670,7 @@ static void __reschedule_timeout(int drive, const char *message, int marg)
if (drive == current_reqD)
drive = current_drive;
del_timer(&fd_timeout);
- if (drive < 0 || drive > N_DRIVE) {
+ if (drive < 0 || drive >= N_DRIVE) {
fd_timeout.expires = jiffies + 20UL * HZ;
drive = 0;
} else
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 5526eadb659..0ed5470d253 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1354,7 +1354,7 @@ static struct block_device_operations lo_fops = {
*/
static int max_loop;
module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand");
+MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
MODULE_LICENSE("GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
@@ -1394,16 +1394,11 @@ int loop_unregister_transfer(int number)
EXPORT_SYMBOL(loop_register_transfer);
EXPORT_SYMBOL(loop_unregister_transfer);
-static struct loop_device *loop_init_one(int i)
+static struct loop_device *loop_alloc(int i)
{
struct loop_device *lo;
struct gendisk *disk;
- list_for_each_entry(lo, &loop_devices, lo_list) {
- if (lo->lo_number == i)
- return lo;
- }
-
lo = kzalloc(sizeof(*lo), GFP_KERNEL);
if (!lo)
goto out;
@@ -1427,8 +1422,6 @@ static struct loop_device *loop_init_one(int i)
disk->private_data = lo;
disk->queue = lo->lo_queue;
sprintf(disk->disk_name, "loop%d", i);
- add_disk(disk);
- list_add_tail(&lo->lo_list, &loop_devices);
return lo;
out_free_queue:
@@ -1439,15 +1432,37 @@ out:
return NULL;
}
-static void loop_del_one(struct loop_device *lo)
+static void loop_free(struct loop_device *lo)
{
- del_gendisk(lo->lo_disk);
blk_cleanup_queue(lo->lo_queue);
put_disk(lo->lo_disk);
list_del(&lo->lo_list);
kfree(lo);
}
+static struct loop_device *loop_init_one(int i)
+{
+ struct loop_device *lo;
+
+ list_for_each_entry(lo, &loop_devices, lo_list) {
+ if (lo->lo_number == i)
+ return lo;
+ }
+
+ lo = loop_alloc(i);
+ if (lo) {
+ add_disk(lo->lo_disk);
+ list_add_tail(&lo->lo_list, &loop_devices);
+ }
+ return lo;
+}
+
+static void loop_del_one(struct loop_device *lo)
+{
+ del_gendisk(lo->lo_disk);
+ loop_free(lo);
+}
+
static struct kobject *loop_probe(dev_t dev, int *part, void *data)
{
struct loop_device *lo;
@@ -1464,28 +1479,77 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)
static int __init loop_init(void)
{
- if (register_blkdev(LOOP_MAJOR, "loop"))
- return -EIO;
- blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
- THIS_MODULE, loop_probe, NULL, NULL);
+ int i, nr;
+ unsigned long range;
+ struct loop_device *lo, *next;
+
+ /*
+ * loop module now has a feature to instantiate underlying device
+ * structure on-demand, provided that there is an access dev node.
+ * However, this will not work well with user space tool that doesn't
+ * know about such "feature". In order to not break any existing
+ * tool, we do the following:
+ *
+ * (1) if max_loop is specified, create that many upfront, and this
+ * also becomes a hard limit.
+ * (2) if max_loop is not specified, create 8 loop device on module
+ * load, user can further extend loop device by create dev node
+ * themselves and have kernel automatically instantiate actual
+ * device on-demand.
+ */
+ if (max_loop > 1UL << MINORBITS)
+ return -EINVAL;
if (max_loop) {
- printk(KERN_INFO "loop: the max_loop option is obsolete "
- "and will be removed in March 2008\n");
+ nr = max_loop;
+ range = max_loop;
+ } else {
+ nr = 8;
+ range = 1UL << MINORBITS;
+ }
+
+ if (register_blkdev(LOOP_MAJOR, "loop"))
+ return -EIO;
+ for (i = 0; i < nr; i++) {
+ lo = loop_alloc(i);
+ if (!lo)
+ goto Enomem;
+ list_add_tail(&lo->lo_list, &loop_devices);
}
+
+ /* point of no return */
+
+ list_for_each_entry(lo, &loop_devices, lo_list)
+ add_disk(lo->lo_disk);
+
+ blk_register_region(MKDEV(LOOP_MAJOR, 0), range,
+ THIS_MODULE, loop_probe, NULL, NULL);
+
printk(KERN_INFO "loop: module loaded\n");
return 0;
+
+Enomem:
+ printk(KERN_INFO "loop: out of memory\n");
+
+ list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
+ loop_free(lo);
+
+ unregister_blkdev(LOOP_MAJOR, "loop");
+ return -ENOMEM;
}
static void __exit loop_exit(void)
{
+ unsigned long range;
struct loop_device *lo, *next;
+ range = max_loop ? max_loop : 1UL << MINORBITS;
+
list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
loop_del_one(lo);
- blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
+ blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range);
if (unregister_blkdev(LOOP_MAJOR, "loop"))
printk(KERN_WARNING "loop: cannot unregister blkdev\n");
}
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index b0238b46dde..7e04dd69f60 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -115,11 +115,11 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
/* Broadcom BCM2045 */
- { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* IBM/Lenovo ThinkPad with Broadcom chip */
- { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
- { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Targus ACB10US */
{ USB_DEVICE(0x0a5c, 0x2100), .driver_info = HCI_RESET },
@@ -128,17 +128,17 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
/* HP laptop with Broadcom chip */
- { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Dell laptop with Broadcom chip */
- { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Microsoft Wireless Transceiver for Bluetooth 2.0 */
{ USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
/* Kensington Bluetooth USB adapter */
{ USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
- { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* ISSC Bluetooth Adapter v3.1 */
{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
@@ -148,8 +148,8 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
/* Belkin F8T012 and F8T013 devices */
- { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
- { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Digianswer devices */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index f574962f428..4310cc84dfe 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -1053,11 +1053,11 @@ static void __exit mcdx_exit(void)
if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
xwarn("cleanup() unregister_blkdev() failed\n");
}
- blk_cleanup_queue(mcdx_queue);
#if !MCDX_QUIET
else
xinfo("cleanup() succeeded\n");
#endif
+ blk_cleanup_queue(mcdx_queue);
}
#ifdef MODULE
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index abcafac6473..ef683ebd367 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -815,7 +815,7 @@ config SGI_IP27_RTC
config GEN_RTC
tristate "Generic /dev/rtc emulation"
- depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390
+ depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 && !SUPERH
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index fdbca25a394..35ab1a9f8e8 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -176,7 +176,7 @@ struct agp_bridge_data {
#define I830_GMCH_MEM_MASK 0x1
#define I830_GMCH_MEM_64M 0x1
#define I830_GMCH_MEM_128M 0
-#define I830_GMCH_GMS_MASK 0x70
+#define I830_GMCH_GMS_MASK 0xF0
#define I830_GMCH_GMS_DISABLED 0x00
#define I830_GMCH_GMS_LOCAL 0x10
#define I830_GMCH_GMS_STOLEN_512 0x20
@@ -231,6 +231,10 @@ struct agp_bridge_data {
#define I965_PGETBL_SIZE_512KB (0 << 1)
#define I965_PGETBL_SIZE_256KB (1 << 1)
#define I965_PGETBL_SIZE_128KB (2 << 1)
+#define G33_PGETBL_SIZE_MASK (3 << 8)
+#define G33_PGETBL_SIZE_1M (1 << 8)
+#define G33_PGETBL_SIZE_2M (2 << 8)
+
#define I810_DRAM_CTL 0x3000
#define I810_DRAM_ROW_0 0x00000001
#define I810_DRAM_ROW_0_SDRAM 0x00000001
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 9c69f2e761f..0439ee951a1 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -20,6 +20,14 @@
#define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2
#define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00
#define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02
+#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
+#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
+#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
+#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
+#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0
+#define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2
+#define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0
+#define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2
#define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
@@ -27,6 +35,9 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
+#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB)
extern int agp_memory_reserved;
@@ -53,6 +64,8 @@ extern int agp_memory_reserved;
#define I915_PTEADDR 0x1C
#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4)
#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4)
+#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4)
+#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4)
/* Intel 965G registers */
#define I965_MSAC 0x62
@@ -86,11 +99,18 @@ static struct gatt_mask intel_i810_masks[] =
.type = INTEL_AGP_CACHED_MEMORY}
};
-static struct _intel_i810_private {
- struct pci_dev *i810_dev; /* device one */
- volatile u8 __iomem *registers;
+static struct _intel_private {
+ struct pci_dev *pcidev; /* device one */
+ u8 __iomem *registers;
+ u32 __iomem *gtt; /* I915G */
int num_dcache_entries;
-} intel_i810_private;
+ /* gtt_entries is the number of gtt entries that are already mapped
+ * to stolen memory. Stolen memory is larger than the memory mapped
+ * through gtt_entries, as it includes some reserved space for the BIOS
+ * popup and for the GTT.
+ */
+ int gtt_entries; /* i830+ */
+} intel_private;
static int intel_i810_fetch_size(void)
{
@@ -127,32 +147,32 @@ static int intel_i810_configure(void)
current_size = A_SIZE_FIX(agp_bridge->current_size);
- if (!intel_i810_private.registers) {
- pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
+ if (!intel_private.registers) {
+ pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp);
temp &= 0xfff80000;
- intel_i810_private.registers = ioremap(temp, 128 * 4096);
- if (!intel_i810_private.registers) {
+ intel_private.registers = ioremap(temp, 128 * 4096);
+ if (!intel_private.registers) {
printk(KERN_ERR PFX "Unable to remap memory.\n");
return -ENOMEM;
}
}
- if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
+ if ((readl(intel_private.registers+I810_DRAM_CTL)
& I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
/* This will need to be dynamically assigned */
printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n");
- intel_i810_private.num_dcache_entries = 1024;
+ intel_private.num_dcache_entries = 1024;
}
- pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
- writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_i810_private.registers+I810_PGETBL_CTL);
- readl(intel_i810_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+ writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
if (agp_bridge->driver->needs_scratch_page) {
for (i = 0; i < current_size->num_entries; i++) {
- writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
- readl(intel_i810_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+ readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */
}
}
global_cache_flush();
@@ -161,9 +181,9 @@ static int intel_i810_configure(void)
static void intel_i810_cleanup(void)
{
- writel(0, intel_i810_private.registers+I810_PGETBL_CTL);
- readl(intel_i810_private.registers); /* PCI Posting. */
- iounmap(intel_i810_private.registers);
+ writel(0, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers); /* PCI Posting. */
+ iounmap(intel_private.registers);
}
static void intel_i810_tlbflush(struct agp_memory *mem)
@@ -261,9 +281,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
global_cache_flush();
for (i = pg_start; i < (pg_start + mem->page_count); i++) {
writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID,
- intel_i810_private.registers+I810_PTE_BASE+(i*4));
+ intel_private.registers+I810_PTE_BASE+(i*4));
}
- readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
break;
case AGP_PHYS_MEMORY:
case AGP_NORMAL_MEMORY:
@@ -273,9 +293,9 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
writel(agp_bridge->driver->mask_memory(agp_bridge,
mem->memory[i],
mask_type),
- intel_i810_private.registers+I810_PTE_BASE+(j*4));
+ intel_private.registers+I810_PTE_BASE+(j*4));
}
- readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
break;
default:
goto out_err;
@@ -298,9 +318,9 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
return 0;
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
- writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
}
- readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
agp_bridge->driver->tlb_flush(mem);
return 0;
@@ -354,7 +374,7 @@ static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
struct agp_memory *new;
if (type == AGP_DCACHE_MEMORY) {
- if (pg_count != intel_i810_private.num_dcache_entries)
+ if (pg_count != intel_private.num_dcache_entries)
return NULL;
new = agp_create_memory(1);
@@ -404,18 +424,6 @@ static struct aper_size_info_fixed intel_i830_sizes[] =
{512, 131072, 7},
};
-static struct _intel_i830_private {
- struct pci_dev *i830_dev; /* device one */
- volatile u8 __iomem *registers;
- volatile u32 __iomem *gtt; /* I915G */
- /* gtt_entries is the number of gtt entries that are already mapped
- * to stolen memory. Stolen memory is larger than the memory mapped
- * through gtt_entries, as it includes some reserved space for the BIOS
- * popup and for the GTT.
- */
- int gtt_entries;
-} intel_i830_private;
-
static void intel_i830_init_gtt_entries(void)
{
u16 gmch_ctrl;
@@ -429,7 +437,7 @@ static void intel_i830_init_gtt_entries(void)
if (IS_I965) {
u32 pgetbl_ctl;
- pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL);
+ pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
/* The 965 has a field telling us the size of the GTT,
* which may be larger than what is necessary to map the
@@ -451,6 +459,22 @@ static void intel_i830_init_gtt_entries(void)
size = 512;
}
size += 4; /* add in BIOS popup space */
+ } else if (IS_G33) {
+ /* G33's GTT size defined in gmch_ctrl */
+ switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
+ case G33_PGETBL_SIZE_1M:
+ size = 1024;
+ break;
+ case G33_PGETBL_SIZE_2M:
+ size = 2048;
+ break;
+ default:
+ printk(KERN_INFO PFX "Unknown page table size 0x%x, "
+ "assuming 512KB\n",
+ (gmch_ctrl & G33_PGETBL_SIZE_MASK));
+ size = 512;
+ }
+ size += 4;
} else {
/* On previous hardware, the GTT size was just what was
* required to map the aperture.
@@ -471,7 +495,7 @@ static void intel_i830_init_gtt_entries(void)
gtt_entries = MB(8) - KB(size);
break;
case I830_GMCH_GMS_LOCAL:
- rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
+ rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE);
gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
MB(ddt[I830_RDRAM_DDT(rdct)]);
local = 1;
@@ -502,7 +526,8 @@ static void intel_i830_init_gtt_entries(void)
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965 )
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+ IS_I965 || IS_G33)
gtt_entries = MB(48) - KB(size);
else
gtt_entries = 0;
@@ -512,10 +537,24 @@ static void intel_i830_init_gtt_entries(void)
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
+ IS_I965 || IS_G33)
gtt_entries = MB(64) - KB(size);
else
gtt_entries = 0;
+ break;
+ case G33_GMCH_GMS_STOLEN_128M:
+ if (IS_G33)
+ gtt_entries = MB(128) - KB(size);
+ else
+ gtt_entries = 0;
+ break;
+ case G33_GMCH_GMS_STOLEN_256M:
+ if (IS_G33)
+ gtt_entries = MB(256) - KB(size);
+ else
+ gtt_entries = 0;
+ break;
default:
gtt_entries = 0;
break;
@@ -529,7 +568,7 @@ static void intel_i830_init_gtt_entries(void)
"No pre-allocated video memory detected.\n");
gtt_entries /= KB(4);
- intel_i830_private.gtt_entries = gtt_entries;
+ intel_private.gtt_entries = gtt_entries;
}
/* The intel i830 automatically initializes the agp aperture during POST.
@@ -547,14 +586,14 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
num_entries = size->num_entries;
agp_bridge->gatt_table_real = NULL;
- pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
+ pci_read_config_dword(intel_private.pcidev,I810_MMADDR,&temp);
temp &= 0xfff80000;
- intel_i830_private.registers = ioremap(temp,128 * 4096);
- if (!intel_i830_private.registers)
+ intel_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_private.registers)
return -ENOMEM;
- temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+ temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ?? */
/* we have to call this as early as possible after the MMIO base address is known */
@@ -614,20 +653,20 @@ static int intel_i830_configure(void)
current_size = A_SIZE_FIX(agp_bridge->current_size);
- pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
+ pci_read_config_dword(intel_private.pcidev,I810_GMADDR,&temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
gmch_ctrl |= I830_GMCH_ENABLED;
pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
- writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
- readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+ writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
if (agp_bridge->driver->needs_scratch_page) {
- for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
- readl(intel_i830_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
+ for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
+ readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
}
}
@@ -637,7 +676,7 @@ static int intel_i830_configure(void)
static void intel_i830_cleanup(void)
{
- iounmap(intel_i830_private.registers);
+ iounmap(intel_private.registers);
}
static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type)
@@ -653,9 +692,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
- if (pg_start < intel_i830_private.gtt_entries) {
- printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
- pg_start,intel_i830_private.gtt_entries);
+ if (pg_start < intel_private.gtt_entries) {
+ printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+ pg_start,intel_private.gtt_entries);
printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
goto out_err;
@@ -683,9 +722,9 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(agp_bridge->driver->mask_memory(agp_bridge,
mem->memory[i], mask_type),
- intel_i830_private.registers+I810_PTE_BASE+(j*4));
+ intel_private.registers+I810_PTE_BASE+(j*4));
}
- readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
agp_bridge->driver->tlb_flush(mem);
out:
@@ -703,15 +742,15 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
if (mem->page_count == 0)
return 0;
- if (pg_start < intel_i830_private.gtt_entries) {
+ if (pg_start < intel_private.gtt_entries) {
printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
return -EINVAL;
}
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
+ writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
}
- readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4));
agp_bridge->driver->tlb_flush(mem);
return 0;
@@ -734,7 +773,7 @@ static int intel_i915_configure(void)
current_size = A_SIZE_FIX(agp_bridge->current_size);
- pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I915_GMADDR, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
@@ -742,13 +781,13 @@ static int intel_i915_configure(void)
gmch_ctrl |= I830_GMCH_ENABLED;
pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
- writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
- readl(intel_i830_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
+ writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL);
+ readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */
if (agp_bridge->driver->needs_scratch_page) {
- for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
- readl(intel_i830_private.gtt+i); /* PCI Posting. */
+ for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
+ writel(agp_bridge->scratch_page, intel_private.gtt+i);
+ readl(intel_private.gtt+i); /* PCI Posting. */
}
}
@@ -758,8 +797,8 @@ static int intel_i915_configure(void)
static void intel_i915_cleanup(void)
{
- iounmap(intel_i830_private.gtt);
- iounmap(intel_i830_private.registers);
+ iounmap(intel_private.gtt);
+ iounmap(intel_private.registers);
}
static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
@@ -776,9 +815,9 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
- if (pg_start < intel_i830_private.gtt_entries) {
- printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
- pg_start,intel_i830_private.gtt_entries);
+ if (pg_start < intel_private.gtt_entries) {
+ printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n",
+ pg_start,intel_private.gtt_entries);
printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
goto out_err;
@@ -805,10 +844,10 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(agp_bridge->driver->mask_memory(agp_bridge,
- mem->memory[i], mask_type), intel_i830_private.gtt+j);
+ mem->memory[i], mask_type), intel_private.gtt+j);
}
- readl(intel_i830_private.gtt+j-1);
+ readl(intel_private.gtt+j-1);
agp_bridge->driver->tlb_flush(mem);
out:
@@ -826,15 +865,15 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
if (mem->page_count == 0)
return 0;
- if (pg_start < intel_i830_private.gtt_entries) {
+ if (pg_start < intel_private.gtt_entries) {
printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
return -EINVAL;
}
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
- writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
+ writel(agp_bridge->scratch_page, intel_private.gtt+i);
}
- readl(intel_i830_private.gtt+i-1);
+ readl(intel_private.gtt+i-1);
agp_bridge->driver->tlb_flush(mem);
return 0;
@@ -850,7 +889,7 @@ static int intel_i9xx_fetch_size(void)
int aper_size; /* size in megabytes */
int i;
- aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
+ aper_size = pci_resource_len(intel_private.pcidev, 2) / MB(1);
for (i = 0; i < num_sizes; i++) {
if (aper_size == intel_i830_sizes[i].size) {
@@ -878,20 +917,20 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
num_entries = size->num_entries;
agp_bridge->gatt_table_real = NULL;
- pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
- pci_read_config_dword(intel_i830_private.i830_dev, I915_PTEADDR,&temp2);
+ pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2);
- intel_i830_private.gtt = ioremap(temp2, 256 * 1024);
- if (!intel_i830_private.gtt)
+ intel_private.gtt = ioremap(temp2, 256 * 1024);
+ if (!intel_private.gtt)
return -ENOMEM;
temp &= 0xfff80000;
- intel_i830_private.registers = ioremap(temp,128 * 4096);
- if (!intel_i830_private.registers)
+ intel_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_private.registers)
return -ENOMEM;
- temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+ temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ? */
/* we have to call this as early as possible after the MMIO base address is known */
@@ -938,20 +977,20 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
num_entries = size->num_entries;
agp_bridge->gatt_table_real = NULL;
- pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp);
+ pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
temp &= 0xfff00000;
- intel_i830_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
+ intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
- if (!intel_i830_private.gtt)
+ if (!intel_private.gtt)
return -ENOMEM;
- intel_i830_private.registers = ioremap(temp,128 * 4096);
- if (!intel_i830_private.registers)
+ intel_private.registers = ioremap(temp,128 * 4096);
+ if (!intel_private.registers)
return -ENOMEM;
- temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
+ temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ? */
/* we have to call this as early as possible after the MMIO base address is known */
@@ -1722,41 +1761,127 @@ static const struct agp_bridge_driver intel_7505_driver = {
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
};
-static int find_i810(u16 device)
-{
- struct pci_dev *i810_dev;
-
- i810_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
- if (!i810_dev)
- return 0;
- intel_i810_private.i810_dev = i810_dev;
- return 1;
-}
+static const struct agp_bridge_driver intel_g33_driver = {
+ .owner = THIS_MODULE,
+ .aperture_sizes = intel_i830_sizes,
+ .size_type = FIXED_APER_SIZE,
+ .num_aperture_sizes = 4,
+ .needs_scratch_page = TRUE,
+ .configure = intel_i915_configure,
+ .fetch_size = intel_i9xx_fetch_size,
+ .cleanup = intel_i915_cleanup,
+ .tlb_flush = intel_i810_tlbflush,
+ .mask_memory = intel_i965_mask_memory,
+ .masks = intel_i810_masks,
+ .agp_enable = intel_i810_agp_enable,
+ .cache_flush = global_cache_flush,
+ .create_gatt_table = intel_i915_create_gatt_table,
+ .free_gatt_table = intel_i830_free_gatt_table,
+ .insert_memory = intel_i915_insert_entries,
+ .remove_memory = intel_i915_remove_entries,
+ .alloc_by_type = intel_i830_alloc_by_type,
+ .free_by_type = intel_i810_free_by_type,
+ .agp_alloc_page = agp_generic_alloc_page,
+ .agp_destroy_page = agp_generic_destroy_page,
+ .agp_type_to_mask_type = intel_i830_type_to_mask_type,
+};
-static int find_i830(u16 device)
+static int find_gmch(u16 device)
{
- struct pci_dev *i830_dev;
+ struct pci_dev *gmch_device;
- i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
- if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
- i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
- device, i830_dev);
+ gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
+ if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) {
+ gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL,
+ device, gmch_device);
}
- if (!i830_dev)
+ if (!gmch_device)
return 0;
- intel_i830_private.i830_dev = i830_dev;
+ intel_private.pcidev = gmch_device;
return 1;
}
+/* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of
+ * driver and gmch_driver must be non-null, and find_gmch will determine
+ * which one should be used if a gmch_chip_id is present.
+ */
+static const struct intel_driver_description {
+ unsigned int chip_id;
+ unsigned int gmch_chip_id;
+ unsigned int multi_gmch_chip; /* if we have more gfx chip type on this HB. */
+ char *name;
+ const struct agp_bridge_driver *driver;
+ const struct agp_bridge_driver *gmch_driver;
+} intel_agp_chipsets[] = {
+ { PCI_DEVICE_ID_INTEL_82443LX_0, 0, 0, "440LX", &intel_generic_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82443BX_0, 0, 0, "440BX", &intel_generic_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82443GX_0, 0, 0, "440GX", &intel_generic_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82810_MC1, PCI_DEVICE_ID_INTEL_82810_IG1, 0, "i810",
+ NULL, &intel_810_driver },
+ { PCI_DEVICE_ID_INTEL_82810_MC3, PCI_DEVICE_ID_INTEL_82810_IG3, 0, "i810",
+ NULL, &intel_810_driver },
+ { PCI_DEVICE_ID_INTEL_82810E_MC, PCI_DEVICE_ID_INTEL_82810E_IG, 0, "i810",
+ NULL, &intel_810_driver },
+ { PCI_DEVICE_ID_INTEL_82815_MC, PCI_DEVICE_ID_INTEL_82815_CGC, 0, "i815",
+ &intel_815_driver, &intel_810_driver },
+ { PCI_DEVICE_ID_INTEL_82820_HB, 0, 0, "i820", &intel_820_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82820_UP_HB, 0, 0, "i820", &intel_820_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82830_HB, PCI_DEVICE_ID_INTEL_82830_CGC, 0, "830M",
+ &intel_830mp_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82840_HB, 0, 0, "i840", &intel_840_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82845_HB, 0, 0, "845G", &intel_845_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, 0, "830M",
+ &intel_845_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82850_HB, 0, 0, "i850", &intel_850_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, 0, "855PM", &intel_845_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, 0, "855GM",
+ &intel_845_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82860_HB, 0, 0, "i860", &intel_860_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82865_HB, PCI_DEVICE_ID_INTEL_82865_IG, 0, "865",
+ &intel_845_driver, &intel_830_driver },
+ { PCI_DEVICE_ID_INTEL_82875_HB, 0, 0, "i875", &intel_845_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_82915G_HB, PCI_DEVICE_ID_INTEL_82915G_IG, 0, "915G",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82915GM_HB, PCI_DEVICE_ID_INTEL_82915GM_IG, 0, "915GM",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 1, "945GM",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME",
+ &intel_845_driver, &intel_915_driver },
+ { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965G_1_HB, PCI_DEVICE_ID_INTEL_82965G_1_IG, 0, "965G",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, 0, "965Q",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 1, "965GM",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE",
+ &intel_845_driver, &intel_i965_driver },
+ { PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL },
+ { PCI_DEVICE_ID_INTEL_G33_HB, PCI_DEVICE_ID_INTEL_G33_IG, 0, "G33",
+ &intel_845_driver, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_Q35_HB, PCI_DEVICE_ID_INTEL_Q35_IG, 0, "Q35",
+ &intel_845_driver, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
+ &intel_845_driver, &intel_g33_driver },
+ { 0, 0, 0, NULL, NULL, NULL }
+};
+
static int __devinit agp_intel_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
- char *name = "(unknown)";
u8 cap_ptr = 0;
struct resource *r;
+ int i;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
@@ -1764,195 +1889,46 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
if (!bridge)
return -ENOMEM;
- switch (pdev->device) {
- case PCI_DEVICE_ID_INTEL_82443LX_0:
- bridge->driver = &intel_generic_driver;
- name = "440LX";
- break;
- case PCI_DEVICE_ID_INTEL_82443BX_0:
- bridge->driver = &intel_generic_driver;
- name = "440BX";
- break;
- case PCI_DEVICE_ID_INTEL_82443GX_0:
- bridge->driver = &intel_generic_driver;
- name = "440GX";
- break;
- case PCI_DEVICE_ID_INTEL_82810_MC1:
- name = "i810";
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1))
- goto fail;
- bridge->driver = &intel_810_driver;
- break;
- case PCI_DEVICE_ID_INTEL_82810_MC3:
- name = "i810 DC100";
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3))
- goto fail;
- bridge->driver = &intel_810_driver;
- break;
- case PCI_DEVICE_ID_INTEL_82810E_MC:
- name = "i810 E";
- if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG))
- goto fail;
- bridge->driver = &intel_810_driver;
- break;
- case PCI_DEVICE_ID_INTEL_82815_MC:
- /*
- * The i815 can operate either as an i810 style
- * integrated device, or as an AGP4X motherboard.
- */
- if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC))
- bridge->driver = &intel_810_driver;
- else
- bridge->driver = &intel_815_driver;
- name = "i815";
- break;
- case PCI_DEVICE_ID_INTEL_82820_HB:
- case PCI_DEVICE_ID_INTEL_82820_UP_HB:
- bridge->driver = &intel_820_driver;
- name = "i820";
- break;
- case PCI_DEVICE_ID_INTEL_82830_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC))
- bridge->driver = &intel_830_driver;
- else
- bridge->driver = &intel_830mp_driver;
- name = "830M";
- break;
- case PCI_DEVICE_ID_INTEL_82840_HB:
- bridge->driver = &intel_840_driver;
- name = "i840";
- break;
- case PCI_DEVICE_ID_INTEL_82845_HB:
- bridge->driver = &intel_845_driver;
- name = "i845";
- break;
- case PCI_DEVICE_ID_INTEL_82845G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG))
- bridge->driver = &intel_830_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "845G";
- break;
- case PCI_DEVICE_ID_INTEL_82850_HB:
- bridge->driver = &intel_850_driver;
- name = "i850";
- break;
- case PCI_DEVICE_ID_INTEL_82855PM_HB:
- bridge->driver = &intel_845_driver;
- name = "855PM";
- break;
- case PCI_DEVICE_ID_INTEL_82855GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
- bridge->driver = &intel_830_driver;
- name = "855";
- } else {
- bridge->driver = &intel_845_driver;
- name = "855GM";
+ for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
+ /* In case that multiple models of gfx chip may
+ stand on same host bridge type, this can be
+ sure we detect the right IGD. */
+ if (pdev->device == intel_agp_chipsets[i].chip_id) {
+ if ((intel_agp_chipsets[i].gmch_chip_id != 0) &&
+ find_gmch(intel_agp_chipsets[i].gmch_chip_id)) {
+ bridge->driver =
+ intel_agp_chipsets[i].gmch_driver;
+ break;
+ } else if (intel_agp_chipsets[i].multi_gmch_chip) {
+ continue;
+ } else {
+ bridge->driver = intel_agp_chipsets[i].driver;
+ break;
+ }
}
- break;
- case PCI_DEVICE_ID_INTEL_82860_HB:
- bridge->driver = &intel_860_driver;
- name = "i860";
- break;
- case PCI_DEVICE_ID_INTEL_82865_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG))
- bridge->driver = &intel_830_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "865";
- break;
- case PCI_DEVICE_ID_INTEL_82875_HB:
- bridge->driver = &intel_845_driver;
- name = "i875";
- break;
- case PCI_DEVICE_ID_INTEL_82915G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82915G_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "915G";
- break;
- case PCI_DEVICE_ID_INTEL_82915GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82915GM_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "915GM";
- break;
- case PCI_DEVICE_ID_INTEL_82945G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "945G";
- break;
- case PCI_DEVICE_ID_INTEL_82945GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82945GM_IG))
- bridge->driver = &intel_915_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "945GM";
- break;
- case PCI_DEVICE_ID_INTEL_82946GZ_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82946GZ_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "946GZ";
- break;
- case PCI_DEVICE_ID_INTEL_82965G_1_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965G";
- break;
- case PCI_DEVICE_ID_INTEL_82965Q_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965Q_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965Q";
- break;
- case PCI_DEVICE_ID_INTEL_82965G_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965G";
- break;
- case PCI_DEVICE_ID_INTEL_82965GM_HB:
- if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
- bridge->driver = &intel_i965_driver;
- else
- bridge->driver = &intel_845_driver;
- name = "965GM";
- break;
- case PCI_DEVICE_ID_INTEL_7505_0:
- bridge->driver = &intel_7505_driver;
- name = "E7505";
- break;
- case PCI_DEVICE_ID_INTEL_7205_0:
- bridge->driver = &intel_7505_driver;
- name = "E7205";
- break;
- default:
+ }
+
+ if (intel_agp_chipsets[i].name == NULL) {
if (cap_ptr)
- printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n",
- pdev->device);
+ printk(KERN_WARNING PFX "Unsupported Intel chipset"
+ "(device id: %04x)\n", pdev->device);
+ agp_put_bridge(bridge);
+ return -ENODEV;
+ }
+
+ if (bridge->driver == NULL) {
+ printk(KERN_WARNING PFX "Failed to find bridge device "
+ "(chip_id: %04x)\n", intel_agp_chipsets[i].gmch_chip_id);
agp_put_bridge(bridge);
return -ENODEV;
- };
+ }
bridge->dev = pdev;
bridge->capndx = cap_ptr;
+ bridge->dev_private_data = &intel_private;
- if (bridge->driver == &intel_810_driver)
- bridge->dev_private_data = &intel_i810_private;
- else if (bridge->driver == &intel_830_driver)
- bridge->dev_private_data = &intel_i830_private;
-
- printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
+ printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n",
+ intel_agp_chipsets[i].name);
/*
* The following fixes the case where the BIOS has "forgotten" to
@@ -1988,12 +1964,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
-
-fail:
- printk(KERN_ERR PFX "Detected an Intel %s chipset, "
- "but could not find the secondary device.\n", name);
- agp_put_bridge(bridge);
- return -ENODEV;
}
static void __devexit agp_intel_remove(struct pci_dev *pdev)
@@ -2002,10 +1972,8 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
agp_remove_bridge(bridge);
- if (intel_i810_private.i810_dev)
- pci_dev_put(intel_i810_private.i810_dev);
- if (intel_i830_private.i830_dev)
- pci_dev_put(intel_i830_private.i830_dev);
+ if (intel_private.pcidev)
+ pci_dev_put(intel_private.pcidev);
agp_put_bridge(bridge);
}
@@ -2021,10 +1989,8 @@ static int agp_intel_resume(struct pci_dev *pdev)
* as host bridge (00:00) resumes before graphics device (02:00),
* then our access to its pci space can work right.
*/
- if (intel_i810_private.i810_dev)
- pci_restore_state(intel_i810_private.i810_dev);
- if (intel_i830_private.i830_dev)
- pci_restore_state(intel_i830_private.i830_dev);
+ if (intel_private.pcidev)
+ pci_restore_state(intel_private.pcidev);
if (bridge->driver == &intel_generic_driver)
intel_configure();
@@ -2087,6 +2053,9 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
ID(PCI_DEVICE_ID_INTEL_82965G_HB),
ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
+ ID(PCI_DEVICE_ID_INTEL_G33_HB),
+ ID(PCI_DEVICE_ID_INTEL_Q35_HB),
+ ID(PCI_DEVICE_ID_INTEL_Q33_HB),
{ }
};
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index c72ee97d389..ca376b92162 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -1061,6 +1061,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
if (data & info->ignore_status_mask) {
info->icount.rx++;
+ spin_unlock(&cinfo->card_lock);
return;
}
if (tty_buffer_request_room(tty, 1)) {
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index ef833a1c27e..0b7ffa5191c 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -6,7 +6,7 @@
#
config DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
- depends on (AGP || AGP=n) && PCI
+ depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
index de37d5f7456..b33313be254 100644
--- a/drivers/char/drm/drm_drawable.c
+++ b/drivers/char/drm/drm_drawable.c
@@ -172,38 +172,49 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
bitfield_length = idx + 1;
- if (idx != id / (8 * sizeof(*bitfield)))
- bitfield = drm_alloc(bitfield_length *
- sizeof(*bitfield), DRM_MEM_BUFS);
+ bitfield = NULL;
- if (!bitfield && bitfield_length) {
- bitfield = dev->drw_bitfield;
- bitfield_length = dev->drw_bitfield_length;
+ if (bitfield_length) {
+ if (bitfield_length != dev->drw_bitfield_length)
+ bitfield = drm_alloc(bitfield_length *
+ sizeof(*bitfield),
+ DRM_MEM_BUFS);
+
+ if (!bitfield) {
+ bitfield = dev->drw_bitfield;
+ bitfield_length = dev->drw_bitfield_length;
+ }
}
}
if (bitfield != dev->drw_bitfield) {
info_length = 8 * sizeof(*bitfield) * bitfield_length;
- info = drm_alloc(info_length * sizeof(*info), DRM_MEM_BUFS);
+ if (info_length) {
+ info = drm_alloc(info_length * sizeof(*info),
+ DRM_MEM_BUFS);
- if (!info && info_length) {
- info = dev->drw_info;
- info_length = dev->drw_info_length;
- }
+ if (!info) {
+ info = dev->drw_info;
+ info_length = dev->drw_info_length;
+ }
+ } else
+ info = NULL;
spin_lock_irqsave(&dev->drw_lock, irqflags);
- memcpy(bitfield, dev->drw_bitfield, bitfield_length *
- sizeof(*bitfield));
+ if (bitfield)
+ memcpy(bitfield, dev->drw_bitfield, bitfield_length *
+ sizeof(*bitfield));
drm_free(dev->drw_bitfield, sizeof(*bitfield) *
dev->drw_bitfield_length, DRM_MEM_BUFS);
dev->drw_bitfield = bitfield;
dev->drw_bitfield_length = bitfield_length;
if (info != dev->drw_info) {
- memcpy(info, dev->drw_info, info_length *
- sizeof(*info));
+ if (info)
+ memcpy(info, dev->drw_info, info_length *
+ sizeof(*info));
drm_free(dev->drw_info, sizeof(*info) *
dev->drw_info_length, DRM_MEM_BUFS);
dev->drw_info = info;
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 31cdde83713..177ccc07f96 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -102,13 +102,20 @@
{0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+ {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index 78c1ae28f17..b92062a239f 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -582,7 +582,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- dev_priv->swaps_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&dev_priv->swaps_lock);
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
dev_priv->swaps_pending = 0;
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index b3d4ccc33a4..154f42203b0 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1191,6 +1191,7 @@ static int job_control(struct tty_struct *tty, struct file *file)
is_current_pgrp_orphaned())
return -EIO;
kill_pgrp(task_pgrp(current), SIGTTIN, 1);
+ set_thread_flag(TIF_SIGPENDING);
return -ERESTARTSYS;
}
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 46c1b97748b..0474cac4a84 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -760,7 +760,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
static void extract_buf(struct entropy_store *r, __u8 *out)
{
- int i, x;
+ int i;
__u32 data[16], buf[5 + SHA_WORKSPACE_WORDS];
sha_init(buf);
@@ -772,9 +772,11 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
* attempts to find previous ouputs), unless the hash
* function can be inverted.
*/
- for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
- sha_transform(buf, (__u8 *)r->pool+i, buf + 5);
- add_entropy_words(r, &buf[x % 5], 1);
+ for (i = 0; i < r->poolinfo->poolwords; i += 16) {
+ /* hash blocks of 16 words = 512 bits */
+ sha_transform(buf, (__u8 *)(r->pool + i), buf + 5);
+ /* feed back portion of the resulting hash */
+ add_entropy_words(r, &buf[i % 5], 1);
}
/*
@@ -782,7 +784,7 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
* portion of the pool while mixing, and hash one
* final time.
*/
- __add_entropy_words(r, &buf[x % 5], 1, data);
+ __add_entropy_words(r, &buf[i % 5], 1, data);
sha_transform(buf, (__u8 *)data, buf + 5);
/*
@@ -1018,37 +1020,44 @@ random_poll(struct file *file, poll_table * wait)
return mask;
}
-static ssize_t
-random_write(struct file * file, const char __user * buffer,
- size_t count, loff_t *ppos)
+static int
+write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
{
- int ret = 0;
size_t bytes;
__u32 buf[16];
const char __user *p = buffer;
- size_t c = count;
- while (c > 0) {
- bytes = min(c, sizeof(buf));
+ while (count > 0) {
+ bytes = min(count, sizeof(buf));
+ if (copy_from_user(&buf, p, bytes))
+ return -EFAULT;
- bytes -= copy_from_user(&buf, p, bytes);
- if (!bytes) {
- ret = -EFAULT;
- break;
- }
- c -= bytes;
+ count -= bytes;
p += bytes;
- add_entropy_words(&input_pool, buf, (bytes + 3) / 4);
- }
- if (p == buffer) {
- return (ssize_t)ret;
- } else {
- struct inode *inode = file->f_path.dentry->d_inode;
- inode->i_mtime = current_fs_time(inode->i_sb);
- mark_inode_dirty(inode);
- return (ssize_t)(p - buffer);
+ add_entropy_words(r, buf, (bytes + 3) / 4);
}
+
+ return 0;
+}
+
+static ssize_t
+random_write(struct file * file, const char __user * buffer,
+ size_t count, loff_t *ppos)
+{
+ size_t ret;
+ struct inode *inode = file->f_path.dentry->d_inode;
+
+ ret = write_pool(&blocking_pool, buffer, count);
+ if (ret)
+ return ret;
+ ret = write_pool(&nonblocking_pool, buffer, count);
+ if (ret)
+ return ret;
+
+ inode->i_mtime = current_fs_time(inode->i_sb);
+ mark_inode_dirty(inode);
+ return (ssize_t)count;
}
static int
@@ -1087,8 +1096,8 @@ random_ioctl(struct inode * inode, struct file * file,
return -EINVAL;
if (get_user(size, p++))
return -EFAULT;
- retval = random_write(file, (const char __user *) p,
- size, &file->f_pos);
+ retval = write_pool(&input_pool, (const char __user *)p,
+ size);
if (retval < 0)
return retval;
credit_entropy_store(&input_pool, ent_count);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index e45113a7a47..45bf2a262a8 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -2172,11 +2172,12 @@ static int __devinit stl_initech(struct stlbrd *brdp)
}
status = inb(ioaddr + ECH_PNLSTATUS);
if ((status & ECH_PNLIDMASK) != nxtid)
- goto err_fr;
+ break;
panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL);
if (!panelp) {
printk("STALLION: failed to allocate memory "
"(size=%Zd)\n", sizeof(struct stlpanel));
+ retval = -ENOMEM;
goto err_fr;
}
panelp->magic = STL_PANELMAGIC;
@@ -2223,8 +2224,10 @@ static int __devinit stl_initech(struct stlbrd *brdp)
brdp->nrports += panelp->nrports;
brdp->panels[panelnr++] = panelp;
if ((brdp->brdtype != BRD_ECHPCI) &&
- (ioaddr >= (brdp->ioaddr2 + brdp->iosize2)))
+ (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) {
+ retval = -EINVAL;
goto err_fr;
+ }
}
brdp->nrpanels = panelnr;
@@ -2371,6 +2374,7 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev,
dev_err(&pdev->dev, "too many boards found, "
"maximum supported %d\n", STL_MAXBRDS);
mutex_unlock(&stl_brdslock);
+ retval = -ENODEV;
goto err_fr;
}
brdp->brdnr = (unsigned int)brdnr;
@@ -4710,6 +4714,29 @@ static int __init stallion_module_init(void)
spin_lock_init(&stallion_lock);
spin_lock_init(&brd_lock);
+ stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
+ if (!stl_serial) {
+ retval = -ENOMEM;
+ goto err;
+ }
+
+ stl_serial->owner = THIS_MODULE;
+ stl_serial->driver_name = stl_drvname;
+ stl_serial->name = "ttyE";
+ stl_serial->major = STL_SERIALMAJOR;
+ stl_serial->minor_start = 0;
+ stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
+ stl_serial->subtype = SERIAL_TYPE_NORMAL;
+ stl_serial->init_termios = stl_deftermios;
+ stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ tty_set_operations(stl_serial, &stl_ops);
+
+ retval = tty_register_driver(stl_serial);
+ if (retval) {
+ printk("STALLION: failed to register serial driver\n");
+ goto err_frtty;
+ }
+
/*
* Find any dynamically supported boards. That is via module load
* line options.
@@ -4739,13 +4766,9 @@ static int __init stallion_module_init(void)
/* this has to be _after_ isa finding because of locking */
retval = pci_register_driver(&stl_pcidriver);
- if (retval && stl_nrbrds == 0)
- goto err;
-
- stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
- if (!stl_serial) {
- retval = -ENOMEM;
- goto err_pcidr;
+ if (retval && stl_nrbrds == 0) {
+ printk(KERN_ERR "STALLION: can't register pci driver\n");
+ goto err_unrtty;
}
/*
@@ -4756,43 +4779,18 @@ static int __init stallion_module_init(void)
printk("STALLION: failed to register serial board device\n");
stallion_class = class_create(THIS_MODULE, "staliomem");
- if (IS_ERR(stallion_class)) {
- retval = PTR_ERR(stallion_class);
- goto err_reg;
- }
+ if (IS_ERR(stallion_class))
+ printk("STALLION: failed to create class\n");
for (i = 0; i < 4; i++)
class_device_create(stallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i), NULL,
"staliomem%d", i);
- stl_serial->owner = THIS_MODULE;
- stl_serial->driver_name = stl_drvname;
- stl_serial->name = "ttyE";
- stl_serial->major = STL_SERIALMAJOR;
- stl_serial->minor_start = 0;
- stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
- stl_serial->subtype = SERIAL_TYPE_NORMAL;
- stl_serial->init_termios = stl_deftermios;
- stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
- tty_set_operations(stl_serial, &stl_ops);
-
- retval = tty_register_driver(stl_serial);
- if (retval) {
- printk("STALLION: failed to register serial driver\n");
- goto err_clsdev;
- }
-
return 0;
-err_clsdev:
- for (i = 0; i < 4; i++)
- class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
- class_destroy(stallion_class);
-err_reg:
- unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
+err_unrtty:
+ tty_unregister_driver(stl_serial);
+err_frtty:
put_tty_driver(stl_serial);
-err_pcidr:
- pci_unregister_driver(&stl_pcidriver);
- stl_free_isabrds();
err:
return retval;
}
@@ -4821,8 +4819,6 @@ static void __exit stallion_module_exit(void)
tty_unregister_device(stl_serial,
brdp->brdnr * STL_MAXPORTS + j);
}
- tty_unregister_driver(stl_serial);
- put_tty_driver(stl_serial);
for (i = 0; i < 4; i++)
class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
@@ -4834,6 +4830,9 @@ static void __exit stallion_module_exit(void)
pci_unregister_driver(&stl_pcidriver);
stl_free_isabrds();
+
+ tty_unregister_driver(stl_serial);
+ put_tty_driver(stl_serial);
}
module_init(stallion_module_init);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 75d2a46e106..3752edc30c3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1148,7 +1148,8 @@ int tty_check_change(struct tty_struct * tty)
return 0;
if (is_current_pgrp_orphaned())
return -EIO;
- (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
+ kill_pgrp(task_pgrp(current), SIGTTOU, 1);
+ set_thread_flag(TIF_SIGPENDING);
return -ERESTARTSYS;
}
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 1cad32c62ed..53f5538c0c0 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -115,6 +115,13 @@ config IXP4XX_WATCHDOG
Say N if you are unsure.
+config KS8695_WATCHDOG
+ tristate "KS8695 watchdog"
+ depends on ARCH_KS8695
+ help
+ Watchdog timer embedded into KS8695 processor. This will reboot your
+ system when the timeout is reached.
+
config S3C2410_WATCHDOG
tristate "S3C2410 Watchdog"
depends on ARCH_S3C2410
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 8bfc00cc7c2..d90f649038c 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
+obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index fd955dbd588..dc7548dcaf3 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -205,7 +205,7 @@ static void __exit ixp2000_wdt_exit(void)
module_init(ixp2000_wdt_init);
module_exit(ixp2000_wdt_exit);
-MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net">);
+MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
MODULE_DESCRIPTION("IXP2000 Network Processor Watchdog");
module_param(heartbeat, int, 0);
diff --git a/drivers/char/watchdog/ks8695_wdt.c b/drivers/char/watchdog/ks8695_wdt.c
new file mode 100644
index 00000000000..7150fb945ea
--- /dev/null
+++ b/drivers/char/watchdog/ks8695_wdt.c
@@ -0,0 +1,308 @@
+/*
+ * Watchdog driver for Kendin/Micrel KS8695.
+ *
+ * (C) 2007 Andrew Victor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/arch/regs-timer.h>
+
+
+#define WDT_DEFAULT_TIME 5 /* seconds */
+#define WDT_MAX_TIME 171 /* seconds */
+
+static int wdt_time = WDT_DEFAULT_TIME;
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_time, int, 0);
+MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")");
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+#endif
+
+
+static unsigned long ks8695wdt_busy;
+
+/* ......................................................................... */
+
+/*
+ * Disable the watchdog.
+ */
+static void inline ks8695_wdt_stop(void)
+{
+ unsigned long tmcon;
+
+ /* disable timer0 */
+ tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+ __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+/*
+ * Enable and reset the watchdog.
+ */
+static void inline ks8695_wdt_start(void)
+{
+ unsigned long tmcon;
+ unsigned long tval = wdt_time * CLOCK_TICK_RATE;
+
+ /* disable timer0 */
+ tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+ __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+
+ /* program timer0 */
+ __raw_writel(tval | T0TC_WATCHDOG, KS8695_TMR_VA + KS8695_T0TC);
+
+ /* re-enable timer0 */
+ tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+ __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+/*
+ * Reload the watchdog timer. (ie, pat the watchdog)
+ */
+static void inline ks8695_wdt_reload(void)
+{
+ unsigned long tmcon;
+
+ /* disable, then re-enable timer0 */
+ tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+ __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+ __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+/*
+ * Change the watchdog time interval.
+ */
+static int ks8695_wdt_settimeout(int new_time)
+{
+ /*
+ * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz
+ *
+ * Since WDV is a 16-bit counter, the maximum period is
+ * 65536 / 0.256 = 256 seconds.
+ */
+ if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
+ return -EINVAL;
+
+ /* Set new watchdog time. It will be used when ks8695_wdt_start() is called. */
+ wdt_time = new_time;
+ return 0;
+}
+
+/* ......................................................................... */
+
+/*
+ * Watchdog device is opened, and watchdog starts running.
+ */
+static int ks8695_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(0, &ks8695wdt_busy))
+ return -EBUSY;
+
+ ks8695_wdt_start();
+ return nonseekable_open(inode, file);
+}
+
+/*
+ * Close the watchdog device.
+ * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also
+ * disabled.
+ */
+static int ks8695_wdt_close(struct inode *inode, struct file *file)
+{
+ if (!nowayout)
+ ks8695_wdt_stop(); /* Disable the watchdog when file is closed */
+
+ clear_bit(0, &ks8695wdt_busy);
+ return 0;
+}
+
+static struct watchdog_info ks8695_wdt_info = {
+ .identity = "ks8695 watchdog",
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+};
+
+/*
+ * Handle commands from user-space.
+ */
+static int ks8695_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int new_value;
+
+ switch(cmd) {
+ case WDIOC_KEEPALIVE:
+ ks8695_wdt_reload(); /* pat the watchdog */
+ return 0;
+
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &ks8695_wdt_info, sizeof(ks8695_wdt_info)) ? -EFAULT : 0;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_value, p))
+ return -EFAULT;
+
+ if (ks8695_wdt_settimeout(new_value))
+ return -EINVAL;
+
+ /* Enable new time value */
+ ks8695_wdt_start();
+
+ /* Return current value */
+ return put_user(wdt_time, p);
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(wdt_time, p);
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, p);
+
+ case WDIOC_SETOPTIONS:
+ if (get_user(new_value, p))
+ return -EFAULT;
+
+ if (new_value & WDIOS_DISABLECARD)
+ ks8695_wdt_stop();
+ if (new_value & WDIOS_ENABLECARD)
+ ks8695_wdt_start();
+ return 0;
+
+ default:
+ return -ENOTTY;
+ }
+}
+
+/*
+ * Pat the watchdog whenever device is written to.
+ */
+static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+{
+ ks8695_wdt_reload(); /* pat the watchdog */
+ return len;
+}
+
+/* ......................................................................... */
+
+static const struct file_operations ks8695wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .ioctl = ks8695_wdt_ioctl,
+ .open = ks8695_wdt_open,
+ .release = ks8695_wdt_close,
+ .write = ks8695_wdt_write,
+};
+
+static struct miscdevice ks8695wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &ks8695wdt_fops,
+};
+
+static int __init ks8695wdt_probe(struct platform_device *pdev)
+{
+ int res;
+
+ if (ks8695wdt_miscdev.parent)
+ return -EBUSY;
+ ks8695wdt_miscdev.parent = &pdev->dev;
+
+ res = misc_register(&ks8695wdt_miscdev);
+ if (res)
+ return res;
+
+ printk("KS8695 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : "");
+ return 0;
+}
+
+static int __exit ks8695wdt_remove(struct platform_device *pdev)
+{
+ int res;
+
+ res = misc_deregister(&ks8695wdt_miscdev);
+ if (!res)
+ ks8695wdt_miscdev.parent = NULL;
+
+ return res;
+}
+
+static void ks8695wdt_shutdown(struct platform_device *pdev)
+{
+ ks8695_wdt_stop();
+}
+
+#ifdef CONFIG_PM
+
+static int ks8695wdt_suspend(struct platform_device *pdev, pm_message_t message)
+{
+ ks8695_wdt_stop();
+ return 0;
+}
+
+static int ks8695wdt_resume(struct platform_device *pdev)
+{
+ if (ks8695wdt_busy)
+ ks8695_wdt_start();
+ return 0;
+}
+
+#else
+#define ks8695wdt_suspend NULL
+#define ks8695wdt_resume NULL
+#endif
+
+static struct platform_driver ks8695wdt_driver = {
+ .probe = ks8695wdt_probe,
+ .remove = __exit_p(ks8695wdt_remove),
+ .shutdown = ks8695wdt_shutdown,
+ .suspend = ks8695wdt_suspend,
+ .resume = ks8695wdt_resume,
+ .driver = {
+ .name = "ks8695_wdt",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ks8695_wdt_init(void)
+{
+ /* Check that the heartbeat value is within range; if not reset to the default */
+ if (ks8695_wdt_settimeout(wdt_time)) {
+ ks8695_wdt_settimeout(WDT_DEFAULT_TIME);
+ pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", wdt_time, WDT_MAX_TIME);
+ }
+
+ return platform_driver_register(&ks8695wdt_driver);
+}
+
+static void __exit ks8695_wdt_exit(void)
+{
+ platform_driver_unregister(&ks8695wdt_driver);
+}
+
+module_init(ks8695_wdt_init);
+module_exit(ks8695_wdt_exit);
+
+MODULE_AUTHOR("Andrew Victor");
+MODULE_DESCRIPTION("Watchdog driver for KS8695");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c
index 6d3840e629d..6a86958b577 100644
--- a/drivers/crypto/geode-aes.c
+++ b/drivers/crypto/geode-aes.c
@@ -102,10 +102,15 @@ geode_aes_crypt(struct geode_aes_op *op)
u32 flags = 0;
unsigned long iflags;
- if (op->len == 0 || op->src == op->dst)
+ if (op->len == 0)
return 0;
- if (op->flags & AES_FLAGS_COHERENT)
+ /* If the source and destination is the same, then
+ * we need to turn on the coherent flags, otherwise
+ * we don't need to worry
+ */
+
+ if (op->src == op->dst)
flags |= (AES_CTRL_DCA | AES_CTRL_SCA);
if (op->dir == AES_DIR_ENCRYPT)
@@ -120,7 +125,7 @@ geode_aes_crypt(struct geode_aes_op *op)
_writefield(AES_WRITEIV0_REG, op->iv);
}
- if (op->flags & AES_FLAGS_USRKEY) {
+ if (!(op->flags & AES_FLAGS_HIDDENKEY)) {
flags |= AES_CTRL_WRKEY;
_writefield(AES_WRITEKEY0_REG, op->key);
}
@@ -289,6 +294,7 @@ static struct crypto_alg geode_cbc_alg = {
.setkey = geode_setkey,
.encrypt = geode_cbc_encrypt,
.decrypt = geode_cbc_decrypt,
+ .ivsize = AES_IV_LENGTH,
}
}
};
diff --git a/drivers/crypto/geode-aes.h b/drivers/crypto/geode-aes.h
index 8003a36f3a8..f47968671ae 100644
--- a/drivers/crypto/geode-aes.h
+++ b/drivers/crypto/geode-aes.h
@@ -20,8 +20,7 @@
#define AES_DIR_DECRYPT 0
#define AES_DIR_ENCRYPT 1
-#define AES_FLAGS_USRKEY (1 << 0)
-#define AES_FLAGS_COHERENT (1 << 1)
+#define AES_FLAGS_HIDDENKEY (1 << 0)
struct geode_aes_op {
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 5932c72f9e4..396dade731f 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -18,7 +18,7 @@ config FIREWIRE
your IEEE 1394 adapter.
To compile this driver as a module, say M here: the module will be
- called fw-core.
+ called firewire-core.
This is the "JUJU" FireWire stack, an alternative implementation
designed for robustness and simplicity. You can build either this
@@ -34,11 +34,11 @@ config FIREWIRE_OHCI
is the only chipset in use, so say Y here.
To compile this driver as a module, say M here: The module will be
- called fw-ohci.
+ called firewire-ohci.
If you also build ohci1394 of the classic IEEE 1394 driver stack,
- blacklist either ohci1394 or fw-ohci to let hotplug load the desired
- driver.
+ blacklist either ohci1394 or firewire-ohci to let hotplug load the
+ desired driver.
config FIREWIRE_SBP2
tristate "Support for storage devices (SBP-2 protocol driver)"
@@ -50,12 +50,12 @@ config FIREWIRE_SBP2
like scanners.
To compile this driver as a module, say M here: The module will be
- called fw-sbp2.
+ called firewire-sbp2.
You should also enable support for disks, CD-ROMs, etc. in the SCSI
configuration section.
If you also build sbp2 of the classic IEEE 1394 driver stack,
- blacklist either sbp2 or fw-sbp2 to let hotplug load the desired
- driver.
+ blacklist either sbp2 or firewire-sbp2 to let hotplug load the
+ desired driver.
diff --git a/drivers/firewire/Makefile b/drivers/firewire/Makefile
index fc7d59d4bce..a7c31e9039c 100644
--- a/drivers/firewire/Makefile
+++ b/drivers/firewire/Makefile
@@ -2,9 +2,11 @@
# Makefile for the Linux IEEE 1394 implementation
#
-fw-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
- fw-device.o fw-cdev.o
+firewire-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
+ fw-device.o fw-cdev.o
+firewire-ohci-y += fw-ohci.o
+firewire-sbp2-y += fw-sbp2.o
-obj-$(CONFIG_FIREWIRE) += fw-core.o
-obj-$(CONFIG_FIREWIRE_OHCI) += fw-ohci.o
-obj-$(CONFIG_FIREWIRE_SBP2) += fw-sbp2.o
+obj-$(CONFIG_FIREWIRE) += firewire-core.o
+obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o
+obj-$(CONFIG_FIREWIRE_SBP2) += firewire-sbp2.o
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index 636151a64ad..9eb1edacd82 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -407,11 +407,6 @@ fw_card_add(struct fw_card *card,
card->link_speed = link_speed;
card->guid = guid;
- /* Activate link_on bit and contender bit in our self ID packets.*/
- if (card->driver->update_phy_reg(card, 4, 0,
- PHY_LINK_ACTIVE | PHY_CONTENDER) < 0)
- return -EIO;
-
/*
* The subsystem grabs a reference when the card is added and
* drops it when the driver calls fw_core_remove_card.
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 0fa5bd54c6a..5d402d63799 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -365,7 +365,7 @@ complete_transaction(struct fw_card *card, int rcode,
response->response.data, response->response.length);
}
-static ssize_t ioctl_send_request(struct client *client, void *buffer)
+static int ioctl_send_request(struct client *client, void *buffer)
{
struct fw_device *device = client->device;
struct fw_cdev_send_request *request = buffer;
@@ -677,12 +677,21 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
return 0;
}
+/* Macros for decoding the iso packet control header. */
+#define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff)
+#define GET_INTERRUPT(v) (((v) >> 16) & 0x01)
+#define GET_SKIP(v) (((v) >> 17) & 0x01)
+#define GET_TAG(v) (((v) >> 18) & 0x02)
+#define GET_SY(v) (((v) >> 20) & 0x04)
+#define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
+
static int ioctl_queue_iso(struct client *client, void *buffer)
{
struct fw_cdev_queue_iso *request = buffer;
struct fw_cdev_iso_packet __user *p, *end, *next;
struct fw_iso_context *ctx = client->iso_context;
unsigned long payload, buffer_end, header_length;
+ u32 control;
int count;
struct {
struct fw_iso_packet packet;
@@ -717,8 +726,14 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
end = (void __user *)p + request->size;
count = 0;
while (p < end) {
- if (__copy_from_user(&u.packet, p, sizeof(*p)))
+ if (get_user(control, &p->control))
return -EFAULT;
+ u.packet.payload_length = GET_PAYLOAD_LENGTH(control);
+ u.packet.interrupt = GET_INTERRUPT(control);
+ u.packet.skip = GET_SKIP(control);
+ u.packet.tag = GET_TAG(control);
+ u.packet.sy = GET_SY(control);
+ u.packet.header_length = GET_HEADER_LENGTH(control);
if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
header_length = u.packet.header_length;
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index 0ba9d64ccf4..af1723eae4b 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -99,6 +99,7 @@ fw_unit(struct device *dev)
#define CSR_DEPENDENT_INFO 0x14
#define CSR_MODEL 0x17
#define CSR_INSTANCE 0x18
+#define CSR_DIRECTORY_ID 0x20
#define SBP2_COMMAND_SET_SPECIFIER 0x38
#define SBP2_COMMAND_SET 0x39
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index c17342d3e6f..0d08bf9b78c 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -268,7 +268,7 @@ static int ar_context_add_page(struct ar_context *ctx)
dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
- ctx->last_buffer->descriptor.branch_address = ab_bus | 1;
+ ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
ctx->last_buffer->next = ab;
ctx->last_buffer = ab;
@@ -417,11 +417,21 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
ctx->current_buffer = ab.next;
ctx->pointer = ctx->current_buffer->data;
- reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab.descriptor.branch_address);
+ return 0;
+}
+
+static void ar_context_run(struct ar_context *ctx)
+{
+ struct ar_buffer *ab = ctx->current_buffer;
+ dma_addr_t ab_bus;
+ size_t offset;
+
+ offset = offsetof(struct ar_buffer, data);
+ ab_bus = ab->descriptor.data_address - offset;
+
+ reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1);
reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
flush_writes(ctx->ohci);
-
- return 0;
}
static void context_tasklet(unsigned long data)
@@ -1038,11 +1048,78 @@ static irqreturn_t irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
+static int software_reset(struct fw_ohci *ohci)
+{
+ int i;
+
+ reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
+
+ for (i = 0; i < OHCI_LOOP_COUNT; i++) {
+ if ((reg_read(ohci, OHCI1394_HCControlSet) &
+ OHCI1394_HCControl_softReset) == 0)
+ return 0;
+ msleep(1);
+ }
+
+ return -EBUSY;
+}
+
static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
{
struct fw_ohci *ohci = fw_ohci(card);
struct pci_dev *dev = to_pci_dev(card->device);
+ if (software_reset(ohci)) {
+ fw_error("Failed to reset ohci card.\n");
+ return -EBUSY;
+ }
+
+ /*
+ * Now enable LPS, which we need in order to start accessing
+ * most of the registers. In fact, on some cards (ALI M5251),
+ * accessing registers in the SClk domain without LPS enabled
+ * will lock up the machine. Wait 50msec to make sure we have
+ * full link enabled.
+ */
+ reg_write(ohci, OHCI1394_HCControlSet,
+ OHCI1394_HCControl_LPS |
+ OHCI1394_HCControl_postedWriteEnable);
+ flush_writes(ohci);
+ msleep(50);
+
+ reg_write(ohci, OHCI1394_HCControlClear,
+ OHCI1394_HCControl_noByteSwapData);
+
+ reg_write(ohci, OHCI1394_LinkControlSet,
+ OHCI1394_LinkControl_rcvSelfID |
+ OHCI1394_LinkControl_cycleTimerEnable |
+ OHCI1394_LinkControl_cycleMaster);
+
+ reg_write(ohci, OHCI1394_ATRetries,
+ OHCI1394_MAX_AT_REQ_RETRIES |
+ (OHCI1394_MAX_AT_RESP_RETRIES << 4) |
+ (OHCI1394_MAX_PHYS_RESP_RETRIES << 8));
+
+ ar_context_run(&ohci->ar_request_ctx);
+ ar_context_run(&ohci->ar_response_ctx);
+
+ reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
+ reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
+ reg_write(ohci, OHCI1394_IntEventClear, ~0);
+ reg_write(ohci, OHCI1394_IntMaskClear, ~0);
+ reg_write(ohci, OHCI1394_IntMaskSet,
+ OHCI1394_selfIDComplete |
+ OHCI1394_RQPkt | OHCI1394_RSPkt |
+ OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
+ OHCI1394_isochRx | OHCI1394_isochTx |
+ OHCI1394_masterIntEnable |
+ OHCI1394_cycle64Seconds);
+
+ /* Activate link_on bit and contender bit in our self ID packets.*/
+ if (ohci_update_phy_reg(card, 4, 0,
+ PHY_LINK_ACTIVE | PHY_CONTENDER) < 0)
+ return -EIO;
+
/*
* When the link is not yet enabled, the atomic config rom
* update mechanism described below in ohci_set_config_rom()
@@ -1700,22 +1777,6 @@ static const struct fw_card_driver ohci_driver = {
.stop_iso = ohci_stop_iso,
};
-static int software_reset(struct fw_ohci *ohci)
-{
- int i;
-
- reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
-
- for (i = 0; i < OHCI_LOOP_COUNT; i++) {
- if ((reg_read(ohci, OHCI1394_HCControlSet) &
- OHCI1394_HCControl_softReset) == 0)
- return 0;
- msleep(1);
- }
-
- return -EBUSY;
-}
-
static int __devinit
pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{
@@ -1761,33 +1822,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
goto fail_iomem;
}
- if (software_reset(ohci)) {
- fw_error("Failed to reset ohci card.\n");
- err = -EBUSY;
- goto fail_registers;
- }
-
- /*
- * Now enable LPS, which we need in order to start accessing
- * most of the registers. In fact, on some cards (ALI M5251),
- * accessing registers in the SClk domain without LPS enabled
- * will lock up the machine. Wait 50msec to make sure we have
- * full link enabled.
- */
- reg_write(ohci, OHCI1394_HCControlSet,
- OHCI1394_HCControl_LPS |
- OHCI1394_HCControl_postedWriteEnable);
- flush_writes(ohci);
- msleep(50);
-
- reg_write(ohci, OHCI1394_HCControlClear,
- OHCI1394_HCControl_noByteSwapData);
-
- reg_write(ohci, OHCI1394_LinkControlSet,
- OHCI1394_LinkControl_rcvSelfID |
- OHCI1394_LinkControl_cycleTimerEnable |
- OHCI1394_LinkControl_cycleMaster);
-
ar_context_init(&ohci->ar_request_ctx, ohci,
OHCI1394_AsReqRcvContextControlSet);
@@ -1800,11 +1834,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
context_init(&ohci->at_response_ctx, ohci, AT_BUFFER_SIZE,
OHCI1394_AsRspTrContextControlSet, handle_at_packet);
- reg_write(ohci, OHCI1394_ATRetries,
- OHCI1394_MAX_AT_REQ_RETRIES |
- (OHCI1394_MAX_AT_RESP_RETRIES << 4) |
- (OHCI1394_MAX_PHYS_RESP_RETRIES << 8));
-
reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0);
ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet);
reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0);
@@ -1834,18 +1863,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
goto fail_registers;
}
- reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
- reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
- reg_write(ohci, OHCI1394_IntEventClear, ~0);
- reg_write(ohci, OHCI1394_IntMaskClear, ~0);
- reg_write(ohci, OHCI1394_IntMaskSet,
- OHCI1394_selfIDComplete |
- OHCI1394_RQPkt | OHCI1394_RSPkt |
- OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
- OHCI1394_isochRx | OHCI1394_isochTx |
- OHCI1394_masterIntEnable |
- OHCI1394_cycle64Seconds);
-
bus_options = reg_read(ohci, OHCI1394_BusOptions);
max_receive = (bus_options >> 12) & 0xf;
link_speed = bus_options & 0x7;
@@ -1907,6 +1924,45 @@ static void pci_remove(struct pci_dev *dev)
fw_notify("Removed fw-ohci device.\n");
}
+#ifdef CONFIG_PM
+static int pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct fw_ohci *ohci = pci_get_drvdata(pdev);
+ int err;
+
+ software_reset(ohci);
+ free_irq(pdev->irq, ohci);
+ err = pci_save_state(pdev);
+ if (err) {
+ fw_error("pci_save_state failed with %d", err);
+ return err;
+ }
+ err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ if (err) {
+ fw_error("pci_set_power_state failed with %d", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int pci_resume(struct pci_dev *pdev)
+{
+ struct fw_ohci *ohci = pci_get_drvdata(pdev);
+ int err;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ err = pci_enable_device(pdev);
+ if (err) {
+ fw_error("pci_enable_device failed with %d", err);
+ return err;
+ }
+
+ return ohci_enable(&ohci->card, ohci->config_rom, CONFIG_ROM_SIZE);
+}
+#endif
+
static struct pci_device_id pci_table[] = {
{ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) },
{ }
@@ -1919,6 +1975,10 @@ static struct pci_driver fw_ohci_pci_driver = {
.id_table = pci_table,
.probe = pci_probe,
.remove = pci_remove,
+#ifdef CONFIG_PM
+ .resume = pci_resume,
+ .suspend = pci_suspend,
+#endif
};
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 68300414e5f..a98d3915e26 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -1108,6 +1108,58 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
return SUCCESS;
}
+/*
+ * Format of /sys/bus/scsi/devices/.../ieee1394_id:
+ * u64 EUI-64 : u24 directory_ID : u16 LUN (all printed in hexadecimal)
+ *
+ * This is the concatenation of target port identifier and logical unit
+ * identifier as per SAM-2...SAM-4 annex A.
+ */
+static ssize_t
+sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ struct sbp2_device *sd;
+ struct fw_unit *unit;
+ struct fw_device *device;
+ u32 directory_id;
+ struct fw_csr_iterator ci;
+ int key, value, lun;
+
+ if (!sdev)
+ return 0;
+ sd = (struct sbp2_device *)sdev->host->hostdata;
+ unit = sd->unit;
+ device = fw_device(unit->device.parent);
+
+ /* implicit directory ID */
+ directory_id = ((unit->directory - device->config_rom) * 4
+ + CSR_CONFIG_ROM) & 0xffffff;
+
+ /* explicit directory ID, overrides implicit ID if present */
+ fw_csr_iterator_init(&ci, unit->directory);
+ while (fw_csr_iterator_next(&ci, &key, &value))
+ if (key == CSR_DIRECTORY_ID) {
+ directory_id = value;
+ break;
+ }
+
+ /* FIXME: Make this work for multi-lun devices. */
+ lun = 0;
+
+ return sprintf(buf, "%08x%08x:%06x:%04x\n",
+ device->config_rom[3], device->config_rom[4],
+ directory_id, lun);
+}
+
+static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);
+
+static struct device_attribute *sbp2_scsi_sysfs_attrs[] = {
+ &dev_attr_ieee1394_id,
+ NULL
+};
+
static struct scsi_host_template scsi_driver_template = {
.module = THIS_MODULE,
.name = "SBP-2 IEEE-1394",
@@ -1121,6 +1173,7 @@ static struct scsi_host_template scsi_driver_template = {
.use_clustering = ENABLE_CLUSTERING,
.cmd_per_lun = 1,
.can_queue = 1,
+ .sdev_attrs = sbp2_scsi_sysfs_attrs,
};
MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 4d1cb5b855d..13eea47dceb 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -620,7 +620,7 @@ config SENSORS_HDAPS
config SENSORS_APPLESMC
tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
- depends on HWMON && INPUT && X86
+ depends on INPUT && X86
select NEW_LEDS
select LEDS_CLASS
default n
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 0c160675b3a..fd1281f4220 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -491,6 +491,12 @@ out:
/* Sysfs Files */
+static ssize_t applesmc_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "applesmc\n");
+}
+
static ssize_t applesmc_position_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -913,6 +919,8 @@ static struct led_classdev applesmc_backlight = {
.brightness_set = applesmc_brightness_set,
};
+static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
+
static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
static DEVICE_ATTR(calibrate, 0644,
applesmc_calibrate_show, applesmc_calibrate_store);
@@ -1197,10 +1205,14 @@ static int __init applesmc_init(void)
goto out_driver;
}
+ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
+ if (ret)
+ goto out_device;
+
/* Create key enumeration sysfs files */
ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
if (ret)
- goto out_device;
+ goto out_name;
/* create fan files */
count = applesmc_get_fan_count();
@@ -1300,6 +1312,8 @@ out_fan_1:
sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
out_key_enumeration:
sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+out_name:
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
out_device:
platform_device_unregister(pdev);
out_driver:
@@ -1325,6 +1339,7 @@ static void __exit applesmc_exit(void)
sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
platform_device_unregister(pdev);
platform_driver_unregister(&applesmc_driver);
release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 75e3911810a..0328382df8f 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -176,6 +176,22 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
goto exit_free;
}
+ /* Check if we have problem with errata AE18 of Core processors:
+ Readings might stop update when processor visited too deep sleep,
+ fixed for stepping D0 (6EC).
+ */
+
+ if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
+ /* check for microcode update */
+ rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx);
+ if (edx < 0x39) {
+ dev_err(&pdev->dev,
+ "Errata AE18 not fixed, update BIOS or "
+ "microcode of the CPU!\n");
+ goto exit_free;
+ }
+ }
+
/* Some processors have Tjmax 85 following magic should detect it
Intel won't disclose the information without signed NDA, but
individuals cannot sign it. Catch(ed) 22.
@@ -193,6 +209,19 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
}
}
+ /* Intel says that above should not work for desktop Core2 processors,
+ but it seems to work. There is no other way how get the absolute
+ readings. Warn the user about this. First check if are desktop,
+ bit 50 of MSR_IA32_PLATFORM_ID should be 0.
+ */
+
+ rdmsr_safe_on_cpu(data->id, MSR_IA32_PLATFORM_ID, &eax, &edx);
+
+ if ((c->x86_model == 0xf) && (!(edx & 0x00040000))) {
+ dev_warn(&pdev->dev, "Using undocumented features, absolute "
+ "temperature might be wrong!\n");
+ }
+
platform_set_drvdata(pdev, data);
if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
@@ -330,9 +359,6 @@ static int __init coretemp_init(void)
int i, err = -ENODEV;
struct pdev_entry *p, *n;
- printk(KERN_NOTICE DRVNAME ": This driver uses undocumented features "
- "of Core CPU. Temperature might be wrong!\n");
-
/* quick check if we run Intel */
if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
goto exit;
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index c849c0c6ee9..d5ac422d73b 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -53,8 +53,8 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low")
/* The DS1621 registers */
#define DS1621_REG_TEMP 0xAA /* word, RO */
-#define DS1621_REG_TEMP_MIN 0xA1 /* word, RW */
-#define DS1621_REG_TEMP_MAX 0xA2 /* word, RW */
+#define DS1621_REG_TEMP_MIN 0xA2 /* word, RW */
+#define DS1621_REG_TEMP_MAX 0xA1 /* word, RW */
#define DS1621_REG_CONF 0xAC /* byte, RW */
#define DS1621_COM_START 0xEE /* no data */
#define DS1621_COM_STOP 0x22 /* no data */
@@ -328,9 +328,9 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
/* reset alarms if necessary */
new_conf = data->conf;
- if (data->temp < data->temp_min)
+ if (data->temp > data->temp_min)
new_conf &= ~DS1621_ALARM_TEMP_LOW;
- if (data->temp > data->temp_max)
+ if (data->temp < data->temp_max)
new_conf &= ~DS1621_ALARM_TEMP_HIGH;
if (data->conf != new_conf)
ds1621_write_value(client, DS1621_REG_CONF,
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 5aab23b93e2..f17e771e42f 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -132,7 +132,9 @@ int vid_from_reg(int val, u8 vrm)
val &= 0x7f;
return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000);
default: /* report 0 for unknown */
- printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
+ if (vrm)
+ printk(KERN_WARNING "hwmon-vid: Requested unsupported "
+ "VRM version (%u)\n", (unsigned int)vrm);
return 0;
}
}
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index a5b774b07cb..12cb40a975d 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -965,8 +965,10 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr,
case W687THF_DEVID:
sio_data->type = w83687thf;
break;
+ case 0xff: /* No device at all */
+ goto exit;
default:
- pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", val);
+ pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val);
goto exit;
}
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 8a0a99b9364..28e7b91a455 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -837,20 +837,10 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
.functionality = i2c_pxa_functionality,
};
-static struct pxa_i2c i2c_pxa = {
- .lock = __SPIN_LOCK_UNLOCKED(i2c_pxa.lock),
- .adap = {
- .owner = THIS_MODULE,
- .algo = &i2c_pxa_algorithm,
- .name = "pxa2xx-i2c.0",
- .retries = 5,
- },
-};
-
#define res_len(r) ((r)->end - (r)->start + 1)
static int i2c_pxa_probe(struct platform_device *dev)
{
- struct pxa_i2c *i2c = &i2c_pxa;
+ struct pxa_i2c *i2c;
struct resource *res;
struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
int ret;
@@ -864,15 +854,20 @@ static int i2c_pxa_probe(struct platform_device *dev)
if (!request_mem_region(res->start, res_len(res), res->name))
return -ENOMEM;
- i2c = kmalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
+ i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
if (!i2c) {
ret = -ENOMEM;
goto emalloc;
}
- memcpy(i2c, &i2c_pxa, sizeof(struct pxa_i2c));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &i2c_pxa_algorithm;
+ i2c->adap.retries = 5;
+
+ spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
- i2c->adap.name[strlen(i2c->adap.name) - 1] = '0' + dev->id % 10;
+
+ sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id);
i2c->reg_base = ioremap(res->start, res_len(res));
if (!i2c->reg_base) {
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index e68a96f589f..e4540fcf647 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -830,7 +830,8 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
i2c->irq = res;
- dev_dbg(&pdev->dev, "irq resource %p (%ld)\n", res, res->start);
+ dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
+ (unsigned long)res->start);
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
index 907999049d5..cb9abe7565a 100644
--- a/drivers/i2c/busses/i2c-tiny-usb.c
+++ b/drivers/i2c/busses/i2c-tiny-usb.c
@@ -208,7 +208,7 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface,
dev->adapter.class = I2C_CLASS_HWMON;
dev->adapter.algo = &usb_algorithm;
dev->adapter.algo_data = dev;
- snprintf(dev->adapter.name, I2C_NAME_SIZE,
+ snprintf(dev->adapter.name, sizeof(dev->adapter.name),
"i2c-tiny-usb at bus %03d device %03d",
dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 64f8e56d300..435925eba43 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -697,9 +697,10 @@ int i2c_attach_client(struct i2c_client *client)
if (client->driver)
client->dev.driver = &client->driver->driver;
- if (client->driver && !is_newstyle_driver(client->driver))
+ if (client->driver && !is_newstyle_driver(client->driver)) {
client->dev.release = i2c_client_release;
- else
+ client->dev.uevent_suppress = 1;
+ } else
client->dev.release = i2c_client_dev_release;
snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 7fff773f2df..dc2175c81f5 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1037,6 +1037,17 @@ static void ide_disk_release(struct kref *kref)
static int ide_disk_probe(ide_drive_t *drive);
+/*
+ * On HPA drives the capacity needs to be
+ * reinitilized on resume otherwise the disk
+ * can not be used and a hard reset is required
+ */
+static void ide_disk_resume(ide_drive_t *drive)
+{
+ if (idedisk_supports_hpa(drive->id))
+ init_idedisk_capacity(drive);
+}
+
static void ide_device_shutdown(ide_drive_t *drive)
{
#ifdef CONFIG_ALPHA
@@ -1071,6 +1082,7 @@ static ide_driver_t idedisk_driver = {
},
.probe = ide_disk_probe,
.remove = ide_disk_remove,
+ .resume = ide_disk_resume,
.shutdown = ide_device_shutdown,
.version = IDEDISK_VERSION,
.media = ide_disk,
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index b77b7d138c4..ead141e2db9 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -119,15 +119,17 @@ static const struct drive_list_entry drive_blacklist [] = {
{ "HITACHI CDR-8335" , "ALL" },
{ "HITACHI CDR-8435" , "ALL" },
{ "Toshiba CD-ROM XM-6202B" , "ALL" },
+ { "TOSHIBA CD-ROM XM-1702BC", "ALL" },
{ "CD-532E-A" , "ALL" },
{ "E-IDE CD-ROM CR-840", "ALL" },
{ "CD-ROM Drive/F5A", "ALL" },
{ "WPI CDD-820", "ALL" },
{ "SAMSUNG CD-ROM SC-148C", "ALL" },
{ "SAMSUNG CD-ROM SC", "ALL" },
- { "SanDisk SDP3B-64" , "ALL" },
{ "ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL" },
{ "_NEC DV5800A", "ALL" },
+ { "SAMSUNG CD-ROM SN-124", "N001" },
+ { "Seagate STT20000A", "ALL" },
{ NULL , NULL }
};
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 3cebed77f55..41bfa4d21ab 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -717,7 +717,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
* This routine only knows how to look for drive units 0 and 1
* on an interface, so any setting of MAX_DRIVES > 2 won't work here.
*/
-static void probe_hwif(ide_hwif_t *hwif)
+static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
{
unsigned int unit;
unsigned long flags;
@@ -820,6 +820,9 @@ static void probe_hwif(ide_hwif_t *hwif)
return;
}
+ if (fixup)
+ fixup(hwif);
+
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
@@ -874,10 +877,7 @@ static int hwif_init(ide_hwif_t *hwif);
int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
{
- probe_hwif(hwif);
-
- if (fixup)
- fixup(hwif);
+ probe_hwif(hwif, fixup);
if (!hwif_init(hwif)) {
printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -1404,7 +1404,7 @@ int ideprobe_init (void)
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
- probe_hwif(&ide_hwifs[index]);
+ probe_hwif(&ide_hwifs[index], NULL);
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
hwif_init(&ide_hwifs[index]);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index d50bd996ff2..ea94c9aa122 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -67,6 +67,8 @@ static int proc_ide_read_imodel
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
case ide_au1xxx: name = "au1xxx"; break;
+ case ide_etrax100: name = "etrax100"; break;
+ case ide_acorn: name = "acorn"; break;
default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 6002713a20a..0af0d1614f7 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1010,9 +1010,11 @@ static int generic_ide_resume(struct device *dev)
{
ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive);
+ ide_driver_t *drv = to_ide_driver(dev->driver);
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
+ int err;
/* Call ACPI _STM only once */
if (!(drive->dn % 2))
@@ -1029,7 +1031,12 @@ static int generic_ide_resume(struct device *dev)
rqpm.pm_step = ide_pm_state_start_resume;
rqpm.pm_state = PM_EVENT_ON;
- return ide_do_drive_cmd(drive, &rq, ide_head_wait);
+ err = ide_do_drive_cmd(drive, &rq, ide_head_wait);
+
+ if (err == 0 && drv && drv->resume)
+ drv->resume(drive);
+
+ return err;
}
int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index becb1a5648b..9db1be826e8 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -1,5 +1,5 @@
/*
- * Version 2.13
+ * Version 2.15
*
* AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
* IDE driver for Linux.
@@ -76,6 +76,8 @@ static struct amd_ide_chip {
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, AMD_UDMA_133 },
+ { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, AMD_UDMA_133 },
+ { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
{ 0 }
};
@@ -494,7 +496,9 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
/* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"),
/* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"),
/* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"),
- /* 20 */ DECLARE_AMD_DEV("AMD5536"),
+ /* 20 */ DECLARE_NV_DEV("NFORCE-MCP73"),
+ /* 21 */ DECLARE_NV_DEV("NFORCE-MCP77"),
+ /* 22 */ DECLARE_AMD_DEV("AMD5536"),
};
static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -534,7 +538,9 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21 },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 0e52ad722a7..8ab33faf6f7 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -317,6 +317,7 @@ static struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index f2c5a141ca1..0d51a11e81d 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -198,32 +198,41 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
ide_pci_device_t *d = &generic_chipsets[id->driver_data];
- u16 command;
int ret = -ENODEV;
/* Don't use the generic entry unless instructed to do so */
if (id->driver_data == 0 && ide_generic_all == 0)
goto out;
- if (dev->vendor == PCI_VENDOR_ID_UMC &&
- dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
- (!(PCI_FUNC(dev->devfn) & 1)))
- goto out; /* UM8886A/BF pair */
-
- if (dev->vendor == PCI_VENDOR_ID_OPTI &&
- dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
- (!(PCI_FUNC(dev->devfn) & 1)))
- goto out;
-
- if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
- if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
+ switch (dev->vendor) {
+ case PCI_VENDOR_ID_UMC:
+ if (dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
+ !(PCI_FUNC(dev->devfn) & 1))
+ goto out; /* UM8886A/BF pair */
+ break;
+ case PCI_VENDOR_ID_OPTI:
+ if (dev->device == PCI_DEVICE_ID_OPTI_82C558 &&
+ !(PCI_FUNC(dev->devfn) & 1))
+ goto out;
+ break;
+ case PCI_VENDOR_ID_JMICRON:
+ if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 &&
+ PCI_FUNC(dev->devfn) != 1)
+ goto out;
+ break;
+ case PCI_VENDOR_ID_NS:
+ if (dev->device == PCI_DEVICE_ID_NS_87410 &&
+ (dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
goto out;
+ break;
}
if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+ u16 command;
pci_read_config_word(dev, PCI_COMMAND, &command);
if (!(command & PCI_COMMAND_IO)) {
- printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
+ printk(KERN_INFO "Skipping disabled %s IDE "
+ "controller.\n", d->name);
goto out;
}
}
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index fcbc5605b38..ce8a5449a57 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/hpt366.c Version 1.03 May 4, 2007
+ * linux/drivers/ide/pci/hpt366.c Version 1.04 Jun 4, 2007
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
@@ -106,7 +106,8 @@
* switch to calculating PCI clock frequency based on the chip's base DPLL
* frequency
* - switch to using the DPLL clock and enable UltraATA/133 mode by default on
- * anything newer than HPT370/A
+ * anything newer than HPT370/A (except HPT374 that is not capable of this
+ * mode according to the manual)
* - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(),
* also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
* unify HPT36x/37x timing setup code and the speedproc handlers by joining
@@ -365,7 +366,6 @@ static u32 sixty_six_base_hpt37x[] = {
};
#define HPT366_DEBUG_DRIVE_INFO 0
-#define HPT374_ALLOW_ATA133_6 1
#define HPT371_ALLOW_ATA133_6 1
#define HPT302_ALLOW_ATA133_6 1
#define HPT372_ALLOW_ATA133_6 1
@@ -450,7 +450,7 @@ static struct hpt_info hpt370a __devinitdata = {
static struct hpt_info hpt374 __devinitdata = {
.chip_type = HPT374,
- .max_mode = HPT374_ALLOW_ATA133_6 ? 4 : 3,
+ .max_mode = 3,
.dpll_clk = 48,
.settings = hpt37x_settings
};
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 5faaff87d58..4bd4bf02e91 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -1,6 +1,6 @@
/*
- * linux/drivers/ide/pci/it821x.c Version 0.10 Mar 10 2007
+ * linux/drivers/ide/pci/it821x.c Version 0.15 Jun 2 2007
*
* Copyright (C) 2004 Red Hat <alan@redhat.com>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
@@ -262,7 +262,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
}
if (itdev->smart)
- goto set_drive_speed;
+ return 0;
/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
itdev->want[unit][1] = pio_want[set_pio];
@@ -271,7 +271,6 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
it821x_clock_strategy(drive);
it821x_program(drive, itdev->pio[unit]);
-set_drive_speed:
return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
}
@@ -455,12 +454,12 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)
default:
return 1;
}
+
+ return ide_config_drive_speed(drive, speed);
}
- /*
- * In smart mode the clocking is done by the host controller
- * snooping the mode we picked. The rest of it is not our problem
- */
- return ide_config_drive_speed(drive, speed);
+
+ /* don't touch anything in the smart mode */
+ return 0;
}
/**
@@ -559,17 +558,10 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
if(idbits[129] != 1)
printk("(%dK stripe)", idbits[146]);
printk(".\n");
- /* Now the core code will have wrongly decided no DMA
- so we need to fix this */
- hwif->dma_off_quietly(drive);
-#ifdef CONFIG_IDEDMA_ONLYDISK
- if (drive->media == ide_disk)
-#endif
- ide_set_dma(drive);
} else {
/* Non RAID volume. Fixups to stop the core code
doing unsupported things */
- id->field_valid &= 1;
+ id->field_valid &= 3;
id->queue_depth = 0;
id->command_set_1 = 0;
id->command_set_2 &= 0xC400;
@@ -584,6 +576,16 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
printk(KERN_INFO "%s: Performing identify fixups.\n",
drive->name);
}
+
+ /*
+ * Set MWDMA0 mode as enabled/support - just to tell
+ * IDE core that DMA is supported (it821x hardware
+ * takes care of DMA mode programming).
+ */
+ if (id->capability & 1) {
+ id->dma_mword |= 0x0101;
+ drive->current_speed = XFER_MW_DMA_0;
+ }
}
}
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 6234f806c6b..d9c4fd1ae99 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/serverworks.c Version 0.9 Mar 4 2007
+ * linux/drivers/ide/pci/serverworks.c Version 0.11 Jun 2 2007
*
* Copyright (C) 1998-2000 Michel Aubry
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -158,48 +158,67 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
pci_read_config_word(dev, 0x4A, &csb5_pio);
pci_read_config_byte(dev, 0x54, &ultra_enable);
+ /* If we are in RAID mode (eg AMI MegaIDE) then we can't it
+ turns out trust the firmware configuration */
+
+ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+ goto oem_setup_failed;
+
/* Per Specified Design by OEM, and ASIC Architect */
if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
(dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
if (!drive->init_speed) {
u8 dma_stat = inb(hwif->dma_status);
-dma_pio:
if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) {
drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)];
return 0;
} else if ((dma_timing) &&
((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
- u8 dmaspeed = dma_timing;
+ u8 dmaspeed;
- dma_timing &= ~0xFF;
- if ((dmaspeed & 0x20) == 0x20)
+ switch (dma_timing & 0x77) {
+ case 0x20:
dmaspeed = XFER_MW_DMA_2;
- else if ((dmaspeed & 0x21) == 0x21)
+ break;
+ case 0x21:
dmaspeed = XFER_MW_DMA_1;
- else if ((dmaspeed & 0x77) == 0x77)
+ break;
+ case 0x77:
dmaspeed = XFER_MW_DMA_0;
- else
+ break;
+ default:
goto dma_pio;
+ }
+
drive->current_speed = drive->init_speed = dmaspeed;
return 0;
- } else if (pio_timing) {
- u8 piospeed = pio_timing;
+ }
+dma_pio:
+ if (pio_timing) {
+ u8 piospeed;
- pio_timing &= ~0xFF;
- if ((piospeed & 0x20) == 0x20)
+ switch (pio_timing & 0x7f) {
+ case 0x20:
piospeed = XFER_PIO_4;
- else if ((piospeed & 0x22) == 0x22)
+ break;
+ case 0x22:
piospeed = XFER_PIO_3;
- else if ((piospeed & 0x34) == 0x34)
+ break;
+ case 0x34:
piospeed = XFER_PIO_2;
- else if ((piospeed & 0x47) == 0x47)
+ break;
+ case 0x47:
piospeed = XFER_PIO_1;
- else if ((piospeed & 0x5d) == 0x5d)
+ break;
+ case 0x5d:
piospeed = XFER_PIO_0;
- else
+ break;
+ default:
goto oem_setup_failed;
+ }
+
drive->current_speed = drive->init_speed = piospeed;
return 0;
}
@@ -208,8 +227,8 @@ dma_pio:
oem_setup_failed:
- pio_timing &= ~0xFF;
- dma_timing &= ~0xFF;
+ pio_timing = 0;
+ dma_timing = 0;
ultra_timing &= ~(0x0F << (4*unit));
ultra_enable &= ~(0x01 << drive->dn);
csb5_pio &= ~(0x0F << (4*drive->dn));
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 2296d43a241..5f026b5d785 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -47,6 +47,7 @@
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/workqueue.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
@@ -235,6 +236,9 @@ static int ether1394_open(struct net_device *dev)
/* This is called after an "ifdown" */
static int ether1394_stop(struct net_device *dev)
{
+ /* flush priv->wake */
+ flush_scheduled_work();
+
netif_stop_queue(dev);
return 0;
}
@@ -531,6 +535,37 @@ static void ether1394_init_dev(struct net_device *dev)
}
/*
+ * Wake the queue up after commonly encountered transmit failure conditions are
+ * hopefully over. Currently only tlabel exhaustion is accounted for.
+ */
+static void ether1394_wake_queue(struct work_struct *work)
+{
+ struct eth1394_priv *priv;
+ struct hpsb_packet *packet;
+
+ priv = container_of(work, struct eth1394_priv, wake);
+ packet = hpsb_alloc_packet(0);
+
+ /* This is really bad, but unjam the queue anyway. */
+ if (!packet)
+ goto out;
+
+ packet->host = priv->host;
+ packet->node_id = priv->wake_node;
+ /*
+ * A transaction label is all we really want. If we get one, it almost
+ * always means we can get a lot more because the ieee1394 core recycled
+ * a whole batch of tlabels, at last.
+ */
+ if (hpsb_get_tlabel(packet) == 0)
+ hpsb_free_tlabel(packet);
+
+ hpsb_free_packet(packet);
+out:
+ netif_wake_queue(priv->wake_dev);
+}
+
+/*
* This function is called every time a card is found. It is generally called
* when the module is installed. This is where we add all of our ethernet
* devices. One for each host.
@@ -564,16 +599,17 @@ static void ether1394_add_host(struct hpsb_host *host)
}
SET_MODULE_OWNER(dev);
-#if 0
- /* FIXME - Is this the correct parent device anyway? */
- SET_NETDEV_DEV(dev, &host->device);
-#endif
+
+ /* This used to be &host->device in Linux 2.6.20 and before. */
+ SET_NETDEV_DEV(dev, host->device.parent);
priv = netdev_priv(dev);
INIT_LIST_HEAD(&priv->ip_node_list);
spin_lock_init(&priv->lock);
priv->host = host;
priv->local_fifo = fifo_addr;
+ INIT_WORK(&priv->wake, ether1394_wake_queue);
+ priv->wake_dev = dev;
hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
if (hi == NULL) {
@@ -1390,22 +1426,17 @@ static int ether1394_prep_write_packet(struct hpsb_packet *p,
u64 addr, void *data, int tx_len)
{
p->node_id = node;
- p->data = NULL;
- p->tcode = TCODE_WRITEB;
- p->header[1] = host->node_id << 16 | addr >> 32;
- p->header[2] = addr & 0xffffffff;
+ if (hpsb_get_tlabel(p))
+ return -EAGAIN;
+ p->tcode = TCODE_WRITEB;
p->header_size = 16;
p->expect_response = 1;
-
- if (hpsb_get_tlabel(p)) {
- ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
- return -1;
- }
p->header[0] =
p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4;
-
+ p->header[1] = host->node_id << 16 | addr >> 32;
+ p->header[2] = addr & 0xffffffff;
p->header[3] = tx_len << 16;
p->data_size = (tx_len + 3) & ~3;
p->data = data;
@@ -1451,7 +1482,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
packet = ether1394_alloc_common_packet(priv->host);
if (!packet)
- return -1;
+ return -ENOMEM;
if (ptask->tx_type == ETH1394_GASP) {
int length = tx_len + 2 * sizeof(quadlet_t);
@@ -1462,7 +1493,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
ptask->addr, ptask->skb->data,
tx_len)) {
hpsb_free_packet(packet);
- return -1;
+ return -EAGAIN;
}
ptask->packet = packet;
@@ -1471,7 +1502,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
if (hpsb_send_packet(packet) < 0) {
ether1394_free_packet(packet);
- return -1;
+ return -EIO;
}
return 0;
@@ -1514,13 +1545,18 @@ static void ether1394_complete_cb(void *__ptask)
ptask->outstanding_pkts--;
if (ptask->outstanding_pkts > 0 && !fail) {
- int tx_len;
+ int tx_len, err;
/* Add the encapsulation header to the fragment */
tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
&ptask->hdr);
- if (ether1394_send_packet(ptask, tx_len))
+ err = ether1394_send_packet(ptask, tx_len);
+ if (err) {
+ if (err == -EAGAIN)
+ ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
+
ether1394_dg_complete(ptask, 1);
+ }
} else {
ether1394_dg_complete(ptask, fail);
}
@@ -1633,10 +1669,18 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
/* Add the encapsulation header to the fragment */
tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
dev->trans_start = jiffies;
- if (ether1394_send_packet(ptask, tx_len))
- goto fail;
+ if (ether1394_send_packet(ptask, tx_len)) {
+ if (dest_node == (LOCAL_BUS | ALL_NODES))
+ goto fail;
+
+ /* Most failures of ether1394_send_packet are recoverable. */
+ netif_stop_queue(dev);
+ priv->wake_node = dest_node;
+ schedule_work(&priv->wake);
+ kmem_cache_free(packet_task_cache, ptask);
+ return NETDEV_TX_BUSY;
+ }
- netif_wake_queue(dev);
return NETDEV_TX_OK;
fail:
if (ptask)
@@ -1650,9 +1694,6 @@ fail:
priv->stats.tx_errors++;
spin_unlock_irqrestore(&priv->lock, flags);
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
-
/*
* FIXME: According to a patch from 2003-02-26, "returning non-zero
* causes serious problems" here, allegedly. Before that patch,
diff --git a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h
index a3439ee7cb4..4f3e2dd46f0 100644
--- a/drivers/ieee1394/eth1394.h
+++ b/drivers/ieee1394/eth1394.h
@@ -66,6 +66,10 @@ struct eth1394_priv {
int bc_dgl; /* Outgoing broadcast datagram label */
struct list_head ip_node_list; /* List of IP capable nodes */
struct unit_directory *ud_list[ALL_NODES]; /* Cached unit dir list */
+
+ struct work_struct wake; /* Wake up after xmit failure */
+ struct net_device *wake_dev; /* Stupid backlink for .wake */
+ nodeid_t wake_node; /* Destination of failed xmit */
};
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 835937e3852..81b3864d2ba 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -976,7 +976,8 @@ static struct unit_directory *nodemgr_process_unit_directory
ud->ne = ne;
ud->ignore_driver = ignore_drivers;
- ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE;
+ ud->address = ud_kv->offset + CSR1212_REGISTER_SPACE_BASE;
+ ud->directory_id = ud->address & 0xffffff;
ud->ud_kv = ud_kv;
ud->id = (*id)++;
@@ -1085,6 +1086,10 @@ static struct unit_directory *nodemgr_process_unit_directory
break;
+ case CSR1212_KV_ID_DIRECTORY_ID:
+ ud->directory_id = kv->value.immediate;
+ break;
+
default:
break;
}
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index e7ac683c72c..4530b29d941 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -75,6 +75,7 @@ struct unit_directory {
struct csr1212_keyval *model_name_kv;
quadlet_t specifier_id;
quadlet_t version;
+ quadlet_t directory_id;
unsigned int id;
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index d382500f421..f1d05eeb9f5 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -936,6 +936,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
struct hpsb_packet *packet;
int header_length = req->req.misc & 0xffff;
int expect_response = req->req.misc >> 16;
+ size_t data_size;
if (header_length > req->req.length || header_length < 12 ||
header_length > FIELD_SIZEOF(struct hpsb_packet, header)) {
@@ -945,7 +946,8 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
return sizeof(struct raw1394_request);
}
- packet = hpsb_alloc_packet(req->req.length - header_length);
+ data_size = req->req.length - header_length;
+ packet = hpsb_alloc_packet(data_size);
req->packet = packet;
if (!packet)
return -ENOMEM;
@@ -960,7 +962,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
if (copy_from_user
(packet->data, int2ptr(req->req.sendb) + header_length,
- packet->data_size)) {
+ data_size)) {
req->req.error = RAW1394_ERROR_MEMFAULT;
req->req.length = 0;
queue_complete_req(req);
@@ -974,7 +976,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
packet->host = fi->host;
packet->expect_response = expect_response;
packet->header_size = header_length;
- packet->data_size = req->req.length - header_length;
+ packet->data_size = data_size;
req->req.length = 0;
hpsb_set_packet_complete_task(packet,
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 4cb6fa2bcfb..3f873cc7e24 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -70,6 +70,7 @@
#include <linux/stringify.h>
#include <linux/types.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <asm/byteorder.h>
#include <asm/errno.h>
@@ -193,6 +194,27 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
", or a combination)");
+/*
+ * This influences the format of the sysfs attribute
+ * /sys/bus/scsi/devices/.../ieee1394_id.
+ *
+ * The default format is like in older kernels: %016Lx:%d:%d
+ * It contains the target's EUI-64, a number given to the logical unit by
+ * the ieee1394 driver's nodemgr (starting at 0), and the LUN.
+ *
+ * The long format is: %016Lx:%06x:%04x
+ * It contains the target's EUI-64, the unit directory's directory_ID as per
+ * IEEE 1212 clause 7.7.19, and the LUN. This format comes closest to the
+ * format of SBP(-3) target port and logical unit identifier as per SAM (SCSI
+ * Architecture Model) rev.2 to 4 annex A. Therefore and because it is
+ * independent of the implementation of the ieee1394 nodemgr, the longer format
+ * is recommended for future use.
+ */
+static int sbp2_long_sysfs_ieee1394_id;
+module_param_named(long_ieee1394_id, sbp2_long_sysfs_ieee1394_id, bool, 0644);
+MODULE_PARM_DESC(long_ieee1394_id, "8+3+2 bytes format of ieee1394_id in sysfs "
+ "(default = backwards-compatible = N, SAM-conforming = Y)");
+
#define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args)
#define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args)
@@ -2099,8 +2121,14 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
if (!(lu = (struct sbp2_lu *)sdev->host->hostdata[0]))
return 0;
- return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)lu->ne->guid,
- lu->ud->id, ORB_SET_LUN(lu->lun));
+ if (sbp2_long_sysfs_ieee1394_id)
+ return sprintf(buf, "%016Lx:%06x:%04x\n",
+ (unsigned long long)lu->ne->guid,
+ lu->ud->directory_id, ORB_SET_LUN(lu->lun));
+ else
+ return sprintf(buf, "%016Lx:%d:%d\n",
+ (unsigned long long)lu->ne->guid,
+ lu->ud->id, ORB_SET_LUN(lu->lun));
}
MODULE_AUTHOR("Ben Collins <bcollins@debian.org>");
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index e840434a96d..40c004a2697 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1297,26 +1297,29 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
- /* Check for duplicate REQ and stale connections. */
+ /* Check for possible duplicate REQ. */
spin_lock_irqsave(&cm.lock, flags);
timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info);
- if (!timewait_info)
- timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
-
if (timewait_info) {
cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
timewait_info->work.remote_id);
- cm_cleanup_timewait(cm_id_priv->timewait_info);
spin_unlock_irqrestore(&cm.lock, flags);
if (cur_cm_id_priv) {
cm_dup_req_handler(work, cur_cm_id_priv);
cm_deref_id(cur_cm_id_priv);
- } else
- cm_issue_rej(work->port, work->mad_recv_wc,
- IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
- NULL, 0);
- listen_cm_id_priv = NULL;
- goto out;
+ }
+ return NULL;
+ }
+
+ /* Check for stale connections. */
+ timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
+ if (timewait_info) {
+ cm_cleanup_timewait(cm_id_priv->timewait_info);
+ spin_unlock_irqrestore(&cm.lock, flags);
+ cm_issue_rej(work->port, work->mad_recv_wc,
+ IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
+ NULL, 0);
+ return NULL;
}
/* Find matching listen request. */
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 2eb52b7a71d..32a0e66d2a2 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2773,8 +2773,8 @@ static int cma_init(void)
int ret;
get_random_bytes(&next_port, sizeof next_port);
- next_port = (next_port % (sysctl_local_port_range[1] -
- sysctl_local_port_range[0])) +
+ next_port = ((unsigned int) next_port %
+ (sysctl_local_port_range[1] - sysctl_local_port_range[0])) +
sysctl_local_port_range[0];
cma_wq = create_singlethread_workqueue("rdma_cm");
if (!cma_wq)
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index 58bc272bd40..0aecea67f3e 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -672,7 +672,7 @@ static int c2_up(struct net_device *netdev)
* rdma interface.
*/
in_dev = in_dev_get(netdev);
- in_dev->cnf.arp_ignore = 1;
+ IN_DEV_CONF_SET(in_dev, ARP_IGNORE, 1);
in_dev_put(in_dev);
return 0;
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 7f0beec74f7..5766ae3a202 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -331,7 +331,7 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
0);
qp->ipz_qp_handle.handle = outs[0];
qp->real_qp_num = (u32)outs[1];
- parms->act_nr_send_sges =
+ parms->act_nr_send_wqes =
(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
parms->act_nr_recv_wqes =
(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index a824bc5f79f..5c6d05427a0 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -189,18 +189,28 @@ static int send_wqe_overhead(enum ib_qp_type type)
}
static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
- struct mlx4_ib_qp *qp)
+ int is_user, int has_srq, struct mlx4_ib_qp *qp)
{
/* Sanity check RQ size before proceeding */
if (cap->max_recv_wr > dev->dev->caps.max_wqes ||
cap->max_recv_sge > dev->dev->caps.max_rq_sg)
return -EINVAL;
- qp->rq.max = cap->max_recv_wr ? roundup_pow_of_two(cap->max_recv_wr) : 0;
+ if (has_srq) {
+ /* QPs attached to an SRQ should have no RQ */
+ if (cap->max_recv_wr)
+ return -EINVAL;
- qp->rq.wqe_shift = ilog2(roundup_pow_of_two(cap->max_recv_sge *
- sizeof (struct mlx4_wqe_data_seg)));
- qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof (struct mlx4_wqe_data_seg);
+ qp->rq.max = qp->rq.max_gs = 0;
+ } else {
+ /* HW requires >= 1 RQ entry with >= 1 gather entry */
+ if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge))
+ return -EINVAL;
+
+ qp->rq.max = roundup_pow_of_two(max(1, cap->max_recv_wr));
+ qp->rq.max_gs = roundup_pow_of_two(max(1, cap->max_recv_sge));
+ qp->rq.wqe_shift = ilog2(qp->rq.max_gs * sizeof (struct mlx4_wqe_data_seg));
+ }
cap->max_recv_wr = qp->rq.max;
cap->max_recv_sge = qp->rq.max_gs;
@@ -270,9 +280,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
struct ib_qp_init_attr *init_attr,
struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp)
{
- struct mlx4_wqe_ctrl_seg *ctrl;
int err;
- int i;
mutex_init(&qp->mutex);
spin_lock_init(&qp->sq.lock);
@@ -287,7 +295,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
qp->sq.head = 0;
qp->sq.tail = 0;
- err = set_rq_size(dev, &init_attr->cap, qp);
+ err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, !!init_attr->srq, qp);
if (err)
goto err;
@@ -319,20 +327,24 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (err)
goto err_mtt;
- err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context),
- ucmd.db_addr, &qp->db);
- if (err)
- goto err_mtt;
+ if (!init_attr->srq) {
+ err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context),
+ ucmd.db_addr, &qp->db);
+ if (err)
+ goto err_mtt;
+ }
} else {
err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp);
if (err)
goto err;
- err = mlx4_ib_db_alloc(dev, &qp->db, 0);
- if (err)
- goto err;
+ if (!init_attr->srq) {
+ err = mlx4_ib_db_alloc(dev, &qp->db, 0);
+ if (err)
+ goto err;
- *qp->db.db = 0;
+ *qp->db.db = 0;
+ }
if (mlx4_buf_alloc(dev->dev, qp->buf_size, PAGE_SIZE * 2, &qp->buf)) {
err = -ENOMEM;
@@ -348,11 +360,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (err)
goto err_mtt;
- for (i = 0; i < qp->sq.max; ++i) {
- ctrl = get_send_wqe(qp, i);
- ctrl->owner_opcode = cpu_to_be32(1 << 31);
- }
-
qp->sq.wrid = kmalloc(qp->sq.max * sizeof (u64), GFP_KERNEL);
qp->rq.wrid = kmalloc(qp->rq.max * sizeof (u64), GFP_KERNEL);
@@ -386,7 +393,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
return 0;
err_wrid:
- if (pd->uobject)
+ if (pd->uobject && !init_attr->srq)
mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db);
else {
kfree(qp->sq.wrid);
@@ -403,7 +410,7 @@ err_buf:
mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf);
err_db:
- if (!pd->uobject)
+ if (!pd->uobject && !init_attr->srq)
mlx4_ib_db_free(dev, &qp->db);
err:
@@ -481,14 +488,16 @@ static void destroy_qp_common(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp,
mlx4_mtt_cleanup(dev->dev, &qp->mtt);
if (is_user) {
- mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context),
- &qp->db);
+ if (!qp->ibqp.srq)
+ mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context),
+ &qp->db);
ib_umem_release(qp->umem);
} else {
kfree(qp->sq.wrid);
kfree(qp->rq.wrid);
mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf);
- mlx4_ib_db_free(dev, &qp->db);
+ if (!qp->ibqp.srq)
+ mlx4_ib_db_free(dev, &qp->db);
}
}
@@ -763,11 +772,6 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
optpar |= MLX4_QP_OPTPAR_PKEY_INDEX;
}
- if (attr_mask & IB_QP_RNR_RETRY) {
- context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
- optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
- }
-
if (attr_mask & IB_QP_AV) {
if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path,
attr_mask & IB_QP_PORT ? attr->port_num : qp->port)) {
@@ -803,6 +807,12 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pdn);
context->params1 = cpu_to_be32(MLX4_IB_ACK_REQ_FREQ << 28);
+
+ if (attr_mask & IB_QP_RNR_RETRY) {
+ context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
+ optpar |= MLX4_QP_OPTPAR_RNR_RETRY;
+ }
+
if (attr_mask & IB_QP_RETRY_CNT) {
context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
optpar |= MLX4_QP_OPTPAR_RETRY_COUNT;
@@ -852,7 +862,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
if (ibqp->srq)
context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->msrq.srqn);
- if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+ if (!ibqp->srq && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
context->db_rec_addr = cpu_to_be64(qp->db.dma);
if (cur_state == IB_QPS_INIT &&
@@ -872,6 +882,21 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
else
sqd_event = 0;
+ /*
+ * Before passing a kernel QP to the HW, make sure that the
+ * ownership bits of the send queue are set so that the
+ * hardware doesn't start processing stale work requests.
+ */
+ if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+ struct mlx4_wqe_ctrl_seg *ctrl;
+ int i;
+
+ for (i = 0; i < qp->sq.max; ++i) {
+ ctrl = get_send_wqe(qp, i);
+ ctrl->owner_opcode = cpu_to_be32(1 << 31);
+ }
+ }
+
err = mlx4_qp_modify(dev->dev, &qp->mtt, to_mlx4_state(cur_state),
to_mlx4_state(new_state), context, optpar,
sqd_event, &qp->mqp);
@@ -919,7 +944,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
qp->rq.tail = 0;
qp->sq.head = 0;
qp->sq.tail = 0;
- *qp->db.db = 0;
+ if (!ibqp->srq)
+ *qp->db.db = 0;
}
out:
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 38102520ffb..f40558d7647 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -772,7 +772,7 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
MTHCA_GET(dev->fw_ver, outbox, QUERY_FW_VER_OFFSET);
/*
- * FW subminor version is at more signifant bits than minor
+ * FW subminor version is at more significant bits than minor
* version, so swap here.
*/
dev->fw_ver = (dev->fw_ver & 0xffff00000000ull) |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 027664979fe..eef415b12b2 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -2284,10 +2284,10 @@ void mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
struct mthca_next_seg *next;
/*
- * For SRQs, all WQEs generate a CQE, so we're always at the
- * end of the doorbell chain.
+ * For SRQs, all receive WQEs generate a CQE, so we're always
+ * at the end of the doorbell chain.
*/
- if (qp->ibqp.srq) {
+ if (qp->ibqp.srq && !is_send) {
*new_wqe = 0;
return;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index a0b3782c762..285c143115c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -156,7 +156,7 @@ struct ipoib_cm_data {
* - and then invoke a Destroy QP or Reset QP.
*
* We use the second option and wait for a completion on the
- * rx_drain_qp before destroying QPs attached to our SRQ.
+ * same CQ before destroying QPs attached to our SRQ.
*/
enum ipoib_cm_state {
@@ -199,7 +199,6 @@ struct ipoib_cm_dev_priv {
struct ib_srq *srq;
struct ipoib_cm_rx_buf *srq_ring;
struct ib_cm_id *id;
- struct ib_qp *rx_drain_qp; /* generates WR described in 10.3.1 */
struct list_head passive_ids; /* state: LIVE */
struct list_head rx_error_list; /* state: ERROR */
struct list_head rx_flush_list; /* state: FLUSH, drain not started */
@@ -429,6 +428,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey);
void ipoib_pkey_poll(struct work_struct *work);
int ipoib_pkey_dev_delay_open(struct net_device *dev);
+void ipoib_drain_cq(struct net_device *dev);
#ifdef CONFIG_INFINIBAND_IPOIB_CM
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index ffec794b791..076a0bbb63d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -69,8 +69,9 @@ static struct ib_qp_attr ipoib_cm_err_attr = {
#define IPOIB_CM_RX_DRAIN_WRID 0x7fffffff
-static struct ib_recv_wr ipoib_cm_rx_drain_wr = {
- .wr_id = IPOIB_CM_RX_DRAIN_WRID
+static struct ib_send_wr ipoib_cm_rx_drain_wr = {
+ .wr_id = IPOIB_CM_RX_DRAIN_WRID,
+ .opcode = IB_WR_SEND,
};
static int ipoib_cm_tx_handler(struct ib_cm_id *cm_id,
@@ -163,16 +164,22 @@ partial_error:
static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv* priv)
{
- struct ib_recv_wr *bad_wr;
+ struct ib_send_wr *bad_wr;
+ struct ipoib_cm_rx *p;
- /* rx_drain_qp send queue depth is 1, so
+ /* We only reserved 1 extra slot in CQ for drain WRs, so
* make sure we have at most 1 outstanding WR. */
if (list_empty(&priv->cm.rx_flush_list) ||
!list_empty(&priv->cm.rx_drain_list))
return;
- if (ib_post_recv(priv->cm.rx_drain_qp, &ipoib_cm_rx_drain_wr, &bad_wr))
- ipoib_warn(priv, "failed to post rx_drain wr\n");
+ /*
+ * QPs on flush list are error state. This way, a "flush
+ * error" WC will be immediately generated for each WR we post.
+ */
+ p = list_entry(priv->cm.rx_flush_list.next, typeof(*p), list);
+ if (ib_post_send(p->qp, &ipoib_cm_rx_drain_wr, &bad_wr))
+ ipoib_warn(priv, "failed to post drain wr\n");
list_splice_init(&priv->cm.rx_flush_list, &priv->cm.rx_drain_list);
}
@@ -199,10 +206,10 @@ static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev,
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ib_qp_init_attr attr = {
.event_handler = ipoib_cm_rx_event_handler,
- .send_cq = priv->cq, /* does not matter, we never send anything */
+ .send_cq = priv->cq, /* For drain WR */
.recv_cq = priv->cq,
.srq = priv->cm.srq,
- .cap.max_send_wr = 1, /* FIXME: 0 Seems not to work */
+ .cap.max_send_wr = 1, /* For drain WR */
.cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
.sq_sig_type = IB_SIGNAL_ALL_WR,
.qp_type = IB_QPT_RC,
@@ -242,6 +249,27 @@ static int ipoib_cm_modify_rx_qp(struct net_device *dev,
ipoib_warn(priv, "failed to modify QP to RTR: %d\n", ret);
return ret;
}
+
+ /*
+ * Current Mellanox HCA firmware won't generate completions
+ * with error for drain WRs unless the QP has been moved to
+ * RTS first. This work-around leaves a window where a QP has
+ * moved to error asynchronously, but this will eventually get
+ * fixed in firmware, so let's not error out if modify QP
+ * fails.
+ */
+ qp_attr.qp_state = IB_QPS_RTS;
+ ret = ib_cm_init_qp_attr(cm_id, &qp_attr, &qp_attr_mask);
+ if (ret) {
+ ipoib_warn(priv, "failed to init QP attr for RTS: %d\n", ret);
+ return 0;
+ }
+ ret = ib_modify_qp(qp, &qp_attr, qp_attr_mask);
+ if (ret) {
+ ipoib_warn(priv, "failed to modify QP to RTS: %d\n", ret);
+ return 0;
+ }
+
return 0;
}
@@ -623,38 +651,11 @@ static void ipoib_cm_tx_completion(struct ib_cq *cq, void *tx_ptr)
int ipoib_cm_dev_open(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- struct ib_qp_init_attr qp_init_attr = {
- .send_cq = priv->cq, /* does not matter, we never send anything */
- .recv_cq = priv->cq,
- .cap.max_send_wr = 1, /* FIXME: 0 Seems not to work */
- .cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
- .cap.max_recv_wr = 1,
- .cap.max_recv_sge = 1, /* FIXME: 0 Seems not to work */
- .sq_sig_type = IB_SIGNAL_ALL_WR,
- .qp_type = IB_QPT_UC,
- };
int ret;
if (!IPOIB_CM_SUPPORTED(dev->dev_addr))
return 0;
- priv->cm.rx_drain_qp = ib_create_qp(priv->pd, &qp_init_attr);
- if (IS_ERR(priv->cm.rx_drain_qp)) {
- printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
- ret = PTR_ERR(priv->cm.rx_drain_qp);
- return ret;
- }
-
- /*
- * We put the QP in error state directly. This way, a "flush
- * error" WC will be immediately generated for each WR we post.
- */
- ret = ib_modify_qp(priv->cm.rx_drain_qp, &ipoib_cm_err_attr, IB_QP_STATE);
- if (ret) {
- ipoib_warn(priv, "failed to modify drain QP to error: %d\n", ret);
- goto err_qp;
- }
-
priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev);
if (IS_ERR(priv->cm.id)) {
printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
@@ -676,8 +677,6 @@ err_listen:
ib_destroy_cm_id(priv->cm.id);
err_cm:
priv->cm.id = NULL;
-err_qp:
- ib_destroy_qp(priv->cm.rx_drain_qp);
return ret;
}
@@ -713,7 +712,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
while (!list_empty(&priv->cm.rx_error_list) ||
!list_empty(&priv->cm.rx_flush_list) ||
!list_empty(&priv->cm.rx_drain_list)) {
- if (!time_after(jiffies, begin + 5 * HZ)) {
+ if (time_after(jiffies, begin + 5 * HZ)) {
ipoib_warn(priv, "RX drain timing out\n");
/*
@@ -726,6 +725,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
}
spin_unlock_irq(&priv->lock);
msleep(1);
+ ipoib_drain_cq(dev);
spin_lock_irq(&priv->lock);
}
@@ -739,7 +739,6 @@ void ipoib_cm_dev_stop(struct net_device *dev)
kfree(p);
}
- ib_destroy_qp(priv->cm.rx_drain_qp);
cancel_delayed_work(&priv->cm.stale_task);
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index c1aad06eb4e..8404f05b2b6 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -550,13 +550,30 @@ static int recvs_pending(struct net_device *dev)
return pending;
}
+void ipoib_drain_cq(struct net_device *dev)
+{
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+ int i, n;
+ do {
+ n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
+ for (i = 0; i < n; ++i) {
+ if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
+ ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
+ else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
+ ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+ else
+ ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+ }
+ } while (n == IPOIB_NUM_WC);
+}
+
int ipoib_ib_dev_stop(struct net_device *dev, int flush)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ib_qp_attr qp_attr;
unsigned long begin;
struct ipoib_tx_buf *tx_req;
- int i, n;
+ int i;
clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
netif_poll_disable(dev);
@@ -611,17 +628,7 @@ int ipoib_ib_dev_stop(struct net_device *dev, int flush)
goto timeout;
}
- do {
- n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
- for (i = 0; i < n; ++i) {
- if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
- ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
- else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
- ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
- else
- ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
- }
- } while (n == IPOIB_NUM_WC);
+ ipoib_drain_cq(dev);
msleep(1);
}
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index f814fb3a469..2d87357e2b2 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -39,6 +39,19 @@ config INPUT_FF_MEMLESS
To compile this driver as a module, choose M here: the
module will be called ff-memless.
+config INPUT_POLLDEV
+ tristate "Polled input device skeleton"
+ help
+ Say Y here if you are using a driver for an input
+ device that periodically polls hardware state. This
+ option is only useful for out-of-tree drivers since
+ in-tree drivers select it automatically.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called input-polldev.
+
comment "Userland interfaces"
config INPUT_MOUSEDEV
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 8a2dd987546..15eb752697b 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_INPUT) += input-core.o
input-core-objs := input.o ff-core.o
obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
+obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index b234729706b..be6b93c20f6 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -699,9 +699,9 @@ static void evdev_disconnect(struct input_handle *handle)
if (evdev->open) {
input_flush_device(handle, NULL);
input_close_device(handle);
- wake_up_interruptible(&evdev->wait);
list_for_each_entry(client, &evdev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ wake_up_interruptible(&evdev->wait);
} else
evdev_free(evdev);
}
diff --git a/drivers/input/misc/input-polldev.c b/drivers/input/input-polldev.c
index 1b2b9c9c5d8..b773d4c756a 100644
--- a/drivers/input/misc/input-polldev.c
+++ b/drivers/input/input-polldev.c
@@ -12,6 +12,11 @@
#include <linux/mutex.h>
#include <linux/input-polldev.h>
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Generic implementation of a polled input device");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+
static DEFINE_MUTEX(polldev_mutex);
static int polldev_users;
static struct workqueue_struct *polldev_wq;
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 06f0541b24d..10e3b7bc925 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -594,9 +594,9 @@ static void joydev_disconnect(struct input_handle *handle)
if (joydev->open) {
input_close_device(handle);
- wake_up_interruptible(&joydev->wait);
list_for_each_entry(client, &joydev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ wake_up_interruptible(&joydev->wait);
} else
joydev_free(joydev);
}
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index 86ad1027e12..b069ee18e35 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -54,7 +54,7 @@ static struct db9_config db9_cfg[DB9_MAX_PORTS] __initdata;
module_param_array_named(dev, db9_cfg[0].args, int, &db9_cfg[0].nargs, 0);
MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
-module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[0].nargs, 0);
+module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[1].nargs, 0);
MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
module_param_array_named(dev3, db9_cfg[2].args, int, &db9_cfg[2].nargs, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index fb129c479a6..682244b1c04 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -370,10 +370,8 @@ int iforce_init_device(struct iforce *iforce)
/*
* Disable spring, enable force feedback.
- * FIXME: We should use iforce_set_autocenter() et al here.
*/
-
- iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000");
+ iforce_set_autocenter(input_dev, 0);
/*
* Find appropriate device entry
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 21c4e13d3a5..3154ccd7400 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -246,6 +246,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
int iforce_get_id_packet(struct iforce *iforce, char *packet)
{
+ int status;
+
switch (iforce->bus) {
case IFORCE_USB:
@@ -254,18 +256,22 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
iforce->cr.bRequest = packet[0];
iforce->ctrl->dev = iforce->usbdev;
- if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC))
+ status = usb_submit_urb(iforce->ctrl, GFP_ATOMIC);
+ if (status) {
+ err("usb_submit_urb failed %d", status);
return -1;
+ }
wait_event_interruptible_timeout(iforce->wait,
iforce->ctrl->status != -EINPROGRESS, HZ);
if (iforce->ctrl->status) {
+ dbg("iforce->ctrl->status = %d", iforce->ctrl->status);
usb_unlink_urb(iforce->ctrl);
return -1;
}
#else
- err("iforce_get_id_packet: iforce->bus = USB!");
+ dbg("iforce_get_id_packet: iforce->bus = USB!");
#endif
break;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 750099d8e3c..1457b73850e 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -65,6 +65,7 @@ void iforce_usb_xmit(struct iforce *iforce)
XMIT_INC(iforce->xmit.tail, n);
if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
+ clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
warn("usb_submit_urb failed %d\n", n);
}
@@ -163,8 +164,8 @@ static int iforce_usb_probe(struct usb_interface *intf,
usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
- usb_fill_bulk_urb(iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress),
- iforce + 1, 32, iforce_usb_out, iforce);
+ usb_fill_int_urb(iforce->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress),
+ iforce + 1, 32, iforce_usb_out, iforce, epout->bInterval);
usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
(void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c
index 06eaf766d9d..f9e82c9ca42 100644
--- a/drivers/input/keyboard/pxa27x_keyboard.c
+++ b/drivers/input/keyboard/pxa27x_keyboard.c
@@ -104,7 +104,7 @@ static int pxakbd_open(struct input_dev *dev)
KPREC = 0x7F;
/* Enable unit clock */
- pxa_set_cken(CKEN19_KEYPAD, 1);
+ pxa_set_cken(CKEN_KEYPAD, 1);
return 0;
}
@@ -112,7 +112,7 @@ static int pxakbd_open(struct input_dev *dev)
static void pxakbd_close(struct input_dev *dev)
{
/* Disable clock unit */
- pxa_set_cken(CKEN19_KEYPAD, 0);
+ pxa_set_cken(CKEN_KEYPAD, 0);
}
#ifdef CONFIG_PM
@@ -185,7 +185,7 @@ static int __devinit pxakbd_probe(struct platform_device *pdev)
DRIVER_NAME, pdev);
if (error) {
printk(KERN_ERR "Cannot request keypad IRQ\n");
- pxa_set_cken(CKEN19_KEYPAD, 0);
+ pxa_set_cken(CKEN_KEYPAD, 0);
goto err_free_dev;
}
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 842a7b4d16f..88e29074ac9 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -170,17 +170,6 @@ config INPUT_UINPUT
To compile this driver as a module, choose M here: the
module will be called uinput.
-config INPUT_POLLDEV
- tristate "Polled input device skeleton"
- help
- Say Y here if you are using a driver for an input
- device that periodically polls hardware state. This
- option is only useful for out-of-tree drivers since
- in-tree drivers select it automatically.
-
- To compile this driver as a module, choose M here: the
- module will be called input-polldev.
-
config HP_SDC_RTC
tristate "HP SDC Real Time Clock"
depends on GSC || HP300
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 8b2f7799e25..3585b503841 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,7 +4,6 @@
# Each configuration option enables a list of files.
-obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index eb0167e9f0c..50e06e8dd05 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -48,7 +48,7 @@ config MOUSE_PS2_ALPS
If unsure, say Y.
config MOUSE_PS2_LOGIPS2PP
- bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED
+ bool "Logitech PS/2++ mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
help
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index cf3e4664e72..2c5f11a4f6b 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -251,11 +251,15 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
- for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++);
- *version = (param[0] << 8) | (param[1] << 4) | i;
+ if (version) {
+ for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
+ /* empty */;
+ *version = (param[0] << 8) | (param[1] << 4) | i;
+ }
for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
- if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature)))
+ if (!memcmp(param, alps_model_data[i].signature,
+ sizeof(alps_model_data[i].signature)))
return alps_model_data + i;
return NULL;
@@ -380,32 +384,46 @@ static int alps_poll(struct psmouse *psmouse)
return 0;
}
-static int alps_reconnect(struct psmouse *psmouse)
+static int alps_hw_init(struct psmouse *psmouse, int *version)
{
struct alps_data *priv = psmouse->private;
- int version;
-
- psmouse_reset(psmouse);
- if (!(priv->i = alps_get_model(psmouse, &version)))
+ priv->i = alps_get_model(psmouse, version);
+ if (!priv->i)
return -1;
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
return -1;
if (alps_tap_mode(psmouse, 1)) {
- printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n");
+ printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
return -1;
}
if (alps_absolute_mode(psmouse)) {
- printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n");
+ printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
return -1;
}
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
return -1;
+ /* ALPS needs stream mode, otherwise it won't report any data */
+ if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
+ printk(KERN_ERR "alps.c: Failed to enable stream mode\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int alps_reconnect(struct psmouse *psmouse)
+{
+ psmouse_reset(psmouse);
+
+ if (alps_hw_init(psmouse, NULL))
+ return -1;
+
return 0;
}
@@ -430,23 +448,9 @@ int alps_init(struct psmouse *psmouse)
goto init_fail;
priv->dev2 = dev2;
+ psmouse->private = priv;
- priv->i = alps_get_model(psmouse, &version);
- if (!priv->i)
- goto init_fail;
-
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
- goto init_fail;
-
- if (alps_tap_mode(psmouse, 1))
- printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
-
- if (alps_absolute_mode(psmouse)) {
- printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
- goto init_fail;
- }
-
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+ if (alps_hw_init(psmouse, &version))
goto init_fail;
dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
@@ -493,13 +497,13 @@ int alps_init(struct psmouse *psmouse)
/* We are having trouble resyncing ALPS touchpads so disable it for now */
psmouse->resync_time = 0;
- psmouse->private = priv;
return 0;
init_fail:
psmouse_reset(psmouse);
input_free_device(dev2);
kfree(priv);
+ psmouse->private = NULL;
return -1;
}
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 9df74b72e6c..0c5660d28ca 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -221,6 +221,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
{ 66, PS2PP_KIND_MX, /* MX3100 reciver */
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
+ { 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */
{ 73, 0, PS2PP_SIDE_BTN },
{ 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 8675f950939..3f4866d8d18 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -766,9 +766,9 @@ static void mousedev_disconnect(struct input_handle *handle)
if (mousedev->open) {
input_close_device(handle);
- wake_up_interruptible(&mousedev->wait);
list_for_each_entry(client, &mousedev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ wake_up_interruptible(&mousedev->wait);
} else
mousedev_free(mousedev);
}
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 6858bc58f0f..f4a2517925e 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -69,6 +69,15 @@ static inline void i8042_write_command(int val)
static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
{
+ /* AUX LOOP command does not raise AUX IRQ */
+ .ident = "ASUS P65UP5",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
+ DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"),
+ },
+ },
+ {
.ident = "Compaq Proliant 8500",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
@@ -92,6 +101,15 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
},
},
+ {
+ /* AUX LOOP does not work properly */
+ .ident = "ULI EV4873",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+ },
+ },
{ }
};
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 559508795af..d31ece8f68e 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -170,7 +170,7 @@ static void ps2_close(struct serio *io)
/*
* Clear the input buffer.
*/
-static void __init ps2_clear_input(struct ps2if *ps2if)
+static void __devinit ps2_clear_input(struct ps2if *ps2if)
{
int maxread = 100;
@@ -228,7 +228,7 @@ static int __init ps2_test(struct ps2if *ps2if)
/*
* Add one device to this driver.
*/
-static int ps2_probe(struct sa1111_dev *dev)
+static int __devinit ps2_probe(struct sa1111_dev *dev)
{
struct ps2if *ps2if;
struct serio *serio;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 4f091800bfe..e5cca9bd040 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -12,17 +12,17 @@ menuconfig INPUT_TOUCHSCREEN
if INPUT_TOUCHSCREEN
config TOUCHSCREEN_ADS7846
- tristate "ADS 7846/7843 based touchscreens"
+ tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
depends on SPI_MASTER
depends on HWMON = n || HWMON
help
Say Y here if you have a touchscreen interface using the
- ADS7846 or ADS7843 controller, and your board-specific setup
- code includes that in its table of SPI devices.
+ ADS7846/TSC2046 or ADS7843 controller, and your board-specific
+ setup code includes that in its table of SPI devices.
If HWMON is selected, and the driver is told the reference voltage
on your board, you will also get hwmon interfaces for the voltage
- (and on ads7846, temperature) sensors of this chip.
+ (and on ads7846/tsc2046, temperature) sensors of this chip.
If unsure, say N (but it's safe to say "Y").
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 693e3b2a65a..1c9069cd3ba 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -39,6 +39,7 @@
/*
* This code has been heavily tested on a Nokia 770, and lightly
* tested on other ads7846 devices (OSK/Mistral, Lubbock).
+ * TSC2046 is just newer ads7846 silicon.
* Support for ads7843 tested on Atmel at91sam926x-EK.
* Support for ads7845 has only been stubbed in.
*
@@ -847,7 +848,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
* may not. So we stick to very-portable 8 bit words, both RX and TX.
*/
spi->bits_per_word = 8;
- spi->mode = SPI_MODE_1;
+ spi->mode = SPI_MODE_0;
err = spi_setup(spi);
if (err < 0)
return err;
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index 61c15024c2a..1a15475aedf 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -1,7 +1,6 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
-
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/delay.h>
@@ -18,12 +17,12 @@
#define PHDR 0xa400012e
#define SCPDR 0xa4000136
-static void do_softint(void *data);
+static void do_softint(struct work_struct *work);
static struct input_dev *hp680_ts_dev;
-static DECLARE_WORK(work, do_softint);
+static DECLARE_DELAYED_WORK(work, do_softint);
-static void do_softint(void *data)
+static void do_softint(struct work_struct *work)
{
int absx = 0, absy = 0;
u8 scpdr;
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 6582816a047..f0cbcdb008e 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -288,9 +288,9 @@ static int ucb1400_ts_thread(void *_ucb)
struct ucb1400 *ucb = _ucb;
struct task_struct *tsk = current;
int valid = 0;
+ struct sched_param param = { .sched_priority = 1 };
- tsk->policy = SCHED_FIFO;
- tsk->rt_priority = 1;
+ sched_setscheduler(tsk, SCHED_FIFO, &param);
while (!kthread_should_stop()) {
unsigned int x, y, p;
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 8e18e6c6477..e3f22852bd0 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -91,7 +91,7 @@ struct usbtouch_usb {
};
-#if defined(CONFIG_USB_TOUCHSCREEN_EGALAX) || defined(CONFIG_USB_TOUCHSCREEN_ETURBO)
+#if defined(CONFIG_TOUCHSCREEN_USB_EGALAX) || defined(CONFIG_TOUCHSCREEN_USB_ETURBO)
#define MULTI_PACKET
#endif
@@ -113,7 +113,7 @@ enum {
};
static struct usb_device_id usbtouch_devices[] = {
-#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+#ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
{USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
{USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX},
{USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
@@ -123,30 +123,30 @@ static struct usb_device_id usbtouch_devices[] = {
{USB_DEVICE(0x1234, 0x0002), .driver_info = DEVTYPE_EGALAX},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+#ifdef CONFIG_TOUCHSCREEN_USB_PANJIT
{USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT},
{USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT},
{USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT},
{USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_3M
+#ifdef CONFIG_TOUCHSCREEN_USB_3M
{USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+#ifdef CONFIG_TOUCHSCREEN_USB_ITM
{USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
+#ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
{USB_DEVICE(0x1234, 0x5678), .driver_info = DEVTYPE_ETURBO},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
+#ifdef CONFIG_TOUCHSCREEN_USB_GUNZE
{USB_DEVICE(0x0637, 0x0001), .driver_info = DEVTYPE_GUNZE},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
+#ifdef CONFIG_TOUCHSCREEN_USB_DMC_TSC10
{USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10},
#endif
@@ -158,7 +158,7 @@ static struct usb_device_id usbtouch_devices[] = {
* eGalax part
*/
-#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+#ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
#define EGALAX_PKT_TYPE_MASK 0xFE
#define EGALAX_PKT_TYPE_REPT 0x80
@@ -197,7 +197,7 @@ static int egalax_get_pkt_len(unsigned char *buf, int len)
/*****************************************************************************
* PanJit Part
*/
-#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+#ifdef CONFIG_TOUCHSCREEN_USB_PANJIT
static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{
dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
@@ -212,7 +212,7 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
/*****************************************************************************
* 3M/Microtouch Part
*/
-#ifdef CONFIG_USB_TOUCHSCREEN_3M
+#ifdef CONFIG_TOUCHSCREEN_USB_3M
#define MTOUCHUSB_ASYNC_REPORT 1
#define MTOUCHUSB_RESET 7
@@ -262,7 +262,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
/*****************************************************************************
* ITM Part
*/
-#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+#ifdef CONFIG_TOUCHSCREEN_USB_ITM
static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{
int touch;
@@ -296,7 +296,7 @@ static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
/*****************************************************************************
* eTurboTouch part
*/
-#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
+#ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{
unsigned int shift;
@@ -327,7 +327,7 @@ static int eturbo_get_pkt_len(unsigned char *buf, int len)
/*****************************************************************************
* Gunze part
*/
-#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
+#ifdef CONFIG_TOUCHSCREEN_USB_GUNZE
static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
{
if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80))
@@ -348,7 +348,7 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
* http://www.dmccoltd.com/files/controler/tsc10usb_pi_e.pdf
* http://www.dmccoltd.com/files/controler/tsc25_usb_e.pdf
*/
-#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
+#ifdef CONFIG_TOUCHSCREEN_USB_DMC_TSC10
/* supported data rates. currently using 130 */
#define TSC10_RATE_POINT 0x50
@@ -419,7 +419,7 @@ static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
* the different device descriptors
*/
static struct usbtouch_device_info usbtouch_dev_info[] = {
-#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+#ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
[DEVTYPE_EGALAX] = {
.min_xc = 0x0,
.max_xc = 0x07ff,
@@ -433,7 +433,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+#ifdef CONFIG_TOUCHSCREEN_USB_PANJIT
[DEVTYPE_PANJIT] = {
.min_xc = 0x0,
.max_xc = 0x0fff,
@@ -444,7 +444,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_3M
+#ifdef CONFIG_TOUCHSCREEN_USB_3M
[DEVTYPE_3M] = {
.min_xc = 0x0,
.max_xc = 0x4000,
@@ -456,7 +456,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+#ifdef CONFIG_TOUCHSCREEN_USB_ITM
[DEVTYPE_ITM] = {
.min_xc = 0x0,
.max_xc = 0x0fff,
@@ -468,7 +468,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
+#ifdef CONFIG_TOUCHSCREEN_USB_ETURBO
[DEVTYPE_ETURBO] = {
.min_xc = 0x0,
.max_xc = 0x07ff,
@@ -482,7 +482,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
+#ifdef CONFIG_TOUCHSCREEN_USB_GUNZE
[DEVTYPE_GUNZE] = {
.min_xc = 0x0,
.max_xc = 0x0fff,
@@ -493,7 +493,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
},
#endif
-#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
+#ifdef CONFIG_TOUCHSCREEN_USB_DMC_TSC10
[DEVTYPE_DMC_TSC10] = {
.min_xc = 0x0,
.max_xc = 0x03ff,
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 8238b13874c..2db364898e1 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -476,9 +476,9 @@ static void tsdev_disconnect(struct input_handle *handle)
if (tsdev->open) {
input_close_device(handle);
- wake_up_interruptible(&tsdev->wait);
list_for_each_entry(client, &tsdev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ wake_up_interruptible(&tsdev->wait);
} else
tsdev_free(tsdev);
}
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index d42fe89cddf..3e088c42b22 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -26,9 +26,9 @@ menu "Old ISDN4Linux"
depends on NET && ISDN
config ISDN_I4L
- tristate "Old ISDN4Linux (obsolete)"
+ tristate "Old ISDN4Linux (deprecated)"
---help---
- This driver allows you to use an ISDN-card for networking
+ This driver allows you to use an ISDN adapter for networking
connections and as dialin/out device. The isdn-tty's have a built
in AT-compatible modem emulator. Network devices support autodial,
channel-bundling, callback and caller-authentication without having
@@ -39,8 +39,9 @@ config ISDN_I4L
ISDN support in the linux kernel is moving towards a new API,
called CAPI (Common ISDN Application Programming Interface).
- Therefore the old ISDN4Linux layer is becoming obsolete. It is
- still usable, though, if you select this option.
+ Therefore the old ISDN4Linux layer will eventually become obsolete.
+ It is still available, though, for use with adapters that are not
+ supported by the new CAPI subsystem yet.
if ISDN_I4L
source "drivers/isdn/i4l/Kconfig"
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index ff284aeb8fb..82edc1c1db7 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -189,21 +189,21 @@ void *TransmitBufferSet(APPL * appl, dword ref)
{
appl->xbuffer_used[ref] = true;
DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))
- return (void *) ref;
+ return (void *)(long)ref;
}
void *TransmitBufferGet(APPL * appl, void *p)
{
- if (appl->xbuffer_internal[(dword) p])
- return appl->xbuffer_internal[(dword) p];
+ if (appl->xbuffer_internal[(dword)(long)p])
+ return appl->xbuffer_internal[(dword)(long)p];
- return appl->xbuffer_ptr[(dword) p];
+ return appl->xbuffer_ptr[(dword)(long)p];
}
void TransmitBufferFree(APPL * appl, void *p)
{
- appl->xbuffer_used[(dword) p] = false;
- DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword) p) + 1))
+ appl->xbuffer_used[(dword)(long)p] = false;
+ DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1))
}
void *ReceiveBufferGet(APPL * appl, int Num)
@@ -301,7 +301,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
/* if DATA_B3_IND, copy data too */
if (command == _DATA_B3_I) {
dword data = GET_DWORD(&msg.info.data_b3_ind.Data);
- memcpy(write + length, (void *) data, dlength);
+ memcpy(write + length, (void *)(long)data, dlength);
}
#ifndef DIVA_NO_DEBUGLIB
@@ -318,7 +318,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
if (myDriverDebugHandle.dbgMask & DL_BLK) {
xlog("\x00\x02", &msg, 0x81, length);
for (i = 0; i < dlength; i += 256) {
- DBG_BLK((((char *) GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
+ DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
((dlength - i) < 256) ? (dlength - i) : 256))
if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
break; /* not more if not explicitely requested */
diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
index 14298b8c835..d755d904e62 100644
--- a/drivers/isdn/hardware/eicon/diva_didd.c
+++ b/drivers/isdn/hardware/eicon/diva_didd.c
@@ -99,7 +99,7 @@ static int DIVA_INIT_FUNCTION create_proc(void)
return (0);
}
-static void DIVA_EXIT_FUNCTION remove_proc(void)
+static void remove_proc(void)
{
remove_proc_entry(DRIVERLNAME, proc_net_eicon);
remove_proc_entry("net/eicon", NULL);
diff --git a/drivers/isdn/hardware/eicon/divasfunc.c b/drivers/isdn/hardware/eicon/divasfunc.c
index df61e510a28..d36a4c09e25 100644
--- a/drivers/isdn/hardware/eicon/divasfunc.c
+++ b/drivers/isdn/hardware/eicon/divasfunc.c
@@ -195,7 +195,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
/*
* disconnect from didd
*/
-static void DIVA_EXIT_FUNCTION disconnect_didd(void)
+static void disconnect_didd(void)
{
IDI_SYNC_REQ req;
@@ -231,7 +231,7 @@ int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask)
/*
* exit
*/
-void DIVA_EXIT_FUNCTION divasfunc_exit(void)
+void divasfunc_exit(void)
{
divasa_xdi_driver_unload();
disconnect_didd();
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 784232a144c..ccd35d047ec 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -1,4 +1,3 @@
-
/*
*
Copyright (c) Eicon Networks, 2002.
@@ -533,7 +532,7 @@ word api_put(APPL * appl, CAPI_MSG * msg)
if (m->header.command == _DATA_B3_R)
{
- m->info.data_b3_req.Data = (dword)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
+ m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
}
@@ -1032,7 +1031,7 @@ static void plci_free_msg_in_queue (PLCI *plci)
{
TransmitBufferFree (plci->appl,
- (byte *)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
+ (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
}
@@ -3118,7 +3117,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
&& (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
{
- data->P = (byte *)(*((dword *)(parms[0].info)));
+ data->P = (byte *)(long)(*((dword *)(parms[0].info)));
}
else
@@ -3151,7 +3150,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
&& (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
{
- TransmitBufferFree (appl, (byte *)(*((dword *)(parms[0].info))));
+ TransmitBufferFree (appl, (byte *)(long)(*((dword *)(parms[0].info))));
}
}
@@ -4057,7 +4056,7 @@ capi_callback_suffix:
{
if (m->header.command == _DATA_B3_R)
- TransmitBufferFree (appl, (byte *)(m->info.data_b3_req.Data));
+ TransmitBufferFree (appl, (byte *)(long)(m->info.data_b3_req.Data));
dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
break;
@@ -7134,7 +7133,7 @@ void nl_ind(PLCI * plci)
case N_UDATA:
if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
{
- plci->RData[0].P = plci->internal_ind_buffer + (-((int)(plci->internal_ind_buffer)) & 3);
+ plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3);
plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE;
plci->NL.R = plci->RData;
plci->NL.RNum = 1;
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index da4196f21e0..8d53a7fd267 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1551,7 +1551,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
if (retval == 0) { // yuck
cards[i].typ = 0;
nrcards--;
- return retval;
+ return -EINVAL;
}
cs = cards[i].cs;
hisax_d_if->cs = cs;
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 1f18f199338..b1a26e02df0 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -485,7 +485,6 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
{
int k;
- spin_lock_init(&urb->lock);
urb->dev = dev;
urb->pipe = pipe;
urb->complete = complete;
@@ -578,16 +577,14 @@ stop_isoc_chain(usb_fifo * fifo)
"HFC-S USB: Stopping iso chain for fifo %i.%i",
fifo->fifonum, i);
#endif
- usb_unlink_urb(fifo->iso[i].purb);
+ usb_kill_urb(fifo->iso[i].purb);
usb_free_urb(fifo->iso[i].purb);
fifo->iso[i].purb = NULL;
}
}
- if (fifo->urb) {
- usb_unlink_urb(fifo->urb);
- usb_free_urb(fifo->urb);
- fifo->urb = NULL;
- }
+ usb_kill_urb(fifo->urb);
+ usb_free_urb(fifo->urb);
+ fifo->urb = NULL;
fifo->active = 0;
}
@@ -1305,7 +1302,11 @@ usb_init(hfcusb_data * hfc)
}
/* default Prot: EURO ISDN, should be a module_param */
hfc->protocol = 2;
- hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol);
+ i = hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol);
+ if (i) {
+ printk(KERN_INFO "HFC-S USB: hisax_register -> %d\n", i);
+ return i;
+ }
#ifdef CONFIG_HISAX_DEBUG
hfc_debug = debug;
@@ -1626,11 +1627,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
#endif
/* init the chip and register the driver */
if (usb_init(context)) {
- if (context->ctrl_urb) {
- usb_unlink_urb(context->ctrl_urb);
- usb_free_urb(context->ctrl_urb);
- context->ctrl_urb = NULL;
- }
+ usb_kill_urb(context->ctrl_urb);
+ usb_free_urb(context->ctrl_urb);
+ context->ctrl_urb = NULL;
kfree(context);
return (-EIO);
}
@@ -1682,21 +1681,15 @@ hfc_usb_disconnect(struct usb_interface
i);
#endif
}
- if (context->fifos[i].urb) {
- usb_unlink_urb(context->fifos[i].urb);
- usb_free_urb(context->fifos[i].urb);
- context->fifos[i].urb = NULL;
- }
+ usb_kill_urb(context->fifos[i].urb);
+ usb_free_urb(context->fifos[i].urb);
+ context->fifos[i].urb = NULL;
}
context->fifos[i].active = 0;
}
- /* wait for all URBS to terminate */
- mdelay(10);
- if (context->ctrl_urb) {
- usb_unlink_urb(context->ctrl_urb);
- usb_free_urb(context->ctrl_urb);
- context->ctrl_urb = NULL;
- }
+ usb_kill_urb(context->ctrl_urb);
+ usb_free_urb(context->ctrl_urb);
+ context->ctrl_urb = NULL;
hisax_unregister(&context->d_if);
kfree(context); /* free our structure again */
} /* hfc_usb_disconnect */
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 9e088fce8c3..7993e01f9fc 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -859,7 +859,11 @@ new_adapter(void)
for (i = 0; i < 2; i++)
b_if[i] = &adapter->bcs[i].b_if;
- hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol);
+ if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp",
+ protocol) != 0) {
+ kfree(adapter);
+ adapter = NULL;
+ }
return adapter;
}
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index bb3a28a53ff..13751237bfc 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -107,12 +107,17 @@ static int probe_st5481(struct usb_interface *intf,
for (i = 0; i < 2; i++)
b_if[i] = &adapter->bcs[i].b_if;
- hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol);
+ if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb",
+ protocol) != 0)
+ goto err_b1;
+
st5481_start(adapter);
usb_set_intfdata(intf, adapter);
return 0;
+ err_b1:
+ st5481_release_b(&adapter->bcs[1]);
err_b:
st5481_release_b(&adapter->bcs[0]);
err_d:
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index ff159512204..4ada66b8b67 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -407,7 +407,6 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev,
{
int k;
- spin_lock_init(&urb->lock);
urb->dev=dev;
urb->pipe=pipe;
urb->interval = 1;
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index ea5f30d4a5a..4e5f87c1e71 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -2693,8 +2693,9 @@ isdn_tty_getdial(char *p, char *q,int cnt)
int limit = ISDN_MSNLEN - 1; /* MUST match the size of interface var to avoid
buffer overflow */
- while (strchr(" 0123456789,#.*WPTS-", *p) && *p && --cnt>0) {
+ while (strchr(" 0123456789,#.*WPTSR-", *p) && *p && --cnt>0) {
if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) ||
+ ((*p == 'R') && first) ||
(*p == '*') || (*p == '#')) {
*q++ = *p;
limit--;
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index e6e4d240b2a..184238e2ece 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -639,7 +639,7 @@ static void free_vmcs(struct vmcs *vmcs)
free_pages((unsigned long)vmcs, vmcs_descriptor.order);
}
-static __exit void free_kvm_area(void)
+static void free_kvm_area(void)
{
int cpu;
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 58926da0ae1..ee699a7d621 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -113,9 +113,8 @@ config PMAC_SMU
config PMAC_APM_EMU
tristate "APM emulation"
- select SYS_SUPPORTS_APM_EMULATION
select APM_EMULATION
- depends on ADB_PMU && PM
+ depends on ADB_PMU && PM && PPC32
config PMAC_MEDIABAY
bool "Support PowerBook hotswap media bay"
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index b77ef5187d6..b46817f699f 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -628,16 +628,16 @@ static void real_leds(unsigned char leds, int device)
*/
static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
- struct adbhid *adbhid = dev->private;
+ struct adbhid *adbhid = input_get_drvdata(dev);
unsigned char leds;
switch (type) {
case EV_LED:
- leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0)
- | (test_bit(LED_NUML, dev->led) ? 1 : 0)
- | (test_bit(LED_CAPSL, dev->led) ? 2 : 0);
- real_leds(leds, adbhid->id);
- return 0;
+ leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) |
+ (test_bit(LED_NUML, dev->led) ? 1 : 0) |
+ (test_bit(LED_CAPSL, dev->led) ? 2 : 0);
+ real_leds(leds, adbhid->id);
+ return 0;
}
return -1;
@@ -649,7 +649,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
switch (code) {
case ADB_MSG_PRE_RESET:
case ADB_MSG_POWERDOWN:
- /* Stop the repeat timer. Autopoll is already off at this point */
+ /* Stop the repeat timer. Autopoll is already off at this point */
{
int i;
for (i = 1; i < 16; i++) {
@@ -699,7 +699,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
hid->current_handler_id = current_handler_id;
hid->mouse_kind = mouse_kind;
hid->flags = 0;
- input_dev->private = hid;
+ input_set_drvdata(input_dev, hid);
input_dev->name = hid->name;
input_dev->phys = hid->phys;
input_dev->id.bustype = BUS_ADB;
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 5a4a74c1097..9620d452d03 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -255,19 +255,25 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
}
-static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
+static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
{
mdk_rdev_t *rdev;
struct list_head *tmp;
+ mddev_t *mddev = bitmap->mddev;
ITERATE_RDEV(mddev, rdev, tmp)
if (test_bit(In_sync, &rdev->flags)
- && !test_bit(Faulty, &rdev->flags))
+ && !test_bit(Faulty, &rdev->flags)) {
+ int size = PAGE_SIZE;
+ if (page->index == bitmap->file_pages-1)
+ size = roundup(bitmap->last_page_size,
+ bdev_hardsect_size(rdev->bdev));
md_super_write(mddev, rdev,
- (rdev->sb_offset<<1) + offset
+ (rdev->sb_offset<<1) + bitmap->offset
+ page->index * (PAGE_SIZE/512),
- PAGE_SIZE,
+ size,
page);
+ }
if (wait)
md_super_wait(mddev);
@@ -282,7 +288,7 @@ static int write_page(struct bitmap *bitmap, struct page *page, int wait)
struct buffer_head *bh;
if (bitmap->file == NULL)
- return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
+ return write_sb_page(bitmap, page, wait);
bh = page_buffers(page);
@@ -923,6 +929,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
}
bitmap->filemap[bitmap->file_pages++] = page;
+ bitmap->last_page_size = count;
}
paddr = kmap_atomic(page, KM_USER0);
if (bitmap->flags & BITMAP_HOSTENDIAN)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index d5ecd2d5304..19274108319 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -139,8 +139,6 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
if (!conf)
return NULL;
- mddev->private = conf;
-
cnt = 0;
conf->array_size = 0;
@@ -232,7 +230,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
* First calculate the device offsets.
*/
conf->disks[0].offset = 0;
- for (i=1; i<mddev->raid_disks; i++)
+ for (i = 1; i < raid_disks; i++)
conf->disks[i].offset =
conf->disks[i-1].offset +
conf->disks[i-1].size;
@@ -244,7 +242,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
curr_offset < conf->array_size;
curr_offset += conf->hash_spacing) {
- while (i < mddev->raid_disks-1 &&
+ while (i < raid_disks-1 &&
curr_offset >= conf->disks[i+1].offset)
i++;
@@ -299,9 +297,11 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev)
*/
linear_conf_t *newconf;
- if (rdev->raid_disk != mddev->raid_disks)
+ if (rdev->saved_raid_disk != mddev->raid_disks)
return -EINVAL;
+ rdev->raid_disk = rdev->saved_raid_disk;
+
newconf = linear_conf(mddev,mddev->raid_disks+1);
if (!newconf)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c10ce91b64e..1c54f3c1cca 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1298,8 +1298,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
ITERATE_RDEV(mddev,rdev2,tmp)
if (rdev2->desc_nr+1 > max_dev)
max_dev = rdev2->desc_nr+1;
-
- sb->max_dev = cpu_to_le32(max_dev);
+
+ if (max_dev > le32_to_cpu(sb->max_dev))
+ sb->max_dev = cpu_to_le32(max_dev);
for (i=0; i<max_dev;i++)
sb->dev_roles[i] = cpu_to_le16(0xfffe);
@@ -1365,10 +1366,14 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
}
/* make sure rdev->size exceeds mddev->size */
if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
- if (mddev->pers)
- /* Cannot change size, so fail */
- return -ENOSPC;
- else
+ if (mddev->pers) {
+ /* Cannot change size, so fail
+ * If mddev->level <= 0, then we don't care
+ * about aligning sizes (e.g. linear)
+ */
+ if (mddev->level > 0)
+ return -ENOSPC;
+ } else
mddev->size = rdev->size;
}
@@ -2142,6 +2147,9 @@ static void analyze_sbs(mddev_t * mddev)
rdev->desc_nr = i++;
rdev->raid_disk = rdev->desc_nr;
set_bit(In_sync, &rdev->flags);
+ } else if (rdev->raid_disk >= mddev->raid_disks) {
+ rdev->raid_disk = -1;
+ clear_bit(In_sync, &rdev->flags);
}
}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index dfe32149ad3..2c404f73a37 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -415,7 +415,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
raid0_conf_t *conf = mddev_to_conf(mddev);
struct strip_zone *zone;
mdk_rdev_t *tmp_dev;
- unsigned long chunk;
+ sector_t chunk;
sector_t block, rsect;
const int rw = bio_data_dir(bio);
@@ -470,7 +470,6 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
sector_div(x, zone->nb_dev);
chunk = x;
- BUG_ON(x != (sector_t)chunk);
x = block >> chunksize_bits;
tmp_dev = zone->dev[sector_div(x, zone->nb_dev)];
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index c120114c241..5c63c8e24ee 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -4,5 +4,6 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV
tristate
+ depends on VIDEO_DEV
select VIDEO_BUF
select VIDEO_SAA7146
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 1a1c3bca55f..bff00b58bf6 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -1,8 +1,11 @@
b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
- flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o \
- flexcop-dma.o
+ flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
+ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
+b2c2-flexcop-objs += flexcop-dma.o
+endif
+
b2c2-flexcop-pci-objs = flexcop-pci.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 0393a3d1992..e908e3cf1e5 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1721,9 +1721,6 @@ static void dst_release(struct dvb_frontend *fe)
symbol_put(dst_ca_attach);
#endif
}
-#ifdef CONFIG_DVB_CORE_ATTACH
- symbol_put(dst_attach);
-#endif
kfree(state);
}
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 34d7abc900d..6aba5b39ed1 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -519,8 +519,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct cinergyt2 *cinergyt2 = dvbdev->priv;
- if (mutex_lock_interruptible(&cinergyt2->sem))
- return -ERESTARTSYS;
+ mutex_lock(&cinergyt2->sem);
if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
cancel_delayed_work(&cinergyt2->query_work);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index e23d8a0ea1d..a9fa3337dd8 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -200,7 +200,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
{
struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
-
+ struct class_device *clsdev;
int id;
mutex_lock(&dvbdev_register_lock);
@@ -242,8 +242,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
mutex_unlock(&dvbdev_register_lock);
- class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
- adap->device, "dvb%d.%s%d", adap->num, dnames[type], id);
+ clsdev = class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR,
+ nums2minor(adap->num, type, id)),
+ adap->device, "dvb%d.%s%d", adap->num,
+ dnames[type], id);
+ if (IS_ERR(clsdev)) {
+ printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
+ __FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev));
+ return PTR_ERR(clsdev);
+ }
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
adap->num, dnames[type], id, nums2minor(adap->num, type, id),
@@ -431,7 +438,7 @@ static void __exit exit_dvbdev(void)
unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
}
-module_init(init_dvbdev);
+subsys_initcall(init_dvbdev);
module_exit(exit_dvbdev);
MODULE_DESCRIPTION("DVB Core Driver");
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
index ccc429cbbad..0f2d4b41556 100644
--- a/drivers/media/dvb/frontends/tda10086.c
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -41,6 +41,7 @@ struct tda10086_state {
/* private demod data */
u32 frequency;
u32 symbol_rate;
+ bool has_lock;
};
static int debug = 0;
@@ -116,7 +117,7 @@ static int tda10086_init(struct dvb_frontend* fe)
// misc setup
tda10086_write_byte(state, 0x01, 0x94);
tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
- tda10086_write_byte(state, 0x03, 0x64);
+ tda10086_write_byte(state, 0x03, 0xe4);
tda10086_write_byte(state, 0x04, 0x43);
tda10086_write_byte(state, 0x0c, 0x0c);
tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
@@ -146,7 +147,7 @@ static int tda10086_init(struct dvb_frontend* fe)
// setup AGC
tda10086_write_byte(state, 0x05, 0x0B);
tda10086_write_byte(state, 0x37, 0x63);
- tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it
+ tda10086_write_byte(state, 0x3f, 0x0a); // NOTE: flydvb varies it
tda10086_write_byte(state, 0x40, 0x64);
tda10086_write_byte(state, 0x41, 0x4f);
tda10086_write_byte(state, 0x42, 0x43);
@@ -398,6 +399,10 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
dprintk ("%s\n", __FUNCTION__);
+ // modify parameters for tuning
+ tda10086_write_byte(state, 0x02, 0x35);
+ state->has_lock = false;
+
// set params
if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, fe_params);
@@ -542,8 +547,14 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
*fe_status |= FE_HAS_VITERBI;
if (val & 0x08)
*fe_status |= FE_HAS_SYNC;
- if (val & 0x10)
+ if (val & 0x10) {
*fe_status |= FE_HAS_LOCK;
+ if (!state->has_lock) {
+ state->has_lock = true;
+ // modify parameters for stable reception
+ tda10086_write_byte(state, 0x02, 0x00);
+ }
+ }
return 0;
}
@@ -555,7 +566,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
dprintk ("%s\n", __FUNCTION__);
- _str = tda10086_read_byte(state, 0x43);
+ _str = 0xff - tda10086_read_byte(state, 0x43);
*signal = (_str << 8) | _str;
return 0;
@@ -568,7 +579,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
dprintk ("%s\n", __FUNCTION__);
- _snr = tda10086_read_byte(state, 0x1c);
+ _snr = 0xff - tda10086_read_byte(state, 0x1c);
*snr = (_snr << 8) | _snr;
return 0;
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
index 79f971dc52b..bd3ebc28483 100644
--- a/drivers/media/dvb/frontends/tda826x.c
+++ b/drivers/media/dvb/frontends/tda826x.c
@@ -89,8 +89,8 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
buf[3] = div >> 7;
buf[4] = div << 1;
- buf[5] = 0xff; // basedband filter to max
- buf[6] = 0xfe; // gains at max + no RF attenuation
+ buf[5] = 0x77; // baseband cut-off 19 MHz
+ buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
buf[7] = 0x83; // charge pumps at high, tests off
buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 5cb3f54b548..4cca55170e2 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -347,7 +347,7 @@ endmenu # encoder / decoder chips
config VIDEO_VIVI
tristate "Virtual Video Driver"
- depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
+ depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI && VIDEO_DEV
select VIDEO_BUF
default n
---help---
diff --git a/drivers/media/video/cafe_ccic-regs.h b/drivers/media/video/cafe_ccic-regs.h
index b2c22a0d664..8e2a87cdc79 100644
--- a/drivers/media/video/cafe_ccic-regs.h
+++ b/drivers/media/video/cafe_ccic-regs.h
@@ -150,6 +150,12 @@
#define REG_GL_IMASK 0x300c /* Interrupt mask register */
#define GIMSK_CCIC_EN 0x00000004 /* CCIC Interrupt enable */
+#define REG_GL_FCR 0x3038 /* GPIO functional control register */
+#define GFCR_GPIO_ON 0x08 /* Camera GPIO enabled */
+#define REG_GL_GPIOR 0x315c /* GPIO register */
+#define GGPIO_OUT 0x80000 /* GPIO output */
+#define GGPIO_VAL 0x00008 /* Output pin value */
+
#define REG_LEN REG_GL_IMASK + 4
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 96254dbaf62..c08f650df42 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -775,6 +775,12 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam)
spin_lock_irqsave(&cam->dev_lock, flags);
cafe_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
/*
+ * Part one of the sensor dance: turn the global
+ * GPIO signal on.
+ */
+ cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON);
+ cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL);
+ /*
* Put the sensor into operational mode (assumes OLPC-style
* wiring). Control 0 is reset - set to 1 to operate.
* Control 1 is power down, set to 0 to operate.
@@ -784,6 +790,7 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam)
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
// mdelay(1); /* Enough? */
spin_unlock_irqrestore(&cam->dev_lock, flags);
+ msleep(5); /* Just to be sure */
}
static void cafe_ctlr_power_down(struct cafe_camera *cam)
@@ -792,6 +799,8 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam)
spin_lock_irqsave(&cam->dev_lock, flags);
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1);
+ cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON);
+ cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT);
cafe_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN);
spin_unlock_irqrestore(&cam->dev_lock, flags);
}
@@ -851,6 +860,7 @@ static int cafe_cam_init(struct cafe_camera *cam)
ret = 0;
cam->state = S_IDLE;
out:
+ cafe_ctlr_power_down(cam);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -2103,10 +2113,16 @@ static int cafe_pci_probe(struct pci_dev *pdev,
ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
if (ret)
goto out_iounmap;
+ /*
+ * Initialize the controller and leave it powered up. It will
+ * stay that way until the sensor driver shows up.
+ */
cafe_ctlr_init(cam);
cafe_ctlr_power_up(cam);
/*
- * Set up I2C/SMBUS communications
+ * Set up I2C/SMBUS communications. We have to drop the mutex here
+ * because the sensor could attach in this call chain, leading to
+ * unsightly deadlocks.
*/
mutex_unlock(&cam->s_mutex); /* attach can deadlock */
ret = cafe_smbus_setup(cam);
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 2c450bd05af..5b6a4037160 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,7 +1,6 @@
config VIDEO_EM28XX
tristate "Empia EM2800/2820/2840 USB video capture support"
- depends on VIDEO_V4L1 && I2C && PCI
- select VIDEO_BUF
+ depends on VIDEO_V4L1 && I2C
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_IR
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index 0cc98a0e249..1aaeaa02f15 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_IVTV
tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
- depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL && PCI
+ depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 15012f88b80..91e9e90c14a 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -86,7 +86,7 @@
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
V4L2_CAP_SLICED_VBI_CAPTURE)
#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \
- V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS)
+ V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
struct ivtv_card_video_input {
u8 video_type; /* video input type */
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index e29f949adf5..efc66355339 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -652,6 +652,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
itv->dma_timer.data = (unsigned long)itv;
itv->cur_dma_stream = -1;
+ itv->cur_pio_stream = -1;
itv->audio_stereo_mode = AUDIO_STEREO;
itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 9a412d6c6d0..e6e56f175f3 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -67,14 +67,6 @@
#include <media/ivtv.h>
-#ifdef CONFIG_LIRC_I2C
-# error "This driver is not compatible with the LIRC I2C kernel configuration option."
-#endif /* CONFIG_LIRC_I2C */
-
-#ifndef CONFIG_PCI
-# error "This driver requires kernel PCI support."
-#endif /* CONFIG_PCI */
-
#define IVTV_ENCODER_OFFSET 0x00000000
#define IVTV_ENCODER_SIZE 0x00800000 /* Last half isn't needed 0x01000000 */
@@ -245,6 +237,7 @@ extern const u32 yuv_offset[4];
#define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29)
#define IVTV_IRQ_ENC_VIM_RST (0x1 << 28)
#define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27)
+#define IVTV_IRQ_ENC_PIO_COMPLETE (0x1 << 25)
#define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24)
#define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22)
#define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20)
@@ -255,7 +248,8 @@ extern const u32 yuv_offset[4];
#define IVTV_IRQ_DEC_VSYNC (0x1 << 10)
/* IRQ Masks */
-#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|IVTV_IRQ_DMA_READ)
+#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
+ IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
#define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
@@ -382,6 +376,9 @@ struct ivtv_mailbox_data {
#define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */
#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */
+#define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */
+#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */
+
/* per-ivtv, i_flags */
#define IVTV_F_I_DMA 0 /* DMA in progress */
#define IVTV_F_I_UDMA 1 /* UDMA in progress */
@@ -398,8 +395,11 @@ struct ivtv_mailbox_data {
#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
-#define IVTV_F_I_WORK_HANDLER_VBI 15 /* there is work to be done for VBI */
-#define IVTV_F_I_WORK_HANDLER_YUV 16 /* there is work to be done for YUV */
+#define IVTV_F_I_HAVE_WORK 15 /* Used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */
+#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */
+#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */
+#define IVTV_F_I_PIO 19 /* PIO in progress */
/* Event notifications */
#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
@@ -492,6 +492,7 @@ struct ivtv_stream {
/* Base Dev SG Array for cx23415/6 */
struct ivtv_SG_element *SGarray;
+ struct ivtv_SG_element *PIOarray;
dma_addr_t SG_handle;
int SG_length;
@@ -714,6 +715,7 @@ struct ivtv {
atomic_t decoding; /* count number of active decoding streams */
u32 irq_rr_idx; /* Round-robin stream index */
int cur_dma_stream; /* index of stream doing DMA */
+ int cur_pio_stream; /* index of stream doing PIO */
u32 dma_data_req_offset;
u32 dma_data_req_size;
int output_mode; /* NONE, MPG, YUV, UDMA YUV, passthrough */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 8976487a65f..555d5e6369c 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -32,6 +32,8 @@
#include "ivtv-yuv.h"
#include "ivtv-controls.h"
#include "ivtv-ioctl.h"
+#include "ivtv-cards.h"
+#include <media/saa7115.h>
/* This function tries to claim the stream for a specific file descriptor.
If no one else is using this stream then the stream is claimed and
@@ -786,6 +788,13 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
ivtv_audio_set_io(itv);
+ if (itv->hw_flags & IVTV_HW_SAA711X)
+ {
+ struct v4l2_crystal_freq crystal_freq;
+ crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+ crystal_freq.flags = 0;
+ ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+ }
/* Done! Unmute and continue. */
ivtv_unmute(itv);
ivtv_release_stream(s);
@@ -872,6 +881,13 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
/* Select the correct audio input (i.e. radio tuner) */
ivtv_audio_set_io(itv);
+ if (itv->hw_flags & IVTV_HW_SAA711X)
+ {
+ struct v4l2_crystal_freq crystal_freq;
+ crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
+ crystal_freq.flags = SAA7115_FREQ_FL_APLL;
+ ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+ }
/* Done! Unmute and continue. */
ivtv_unmute(itv);
}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 794a6a02f82..57af1762de1 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -362,8 +362,6 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL;
- fmt->fmt.pix.left = itv->main_rect.left;
- fmt->fmt.pix.top = itv->main_rect.top;
fmt->fmt.pix.width = itv->main_rect.width;
fmt->fmt.pix.height = itv->main_rect.height;
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
@@ -402,8 +400,6 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- fmt->fmt.pix.left = 0;
- fmt->fmt.pix.top = 0;
fmt->fmt.pix.width = itv->params.width;
fmt->fmt.pix.height = itv->params.height;
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
@@ -498,15 +494,13 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL;
field = fmt->fmt.pix.field;
- r.top = fmt->fmt.pix.top;
- r.left = fmt->fmt.pix.left;
+ r.top = 0;
+ r.left = 0;
r.width = fmt->fmt.pix.width;
r.height = fmt->fmt.pix.height;
ivtv_get_fmt(itv, streamtype, fmt);
if (itv->output_mode != OUT_UDMA_YUV) {
/* TODO: would setting the rect also be valid for this mode? */
- fmt->fmt.pix.top = r.top;
- fmt->fmt.pix.left = r.left;
fmt->fmt.pix.width = r.width;
fmt->fmt.pix.height = r.height;
}
@@ -538,11 +532,6 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
itv->yuv_info.yuv_forced_update = 1;
return 0;
}
- if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- r.width, r.height, r.left, r.top))
- itv->main_rect = r;
- else
- return -EINVAL;
}
return 0;
}
@@ -805,9 +794,39 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return ivtv_get_fmt(itv, id->type, fmt);
}
+ case VIDIOC_CROPCAP: {
+ struct v4l2_cropcap *cropcap = arg;
+
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ cropcap->bounds.top = cropcap->bounds.left = 0;
+ cropcap->bounds.width = 720;
+ if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ cropcap->bounds.height = itv->is_50hz ? 576 : 480;
+ cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
+ } else {
+ cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
+ cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+ }
+ cropcap->defrect = cropcap->bounds;
+ return 0;
+ }
+
case VIDIOC_S_CROP: {
struct v4l2_crop *crop = arg;
+ if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+ if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+ crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
+ itv->main_rect = crop->c;
+ return 0;
+ }
+ return -EINVAL;
+ }
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
@@ -816,6 +835,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
case VIDIOC_G_CROP: {
struct v4l2_crop *crop = arg;
+ if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+ crop->c = itv->main_rect;
+ return 0;
+ }
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
@@ -983,7 +1007,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
if (itv->hw_flags & IVTV_HW_CX25840) {
itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
}
- IVTV_DEBUG_INFO("Switching standard to %llx.\n", itv->std);
+ IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
/* Tuner */
ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
@@ -1141,8 +1165,6 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
fb->fmt.pixelformat = itv->osd_pixelformat;
fb->fmt.width = itv->osd_rect.width;
fb->fmt.height = itv->osd_rect.height;
- fb->fmt.left = itv->osd_rect.left;
- fb->fmt.top = itv->osd_rect.top;
fb->base = (void *)itv->osd_video_pbase;
if (itv->osd_global_alpha_state)
fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
@@ -1215,7 +1237,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
(s->buffers - s->q_free.buffers) * 100 / s->buffers,
(s->buffers * s->buf_size) / 1024, s->buffers);
}
- IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", itv->mpg_data_received, itv->vbi_data_inserted);
+ IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
break;
}
@@ -1463,6 +1485,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
case VIDIOC_ENUM_FMT:
+ case VIDIOC_CROPCAP:
case VIDIOC_G_CROP:
case VIDIOC_S_CROP:
case VIDIOC_G_FREQUENCY:
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index c3a047b381b..ba98bf054f2 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -31,8 +31,6 @@
#define DMA_MAGIC_COOKIE 0x000001fe
-#define SLICED_VBI_PIO 1
-
static void ivtv_dma_dec_start(struct ivtv_stream *s);
static const int ivtv_stream_map[] = {
@@ -42,12 +40,40 @@ static const int ivtv_stream_map[] = {
IVTV_ENC_STREAM_TYPE_VBI,
};
-static inline int ivtv_use_pio(struct ivtv_stream *s)
+
+static void ivtv_pio_work_handler(struct ivtv *itv)
{
- struct ivtv *itv = s->itv;
+ struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
+ struct ivtv_buffer *buf;
+ struct list_head *p;
+ int i = 0;
+
+ IVTV_DEBUG_DMA("ivtv_pio_work_handler\n");
+ if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
+ s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+ itv->cur_pio_stream = -1;
+ /* trigger PIO complete user interrupt */
+ write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
+ return;
+ }
+ IVTV_DEBUG_DMA("Process PIO %s\n", s->name);
+ buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list);
+ list_for_each(p, &s->q_dma.list) {
+ struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
+ u32 size = s->PIOarray[i].size & 0x3ffff;
- return s->dma == PCI_DMA_NONE ||
- (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+ /* Copy the data from the card to the buffer */
+ if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
+ memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size);
+ }
+ else {
+ memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size);
+ }
+ if (s->PIOarray[i].size & 0x80000000)
+ break;
+ i++;
+ }
+ write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
}
void ivtv_irq_work_handler(struct work_struct *work)
@@ -56,8 +82,11 @@ void ivtv_irq_work_handler(struct work_struct *work)
DEFINE_WAIT(wait);
+ if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
+ ivtv_pio_work_handler(itv);
+
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
- vbi_work_handler(itv);
+ ivtv_vbi_work_handler(itv);
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
ivtv_yuv_work_handler(itv);
@@ -173,8 +202,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
}
s->buffers_stolen = rc;
- /* got the buffers, now fill in SGarray (DMA) or copy the data from the card
- to the buffers (PIO). */
+ /* got the buffers, now fill in SGarray (DMA) */
buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
memset(buf->buf, 0, 128);
list_for_each(p, &s->q_predma.list) {
@@ -182,21 +210,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
if (skip_bufs-- > 0)
continue;
- if (!ivtv_use_pio(s)) {
- s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
- s->SGarray[idx].src = cpu_to_le32(offset);
- s->SGarray[idx].size = cpu_to_le32(s->buf_size);
- }
+ s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
+ s->SGarray[idx].src = cpu_to_le32(offset);
+ s->SGarray[idx].size = cpu_to_le32(s->buf_size);
buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
- /* If PIO, then copy the data from the card to the buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- memcpy_fromio(buf->buf, itv->dec_mem + offset - IVTV_DECODER_OFFSET, buf->bytesused);
- }
- else if (ivtv_use_pio(s)) {
- memcpy_fromio(buf->buf, itv->enc_mem + offset, buf->bytesused);
- }
-
s->q_predma.bytesused += buf->bytesused;
size -= buf->bytesused;
offset += s->buf_size;
@@ -224,11 +242,6 @@ static void dma_post(struct ivtv_stream *s)
u32 *u32buf;
int x = 0;
- if (ivtv_use_pio(s)) {
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- s->SG_length = 0;
- }
IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
s->name, s->dma_offset);
list_for_each(p, &s->q_dma.list) {
@@ -278,10 +291,14 @@ static void dma_post(struct ivtv_stream *s)
if (buf)
buf->bytesused += s->dma_last_offset;
if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- /* Parse and Groom VBI Data */
- s->q_dma.bytesused -= buf->bytesused;
- ivtv_process_vbi_data(itv, buf, 0, s->type);
- s->q_dma.bytesused += buf->bytesused;
+ list_for_each(p, &s->q_dma.list) {
+ buf = list_entry(p, struct ivtv_buffer, list);
+
+ /* Parse and Groom VBI Data */
+ s->q_dma.bytesused -= buf->bytesused;
+ ivtv_process_vbi_data(itv, buf, 0, s->type);
+ s->q_dma.bytesused += buf->bytesused;
+ }
if (s->id == -1) {
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
return;
@@ -351,10 +368,14 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
int i;
+ IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
+
if (s->q_predma.bytesused)
ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- IVTV_DEBUG_DMA("start DMA for %s\n", s->name);
- s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
+
+ if (ivtv_use_dma(s))
+ s->SGarray[s->SG_length - 1].size =
+ cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
/* If this is an MPEG stream, and VBI data is also pending, then append the
VBI DMA to the MPEG DMA and transfer both sets of data at once.
@@ -368,7 +389,8 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
s->SG_length + s_vbi->SG_length <= s->buffers) {
ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
- s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
+ if (ivtv_use_dma(s_vbi))
+ s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
for (i = 0; i < s_vbi->SG_length; i++) {
s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
}
@@ -381,14 +403,26 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
/* Mark last buffer size for Interrupt flag */
s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = s->type;
- itv->dma_timer.expires = jiffies + HZ / 10;
- add_timer(&itv->dma_timer);
+ if (ivtv_use_pio(s)) {
+ for (i = 0; i < s->SG_length; i++) {
+ s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
+ s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size);
+ }
+ set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
+ set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
+ set_bit(IVTV_F_I_PIO, &itv->i_flags);
+ itv->cur_pio_stream = s->type;
+ }
+ else {
+ /* Sync Hardware SG List of buffers */
+ ivtv_stream_sync_for_device(s);
+ write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
+ write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
+ set_bit(IVTV_F_I_DMA, &itv->i_flags);
+ itv->cur_dma_stream = s->type;
+ itv->dma_timer.expires = jiffies + HZ / 10;
+ add_timer(&itv->dma_timer);
+ }
}
static void ivtv_dma_dec_start(struct ivtv_stream *s)
@@ -489,6 +523,40 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
wake_up(&itv->dma_waitq);
}
+static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
+{
+ struct ivtv_stream *s;
+
+ if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
+ itv->cur_pio_stream = -1;
+ return;
+ }
+ s = &itv->streams[itv->cur_pio_stream];
+ IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name);
+ s->SG_length = 0;
+ clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+ clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+ itv->cur_pio_stream = -1;
+ dma_post(s);
+ if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
+ ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
+ else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
+ ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
+ else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
+ ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
+ clear_bit(IVTV_F_I_PIO, &itv->i_flags);
+ if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
+ u32 tmp;
+
+ s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
+ tmp = s->dma_offset;
+ s->dma_offset = itv->vbi.dma_offset;
+ dma_post(s);
+ s->dma_offset = tmp;
+ }
+ wake_up(&itv->dma_waitq);
+}
+
static void ivtv_irq_dma_err(struct ivtv *itv)
{
u32 data[CX2341X_MBOX_MAX_DATA];
@@ -532,13 +600,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
s = &itv->streams[ivtv_stream_map[data[0]]];
if (!stream_enc_dma_append(s, data)) {
- if (ivtv_use_pio(s)) {
- dma_post(s);
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[0]);
- }
- else {
- set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
- }
+ set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
}
}
@@ -551,15 +613,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
IVTV_DEBUG_IRQ("ENC START VBI CAP\n");
s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- if (ivtv_use_pio(s)) {
- if (stream_enc_dma_append(s, data))
- return;
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- s->SG_length = 0;
- dma_post(s);
- return;
- }
/* If more than two VBI buffers are pending, then
clear the old ones and start with this new one.
This can happen during transition stages when MPEG capturing is
@@ -582,11 +635,11 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
if (!stream_enc_dma_append(s, data) &&
!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
- set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
+ set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
}
}
-static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
+static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
{
u32 data[CX2341X_MBOX_MAX_DATA];
struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
@@ -594,7 +647,7 @@ static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
IVTV_DEBUG_IRQ("DEC VBI REINSERT\n");
if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
!stream_enc_dma_append(s, data)) {
- dma_post(s);
+ set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
}
}
@@ -657,7 +710,6 @@ static void ivtv_irq_vsync(struct ivtv *itv)
}
if (frame != (itv->lastVsyncFrame & 1)) {
struct ivtv_stream *s = ivtv_get_output_stream(itv);
- int work = 0;
itv->lastVsyncFrame += 1;
if (frame == 0) {
@@ -678,7 +730,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
/* Send VBI to saa7127 */
if (frame) {
set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
- work = 1;
+ set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
}
/* Check if we need to update the yuv registers */
@@ -691,11 +743,9 @@ static void ivtv_irq_vsync(struct ivtv *itv)
itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
itv->yuv_info.yuv_forced_update = 0;
set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
- work = 1;
+ set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
}
}
- if (work)
- queue_work(itv->irq_work_queues, &itv->irq_work_queue);
}
}
@@ -755,6 +805,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
ivtv_irq_enc_dma_complete(itv);
}
+ if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
+ ivtv_irq_enc_pio_complete(itv);
+ }
+
if (combo & IVTV_IRQ_DMA_ERR) {
ivtv_irq_dma_err(itv);
}
@@ -768,7 +822,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
}
if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
- ivtv_irq_dev_vbi_reinsert(itv);
+ ivtv_irq_dec_vbi_reinsert(itv);
}
if (combo & IVTV_IRQ_ENC_EOS) {
@@ -813,6 +867,22 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
}
}
+ if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
+ for (i = 0; i < IVTV_MAX_STREAMS; i++) {
+ int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
+ struct ivtv_stream *s = &itv->streams[idx];
+
+ if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
+ continue;
+ if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
+ ivtv_dma_enc_start(s);
+ break;
+ }
+ }
+
+ if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags))
+ queue_work(itv->irq_work_queues, &itv->irq_work_queue);
+
spin_unlock(&itv->dma_reg_lock);
/* If we've just handled a 'forced' vsync, it's safest to say it
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index ccfcef1ad91..a04f9387f63 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -195,14 +195,26 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
s->dma != PCI_DMA_NONE ? "DMA " : "",
s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
- /* Allocate DMA SG Arrays */
- if (s->dma != PCI_DMA_NONE) {
- s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
- if (s->SGarray == NULL) {
- IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+ if (ivtv_might_use_pio(s)) {
+ s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+ if (s->PIOarray == NULL) {
+ IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name);
return -ENOMEM;
}
- s->SG_length = 0;
+ }
+
+ /* Allocate DMA SG Arrays */
+ s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
+ if (s->SGarray == NULL) {
+ IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
+ if (ivtv_might_use_pio(s)) {
+ kfree(s->PIOarray);
+ s->PIOarray = NULL;
+ }
+ return -ENOMEM;
+ }
+ s->SG_length = 0;
+ if (ivtv_might_use_dma(s)) {
s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
ivtv_stream_sync_for_cpu(s);
}
@@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
break;
}
INIT_LIST_HEAD(&buf->list);
- if (s->dma != PCI_DMA_NONE) {
+ if (ivtv_might_use_dma(s)) {
buf->dma_handle = pci_map_single(s->itv->dev,
buf->buf, s->buf_size + 256, s->dma);
ivtv_buf_sync_for_cpu(s, buf);
@@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* empty q_free */
while ((buf = ivtv_dequeue(s, &s->q_free))) {
- if (s->dma != PCI_DMA_NONE)
+ if (ivtv_might_use_dma(s))
pci_unmap_single(s->itv->dev, buf->dma_handle,
s->buf_size + 256, s->dma);
kfree(buf->buf);
@@ -256,6 +268,9 @@ void ivtv_stream_free(struct ivtv_stream *s)
sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
s->SG_handle = IVTV_DMA_UNMAPPED;
}
+ kfree(s->SGarray);
+ kfree(s->PIOarray);
+ s->PIOarray = NULL;
s->SGarray = NULL;
s->SG_length = 0;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
index 903edd4b438..2ed8d548255 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -20,18 +20,43 @@
*/
#define IVTV_DMA_UNMAPPED ((u32) -1)
+#define SLICED_VBI_PIO 1
/* ivtv_buffer utility functions */
+
+static inline int ivtv_might_use_pio(struct ivtv_stream *s)
+{
+ return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI);
+}
+
+static inline int ivtv_use_pio(struct ivtv_stream *s)
+{
+ struct ivtv *itv = s->itv;
+
+ return s->dma == PCI_DMA_NONE ||
+ (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
+}
+
+static inline int ivtv_might_use_dma(struct ivtv_stream *s)
+{
+ return s->dma != PCI_DMA_NONE;
+}
+
+static inline int ivtv_use_dma(struct ivtv_stream *s)
+{
+ return !ivtv_use_pio(s);
+}
+
static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
- if (s->dma != PCI_DMA_NONE)
+ if (ivtv_use_dma(s))
pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
- if (s->dma != PCI_DMA_NONE)
+ if (ivtv_use_dma(s))
pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
@@ -53,12 +78,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
{
- pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
- sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+ if (ivtv_use_dma(s))
+ pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
+ sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
}
static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
{
- pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
- sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+ if (ivtv_use_dma(s))
+ pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
+ sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 01a41a844a3..6af88ae9295 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -868,7 +868,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
return 0;
- IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", pts, flags);
+ IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
/* Stop Decoder */
if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 5efa5a86781..3ba46e07ea1 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -450,7 +450,7 @@ void ivtv_disable_vbi(struct ivtv *itv)
}
-void vbi_work_handler(struct ivtv *itv)
+void ivtv_vbi_work_handler(struct ivtv *itv)
{
struct v4l2_sliced_vbi_data data;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
index cdaea697b3e..ec211b49702 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ b/drivers/media/video/ivtv/ivtv-vbi.h
@@ -23,4 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
int ivtv_used_line(struct ivtv *itv, int line, int field);
void ivtv_disable_vbi(struct ivtv *itv);
void ivtv_set_vbi(unsigned long arg);
-void vbi_work_handler(struct ivtv *itv);
+void ivtv_vbi_work_handler(struct ivtv *itv);
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 03bc369a9e4..3ceb8a6249d 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -720,12 +720,22 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
struct ov7670_format_struct *ovfmt;
struct ov7670_win_size *wsize;
struct ov7670_info *info = i2c_get_clientdata(c);
- unsigned char com7;
+ unsigned char com7, clkrc;
ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize);
if (ret)
return ret;
/*
+ * HACK: if we're running rgb565 we need to grab then rewrite
+ * CLKRC. If we're *not*, however, then rewriting clkrc hoses
+ * the colors.
+ */
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
+ ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ if (ret)
+ return ret;
+ }
+ /*
* COM7 is a pain in the ass, it doesn't like to be read then
* quickly written afterward. But we have everything we need
* to set it absolutely here, as long as the format-specific
@@ -744,7 +754,10 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
if (wsize->regs)
ret = ov7670_write_array(c, wsize->regs);
info->fmt = ovfmt;
- return 0;
+
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0)
+ ret = ov7670_write(c, REG_CLKRC, clkrc);
+ return ret;
}
/*
@@ -1267,7 +1280,9 @@ static int ov7670_attach(struct i2c_adapter *adapter)
ret = ov7670_detect(client);
if (ret)
goto out_free_info;
- i2c_attach_client(client);
+ ret = i2c_attach_client(client);
+ if (ret)
+ goto out_free_info;
return 0;
out_free_info:
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
index 74839f98b7c..c1a392e4717 100644
--- a/drivers/media/video/saa7111.c
+++ b/drivers/media/video/saa7111.c
@@ -75,10 +75,6 @@ struct saa7111 {
int norm;
int input;
int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
#define I2C_SAA7111 0x48
@@ -96,6 +92,17 @@ saa7111_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
+static inline void
+saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
+{
+ struct saa7111 *decoder = i2c_get_clientdata(client);
+
+ if (decoder->reg[reg] != value) {
+ decoder->reg[reg] = value;
+ i2c_smbus_write_byte_data(client, reg, value);
+ }
+}
+
static int
saa7111_write_block (struct i2c_client *client,
const u8 *data,
@@ -439,28 +446,14 @@ saa7111_command (struct i2c_client *client,
{
struct video_picture *pic = arg;
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7111_write(client, 0x0a, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7111_write(client, 0x0b,
- decoder->contrast >> 9);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7111_write(client, 0x0c, decoder->sat >> 9);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7111_write(client, 0x0d,
- (decoder->hue - 32768) >> 8);
- }
+ /* We want 0 to 255 we get 0-65535 */
+ saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
+ /* We want 0 to 127 we get 0-65535 */
+ saa7111_write(client, 0x0b, pic->contrast >> 9);
+ /* We want 0 to 127 we get 0-65535 */
+ saa7111_write(client, 0x0c, pic->colour >> 9);
+ /* We want -128 to 127 we get 0-65535 */
+ saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
}
break;
@@ -524,10 +517,6 @@ saa7111_detect_client (struct i2c_adapter *adapter,
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = 0;
decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
i2c_set_clientdata(client, decoder);
i = i2c_attach_client(client);
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 1b9b0742f75..c40b92ce1fa 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -205,9 +205,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
/* 0x01 -> ??? no change ??? */
/* 0x02 -> PAL BDGHI / SECAM L */
/* 0x04 -> ??? PAL others / SECAM others ??? */
- cb &= ~0x02;
- if (t->std & V4L2_STD_SECAM)
- cb |= 0x02;
+ cb &= ~0x03;
+ if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM
+ cb |= PHILIPS_MF_SET_PAL_L;
+ else if (t->std & V4L2_STD_SECAM_LC)
+ cb |= PHILIPS_MF_SET_PAL_L2;
+ else /* V4L2_STD_B|V4L2_STD_GH */
+ cb |= PHILIPS_MF_SET_BG;
break;
case TUNER_TEMIC_4046FM5:
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 9118a6227ea..7df071eb0a3 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -1414,6 +1414,11 @@ static void usbvision_isocIrq(struct urb *urb)
if (!USBVISION_IS_OPERATIONAL(usbvision))
return;
+ /* any urb with wrong status is ignored without acknowledgement */
+ if (urb->status == -ENOENT) {
+ return;
+ }
+
f = &usbvision->curFrame;
/* Manage streaming interruption */
@@ -1436,18 +1441,21 @@ static void usbvision_isocIrq(struct urb *urb)
if (usbvision->streaming == Stream_On) {
/* If we collected enough data let's parse! */
- if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH) { /* 12 == header_length */
- /*If we don't have a frame we're current working on, complain */
- if(!list_empty(&(usbvision->inqueue))) {
- if (!(*f)) {
- (*f) = list_entry(usbvision->inqueue.next,struct usbvision_frame, frame);
- }
- usbvision_parse_data(usbvision);
- }
- else {
- PDEBUG(DBG_IRQ, "received data, but no one needs it");
- scratch_reset(usbvision);
+ if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
+ (!list_empty(&(usbvision->inqueue))) ) {
+ if (!(*f)) {
+ (*f) = list_entry(usbvision->inqueue.next,
+ struct usbvision_frame,
+ frame);
}
+ usbvision_parse_data(usbvision);
+ }
+ else {
+ /*If we don't have a frame
+ we're current working on, complain */
+ PDEBUG(DBG_IRQ,
+ "received data, but no one needs it");
+ scratch_reset(usbvision);
}
}
else {
@@ -1466,10 +1474,10 @@ static void usbvision_isocIrq(struct urb *urb)
urb->dev = usbvision->dev;
errCode = usb_submit_urb (urb, GFP_ATOMIC);
- /* Disable this warning. By design of the driver. */
- // if(errCode) {
- // err("%s: usb_submit_urb failed: error %d", __FUNCTION__, errCode);
- // }
+ if(errCode) {
+ err("%s: usb_submit_urb failed: error %d",
+ __FUNCTION__, errCode);
+ }
return;
}
@@ -2394,7 +2402,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
{
struct usb_device *dev = usbvision->dev;
int bufIdx, errCode, regValue;
- const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+ int sb_size;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return -EFAULT;
@@ -2408,11 +2416,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
usbvision->last_error = errCode;
return -EBUSY;
}
+ sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
- regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+ regValue = (16 - usbvision_read_reg(usbvision,
+ USBVISION_ALTER_REG)) & 0x0F;
usbvision->usb_bandwidth = regValue >> 1;
- PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+ PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+ usbvision->usb_bandwidth);
@@ -2428,7 +2439,11 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
return -ENOMEM;
}
usbvision->sbuf[bufIdx].urb = urb;
- usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma);
+ usbvision->sbuf[bufIdx].data =
+ usb_buffer_alloc(usbvision->dev,
+ sb_size,
+ GFP_KERNEL,
+ &urb->transfer_dma);
urb->dev = dev;
urb->context = usbvision;
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
@@ -2442,21 +2457,26 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
k += usbvision->isocPacketSize) {
urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length = usbvision->isocPacketSize;
+ urb->iso_frame_desc[j].length =
+ usbvision->isocPacketSize;
}
}
/* Submit all URBs */
for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
- errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL);
+ errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
+ GFP_KERNEL);
if (errCode) {
- err("%s: usb_submit_urb(%d) failed: error %d", __FUNCTION__, bufIdx, errCode);
+ err("%s: usb_submit_urb(%d) failed: error %d",
+ __FUNCTION__, bufIdx, errCode);
}
}
usbvision->streaming = Stream_Idle;
- PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
+ PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
+ __FUNCTION__,
+ usbvision->video_endp);
return 0;
}
@@ -2470,7 +2490,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
void usbvision_stop_isoc(struct usb_usbvision *usbvision)
{
int bufIdx, errCode, regValue;
- const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
+ int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
return;
@@ -2499,15 +2519,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->ifaceAlt);
if (errCode < 0) {
- err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
+ err("%s: usb_set_interface() failed: error %d",
+ __FUNCTION__, errCode);
usbvision->last_error = errCode;
}
- regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
- usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
- PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
+ regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
+ usbvision->isocPacketSize =
+ (regValue == 0) ? 0 : (regValue * 64) - 1;
+ PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
+ usbvision->isocPacketSize);
usbvision->usb_bandwidth = regValue >> 1;
- PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
+ PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
+ usbvision->usb_bandwidth);
}
}
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index bd6f6422ed5..c759d00d701 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -146,7 +146,6 @@
#define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask
#define USBVISION_URB_FRAMES 32
-#define USBVISION_MAX_ISOC_PACKET_SIZE 959 // NT1003 Specs Document says 1023
#define USBVISION_NUM_HEADERMARKER 20
#define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index d25d3be8fcd..165f81d16d0 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -436,7 +436,7 @@ typedef struct _MPT_SAS_MGMT {
typedef struct _mpt_ioctl_events {
u32 event; /* Specified by define above */
u32 eventContext; /* Index or counter */
- int data[2]; /* First 8 bytes of Event Data */
+ u32 data[2]; /* First 8 bytes of Event Data */
} MPT_IOCTL_EVENTS;
/*
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index fa0f7761652..3bd94f11e7d 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -2463,11 +2463,11 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR
ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
ioc->events[idx].eventContext = ioc->eventContext;
- ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
- (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
- (sc->device->channel << 8) || sc->device->id;
+ ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
+ (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
+ (sc->device->channel << 8) | sc->device->id;
- ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
+ ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
ioc->eventContext++;
if (hd->ioc->pcidev->vendor ==
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index d3235f213c8..e0d474b1743 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -123,8 +123,12 @@ int i2o_driver_register(struct i2o_driver *drv)
}
rc = driver_register(&drv->driver);
- if (rc)
- destroy_workqueue(drv->event_queue);
+ if (rc) {
+ if (drv->event) {
+ destroy_workqueue(drv->event_queue);
+ drv->event_queue = NULL;
+ }
+ }
return rc;
};
@@ -256,7 +260,7 @@ void i2o_driver_notify_controller_add_all(struct i2o_controller *c)
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -276,7 +280,7 @@ void i2o_driver_notify_controller_remove_all(struct i2o_controller *c)
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -295,7 +299,7 @@ void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev)
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -314,7 +318,7 @@ void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev)
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -335,17 +339,15 @@ int __init i2o_driver_init(void)
spin_lock_init(&i2o_drivers_lock);
- if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
- ((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
- (2 * i2o_max_drivers - 1))) {
- osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
- "a power of 2\n", i2o_max_drivers);
+ if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64)) {
+ osm_warn("max_drivers set to %d, but must be >=2 and <= 64\n",
+ i2o_max_drivers);
i2o_max_drivers = I2O_MAX_DRIVERS;
}
osm_info("max drivers = %d\n", i2o_max_drivers);
i2o_drivers =
- kzalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
+ kcalloc(i2o_max_drivers, sizeof(*i2o_drivers), GFP_KERNEL);
if (!i2o_drivers)
return -ENOMEM;
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index cb8c264eaff..38e815a2e87 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -207,16 +207,7 @@ static int ucb1x00_thread(void *_ts)
struct ucb1x00_ts *ts = _ts;
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
- int valid;
-
- /*
- * We could run as a real-time thread. However, thus far
- * this doesn't seem to be necessary.
- */
-// tsk->policy = SCHED_FIFO;
-// tsk->rt_priority = 1;
-
- valid = 0;
+ int valid = 0;
add_wait_queue(&ts->irq_wait, &wait);
while (!kthread_should_stop()) {
@@ -300,7 +291,7 @@ static void ucb1x00_ts_irq(int idx, void *id)
static int ucb1x00_ts_open(struct input_dev *idev)
{
- struct ucb1x00_ts *ts = idev->private;
+ struct ucb1x00_ts *ts = input_get_drvdata(idev);
int ret = 0;
BUG_ON(ts->rtask);
@@ -337,7 +328,7 @@ static int ucb1x00_ts_open(struct input_dev *idev)
*/
static void ucb1x00_ts_close(struct input_dev *idev)
{
- struct ucb1x00_ts *ts = idev->private;
+ struct ucb1x00_ts *ts = input_get_drvdata(idev);
if (ts->rtask)
kthread_stop(ts->rtask);
@@ -389,7 +380,6 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
ts->idev = idev;
ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
- idev->private = ts;
idev->name = "Touchscreen panel";
idev->id.product = ts->ucb->id;
idev->open = ucb1x00_ts_open;
@@ -400,6 +390,8 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
__set_bit(ABS_Y, idev->absbit);
__set_bit(ABS_PRESSURE, idev->absbit);
+ input_set_drvdata(idev, ts);
+
err = input_register_device(idev);
if (err)
goto fail;
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 35b139b0e5f..5108b7c576d 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -47,6 +47,7 @@ struct phantom_device {
struct cdev cdev;
struct mutex open_lock;
+ spinlock_t ioctl_lock;
};
static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
@@ -59,8 +60,11 @@ static int phantom_status(struct phantom_device *dev, unsigned long newstat)
atomic_set(&dev->counter, 0);
iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
iowrite32(0x43, dev->caddr + PHN_IRQCTL);
- } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING))
+ ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
+ } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) {
iowrite32(0, dev->caddr + PHN_IRQCTL);
+ ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
+ }
dev->status = newstat;
@@ -71,8 +75,8 @@ static int phantom_status(struct phantom_device *dev, unsigned long newstat)
* File ops
*/
-static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg)
+static long phantom_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
struct phantom_device *dev = file->private_data;
struct phm_regs rs;
@@ -92,24 +96,32 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
if (r.reg > 7)
return -EINVAL;
+ spin_lock(&dev->ioctl_lock);
if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
- phantom_status(dev, dev->status | PHB_RUNNING))
+ phantom_status(dev, dev->status | PHB_RUNNING)){
+ spin_unlock(&dev->ioctl_lock);
return -ENODEV;
+ }
pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
iowrite32(r.value, dev->iaddr + r.reg);
+ ioread32(dev->iaddr); /* PCI posting */
if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
phantom_status(dev, dev->status & ~PHB_RUNNING);
+ spin_unlock(&dev->ioctl_lock);
break;
case PHN_SET_REGS:
if (copy_from_user(&rs, argp, sizeof(rs)))
return -EFAULT;
pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
+ spin_lock(&dev->ioctl_lock);
for (i = 0; i < min(rs.count, 8U); i++)
if ((1 << i) & rs.mask)
iowrite32(rs.values[i], dev->oaddr + i);
+ ioread32(dev->iaddr); /* PCI posting */
+ spin_unlock(&dev->ioctl_lock);
break;
case PHN_GET_REG:
if (copy_from_user(&r, argp, sizeof(r)))
@@ -128,9 +140,11 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
return -EFAULT;
pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
+ spin_lock(&dev->ioctl_lock);
for (i = 0; i < min(rs.count, 8U); i++)
if ((1 << i) & rs.mask)
rs.values[i] = ioread32(dev->iaddr + i);
+ spin_unlock(&dev->ioctl_lock);
if (copy_to_user(argp, &rs, sizeof(rs)))
return -EFAULT;
@@ -199,7 +213,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait)
static struct file_operations phantom_file_ops = {
.open = phantom_open,
.release = phantom_release,
- .ioctl = phantom_ioctl,
+ .unlocked_ioctl = phantom_ioctl,
.poll = phantom_poll,
};
@@ -212,6 +226,7 @@ static irqreturn_t phantom_isr(int irq, void *data)
iowrite32(0, dev->iaddr);
iowrite32(0xc0, dev->iaddr);
+ ioread32(dev->iaddr); /* PCI posting */
atomic_inc(&dev->counter);
wake_up_interruptible(&dev->wait);
@@ -282,11 +297,13 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
}
mutex_init(&pht->open_lock);
+ spin_lock_init(&pht->ioctl_lock);
init_waitqueue_head(&pht->wait);
cdev_init(&pht->cdev, &phantom_file_ops);
pht->cdev.owner = THIS_MODULE;
iowrite32(0, pht->caddr + PHN_IRQCTL);
+ ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
retval = request_irq(pdev->irq, phantom_isr,
IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
if (retval) {
@@ -337,6 +354,7 @@ static void __devexit phantom_remove(struct pci_dev *pdev)
cdev_del(&pht->cdev);
iowrite32(0, pht->caddr + PHN_IRQCTL);
+ ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
free_irq(pdev->irq, pht);
pci_iounmap(pdev, pht->oaddr);
@@ -358,6 +376,7 @@ static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
struct phantom_device *dev = pci_get_drvdata(pdev);
iowrite32(0, dev->caddr + PHN_IRQCTL);
+ ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
return 0;
}
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 6c36a55cb3d..95c0b96e83f 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -740,7 +740,7 @@ static ssize_t hotkey_enable_store(struct device *dev,
}
static struct device_attribute dev_attr_hotkey_enable =
- __ATTR(enable, S_IWUSR | S_IRUGO,
+ __ATTR(hotkey_enable, S_IWUSR | S_IRUGO,
hotkey_enable_show, hotkey_enable_store);
/* sysfs hotkey mask --------------------------------------------------- */
@@ -775,7 +775,7 @@ static ssize_t hotkey_mask_store(struct device *dev,
}
static struct device_attribute dev_attr_hotkey_mask =
- __ATTR(mask, S_IWUSR | S_IRUGO,
+ __ATTR(hotkey_mask, S_IWUSR | S_IRUGO,
hotkey_mask_show, hotkey_mask_store);
/* sysfs hotkey bios_enabled ------------------------------------------- */
@@ -787,7 +787,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev,
}
static struct device_attribute dev_attr_hotkey_bios_enabled =
- __ATTR(bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
+ __ATTR(hotkey_bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL);
/* sysfs hotkey bios_mask ---------------------------------------------- */
static ssize_t hotkey_bios_mask_show(struct device *dev,
@@ -798,7 +798,7 @@ static ssize_t hotkey_bios_mask_show(struct device *dev,
}
static struct device_attribute dev_attr_hotkey_bios_mask =
- __ATTR(bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
+ __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
/* --------------------------------------------------------------------- */
@@ -824,8 +824,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
str_supported(tp_features.hotkey));
if (tp_features.hotkey) {
- hotkey_dev_attributes = create_attr_set(4,
- TPACPI_HOTKEY_SYSFS_GROUP);
+ hotkey_dev_attributes = create_attr_set(4, NULL);
if (!hotkey_dev_attributes)
return -ENOMEM;
res = add_to_attr_set(hotkey_dev_attributes,
@@ -1050,7 +1049,7 @@ static ssize_t bluetooth_enable_store(struct device *dev,
}
static struct device_attribute dev_attr_bluetooth_enable =
- __ATTR(enable, S_IWUSR | S_IRUGO,
+ __ATTR(bluetooth_enable, S_IWUSR | S_IRUGO,
bluetooth_enable_show, bluetooth_enable_store);
/* --------------------------------------------------------------------- */
@@ -1061,7 +1060,6 @@ static struct attribute *bluetooth_attributes[] = {
};
static const struct attribute_group bluetooth_attr_group = {
- .name = TPACPI_BLUETH_SYSFS_GROUP,
.attrs = bluetooth_attributes,
};
@@ -1215,7 +1213,7 @@ static ssize_t wan_enable_store(struct device *dev,
}
static struct device_attribute dev_attr_wan_enable =
- __ATTR(enable, S_IWUSR | S_IRUGO,
+ __ATTR(wwan_enable, S_IWUSR | S_IRUGO,
wan_enable_show, wan_enable_store);
/* --------------------------------------------------------------------- */
@@ -1226,7 +1224,6 @@ static struct attribute *wan_attributes[] = {
};
static const struct attribute_group wan_attr_group = {
- .name = TPACPI_WAN_SYSFS_GROUP,
.attrs = wan_attributes,
};
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 440145a0261..72d62f2dabb 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -278,8 +278,6 @@ static int beep_write(char *buf);
* Bluetooth subdriver
*/
-#define TPACPI_BLUETH_SYSFS_GROUP "bluetooth"
-
enum {
/* ACPI GBDC/SBDC bits */
TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
@@ -416,8 +414,6 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
* Hotkey subdriver
*/
-#define TPACPI_HOTKEY_SYSFS_GROUP "hotkey"
-
static int hotkey_orig_status;
static int hotkey_orig_mask;
@@ -553,8 +549,6 @@ static int volume_write(char *buf);
* Wan subdriver
*/
-#define TPACPI_WAN_SYSFS_GROUP "wwan"
-
enum {
/* ACPI GWAN/SWAN bits */
TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index c08ad8f823d..2d1b3df95c5 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -343,7 +343,7 @@ static int tifm_7xx1_probe(struct pci_dev *dev,
if (!fm->addr)
goto err_out_free;
- rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm);
+ rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm);
if (rc)
goto err_out_unmap;
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a7562f7fc0b..540ff4bea54 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -135,23 +135,6 @@ struct mmc_blk_request {
struct mmc_data data;
};
-static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req)
-{
- struct mmc_blk_data *md = mq->data;
- int stat = BLKPREP_OK;
-
- /*
- * If we have no device, we haven't finished initialising.
- */
- if (!md || !mq->card) {
- printk(KERN_ERR "%s: killing request - no device/host\n",
- req->rq_disk->disk_name);
- stat = BLKPREP_KILL;
- }
-
- return stat;
-}
-
static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
{
int err;
@@ -460,7 +443,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
if (ret)
goto err_putdisk;
- md->queue.prep_fn = mmc_blk_prep_rq;
md->queue.issue_fn = mmc_blk_issue_rq;
md->queue.data = md;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 2e77963db33..dd97bc79840 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -20,40 +20,21 @@
#define MMC_QUEUE_SUSPENDED (1 << 0)
/*
- * Prepare a MMC request. Essentially, this means passing the
- * preparation off to the media driver. The media driver will
- * create a mmc_io_request in req->special.
+ * Prepare a MMC request. This just filters out odd stuff.
*/
static int mmc_prep_request(struct request_queue *q, struct request *req)
{
- struct mmc_queue *mq = q->queuedata;
- int ret = BLKPREP_KILL;
-
- if (blk_special_request(req)) {
- /*
- * Special commands already have the command
- * blocks already setup in req->special.
- */
- BUG_ON(!req->special);
-
- ret = BLKPREP_OK;
- } else if (blk_fs_request(req) || blk_pc_request(req)) {
- /*
- * Block I/O requests need translating according
- * to the protocol.
- */
- ret = mq->prep_fn(mq, req);
- } else {
- /*
- * Everything else is invalid.
- */
+ /*
+ * We only like normal block requests.
+ */
+ if (!blk_fs_request(req) && !blk_pc_request(req)) {
blk_dump_rq_flags(req, "MMC bad request");
+ return BLKPREP_KILL;
}
- if (ret == BLKPREP_OK)
- req->cmd_flags |= REQ_DONTPREP;
+ req->cmd_flags |= REQ_DONTPREP;
- return ret;
+ return BLKPREP_OK;
}
static int mmc_queue_thread(void *d)
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index c9f139e764f..1590b3f3f1f 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -10,20 +10,12 @@ struct mmc_queue {
struct semaphore thread_sem;
unsigned int flags;
struct request *req;
- int (*prep_fn)(struct mmc_queue *, struct request *);
int (*issue_fn)(struct mmc_queue *, struct request *);
void *data;
struct request_queue *queue;
struct scatterlist *sg;
};
-struct mmc_io_request {
- struct request *rq;
- int num;
- struct mmc_command selcmd; /* mmc_queue private */
- struct mmc_command cmd[4]; /* max 4 commands */
-};
-
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
extern void mmc_cleanup_queue(struct mmc_queue *);
extern void mmc_queue_suspend(struct mmc_queue *);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index c1dfd03d559..918477c490b 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -15,6 +15,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
#include "core.h"
#include "sysfs.h"
@@ -192,6 +193,16 @@ static int mmc_read_switch(struct mmc_card *card)
int err;
u8 *status;
+ if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+ return MMC_ERR_NONE;
+
+ if (!(card->csd.cmdclass & CCC_SWITCH)) {
+ printk(KERN_WARNING "%s: card lacks mandatory switch "
+ "function, performance might suffer.\n",
+ mmc_hostname(card->host));
+ return MMC_ERR_NONE;
+ }
+
err = MMC_ERR_FAILED;
status = kmalloc(64, GFP_KERNEL);
@@ -204,10 +215,9 @@ static int mmc_read_switch(struct mmc_card *card)
err = mmc_sd_switch(card, 0, 0, 1, status);
if (err != MMC_ERR_NONE) {
- /*
- * Card not supporting high-speed will ignore the
- * command.
- */
+ printk(KERN_WARNING "%s: problem reading switch "
+ "capabilities, performance might suffer.\n",
+ mmc_hostname(card->host));
err = MMC_ERR_NONE;
goto out;
}
@@ -229,6 +239,12 @@ static int mmc_switch_hs(struct mmc_card *card)
int err;
u8 *status;
+ if (card->scr.sda_vsn < SCR_SPEC_VER_1)
+ return MMC_ERR_NONE;
+
+ if (!(card->csd.cmdclass & CCC_SWITCH))
+ return MMC_ERR_NONE;
+
if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
return MMC_ERR_NONE;
@@ -402,7 +418,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
/*
* Switch to wider bus (if supported).
*/
- if ((host->caps && MMC_CAP_4_BIT_DATA) &&
+ if ((host->caps & MMC_CAP_4_BIT_DATA) &&
(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
if (err != MMC_ERR_NONE)
@@ -411,6 +427,21 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
}
+ /*
+ * Check if read-only switch is active.
+ */
+ if (!oldcard) {
+ if (!host->ops->get_ro) {
+ printk(KERN_WARNING "%s: host does not "
+ "support reading read-only "
+ "switch. assuming write-enable.\n",
+ mmc_hostname(host));
+ } else {
+ if (host->ops->get_ro(host))
+ mmc_card_set_readonly(card);
+ }
+ }
+
if (!oldcard)
host->card = card;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index e37943c314c..5b00c194b62 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -417,7 +417,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
blocks = 0;
}
- if (cmd->opcode == MMC_STOP_TRANSMISSION)
+ if (host->flags & FL_SENT_STOP)
cmdr |= AT91_MCI_TRCMD_STOP;
if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
@@ -563,8 +563,7 @@ static void at91mci_completed_command(struct at91mci_host *host)
if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
- if ((status & AT91_MCI_RCRCE) &&
- ((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
+ if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
cmd->error = MMC_ERR_NONE;
}
else {
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index f967226d750..52b63f11ddd 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -76,8 +76,7 @@ const struct {
#endif
};
-#define AU1XMMC_CONTROLLER_COUNT \
- (sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0]))
+#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table))
/* This array stores pointers for the hosts (used by the IRQ handler) */
struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 1914e65d4db..b0824a38f42 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -522,28 +522,10 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
if (status & OMAP_MMC_STAT_CARD_ERR) {
- if (host->cmd && host->cmd->opcode == MMC_STOP_TRANSMISSION) {
- u32 response = OMAP_MMC_READ(host, RSP6)
- | (OMAP_MMC_READ(host, RSP7) << 16);
- /* STOP sometimes sets must-ignore bits */
- if (!(response & (R1_CC_ERROR
- | R1_ILLEGAL_COMMAND
- | R1_COM_CRC_ERROR))) {
- end_command = 1;
- continue;
- }
- }
-
- dev_dbg(mmc_dev(host->mmc), "card status error (CMD%d)\n",
+ dev_dbg(mmc_dev(host->mmc),
+ "ignoring card status error (CMD%d)\n",
host->cmd->opcode);
- if (host->cmd) {
- host->cmd->error = MMC_ERR_FAILED;
- end_command = 1;
- }
- if (host->data) {
- host->data->error = MMC_ERR_FAILED;
- transfer_error = 1;
- }
+ end_command = 1;
}
/*
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 92055405cb3..451adcc52b3 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,10 +1,9 @@
#
# Makefile for the memory technology device drivers.
#
-# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $
# Core functionality.
-mtd-y := mtdcore.o
+mtd-y := mtdcore.o mtdsuper.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD) += $(mtd-y)
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index a4873ab84e6..e8f686f7a35 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -650,7 +650,7 @@ MODULE_DESCRIPTION(PMC551_VERSION);
*/
static int msize = 0;
#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
-static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE
+static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE;
#else
static int asize = 0;
#endif
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index 389fea28b9a..14ffb1a9302 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/major.h>
-#include <linux/root_dev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
@@ -89,10 +88,6 @@ int __init uclinux_mtd_init(void)
uclinux_ram_mtdinfo = mtd;
add_mtd_partitions(mtd, uclinux_romfs, NUM_PARTITIONS);
- printk("uclinux[mtd]: set %s to be root filesystem\n",
- uclinux_romfs[0].name);
- ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
-
return(0);
}
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
new file mode 100644
index 00000000000..aca33197120
--- /dev/null
+++ b/drivers/mtd/mtdsuper.c
@@ -0,0 +1,232 @@
+/* MTD-based superblock management
+ *
+ * Copyright © 2001-2007 Red Hat, Inc. All Rights Reserved.
+ * Written by: David Howells <dhowells@redhat.com>
+ * David Woodhouse <dwmw2@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/mtd/super.h>
+#include <linux/namei.h>
+#include <linux/ctype.h>
+
+/*
+ * compare superblocks to see if they're equivalent
+ * - they are if the underlying MTD device is the same
+ */
+static int get_sb_mtd_compare(struct super_block *sb, void *_mtd)
+{
+ struct mtd_info *mtd = _mtd;
+
+ if (sb->s_mtd == mtd) {
+ DEBUG(2, "MTDSB: Match on device %d (\"%s\")\n",
+ mtd->index, mtd->name);
+ return 1;
+ }
+
+ DEBUG(2, "MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
+ sb->s_mtd->index, sb->s_mtd->name, mtd->index, mtd->name);
+ return 0;
+}
+
+/*
+ * mark the superblock by the MTD device it is using
+ * - set the device number to be the correct MTD block device for pesuperstence
+ * of NFS exports
+ */
+static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
+{
+ struct mtd_info *mtd = _mtd;
+
+ sb->s_mtd = mtd;
+ sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+ return 0;
+}
+
+/*
+ * get a superblock on an MTD-backed filesystem
+ */
+static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data,
+ struct mtd_info *mtd,
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt)
+{
+ struct super_block *sb;
+ int ret;
+
+ sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, mtd);
+ if (IS_ERR(sb))
+ goto out_error;
+
+ if (sb->s_root)
+ goto already_mounted;
+
+ /* fresh new superblock */
+ DEBUG(1, "MTDSB: New superblock for device %d (\"%s\")\n",
+ mtd->index, mtd->name);
+
+ ret = fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
+ if (ret < 0) {
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ return ret;
+ }
+
+ /* go */
+ sb->s_flags |= MS_ACTIVE;
+ return simple_set_mnt(mnt, sb);
+
+ /* new mountpoint for an already mounted superblock */
+already_mounted:
+ DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
+ mtd->index, mtd->name);
+ ret = simple_set_mnt(mnt, sb);
+ goto out_put;
+
+out_error:
+ ret = PTR_ERR(sb);
+out_put:
+ put_mtd_device(mtd);
+ return ret;
+}
+
+/*
+ * get a superblock on an MTD-backed filesystem by MTD device number
+ */
+static int get_sb_mtd_nr(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data, int mtdnr,
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt)
+{
+ struct mtd_info *mtd;
+
+ mtd = get_mtd_device(NULL, mtdnr);
+ if (IS_ERR(mtd)) {
+ DEBUG(0, "MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
+ return PTR_ERR(mtd);
+ }
+
+ return get_sb_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super,
+ mnt);
+}
+
+/*
+ * set up an MTD-based superblock
+ */
+int get_sb_mtd(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data,
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt)
+{
+ struct nameidata nd;
+ int mtdnr, ret;
+
+ if (!dev_name)
+ return -EINVAL;
+
+ DEBUG(2, "MTDSB: dev_name \"%s\"\n", dev_name);
+
+ /* the preferred way of mounting in future; especially when
+ * CONFIG_BLOCK=n - we specify the underlying MTD device by number or
+ * by name, so that we don't require block device support to be present
+ * in the kernel. */
+ if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
+ if (dev_name[3] == ':') {
+ struct mtd_info *mtd;
+
+ /* mount by MTD device name */
+ DEBUG(1, "MTDSB: mtd:%%s, name \"%s\"\n",
+ dev_name + 4);
+
+ for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
+ mtd = get_mtd_device(NULL, mtdnr);
+ if (!IS_ERR(mtd)) {
+ if (!strcmp(mtd->name, dev_name + 4))
+ return get_sb_mtd_aux(
+ fs_type, flags,
+ dev_name, data, mtd,
+ fill_super, mnt);
+
+ put_mtd_device(mtd);
+ }
+ }
+
+ printk(KERN_NOTICE "MTD:"
+ " MTD device with name \"%s\" not found.\n",
+ dev_name + 4);
+
+ } else if (isdigit(dev_name[3])) {
+ /* mount by MTD device number name */
+ char *endptr;
+
+ mtdnr = simple_strtoul(dev_name + 3, &endptr, 0);
+ if (!*endptr) {
+ /* It was a valid number */
+ DEBUG(1, "MTDSB: mtd%%d, mtdnr %d\n",
+ mtdnr);
+ return get_sb_mtd_nr(fs_type, flags,
+ dev_name, data,
+ mtdnr, fill_super, mnt);
+ }
+ }
+ }
+
+ /* try the old way - the hack where we allowed users to mount
+ * /dev/mtdblock$(n) but didn't actually _use_ the blockdev
+ */
+ ret = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
+
+ DEBUG(1, "MTDSB: path_lookup() returned %d, inode %p\n",
+ ret, nd.dentry ? nd.dentry->d_inode : NULL);
+
+ if (ret)
+ return ret;
+
+ ret = -EINVAL;
+
+ if (!S_ISBLK(nd.dentry->d_inode->i_mode))
+ goto out;
+
+ if (nd.mnt->mnt_flags & MNT_NODEV) {
+ ret = -EACCES;
+ goto out;
+ }
+
+ if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR)
+ goto not_an_MTD_device;
+
+ mtdnr = iminor(nd.dentry->d_inode);
+ path_release(&nd);
+
+ return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
+ mnt);
+
+not_an_MTD_device:
+ if (!(flags & MS_SILENT))
+ printk(KERN_NOTICE
+ "MTD: Attempt to mount non-MTD device \"%s\"\n",
+ dev_name);
+out:
+ path_release(&nd);
+ return ret;
+
+}
+
+EXPORT_SYMBOL_GPL(get_sb_mtd);
+
+/*
+ * destroy an MTD-based superblock
+ */
+void kill_mtd_super(struct super_block *sb)
+{
+ generic_shutdown_super(sb);
+ put_mtd_device(sb->s_mtd);
+ sb->s_mtd = NULL;
+}
+
+EXPORT_SYMBOL_GPL(kill_mtd_super);
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index fe94ae9ae1f..e3744eb8ecc 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -101,7 +101,7 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd,
struct nand_chip *chip = mtd->priv;
if (ctrl & NAND_CTRL_CHANGE) {
- void __iomem *addr
+ void __iomem *addr;
unsigned char bits;
addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET;
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index eb7d4d443de..082073acf20 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -81,7 +81,7 @@ __setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase);
*/
static struct mtd_partition partition_info_hi[] = {
{ .name = "PPChameleon HI Nand Flash",
- offset = 0,
+ .offset = 0,
.size = 128 * 1024 * 1024
}
};
@@ -424,9 +424,9 @@ static void __exit ppchameleonevb_cleanup(void)
/* Release iomaps */
this = (struct nand_chip *) &ppchameleon_mtd[1];
- iounmap((void *) this->IO_ADDR_R;
+ iounmap((void *) this->IO_ADDR_R);
this = (struct nand_chip *) &ppchameleonevb_mtd[1];
- iounmap((void *) this->IO_ADDR_R;
+ iounmap((void *) this->IO_ADDR_R);
/* Free the MTD device structure */
kfree (ppchameleon_mtd);
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index e8c9f27817b..a804965e654 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -435,20 +435,12 @@ static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
spin_lock_irqsave(&cp->lock, flags);
cp->vlgrp = grp;
- cp->cpcmd |= RxVlanOn;
- cpw16(CpCmd, cp->cpcmd);
- spin_unlock_irqrestore(&cp->lock, flags);
-}
-
-static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct cp_private *cp = netdev_priv(dev);
- unsigned long flags;
+ if (grp)
+ cp->cpcmd |= RxVlanOn;
+ else
+ cp->cpcmd &= ~RxVlanOn;
- spin_lock_irqsave(&cp->lock, flags);
- cp->cpcmd &= ~RxVlanOn;
cpw16(CpCmd, cp->cpcmd);
- vlan_group_set_device(cp->vlgrp, vid, NULL);
spin_unlock_irqrestore(&cp->lock, flags);
}
#endif /* CP_VLAN_TAG_USED */
@@ -1944,7 +1936,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
#if CP_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = cp_vlan_rx_register;
- dev->vlan_rx_kill_vid = cp_vlan_rx_kill_vid;
#endif
if (pci_using_dac)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c5baa197bc0..7d57f4a25dc 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2218,7 +2218,7 @@ config SK98LIN
config VIA_VELOCITY
tristate "VIA Velocity support"
- depends on NET_PCI && PCI
+ depends on PCI
select CRC32
select CRC_CCITT
select MII
@@ -2280,7 +2280,7 @@ config GFAR_NAPI
config UCC_GETH
tristate "Freescale QE Gigabit Ethernet"
depends on QUICC_ENGINE
- select UCC_FAST
+ select PHYLIB
help
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
which is available on some Freescale SOCs.
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 7122b7ba8d6..04382f979c9 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -480,12 +480,10 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev,
#if ACENIC_DO_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = ace_vlan_rx_register;
- dev->vlan_rx_kill_vid = ace_vlan_rx_kill_vid;
#endif
- if (1) {
- dev->tx_timeout = &ace_watchdog;
- dev->watchdog_timeo = 5*HZ;
- }
+
+ dev->tx_timeout = &ace_watchdog;
+ dev->watchdog_timeo = 5*HZ;
dev->open = &ace_open;
dev->stop = &ace_close;
@@ -2283,19 +2281,6 @@ static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
ace_unmask_irq(dev);
local_irq_restore(flags);
}
-
-
-static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct ace_private *ap = netdev_priv(dev);
- unsigned long flags;
-
- local_irq_save(flags);
- ace_mask_irq(dev);
- vlan_group_set_device(ap->vlgrp, vid, NULL);
- ace_unmask_irq(dev);
- local_irq_restore(flags);
-}
#endif /* ACENIC_DO_VLAN */
diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h
index 8ca8534d70b..60ed1837fa8 100644
--- a/drivers/net/acenic.h
+++ b/drivers/net/acenic.h
@@ -787,7 +787,6 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev);
static int read_eeprom_byte(struct net_device *dev, unsigned long offset);
#if ACENIC_DO_VLAN
static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
-static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
#endif
#endif /* _ACENIC_H_ */
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 675fe918421..a61b2f89fc3 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -155,7 +155,7 @@ This function will write into PHY registers.
*/
static int amd8111e_write_phy(struct amd8111e_priv* lp,int phy_id, int reg, u32 val)
{
- unsigned int repeat = REPEAT_CNT
+ unsigned int repeat = REPEAT_CNT;
void __iomem *mmio = lp->mmio;
unsigned int reg_val;
@@ -1728,15 +1728,8 @@ static void amd8111e_vlan_rx_register(struct net_device *dev, struct vlan_group
lp->vlgrp = grp;
spin_unlock_irq(&lp->lock);
}
-
-static void amd8111e_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct amd8111e_priv *lp = netdev_priv(dev);
- spin_lock_irq(&lp->lock);
- vlan_group_set_device(lp->vlgrp, vid, NULL);
- spin_unlock_irq(&lp->lock);
-}
#endif
+
static int amd8111e_enable_magicpkt(struct amd8111e_priv* lp)
{
writel( VAL1|MPPLBA, lp->mmio + CMD3);
@@ -1996,7 +1989,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
#if AMD8111E_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX ;
dev->vlan_rx_register =amd8111e_vlan_rx_register;
- dev->vlan_rx_kill_vid = amd8111e_vlan_rx_kill_vid;
#endif
lp = netdev_priv(dev);
@@ -2049,7 +2041,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
#if AMD8111E_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register =amd8111e_vlan_rx_register;
- dev->vlan_rx_kill_vid = amd8111e_vlan_rx_kill_vid;
#endif
/* Probe the external PHY */
amd8111e_probe_ext_phy(dev);
diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h
index 2007510c4eb..e65080a5994 100644
--- a/drivers/net/amd8111e.h
+++ b/drivers/net/amd8111e.h
@@ -615,7 +615,7 @@ typedef enum {
#define SSTATE 2
/* Assume contoller gets data 10 times the maximum processing time */
-#define REPEAT_CNT 10;
+#define REPEAT_CNT 10
/* amd8111e decriptor flag definitions */
typedef enum {
diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
index 7284ccad0b9..4030274fe78 100644
--- a/drivers/net/arcnet/Kconfig
+++ b/drivers/net/arcnet/Kconfig
@@ -2,10 +2,8 @@
# Arcnet configuration
#
-menu "ARCnet devices"
+menuconfig ARCNET
depends on NETDEVICES && (ISA || PCI)
-
-config ARCNET
tristate "ARCnet support"
---help---
If you have a network card of this type, say Y and check out the
@@ -25,9 +23,10 @@ config ARCNET
<file:Documentation/networking/net-modules.txt>. The module will
be called arcnet.
+if ARCNET
+
config ARCNET_1201
tristate "Enable standard ARCNet packet format (RFC 1201)"
- depends on ARCNET
help
This allows you to use RFC1201 with your ARCnet card via the virtual
arc0 device. You need to say Y here to communicate with
@@ -38,7 +37,6 @@ config ARCNET_1201
config ARCNET_1051
tristate "Enable old ARCNet packet format (RFC 1051)"
- depends on ARCNET
---help---
This allows you to use RFC1051 with your ARCnet card via the virtual
arc0s device. You only need arc0s if you want to talk to ARCnet
@@ -53,7 +51,6 @@ config ARCNET_1051
config ARCNET_RAW
tristate "Enable raw mode packet interface"
- depends on ARCNET
help
ARCnet "raw mode" packet encapsulation, no soft headers. Unlikely
to work unless talking to a copy of the same Linux arcnet driver,
@@ -61,7 +58,6 @@ config ARCNET_RAW
config ARCNET_CAP
tristate "Enable CAP mode packet interface"
- depends on ARCNET
help
ARCnet "cap mode" packet encapsulation. Used to get the hardware
acknowledge back to userspace. After the initial protocol byte every
@@ -80,7 +76,6 @@ config ARCNET_CAP
config ARCNET_COM90xx
tristate "ARCnet COM90xx (normal) chipset driver"
- depends on ARCNET
help
This is the chipset driver for the standard COM90xx cards. If you
have always used the old ARCnet driver without knowing what type of
@@ -92,7 +87,6 @@ config ARCNET_COM90xx
config ARCNET_COM90xxIO
tristate "ARCnet COM90xx (IO mapped) chipset driver"
- depends on ARCNET
---help---
This is the chipset driver for the COM90xx cards, using them in
IO-mapped mode instead of memory-mapped mode. This is slower than
@@ -105,7 +99,6 @@ config ARCNET_COM90xxIO
config ARCNET_RIM_I
tristate "ARCnet COM90xx (RIM I) chipset driver"
- depends on ARCNET
---help---
This is yet another chipset driver for the COM90xx cards, but this
time only using memory-mapped mode, and no IO ports at all. This
@@ -118,7 +111,6 @@ config ARCNET_RIM_I
config ARCNET_COM20020
tristate "ARCnet COM20020 chipset driver"
- depends on ARCNET
help
This is the driver for the new COM20020 chipset. It supports such
things as promiscuous mode, so packet sniffing is possible, and
@@ -136,5 +128,4 @@ config ARCNET_COM20020_PCI
tristate "Support for COM20020 on PCI"
depends on ARCNET_COM20020 && PCI
-endmenu
-
+endif # ARCNET
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 78cf00ff3d3..6862c11ff86 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -1229,39 +1229,9 @@ static void atl1_vlan_rx_register(struct net_device *netdev,
spin_unlock_irqrestore(&adapter->lock, flags);
}
-/* FIXME: justify or remove -- CHS */
-static void atl1_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-{
- /* We don't do Vlan filtering */
- return;
-}
-
-/* FIXME: this looks wrong too -- CHS */
-static void atl1_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-{
- struct atl1_adapter *adapter = netdev_priv(netdev);
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->lock, flags);
- /* atl1_irq_disable(adapter); */
- vlan_group_set_device(adapter->vlgrp, vid, NULL);
- /* atl1_irq_enable(adapter); */
- spin_unlock_irqrestore(&adapter->lock, flags);
- /* We don't do Vlan filtering */
- return;
-}
-
static void atl1_restore_vlan(struct atl1_adapter *adapter)
{
atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp);
- if (adapter->vlgrp) {
- u16 vid;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
- if (!vlan_group_get_device(adapter->vlgrp, vid))
- continue;
- atl1_vlan_rx_add_vid(adapter->netdev, vid);
- }
- }
}
static u16 tpd_avail(struct atl1_tpd_ring *tpd_ring)
@@ -2203,8 +2173,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netdev->poll_controller = atl1_poll_controller;
#endif
netdev->vlan_rx_register = atl1_vlan_rx_register;
- netdev->vlan_rx_add_vid = atl1_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = atl1_vlan_rx_kill_vid;
+
netdev->ethtool_ops = &atl1_ethtool_ops;
adapter->bd_number = cards_found;
adapter->pci_using_64 = pci_using_64;
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 88b33c6ddda..ce3ed67a878 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -54,8 +54,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.5.10"
-#define DRV_MODULE_RELDATE "May 1, 2007"
+#define DRV_MODULE_VERSION "1.5.11"
+#define DRV_MODULE_RELDATE "June 4, 2007"
#define RUN_AT(x) (jiffies + (x))
@@ -1778,6 +1778,15 @@ bnx2_init_5709_context(struct bnx2 *bp)
val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
val |= (BCM_PAGE_BITS - 8) << 16;
REG_WR(bp, BNX2_CTX_COMMAND, val);
+ for (i = 0; i < 10; i++) {
+ val = REG_RD(bp, BNX2_CTX_COMMAND);
+ if (!(val & BNX2_CTX_COMMAND_MEM_INIT))
+ break;
+ udelay(2);
+ }
+ if (val & BNX2_CTX_COMMAND_MEM_INIT)
+ return -EBUSY;
+
for (i = 0; i < bp->ctx_pages; i++) {
int j;
@@ -1811,6 +1820,7 @@ bnx2_init_context(struct bnx2 *bp)
vcid = 96;
while (vcid) {
u32 vcid_addr, pcid_addr, offset;
+ int i;
vcid--;
@@ -1831,16 +1841,20 @@ bnx2_init_context(struct bnx2 *bp)
pcid_addr = vcid_addr;
}
- REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
- REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+ for (i = 0; i < (CTX_SIZE / PHY_CTX_SIZE); i++) {
+ vcid_addr += (i << PHY_CTX_SHIFT);
+ pcid_addr += (i << PHY_CTX_SHIFT);
- /* Zero out the context. */
- for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
- CTX_WR(bp, 0x00, offset, 0);
- }
+ REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
+ REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+
+ /* Zero out the context. */
+ for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
+ CTX_WR(bp, 0x00, offset, 0);
- REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
- REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+ REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
+ REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+ }
}
}
@@ -3691,9 +3705,11 @@ bnx2_init_chip(struct bnx2 *bp)
/* Initialize context mapping and zero out the quick contexts. The
* context block must have already been enabled. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- bnx2_init_5709_context(bp);
- else
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ rc = bnx2_init_5709_context(bp);
+ if (rc)
+ return rc;
+ } else
bnx2_init_context(bp);
if ((rc = bnx2_init_cpus(bp)) != 0)
@@ -3772,7 +3788,10 @@ bnx2_init_chip(struct bnx2 *bp)
REG_WR(bp, BNX2_HC_CMD_TICKS,
(bp->cmd_ticks_int << 16) | bp->cmd_ticks);
- REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
+ if (CHIP_NUM(bp) == CHIP_NUM_5708)
+ REG_WR(bp, BNX2_HC_STATS_TICKS, 0);
+ else
+ REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */
if (CHIP_ID(bp) == CHIP_ID_5706_A1)
@@ -3799,6 +3818,11 @@ bnx2_init_chip(struct bnx2 *bp)
/* Initialize the receive filter. */
bnx2_set_rx_mode(bp->dev);
+ if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+ val |= BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
+ REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
+ }
rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
0);
@@ -4620,6 +4644,11 @@ bnx2_timer(unsigned long data)
bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT);
+ /* workaround occasional corrupted counters */
+ if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
+ REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
+ BNX2_HC_COMMAND_STATS_NOW);
+
if (bp->phy_flags & PHY_SERDES_FLAG) {
if (CHIP_NUM(bp) == CHIP_NUM_5706)
bnx2_5706_serdes_timer(bp);
@@ -4786,19 +4815,6 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
bnx2_netif_start(bp);
}
-
-/* Called with rtnl_lock */
-static void
-bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
-{
- struct bnx2 *bp = netdev_priv(dev);
-
- bnx2_netif_stop(bp);
- vlan_group_set_device(bp->vlgrp, vid, NULL);
- bnx2_set_rx_mode(dev);
-
- bnx2_netif_start(bp);
-}
#endif
/* Called with netif_tx_lock.
@@ -5430,6 +5446,10 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
0xff;
bp->stats_ticks = coal->stats_block_coalesce_usecs;
+ if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC)
+ bp->stats_ticks = USEC_PER_SEC;
+ }
if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00;
bp->stats_ticks &= 0xffff00;
@@ -6453,7 +6473,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->watchdog_timeo = TX_TIMEOUT;
#ifdef BCM_VLAN
dev->vlan_rx_register = bnx2_vlan_rx_register;
- dev->vlan_rx_kill_vid = bnx2_vlan_rx_kill_vid;
#endif
dev->poll = bnx2_poll;
dev->ethtool_ops = &bnx2_ethtool_ops;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index bd6288d6350..49a5de253b1 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1373,6 +1373,7 @@ struct l2_fhdr {
#define BNX2_MISC_NEW_CORE_CTL 0x000008c8
#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS (1L<<0)
#define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ (1L<<1)
+#define BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE (1L<<16)
#define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN (0x3fffL<<2)
#define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC (0xffffL<<16)
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 4aec747d9e4..59b9943b077 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4919,7 +4919,10 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
pci_cmd &= ~PCI_COMMAND_SERR;
pci_cmd |= PCI_COMMAND_PARITY;
pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
- pci_set_mwi(pdev);
+ if (pci_set_mwi(pdev))
+ printk(KERN_WARNING PFX "Could not enable MWI for %s\n",
+ pci_name(pdev));
+
/*
* On some architectures, the default cache line size set
* by pci_set_mwi reduces perforamnce. We have to increase
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 125c9b10586..231ce43b97c 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -883,15 +883,6 @@ static void vlan_rx_register(struct net_device *dev,
t1_set_vlan_accel(adapter, grp != NULL);
spin_unlock_irq(&adapter->async_lock);
}
-
-static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct adapter *adapter = dev->priv;
-
- spin_lock_irq(&adapter->async_lock);
- vlan_group_set_device(adapter->vlan_grp, vid, NULL);
- spin_unlock_irq(&adapter->async_lock);
-}
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1099,7 +1090,6 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->features |=
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
netdev->vlan_rx_register = vlan_rx_register;
- netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
#endif
/* T204: disable TSO */
diff --git a/drivers/net/chelsio/suni1x10gexp_regs.h b/drivers/net/chelsio/suni1x10gexp_regs.h
index 269d097dd92..d0f87d82566 100644
--- a/drivers/net/chelsio/suni1x10gexp_regs.h
+++ b/drivers/net/chelsio/suni1x10gexp_regs.h
@@ -105,7 +105,7 @@
#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_LOW(filterId) (0x204A + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_MID(filterId) (0x204B + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_HIGH(filterId)(0x204C + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
-#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId) (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId)
+#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId) (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId))
#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_LOW 0x204A
#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_MID 0x204B
#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_HIGH 0x204C
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 67b4b219d92..1b20f4060e2 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -2067,11 +2067,6 @@ static void vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
t3_synchronize_rx(adapter, pi);
}
-static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- /* nothing */
-}
-
#ifdef CONFIG_NET_POLL_CONTROLLER
static void cxgb_netpoll(struct net_device *dev)
{
@@ -2409,7 +2404,6 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
netdev->vlan_rx_register = vlan_rx_register;
- netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
netdev->open = cxgb_open;
netdev->stop = cxgb_close;
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 571d82f8008..7df23dc2819 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -566,6 +566,7 @@ static int __devinit dfx_register(struct device *bdev)
bp->base.mem = ioremap_nocache(bar_start, bar_len);
if (!bp->base.mem) {
printk(KERN_ERR "%s: Cannot map MMIO\n", print_name);
+ err = -ENOMEM;
goto err_out_region;
}
} else {
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 61696637a21..763810c7f33 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -285,6 +285,12 @@ enum scb_status {
rus_mask = 0x3C,
};
+enum ru_state {
+ RU_SUSPENDED = 0,
+ RU_RUNNING = 1,
+ RU_UNINITIALIZED = -1,
+};
+
enum scb_stat_ack {
stat_ack_not_ours = 0x00,
stat_ack_sw_gen = 0x04,
@@ -526,6 +532,7 @@ struct nic {
struct rx *rx_to_use;
struct rx *rx_to_clean;
struct rfd blank_rfd;
+ enum ru_state ru_running;
spinlock_t cb_lock ____cacheline_aligned;
spinlock_t cmd_lock;
@@ -947,7 +954,7 @@ static void e100_get_defaults(struct nic *nic)
((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
/* Template for a freshly allocated RFD */
- nic->blank_rfd.command = cpu_to_le16(cb_el & cb_s);
+ nic->blank_rfd.command = cpu_to_le16(cb_el);
nic->blank_rfd.rbd = 0xFFFFFFFF;
nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
@@ -1742,11 +1749,19 @@ static int e100_alloc_cbs(struct nic *nic)
return 0;
}
-static inline void e100_start_receiver(struct nic *nic)
+static inline void e100_start_receiver(struct nic *nic, struct rx *rx)
{
- /* Start if RFA is non-NULL */
- if(nic->rx_to_clean->skb)
- e100_exec_cmd(nic, ruc_start, nic->rx_to_clean->dma_addr);
+ if(!nic->rxs) return;
+ if(RU_SUSPENDED != nic->ru_running) return;
+
+ /* handle init time starts */
+ if(!rx) rx = nic->rxs;
+
+ /* (Re)start RU if suspended or idle and RFA is non-NULL */
+ if(rx->skb) {
+ e100_exec_cmd(nic, ruc_start, rx->dma_addr);
+ nic->ru_running = RU_RUNNING;
+ }
}
#define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
@@ -1775,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
put_unaligned(cpu_to_le32(rx->dma_addr),
(u32 *)&prev_rfd->link);
wmb();
- prev_rfd->command &= ~cpu_to_le16(cb_el & cb_s);
+ prev_rfd->command &= ~cpu_to_le16(cb_el);
pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
sizeof(struct rfd), PCI_DMA_TODEVICE);
}
@@ -1813,6 +1828,10 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
pci_unmap_single(nic->pdev, rx->dma_addr,
RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
+ /* this allows for a fast restart without re-enabling interrupts */
+ if(le16_to_cpu(rfd->command) & cb_el)
+ nic->ru_running = RU_SUSPENDED;
+
/* Pull off the RFD and put the actual data (minus eth hdr) */
skb_reserve(skb, sizeof(struct rfd));
skb_put(skb, actual_size);
@@ -1843,18 +1862,45 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
unsigned int work_to_do)
{
struct rx *rx;
+ int restart_required = 0;
+ struct rx *rx_to_start = NULL;
+
+ /* are we already rnr? then pay attention!!! this ensures that
+ * the state machine progression never allows a start with a
+ * partially cleaned list, avoiding a race between hardware
+ * and rx_to_clean when in NAPI mode */
+ if(RU_SUSPENDED == nic->ru_running)
+ restart_required = 1;
/* Indicate newly arrived packets */
for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) {
- if(e100_rx_indicate(nic, rx, work_done, work_to_do))
+ int err = e100_rx_indicate(nic, rx, work_done, work_to_do);
+ if(-EAGAIN == err) {
+ /* hit quota so have more work to do, restart once
+ * cleanup is complete */
+ restart_required = 0;
+ break;
+ } else if(-ENODATA == err)
break; /* No more to clean */
}
+ /* save our starting point as the place we'll restart the receiver */
+ if(restart_required)
+ rx_to_start = nic->rx_to_clean;
+
/* Alloc new skbs to refill list */
for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
if(unlikely(e100_rx_alloc_skb(nic, rx)))
break; /* Better luck next time (see watchdog) */
}
+
+ if(restart_required) {
+ // ack the rnr?
+ writeb(stat_ack_rnr, &nic->csr->scb.stat_ack);
+ e100_start_receiver(nic, rx_to_start);
+ if(work_done)
+ (*work_done)++;
+ }
}
static void e100_rx_clean_list(struct nic *nic)
@@ -1862,6 +1908,8 @@ static void e100_rx_clean_list(struct nic *nic)
struct rx *rx;
unsigned int i, count = nic->params.rfds.count;
+ nic->ru_running = RU_UNINITIALIZED;
+
if(nic->rxs) {
for(rx = nic->rxs, i = 0; i < count; rx++, i++) {
if(rx->skb) {
@@ -1883,6 +1931,7 @@ static int e100_rx_alloc_list(struct nic *nic)
unsigned int i, count = nic->params.rfds.count;
nic->rx_to_use = nic->rx_to_clean = NULL;
+ nic->ru_running = RU_UNINITIALIZED;
if(!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC)))
return -ENOMEM;
@@ -1897,6 +1946,7 @@ static int e100_rx_alloc_list(struct nic *nic)
}
nic->rx_to_use = nic->rx_to_clean = nic->rxs;
+ nic->ru_running = RU_SUSPENDED;
return 0;
}
@@ -1916,6 +1966,10 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
/* Ack interrupt(s) */
iowrite8(stat_ack, &nic->csr->scb.stat_ack);
+ /* We hit Receive No Resource (RNR); restart RU after cleaning */
+ if(stat_ack & stat_ack_rnr)
+ nic->ru_running = RU_SUSPENDED;
+
if(likely(netif_rx_schedule_prep(netdev))) {
e100_disable_irq(nic);
__netif_rx_schedule(netdev);
@@ -2007,7 +2061,7 @@ static int e100_up(struct nic *nic)
if((err = e100_hw_init(nic)))
goto err_clean_cbs;
e100_set_multicast_list(nic->netdev);
- e100_start_receiver(nic);
+ e100_start_receiver(nic, NULL);
mod_timer(&nic->watchdog, jiffies);
if((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED,
nic->netdev->name, nic->netdev)))
@@ -2088,7 +2142,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
BMCR_LOOPBACK);
- e100_start_receiver(nic);
+ e100_start_receiver(nic, NULL);
if(!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) {
err = -ENOMEM;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index cbc7febe9cd..cf8af928a69 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1142,13 +1142,16 @@ e1000_probe(struct pci_dev *pdev,
!e1000_check_mng_mode(&adapter->hw))
e1000_get_hw_control(adapter);
- strcpy(netdev->name, "eth%d");
- if ((err = register_netdev(netdev)))
- goto err_register;
-
/* tell the stack to leave us alone until e1000_open() is called */
netif_carrier_off(netdev);
netif_stop_queue(netdev);
+#ifdef CONFIG_E1000_NAPI
+ netif_poll_disable(netdev);
+#endif
+
+ strcpy(netdev->name, "eth%d");
+ if ((err = register_netdev(netdev)))
+ goto err_register;
DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
@@ -1325,7 +1328,10 @@ e1000_sw_init(struct e1000_adapter *adapter)
spin_lock_init(&adapter->tx_queue_lock);
#endif
- atomic_set(&adapter->irq_sem, 1);
+ /* Explicitly disable IRQ since the NIC can be in any state. */
+ atomic_set(&adapter->irq_sem, 0);
+ e1000_irq_disable(adapter);
+
spin_lock_init(&adapter->stats_lock);
set_bit(__E1000_DOWN, &adapter->flags);
@@ -1431,6 +1437,10 @@ e1000_open(struct net_device *netdev)
/* From here on the code is the same as e1000_up() */
clear_bit(__E1000_DOWN, &adapter->flags);
+#ifdef CONFIG_E1000_NAPI
+ netif_poll_enable(netdev);
+#endif
+
e1000_irq_enable(adapter);
/* fire a link status change interrupt to start the watchdog */
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 602872dbe15..c0f81b5a30f 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0058"
+#define DRV_VERSION "EHEA_0064"
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index f6e0cb1ada1..9e13433a268 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -428,7 +428,7 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
}
skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
cqe->num_bytes_transfered - 4);
- ehea_fill_skb(dev, skb, cqe);
+ ehea_fill_skb(port->netdev, skb, cqe);
} else if (rq == 2) { /* RQ2 */
skb = get_skb_by_index(skb_arr_rq2,
skb_arr_rq2_len, cqe);
@@ -451,7 +451,8 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
processed_rq3++;
}
- if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT)
+ if ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT)
+ && port->vgrp)
vlan_hwaccel_receive_skb(skb, port->vgrp,
cqe->vlan_tag);
else
@@ -1910,10 +1911,7 @@ static void ehea_vlan_rx_register(struct net_device *dev,
goto out;
}
- if (grp)
- memset(cb1->vlan_filter, 0, sizeof(cb1->vlan_filter));
- else
- memset(cb1->vlan_filter, 0xFF, sizeof(cb1->vlan_filter));
+ memset(cb1->vlan_filter, 0, sizeof(cb1->vlan_filter));
hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
@@ -1947,7 +1945,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
}
index = (vid / 64);
- cb1->vlan_filter[index] |= ((u64)(1 << (vid & 0x3F)));
+ cb1->vlan_filter[index] |= ((u64)(0x8000000000000000 >> (vid & 0x3F)));
hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
@@ -1982,7 +1980,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
}
index = (vid / 64);
- cb1->vlan_filter[index] &= ~((u64)(1 << (vid & 0x3F)));
+ cb1->vlan_filter[index] &= ~((u64)(0x8000000000000000 >> (vid & 0x3F)));
hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id,
H_PORT_CB1, H_PORT_CB1_ALL, cb1);
diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c
index 88efe9731ba..e5502af5b8e 100644
--- a/drivers/net/fec_8xx/fec_main.c
+++ b/drivers/net/fec_8xx/fec_main.c
@@ -550,7 +550,7 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget)
skbn = dev_alloc_skb(pkt_len + 2);
if (skbn != NULL) {
skb_reserve(skbn, 2); /* align IP header */
- skb_copy_from_linear_data(skb
+ skb_copy_from_linear_data(skb,
skbn->data,
pkt_len);
/* swap */
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 7a018027fcc..32788ca40d2 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -195,7 +195,7 @@ enum {
#define NVREG_IRQ_TX_FORCED 0x0100
#define NVREG_IRQ_RECOVER_ERROR 0x8000
#define NVREG_IRQMASK_THROUGHPUT 0x00df
-#define NVREG_IRQMASK_CPU 0x0040
+#define NVREG_IRQMASK_CPU 0x0060
#define NVREG_IRQ_TX_ALL (NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
#define NVREG_IRQ_RX_ALL (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
#define NVREG_IRQ_OTHER (NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)
@@ -4605,12 +4605,7 @@ static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
writel(np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
spin_unlock_irq(&np->lock);
-};
-
-static void nv_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- /* nothing to do */
-};
+}
/* The mgmt unit and driver use a semaphore to access the phy during init */
static int nv_mgmt_acquire_sema(struct net_device *dev)
@@ -4956,7 +4951,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->vlanctl_bits = NVREG_VLANCONTROL_ENABLE;
dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
dev->vlan_rx_register = nv_vlan_rx_register;
- dev->vlan_rx_kill_vid = nv_vlan_rx_kill_vid;
}
np->msi_flags = 0;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index f5b3cba23fc..6822bf14267 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -140,7 +140,6 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
static void gfar_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
-static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
void gfar_halt(struct net_device *dev);
void gfar_start(struct net_device *dev);
static void gfar_clear_exact_match(struct net_device *dev);
@@ -284,7 +283,6 @@ static int gfar_probe(struct platform_device *pdev)
if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
dev->vlan_rx_register = gfar_vlan_rx_register;
- dev->vlan_rx_kill_vid = gfar_vlan_rx_kill_vid;
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
@@ -1133,20 +1131,6 @@ static void gfar_vlan_rx_register(struct net_device *dev,
spin_unlock_irqrestore(&priv->rxlock, flags);
}
-
-static void gfar_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
-{
- struct gfar_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->rxlock, flags);
-
- vlan_group_set_device(priv->vlgrp, vid, NULL);
-
- spin_unlock_irqrestore(&priv->rxlock, flags);
-}
-
-
static int gfar_change_mtu(struct net_device *dev, int new_mtu)
{
int tempsize, tempval;
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 8118a6750b6..8caa591c564 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -3005,7 +3005,7 @@ static int __init hp100_isa_init(void)
return cards > 0 ? 0 : -ENODEV;
}
-static void __exit hp100_isa_cleanup(void)
+static void hp100_isa_cleanup(void)
{
int i;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 3bec0f733f0..6ec3d500f33 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -915,17 +915,36 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
{
struct ibmveth_adapter *adapter = dev->priv;
int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH;
- int i;
+ int reinit = 0;
+ int i, rc;
if (new_mtu < IBMVETH_MAX_MTU)
return -EINVAL;
+ for (i = 0; i < IbmVethNumBufferPools; i++)
+ if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size)
+ break;
+
+ if (i == IbmVethNumBufferPools)
+ return -EINVAL;
+
/* Look for an active buffer pool that can hold the new MTU */
for(i = 0; i<IbmVethNumBufferPools; i++) {
- if (!adapter->rx_buff_pool[i].active)
- continue;
+ if (!adapter->rx_buff_pool[i].active) {
+ adapter->rx_buff_pool[i].active = 1;
+ reinit = 1;
+ }
+
if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) {
- dev->mtu = new_mtu;
+ if (reinit && netif_running(adapter->netdev)) {
+ adapter->pool_config = 1;
+ ibmveth_close(adapter->netdev);
+ adapter->pool_config = 0;
+ dev->mtu = new_mtu;
+ if ((rc = ibmveth_open(adapter->netdev)))
+ return rc;
+ } else
+ dev->mtu = new_mtu;
return 0;
}
}
@@ -1243,16 +1262,19 @@ const char * buf, size_t count)
if (attr == &veth_active_attr) {
if (value && !pool->active) {
- if(ibmveth_alloc_buffer_pool(pool)) {
- ibmveth_error_printk("unable to alloc pool\n");
- return -ENOMEM;
- }
- pool->active = 1;
- adapter->pool_config = 1;
- ibmveth_close(netdev);
- adapter->pool_config = 0;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ if (netif_running(netdev)) {
+ if(ibmveth_alloc_buffer_pool(pool)) {
+ ibmveth_error_printk("unable to alloc pool\n");
+ return -ENOMEM;
+ }
+ pool->active = 1;
+ adapter->pool_config = 1;
+ ibmveth_close(netdev);
+ adapter->pool_config = 0;
+ if ((rc = ibmveth_open(netdev)))
+ return rc;
+ } else
+ pool->active = 1;
} else if (!value && pool->active) {
int mtu = netdev->mtu + IBMVETH_BUFF_OH;
int i;
@@ -1281,23 +1303,29 @@ const char * buf, size_t count)
if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT)
return -EINVAL;
else {
- adapter->pool_config = 1;
- ibmveth_close(netdev);
- adapter->pool_config = 0;
- pool->size = value;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ if (netif_running(netdev)) {
+ adapter->pool_config = 1;
+ ibmveth_close(netdev);
+ adapter->pool_config = 0;
+ pool->size = value;
+ if ((rc = ibmveth_open(netdev)))
+ return rc;
+ } else
+ pool->size = value;
}
} else if (attr == &veth_size_attr) {
if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE)
return -EINVAL;
else {
- adapter->pool_config = 1;
- ibmveth_close(netdev);
- adapter->pool_config = 0;
- pool->buff_size = value;
- if ((rc = ibmveth_open(netdev)))
- return rc;
+ if (netif_running(netdev)) {
+ adapter->pool_config = 1;
+ ibmveth_close(netdev);
+ adapter->pool_config = 0;
+ pool->buff_size = value;
+ if ((rc = ibmveth_open(netdev)))
+ return rc;
+ } else
+ pool->buff_size = value;
}
}
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 0343ea12b29..92b403bf38b 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -8,15 +8,16 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h> /* printk() */
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/errno.h> /* error codes */
-#include <linux/types.h> /* size_t */
-#include <linux/interrupt.h> /* mark_bh */
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/in6.h>
@@ -33,7 +34,6 @@
#include <asm/io.h>
#include <asm/scatterlist.h>
-#include <linux/dma-mapping.h>
#include "meth.h"
@@ -51,8 +51,6 @@
static const char *meth_str="SGI O2 Fast Ethernet";
-MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>");
-MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
#define HAVE_TX_TIMEOUT
/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */
@@ -784,15 +782,15 @@ static struct net_device_stats *meth_stats(struct net_device *dev)
/*
* The init function.
*/
-static struct net_device *meth_init(void)
+static int __init meth_probe(struct platform_device *pdev)
{
struct net_device *dev;
struct meth_private *priv;
- int ret;
+ int err;
dev = alloc_etherdev(sizeof(struct meth_private));
if (!dev)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
dev->open = meth_open;
dev->stop = meth_release;
@@ -808,11 +806,12 @@ static struct net_device *meth_init(void)
priv = netdev_priv(dev);
spin_lock_init(&priv->meth_lock);
+ SET_NETDEV_DEV(dev, &pdev->dev);
- ret = register_netdev(dev);
- if (ret) {
+ err = register_netdev(dev);
+ if (err) {
free_netdev(dev);
- return ERR_PTR(ret);
+ return err;
}
printk(KERN_INFO "%s: SGI MACE Ethernet rev. %d\n",
@@ -820,21 +819,44 @@ static struct net_device *meth_init(void)
return 0;
}
-static struct net_device *meth_dev;
+static int __exit meth_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ unregister_netdev(dev);
+ free_netdev(dev);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver meth_driver = {
+ .probe = meth_probe,
+ .remove = __devexit_p(meth_remove),
+ .driver = {
+ .name = "meth",
+ }
+};
static int __init meth_init_module(void)
{
- meth_dev = meth_init();
- if (IS_ERR(meth_dev))
- return PTR_ERR(meth_dev);
- return 0;
+ int err;
+
+ err = platform_driver_register(&meth_driver);
+ if (err)
+ printk(KERN_ERR "Driver registration failed\n");
+
+ return err;
}
static void __exit meth_exit_module(void)
{
- unregister_netdev(meth_dev);
- free_netdev(meth_dev);
+ platform_driver_unregister(&meth_driver);
}
module_init(meth_init_module);
module_exit(meth_exit_module);
+
+MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>");
+MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index dfbd5809d74..f8d63d39f59 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -51,8 +51,8 @@ u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap)
if (obj < bitmap->max) {
set_bit(obj, bitmap->table);
+ bitmap->last = (obj + 1) & (bitmap->max - 1);
obj |= bitmap->top;
- bitmap->last = obj + 1;
} else
obj = -1;
diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c
index 437d78ad091..39253d0c159 100644
--- a/drivers/net/mlx4/cq.c
+++ b/drivers/net/mlx4/cq.c
@@ -61,7 +61,7 @@ struct mlx4_cq_context {
__be32 solicit_producer_index;
__be32 consumer_index;
__be32 producer_index;
- u8 reserved6[2];
+ u32 reserved6[2];
__be64 db_rec_addr;
};
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 0f11adb8eb4..27a82cecd69 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -490,9 +490,11 @@ static void mlx4_free_irqs(struct mlx4_dev *dev)
if (eq_table->have_irq)
free_irq(dev->pdev->irq, dev);
- for (i = 0; i < MLX4_NUM_EQ; ++i)
+ for (i = 0; i < MLX4_EQ_CATAS; ++i)
if (eq_table->eq[i].have_irq)
free_irq(eq_table->eq[i].irq, eq_table->eq + i);
+ if (eq_table->eq[MLX4_EQ_CATAS].have_irq)
+ free_irq(eq_table->eq[MLX4_EQ_CATAS].irq, dev);
}
static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev)
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index cfa5cc07233..e7ca118c8df 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -37,6 +37,10 @@
#include "fw.h"
#include "icm.h"
+enum {
+ MLX4_COMMAND_INTERFACE_REV = 1
+};
+
extern void __buggy_use_of_MLX4_GET(void);
extern void __buggy_use_of_MLX4_PUT(void);
@@ -452,10 +456,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
u32 *outbox;
int err = 0;
u64 fw_ver;
+ u16 cmd_if_rev;
u8 lg;
#define QUERY_FW_OUT_SIZE 0x100
#define QUERY_FW_VER_OFFSET 0x00
+#define QUERY_FW_CMD_IF_REV_OFFSET 0x0a
#define QUERY_FW_MAX_CMD_OFFSET 0x0f
#define QUERY_FW_ERR_START_OFFSET 0x30
#define QUERY_FW_ERR_SIZE_OFFSET 0x38
@@ -477,21 +483,36 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev)
MLX4_GET(fw_ver, outbox, QUERY_FW_VER_OFFSET);
/*
- * FW subminor version is at more signifant bits than minor
+ * FW subminor version is at more significant bits than minor
* version, so swap here.
*/
dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) |
((fw_ver & 0xffff0000ull) >> 16) |
((fw_ver & 0x0000ffffull) << 16);
+ MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET);
+ if (cmd_if_rev != MLX4_COMMAND_INTERFACE_REV) {
+ mlx4_err(dev, "Installed FW has unsupported "
+ "command interface revision %d.\n",
+ cmd_if_rev);
+ mlx4_err(dev, "(Installed FW version is %d.%d.%03d)\n",
+ (int) (dev->caps.fw_ver >> 32),
+ (int) (dev->caps.fw_ver >> 16) & 0xffff,
+ (int) dev->caps.fw_ver & 0xffff);
+ mlx4_err(dev, "This driver version supports only revision %d.\n",
+ MLX4_COMMAND_INTERFACE_REV);
+ err = -ENODEV;
+ goto out;
+ }
+
MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET);
cmd->max_cmds = 1 << lg;
- mlx4_dbg(dev, "FW version %d.%d.%03d, max commands %d\n",
+ mlx4_dbg(dev, "FW version %d.%d.%03d (cmd intf rev %d), max commands %d\n",
(int) (dev->caps.fw_ver >> 32),
(int) (dev->caps.fw_ver >> 16) & 0xffff,
(int) dev->caps.fw_ver & 0xffff,
- cmd->max_cmds);
+ cmd_if_rev, cmd->max_cmds);
MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET);
MLX4_GET(fw->catas_size, outbox, QUERY_FW_ERR_SIZE_OFFSET);
diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c
index 65854f9e9c7..9ae951bf6aa 100644
--- a/drivers/net/mlx4/intf.c
+++ b/drivers/net/mlx4/intf.c
@@ -135,9 +135,6 @@ int mlx4_register_device(struct mlx4_dev *dev)
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_interface *intf;
- INIT_LIST_HEAD(&priv->ctx_list);
- spin_lock_init(&priv->ctx_lock);
-
mutex_lock(&intf_mutex);
list_add_tail(&priv->dev_list, &dev_list);
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 20b8c0d3ced..d4172937025 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -787,6 +787,8 @@ static int __devinit mlx4_init_one(struct pci_dev *pdev,
dev = &priv->dev;
dev->pdev = pdev;
+ INIT_LIST_HEAD(&priv->ctx_list);
+ spin_lock_init(&priv->ctx_lock);
/*
* Now reset the HCA before we touch the PCI capabilities or
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index b33864dab17..d0808fa3ec8 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -324,15 +324,17 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
MLX4_MPT_FLAG_MIO |
MLX4_MPT_FLAG_REGION |
mr->access);
- if (mr->mtt.order < 0)
- mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL);
mpt_entry->key = cpu_to_be32(key_to_hw_index(mr->key));
mpt_entry->pd = cpu_to_be32(mr->pd);
mpt_entry->start = cpu_to_be64(mr->iova);
mpt_entry->length = cpu_to_be64(mr->size);
mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift);
- mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt));
+ if (mr->mtt.order < 0) {
+ mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL);
+ mpt_entry->mtt_seg = 0;
+ } else
+ mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt));
err = mlx4_SW2HW_MPT(dev, mailbox,
key_to_hw_index(mr->key) & (dev->caps.num_mpts - 1));
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 5d14be7405a..0f9904fe3a5 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -71,7 +71,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.3.0-1.233"
+#define MYRI10GE_VERSION_STR "1.3.1-1.248"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -279,6 +279,8 @@ static int myri10ge_fill_thresh = 256;
module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
+static int myri10ge_reset_recover = 1;
+
static int myri10ge_wcfifo = 0;
module_param(myri10ge_wcfifo, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
@@ -1154,9 +1156,11 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
struct mcp_irq_data *stats = mgp->fw_stats;
if (unlikely(stats->stats_updated)) {
- if (mgp->link_state != stats->link_up) {
- mgp->link_state = stats->link_up;
- if (mgp->link_state) {
+ unsigned link_up = ntohl(stats->link_up);
+ if (mgp->link_state != link_up) {
+ mgp->link_state = link_up;
+
+ if (mgp->link_state == MXGEFW_LINK_UP) {
if (netif_msg_link(mgp))
printk(KERN_INFO
"myri10ge: %s: link up\n",
@@ -1166,8 +1170,11 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
} else {
if (netif_msg_link(mgp))
printk(KERN_INFO
- "myri10ge: %s: link down\n",
- mgp->dev->name);
+ "myri10ge: %s: link %s\n",
+ mgp->dev->name,
+ (link_up == MXGEFW_LINK_MYRINET ?
+ "mismatch (Myrinet detected)" :
+ "down"));
netif_carrier_off(mgp->dev);
mgp->link_changes++;
}
@@ -1472,6 +1479,7 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
.set_sg = ethtool_op_set_sg,
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
+ .get_link = ethtool_op_get_link,
.get_strings = myri10ge_get_strings,
.get_stats_count = myri10ge_get_stats_count,
.get_ethtool_stats = myri10ge_get_ethtool_stats,
@@ -2729,8 +2737,14 @@ static void myri10ge_watchdog(struct work_struct *work)
* For now, just report it */
reboot = myri10ge_read_reboot(mgp);
printk(KERN_ERR
- "myri10ge: %s: NIC rebooted (0x%x), resetting\n",
- mgp->dev->name, reboot);
+ "myri10ge: %s: NIC rebooted (0x%x),%s resetting\n",
+ mgp->dev->name, reboot,
+ myri10ge_reset_recover ? " " : " not");
+ if (myri10ge_reset_recover == 0)
+ return;
+
+ myri10ge_reset_recover--;
+
/*
* A rebooted nic will come back with config space as
* it was after power was applied to PCIe bus.
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index ad6688eab26..91f25e0a638 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -68,9 +68,10 @@
#define _NETXEN_NIC_LINUX_SUBVERSION 2
#define NETXEN_NIC_LINUX_VERSIONID "3.4.2"
-#define NUM_FLASH_SECTORS (64)
-#define FLASH_SECTOR_SIZE (64 * 1024)
-#define FLASH_TOTAL_SIZE (NUM_FLASH_SECTORS * FLASH_SECTOR_SIZE)
+#define NETXEN_NUM_FLASH_SECTORS (64)
+#define NETXEN_FLASH_SECTOR_SIZE (64 * 1024)
+#define NETXEN_FLASH_TOTAL_SIZE (NETXEN_NUM_FLASH_SECTORS \
+ * NETXEN_FLASH_SECTOR_SIZE)
#define PHAN_VENDOR_ID 0x4040
@@ -677,28 +678,28 @@ struct netxen_new_user_info {
/* Flash memory map */
typedef enum {
- CRBINIT_START = 0, /* Crbinit section */
- BRDCFG_START = 0x4000, /* board config */
- INITCODE_START = 0x6000, /* pegtune code */
- BOOTLD_START = 0x10000, /* bootld */
- IMAGE_START = 0x43000, /* compressed image */
- SECONDARY_START = 0x200000, /* backup images */
- PXE_START = 0x3E0000, /* user defined region */
- USER_START = 0x3E8000, /* User defined region for new boards */
- FIXED_START = 0x3F0000 /* backup of crbinit */
+ NETXEN_CRBINIT_START = 0, /* Crbinit section */
+ NETXEN_BRDCFG_START = 0x4000, /* board config */
+ NETXEN_INITCODE_START = 0x6000, /* pegtune code */
+ NETXEN_BOOTLD_START = 0x10000, /* bootld */
+ NETXEN_IMAGE_START = 0x43000, /* compressed image */
+ NETXEN_SECONDARY_START = 0x200000, /* backup images */
+ NETXEN_PXE_START = 0x3E0000, /* user defined region */
+ NETXEN_USER_START = 0x3E8000, /* User defined region for new boards */
+ NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */
} netxen_flash_map_t;
-#define USER_START_OLD PXE_START /* for backward compatibility */
-
-#define FLASH_START (CRBINIT_START)
-#define INIT_SECTOR (0)
-#define PRIMARY_START (BOOTLD_START)
-#define FLASH_CRBINIT_SIZE (0x4000)
-#define FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info))
-#define FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32))
-#define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START)
-#define NUM_PRIMARY_SECTORS (0x20)
-#define NUM_CONFIG_SECTORS (1)
+#define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */
+
+#define NETXEN_FLASH_START (NETXEN_CRBINIT_START)
+#define NETXEN_INIT_SECTOR (0)
+#define NETXEN_PRIMARY_START (NETXEN_BOOTLD_START)
+#define NETXEN_FLASH_CRBINIT_SIZE (0x4000)
+#define NETXEN_FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info))
+#define NETXEN_FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32))
+#define NETXEN_FLASH_SECONDARY_SIZE (NETXEN_USER_START-NETXEN_SECONDARY_START)
+#define NETXEN_NUM_PRIMARY_SECTORS (0x20)
+#define NETXEN_NUM_CONFIG_SECTORS (1)
#define PFX "NetXen: "
extern char netxen_nic_driver_name[];
@@ -1048,6 +1049,7 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr);
int netxen_do_rom_se(struct netxen_adapter *adapter, int addr);
/* Functions from netxen_nic_isr.c */
+int netxen_nic_link_ok(struct netxen_adapter *adapter);
void netxen_nic_isr_other(struct netxen_adapter *adapter);
void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link);
void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable);
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 16fabb37748..0175f6c353f 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -94,7 +94,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
static int netxen_nic_get_eeprom_len(struct net_device *dev)
{
- return FLASH_TOTAL_SIZE;
+ return NETXEN_FLASH_TOTAL_SIZE;
}
static void
@@ -470,7 +470,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return 0;
}
- if (offset == BOOTLD_START) {
+ if (offset == NETXEN_BOOTLD_START) {
ret = netxen_flash_erase_primary(adapter);
if (ret != FLASH_SUCCESS) {
printk(KERN_ERR "%s: Flash erase failed.\n",
@@ -478,10 +478,10 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return ret;
}
- ret = netxen_rom_se(adapter, USER_START);
+ ret = netxen_rom_se(adapter, NETXEN_USER_START);
if (ret != FLASH_SUCCESS)
return ret;
- ret = netxen_rom_se(adapter, FIXED_START);
+ ret = netxen_rom_se(adapter, NETXEN_FIXED_START);
if (ret != FLASH_SUCCESS)
return ret;
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index baff17a24d6..c012764d114 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -257,7 +257,7 @@ u64 ctx_addr_sig_regs[][3] = {
#define ADDR_IN_RANGE(addr, low, high) \
(((addr) <= (high)) && ((addr) >= (low)))
-#define NETXEN_FLASH_BASE (BOOTLD_START)
+#define NETXEN_FLASH_BASE (NETXEN_BOOTLD_START)
#define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE)
#define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
#define NETXEN_MIN_MTU 64
@@ -611,7 +611,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
u32 *pmac = (u32 *) & mac[0];
if (netxen_get_flash_block(adapter,
- USER_START +
+ NETXEN_USER_START +
offsetof(struct netxen_new_user_info,
mac_addr),
FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
@@ -619,7 +619,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
}
if (*mac == ~0ULL) {
if (netxen_get_flash_block(adapter,
- USER_START_OLD +
+ NETXEN_USER_START_OLD +
offsetof(struct netxen_user_old_info,
mac_addr),
FLASH_NUM_PORTS * sizeof(u64),
@@ -942,7 +942,7 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
int
netxen_nic_erase_pxe(struct netxen_adapter *adapter)
{
- if (netxen_rom_fast_write(adapter, PXE_START, 0) == -1) {
+ if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) {
printk(KERN_ERR "%s: erase pxe failed\n",
netxen_nic_driver_name);
return -1;
@@ -953,7 +953,7 @@ netxen_nic_erase_pxe(struct netxen_adapter *adapter)
int netxen_nic_get_board_info(struct netxen_adapter *adapter)
{
int rv = 0;
- int addr = BRDCFG_START;
+ int addr = NETXEN_BRDCFG_START;
struct netxen_board_info *boardinfo;
int index;
u32 *ptr32;
@@ -1115,7 +1115,7 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
u32 fw_build = 0;
char brd_name[NETXEN_MAX_SHORT_NAME];
struct netxen_new_user_info user_info;
- int i, addr = USER_START;
+ int i, addr = NETXEN_USER_START;
__le32 *ptr32;
struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index a3689245776..bb23f4c360d 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -585,7 +585,7 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter)
{
int ret = FLASH_SUCCESS;
int val;
- char *buffer = kmalloc(FLASH_SECTOR_SIZE, GFP_KERNEL);
+ char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
@@ -601,13 +601,13 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter)
goto out_kfree;
/* copy sector 0 to sector 63 */
- ret = netxen_rom_fast_read_words(adapter, CRBINIT_START,
- buffer, FLASH_SECTOR_SIZE);
+ ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START,
+ buffer, NETXEN_FLASH_SECTOR_SIZE);
if (ret != FLASH_SUCCESS)
goto out_kfree;
- ret = netxen_rom_fast_write_words(adapter, FIXED_START,
- buffer, FLASH_SECTOR_SIZE);
+ ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START,
+ buffer, NETXEN_FLASH_SECTOR_SIZE);
if (ret != FLASH_SUCCESS)
goto out_kfree;
@@ -654,7 +654,8 @@ void check_erased_flash(struct netxen_adapter *adapter, int addr)
int count = 0, erased_errors = 0;
int range;
- range = (addr == USER_START) ? FIXED_START : addr + FLASH_SECTOR_SIZE;
+ range = (addr == NETXEN_USER_START) ?
+ NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE;
for (i = addr; i < range; i += 4) {
netxen_rom_fast_read(adapter, i, &val);
@@ -689,7 +690,7 @@ netxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end)
int i;
for (i = start; i < end; i++) {
- ret = netxen_rom_se(adapter, i * FLASH_SECTOR_SIZE);
+ ret = netxen_rom_se(adapter, i * NETXEN_FLASH_SECTOR_SIZE);
if (ret)
break;
ret = netxen_rom_wip_poll(adapter);
@@ -706,8 +707,8 @@ netxen_flash_erase_secondary(struct netxen_adapter *adapter)
int ret = FLASH_SUCCESS;
int start, end;
- start = SECONDARY_START / FLASH_SECTOR_SIZE;
- end = USER_START / FLASH_SECTOR_SIZE;
+ start = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
+ end = NETXEN_USER_START / NETXEN_FLASH_SECTOR_SIZE;
ret = netxen_flash_erase_sections(adapter, start, end);
return ret;
@@ -719,8 +720,8 @@ netxen_flash_erase_primary(struct netxen_adapter *adapter)
int ret = FLASH_SUCCESS;
int start, end;
- start = PRIMARY_START / FLASH_SECTOR_SIZE;
- end = SECONDARY_START / FLASH_SECTOR_SIZE;
+ start = NETXEN_PRIMARY_START / NETXEN_FLASH_SECTOR_SIZE;
+ end = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
ret = netxen_flash_erase_sections(adapter, start, end);
return ret;
@@ -1036,18 +1037,23 @@ void netxen_watchdog_task(struct work_struct *work)
if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter))
return;
+ if (adapter->handle_phy_intr)
+ adapter->handle_phy_intr(adapter);
+
netdev = adapter->netdev;
- if ((netif_running(netdev)) && !netif_carrier_ok(netdev)) {
- printk(KERN_INFO "%s port %d, %s carrier is now ok\n",
- netxen_nic_driver_name, adapter->portnum, netdev->name);
+ if ((netif_running(netdev)) && !netif_carrier_ok(netdev) &&
+ netxen_nic_link_ok(adapter) ) {
+ printk(KERN_INFO "%s %s (port %d), Link is up\n",
+ netxen_nic_driver_name, netdev->name, adapter->portnum);
netif_carrier_on(netdev);
- }
-
- if (netif_queue_stopped(netdev))
netif_wake_queue(netdev);
+ } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) {
+ printk(KERN_ERR "%s %s Link is Down\n",
+ netxen_nic_driver_name, netdev->name);
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
- if (adapter->handle_phy_intr)
- adapter->handle_phy_intr(adapter);
mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
}
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c
index b213b062eb5..b2de6b6c2a7 100644
--- a/drivers/net/netxen/netxen_nic_isr.c
+++ b/drivers/net/netxen/netxen_nic_isr.c
@@ -169,6 +169,24 @@ void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter)
netxen_nic_isr_other(adapter);
}
+int netxen_nic_link_ok(struct netxen_adapter *adapter)
+{
+ switch (adapter->ahw.board_type) {
+ case NETXEN_NIC_GBE:
+ return ((adapter->ahw.qg_linksup) & 1);
+
+ case NETXEN_NIC_XGBE:
+ return ((adapter->ahw.xg_linkup) & 1);
+
+ default:
+ printk(KERN_ERR"%s: Function: %s, Unknown board type\n",
+ netxen_nic_driver_name, __FUNCTION__);
+ break;
+ }
+
+ return 0;
+}
+
void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
@@ -183,6 +201,10 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
printk(KERN_INFO "%s: %s NIC Link is down\n",
netxen_nic_driver_name, netdev->name);
adapter->ahw.xg_linkup = 0;
+ if (netif_running(netdev)) {
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
/* read twice to clear sticky bits */
/* WINDOW = 0 */
netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);
@@ -196,5 +218,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
printk(KERN_INFO "%s: %s NIC Link is up\n",
netxen_nic_driver_name, netdev->name);
adapter->ahw.xg_linkup = 1;
+ netif_carrier_on(netdev);
+ netif_wake_queue(netdev);
}
}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 2c5c6d20e6e..6167b58d273 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -542,6 +542,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
/* Handshake with the card before we register the devices. */
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+
+ /* leave the hw in the same state as reboot */
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+ netxen_pinit_from_rom(adapter, 0);
+ udelay(500);
+ netxen_load_firmware(adapter);
+ netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
}
/*
@@ -654,8 +661,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->portnum == 0)
netxen_free_adapter_offload(adapter);
- if (adapter->irq)
- free_irq(adapter->irq, adapter);
if(adapter->portnum == 0) {
/* leave the hw in the same state as reboot */
writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index cef90a78351..75102d30730 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -454,16 +454,12 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
{
- u32 reg;
u32 portnum = physical_port[adapter->portnum];
netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5);
- netxen_nic_hw_read_wx(adapter,
- NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), &reg, 4);
- reg = (reg & ~0x2000UL);
+ NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447);
netxen_crb_writelit_adapter(adapter,
- NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), reg);
+ NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5);
return 0;
}
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 3439f8c649f..717d8e9b983 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -506,17 +506,6 @@ static void ns83820_vlan_rx_register(struct net_device *ndev, struct vlan_group
spin_unlock(&dev->tx_lock);
spin_unlock_irq(&dev->misc_lock);
}
-
-static void ns83820_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid)
-{
- struct ns83820 *dev = PRIV(ndev);
-
- spin_lock_irq(&dev->misc_lock);
- spin_lock(&dev->tx_lock);
- vlan_group_set_device(dev->vlgrp, vid, NULL);
- spin_unlock(&dev->tx_lock);
- spin_unlock_irq(&dev->misc_lock);
-}
#endif
/* Packet Receiver
@@ -2083,7 +2072,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
/* We also support hardware vlan acceleration */
ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
ndev->vlan_rx_register = ns83820_vlan_rx_register;
- ndev->vlan_rx_kill_vid = ns83820_vlan_rx_kill_vid;
#endif
if (using_dac) {
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 68c99b4c525..bb966911a13 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -89,6 +89,7 @@ EXPORT_SYMBOL(fixed_mdio_set_link_update);
/*-----------------------------------------------------------------------------
* This is used for updating internal mii regs from the status
*-----------------------------------------------------------------------------*/
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
static int fixed_mdio_update_regs(struct fixed_info *fixed)
{
u16 *regs = fixed->regs;
@@ -165,6 +166,7 @@ static int fixed_mii_reset(struct mii_bus *bus)
/*nothing here - no way/need to reset it*/
return 0;
}
+#endif
static int fixed_config_aneg(struct phy_device *phydev)
{
@@ -194,6 +196,7 @@ static struct phy_driver fixed_mdio_driver = {
* number is used to create multiple fixed PHYs, so that several devices can
* utilize them simultaneously.
*-----------------------------------------------------------------------------*/
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
static int fixed_mdio_register_device(int number, int speed, int duplex)
{
struct mii_bus *new_bus;
@@ -301,6 +304,7 @@ device_create_fail:
return err;
}
+#endif
MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 22aec5cce68..b87f8d2a888 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -54,6 +54,12 @@
#define MII_M1111_PHY_LED_CONTROL 0x18
#define MII_M1111_PHY_LED_DIRECT 0x4100
#define MII_M1111_PHY_LED_COMBINE 0x411c
+#define MII_M1111_PHY_EXT_CR 0x14
+#define MII_M1111_RX_DELAY 0x80
+#define MII_M1111_TX_DELAY 0x2
+#define MII_M1111_PHY_EXT_SR 0x1b
+#define MII_M1111_HWCFG_MODE_MASK 0xf
+#define MII_M1111_HWCFG_MODE_RGMII 0xb
MODULE_DESCRIPTION("Marvell PHY driver");
MODULE_AUTHOR("Andy Fleming");
@@ -131,6 +137,45 @@ static int marvell_config_aneg(struct phy_device *phydev)
return err;
}
+static int m88e1111_config_init(struct phy_device *phydev)
+{
+ int err;
+
+ if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+ (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) {
+ int temp;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
+ temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
+ if (temp < 0)
+ return temp;
+
+ temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
+
+ err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
+ if (err < 0)
+ return err;
+ }
+
+ temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
+ if (temp < 0)
+ return temp;
+
+ temp &= ~(MII_M1111_HWCFG_MODE_MASK);
+ temp |= MII_M1111_HWCFG_MODE_RGMII;
+
+ err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
+ if (err < 0)
+ return err;
+ }
+
+ err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
static int m88e1145_config_init(struct phy_device *phydev)
{
int err;
@@ -152,7 +197,7 @@ static int m88e1145_config_init(struct phy_device *phydev)
if (err < 0)
return err;
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR);
if (temp < 0)
return temp;
@@ -206,7 +251,7 @@ static struct phy_driver m88e1101_driver = {
.driver = {.owner = THIS_MODULE,},
};
-static struct phy_driver m88e1111s_driver = {
+static struct phy_driver m88e1111_driver = {
.phy_id = 0x01410cc0,
.phy_id_mask = 0xfffffff0,
.name = "Marvell 88E1111",
@@ -216,6 +261,7 @@ static struct phy_driver m88e1111s_driver = {
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
+ .config_init = &m88e1111_config_init,
.driver = {.owner = THIS_MODULE,},
};
@@ -241,9 +287,9 @@ static int __init marvell_init(void)
if (ret)
return ret;
- ret = phy_driver_register(&m88e1111s_driver);
+ ret = phy_driver_register(&m88e1111_driver);
if (ret)
- goto err1111s;
+ goto err1111;
ret = phy_driver_register(&m88e1145_driver);
if (ret)
@@ -251,9 +297,9 @@ static int __init marvell_init(void)
return 0;
- err1145:
- phy_driver_unregister(&m88e1111s_driver);
- err1111s:
+err1145:
+ phy_driver_unregister(&m88e1111_driver);
+err1111:
phy_driver_unregister(&m88e1101_driver);
return ret;
}
@@ -261,7 +307,7 @@ static int __init marvell_init(void)
static void __exit marvell_exit(void)
{
phy_driver_unregister(&m88e1101_driver);
- phy_driver_unregister(&m88e1111s_driver);
+ phy_driver_unregister(&m88e1111_driver);
phy_driver_unregister(&m88e1145_driver);
}
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index d5bdd257465..5ae80bbe2ed 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -493,14 +493,14 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
/*
* Make sure we have enough room to decrypt the packet.
- * Note that for our test we only subtract 1 byte whereas in
- * mppe_compress() we added 2 bytes (+MPPE_OVHD);
- * this is to account for possible PFC.
+ * To account for possible PFC we should only subtract 1
+ * byte whereas in mppe_compress() we added 2 bytes (+MPPE_OVHD);
+ * However, we assume no PFC, thus subtracting 2 bytes.
*/
- if (osize < isize - MPPE_OVHD - 1) {
+ if (osize < isize - MPPE_OVHD - 2) {
printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
"(have: %d need: %d)\n", state->unit,
- osize, isize - MPPE_OVHD - 1);
+ osize, isize - MPPE_OVHD - 2);
return DECOMP_ERROR;
}
osize = isize - MPPE_OVHD - 2; /* assume no PFC */
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index d8766c0e825..585be044ebb 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -4044,7 +4044,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
if (pci_using_dac)
ndev->features |= NETIF_F_HIGHDMA;
if (qdev->device_id == QL3032_DEVICE_ID)
- ndev->features |= (NETIF_F_HW_CSUM | NETIF_F_SG);
+ ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
qdev->mem_map_registers =
ioremap_nocache(pci_resource_start(pdev, 1),
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 45876a854f0..5ec7752caa4 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -886,16 +886,6 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,
spin_unlock_irqrestore(&tp->lock, flags);
}
-static void rtl8169_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct rtl8169_private *tp = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
- vlan_group_set_device(tp->vlgrp, vid, NULL);
- spin_unlock_irqrestore(&tp->lock, flags);
-}
-
static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
struct sk_buff *skb)
{
@@ -1671,7 +1661,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#ifdef CONFIG_R8169_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = rtl8169_vlan_rx_register;
- dev->vlan_rx_kill_vid = rtl8169_vlan_rx_kill_vid;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index e3e6d410d72..c6ba3dee8ae 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -340,17 +340,6 @@ static void s2io_vlan_rx_register(struct net_device *dev,
/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
static int vlan_strip_flag;
-/* Unregister the vlan */
-static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
-{
- struct s2io_nic *nic = dev->priv;
- unsigned long flags;
-
- spin_lock_irqsave(&nic->tx_lock, flags);
- vlan_group_set_device(nic->vlgrp, vid, NULL);
- spin_unlock_irqrestore(&nic->tx_lock, flags);
-}
-
/*
* Constants to be programmed into the Xena's registers, to configure
* the XAUI.
@@ -7412,7 +7401,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = s2io_vlan_rx_register;
- dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid;
/*
* will use eth_mac_addr() for dev->set_mac_address
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index fe847800acd..75afc1f07ba 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -1748,7 +1748,7 @@ char *addr_to_string(struct fddi_addr *addr)
#endif
#ifdef AM29K
-smt_ifconfig(int argc, char *argv[])
+int smt_ifconfig(int argc, char *argv[])
{
if (argc >= 2 && !strcmp(argv[0],"opt_bypass") &&
!strcmp(argv[1],"yes")) {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 832fd69a0e5..fe01b961b59 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -364,7 +364,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
/* for SFP-module set SIGDET polarity to low */
ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
ctrl |= PHY_M_FIB_SIGD_POL;
- gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
}
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
@@ -658,7 +658,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
const u8 *addr = hw->dev[port]->dev_addr;
sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
- sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
+ sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
@@ -1049,26 +1049,22 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
u16 port = sky2->port;
netif_tx_lock_bh(dev);
+ netif_poll_disable(sky2->hw->dev[0]);
- sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
- sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
sky2->vlgrp = grp;
+ if (grp) {
+ sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+ RX_VLAN_STRIP_ON);
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_VLAN_TAG_ON);
+ } else {
+ sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+ RX_VLAN_STRIP_OFF);
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_VLAN_TAG_OFF);
+ }
- netif_tx_unlock_bh(dev);
-}
-
-static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
- struct sky2_hw *hw = sky2->hw;
- u16 port = sky2->port;
-
- netif_tx_lock_bh(dev);
-
- sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
- sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
- vlan_group_set_device(sky2->vlgrp, vid, NULL);
-
+ netif_poll_enable(sky2->hw->dev[0]);
netif_tx_unlock_bh(dev);
}
#endif
@@ -1432,7 +1428,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
tcpsum = offset << 16; /* sum start */
tcpsum |= offset + skb->csum_offset; /* sum write */
- ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+ ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
if (ip_hdr(skb)->protocol == IPPROTO_UDP)
ctrl |= UDPTCP;
@@ -3484,7 +3480,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
#ifdef SKY2_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = sky2_vlan_rx_register;
- dev->vlan_rx_kill_vid = sky2_vlan_rx_kill_vid;
#endif
/* read the mac address */
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 5efb5afc45b..b8c4a3b5ead 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1149,7 +1149,7 @@ enum {
PHY_M_IS_JABBER = 1<<0, /* Jabber */
PHY_M_DEF_MSK = PHY_M_IS_LSP_CHANGE | PHY_M_IS_LST_CHANGE
- | PHY_M_IS_FIFO_ERROR,
+ | PHY_M_IS_DUP_CHANGE,
PHY_M_AN_MSK = PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL,
};
@@ -1732,28 +1732,6 @@ enum {
/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */
enum {
- GPC_SEL_BDT = 1<<28, /* Select Bi-Dir. Transfer for MDC/MDIO */
- GPC_INT_POL_HI = 1<<27, /* IRQ Polarity is Active HIGH */
- GPC_75_OHM = 1<<26, /* Use 75 Ohm Termination instead of 50 */
- GPC_DIS_FC = 1<<25, /* Disable Automatic Fiber/Copper Detection */
- GPC_DIS_SLEEP = 1<<24, /* Disable Energy Detect */
- GPC_HWCFG_M_3 = 1<<23, /* HWCFG_MODE[3] */
- GPC_HWCFG_M_2 = 1<<22, /* HWCFG_MODE[2] */
- GPC_HWCFG_M_1 = 1<<21, /* HWCFG_MODE[1] */
- GPC_HWCFG_M_0 = 1<<20, /* HWCFG_MODE[0] */
- GPC_ANEG_0 = 1<<19, /* ANEG[0] */
- GPC_ENA_XC = 1<<18, /* Enable MDI crossover */
- GPC_DIS_125 = 1<<17, /* Disable 125 MHz clock */
- GPC_ANEG_3 = 1<<16, /* ANEG[3] */
- GPC_ANEG_2 = 1<<15, /* ANEG[2] */
- GPC_ANEG_1 = 1<<14, /* ANEG[1] */
- GPC_ENA_PAUSE = 1<<13, /* Enable Pause (SYM_OR_REM) */
- GPC_PHYADDR_4 = 1<<12, /* Bit 4 of Phy Addr */
- GPC_PHYADDR_3 = 1<<11, /* Bit 3 of Phy Addr */
- GPC_PHYADDR_2 = 1<<10, /* Bit 2 of Phy Addr */
- GPC_PHYADDR_1 = 1<<9, /* Bit 1 of Phy Addr */
- GPC_PHYADDR_0 = 1<<8, /* Bit 0 of Phy Addr */
- /* Bits 7..2: reserved */
GPC_RST_CLR = 1<<1, /* Clear GPHY Reset */
GPC_RST_SET = 1<<0, /* Set GPHY Reset */
};
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 111f23d0576..506bffcbc6d 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -281,17 +281,14 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#elif defined(CONFIG_SUPERH)
-#if defined(CONFIG_SH_7780_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+#ifdef CONFIG_SOLUTION_ENGINE
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
-#define SMC_inb(a, r) (inw((a) + ((r)&~1)) >> (8*(r%2)))&0xff
#define SMC_inw(a, r) inw((a) + (r))
-#define SMC_outb(v, a, r) outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))
-
#define SMC_outw(v, a, r) outw(v, (a) + (r))
#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c3964c3d89d..b47ad1df2e0 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1014,12 +1014,12 @@ spider_net_pass_skb_up(struct spider_net_descr *descr,
*/
}
- /* pass skb up to stack */
- netif_receive_skb(skb);
-
/* update netdevice statistics */
card->netdev_stats.rx_packets++;
card->netdev_stats.rx_bytes += skb->len;
+
+ /* pass skb up to stack */
+ netif_receive_skb(skb);
}
#ifdef DEBUG
@@ -1191,43 +1191,6 @@ spider_net_poll(struct net_device *netdev, int *budget)
}
/**
- * spider_net_vlan_rx_reg - initializes VLAN structures in the driver and card
- * @netdev: interface device structure
- * @grp: vlan_group structure that is registered (NULL on destroying interface)
- */
-static void
-spider_net_vlan_rx_reg(struct net_device *netdev, struct vlan_group *grp)
-{
- /* further enhancement... yet to do */
- return;
-}
-
-/**
- * spider_net_vlan_rx_add - adds VLAN id to the card filter
- * @netdev: interface device structure
- * @vid: VLAN id to add
- */
-static void
-spider_net_vlan_rx_add(struct net_device *netdev, uint16_t vid)
-{
- /* further enhancement... yet to do */
- /* add vid to card's VLAN filter table */
- return;
-}
-
-/**
- * spider_net_vlan_rx_kill - removes VLAN id to the card filter
- * @netdev: interface device structure
- * @vid: VLAN id to remove
- */
-static void
-spider_net_vlan_rx_kill(struct net_device *netdev, uint16_t vid)
-{
- /* further enhancement... yet to do */
- /* remove vid from card's VLAN filter table */
-}
-
-/**
* spider_net_get_stats - get interface statistics
* @netdev: interface device structure
*
@@ -2177,9 +2140,6 @@ spider_net_setup_netdev_ops(struct net_device *netdev)
netdev->poll = &spider_net_poll;
netdev->weight = SPIDER_NET_NAPI_WEIGHT;
/* HW VLAN */
- netdev->vlan_rx_register = &spider_net_vlan_rx_reg;
- netdev->vlan_rx_add_vid = &spider_net_vlan_rx_add;
- netdev->vlan_rx_kill_vid = &spider_net_vlan_rx_kill;
#ifdef CONFIG_NET_POLL_CONTROLLER
/* poll controller */
netdev->poll_controller = &spider_net_poll_controller;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 923b9c725cc..2f3184184ad 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.76"
-#define DRV_MODULE_RELDATE "May 5, 2007"
+#define DRV_MODULE_VERSION "3.77"
+#define DRV_MODULE_RELDATE "May 31, 2007"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -9121,21 +9121,6 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
if (netif_running(dev))
tg3_netif_start(tp);
}
-
-static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct tg3 *tp = netdev_priv(dev);
-
- if (netif_running(dev))
- tg3_netif_stop(tp);
-
- tg3_full_lock(tp, 0);
- vlan_group_set_device(tp->vlgrp, vid, NULL);
- tg3_full_unlock(tp);
-
- if (netif_running(dev))
- tg3_netif_start(tp);
-}
#endif
static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
@@ -10976,6 +10961,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
* upon subsystem IDs.
*/
if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT |
TG3_FLAG_USE_LINKCHG_REG);
@@ -11778,7 +11764,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
#if TG3_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = tg3_vlan_rx_register;
- dev->vlan_rx_kill_vid = tg3_vlan_rx_kill_vid;
#endif
tp = netdev_priv(dev);
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
index 99c4c1922f1..e6b2e06493e 100644
--- a/drivers/net/tokenring/Kconfig
+++ b/drivers/net/tokenring/Kconfig
@@ -2,12 +2,10 @@
# Token Ring driver configuration
#
-menu "Token Ring devices"
- depends on NETDEVICES && !UML
-
# So far, we only have PCI, ISA, and MCA token ring devices
-config TR
+menuconfig TR
bool "Token Ring driver support"
+ depends on NETDEVICES && !UML
depends on (PCI || ISA || MCA || CCW)
select LLC
help
@@ -20,9 +18,11 @@ config TR
from <http://www.tldp.org/docs.html#howto>. Most people can
say N here.
+if TR
+
config IBMTR
tristate "IBM Tropic chipset based adapter support"
- depends on TR && (ISA || MCA)
+ depends on ISA || MCA
---help---
This is support for all IBM Token Ring cards that don't use DMA. If
you have such a beast, say Y and read the Token-Ring mini-HOWTO,
@@ -36,7 +36,7 @@ config IBMTR
config IBMOL
tristate "IBM Olympic chipset PCI adapter support"
- depends on TR && PCI
+ depends on PCI
---help---
This is support for all non-Lanstreamer IBM PCI Token Ring Cards.
Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II
@@ -54,7 +54,7 @@ config IBMOL
config IBMLS
tristate "IBM Lanstreamer chipset PCI adapter support"
- depends on TR && PCI && !64BIT
+ depends on PCI && !64BIT
help
This is support for IBM Lanstreamer PCI Token Ring Cards.
@@ -66,7 +66,7 @@ config IBMLS
config 3C359
tristate "3Com 3C359 Token Link Velocity XL adapter support"
- depends on TR && PCI
+ depends on PCI
---help---
This is support for the 3Com PCI Velocity XL cards, specifically
the 3Com 3C359, please note this is not for the 3C339 cards, you
@@ -84,7 +84,7 @@ config 3C359
config TMS380TR
tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
- depends on TR && (PCI || ISA && ISA_DMA_API || MCA)
+ depends on PCI || ISA && ISA_DMA_API || MCA
select FW_LOADER
---help---
This driver provides generic support for token ring adapters
@@ -108,7 +108,7 @@ config TMS380TR
config TMSPCI
tristate "Generic TMS380 PCI support"
- depends on TR && TMS380TR && PCI
+ depends on TMS380TR && PCI
---help---
This tms380 module supports generic TMS380-based PCI cards.
@@ -123,7 +123,7 @@ config TMSPCI
config SKISA
tristate "SysKonnect TR4/16 ISA support"
- depends on TR && TMS380TR && ISA
+ depends on TMS380TR && ISA
help
This tms380 module supports SysKonnect TR4/16 ISA cards.
@@ -135,7 +135,7 @@ config SKISA
config PROTEON
tristate "Proteon ISA support"
- depends on TR && TMS380TR && ISA
+ depends on TMS380TR && ISA
help
This tms380 module supports Proteon ISA cards.
@@ -148,7 +148,7 @@ config PROTEON
config ABYSS
tristate "Madge Smart 16/4 PCI Mk2 support"
- depends on TR && TMS380TR && PCI
+ depends on TMS380TR && PCI
help
This tms380 module supports the Madge Smart 16/4 PCI Mk2
cards (51-02).
@@ -158,7 +158,7 @@ config ABYSS
config MADGEMC
tristate "Madge Smart 16/4 Ringnode MicroChannel"
- depends on TR && TMS380TR && MCA
+ depends on TMS380TR && MCA
help
This tms380 module supports the Madge Smart 16/4 MC16 and MC32
MicroChannel adapters.
@@ -168,7 +168,7 @@ config MADGEMC
config SMCTR
tristate "SMC ISA/MCA adapter support"
- depends on TR && (ISA || MCA_LEGACY) && (BROKEN || !64BIT)
+ depends on (ISA || MCA_LEGACY) && (BROKEN || !64BIT)
---help---
This is support for the ISA and MCA SMC Token Ring cards,
specifically SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A
@@ -182,5 +182,4 @@ config SMCTR
To compile this driver as a module, choose M here: the module will be
called smctr.
-endmenu
-
+endif # TR
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index f7257359412..15b2fb8aa49 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -741,15 +741,6 @@ typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
spin_unlock_bh(&tp->state_lock);
}
-static void
-typhoon_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
- struct typhoon *tp = netdev_priv(dev);
- spin_lock_bh(&tp->state_lock);
- vlan_group_set_device(tp->vlgrp, vid, NULL);
- spin_unlock_bh(&tp->state_lock);
-}
-
static inline void
typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
u32 ring_dma)
@@ -2542,7 +2533,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->get_stats = typhoon_get_stats;
dev->set_mac_address = typhoon_set_mac_address;
dev->vlan_rx_register = typhoon_vlan_rx_register;
- dev->vlan_rx_kill_vid = typhoon_vlan_rx_kill_vid;
+
SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops);
/* We can handle scatter gather, up to 16 entries, and
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index c2ccbd098f5..18b731bb4da 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -23,11 +23,8 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/fsl_devices.h>
-#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/workqueue.h>
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index f96966d4bcc..7bcb82f50cf 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -260,8 +260,6 @@ static struct of_device_id uec_mdio_match[] = {
{},
};
-MODULE_DEVICE_TABLE(of, uec_mdio_match);
-
static struct of_platform_driver uec_mdio_driver = {
.name = DRV_NAME,
.probe = uec_mdio_probe,
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 3de564b2314..8dc09a3790c 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -313,8 +313,8 @@ config USB_KC2190
boolean "KT Technology KC2190 based cables (InstaNet)"
depends on USB_NET_CDC_SUBSET && EXPERIMENTAL
help
-  Choose this option if you're using a host-to-host cable
-  with one of these chips.
+ Choose this option if you're using a host-to-host cable
+ with one of these chips.
config USB_NET_ZAURUS
tristate "Sharp Zaurus (stock ROMs) and compatible"
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index d5ef97bc4d0..6d95cacd528 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1458,6 +1458,10 @@ static const struct usb_device_id products [] = {
// IO-DATA ETG-US2
USB_DEVICE (0x04bb, 0x0930),
.driver_info = (unsigned long) &ax88178_info,
+}, {
+ // Belkin F5D5055
+ USB_DEVICE(0x050d, 0x5055),
+ .driver_info = (unsigned long) &ax88178_info,
},
{ }, // END
};
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 5a21f06bf8a..675ac99a79c 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -91,6 +91,22 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
"CDC descriptors on config\n");
}
+ /* Maybe CDC descriptors are after the endpoint? This bug has
+ * been seen on some 2Wire Inc RNDIS-ish products.
+ */
+ if (len == 0) {
+ struct usb_host_endpoint *hep;
+
+ hep = intf->cur_altsetting->endpoint;
+ if (hep) {
+ buf = hep->extra;
+ len = hep->extralen;
+ }
+ if (len)
+ dev_dbg(&intf->dev,
+ "CDC descriptors on endpoint\n");
+ }
+
/* this assumes that if there's a non-RNDIS vendor variant
* of cdc-acm, it'll fail RNDIS requests cleanly.
*/
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 980e4aaa97a..cd991a0f75b 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -515,6 +515,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
dev_err(&intf->dev,
"dev can't take %u byte packets (max %u)\n",
dev->hard_mtu, tmp);
+ retval = -EINVAL;
goto fail_and_release;
}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f9cd42d058b..5b16d9a1269 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1252,20 +1252,23 @@ EXPORT_SYMBOL_GPL(usbnet_probe);
/*-------------------------------------------------------------------------*/
-/* FIXME these suspend/resume methods assume non-CDC style
- * devices, with only one interface.
+/*
+ * suspend the whole driver as soon as the first interface is suspended
+ * resume only when the last interface is resumed
*/
int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- /* accelerate emptying of the rx and queues, to avoid
- * having everything error out.
- */
- netif_device_detach (dev->net);
- (void) unlink_urbs (dev, &dev->rxq);
- (void) unlink_urbs (dev, &dev->txq);
+ if (!dev->suspend_count++) {
+ /* accelerate emptying of the rx and queues, to avoid
+ * having everything error out.
+ */
+ netif_device_detach (dev->net);
+ (void) unlink_urbs (dev, &dev->rxq);
+ (void) unlink_urbs (dev, &dev->txq);
+ }
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_suspend);
@@ -1274,8 +1277,10 @@ int usbnet_resume (struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- netif_device_attach (dev->net);
- tasklet_schedule (&dev->bh);
+ if (!--dev->suspend_count) {
+ netif_device_attach (dev->net);
+ tasklet_schedule (&dev->bh);
+ }
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_resume);
diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
index 82db5a8e528..a3f8b9e7bc0 100644
--- a/drivers/net/usb/usbnet.h
+++ b/drivers/net/usb/usbnet.h
@@ -32,6 +32,7 @@ struct usbnet {
const char *driver_name;
wait_queue_head_t *wait;
struct mutex phy_mutex;
+ unsigned char suspend_count;
/* i/o info: pipes etc */
unsigned in, out;
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 25b75b61518..b670b97bcfd 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1562,7 +1562,7 @@ static void velocity_print_link_status(struct velocity_info *vptr)
if (vptr->mii_status & VELOCITY_LINK_FAIL) {
VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
} else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
- VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link autonegation", vptr->dev->name);
+ VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
if (vptr->mii_status & VELOCITY_SPEED_1000)
VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index e3f5bb0fe60..fa2399cbd5c 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -266,16 +266,23 @@ config IPW2200_DEBUG
If you are not sure, say N here.
-config LIBERTAS_USB
- tristate "Marvell Libertas 8388 802.11a/b/g cards"
- depends on USB && WLAN_80211
+config LIBERTAS
+ tristate "Marvell 8xxx Libertas WLAN driver support"
+ depends on WLAN_80211
+ select IEEE80211
select FW_LOADER
---help---
+ A library for Marvell Libertas 8xxx devices.
+
+config LIBERTAS_USB
+ tristate "Marvell Libertas 8388 USB 802.11b/g cards"
+ depends on LIBERTAS && USB
+ ---help---
A driver for Marvell Libertas 8388 USB devices.
-config LIBERTAS_USB_DEBUG
- bool "Enable full debugging output in the Libertas USB module."
- depends on LIBERTAS_USB
+config LIBERTAS_DEBUG
+ bool "Enable full debugging output in the Libertas module."
+ depends on LIBERTAS
---help---
Debugging support.
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 246fac0e800..3df3c60263d 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -311,7 +311,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
local_info_t *local;
struct ieee80211_hdr_4addr *hdr;
u16 fc;
- int hdr_len, res;
+ int prefix_len, postfix_len, hdr_len, res;
iface = netdev_priv(skb->dev);
local = iface->local;
@@ -337,10 +337,13 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (skb == NULL)
return NULL;
- if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
- skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
- pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
- crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
+ prefix_len = crypt->ops->extra_mpdu_prefix_len +
+ crypt->ops->extra_msdu_prefix_len;
+ postfix_len = crypt->ops->extra_mpdu_postfix_len +
+ crypt->ops->extra_msdu_postfix_len;
+ if ((skb_headroom(skb) < prefix_len ||
+ skb_tailroom(skb) < postfix_len) &&
+ pskb_expand_head(skb, prefix_len, postfix_len, GFP_ATOMIC)) {
kfree_skb(skb);
return NULL;
}
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
index e0ecc4d483b..4cf0ff7b833 100644
--- a/drivers/net/wireless/libertas/11d.c
+++ b/drivers/net/wireless/libertas/11d.c
@@ -95,7 +95,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
for (i = 0; i < cfp_no; i++) {
if ((cfp + i)->channel == firstchan) {
- lbs_pr_debug(1, "firstchan found\n");
+ lbs_deb_11d("firstchan found\n");
break;
}
}
@@ -129,12 +129,12 @@ static u8 wlan_channel_known_11d(u8 chan,
for (i = 0; i < nr_chan; i++) {
if (chan == chanpwr[i].chan) {
- lbs_pr_debug(1, "11D: Found Chan:%d\n", chan);
+ lbs_deb_11d("11D: Found Chan:%d\n", chan);
return 1;
}
}
- lbs_pr_debug(1, "11D: Not Find Chan:%d\n", chan);
+ lbs_deb_11d("11D: Not Find Chan:%d\n", chan);
return 0;
}
@@ -174,7 +174,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
memcpy(domaininfo->countrycode, parsed_region_chan->countrycode,
COUNTRY_CODE_LEN);
- lbs_pr_debug(1, "11D:nrchan=%d\n", nr_chan);
+ lbs_deb_11d("11D:nrchan=%d\n", nr_chan);
lbs_dbg_hex("11D:parsed_region_chan:", (char *)parsed_region_chan,
sizeof(struct parsed_region_chan_11d));
@@ -212,7 +212,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
}
domaininfo->nr_subband = nr_subband;
- lbs_pr_debug(1, "nr_subband=%x\n", domaininfo->nr_subband);
+ lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
lbs_dbg_hex("11D:domaininfo:", (char *)domaininfo,
COUNTRY_CODE_LEN + 1 +
sizeof(struct ieeetypes_subbandset) * nr_subband);
@@ -233,13 +233,13 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_
struct chan_freq_power *cfp;
if (region_chan == NULL) {
- lbs_pr_debug(1, "11D: region_chan is NULL\n");
+ lbs_deb_11d("11D: region_chan is NULL\n");
return;
}
cfp = region_chan->CFP;
if (cfp == NULL) {
- lbs_pr_debug(1, "11D: cfp equal NULL \n");
+ lbs_deb_11d("11D: cfp equal NULL \n");
return;
}
@@ -248,19 +248,19 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_
memcpy(parsed_region_chan->countrycode,
wlan_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
- lbs_pr_debug(1, "11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
+ lbs_deb_11d("11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
parsed_region_chan->band);
for (i = 0; i < region_chan->nrcfp; i++, cfp++) {
parsed_region_chan->chanpwr[i].chan = cfp->channel;
parsed_region_chan->chanpwr[i].pwr = cfp->maxtxpower;
- lbs_pr_debug(1, "11D: Chan[%d] Pwr[%d]\n",
+ lbs_deb_11d("11D: Chan[%d] Pwr[%d]\n",
parsed_region_chan->chanpwr[i].chan,
parsed_region_chan->chanpwr[i].pwr);
}
parsed_region_chan->nr_chan = region_chan->nrcfp;
- lbs_pr_debug(1, "11D: nrchan[%d]\n", parsed_region_chan->nr_chan);
+ lbs_deb_11d("11D: nrchan[%d]\n", parsed_region_chan->nr_chan);
return;
}
@@ -277,8 +277,9 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
struct chan_freq_power *cfp;
int cfp_no;
u8 idx;
+ int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_11D);
cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
if (cfp == NULL)
@@ -288,16 +289,19 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
if (chan == (cfp + idx)->channel) {
/* If Mrvl Chip Supported? */
if ((cfp + idx)->unsupported) {
- return 0;
+ ret = 0;
} else {
- return 1;
+ ret = 1;
}
+ goto done;
}
}
/*chan is not in the region table */
- LEAVE();
- return 0;
+
+done:
+ lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
+ return ret;
}
/**
@@ -321,7 +325,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
u8 j, i;
- ENTER();
+ lbs_deb_enter(LBS_DEB_11D);
/*validation Rules:
1. valid region Code
@@ -337,15 +341,14 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
if ((*(countryinfo->countrycode)) == 0
|| (countryinfo->len <= COUNTRY_CODE_LEN)) {
/* No region Info or Wrong region info: treat as No 11D info */
- LEAVE();
- return 0;
+ goto done;
}
/*Step1: check region_code */
parsed_region_chan->region = region =
wlan_region_2_code(countryinfo->countrycode);
- lbs_pr_debug(1, "regioncode=%x\n", (u8) parsed_region_chan->region);
+ lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region);
lbs_dbg_hex("CountryCode:", (char *)countryinfo->countrycode,
COUNTRY_CODE_LEN);
@@ -361,7 +364,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
if (countryinfo->subband[j].firstchan <= lastchan) {
/*Step2&3. Check First Chan Num increment and no overlap */
- lbs_pr_debug(1, "11D: Chan[%d>%d] Overlap\n",
+ lbs_deb_11d("11D: Chan[%d>%d] Overlap\n",
countryinfo->subband[j].firstchan, lastchan);
continue;
}
@@ -374,7 +377,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
if (!wlan_get_chan_11d(band, firstchan, i, &curchan)) {
/* Chan is not found in UN table */
- lbs_pr_debug(1, "chan is not supported: %d \n", i);
+ lbs_deb_11d("chan is not supported: %d \n", i);
break;
}
@@ -389,7 +392,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
idx++;
} else {
/*not supported and ignore the chan */
- lbs_pr_debug(1,
+ lbs_deb_11d(
"11D:i[%d] chan[%d] unsupported in region[%x] band[%d]\n",
i, curchan, region, band);
}
@@ -401,11 +404,12 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
parsed_region_chan->nr_chan = idx;
- lbs_pr_debug(1, "nrchan=%x\n", parsed_region_chan->nr_chan);
+ lbs_deb_11d("nrchan=%x\n", parsed_region_chan->nr_chan);
lbs_dbg_hex("11D:parsed_region_chan:", (u8 *) parsed_region_chan,
2 + COUNTRY_CODE_LEN + sizeof(struct parsed_region_chan_11d) * idx);
- LEAVE();
+done:
+ lbs_deb_enter(LBS_DEB_11D);
return 0;
}
@@ -420,16 +424,16 @@ u8 libertas_get_scan_type_11d(u8 chan,
{
u8 scan_type = cmd_scan_type_passive;
- ENTER();
+ lbs_deb_enter(LBS_DEB_11D);
if (wlan_channel_known_11d(chan, parsed_region_chan)) {
- lbs_pr_debug(1, "11D: Found and do Active Scan\n");
+ lbs_deb_11d("11D: Found and do Active Scan\n");
scan_type = cmd_scan_type_active;
} else {
- lbs_pr_debug(1, "11D: Not Find and do Passive Scan\n");
+ lbs_deb_11d("11D: Not Find and do Passive Scan\n");
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_11D, "ret scan_type %d", scan_type);
return scan_type;
}
@@ -456,7 +460,7 @@ static int wlan_enable_11d(wlan_private * priv, u8 flag)
OID_802_11D_ENABLE,
&priv->adapter->enable11d);
if (ret)
- lbs_pr_debug(1, "11D: Fail to enable 11D \n");
+ lbs_deb_11d("11D: Fail to enable 11D \n");
return 0;
}
@@ -471,7 +475,7 @@ static int set_domain_info_11d(wlan_private * priv)
int ret;
if (!priv->adapter->enable11d) {
- lbs_pr_debug(1, "11D: dnld domain Info with 11d disabled\n");
+ lbs_deb_11d("11D: dnld domain Info with 11d disabled\n");
return 0;
}
@@ -479,7 +483,7 @@ static int set_domain_info_11d(wlan_private * priv)
cmd_act_set,
cmd_option_waitforrsp, 0, NULL);
if (ret)
- lbs_pr_debug(1, "11D: Fail to dnld domain Info\n");
+ lbs_deb_11d("11D: Fail to dnld domain Info\n");
return ret;
}
@@ -501,7 +505,7 @@ int libertas_set_universaltable(wlan_private * priv, u8 band)
adapter->universal_channel[i].nrcfp =
sizeof(channel_freq_power_UN_BG) / size;
- lbs_pr_debug(1, "11D: BG-band nrcfp=%d\n",
+ lbs_deb_11d("11D: BG-band nrcfp=%d\n",
adapter->universal_channel[i].nrcfp);
adapter->universal_channel[i].CFP = channel_freq_power_UN_BG;
@@ -531,9 +535,9 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u8 nr_subband = adapter->domainreg.nr_subband;
- ENTER();
+ lbs_deb_enter(LBS_DEB_11D);
- lbs_pr_debug(1, "nr_subband=%x\n", nr_subband);
+ lbs_deb_11d("nr_subband=%x\n", nr_subband);
cmd->command = cpu_to_le16(cmdno);
pdomaininfo->action = cpu_to_le16(cmdoption);
@@ -542,8 +546,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
lbs_dbg_hex("11D: 802_11D_DOMAIN_INFO:", (u8 *) cmd,
(int)(cmd->size));
- LEAVE();
- return 0;
+ goto done;
}
domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
@@ -567,10 +570,10 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
}
- lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, (int)(cmd->size));
-
- LEAVE();
+ lbs_dbg_hex("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, le16_to_cpu(cmd->size));
+done:
+ lbs_deb_enter(LBS_DEB_11D);
return 0;
}
@@ -585,17 +588,17 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq)
int data = 0;
int *val;
- ENTER();
+ lbs_deb_enter(LBS_DEB_11D);
data = SUBCMD_DATA(wrq);
- lbs_pr_debug(1, "enable 11D: %s\n",
+ lbs_deb_11d("enable 11D: %s\n",
(data == 1) ? "enable" : "Disable");
wlan_enable_11d(priv, data);
val = (int *)wrq->u.name;
*val = priv->adapter->enable11d;
- LEAVE();
+ lbs_deb_enter(LBS_DEB_11D);
return 0;
}
@@ -608,25 +611,24 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq)
int libertas_ret_802_11d_domain_info(wlan_private * priv,
struct cmd_ds_command *resp)
{
- struct cmd_ds_802_11d_domain_info
- *domaininfo = &resp->params.domaininforesp;
+ struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
struct mrvlietypes_domainparamset *domain = &domaininfo->domain;
u16 action = le16_to_cpu(domaininfo->action);
s16 ret = 0;
u8 nr_subband = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_11D);
lbs_dbg_hex("11D DOMAIN Info Rsp Data:", (u8 *) resp,
(int)le16_to_cpu(resp->size));
- nr_subband = (domain->header.len - 3) / sizeof(struct ieeetypes_subbandset);
- /* countrycode 3 bytes */
+ nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
+ sizeof(struct ieeetypes_subbandset);
- lbs_pr_debug(1, "11D Domain Info Resp: nr_subband=%d\n", nr_subband);
+ lbs_deb_11d("11D Domain Info Resp: nr_subband=%d\n", nr_subband);
if (nr_subband > MRVDRV_MAX_SUBBAND_802_11D) {
- lbs_pr_debug(1, "Invalid Numrer of Subband returned!!\n");
+ lbs_deb_11d("Invalid Numrer of Subband returned!!\n");
return -1;
}
@@ -637,12 +639,12 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv,
case cmd_act_get:
break;
default:
- lbs_pr_debug(1, "Invalid action:%d\n", domaininfo->action);
+ lbs_deb_11d("Invalid action:%d\n", domaininfo->action);
ret = -1;
break;
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
return ret;
}
@@ -651,23 +653,22 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv,
* @param priv pointer to wlan_private
* @return 0; -1
*/
-int libertas_parse_dnld_countryinfo_11d(wlan_private * priv)
+int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
+ struct bss_descriptor * bss)
{
int ret;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_11D);
if (priv->adapter->enable11d) {
memset(&adapter->parsed_region_chan, 0,
sizeof(struct parsed_region_chan_11d));
- ret = parse_domain_info_11d(&adapter->pattemptedbssdesc->
- countryinfo, 0,
+ ret = parse_domain_info_11d(&bss->countryinfo, 0,
&adapter->parsed_region_chan);
if (ret == -1) {
- lbs_pr_debug(1, "11D: Err Parse domain_info from AP..\n");
- LEAVE();
- return ret;
+ lbs_deb_11d("11D: Err Parse domain_info from AP..\n");
+ goto done;
}
memset(&adapter->domainreg, 0,
@@ -678,13 +679,15 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv)
ret = set_domain_info_11d(priv);
if (ret) {
- lbs_pr_debug(1, "11D: Err set domainInfo to FW\n");
- LEAVE();
- return ret;
+ lbs_deb_11d("11D: Err set domainInfo to FW\n");
+ goto done;
}
}
- LEAVE();
- return 0;
+ ret = 0;
+
+done:
+ lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
+ return ret;
}
/**
@@ -699,8 +702,8 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
struct region_channel *region_chan;
u8 j;
- ENTER();
- lbs_pr_debug(1, "11D:curbssparams.band[%d]\n", adapter->curbssparams.band);
+ lbs_deb_enter(LBS_DEB_11D);
+ lbs_deb_11d("11D:curbssparams.band[%d]\n", adapter->curbssparams.band);
if (priv->adapter->enable11d) {
/* update parsed_region_chan_11; dnld domaininf to FW */
@@ -709,7 +712,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
sizeof(adapter->region_channel[0]); j++) {
region_chan = &adapter->region_channel[j];
- lbs_pr_debug(1, "11D:[%d] region_chan->band[%d]\n", j,
+ lbs_deb_11d("11D:[%d] region_chan->band[%d]\n", j,
region_chan->band);
if (!region_chan || !region_chan->valid
@@ -722,10 +725,10 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
if (j >= sizeof(adapter->region_channel) /
sizeof(adapter->region_channel[0])) {
- lbs_pr_debug(1, "11D:region_chan not found. band[%d]\n",
+ lbs_deb_11d("11D:region_chan not found. band[%d]\n",
adapter->curbssparams.band);
- LEAVE();
- return -1;
+ ret = -1;
+ goto done;
}
memset(&adapter->parsed_region_chan, 0,
@@ -742,13 +745,14 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
ret = set_domain_info_11d(priv);
if (ret) {
- lbs_pr_debug(1, "11D: Err set domainInfo to FW\n");
- LEAVE();
- return ret;
+ lbs_deb_11d("11D: Err set domainInfo to FW\n");
+ goto done;
}
}
+ ret = 0;
- LEAVE();
- return 0;
+done:
+ lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
+ return ret;
}
diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h
index db2ebea9f23..73e42e71291 100644
--- a/drivers/net/wireless/libertas/11d.h
+++ b/drivers/net/wireless/libertas/11d.h
@@ -47,7 +47,7 @@ struct mrvlietypes_domainparamset {
} __attribute__ ((packed));
struct cmd_ds_802_11d_domain_info {
- u16 action;
+ __le16 action;
struct mrvlietypes_domainparamset domain;
} __attribute__ ((packed));
@@ -98,7 +98,9 @@ int libertas_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq);
int libertas_ret_802_11d_domain_info(wlan_private * priv,
struct cmd_ds_command *resp);
-int libertas_parse_dnld_countryinfo_11d(wlan_private * priv);
+struct bss_descriptor;
+int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
+ struct bss_descriptor * bss);
int libertas_create_dnld_countryinfo_11d(wlan_private * priv);
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index 56a8ea1fbf0..a1097f59fd4 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -1,4 +1,4 @@
-usb8xxx-objs := main.o fw.o wext.o \
+libertas-objs := main.o fw.o wext.o \
rx.o tx.o cmd.o \
cmdresp.o scan.o \
join.o 11d.o \
@@ -8,5 +8,5 @@ usb8xxx-objs := main.o fw.o wext.o \
usb8xxx-objs += if_bootcmd.o
usb8xxx-objs += if_usb.o
+obj-$(CONFIG_LIBERTAS) += libertas.o
obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
-
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index 378577200b5..1f92f50b643 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -1,7 +1,7 @@
================================================================================
README for USB8388
- (c) Copyright © 2003-2006, Marvell International Ltd.
+ (c) Copyright © 2003-2006, Marvell International Ltd.
All Rights Reserved
This software file (the "File") is distributed by Marvell International
@@ -47,15 +47,19 @@ Version 5 Command:
iwpriv ethX ledgpio <n>
BT Commands:
- The blinding table (BT) contains a list of mac addresses that should be
- ignored by the firmware. It is primarily used for debugging and
- testing networks. It can be edited and inspected with the following
- commands:
+ The blinding table (BT) contains a list of mac addresses that will be,
+ by default, ignored by the firmware. It is also possible to invert this
+ behavior so that we will ignore all traffic except for the portion
+ coming from mac addresess in the list. It is primarily used for
+ debugging and testing networks. It can be edited and inspected with
+ the following commands:
iwpriv ethX bt_reset
iwpriv ethX bt_add <mac_address>
iwpriv ethX bt_del <mac_address>
iwpriv ethX bt_list <id>
+ iwpriv ethX bt_get_invert <n>
+ iwpriv ethX bt_set_invert <n>
FWT Commands:
The forwarding table (FWT) is a feature used to manage mesh network
@@ -135,7 +139,7 @@ fwt_add
This command is used to insert an entry into the FWT table. The list of
parameters must follow the following structure:
- iwpriv ethX fwt_add da ra [metric dir ssn dsn hopcount ttl expiration sleepmode snr]
+ iwpriv ethX fwt_add da ra [metric dir rate ssn dsn hopcount ttl expiration sleepmode snr]
The parameters between brackets are optional, but they must appear in
the order specified. For example, if you want to specify the metric,
@@ -150,6 +154,9 @@ fwt_add
preferred, default is 0)
dir -- direction (1 for direct, 0 for reverse,
default is 1)
+ rate -- data rate used for transmission to the RA,
+ as specified for the rateadapt command,
+ default is 3 (11Mbps)
ssn -- Source Sequence Number (time at the RA for
reverse routes. Default is 0)
dsn -- Destination Sequence Number (time at the DA
@@ -207,13 +214,17 @@ fwt_list
The output is a string of the following form:
- da ra metric dir ssn dsn hopcount ttl expiration sleepmode snr
+ da ra valid metric dir rate ssn dsn hopcount ttl expiration
+ sleepmode snr precursor
where the different fields are:-
da -- DA MAC address (in the form "00:11:22:33:44:55")
ra -- RA MAC address (in the form "00:11:22:33:44:55")
+ valid -- whether the route is valid (0 if not valid)
metric -- route metric (cost: smaller-metric routes are preferred)
dir -- direction (1 for direct, 0 for reverse)
+ rate -- data rate used for transmission to the RA,
+ as specified for the rateadapt command
ssn -- Source Sequence Number (time at the RA for reverse routes)
dsn -- Destination Sequence Number (time at the DA for direct routes)
hopcount -- hop count (currently unused)
@@ -221,33 +232,10 @@ fwt_list
expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry)
sleepmode -- RA's sleep mode (currently unused)
snr -- SNR in the link to RA (currently unused)
+ precursor -- predecessor in direct routes
fwt_list_route
- This command is used to list a route from the FWT table. The only
- parameter is the route ID. If you want to list all the routes in a
- table, start with rid=0, and keep incrementing rid until you get a
- "(null)" string. This function is similar to fwt_list. The only
- difference is the output format. Also note that this command is meant
- for debugging. It is expected that users will use fwt_lookup and
- fwt_list. One important reason for this is that the route id may change
- as the route table is altered.
-
- iwpriv ethX fwt_list_route rid
-
- The output is a string of the following form:
-
- da metric dir nid ssn dsn hopcount ttl expiration
-
- where the different fields are:-
- da -- DA MAC address (in the form "00:11:22:33:44:55")
- metric -- route metric (cost: smaller-metric routes are preferred)
- dir -- direction (1 for direct, 0 for reverse)
- nid -- Next-hop (neighbor) host ID (nid)
- ssn -- Source Sequence Number (time at the RA for reverse routes)
- dsn -- Destination Sequence Number (time at the DA for direct routes)
- hopcount -- hop count (currently unused)
- ttl -- TTL count (only used in reverse entries)
- expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry)
+ This command is equivalent to fwt_list.
fwt_list_neigh
This command is used to list a neighbor from the FWT table. The only
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index c260bd1b3d4..f67efa0815f 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -2,6 +2,7 @@
#include <linux/bitops.h>
#include <net/ieee80211.h>
+#include <linux/etherdevice.h>
#include "assoc.h"
#include "join.h"
@@ -13,59 +14,88 @@
static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static void print_assoc_req(const char * extra, struct assoc_request * assoc_req)
+{
+ lbs_deb_assoc(
+ "#### Association Request: %s\n"
+ " flags: 0x%08lX\n"
+ " SSID: '%s'\n"
+ " channel: %d\n"
+ " band: %d\n"
+ " mode: %d\n"
+ " BSSID: " MAC_FMT "\n"
+ " Encryption:%s%s%s\n"
+ " auth: %d\n",
+ extra, assoc_req->flags,
+ escape_essid(assoc_req->ssid, assoc_req->ssid_len),
+ assoc_req->channel, assoc_req->band, assoc_req->mode,
+ MAC_ARG(assoc_req->bssid),
+ assoc_req->secinfo.WPAenabled ? " WPA" : "",
+ assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
+ assoc_req->secinfo.wep_enabled ? " WEP" : "",
+ assoc_req->secinfo.auth_mode);
+}
+
+
static int assoc_helper_essid(wlan_private *priv,
struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- int i;
+ struct bss_descriptor * bss;
+ int channel = -1;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
- lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid);
+ /* FIXME: take channel into account when picking SSIDs if a channel
+ * is set.
+ */
+
+ if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
+ channel = assoc_req->channel;
+
+ lbs_deb_assoc("New SSID requested: '%s'\n",
+ escape_essid(assoc_req->ssid, assoc_req->ssid_len));
if (assoc_req->mode == IW_MODE_INFRA) {
if (adapter->prescan) {
- libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1);
+ libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
+ assoc_req->ssid_len, 0);
}
- i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid,
- NULL, IW_MODE_INFRA);
- if (i >= 0) {
- lbs_pr_debug(1,
- "SSID found in scan list ... associating...\n");
-
- ret = wlan_associate(priv, &adapter->scantable[i]);
- if (ret == 0) {
- memcpy(&assoc_req->bssid,
- &adapter->scantable[i].macaddress,
- ETH_ALEN);
- }
+ bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
+ assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
+ if (bss != NULL) {
+ lbs_deb_assoc("SSID found in scan list, associating\n");
+ memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
+ ret = wlan_associate(priv, assoc_req);
} else {
- lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n",
- assoc_req->ssid.ssid);
+ lbs_deb_assoc("SSID not found; cannot associate\n");
}
} else if (assoc_req->mode == IW_MODE_ADHOC) {
/* Scan for the network, do not save previous results. Stale
* scan data will cause us to join a non-existant adhoc network
*/
- libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 0);
+ libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
+ assoc_req->ssid_len, 1);
/* Search for the requested SSID in the scan table */
- i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL,
- IW_MODE_ADHOC);
- if (i >= 0) {
- lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret);
- libertas_join_adhoc_network(priv, &adapter->scantable[i]);
+ bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
+ assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel);
+ if (bss != NULL) {
+ lbs_deb_assoc("SSID found, will join\n");
+ memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
+ libertas_join_adhoc_network(priv, assoc_req);
} else {
/* else send START command */
- lbs_pr_debug(1, "SSID not found in list, so creating adhoc"
- " with SSID '%s'\n", assoc_req->ssid.ssid);
- libertas_start_adhoc_network(priv, &assoc_req->ssid);
+ lbs_deb_assoc("SSID not found, creating adhoc network\n");
+ memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
+ IW_ESSID_MAX_SIZE);
+ assoc_req->bss.ssid_len = assoc_req->ssid_len;
+ libertas_start_adhoc_network(priv, assoc_req);
}
- memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN);
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
@@ -74,33 +104,31 @@ static int assoc_helper_bssid(wlan_private *priv,
struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
- int i, ret = 0;
-
- ENTER();
+ int ret = 0;
+ struct bss_descriptor * bss;
- lbs_pr_debug(1, "ASSOC: WAP: BSSID = " MAC_FMT "\n",
+ lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT,
MAC_ARG(assoc_req->bssid));
/* Search for index position in list for requested MAC */
- i = libertas_find_BSSID_in_list(adapter, assoc_req->bssid,
+ bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid,
assoc_req->mode);
- if (i < 0) {
- lbs_pr_debug(1, "ASSOC: WAP: BSSID " MAC_FMT " not found, "
+ if (bss == NULL) {
+ lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, "
"cannot associate.\n", MAC_ARG(assoc_req->bssid));
goto out;
}
+ memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
if (assoc_req->mode == IW_MODE_INFRA) {
- ret = wlan_associate(priv, &adapter->scantable[i]);
- lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret);
+ ret = wlan_associate(priv, assoc_req);
+ lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret);
} else if (assoc_req->mode == IW_MODE_ADHOC) {
- libertas_join_adhoc_network(priv, &adapter->scantable[i]);
+ libertas_join_adhoc_network(priv, assoc_req);
}
- memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid,
- sizeof(struct WLAN_802_11_SSID));
out:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
@@ -113,12 +141,12 @@ static int assoc_helper_associate(wlan_private *priv,
/* If we're given and 'any' BSSID, try associating based on SSID */
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
- if (memcmp(bssid_any, assoc_req->bssid, ETH_ALEN)
- && memcmp(bssid_off, assoc_req->bssid, ETH_ALEN)) {
+ if (compare_ether_addr(bssid_any, assoc_req->bssid)
+ && compare_ether_addr(bssid_off, assoc_req->bssid)) {
ret = assoc_helper_bssid(priv, assoc_req);
done = 1;
if (ret) {
- lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret);
+ lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
}
}
}
@@ -126,7 +154,7 @@ static int assoc_helper_associate(wlan_private *priv,
if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
ret = assoc_helper_essid(priv, assoc_req);
if (ret) {
- lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret);
+ lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
}
}
@@ -140,12 +168,10 @@ static int assoc_helper_mode(wlan_private *priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
- if (assoc_req->mode == adapter->mode) {
- LEAVE();
- return 0;
- }
+ if (assoc_req->mode == adapter->mode)
+ goto done;
if (assoc_req->mode == IW_MODE_INFRA) {
if (adapter->psstate != PS_STATE_FULL_POWER)
@@ -158,9 +184,81 @@ static int assoc_helper_mode(wlan_private *priv,
cmd_802_11_snmp_mib,
0, cmd_option_waitforrsp,
OID_802_11_INFRASTRUCTURE_MODE,
- (void *) (size_t) assoc_req->mode);
+ /* Shoot me now */ (void *) (size_t) assoc_req->mode);
- LEAVE();
+done:
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
+ return ret;
+}
+
+
+static int update_channel(wlan_private * priv)
+{
+ /* the channel in f/w could be out of sync, get the current channel */
+ return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
+ cmd_opt_802_11_rf_channel_get,
+ cmd_option_waitforrsp, 0, NULL);
+}
+
+void libertas_sync_channel(struct work_struct *work)
+{
+ wlan_private *priv = container_of(work, wlan_private, sync_channel);
+
+ if (update_channel(priv) != 0)
+ lbs_pr_info("Channel synchronization failed.");
+}
+
+static int assoc_helper_channel(wlan_private *priv,
+ struct assoc_request * assoc_req)
+{
+ wlan_adapter *adapter = priv->adapter;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_ASSOC);
+
+ ret = update_channel(priv);
+ if (ret < 0) {
+ lbs_deb_assoc("ASSOC: channel: error getting channel.");
+ }
+
+ if (assoc_req->channel == adapter->curbssparams.channel)
+ goto done;
+
+ lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
+ adapter->curbssparams.channel, assoc_req->channel);
+
+ ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
+ cmd_opt_802_11_rf_channel_set,
+ cmd_option_waitforrsp, 0, &assoc_req->channel);
+ if (ret < 0) {
+ lbs_deb_assoc("ASSOC: channel: error setting channel.");
+ }
+
+ ret = update_channel(priv);
+ if (ret < 0) {
+ lbs_deb_assoc("ASSOC: channel: error getting channel.");
+ }
+
+ if (assoc_req->channel != adapter->curbssparams.channel) {
+ lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
+ assoc_req->channel);
+ goto done;
+ }
+
+ if ( assoc_req->secinfo.wep_enabled
+ && (assoc_req->wep_keys[0].len
+ || assoc_req->wep_keys[1].len
+ || assoc_req->wep_keys[2].len
+ || assoc_req->wep_keys[3].len)) {
+ /* Make sure WEP keys are re-sent to firmware */
+ set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
+ }
+
+ /* Must restart/rejoin adhoc networks after channel change */
+ set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
+
+done:
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
@@ -172,7 +270,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
int i;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
/* Set or remove WEP keys */
if ( assoc_req->wep_keys[0].len
@@ -216,7 +314,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
mutex_unlock(&adapter->lock);
out:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
@@ -226,14 +324,24 @@ static int assoc_helper_secinfo(wlan_private *priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
memcpy(&adapter->secinfo, &assoc_req->secinfo,
sizeof(struct wlan_802_11_security));
ret = libertas_set_mac_packet_filter(priv);
+ if (ret)
+ goto out;
- LEAVE();
+ /* enable/disable RSN */
+ ret = libertas_prepare_and_send_command(priv,
+ cmd_802_11_enable_rsn,
+ cmd_act_set,
+ cmd_option_waitforrsp,
+ 0, assoc_req);
+
+out:
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
@@ -243,16 +351,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
{
int ret = 0;
- ENTER();
-
- /* enable/Disable RSN */
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_enable_rsn,
- cmd_act_set,
- cmd_option_waitforrsp,
- 0, assoc_req);
- if (ret)
- goto out;
+ lbs_deb_enter(LBS_DEB_ASSOC);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_key_material,
@@ -260,8 +359,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
cmd_option_waitforrsp,
0, assoc_req);
-out:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
@@ -272,7 +370,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
@@ -282,7 +380,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv,
adapter->wpa_ie_len = 0;
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
@@ -294,25 +392,30 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
return 0;
if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
- lbs_pr_debug(1, "Deauthenticating due to new SSID in "
+ lbs_deb_assoc("Deauthenticating due to new SSID in "
" configuration request.\n");
return 1;
}
if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
- lbs_pr_debug(1, "Deauthenticating due to updated security "
+ lbs_deb_assoc("Deauthenticating due to updated security "
"info in configuration request.\n");
return 1;
}
}
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
- lbs_pr_debug(1, "Deauthenticating due to new BSSID in "
+ lbs_deb_assoc("Deauthenticating due to new BSSID in "
" configuration request.\n");
return 1;
}
+ if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
+ lbs_deb_assoc("Deauthenticating due to channel switch.\n");
+ return 1;
+ }
+
/* FIXME: deal with 'auto' mode somehow */
if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
if (assoc_req->mode != IW_MODE_INFRA)
@@ -329,10 +432,9 @@ static int should_stop_adhoc(wlan_adapter *adapter,
if (adapter->connect_status != libertas_connected)
return 0;
- if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength)
- return 1;
- if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid,
- adapter->curbssparams.ssid.ssidlength))
+ if (libertas_ssid_cmp(adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len,
+ assoc_req->ssid, assoc_req->ssid_len) != 0)
return 1;
/* FIXME: deal with 'auto' mode somehow */
@@ -341,11 +443,16 @@ static int should_stop_adhoc(wlan_adapter *adapter,
return 1;
}
+ if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
+ if (assoc_req->channel != adapter->curbssparams.channel)
+ return 1;
+ }
+
return 0;
}
-void wlan_association_worker(struct work_struct *work)
+void libertas_association_worker(struct work_struct *work)
{
wlan_private *priv = container_of(work, wlan_private, assoc_work.work);
wlan_adapter *adapter = priv->adapter;
@@ -353,40 +460,38 @@ void wlan_association_worker(struct work_struct *work)
int ret = 0;
int find_any_ssid = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
mutex_lock(&adapter->lock);
- assoc_req = adapter->assoc_req;
- adapter->assoc_req = NULL;
+ assoc_req = adapter->pending_assoc_req;
+ adapter->pending_assoc_req = NULL;
+ adapter->in_progress_assoc_req = assoc_req;
mutex_unlock(&adapter->lock);
- if (!assoc_req) {
- LEAVE();
- return;
- }
+ if (!assoc_req)
+ goto done;
- lbs_pr_debug(1, "ASSOC: starting new association request: flags = 0x%lX\n",
- assoc_req->flags);
+ print_assoc_req(__func__, assoc_req);
/* If 'any' SSID was specified, find an SSID to associate with */
if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
- && !assoc_req->ssid.ssidlength)
+ && !assoc_req->ssid_len)
find_any_ssid = 1;
/* But don't use 'any' SSID if there's a valid locked BSSID to use */
if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
- if (memcmp(&assoc_req->bssid, bssid_any, ETH_ALEN)
- && memcmp(&assoc_req->bssid, bssid_off, ETH_ALEN))
+ if (compare_ether_addr(assoc_req->bssid, bssid_any)
+ && compare_ether_addr(assoc_req->bssid, bssid_off))
find_any_ssid = 0;
}
if (find_any_ssid) {
u8 new_mode;
- ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid,
- assoc_req->mode, &new_mode);
+ ret = libertas_find_best_network_ssid(priv, assoc_req->ssid,
+ &assoc_req->ssid_len, assoc_req->mode, &new_mode);
if (ret) {
- lbs_pr_debug(1, "Could not find best network\n");
+ lbs_deb_assoc("Could not find best network\n");
ret = -ENETUNREACH;
goto out;
}
@@ -406,7 +511,7 @@ void wlan_association_worker(struct work_struct *work)
if (should_deauth_infrastructure(adapter, assoc_req)) {
ret = libertas_send_deauthentication(priv);
if (ret) {
- lbs_pr_debug(1, "Deauthentication due to new "
+ lbs_deb_assoc("Deauthentication due to new "
"configuration request failed: %d\n",
ret);
}
@@ -415,7 +520,7 @@ void wlan_association_worker(struct work_struct *work)
if (should_stop_adhoc(adapter, assoc_req)) {
ret = libertas_stop_adhoc_network(priv);
if (ret) {
- lbs_pr_debug(1, "Teardown of AdHoc network due to "
+ lbs_deb_assoc("Teardown of AdHoc network due to "
"new configuration request failed: %d\n",
ret);
}
@@ -427,7 +532,16 @@ void wlan_association_worker(struct work_struct *work)
if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
ret = assoc_helper_mode(priv, assoc_req);
if (ret) {
-lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
+lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
+ goto out;
+ }
+ }
+
+ if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
+ ret = assoc_helper_channel(priv, assoc_req);
+ if (ret) {
+ lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
+ __LINE__, ret);
goto out;
}
}
@@ -436,7 +550,7 @@ lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret);
|| test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
ret = assoc_helper_wep_keys(priv, assoc_req);
if (ret) {
-lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
+lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
goto out;
}
}
@@ -444,7 +558,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret);
if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
ret = assoc_helper_secinfo(priv, assoc_req);
if (ret) {
-lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
+lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
goto out;
}
}
@@ -452,7 +566,7 @@ lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret);
if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
ret = assoc_helper_wpa_ie(priv, assoc_req);
if (ret) {
-lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
+lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
goto out;
}
}
@@ -461,7 +575,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret);
|| test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
ret = assoc_helper_wpa_keys(priv, assoc_req);
if (ret) {
-lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
+lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
goto out;
}
}
@@ -475,21 +589,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
ret = assoc_helper_associate(priv, assoc_req);
if (ret) {
- lbs_pr_debug(1, "ASSOC: association attempt unsuccessful: %d\n",
+ lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n",
ret);
success = 0;
}
if (adapter->connect_status != libertas_connected) {
- lbs_pr_debug(1, "ASSOC: assoication attempt unsuccessful, "
+ lbs_deb_assoc("ASSOC: assoication attempt unsuccessful, "
"not connected.\n");
success = 0;
}
if (success) {
- lbs_pr_debug(1, "ASSOC: association attempt successful. "
+ lbs_deb_assoc("ASSOC: association attempt successful. "
"Associated to '%s' (" MAC_FMT ")\n",
- assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid));
+ escape_essid(adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len),
+ MAC_ARG(adapter->curbssparams.bssid));
libertas_prepare_and_send_command(priv,
cmd_802_11_rssi,
0, cmd_option_waitforrsp, 0, NULL);
@@ -498,18 +614,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret);
cmd_802_11_get_log,
0, cmd_option_waitforrsp, 0, NULL);
} else {
-
ret = -1;
}
}
out:
if (ret) {
- lbs_pr_debug(1, "ASSOC: reconfiguration attempt unsuccessful: %d\n",
+ lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n",
ret);
}
+
+ mutex_lock(&adapter->lock);
+ adapter->in_progress_assoc_req = NULL;
+ mutex_unlock(&adapter->lock);
kfree(assoc_req);
- LEAVE();
+
+done:
+ lbs_deb_leave(LBS_DEB_ASSOC);
}
@@ -520,9 +641,10 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
{
struct assoc_request * assoc_req;
- if (!adapter->assoc_req) {
- adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL);
- if (!adapter->assoc_req) {
+ if (!adapter->pending_assoc_req) {
+ adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
+ GFP_KERNEL);
+ if (!adapter->pending_assoc_req) {
lbs_pr_info("Not enough memory to allocate association"
" request!\n");
return NULL;
@@ -532,15 +654,19 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
/* Copy current configuration attributes to the association request,
* but don't overwrite any that are already set.
*/
- assoc_req = adapter->assoc_req;
+ assoc_req = adapter->pending_assoc_req;
if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
- memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid,
- adapter->curbssparams.ssid.ssidlength);
+ memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid,
+ IW_ESSID_MAX_SIZE);
+ assoc_req->ssid_len = adapter->curbssparams.ssid_len;
}
if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
assoc_req->channel = adapter->curbssparams.channel;
+ if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags))
+ assoc_req->band = adapter->curbssparams.band;
+
if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
assoc_req->mode = adapter->mode;
@@ -581,7 +707,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
assoc_req->wpa_ie_len = adapter->wpa_ie_len;
}
+ print_assoc_req(__func__, assoc_req);
+
return assoc_req;
}
-
-
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index 2ffd82d99b3..5e9c31f0932 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -5,10 +5,12 @@
#include "dev.h"
-void wlan_association_worker(struct work_struct *work);
+void libertas_association_worker(struct work_struct *work);
struct assoc_request * wlan_get_association_request(wlan_adapter *adapter);
+void libertas_sync_channel(struct work_struct *work);
+
#define ASSOC_DELAY (HZ / 2)
static inline void wlan_postpone_association_work(wlan_private *priv)
{
@@ -21,9 +23,9 @@ static inline void wlan_postpone_association_work(wlan_private *priv)
static inline void wlan_cancel_association_work(wlan_private *priv)
{
cancel_delayed_work(&priv->assoc_work);
- if (priv->adapter->assoc_req) {
- kfree(priv->adapter->assoc_req);
- priv->adapter->assoc_req = NULL;
+ if (priv->adapter->pending_assoc_req) {
+ kfree(priv->adapter->pending_assoc_req);
+ priv->adapter->pending_assoc_req = NULL;
}
}
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index de9cb46a70f..124e029f1bf 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -6,7 +6,6 @@
#include <net/iw_handler.h>
#include "host.h"
#include "hostcmd.h"
-#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
@@ -26,13 +25,11 @@ static u16 commands_allowed_in_ps[] = {
* @param command the command ID
* @return TRUE or FALSE
*/
-static u8 is_command_allowed_in_ps(u16 command)
+static u8 is_command_allowed_in_ps(__le16 command)
{
- int count = sizeof(commands_allowed_in_ps)
- / sizeof(commands_allowed_in_ps[0]);
int i;
- for (i = 0; i < count; i++) {
+ for (i = 0; i < ARRAY_SIZE(commands_allowed_in_ps); i++) {
if (command == cpu_to_le16(commands_allowed_in_ps[i]))
return 1;
}
@@ -44,14 +41,13 @@ static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd)
{
struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_get_hw_spec);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -60,21 +56,19 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
u16 cmd_action)
{
struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
- u16 action = cmd_action;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_ps_mode);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
- S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
+ S_DS_GEN);
psm->action = cpu_to_le16(cmd_action);
psm->multipledtim = 0;
- switch (action) {
+ switch (cmd_action) {
case cmd_subcmd_enter_ps:
- lbs_pr_debug(1, "PS command:" "SubCode- Enter PS\n");
- lbs_pr_debug(1, "locallisteninterval = %d\n",
+ lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
+ lbs_deb_cmd("locallisteninterval = %d\n",
adapter->locallisteninterval);
psm->locallisteninterval =
@@ -86,18 +80,18 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
break;
case cmd_subcmd_exit_ps:
- lbs_pr_debug(1, "PS command:" "SubCode- Exit PS\n");
+ lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
break;
case cmd_subcmd_sleep_confirmed:
- lbs_pr_debug(1, "PS command: SubCode- sleep confirm\n");
+ lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
break;
default:
break;
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -115,8 +109,7 @@ static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv,
cmd->params.inactivity_timeout.action = cpu_to_le16(cmd_action);
if (cmd_action)
- cmd->params.inactivity_timeout.timeout =
- cpu_to_le16(*timeout);
+ cmd->params.inactivity_timeout.timeout = cpu_to_le16(*timeout);
else
cmd->params.inactivity_timeout.timeout = 0;
@@ -130,11 +123,10 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- cmd->size =
- cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) +
- S_DS_GEN);
+ cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) +
+ S_DS_GEN);
cmd->command = cpu_to_le16(cmd_802_11_sleep_params);
if (cmd_action == cmd_act_get) {
@@ -151,7 +143,7 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv,
sp->reserved = cpu_to_le16(adapter->sp.sp_reserved);
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -165,17 +157,16 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
int ret = 0;
struct assoc_request * assoc_req = pdata_buf;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_set_wep);
- cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_set_wep))
- + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN);
if (cmd_act == cmd_act_add) {
int i;
if (!assoc_req) {
- lbs_pr_debug(1, "Invalid association request!");
+ lbs_deb_cmd("Invalid association request!");
ret = -1;
goto done;
}
@@ -183,11 +174,10 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
wep->action = cpu_to_le16(cmd_act_add);
/* default tx key index */
- wep->keyindex = cpu_to_le16((u16)
- (assoc_req->wep_tx_keyidx &
- (u32)cmd_WEP_KEY_INDEX_MASK));
+ wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx &
+ (u32)cmd_WEP_KEY_INDEX_MASK));
- lbs_pr_debug(1, "Tx key Index: %u\n", wep->keyindex);
+ lbs_deb_cmd("Tx key Index: %u\n", le16_to_cpu(wep->keyindex));
/* Copy key types and material to host command structure */
for (i = 0; i < 4; i++) {
@@ -195,19 +185,21 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
switch (pkey->len) {
case KEY_LEN_WEP_40:
- wep->keytype[i] = cmd_type_wep_40_bit;
+ wep->keytype[i] =
+ cpu_to_le16(cmd_type_wep_40_bit);
memmove(&wep->keymaterial[i], pkey->key,
pkey->len);
break;
case KEY_LEN_WEP_104:
- wep->keytype[i] = cmd_type_wep_104_bit;
+ wep->keytype[i] =
+ cpu_to_le16(cmd_type_wep_104_bit);
memmove(&wep->keymaterial[i], pkey->key,
pkey->len);
break;
case 0:
break;
default:
- lbs_pr_debug(1, "Invalid WEP key %d length of %d\n",
+ lbs_deb_cmd("Invalid WEP key %d length of %d\n",
i, pkey->len);
ret = -1;
goto done;
@@ -219,36 +211,37 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv,
wep->action = cpu_to_le16(cmd_act_remove);
/* default tx key index */
- wep->keyindex = cpu_to_le16((u16)
- (adapter->wep_tx_keyidx &
- (u32)cmd_WEP_KEY_INDEX_MASK));
+ wep->keyindex = cpu_to_le16((u16)(adapter->wep_tx_keyidx &
+ (u32)cmd_WEP_KEY_INDEX_MASK));
}
ret = 0;
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
struct cmd_ds_command *cmd,
- u16 cmd_action)
+ u16 cmd_action,
+ void * pdata_buf)
{
struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn;
- wlan_adapter *adapter = priv->adapter;
+ struct assoc_request * assoc_req = pdata_buf;
+
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_enable_rsn);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_enable_rsn) +
- S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN);
penableRSN->action = cpu_to_le16(cmd_action);
- if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
+ if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
} else {
penableRSN->enable = cpu_to_le16(cmd_disable_rsn);
}
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -259,14 +252,12 @@ static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
pkeyparamset->keytypeid = cpu_to_le16(pkey->type);
if (pkey->flags & KEY_INFO_WPA_ENABLED) {
- pkeyparamset->keyinfo = cpu_to_le16(KEY_INFO_WPA_ENABLED);
- } else {
- pkeyparamset->keyinfo = cpu_to_le16(!KEY_INFO_WPA_ENABLED);
+ pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
}
-
if (pkey->flags & KEY_INFO_WPA_UNICAST) {
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
- } else if (pkey->flags & KEY_INFO_WPA_MCAST) {
+ }
+ if (pkey->flags & KEY_INFO_WPA_MCAST) {
pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
}
@@ -284,46 +275,45 @@ static int wlan_cmd_802_11_key_material(wlan_private * priv,
u16 cmd_action,
u32 cmd_oid, void *pdata_buf)
{
- wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_key_material *pkeymaterial =
&cmd->params.keymaterial;
+ struct assoc_request * assoc_req = pdata_buf;
int ret = 0;
int index = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_key_material);
pkeymaterial->action = cpu_to_le16(cmd_action);
if (cmd_action == cmd_act_get) {
- cmd->size = cpu_to_le16( S_DS_GEN
- + sizeof (pkeymaterial->action));
+ cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action));
ret = 0;
goto done;
}
memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet));
- if (adapter->wpa_unicast_key.len) {
+ if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
set_one_wpa_key(&pkeymaterial->keyParamSet[index],
- &adapter->wpa_unicast_key);
+ &assoc_req->wpa_unicast_key);
index++;
}
- if (adapter->wpa_mcast_key.len) {
+ if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
set_one_wpa_key(&pkeymaterial->keyParamSet[index],
- &adapter->wpa_mcast_key);
+ &assoc_req->wpa_mcast_key);
index++;
}
cmd->size = cpu_to_le16( S_DS_GEN
- + sizeof (pkeymaterial->action)
- + index * sizeof(struct MrvlIEtype_keyParamSet));
+ + sizeof (pkeymaterial->action)
+ + (index * sizeof(struct MrvlIEtype_keyParamSet)));
ret = 0;
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
@@ -354,8 +344,7 @@ static int wlan_cmd_802_11_get_stat(wlan_private * priv,
{
cmd->command = cpu_to_le16(cmd_802_11_get_stat);
cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) +
- S_DS_GEN);
+ cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN);
return 0;
}
@@ -369,14 +358,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u8 ucTemp;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- lbs_pr_debug(1, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
+ lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
cmd->command = cpu_to_le16(cmd_802_11_snmp_mib);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_snmp_mib) +
- S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN);
switch (cmd_oid) {
case OID_802_11_INFRASTRUCTURE_MODE:
@@ -407,7 +394,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->querytype = cmd_act_set;
pSNMPMIB->bufsize = sizeof(u16);
ulTemp = *(u32 *)pdata_buf;
- *((unsigned short *)(pSNMPMIB->value)) =
+ *((__le16 *)(pSNMPMIB->value)) =
cpu_to_le16((u16) ulTemp);
}
break;
@@ -420,15 +407,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->oid = cpu_to_le16((u16) fragthresh_i);
if (cmd_action == cmd_act_get) {
- pSNMPMIB->querytype =
- cpu_to_le16(cmd_act_get);
+ pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
} else if (cmd_action == cmd_act_set) {
- pSNMPMIB->querytype =
- cpu_to_le16(cmd_act_set);
- pSNMPMIB->bufsize =
- cpu_to_le16(sizeof(u16));
+ pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
+ pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
ulTemp = *((u32 *) pdata_buf);
- *((unsigned short *)(pSNMPMIB->value)) =
+ *((__le16 *)(pSNMPMIB->value)) =
cpu_to_le16((u16) ulTemp);
}
@@ -443,16 +427,12 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->oid = le16_to_cpu((u16) rtsthresh_i);
if (cmd_action == cmd_act_get) {
- pSNMPMIB->querytype =
- cpu_to_le16(cmd_act_get);
+ pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
} else if (cmd_action == cmd_act_set) {
- pSNMPMIB->querytype =
- cpu_to_le16(cmd_act_set);
- pSNMPMIB->bufsize =
- cpu_to_le16(sizeof(u16));
- ulTemp = *((u32 *)
- pdata_buf);
- *(unsigned short *)(pSNMPMIB->value) =
+ pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
+ pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
+ ulTemp = *((u32 *)pdata_buf);
+ *(__le16 *)(pSNMPMIB->value) =
cpu_to_le16((u16) ulTemp);
}
@@ -462,13 +442,11 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
pSNMPMIB->oid = cpu_to_le16((u16) short_retrylim_i);
if (cmd_action == cmd_act_get) {
- pSNMPMIB->querytype =
- cpu_to_le16(cmd_act_get);
+ pSNMPMIB->querytype = cpu_to_le16(cmd_act_get);
} else if (cmd_action == cmd_act_set) {
- pSNMPMIB->querytype =
- cpu_to_le16(cmd_act_set);
+ pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
- *((unsigned short *)(pSNMPMIB->value)) =
+ *((__le16 *)(pSNMPMIB->value)) =
cpu_to_le16((u16) adapter->txretrycount);
}
@@ -477,16 +455,18 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
break;
}
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n",
- cmd->command, cmd->size, cmd->seqnum, cmd->result);
+ le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
+ le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result));
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"SNMP_CMD: action=0x%x, oid=0x%x, oidsize=0x%x, value=0x%x\n",
- pSNMPMIB->querytype, pSNMPMIB->oid, pSNMPMIB->bufsize,
- *(u16 *) pSNMPMIB->value);
+ le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid),
+ le16_to_cpu(pSNMPMIB->bufsize),
+ le16_to_cpu(*(__le16 *) pSNMPMIB->value));
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -495,10 +475,9 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv,
int cmd_action)
{
wlan_adapter *adapter = priv->adapter;
- struct cmd_ds_802_11_radio_control *pradiocontrol =
- &cmd->params.radio;
+ struct cmd_ds_802_11_radio_control *pradiocontrol = &cmd->params.radio;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->size =
cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control)) +
@@ -527,7 +506,7 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv,
else
pradiocontrol->control &= cpu_to_le16(~TURN_ON_RF);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -538,16 +517,16 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->size =
- cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) +
- S_DS_GEN);
+ cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN);
cmd->command = cpu_to_le16(cmd_802_11_rf_tx_power);
- prtp->action = cmd_action;
+ prtp->action = cpu_to_le16(cmd_action);
- lbs_pr_debug(1, "RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", cmd->size,
- cmd->command, prtp->action);
+ lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n",
+ le16_to_cpu(cmd->size), le16_to_cpu(cmd->command),
+ le16_to_cpu(prtp->action));
switch (cmd_action) {
case cmd_act_tx_power_opt_get:
@@ -557,14 +536,12 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
case cmd_act_tx_power_opt_set_high:
prtp->action = cpu_to_le16(cmd_act_set);
- prtp->currentlevel =
- cpu_to_le16(cmd_act_tx_power_index_high);
+ prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_high);
break;
case cmd_act_tx_power_opt_set_mid:
prtp->action = cpu_to_le16(cmd_act_set);
- prtp->currentlevel =
- cpu_to_le16(cmd_act_tx_power_index_mid);
+ prtp->currentlevel = cpu_to_le16(cmd_act_tx_power_index_mid);
break;
case cmd_act_tx_power_opt_set_low:
@@ -572,7 +549,8 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf));
break;
}
- LEAVE();
+
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -583,15 +561,12 @@ static int wlan_cmd_802_11_rf_antenna(wlan_private * priv,
struct cmd_ds_802_11_rf_antenna *rant = &cmd->params.rant;
cmd->command = cpu_to_le16(cmd_802_11_rf_antenna);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) +
- S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_antenna) +
+ S_DS_GEN);
rant->action = cpu_to_le16(cmd_action);
- if ((cmd_action == cmd_act_set_rx) ||
- (cmd_action == cmd_act_set_tx)) {
- rant->antennamode =
- cpu_to_le16((u16) (*(u32 *) pdata_buf));
+ if ((cmd_action == cmd_act_set_rx) || (cmd_action == cmd_act_set_tx)) {
+ rant->antennamode = cpu_to_le16((u16) (*(u32 *) pdata_buf));
}
return 0;
@@ -610,13 +585,13 @@ static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv,
+ S_DS_GEN);
cmd->command = cpu_to_le16(cmd_802_11_rate_adapt_rateset);
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- rateadapt->action = cmd_action;
- rateadapt->enablehwauto = adapter->enablehwauto;
- rateadapt->bitmap = adapter->ratebitmap;
+ rateadapt->action = cpu_to_le16(cmd_action);
+ rateadapt->enablehwauto = cpu_to_le16(adapter->enablehwauto);
+ rateadapt->bitmap = cpu_to_le16(adapter->ratebitmap);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -626,12 +601,10 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv,
{
struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate;
wlan_adapter *adapter = priv->adapter;
- u16 action = cmd_action;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
S_DS_GEN);
cmd->command = cpu_to_le16(cmd_802_11_data_rate);
@@ -640,15 +613,15 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv,
pdatarate->action = cpu_to_le16(cmd_action);
- if (action == cmd_act_set_tx_fix_rate) {
+ if (cmd_action == cmd_act_set_tx_fix_rate) {
pdatarate->datarate[0] = libertas_data_rate_to_index(adapter->datarate);
- lbs_pr_debug(1, "Setting FW for fixed rate 0x%02X\n",
+ lbs_deb_cmd("Setting FW for fixed rate 0x%02X\n",
adapter->datarate);
- } else if (action == cmd_act_set_tx_auto) {
- lbs_pr_debug(1, "Setting FW for AUTO rate\n");
+ } else if (cmd_action == cmd_act_set_tx_auto) {
+ lbs_deb_cmd("Setting FW for AUTO rate\n");
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -659,8 +632,7 @@ static int wlan_cmd_mac_multicast_adr(wlan_private * priv,
struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
wlan_adapter *adapter = priv->adapter;
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
S_DS_GEN);
cmd->command = cpu_to_le16(cmd_mac_multicast_adr);
@@ -680,8 +652,8 @@ static int wlan_cmd_802_11_rf_channel(wlan_private * priv,
struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel;
cmd->command = cpu_to_le16(cmd_802_11_rf_channel);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel)
- + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) +
+ S_DS_GEN);
if (option == cmd_opt_802_11_rf_channel_set) {
rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf));
@@ -698,9 +670,8 @@ static int wlan_cmd_802_11_rssi(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
cmd->command = cpu_to_le16(cmd_802_11_rssi);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
- cmd->params.rssi.N = priv->adapter->bcn_avg_factor;
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
+ cmd->params.rssi.N = cpu_to_le16(priv->adapter->bcn_avg_factor);
/* reset Beacon SNR/NF/RSSI values */
adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
@@ -719,7 +690,7 @@ static int wlan_cmd_reg_access(wlan_private * priv,
{
struct wlan_offset_value *offval;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
offval = (struct wlan_offset_value *)pdata_buf;
@@ -729,9 +700,8 @@ static int wlan_cmd_reg_access(wlan_private * priv,
struct cmd_ds_mac_reg_access *macreg;
cmdptr->size =
- cpu_to_le16(sizeof
- (struct cmd_ds_mac_reg_access)
- + S_DS_GEN);
+ cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access)
+ + S_DS_GEN);
macreg =
(struct cmd_ds_mac_reg_access *)&cmdptr->params.
macreg;
@@ -785,7 +755,7 @@ static int wlan_cmd_reg_access(wlan_private * priv,
break;
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -796,8 +766,7 @@ static int wlan_cmd_802_11_mac_address(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
cmd->command = cpu_to_le16(cmd_802_11_mac_address);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
S_DS_GEN);
cmd->result = 0;
@@ -818,12 +787,11 @@ static int wlan_cmd_802_11_eeprom_access(wlan_private * priv,
{
struct wlan_ioctl_regrdwr *ea = pdata_buf;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_802_11_eeprom_access);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
- S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
+ S_DS_GEN);
cmd->result = 0;
cmd->params.rdeeprom.action = cpu_to_le16(ea->action);
@@ -839,11 +807,10 @@ static int wlan_cmd_bt_access(wlan_private * priv,
u16 cmd_action, void *pdata_buf)
{
struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
- lbs_pr_debug(1, "BT CMD(%d)\n", cmd_action);
+ lbs_deb_cmd("BT CMD(%d)\n", cmd_action);
cmd->command = cpu_to_le16(cmd_bt_access);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access)
- + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + S_DS_GEN);
cmd->result = 0;
bt_access->action = cpu_to_le16(cmd_action);
@@ -861,6 +828,11 @@ static int wlan_cmd_bt_access(wlan_private * priv,
break;
case cmd_act_bt_access_reset:
break;
+ case cmd_act_bt_access_set_invert:
+ bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
+ break;
+ case cmd_act_bt_access_get_invert:
+ break;
default:
break;
}
@@ -872,11 +844,10 @@ static int wlan_cmd_fwt_access(wlan_private * priv,
u16 cmd_action, void *pdata_buf)
{
struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
- lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action);
+ lbs_deb_cmd("FWT CMD(%d)\n", cmd_action);
cmd->command = cpu_to_le16(cmd_fwt_access);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)
- + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + S_DS_GEN);
cmd->result = 0;
if (pdata_buf)
@@ -894,11 +865,10 @@ static int wlan_cmd_mesh_access(wlan_private * priv,
u16 cmd_action, void *pdata_buf)
{
struct cmd_ds_mesh_access *mesh_access = &cmd->params.mesh;
- lbs_pr_debug(1, "FWT CMD(%d)\n", cmd_action);
+ lbs_deb_cmd("FWT CMD(%d)\n", cmd_action);
cmd->command = cpu_to_le16(cmd_mesh_access);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access)
- + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN);
cmd->result = 0;
if (pdata_buf)
@@ -916,23 +886,23 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
unsigned long flags;
struct cmd_ds_command *cmdptr;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
if (!cmdnode) {
- lbs_pr_debug(1, "QUEUE_CMD: cmdnode is NULL\n");
+ lbs_deb_cmd("QUEUE_CMD: cmdnode is NULL\n");
goto done;
}
cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
if (!cmdptr) {
- lbs_pr_debug(1, "QUEUE_CMD: cmdptr is NULL\n");
+ lbs_deb_cmd("QUEUE_CMD: cmdptr is NULL\n");
goto done;
}
/* Exit_PS command needs to be queued in the header always. */
if (cmdptr->command == cmd_802_11_ps_mode) {
struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode;
- if (psm->action == cmd_subcmd_exit_ps) {
+ if (psm->action == cpu_to_le16(cmd_subcmd_exit_ps)) {
if (adapter->psstate != PS_STATE_FULL_POWER)
addtail = 0;
}
@@ -948,13 +918,12 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
spin_unlock_irqrestore(&adapter->driver_lock, flags);
- lbs_pr_debug(1, "QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
+ lbs_deb_cmd("QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
cmdnode,
- ((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command);
+ le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command));
done:
- LEAVE();
- return;
+ lbs_deb_leave(LBS_DEB_CMD);
}
/*
@@ -974,10 +943,10 @@ static int DownloadcommandToStation(wlan_private * priv,
u16 cmdsize;
u16 command;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
if (!adapter || !cmdnode) {
- lbs_pr_debug(1, "DNLD_CMD: adapter = %p, cmdnode = %p\n",
+ lbs_deb_cmd("DNLD_CMD: adapter = %p, cmdnode = %p\n",
adapter, cmdnode);
if (cmdnode) {
spin_lock_irqsave(&adapter->driver_lock, flags);
@@ -993,7 +962,7 @@ static int DownloadcommandToStation(wlan_private * priv,
spin_lock_irqsave(&adapter->driver_lock, flags);
if (!cmdptr || !cmdptr->size) {
- lbs_pr_debug(1, "DNLD_CMD: cmdptr is Null or cmd size is Zero, "
+ lbs_deb_cmd("DNLD_CMD: cmdptr is Null or cmd size is Zero, "
"Not sending\n");
__libertas_cleanup_and_insert_cmd(priv, cmdnode);
spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -1004,8 +973,8 @@ static int DownloadcommandToStation(wlan_private * priv,
adapter->cur_cmd = cmdnode;
adapter->cur_cmd_retcode = 0;
spin_unlock_irqrestore(&adapter->driver_lock, flags);
- lbs_pr_debug(1, "DNLD_CMD:: Before download, size of cmd = %d\n",
- cmdptr->size);
+ lbs_deb_cmd("DNLD_CMD:: Before download, size of cmd = %d\n",
+ le16_to_cpu(cmdptr->size));
cmdsize = cmdptr->size;
@@ -1014,10 +983,10 @@ static int DownloadcommandToStation(wlan_private * priv,
cmdnode->cmdwaitqwoken = 0;
cmdsize = cpu_to_le16(cmdsize);
- ret = libertas_sbi_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
+ ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
if (ret != 0) {
- lbs_pr_debug(1, "DNLD_CMD: Host to Card failed\n");
+ lbs_deb_cmd("DNLD_CMD: Host to Card failed\n");
spin_lock_irqsave(&adapter->driver_lock, flags);
__libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
adapter->cur_cmd = NULL;
@@ -1026,12 +995,11 @@ static int DownloadcommandToStation(wlan_private * priv,
goto done;
}
- lbs_pr_debug(1, "DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies);
+ lbs_deb_cmd("DNLD_CMD: Sent command 0x%x @ %lu\n", command, jiffies);
lbs_dbg_hex("DNLD_CMD: command", cmdnode->bufvirtualaddr, cmdsize);
/* Setup the timer after transmit command */
- if (command == cmd_802_11_scan
- || command == cmd_802_11_authenticate
+ if (command == cmd_802_11_scan || command == cmd_802_11_authenticate
|| command == cmd_802_11_associate)
mod_timer(&adapter->command_timer, jiffies + (10*HZ));
else
@@ -1039,8 +1007,8 @@ static int DownloadcommandToStation(wlan_private * priv,
ret = 0;
- done:
- LEAVE();
+done:
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
@@ -1049,17 +1017,16 @@ static int wlan_cmd_mac_control(wlan_private * priv,
{
struct cmd_ds_mac_control *mac = &cmd->params.macctrl;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
cmd->command = cpu_to_le16(cmd_mac_control);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
mac->action = cpu_to_le16(priv->adapter->currentpacketfilter);
- lbs_pr_debug(1, "wlan_cmd_mac_control(): action=0x%X size=%d\n",
- mac->action, cmd->size);
+ lbs_deb_cmd("wlan_cmd_mac_control(): action=0x%X size=%d\n",
+ le16_to_cpu(mac->action), le16_to_cpu(cmd->size));
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -1093,17 +1060,17 @@ int libertas_set_radio_control(wlan_private * priv)
{
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_radio_control,
cmd_act_set,
cmd_option_waitforrsp, 0, NULL);
- lbs_pr_debug(1, "RADIO_SET: on or off: 0x%X, preamble = 0x%X\n",
+ lbs_deb_cmd("RADIO_SET: on or off: 0x%X, preamble = 0x%X\n",
priv->adapter->radioon, priv->adapter->preamble);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
@@ -1111,16 +1078,16 @@ int libertas_set_mac_packet_filter(wlan_private * priv)
{
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- lbs_pr_debug(1, "libertas_set_mac_packet_filter value = %x\n",
+ lbs_deb_cmd("libertas_set_mac_packet_filter value = %x\n",
priv->adapter->currentpacketfilter);
/* Send MAC control command to station */
ret = libertas_prepare_and_send_command(priv,
cmd_mac_control, 0, 0, 0, NULL);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
@@ -1146,16 +1113,16 @@ int libertas_prepare_and_send_command(wlan_private * priv,
struct cmd_ds_command *cmdptr;
unsigned long flags;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
if (!adapter) {
- lbs_pr_debug(1, "PREP_CMD: adapter is Null\n");
+ lbs_deb_cmd("PREP_CMD: adapter is Null\n");
ret = -1;
goto done;
}
if (adapter->surpriseremoved) {
- lbs_pr_debug(1, "PREP_CMD: Card is Removed\n");
+ lbs_deb_cmd("PREP_CMD: Card is Removed\n");
ret = -1;
goto done;
}
@@ -1163,7 +1130,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
cmdnode = libertas_get_free_cmd_ctrl_node(priv);
if (cmdnode == NULL) {
- lbs_pr_debug(1, "PREP_CMD: No free cmdnode\n");
+ lbs_deb_cmd("PREP_CMD: No free cmdnode\n");
/* Wake up main thread to execute next command */
wake_up_interruptible(&priv->mainthread.waitq);
@@ -1175,11 +1142,11 @@ int libertas_prepare_and_send_command(wlan_private * priv,
cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
- lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
+ lbs_deb_cmd("PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
cmdptr, cmd_no);
if (!cmdptr) {
- lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
+ lbs_deb_cmd("PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
libertas_cleanup_and_insert_cmd(priv, cmdnode);
ret = -1;
goto done;
@@ -1189,7 +1156,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
adapter->seqnum++;
cmdptr->seqnum = cpu_to_le16(adapter->seqnum);
- cmdptr->command = cmd_no;
+ cmdptr->command = cpu_to_le16(cmd_no);
cmdptr->result = 0;
switch (cmd_no) {
@@ -1298,13 +1265,13 @@ int libertas_prepare_and_send_command(wlan_private * priv,
break;
case cmd_802_11_enable_rsn:
- ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action);
+ ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action,
+ pdata_buf);
break;
case cmd_802_11_key_material:
- ret = wlan_cmd_802_11_key_material(priv, cmdptr,
- cmd_action, cmd_oid,
- pdata_buf);
+ ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action,
+ cmd_oid, pdata_buf);
break;
case cmd_802_11_pairwise_tsc:
@@ -1325,9 +1292,8 @@ int libertas_prepare_and_send_command(wlan_private * priv,
case cmd_802_11_get_afc:
cmdptr->command = cpu_to_le16(cmd_no);
- cmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
- S_DS_GEN);
+ cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
+ S_DS_GEN);
memmove(&cmdptr->params.afc,
pdata_buf, sizeof(struct cmd_ds_802_11_afc));
@@ -1406,29 +1372,26 @@ int libertas_prepare_and_send_command(wlan_private * priv,
case cmd_get_tsf:
cmdptr->command = cpu_to_le16(cmd_get_tsf);
- cmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_get_tsf)
- + S_DS_GEN);
+ cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) +
+ S_DS_GEN);
ret = 0;
break;
case cmd_802_11_tx_rate_query:
- cmdptr->command =
- cpu_to_le16(cmd_802_11_tx_rate_query);
- cmdptr->size =
- cpu_to_le16(sizeof(struct cmd_tx_rate_query) +
- S_DS_GEN);
+ cmdptr->command = cpu_to_le16(cmd_802_11_tx_rate_query);
+ cmdptr->size = cpu_to_le16(sizeof(struct cmd_tx_rate_query) +
+ S_DS_GEN);
adapter->txrate = 0;
ret = 0;
break;
default:
- lbs_pr_debug(1, "PREP_CMD: unknown command- %#x\n", cmd_no);
+ lbs_deb_cmd("PREP_CMD: unknown command- %#x\n", cmd_no);
ret = -1;
break;
}
/* return error, since the command preparation failed */
if (ret != 0) {
- lbs_pr_debug(1, "PREP_CMD: command preparation failed\n");
+ lbs_deb_cmd("PREP_CMD: command preparation failed\n");
libertas_cleanup_and_insert_cmd(priv, cmdnode);
ret = -1;
goto done;
@@ -1441,7 +1404,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
wake_up_interruptible(&priv->mainthread.waitq);
if (wait_option & cmd_option_waitforrsp) {
- lbs_pr_debug(1, "PREP_CMD: Wait for CMD response\n");
+ lbs_deb_cmd("PREP_CMD: Wait for CMD response\n");
might_sleep();
wait_event_interruptible(cmdnode->cmdwait_q,
cmdnode->cmdwaitqwoken);
@@ -1449,7 +1412,7 @@ int libertas_prepare_and_send_command(wlan_private * priv,
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->cur_cmd_retcode) {
- lbs_pr_debug(1, "PREP_CMD: command failed with return code=%d\n",
+ lbs_deb_cmd("PREP_CMD: command failed with return code=%d\n",
adapter->cur_cmd_retcode);
adapter->cur_cmd_retcode = 0;
ret = -1;
@@ -1457,9 +1420,10 @@ int libertas_prepare_and_send_command(wlan_private * priv,
spin_unlock_irqrestore(&adapter->driver_lock, flags);
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
+EXPORT_SYMBOL_GPL(libertas_prepare_and_send_command);
/**
* @brief This function allocates the command buffer and link
@@ -1477,33 +1441,29 @@ int libertas_allocate_cmd_buffer(wlan_private * priv)
u8 *ptempvirtualaddr;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
/* Allocate and initialize cmdCtrlNode */
ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
- if (!(tempcmd_array = kmalloc(ulbufsize, GFP_KERNEL))) {
- lbs_pr_debug(1,
+ if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) {
+ lbs_deb_cmd(
"ALLOC_CMD_BUF: failed to allocate tempcmd_array\n");
ret = -1;
goto done;
}
-
adapter->cmd_array = tempcmd_array;
- memset(adapter->cmd_array, 0, ulbufsize);
/* Allocate and initialize command buffers */
ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
- if (!(ptempvirtualaddr = kmalloc(ulbufsize, GFP_KERNEL))) {
- lbs_pr_debug(1,
+ if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) {
+ lbs_deb_cmd(
"ALLOC_CMD_BUF: ptempvirtualaddr: out of memory\n");
ret = -1;
goto done;
}
- memset(ptempvirtualaddr, 0, ulbufsize);
-
/* Update command buffer virtual */
tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr;
}
@@ -1514,8 +1474,9 @@ int libertas_allocate_cmd_buffer(wlan_private * priv)
}
ret = 0;
- done:
- LEAVE();
+
+done:
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
@@ -1527,16 +1488,16 @@ int libertas_allocate_cmd_buffer(wlan_private * priv)
*/
int libertas_free_cmd_buffer(wlan_private * priv)
{
- u32 ulbufsize;
+ u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */
unsigned int i;
struct cmd_ctrl_node *tempcmd_array;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
/* need to check if cmd array is allocated or not */
if (adapter->cmd_array == NULL) {
- lbs_pr_debug(1, "FREE_CMD_BUF: cmd_array is Null\n");
+ lbs_deb_cmd("FREE_CMD_BUF: cmd_array is Null\n");
goto done;
}
@@ -1546,7 +1507,7 @@ int libertas_free_cmd_buffer(wlan_private * priv)
ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
if (tempcmd_array[i].bufvirtualaddr) {
- lbs_pr_debug(1, "Free all the array\n");
+ lbs_deb_cmd("Free all the array\n");
kfree(tempcmd_array[i].bufvirtualaddr);
tempcmd_array[i].bufvirtualaddr = NULL;
}
@@ -1554,13 +1515,13 @@ int libertas_free_cmd_buffer(wlan_private * priv)
/* Release cmd_ctrl_node */
if (adapter->cmd_array) {
- lbs_pr_debug(1, "Free cmd_array\n");
+ lbs_deb_cmd("Free cmd_array\n");
kfree(adapter->cmd_array);
adapter->cmd_array = NULL;
}
done:
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
return 0;
}
@@ -1586,16 +1547,18 @@ struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv)
tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next;
list_del((struct list_head *)tempnode);
} else {
- lbs_pr_debug(1, "GET_CMD_NODE: cmd_ctrl_node is not available\n");
+ lbs_deb_cmd("GET_CMD_NODE: cmd_ctrl_node is not available\n");
tempnode = NULL;
}
spin_unlock_irqrestore(&adapter->driver_lock, flags);
if (tempnode) {
+ /*
lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode available\n");
lbs_pr_debug(3, "GET_CMD_NODE: cmdCtrlNode Address = %p\n",
tempnode);
+ */
cleanup_cmdnode(tempnode);
}
@@ -1638,7 +1601,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv,
struct cmd_ctrl_node *ptempnode,
u32 cmd_oid, u16 wait_option, void *pdata_buf)
{
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
if (!ptempnode)
return;
@@ -1647,7 +1610,7 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv,
ptempnode->wait_option = wait_option;
ptempnode->pdata_buf = pdata_buf;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
}
/**
@@ -1666,7 +1629,7 @@ int libertas_execute_next_command(wlan_private * priv)
unsigned long flags;
int ret = 0;
- lbs_pr_debug(1, "libertas_execute_next_command\n");
+ lbs_deb_enter(LBS_DEB_CMD);
spin_lock_irqsave(&adapter->driver_lock, flags);
@@ -1685,23 +1648,24 @@ int libertas_execute_next_command(wlan_private * priv)
spin_unlock_irqrestore(&adapter->driver_lock, flags);
if (cmdnode) {
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: Got next command from cmdpendingq\n");
cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
if (is_command_allowed_in_ps(cmdptr->command)) {
- if ((adapter->psstate == PS_STATE_SLEEP)
- || (adapter->psstate == PS_STATE_PRE_SLEEP)
- ) {
- lbs_pr_debug(1,
+ if ((adapter->psstate == PS_STATE_SLEEP) ||
+ (adapter->psstate == PS_STATE_PRE_SLEEP)) {
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: Cannot send cmd 0x%x in psstate %d\n",
- cmdptr->command, adapter->psstate);
+ le16_to_cpu(cmdptr->command),
+ adapter->psstate);
ret = -1;
goto done;
}
- lbs_pr_debug(1, "EXEC_NEXT_CMD: OK to send command "
+ lbs_deb_cmd("EXEC_NEXT_CMD: OK to send command "
"0x%x in psstate %d\n",
- cmdptr->command, adapter->psstate);
+ le16_to_cpu(cmdptr->command),
+ adapter->psstate);
} else if (adapter->psstate != PS_STATE_FULL_POWER) {
/*
* 1. Non-PS command:
@@ -1737,12 +1701,12 @@ int libertas_execute_next_command(wlan_private * priv)
struct cmd_ds_802_11_ps_mode *psm =
&cmdptr->params.psmode;
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: PS cmd- action=0x%x\n",
psm->action);
if (psm->action !=
cpu_to_le16(cmd_subcmd_exit_ps)) {
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: Ignore Enter PS cmd\n");
list_del((struct list_head *)cmdnode);
libertas_cleanup_and_insert_cmd(priv, cmdnode);
@@ -1751,10 +1715,9 @@ int libertas_execute_next_command(wlan_private * priv)
goto done;
}
- if ((adapter->psstate == PS_STATE_SLEEP)
- || (adapter->psstate == PS_STATE_PRE_SLEEP)
- ) {
- lbs_pr_debug(1,
+ if ((adapter->psstate == PS_STATE_SLEEP) ||
+ (adapter->psstate == PS_STATE_PRE_SLEEP)) {
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: Ignore ExitPS cmd in sleep\n");
list_del((struct list_head *)cmdnode);
libertas_cleanup_and_insert_cmd(priv, cmdnode);
@@ -1764,13 +1727,13 @@ int libertas_execute_next_command(wlan_private * priv)
goto done;
}
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: Sending Exit_PS down...\n");
}
}
list_del((struct list_head *)cmdnode);
- lbs_pr_debug(1, "EXEC_NEXT_CMD: Sending 0x%04X command\n",
- cmdptr->command);
+ lbs_deb_cmd("EXEC_NEXT_CMD: Sending 0x%04X command\n",
+ le16_to_cpu(cmdptr->command));
DownloadcommandToStation(priv, cmdnode);
} else {
/*
@@ -1780,18 +1743,18 @@ int libertas_execute_next_command(wlan_private * priv)
if ((adapter->psmode != wlan802_11powermodecam) &&
(adapter->psstate == PS_STATE_FULL_POWER) &&
(adapter->connect_status == libertas_connected)) {
- if (adapter->secinfo.WPAenabled
- || adapter->secinfo.WPA2enabled) {
+ if (adapter->secinfo.WPAenabled ||
+ adapter->secinfo.WPA2enabled) {
/* check for valid WPA group keys */
- if (adapter->wpa_mcast_key.len
- || adapter->wpa_unicast_key.len) {
- lbs_pr_debug(1,
+ if (adapter->wpa_mcast_key.len ||
+ adapter->wpa_unicast_key.len) {
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: WPA enabled and GTK_SET"
" go back to PS_SLEEP");
libertas_ps_sleep(priv, 0);
}
} else {
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"EXEC_NEXT_CMD: command PendQ is empty,"
" go back to PS_SLEEP");
libertas_ps_sleep(priv, 0);
@@ -1801,6 +1764,7 @@ int libertas_execute_next_command(wlan_private * priv)
ret = 0;
done:
+ lbs_deb_leave(LBS_DEB_CMD);
return ret;
}
@@ -1809,7 +1773,7 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
union iwreq_data iwrq;
u8 buf[50];
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
memset(&iwrq, 0, sizeof(union iwreq_data));
memset(buf, 0, sizeof(buf));
@@ -1819,15 +1783,13 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
/* Send Event to upper layer */
- lbs_pr_debug(1, "Event Indication string = %s\n",
- (char *)buf);
- lbs_pr_debug(1, "Event Indication String length = %d\n", iwrq.data.length);
+ lbs_deb_cmd("Event Indication string = %s\n", (char *)buf);
+ lbs_deb_cmd("Event Indication String length = %d\n", iwrq.data.length);
- lbs_pr_debug(1, "Sending wireless event IWEVCUSTOM for %s\n", str);
- wireless_send_event(priv->wlan_dev.netdev, IWEVCUSTOM, &iwrq, buf);
+ lbs_deb_cmd("Sending wireless event IWEVCUSTOM for %s\n", str);
+ wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);
- LEAVE();
- return;
+ lbs_deb_leave(LBS_DEB_CMD);
}
static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
@@ -1836,19 +1798,19 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- lbs_pr_debug(1, "SEND_SLEEPC_CMD: Before download, size of cmd = %d\n",
+ lbs_deb_cmd("SEND_SLEEPC_CMD: Before download, size of cmd = %d\n",
size);
lbs_dbg_hex("SEND_SLEEPC_CMD: Sleep confirm command", cmdptr, size);
- ret = libertas_sbi_host_to_card(priv, MVMS_CMD, cmdptr, size);
- priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
+ ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size);
+ priv->dnld_sent = DNLD_RES_RECEIVED;
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->intcounter || adapter->currenttxskb)
- lbs_pr_debug(1, "SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n",
+ lbs_deb_cmd("SEND_SLEEPC_CMD: intcounter=%d currenttxskb=%p\n",
adapter->intcounter, adapter->currenttxskb);
spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -1860,23 +1822,22 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
if (!adapter->intcounter) {
adapter->psstate = PS_STATE_SLEEP;
} else {
- lbs_pr_debug(1, "SEND_SLEEPC_CMD: After sent,IntC=%d\n",
+ lbs_deb_cmd("SEND_SLEEPC_CMD: After sent,IntC=%d\n",
adapter->intcounter);
}
spin_unlock_irqrestore(&adapter->driver_lock, flags);
- lbs_pr_debug(1, "SEND_SLEEPC_CMD: Sent Confirm Sleep command\n");
- lbs_pr_debug(1, "+");
+ lbs_deb_cmd("SEND_SLEEPC_CMD: Sent Confirm Sleep command\n");
+ lbs_deb_cmd("+");
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
void libertas_ps_sleep(wlan_private * priv, int wait_option)
{
-
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
/*
* PS is currently supported only in Infrastructure mode
@@ -1886,8 +1847,7 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option)
libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
cmd_subcmd_enter_ps, wait_option, 0, NULL);
- LEAVE();
- return;
+ lbs_deb_leave(LBS_DEB_CMD);
}
/**
@@ -1899,20 +1859,19 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option)
*/
void libertas_ps_wakeup(wlan_private * priv, int wait_option)
{
- enum WLAN_802_11_POWER_MODE Localpsmode;
+ __le32 Localpsmode;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- Localpsmode = wlan802_11powermodecam;
+ Localpsmode = cpu_to_le32(wlan802_11powermodecam);
- lbs_pr_debug(1, "Exit_PS: Localpsmode = %d\n", Localpsmode);
+ lbs_deb_cmd("Exit_PS: Localpsmode = %d\n", wlan802_11powermodecam);
libertas_prepare_and_send_command(priv, cmd_802_11_ps_mode,
cmd_subcmd_exit_ps,
wait_option, 0, &Localpsmode);
- LEAVE();
- return;
+ lbs_deb_leave(LBS_DEB_CMD);
}
/**
@@ -1929,31 +1888,31 @@ void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode)
wlan_adapter *adapter = priv->adapter;
u8 allowed = 1;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- if (priv->wlan_dev.dnld_sent) {
+ if (priv->dnld_sent) {
allowed = 0;
- lbs_pr_debug(1, "D");
+ lbs_deb_cmd("D");
}
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->cur_cmd) {
allowed = 0;
- lbs_pr_debug(1, "C");
+ lbs_deb_cmd("C");
}
if (adapter->intcounter > 0) {
allowed = 0;
- lbs_pr_debug(1, "I%d", adapter->intcounter);
+ lbs_deb_cmd("I%d", adapter->intcounter);
}
spin_unlock_irqrestore(&adapter->driver_lock, flags);
if (allowed) {
- lbs_pr_debug(1, "Sending libertas_ps_confirm_sleep\n");
+ lbs_deb_cmd("Sending libertas_ps_confirm_sleep\n");
sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep,
sizeof(struct PS_CMD_ConfirmSleep));
} else {
- lbs_pr_debug(1, "Sleep Confirm has been delayed\n");
+ lbs_deb_cmd("Sleep Confirm has been delayed\n");
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_CMD);
}
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index c86454034b5..0c3b9a583d8 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -9,7 +9,6 @@
#include <net/iw_handler.h>
#include "host.h"
-#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
@@ -32,7 +31,7 @@ void libertas_mac_event_disconnected(wlan_private * priv)
if (adapter->connect_status != libertas_connected)
return;
- lbs_pr_debug(1, "Handles disconnect event.\n");
+ lbs_deb_cmd("Handles disconnect event.\n");
memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
@@ -43,15 +42,15 @@ void libertas_mac_event_disconnected(wlan_private * priv)
*/
msleep_interruptible(1000);
- wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
+ wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
/* Free Tx and Rx packets */
kfree_skb(priv->adapter->currenttxskb);
priv->adapter->currenttxskb = NULL;
/* report disconnect to upper layer */
- netif_stop_queue(priv->wlan_dev.netdev);
- netif_carrier_off(priv->wlan_dev.netdev);
+ netif_stop_queue(priv->dev);
+ netif_carrier_off(priv->dev);
/* reset SNR/NF/RSSI values */
memset(adapter->SNR, 0x00, sizeof(adapter->SNR));
@@ -62,35 +61,32 @@ void libertas_mac_event_disconnected(wlan_private * priv)
adapter->nextSNRNF = 0;
adapter->numSNRNF = 0;
adapter->rxpd_rate = 0;
- lbs_pr_debug(1, "Current SSID=%s, ssid length=%u\n",
- adapter->curbssparams.ssid.ssid,
- adapter->curbssparams.ssid.ssidlength);
- lbs_pr_debug(1, "Previous SSID=%s, ssid length=%u\n",
- adapter->previousssid.ssid, adapter->previousssid.ssidlength);
-
- /* reset internal flags */
- adapter->secinfo.WPAenabled = 0;
- adapter->secinfo.WPA2enabled = 0;
- adapter->wpa_ie_len = 0;
+ lbs_deb_cmd("Current SSID='%s', ssid length=%u\n",
+ escape_essid(adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len),
+ adapter->curbssparams.ssid_len);
+ lbs_deb_cmd("Previous SSID='%s', ssid length=%u\n",
+ escape_essid(adapter->prev_ssid, adapter->prev_ssid_len),
+ adapter->prev_ssid_len);
adapter->connect_status = libertas_disconnected;
- /*
- * memorize the previous SSID and BSSID
- * it could be used for re-assoc
- */
- memcpy(&adapter->previousssid,
- &adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID));
- memcpy(adapter->previousbssid,
- adapter->curbssparams.bssid, ETH_ALEN);
+ /* Save previous SSID and BSSID for possible reassociation */
+ memcpy(&adapter->prev_ssid, &adapter->curbssparams.ssid,
+ IW_ESSID_MAX_SIZE);
+ adapter->prev_ssid_len = adapter->curbssparams.ssid_len;
+ memcpy(adapter->prev_bssid, adapter->curbssparams.bssid, ETH_ALEN);
- /* need to erase the current SSID and BSSID info */
- adapter->pattemptedbssdesc = NULL;
- memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
+ /* Clear out associated SSID and BSSID since connection is
+ * no longer valid.
+ */
+ memset(&adapter->curbssparams.bssid, 0, ETH_ALEN);
+ memset(&adapter->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
+ adapter->curbssparams.ssid_len = 0;
if (adapter->psstate != PS_STATE_FULL_POWER) {
/* make firmware to exit PS mode */
- lbs_pr_debug(1, "Disconnected, so exit PS mode.\n");
+ lbs_deb_cmd("Disconnected, so exit PS mode.\n");
libertas_ps_wakeup(priv, 0);
}
}
@@ -122,55 +118,45 @@ static void handle_mic_failureevent(wlan_private * priv, u32 event)
static int wlan_ret_reg_access(wlan_private * priv,
u16 type, struct cmd_ds_command *resp)
{
+ int ret = 0;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
switch (type) {
case cmd_ret_mac_reg_access:
{
- struct cmd_ds_mac_reg_access *reg;
-
- reg =
- (struct cmd_ds_mac_reg_access *)&resp->params.
- macreg;
+ struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
- adapter->offsetvalue.offset = reg->offset;
- adapter->offsetvalue.value = reg->value;
+ adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
+ adapter->offsetvalue.value = le32_to_cpu(reg->value);
break;
}
case cmd_ret_bbp_reg_access:
{
- struct cmd_ds_bbp_reg_access *reg;
- reg =
- (struct cmd_ds_bbp_reg_access *)&resp->params.
- bbpreg;
+ struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
- adapter->offsetvalue.offset = reg->offset;
+ adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
adapter->offsetvalue.value = reg->value;
break;
}
case cmd_ret_rf_reg_access:
{
- struct cmd_ds_rf_reg_access *reg;
- reg =
- (struct cmd_ds_rf_reg_access *)&resp->params.
- rfreg;
+ struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
- adapter->offsetvalue.offset = reg->offset;
+ adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
adapter->offsetvalue.value = reg->value;
break;
}
default:
- LEAVE();
- return -1;
+ ret = -1;
}
- LEAVE();
- return 0;
+ lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
+ return ret;
}
static int wlan_ret_get_hw_spec(wlan_private * priv,
@@ -181,19 +167,20 @@ static int wlan_ret_get_hw_spec(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo);
- adapter->fwreleasenumber = hwspec->fwreleasenumber;
+ memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4);
- lbs_pr_debug(1, "GET_HW_SPEC: FWReleaseVersion- 0x%X\n",
- adapter->fwreleasenumber);
- lbs_pr_debug(1, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
+ lbs_deb_cmd("GET_HW_SPEC: FWReleaseVersion- %u.%u.%u.p%u\n",
+ adapter->fwreleasenumber[2], adapter->fwreleasenumber[1],
+ adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]);
+ lbs_deb_cmd("GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
hwspec->permanentaddr[0], hwspec->permanentaddr[1],
hwspec->permanentaddr[2], hwspec->permanentaddr[3],
hwspec->permanentaddr[4], hwspec->permanentaddr[5]);
- lbs_pr_debug(1, "GET_HW_SPEC: hwifversion=0x%X version=0x%X\n",
+ lbs_deb_cmd("GET_HW_SPEC: hwifversion=0x%X version=0x%X\n",
hwspec->hwifversion, hwspec->version);
adapter->regioncode = le16_to_cpu(hwspec->regioncode);
@@ -210,17 +197,15 @@ static int wlan_ret_get_hw_spec(wlan_private * priv,
if (i >= MRVDRV_MAX_REGION_CODE) {
adapter->regioncode = 0x10;
adapter->regiontableindex = 0;
- lbs_pr_info(
- "unidentified region code, use the default (USA)\n");
+ lbs_pr_info("unidentified region code; using the default (USA)\n");
}
- if (adapter->current_addr[0] == 0xff) {
- memmove(adapter->current_addr, hwspec->permanentaddr,
- ETH_ALEN);
- }
+ if (adapter->current_addr[0] == 0xff)
+ memmove(adapter->current_addr, hwspec->permanentaddr, ETH_ALEN);
- memcpy(priv->wlan_dev.netdev->dev_addr, adapter->current_addr, ETH_ALEN);
- memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
+ memcpy(priv->dev->dev_addr, adapter->current_addr, ETH_ALEN);
+ if (priv->mesh_dev)
+ memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
if (libertas_set_regiontable(priv, adapter->regioncode, 0)) {
ret = -1;
@@ -232,8 +217,8 @@ static int wlan_ret_get_hw_spec(wlan_private * priv,
goto done;
}
- done:
- LEAVE();
+done:
+ lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
@@ -243,19 +228,21 @@ static int wlan_ret_802_11_sleep_params(wlan_private * priv,
struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
+
+ lbs_deb_cmd("error=%x offset=%x stabletime=%x calcontrol=%x\n"
+ " extsleepclk=%x\n", le16_to_cpu(sp->error),
+ le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime),
+ sp->calcontrol, sp->externalsleepclk);
- lbs_pr_debug(1, "error=%x offset=%x stabletime=%x calcontrol=%x\n"
- " extsleepclk=%x\n", sp->error, sp->offset,
- sp->stabletime, sp->calcontrol, sp->externalsleepclk);
adapter->sp.sp_error = le16_to_cpu(sp->error);
adapter->sp.sp_offset = le16_to_cpu(sp->offset);
adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
- adapter->sp.sp_calcontrol = le16_to_cpu(sp->calcontrol);
- adapter->sp.sp_extsleepclk = le16_to_cpu(sp->externalsleepclk);
+ adapter->sp.sp_calcontrol = sp->calcontrol;
+ adapter->sp.sp_extsleepclk = sp->externalsleepclk;
adapter->sp.sp_reserved = le16_to_cpu(sp->reserved);
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -281,42 +268,38 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
u16 oid = le16_to_cpu(smib->oid);
u16 querytype = le16_to_cpu(smib->querytype);
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- lbs_pr_debug(1, "SNMP_RESP: value of the oid = %x, querytype=%x\n", oid,
+ lbs_deb_cmd("SNMP_RESP: value of the oid = %x, querytype=%x\n", oid,
querytype);
- lbs_pr_debug(1, "SNMP_RESP: Buf size = %x\n",
- le16_to_cpu(smib->bufsize));
+ lbs_deb_cmd("SNMP_RESP: Buf size = %x\n", le16_to_cpu(smib->bufsize));
if (querytype == cmd_act_get) {
switch (oid) {
case fragthresh_i:
priv->adapter->fragthsd =
- le16_to_cpu(*
- ((unsigned short *)(smib->value)));
- lbs_pr_debug(1, "SNMP_RESP: fragthsd =%u\n",
- priv->adapter->fragthsd);
+ le16_to_cpu(*((__le16 *)(smib->value)));
+ lbs_deb_cmd("SNMP_RESP: fragthsd =%u\n",
+ priv->adapter->fragthsd);
break;
case rtsthresh_i:
priv->adapter->rtsthsd =
- le16_to_cpu(*
- ((unsigned short *)(smib->value)));
- lbs_pr_debug(1, "SNMP_RESP: rtsthsd =%u\n",
- priv->adapter->rtsthsd);
+ le16_to_cpu(*((__le16 *)(smib->value)));
+ lbs_deb_cmd("SNMP_RESP: rtsthsd =%u\n",
+ priv->adapter->rtsthsd);
break;
case short_retrylim_i:
priv->adapter->txretrycount =
- le16_to_cpu(*
- ((unsigned short *)(smib->value)));
- lbs_pr_debug(1, "SNMP_RESP: txretrycount =%u\n",
- priv->adapter->rtsthsd);
+ le16_to_cpu(*((__le16 *)(smib->value)));
+ lbs_deb_cmd("SNMP_RESP: txretrycount =%u\n",
+ priv->adapter->rtsthsd);
break;
default:
break;
}
}
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -328,7 +311,7 @@ static int wlan_ret_802_11_key_material(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u16 action = le16_to_cpu(pkeymaterial->action);
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
/* Copy the returned key to driver private data */
if (action == cmd_act_get) {
@@ -371,7 +354,7 @@ static int wlan_ret_802_11_key_material(wlan_private * priv,
}
}
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -381,11 +364,11 @@ static int wlan_ret_802_11_mac_address(wlan_private * priv,
struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN);
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -395,13 +378,13 @@ static int wlan_ret_802_11_rf_tx_power(wlan_private * priv,
struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel);
- lbs_pr_debug(1, "Current TxPower Level = %d\n", adapter->txpowerlevel);
+ lbs_deb_cmd("Current TxPower Level = %d\n", adapter->txpowerlevel);
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -413,14 +396,12 @@ static int wlan_ret_802_11_rf_antenna(wlan_private * priv,
u16 action = le16_to_cpu(pAntenna->action);
if (action == cmd_act_get_rx)
- adapter->rxantennamode =
- le16_to_cpu(pAntenna->antennamode);
+ adapter->rxantennamode = le16_to_cpu(pAntenna->antennamode);
if (action == cmd_act_get_tx)
- adapter->txantennamode =
- le16_to_cpu(pAntenna->antennamode);
+ adapter->txantennamode = le16_to_cpu(pAntenna->antennamode);
- lbs_pr_debug(1, "RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
+ lbs_deb_cmd("RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
action, le16_to_cpu(pAntenna->antennamode));
return 0;
@@ -429,19 +410,17 @@ static int wlan_ret_802_11_rf_antenna(wlan_private * priv,
static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv,
struct cmd_ds_command *resp)
{
- struct cmd_ds_802_11_rate_adapt_rateset *rates =
- &resp->params.rateset;
+ struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
if (rates->action == cmd_act_get) {
- adapter->enablehwauto = rates->enablehwauto;
- adapter->ratebitmap = rates->bitmap;
+ adapter->enablehwauto = le16_to_cpu(rates->enablehwauto);
+ adapter->ratebitmap = le16_to_cpu(rates->bitmap);
}
- LEAVE();
-
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -452,43 +431,42 @@ static int wlan_ret_802_11_data_rate(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
u8 dot11datarate;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
lbs_dbg_hex("DATA_RATE_RESP: data_rate- ",
(u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate));
dot11datarate = pdatarate->datarate[0];
- if (pdatarate->action == cmd_act_get_tx_rate) {
+ if (pdatarate->action == cpu_to_le16(cmd_act_get_tx_rate)) {
memcpy(adapter->libertas_supported_rates, pdatarate->datarate,
sizeof(adapter->libertas_supported_rates));
}
adapter->datarate = libertas_index_to_data_rate(dot11datarate);
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
static int wlan_ret_802_11_rf_channel(wlan_private * priv,
struct cmd_ds_command *resp)
{
- struct cmd_ds_802_11_rf_channel *rfchannel =
- &resp->params.rfchannel;
+ struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
wlan_adapter *adapter = priv->adapter;
u16 action = le16_to_cpu(rfchannel->action);
u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
if (action == cmd_opt_802_11_rf_channel_get
&& adapter->curbssparams.channel != newchannel) {
- lbs_pr_debug(1, "channel Switch: %d to %d\n",
+ lbs_deb_cmd("channel Switch: %d to %d\n",
adapter->curbssparams.channel, newchannel);
/* Update the channel again */
adapter->curbssparams.channel = newchannel;
}
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -500,12 +478,10 @@ static int wlan_ret_802_11_rssi(wlan_private * priv,
/* store the non average value */
adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
- adapter->NF[TYPE_BEACON][TYPE_NOAVG] =
- le16_to_cpu(rssirsp->noisefloor);
+ adapter->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
- adapter->NF[TYPE_BEACON][TYPE_AVG] =
- le16_to_cpu(rssirsp->avgnoisefloor);
+ adapter->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] =
CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
@@ -515,7 +491,7 @@ static int wlan_ret_802_11_rssi(wlan_private * priv,
CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
- lbs_pr_debug(1, "Beacon RSSI value = 0x%x\n",
+ lbs_deb_cmd("Beacon RSSI value = 0x%x\n",
adapter->RSSI[TYPE_BEACON][TYPE_AVG]);
return 0;
@@ -528,11 +504,11 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
struct wlan_ioctl_regrdwr *pbuf;
pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom;
- lbs_pr_debug(1, "eeprom read len=%x\n",
+ lbs_deb_cmd("eeprom read len=%x\n",
le16_to_cpu(resp->params.rdeeprom.bytecount));
if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) {
pbuf->NOB = 0;
- lbs_pr_debug(1, "eeprom read return length is too big\n");
+ lbs_deb_cmd("eeprom read return length is too big\n");
return -1;
}
pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount);
@@ -549,17 +525,15 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
static int wlan_ret_get_log(wlan_private * priv,
struct cmd_ds_command *resp)
{
- struct cmd_ds_802_11_get_log *logmessage =
- (struct cmd_ds_802_11_get_log *)&resp->params.glog;
+ struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- /* TODO Convert it to Big Endian before copy */
- memcpy(&adapter->logmsg, logmessage,
- sizeof(struct cmd_ds_802_11_get_log));
+ /* Stored little-endian */
+ memcpy(&adapter->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log));
- LEAVE();
+ lbs_deb_enter(LBS_DEB_CMD);
return 0;
}
@@ -620,8 +594,7 @@ static inline int handle_cmd_response(u16 respcmd,
case cmd_ret_802_11_set_afc:
case cmd_ret_802_11_get_afc:
spin_lock_irqsave(&adapter->driver_lock, flags);
- memmove(adapter->cur_cmd->pdata_buf,
- &resp->params.afc,
+ memmove(adapter->cur_cmd->pdata_buf, &resp->params.afc,
sizeof(struct cmd_ds_802_11_afc));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -663,7 +636,7 @@ static inline int handle_cmd_response(u16 respcmd,
break;
case cmd_ret_802_11_key_material:
- lbs_pr_debug(1, "CMD_RESP: KEY_MATERIAL command response\n");
+ lbs_deb_cmd("CMD_RESP: KEY_MATERIAL command response\n");
ret = wlan_ret_802_11_key_material(priv, resp);
break;
@@ -687,22 +660,19 @@ static inline int handle_cmd_response(u16 respcmd,
case cmd_ret_802_11_tpc_cfg:
spin_lock_irqsave(&adapter->driver_lock, flags);
- memmove(adapter->cur_cmd->pdata_buf,
- &resp->params.tpccfg,
+ memmove(adapter->cur_cmd->pdata_buf, &resp->params.tpccfg,
sizeof(struct cmd_ds_802_11_tpc_cfg));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
break;
case cmd_ret_802_11_led_gpio_ctrl:
spin_lock_irqsave(&adapter->driver_lock, flags);
- memmove(adapter->cur_cmd->pdata_buf,
- &resp->params.ledgpio,
+ memmove(adapter->cur_cmd->pdata_buf, &resp->params.ledgpio,
sizeof(struct cmd_ds_802_11_led_ctrl));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
break;
case cmd_ret_802_11_pwr_cfg:
spin_lock_irqsave(&adapter->driver_lock, flags);
- memmove(adapter->cur_cmd->pdata_buf,
- &resp->params.pwrcfg,
+ memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg,
sizeof(struct cmd_ds_802_11_pwr_cfg));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -724,23 +694,21 @@ static inline int handle_cmd_response(u16 respcmd,
case cmd_ret_fwt_access:
spin_lock_irqsave(&adapter->driver_lock, flags);
if (adapter->cur_cmd->pdata_buf)
- memcpy(adapter->cur_cmd->pdata_buf,
- &resp->params.fwt,
- sizeof(resp->params.fwt));
+ memcpy(adapter->cur_cmd->pdata_buf, &resp->params.fwt,
+ sizeof(resp->params.fwt));
spin_unlock_irqrestore(&adapter->driver_lock, flags);
break;
case cmd_ret_mesh_access:
if (adapter->cur_cmd->pdata_buf)
- memcpy(adapter->cur_cmd->pdata_buf,
- &resp->params.mesh,
+ memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh,
sizeof(resp->params.mesh));
break;
case cmd_rte_802_11_tx_rate_query:
priv->adapter->txrate = resp->params.txrate.txrate;
break;
default:
- lbs_pr_debug(1, "CMD_RESP: Unknown command response %#x\n",
- resp->command);
+ lbs_deb_cmd("CMD_RESP: Unknown command response %#x\n",
+ resp->command);
break;
}
return ret;
@@ -755,9 +723,9 @@ int libertas_process_rx_command(wlan_private * priv)
ulong flags;
u16 result;
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- lbs_pr_debug(1, "CMD_RESP: @ %lu\n", jiffies);
+ lbs_deb_cmd("CMD_RESP: @ %lu\n", jiffies);
/* Now we got response from FW, cancel the command timer */
del_timer(&adapter->command_timer);
@@ -766,7 +734,7 @@ int libertas_process_rx_command(wlan_private * priv)
spin_lock_irqsave(&adapter->driver_lock, flags);
if (!adapter->cur_cmd) {
- lbs_pr_debug(1, "CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd);
+ lbs_deb_cmd("CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd);
ret = -1;
spin_unlock_irqrestore(&adapter->driver_lock, flags);
goto done;
@@ -774,17 +742,17 @@ int libertas_process_rx_command(wlan_private * priv)
resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr);
lbs_dbg_hex("CMD_RESP:", adapter->cur_cmd->bufvirtualaddr,
- priv->wlan_dev.upld_len);
+ priv->upld_len);
respcmd = le16_to_cpu(resp->command);
result = le16_to_cpu(resp->result);
- lbs_pr_debug(1, "CMD_RESP: %x result: %d length: %d\n", respcmd,
- result, priv->wlan_dev.upld_len);
+ lbs_deb_cmd("CMD_RESP: %x result: %d length: %d\n", respcmd,
+ result, priv->upld_len);
if (!(respcmd & 0x8000)) {
- lbs_pr_debug(1, "Invalid response to command!");
+ lbs_deb_cmd("Invalid response to command!");
adapter->cur_cmd_retcode = -1;
__libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
adapter->nr_cmd_pending--;
@@ -795,56 +763,52 @@ int libertas_process_rx_command(wlan_private * priv)
}
/* Store the response code to cur_cmd_retcode. */
- adapter->cur_cmd_retcode = le16_to_cpu(resp->result);
+ adapter->cur_cmd_retcode = result;;
if (respcmd == cmd_ret_802_11_ps_mode) {
- struct cmd_ds_802_11_ps_mode *psmode;
+ struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode;
+ u16 action = le16_to_cpu(psmode->action);
- psmode = &resp->params.psmode;
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
- resp->result, psmode->action);
- psmode->action = cpu_to_le16(psmode->action);
+ result, action);
if (result) {
- lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n",
- resp->result);
- if (adapter->mode == IW_MODE_ADHOC) {
- /*
- * We should not re-try enter-ps command in
- * ad-hoc mode. It takes place in
- * libertas_execute_next_command().
- */
- if (psmode->action == cmd_subcmd_enter_ps)
- adapter->psmode =
- wlan802_11powermodecam;
- }
- } else if (psmode->action == cmd_subcmd_enter_ps) {
+ lbs_deb_cmd("CMD_RESP: PS command failed- %#x \n",
+ result);
+ /*
+ * We should not re-try enter-ps command in
+ * ad-hoc mode. It takes place in
+ * libertas_execute_next_command().
+ */
+ if (adapter->mode == IW_MODE_ADHOC &&
+ action == cmd_subcmd_enter_ps)
+ adapter->psmode = wlan802_11powermodecam;
+ } else if (action == cmd_subcmd_enter_ps) {
adapter->needtowakeup = 0;
adapter->psstate = PS_STATE_AWAKE;
- lbs_pr_debug(1, "CMD_RESP: Enter_PS command response\n");
+ lbs_deb_cmd("CMD_RESP: Enter_PS command response\n");
if (adapter->connect_status != libertas_connected) {
/*
* When Deauth Event received before Enter_PS command
* response, We need to wake up the firmware.
*/
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"Disconnected, Going to invoke libertas_ps_wakeup\n");
- mutex_unlock(&adapter->lock);
spin_unlock_irqrestore(&adapter->driver_lock, flags);
+ mutex_unlock(&adapter->lock);
libertas_ps_wakeup(priv, 0);
mutex_lock(&adapter->lock);
spin_lock_irqsave(&adapter->driver_lock, flags);
}
- } else if (psmode->action == cmd_subcmd_exit_ps) {
+ } else if (action == cmd_subcmd_exit_ps) {
adapter->needtowakeup = 0;
adapter->psstate = PS_STATE_FULL_POWER;
- lbs_pr_debug(1, "CMD_RESP: Exit_PS command response\n");
+ lbs_deb_cmd("CMD_RESP: Exit_PS command response\n");
} else {
- lbs_pr_debug(1, "CMD_RESP: PS- action=0x%X\n",
- psmode->action);
+ lbs_deb_cmd("CMD_RESP: PS- action=0x%X\n", action);
}
__libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
@@ -865,15 +829,15 @@ int libertas_process_rx_command(wlan_private * priv)
/* If the command is not successful, cleanup and return failure */
if ((result != 0 || !(respcmd & 0x8000))) {
- lbs_pr_debug(1, "CMD_RESP: command reply %#x result=%#x\n",
- resp->command, resp->result);
+ lbs_deb_cmd("CMD_RESP: command reply %#x result=%#x\n",
+ respcmd, result);
/*
* Handling errors here
*/
switch (respcmd) {
case cmd_ret_hw_spec_info:
case cmd_ret_802_11_reset:
- lbs_pr_debug(1, "CMD_RESP: Reset command failed\n");
+ lbs_deb_cmd("CMD_RESP: Reset command failed\n");
break;
}
@@ -903,7 +867,7 @@ int libertas_process_rx_command(wlan_private * priv)
done:
mutex_unlock(&adapter->lock);
- LEAVE();
+ lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
@@ -917,37 +881,37 @@ int libertas_process_event(wlan_private * priv)
eventcause = adapter->eventcause;
spin_unlock_irq(&adapter->driver_lock);
- ENTER();
+ lbs_deb_enter(LBS_DEB_CMD);
- lbs_pr_debug(1, "EVENT Cause %x\n", eventcause);
+ lbs_deb_cmd("EVENT Cause %x\n", eventcause);
switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) {
case MACREG_INT_CODE_LINK_SENSED:
- lbs_pr_debug(1, "EVENT: MACREG_INT_CODE_LINK_SENSED\n");
+ lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
break;
case MACREG_INT_CODE_DEAUTHENTICATED:
- lbs_pr_debug(1, "EVENT: Deauthenticated\n");
+ lbs_deb_cmd("EVENT: Deauthenticated\n");
libertas_mac_event_disconnected(priv);
break;
case MACREG_INT_CODE_DISASSOCIATED:
- lbs_pr_debug(1, "EVENT: Disassociated\n");
+ lbs_deb_cmd("EVENT: Disassociated\n");
libertas_mac_event_disconnected(priv);
break;
case MACREG_INT_CODE_LINK_LOSE_NO_SCAN:
- lbs_pr_debug(1, "EVENT: Link lost\n");
+ lbs_deb_cmd("EVENT: Link lost\n");
libertas_mac_event_disconnected(priv);
break;
case MACREG_INT_CODE_PS_SLEEP:
- lbs_pr_debug(1, "EVENT: SLEEP\n");
- lbs_pr_debug(1, "_");
+ lbs_deb_cmd("EVENT: SLEEP\n");
+ lbs_deb_cmd("_");
/* handle unexpected PS SLEEP event */
if (adapter->psstate == PS_STATE_FULL_POWER) {
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"EVENT: In FULL POWER mode - ignore PS SLEEP\n");
break;
}
@@ -958,12 +922,12 @@ int libertas_process_event(wlan_private * priv)
break;
case MACREG_INT_CODE_PS_AWAKE:
- lbs_pr_debug(1, "EVENT: AWAKE \n");
- lbs_pr_debug(1, "|");
+ lbs_deb_cmd("EVENT: AWAKE \n");
+ lbs_deb_cmd("|");
/* handle unexpected PS AWAKE event */
if (adapter->psstate == PS_STATE_FULL_POWER) {
- lbs_pr_debug(1,
+ lbs_deb_cmd(
"EVENT: In FULL POWER mode - ignore PS AWAKE\n");
break;
}
@@ -977,18 +941,18 @@ int libertas_process_event(wlan_private * priv)
* adapter->needtowakeup will be set to FALSE
* in libertas_ps_wakeup()
*/
- lbs_pr_debug(1, "Waking up...\n");
+ lbs_deb_cmd("Waking up...\n");
libertas_ps_wakeup(priv, 0);
}
break;
case MACREG_INT_CODE_MIC_ERR_UNICAST:
- lbs_pr_debug(1, "EVENT: UNICAST MIC ERROR\n");
+ lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST);
break;
case MACREG_INT_CODE_MIC_ERR_MULTICAST:
- lbs_pr_debug(1, "EVENT: MULTICAST MIC ERROR\n");
+ lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST);
break;
case MACREG_INT_CODE_MIB_CHANGED:
@@ -996,7 +960,7 @@ int libertas_process_event(wlan_private * priv)
break;
case MACREG_INT_CODE_ADHOC_BCN_LOST:
- lbs_pr_debug(1, "EVENT: HWAC - ADHOC BCN LOST\n");
+ lbs_deb_cmd("EVENT: HWAC - ADHOC BCN LOST\n");
break;
case MACREG_INT_CODE_RSSI_LOW:
@@ -1015,6 +979,17 @@ int libertas_process_event(wlan_private * priv)
lbs_pr_alert( "EVENT: SNR_HIGH\n");
break;
+ case MACREG_INT_CODE_MESH_AUTO_STARTED:
+ lbs_pr_alert( "EVENT: MESH_AUTO_STARTED\n");
+ adapter->connect_status = libertas_connected ;
+ if (priv->mesh_open == 1) {
+ netif_wake_queue(priv->mesh_dev) ;
+ netif_carrier_on(priv->mesh_dev) ;
+ }
+ adapter->mode = IW_MODE_ADHOC ;
+ schedule_work(&priv->sync_channel);
+ break;
+
default:
lbs_pr_alert( "EVENT: unknown event id: %#x\n",
eventcause >> SBI_EVENT_CAUSE_SHIFT);
@@ -1024,6 +999,7 @@ int libertas_process_event(wlan_private * priv)
spin_lock_irq(&adapter->driver_lock);
adapter->eventcause = 0;
spin_unlock_irq(&adapter->driver_lock);
- LEAVE();
+
+ lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 7d7bc5e86a5..715cbdaa1d4 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -4,6 +4,7 @@
#include <linux/delay.h>
#include <linux/mm.h>
#include <net/iw_handler.h>
+
#include "dev.h"
#include "decl.h"
#include "host.h"
@@ -15,7 +16,9 @@ static char *szStates[] = {
"Disconnected"
};
-void libertas_debug_init(wlan_private * priv, struct net_device *dev);
+#ifdef PROC_DEBUG
+static void libertas_debug_init(wlan_private * priv, struct net_device *dev);
+#endif
static int open_file_generic(struct inode *inode, struct file *file)
{
@@ -60,43 +63,33 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
int numscansdone = 0, res;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
+ struct bss_descriptor * iter_bss;
pos += snprintf(buf+pos, len-pos,
- "---------------------------------------");
- pos += snprintf(buf+pos, len-pos,
- "---------------------------------------\n");
- pos += snprintf(buf+pos, len-pos,
"# | ch | ss | bssid | cap | TSF | Qual | SSID \n");
- pos += snprintf(buf+pos, len-pos,
- "---------------------------------------");
- pos += snprintf(buf+pos, len-pos,
- "---------------------------------------\n");
- while (numscansdone < priv->adapter->numinscantable) {
- struct bss_descriptor *pbssinfo;
+ mutex_lock(&priv->adapter->lock);
+ list_for_each_entry (iter_bss, &priv->adapter->network_list, list) {
u16 cap;
- pbssinfo = &priv->adapter->scantable[numscansdone];
- memcpy(&cap, &pbssinfo->cap, sizeof(cap));
+ memcpy(&cap, &iter_bss->cap, sizeof(cap));
pos += snprintf(buf+pos, len-pos,
- "%02u| %03d | %03ld | %02x:%02x:%02x:%02x:%02x:%02x |",
- numscansdone, pbssinfo->channel, pbssinfo->rssi,
- pbssinfo->macaddress[0], pbssinfo->macaddress[1],
- pbssinfo->macaddress[2], pbssinfo->macaddress[3],
- pbssinfo->macaddress[4], pbssinfo->macaddress[5]);
+ "%02u| %03d | %03ld | " MAC_FMT " |",
+ numscansdone, iter_bss->channel, iter_bss->rssi,
+ MAC_ARG(iter_bss->bssid));
pos += snprintf(buf+pos, len-pos, " %04x-", cap);
pos += snprintf(buf+pos, len-pos, "%c%c%c |",
- pbssinfo->cap.ibss ? 'A' : 'I',
- pbssinfo->cap.privacy ? 'P' : ' ',
- pbssinfo->cap.spectrummgmt ? 'S' : ' ');
- pos += snprintf(buf+pos, len-pos, " %08llx |", pbssinfo->networktsf);
- pos += snprintf(buf+pos, len-pos, " %d |",
- SCAN_RSSI(priv->adapter->scantable[numscansdone].rssi));
-
- pos += snprintf(buf+pos, len-pos, " %s\n", pbssinfo->ssid.ssid);
+ iter_bss->cap.ibss ? 'A' : 'I',
+ iter_bss->cap.privacy ? 'P' : ' ',
+ iter_bss->cap.spectrummgmt ? 'S' : ' ');
+ pos += snprintf(buf+pos, len-pos, " %08llx |", iter_bss->networktsf);
+ pos += snprintf(buf+pos, len-pos, " %d |", SCAN_RSSI(iter_bss->rssi));
+ pos += snprintf(buf+pos, len-pos, " %s\n",
+ escape_essid(iter_bss->ssid, iter_bss->ssid_len));
numscansdone++;
}
+ mutex_unlock(&priv->adapter->lock);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
@@ -111,7 +104,6 @@ static ssize_t libertas_sleepparams_write(struct file *file,
wlan_private *priv = file->private_data;
ssize_t buf_size, res;
int p1, p2, p3, p4, p5, p6;
- struct sleep_params sp;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
@@ -125,14 +117,12 @@ static ssize_t libertas_sleepparams_write(struct file *file,
res = -EFAULT;
goto out_unlock;
}
- sp.sp_error = p1;
- sp.sp_offset = p2;
- sp.sp_stabletime = p3;
- sp.sp_calcontrol = p4;
- sp.sp_extsleepclk = p5;
- sp.sp_reserved = p6;
-
- memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params));
+ priv->adapter->sp.sp_error = p1;
+ priv->adapter->sp.sp_offset = p2;
+ priv->adapter->sp.sp_stabletime = p3;
+ priv->adapter->sp.sp_calcontrol = p4;
+ priv->adapter->sp.sp_extsleepclk = p5;
+ priv->adapter->sp.sp_reserved = p6;
res = libertas_prepare_and_send_command(priv,
cmd_802_11_sleep_params,
@@ -185,7 +175,6 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
{
wlan_private *priv = file->private_data;
ssize_t res, buf_size;
- struct WLAN_802_11_SSID extscan_ssid;
union iwreq_data wrqu;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr;
@@ -196,13 +185,10 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
goto out_unlock;
}
- memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1);
- extscan_ssid.ssidlength = strlen(buf)-1;
-
- libertas_send_specific_SSID_scan(priv, &extscan_ssid, 1);
+ libertas_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);
memset(&wrqu, 0, sizeof(union iwreq_data));
- wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
+ wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
out_unlock:
free_page(addr);
@@ -251,16 +237,13 @@ static void libertas_parse_bssid(char *buf, size_t count,
{
char *hold;
unsigned int mac[ETH_ALEN];
- int i;
hold = strstr(buf, "bssid=");
if (!hold)
return;
hold += 6;
- sscanf(hold, "%2x:%2x:%2x:%2x:%2x:%2x", mac, mac+1, mac+2, mac+3,
- mac+4, mac+5);
- for(i=0;i<ETH_ALEN;i++)
- scan_cfg->specificBSSID[i] = mac[i];
+ sscanf(hold, MAC_FMT, mac, mac+1, mac+2, mac+3, mac+4, mac+5);
+ memcpy(scan_cfg->bssid, mac, ETH_ALEN);
}
static void libertas_parse_ssid(char *buf, size_t count,
@@ -278,28 +261,26 @@ static void libertas_parse_ssid(char *buf, size_t count,
end = buf + count - 1;
size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
- strncpy(scan_cfg->specificSSID, hold, size);
+ strncpy(scan_cfg->ssid, hold, size);
return;
}
-static void libertas_parse_keep(char *buf, size_t count,
- struct wlan_ioctl_user_scan_cfg *scan_cfg)
+static int libertas_parse_clear(char *buf, size_t count, const char *tag)
{
char *hold;
int val;
- hold = strstr(buf, "keep=");
+ hold = strstr(buf, tag);
if (!hold)
- return;
- hold += 5;
+ return 0;
+ hold += strlen(tag);
sscanf(hold, "%d", &val);
if (val != 0)
val = 1;
- scan_cfg->keeppreviousscan = val;
- return;
+ return val;
}
static int libertas_parse_dur(char *buf, size_t count,
@@ -382,17 +363,18 @@ static ssize_t libertas_setuserscan(struct file *file,
dur = libertas_parse_dur(buf, count, scan_cfg);
libertas_parse_chan(buf, count, scan_cfg, dur);
libertas_parse_bssid(buf, count, scan_cfg);
+ scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid=");
libertas_parse_ssid(buf, count, scan_cfg);
- libertas_parse_keep(buf, count, scan_cfg);
+ scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid=");
libertas_parse_probes(buf, count, scan_cfg);
libertas_parse_type(buf, count, scan_cfg);
- wlan_scan_networks(priv, scan_cfg);
+ wlan_scan_networks(priv, scan_cfg, 1);
wait_event_interruptible(priv->adapter->cmd_pending,
!priv->adapter->nr_cmd_pending);
memset(&wrqu, 0x00, sizeof(union iwreq_data));
- wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
+ wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
out_unlock:
free_page(addr);
@@ -407,11 +389,11 @@ static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
u16 wait_option = cmd_option_waitforrsp;
if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
- lbs_pr_debug(1, "failed libertas_get_free_cmd_ctrl_node\n");
+ lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
return -ENOMEM;
}
if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
- lbs_pr_debug(1, "failed to allocate response buffer!\n");
+ lbs_deb_debugfs("failed to allocate response buffer!\n");
return -ENOMEM;
}
libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
@@ -420,8 +402,8 @@ static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
(*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
(*cmdnode)->cmdwaitqwoken = 0;
*cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
- (*cmd)->command = cmd_802_11_subscribe_event;
- (*cmd)->seqnum = ++priv->adapter->seqnum;
+ (*cmd)->command = cpu_to_le16(cmd_802_11_subscribe_event);
+ (*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum);
(*cmd)->result = 0;
return 0;
}
@@ -447,26 +429,25 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_get;
- pcmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
+ event->action = cpu_to_le16(cmd_act_get);
+ pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -474,17 +455,17 @@ static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
- event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
- while (cmd_len < pcmdptr->size) {
- struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
- switch(header->type) {
+ event = (void *)(response_buf + S_DS_GEN);
+ while (cmd_len < le16_to_cpu(pcmdptr->size)) {
+ struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
+ switch (header->type) {
struct mrvlietypes_rssithreshold *Lowrssi;
- case TLV_TYPE_RSSI_LOW:
- Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
- pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
- Lowrssi->rssivalue,
- Lowrssi->rssifreq,
- (event->events & 0x0001)?1:0);
+ case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW):
+ Lowrssi = (void *)(response_buf + cmd_len);
+ pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
+ Lowrssi->rssivalue,
+ Lowrssi->rssifreq,
+ (event->events & cpu_to_le16(0x0001))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
@@ -512,21 +493,20 @@ static u16 libertas_get_events_bitmap(wlan_private *priv)
return res;
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_get;
- pcmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
+ event->action = cpu_to_le16(cmd_act_get);
+ pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
return 0;
}
@@ -538,7 +518,7 @@ static u16 libertas_get_events_bitmap(wlan_private *priv)
}
event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
- event_bitmap = event->events;
+ event_bitmap = le16_to_cpu(event->events);
kfree(response_buf);
return event_bitmap;
}
@@ -579,7 +559,7 @@ static ssize_t libertas_lowrssi_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_set;
+ event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_rssithreshold));
@@ -588,30 +568,30 @@ static ssize_t libertas_lowrssi_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
rssi_threshold->header.type = cpu_to_le16(0x0104);
- rssi_threshold->header.len = 2;
- rssi_threshold->rssivalue = cpu_to_le16(value);
- rssi_threshold->rssifreq = cpu_to_le16(freq);
+ rssi_threshold->header.len = cpu_to_le16(2);
+ rssi_threshold->rssivalue = value;
+ rssi_threshold->rssifreq = freq;
event_bitmap |= subscribed ? 0x0001 : 0x0;
- event->events = event_bitmap;
+ event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -645,27 +625,26 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_get;
- pcmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
+ event->action = cpu_to_le16(cmd_act_get);
+ pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -673,17 +652,17 @@ static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
- event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
- while (cmd_len < pcmdptr->size) {
- struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
- switch(header->type) {
+ event = (void *)(response_buf + S_DS_GEN);
+ while (cmd_len < le16_to_cpu(pcmdptr->size)) {
+ struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
+ switch (header->type) {
struct mrvlietypes_snrthreshold *LowSnr;
- case TLV_TYPE_SNR_LOW:
- LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
- pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
- LowSnr->snrvalue,
- LowSnr->snrfreq,
- (event->events & 0x0002)?1:0);
+ case __constant_cpu_to_le16(TLV_TYPE_SNR_LOW):
+ LowSnr = (void *)(response_buf + cmd_len);
+ pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
+ LowSnr->snrvalue,
+ LowSnr->snrfreq,
+ (event->events & cpu_to_le16(0x0002))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
@@ -733,7 +712,7 @@ static ssize_t libertas_lowsnr_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_set;
+ event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_snrthreshold));
@@ -741,30 +720,30 @@ static ssize_t libertas_lowsnr_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
- snr_threshold->header.len = 2;
- snr_threshold->snrvalue = cpu_to_le16(value);
- snr_threshold->snrfreq = cpu_to_le16(freq);
+ snr_threshold->header.len = cpu_to_le16(2);
+ snr_threshold->snrvalue = value;
+ snr_threshold->snrfreq = freq;
event_bitmap |= subscribed ? 0x0002 : 0x0;
- event->events = event_bitmap;
+ event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -799,27 +778,26 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_get;
- pcmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
+ event->action = cpu_to_le16(cmd_act_get);
+ pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -827,17 +805,17 @@ static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
- event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
- while (cmd_len < pcmdptr->size) {
- struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
- switch(header->type) {
+ event = (void *)(response_buf + S_DS_GEN);
+ while (cmd_len < le16_to_cpu(pcmdptr->size)) {
+ struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
+ switch (header->type) {
struct mrvlietypes_failurecount *failcount;
- case TLV_TYPE_FAILCOUNT:
- failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
- pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
- failcount->failvalue,
- failcount->Failfreq,
- (event->events & 0x0004)?1:0);
+ case __constant_cpu_to_le16(TLV_TYPE_FAILCOUNT):
+ failcount = (void *)(response_buf + cmd_len);
+ pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
+ failcount->failvalue,
+ failcount->Failfreq,
+ (event->events & cpu_to_le16(0x0004))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_failurecount);
break;
@@ -886,7 +864,7 @@ static ssize_t libertas_failcount_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_set;
+ event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_failurecount));
@@ -894,30 +872,30 @@ static ssize_t libertas_failcount_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
failcount = (struct mrvlietypes_failurecount *)(ptr);
failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
- failcount->header.len = 2;
- failcount->failvalue = cpu_to_le16(value);
- failcount->Failfreq = cpu_to_le16(freq);
+ failcount->header.len = cpu_to_le16(2);
+ failcount->failvalue = value;
+ failcount->Failfreq = freq;
event_bitmap |= subscribed ? 0x0004 : 0x0;
- event->events = event_bitmap;
+ event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = (struct cmd_ds_command *)response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -951,27 +929,26 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_get;
- pcmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
+ event->action = cpu_to_le16(cmd_act_get);
+ pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
free_page(addr);
kfree(response_buf);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
free_page(addr);
kfree(response_buf);
@@ -979,16 +956,16 @@ static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
- event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
- while (cmd_len < pcmdptr->size) {
- struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
- switch(header->type) {
+ event = (void *)(response_buf + S_DS_GEN);
+ while (cmd_len < le16_to_cpu(pcmdptr->size)) {
+ struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
+ switch (header->type) {
struct mrvlietypes_beaconsmissed *bcnmiss;
- case TLV_TYPE_BCNMISS:
- bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
- pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
- bcnmiss->beaconmissed,
- (event->events & 0x0008)?1:0);
+ case __constant_cpu_to_le16(TLV_TYPE_BCNMISS):
+ bcnmiss = (void *)(response_buf + cmd_len);
+ pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
+ bcnmiss->beaconmissed,
+ (event->events & cpu_to_le16(0x0008))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
break;
@@ -1038,7 +1015,7 @@ static ssize_t libertas_bcnmiss_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_set;
+ event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_beaconsmissed));
@@ -1046,29 +1023,29 @@ static ssize_t libertas_bcnmiss_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
- bcnmiss->header.len = 2;
- bcnmiss->beaconmissed = cpu_to_le16(value);
+ bcnmiss->header.len = cpu_to_le16(2);
+ bcnmiss->beaconmissed = value;
event_bitmap |= subscribed ? 0x0008 : 0x0;
- event->events = event_bitmap;
+ event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
free_page(addr);
kfree(response_buf);
@@ -1102,27 +1079,26 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_get;
- pcmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
+ event->action = cpu_to_le16(cmd_act_get);
+ pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -1130,17 +1106,17 @@ static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
- event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
- while (cmd_len < pcmdptr->size) {
- struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
- switch(header->type) {
+ event = (void *)(response_buf + S_DS_GEN);
+ while (cmd_len < le16_to_cpu(pcmdptr->size)) {
+ struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
+ switch (header->type) {
struct mrvlietypes_rssithreshold *Highrssi;
- case TLV_TYPE_RSSI_HIGH:
- Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
- pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
- Highrssi->rssivalue,
- Highrssi->rssifreq,
- (event->events & 0x0010)?1:0);
+ case __constant_cpu_to_le16(TLV_TYPE_RSSI_HIGH):
+ Highrssi = (void *)(response_buf + cmd_len);
+ pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
+ Highrssi->rssivalue,
+ Highrssi->rssifreq,
+ (event->events & cpu_to_le16(0x0010))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
@@ -1190,7 +1166,7 @@ static ssize_t libertas_highrssi_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_set;
+ event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_rssithreshold));
@@ -1198,29 +1174,29 @@ static ssize_t libertas_highrssi_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
- rssi_threshold->header.len = 2;
- rssi_threshold->rssivalue = cpu_to_le16(value);
- rssi_threshold->rssifreq = cpu_to_le16(freq);
+ rssi_threshold->header.len = cpu_to_le16(2);
+ rssi_threshold->rssivalue = value;
+ rssi_threshold->rssifreq = freq;
event_bitmap |= subscribed ? 0x0010 : 0x0;
- event->events = event_bitmap;
+ event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
return 0;
@@ -1253,27 +1229,26 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
}
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_get;
- pcmdptr->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
+ event->action = cpu_to_le16(cmd_act_get);
+ pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -1281,17 +1256,17 @@ static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
}
cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
- event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
- while (cmd_len < pcmdptr->size) {
- struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
- switch(header->type) {
+ event = (void *)(response_buf + S_DS_GEN);
+ while (cmd_len < le16_to_cpu(pcmdptr->size)) {
+ struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
+ switch (header->type) {
struct mrvlietypes_snrthreshold *HighSnr;
- case TLV_TYPE_SNR_HIGH:
- HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
- pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
- HighSnr->snrvalue,
- HighSnr->snrfreq,
- (event->events & 0x0020)?1:0);
+ case __constant_cpu_to_le16(TLV_TYPE_SNR_HIGH):
+ HighSnr = (void *)(response_buf + cmd_len);
+ pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
+ HighSnr->snrvalue,
+ HighSnr->snrfreq,
+ (event->events & cpu_to_le16(0x0020))?1:0);
default:
cmd_len += sizeof(struct mrvlietypes_snrthreshold);
break;
@@ -1341,7 +1316,7 @@ static ssize_t libertas_highsnr_write(struct file *file,
goto out_unlock;
event = &pcmdptr->params.subscribe_event;
- event->action = cmd_act_set;
+ event->action = cpu_to_le16(cmd_act_set);
pcmdptr->size = cpu_to_le16(S_DS_GEN +
sizeof(struct cmd_ds_802_11_subscribe_event) +
sizeof(struct mrvlietypes_snrthreshold));
@@ -1349,30 +1324,30 @@ static ssize_t libertas_highsnr_write(struct file *file,
ptr = (u8*) pcmdptr+cmd_len;
snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
- snr_threshold->header.len = 2;
- snr_threshold->snrvalue = cpu_to_le16(value);
- snr_threshold->snrfreq = cpu_to_le16(freq);
+ snr_threshold->header.len = cpu_to_le16(2);
+ snr_threshold->snrvalue = value;
+ snr_threshold->snrfreq = freq;
event_bitmap |= subscribed ? 0x0020 : 0x0;
- event->events = event_bitmap;
+ event->events = cpu_to_le16(event_bitmap);
libertas_queue_cmd(adapter, pcmdnode, 1);
wake_up_interruptible(&priv->mainthread.waitq);
/* Sleep until response is generated by FW */
wait_event_interruptible(pcmdnode->cmdwait_q,
- pcmdnode->cmdwaitqwoken);
+ pcmdnode->cmdwaitqwoken);
pcmdptr = response_buf;
if (pcmdptr->result) {
- lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
- pcmdptr->result);
+ lbs_pr_err("%s: fail, result=%d\n", __func__,
+ le16_to_cpu(pcmdptr->result));
kfree(response_buf);
free_page(addr);
return 0;
}
- if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
+ if (pcmdptr->command != cpu_to_le16(cmd_ret_802_11_subscribe_event)) {
lbs_pr_err("command response incorrect!\n");
kfree(response_buf);
free_page(addr);
@@ -1760,7 +1735,7 @@ void libertas_debugfs_remove_one(wlan_private *priv)
debugfs_remove(priv->regs_dir);
- for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
+ for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
debugfs_remove(priv->debugfs_events_files[i]);
debugfs_remove(priv->events_dir);
@@ -1769,13 +1744,19 @@ void libertas_debugfs_remove_one(wlan_private *priv)
#endif
for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
debugfs_remove(priv->debugfs_files[i]);
+ debugfs_remove(priv->debugfs_dir);
}
+
+
/* debug entry */
+#ifdef PROC_DEBUG
+
#define item_size(n) (FIELD_SIZEOF(wlan_adapter, n))
#define item_addr(n) (offsetof(wlan_adapter, n))
+
struct debug_data {
char name[32];
u32 size;
@@ -1863,7 +1844,7 @@ static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
return 0;
if (copy_from_user(pdata, buf, cnt)) {
- lbs_pr_debug(1, "Copy from user failed\n");
+ lbs_deb_debugfs("Copy from user failed\n");
kfree(pdata);
return 0;
}
@@ -1913,7 +1894,7 @@ static struct file_operations libertas_debug_fops = {
* @param dev pointer net_device
* @return N/A
*/
-void libertas_debug_init(wlan_private * priv, struct net_device *dev)
+static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
{
int i;
@@ -1927,4 +1908,5 @@ void libertas_debug_init(wlan_private * priv, struct net_device *dev)
priv->debugfs_dir, &items[0],
&libertas_debug_fops);
}
+#endif
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 606bdd002be..40f56bb1eac 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -6,6 +6,8 @@
#ifndef _WLAN_DECL_H_
#define _WLAN_DECL_H_
+#include <linux/device.h>
+
#include "defs.h"
/** Function Prototype Declaration */
@@ -46,7 +48,7 @@ u32 libertas_index_to_data_rate(u8 index);
u8 libertas_data_rate_to_index(u32 rate);
void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen);
-int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
+void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
/** The proc fs interface */
int libertas_process_rx_command(wlan_private * priv);
@@ -66,18 +68,24 @@ void libertas_ps_wakeup(wlan_private * priv, int wait_option);
void libertas_tx_runqueue(wlan_private *priv);
-extern struct chan_freq_power *libertas_find_cfp_by_band_and_channel(
+struct chan_freq_power *libertas_find_cfp_by_band_and_channel(
wlan_adapter * adapter, u8 band, u16 channel);
-extern void libertas_mac_event_disconnected(wlan_private * priv);
+void libertas_mac_event_disconnected(wlan_private * priv);
void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str);
-int reset_device(wlan_private *priv);
+/* fw.c */
+int libertas_init_fw(wlan_private * priv, char *fw_name);
+
/* main.c */
-extern struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
+struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
int *cfp_no);
-wlan_private *wlan_add_card(void *card);
-int wlan_remove_card(void *card);
+wlan_private *libertas_add_card(void *card, struct device *dmdev);
+int libertas_activate_card(wlan_private *priv, char *fw_name);
+int libertas_remove_card(wlan_private *priv);
+int libertas_add_mesh(wlan_private *priv, struct device *dev);
+void libertas_remove_mesh(wlan_private *priv);
+
#endif /* _WLAN_DECL_H_ */
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 80dd9ea19c8..4dd43e59bda 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -7,14 +7,79 @@
#include <linux/spinlock.h>
-extern unsigned int libertas_debug;
-
#ifdef CONFIG_LIBERTAS_DEBUG
#define DEBUG
#define PROC_DEBUG
#endif
-#define DRV_NAME "usb8xxx"
+#ifndef DRV_NAME
+#define DRV_NAME "libertas"
+#endif
+
+
+#define LBS_DEB_ENTER 0x00000001
+#define LBS_DEB_LEAVE 0x00000002
+#define LBS_DEB_MAIN 0x00000004
+#define LBS_DEB_NET 0x00000008
+#define LBS_DEB_MESH 0x00000010
+#define LBS_DEB_WEXT 0x00000020
+#define LBS_DEB_IOCTL 0x00000040
+#define LBS_DEB_SCAN 0x00000080
+#define LBS_DEB_ASSOC 0x00000100
+#define LBS_DEB_JOIN 0x00000200
+#define LBS_DEB_11D 0x00000400
+#define LBS_DEB_DEBUGFS 0x00000800
+#define LBS_DEB_ETHTOOL 0x00001000
+#define LBS_DEB_HOST 0x00002000
+#define LBS_DEB_CMD 0x00004000
+#define LBS_DEB_RX 0x00008000
+#define LBS_DEB_TX 0x00010000
+#define LBS_DEB_USB 0x00020000
+#define LBS_DEB_CS 0x00040000
+#define LBS_DEB_FW 0x00080000
+#define LBS_DEB_THREAD 0x00100000
+#define LBS_DEB_HEX 0x00200000
+
+extern unsigned int libertas_debug;
+
+#ifdef DEBUG
+#define LBS_DEB_LL(grp, fmt, args...) \
+do { if ((libertas_debug & (grp)) == (grp)) \
+ printk(KERN_DEBUG DRV_NAME "%s: " fmt, \
+ in_interrupt() ? " (INT)" : "", ## args); } while (0)
+#else
+#define LBS_DEB_LL(grp, fmt, args...) do {} while (0)
+#endif
+
+#define lbs_deb_enter(grp) \
+ LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s():%d enter\n", __FUNCTION__, __LINE__);
+#define lbs_deb_enter_args(grp, fmt, args...) \
+ LBS_DEB_LL(grp | LBS_DEB_ENTER, "%s(" fmt "):%d\n", __FUNCTION__, ## args, __LINE__);
+#define lbs_deb_leave(grp) \
+ LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave\n", __FUNCTION__, __LINE__);
+#define lbs_deb_leave_args(grp, fmt, args...) \
+ LBS_DEB_LL(grp | LBS_DEB_LEAVE, "%s():%d leave, " fmt "\n", \
+ __FUNCTION__, __LINE__, ##args);
+#define lbs_deb_main(fmt, args...) LBS_DEB_LL(LBS_DEB_MAIN, fmt, ##args)
+#define lbs_deb_net(fmt, args...) LBS_DEB_LL(LBS_DEB_NET, fmt, ##args)
+#define lbs_deb_mesh(fmt, args...) LBS_DEB_LL(LBS_DEB_MESH, fmt, ##args)
+#define lbs_deb_wext(fmt, args...) LBS_DEB_LL(LBS_DEB_WEXT, fmt, ##args)
+#define lbs_deb_ioctl(fmt, args...) LBS_DEB_LL(LBS_DEB_IOCTL, fmt, ##args)
+#define lbs_deb_scan(fmt, args...) LBS_DEB_LL(LBS_DEB_SCAN, fmt, ##args)
+#define lbs_deb_assoc(fmt, args...) LBS_DEB_LL(LBS_DEB_ASSOC, fmt, ##args)
+#define lbs_deb_join(fmt, args...) LBS_DEB_LL(LBS_DEB_JOIN, fmt, ##args)
+#define lbs_deb_11d(fmt, args...) LBS_DEB_LL(LBS_DEB_11D, fmt, ##args)
+#define lbs_deb_debugfs(fmt, args...) LBS_DEB_LL(LBS_DEB_DEBUGFS, fmt, ##args)
+#define lbs_deb_ethtool(fmt, args...) LBS_DEB_LL(LBS_DEB_ETHTOOL, fmt, ##args)
+#define lbs_deb_host(fmt, args...) LBS_DEB_LL(LBS_DEB_HOST, fmt, ##args)
+#define lbs_deb_cmd(fmt, args...) LBS_DEB_LL(LBS_DEB_CMD, fmt, ##args)
+#define lbs_deb_rx(fmt, args...) LBS_DEB_LL(LBS_DEB_RX, fmt, ##args)
+#define lbs_deb_tx(fmt, args...) LBS_DEB_LL(LBS_DEB_TX, fmt, ##args)
+#define lbs_deb_fw(fmt, args...) LBS_DEB_LL(LBS_DEB_FW, fmt, ##args)
+#define lbs_deb_usb(fmt, args...) LBS_DEB_LL(LBS_DEB_USB, fmt, ##args)
+#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, "%s:" fmt, (dev)->bus_id, ##args)
+#define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, fmt, ##args)
+#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, fmt, ##args)
#define lbs_pr_info(format, args...) \
printk(KERN_INFO DRV_NAME": " format, ## args)
@@ -24,37 +89,25 @@ extern unsigned int libertas_debug;
printk(KERN_ALERT DRV_NAME": " format, ## args)
#ifdef DEBUG
-#define lbs_pr_debug(level, format, args...) \
- do { if (libertas_debug >= level) \
- printk(KERN_INFO DRV_NAME": " format, ##args); } while (0)
-#define lbs_dev_dbg(level, device, format, args...) \
- lbs_pr_debug(level, "%s: " format, \
- (device)->bus_id , ## args)
-
static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
{
int i = 0;
- if (!libertas_debug)
+ if (!(libertas_debug & LBS_DEB_HEX))
return;
printk(KERN_DEBUG "%s: ", prompt);
for (i = 1; i <= len; i++) {
- printk(KERN_DEBUG "%02x ", (u8) * buf);
+ printk("%02x ", (u8) * buf);
buf++;
}
printk("\n");
}
#else
-#define lbs_pr_debug(level, format, args...) do {} while (0)
-#define lbs_dev_dbg(level, device, format, args...) do {} while (0)
#define lbs_dbg_hex(x,y,z) do {} while (0)
#endif
-#define ENTER() lbs_pr_debug(1, "Enter: %s, %s:%i\n", \
- __FUNCTION__, __FILE__, __LINE__)
-#define LEAVE() lbs_pr_debug(1, "Leave: %s, %s:%i\n", \
- __FUNCTION__, __FILE__, __LINE__)
+
/** Buffer Constants */
@@ -74,7 +127,6 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
#define MRVDRV_NUM_OF_CMD_BUFFER 10
#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024)
#define MRVDRV_MAX_CHANNEL_SIZE 14
-#define MRVDRV_MAX_BSSID_LIST 64
#define MRVDRV_ASSOCIATION_TIME_OUT 255
#define MRVDRV_SNAP_HEADER_LEN 8
@@ -104,6 +156,13 @@ static inline void lbs_dbg_hex(char *prompt, u8 * buf, int len)
#define MRVDRV_MAX_BEACON_INTERVAL 1000
#define MRVDRV_BEACON_INTERVAL 100
+/** INT status Bit Definition*/
+#define his_cmddnldrdy 0x01
+#define his_cardevent 0x02
+#define his_cmdupldrdy 0x04
+
+#define SBI_EVENT_CAUSE_SHIFT 3
+
/** TxPD status */
/* Station firmware use TxPD status field to report final Tx transmit
@@ -205,8 +264,6 @@ typedef struct _wlan_adapter wlan_adapter;
extern const char libertas_driver_version[];
extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE];
-extern u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES];
-
extern u8 libertas_supported_rates[G_SUPPORTED_RATES];
extern u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES];
@@ -316,6 +373,8 @@ enum SNMP_MIB_VALUE_e {
/* Default values for fwt commands. */
#define FWT_DEFAULT_METRIC 0
#define FWT_DEFAULT_DIR 1
+/* Default Rate, 11Mbps */
+#define FWT_DEFAULT_RATE 3
#define FWT_DEFAULT_SSN 0xffffffff
#define FWT_DEFAULT_DSN 0
#define FWT_DEFAULT_HOPCOUNT 0
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index e8b9020f9bd..785192b884b 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -63,11 +63,11 @@ struct wlan_802_11_security {
/** Current Basic Service Set State Structure */
struct current_bss_params {
- struct bss_descriptor bssdescriptor;
/** bssid */
u8 bssid[ETH_ALEN];
/** ssid */
- struct WLAN_802_11_SSID ssid;
+ u8 ssid[IW_ESSID_MAX_SIZE + 1];
+ u8 ssid_len;
/** band */
u8 band;
@@ -89,31 +89,6 @@ struct sleep_params {
u16 sp_reserved;
};
-/** Data structure for the Marvell WLAN device */
-typedef struct _wlan_dev {
- /** device name */
- char name[DEV_NAME_LEN];
- /** card pointer */
- void *card;
- /** IO port */
- u32 ioport;
- /** Upload received */
- u32 upld_rcv;
- /** Upload type */
- u32 upld_typ;
- /** Upload length */
- u32 upld_len;
- /** netdev pointer */
- struct net_device *netdev;
- /* Upload buffer */
- u8 upld_buf[WLAN_UPLD_SIZE];
- /* Download sent:
- bit0 1/0=data_sent/data_tx_done,
- bit1 1/0=cmd_sent/cmd_tx_done,
- all other bits reserved 0 */
- u8 dnld_sent;
-} wlan_dev_t, *pwlan_dev_t;
-
/* Mesh statistics */
struct wlan_mesh_stats {
u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */
@@ -123,6 +98,7 @@ struct wlan_mesh_stats {
u32 fwd_drop_noroute; /* Fwd: No route to Destination */
u32 fwd_drop_nobuf; /* Fwd: Run out of internal buffers */
u32 drop_blind; /* Rx: Dropped by blinding table */
+ u32 tx_failed_cnt; /* Tx: Failed transmissions */
};
/** Private structure for the MV device */
@@ -131,8 +107,11 @@ struct _wlan_private {
int mesh_open;
int infra_open;
+ char name[DEV_NAME_LEN];
+
+ void *card;
wlan_adapter *adapter;
- wlan_dev_t wlan_dev;
+ struct net_device *dev;
struct net_device_stats stats;
struct net_device *mesh_dev ; /* Virtual device */
@@ -153,6 +132,16 @@ struct _wlan_private {
u32 bbp_offset;
u32 rf_offset;
+ /** Upload length */
+ u32 upld_len;
+ /* Upload buffer */
+ u8 upld_buf[WLAN_UPLD_SIZE];
+ /* Download sent:
+ bit0 1/0=data_sent/data_tx_done,
+ bit1 1/0=cmd_sent/cmd_tx_done,
+ all other bits reserved 0 */
+ u8 dnld_sent;
+
const struct firmware *firmware;
struct device *hotplug_device;
@@ -161,6 +150,15 @@ struct _wlan_private {
struct delayed_work assoc_work;
struct workqueue_struct *assoc_thread;
+ struct work_struct sync_channel;
+
+ /** Hardware access */
+ int (*hw_register_dev) (wlan_private * priv);
+ int (*hw_unregister_dev) (wlan_private *);
+ int (*hw_prog_firmware) (wlan_private *);
+ int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb);
+ int (*hw_get_int_status) (wlan_private * priv, u8 *);
+ int (*hw_read_event_cause) (wlan_private *);
};
/** Association request
@@ -171,18 +169,21 @@ struct _wlan_private {
struct assoc_request {
#define ASSOC_FLAG_SSID 1
#define ASSOC_FLAG_CHANNEL 2
-#define ASSOC_FLAG_MODE 3
-#define ASSOC_FLAG_BSSID 4
-#define ASSOC_FLAG_WEP_KEYS 5
-#define ASSOC_FLAG_WEP_TX_KEYIDX 6
-#define ASSOC_FLAG_WPA_MCAST_KEY 7
-#define ASSOC_FLAG_WPA_UCAST_KEY 8
-#define ASSOC_FLAG_SECINFO 9
-#define ASSOC_FLAG_WPA_IE 10
+#define ASSOC_FLAG_BAND 3
+#define ASSOC_FLAG_MODE 4
+#define ASSOC_FLAG_BSSID 5
+#define ASSOC_FLAG_WEP_KEYS 6
+#define ASSOC_FLAG_WEP_TX_KEYIDX 7
+#define ASSOC_FLAG_WPA_MCAST_KEY 8
+#define ASSOC_FLAG_WPA_UCAST_KEY 9
+#define ASSOC_FLAG_SECINFO 10
+#define ASSOC_FLAG_WPA_IE 11
unsigned long flags;
- struct WLAN_802_11_SSID ssid;
+ u8 ssid[IW_ESSID_MAX_SIZE + 1];
+ u8 ssid_len;
u8 channel;
+ u8 band;
u8 mode;
u8 bssid[ETH_ALEN];
@@ -199,12 +200,15 @@ struct assoc_request {
/** WPA Information Elements*/
u8 wpa_ie[MAX_WPA_IE_LEN];
u8 wpa_ie_len;
+
+ /* BSS to associate with for infrastructure of Ad-Hoc join */
+ struct bss_descriptor bss;
};
/** Wlan adapter data structure*/
struct _wlan_adapter {
/** STATUS variables */
- u32 fwreleasenumber;
+ u8 fwreleasenumber[4];
u32 fwcapinfo;
/* protected with big lock */
@@ -255,13 +259,14 @@ struct _wlan_adapter {
/* IW_MODE_* */
u8 mode;
- struct bss_descriptor *pattemptedbssdesc;
-
- struct WLAN_802_11_SSID previousssid;
- u8 previousbssid[ETH_ALEN];
+ u8 prev_ssid[IW_ESSID_MAX_SIZE + 1];
+ u8 prev_ssid_len;
+ u8 prev_bssid[ETH_ALEN];
- struct bss_descriptor *scantable;
- u32 numinscantable;
+ /* Scan results list */
+ struct list_head network_list;
+ struct list_head network_free_list;
+ struct bss_descriptor *networks;
u8 scantype;
u32 scanmode;
@@ -288,7 +293,6 @@ struct _wlan_adapter {
u32 txantenna;
u32 rxantenna;
- u8 adhocchannel;
u32 fragthsd;
u32 rtsthsd;
@@ -324,7 +328,8 @@ struct _wlan_adapter {
u16 locallisteninterval;
u16 nullpktinterval;
- struct assoc_request * assoc_req;
+ struct assoc_request * pending_assoc_req;
+ struct assoc_request * in_progress_assoc_req;
/** Encryption parameter */
struct wlan_802_11_security secinfo;
@@ -396,6 +401,8 @@ struct _wlan_adapter {
u32 radiomode;
u32 debugmode;
u8 fw_ready;
+
+ u8 last_scanned_channel;
};
#endif /* _WLAN_DEV_H_ */
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 0064de54296..96f1974685d 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -1,10 +1,8 @@
-
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include "host.h"
-#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
@@ -17,7 +15,8 @@ static const char * mesh_stat_strings[]= {
"drop_no_buffers",
"fwded_unicast_cnt",
"fwded_bcast_cnt",
- "drop_blind_table"
+ "drop_blind_table",
+ "tx_failed_cnt"
};
static void libertas_ethtool_get_drvinfo(struct net_device *dev,
@@ -69,7 +68,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
/* +14 is for action, offset, and NOB in
* response */
- lbs_pr_debug(1, "action:%d offset: %x NOB: %02x\n",
+ lbs_deb_ethtool("action:%d offset: %x NOB: %02x\n",
regctrl.action, regctrl.offset, regctrl.NOB);
ret = libertas_prepare_and_send_command(priv,
@@ -81,8 +80,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
if (ret) {
if (adapter->prdeeprom)
kfree(adapter->prdeeprom);
- LEAVE();
- return ret;
+ goto done;
}
mdelay(10);
@@ -101,7 +99,11 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
kfree(adapter->prdeeprom);
// mutex_unlock(&priv->mutex);
- return 0;
+ ret = 0;
+
+done:
+ lbs_deb_enter_args(LBS_DEB_ETHTOOL, "ret %d", ret);
+ return ret;
}
static void libertas_ethtool_get_stats(struct net_device * dev,
@@ -109,7 +111,7 @@ static void libertas_ethtool_get_stats(struct net_device * dev,
{
wlan_private *priv = dev->priv;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
stats->cmd = ETHTOOL_GSTATS;
BUG_ON(stats->n_stats != MESH_STATS_NUM);
@@ -121,8 +123,9 @@ static void libertas_ethtool_get_stats(struct net_device * dev,
data[4] = priv->mstats.fwd_unicast_cnt;
data[5] = priv->mstats.fwd_bcast_cnt;
data[6] = priv->mstats.drop_blind;
+ data[7] = priv->mstats.tx_failed_cnt;
- LEAVE();
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
}
static int libertas_ethtool_get_stats_count(struct net_device * dev)
@@ -131,27 +134,32 @@ static int libertas_ethtool_get_stats_count(struct net_device * dev)
wlan_private *priv = dev->priv;
struct cmd_ds_mesh_access mesh_access;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
+
/* Get Mesh Statistics */
ret = libertas_prepare_and_send_command(priv,
cmd_mesh_access, cmd_act_mesh_get_stats,
cmd_option_waitforrsp, 0, &mesh_access);
if (ret) {
- LEAVE();
- return 0;
+ ret = 0;
+ goto done;
}
- priv->mstats.fwd_drop_rbt = mesh_access.data[0];
- priv->mstats.fwd_drop_ttl = mesh_access.data[1];
- priv->mstats.fwd_drop_noroute = mesh_access.data[2];
- priv->mstats.fwd_drop_nobuf = mesh_access.data[3];
- priv->mstats.fwd_unicast_cnt = mesh_access.data[4];
- priv->mstats.fwd_bcast_cnt = mesh_access.data[5];
- priv->mstats.drop_blind = mesh_access.data[6];
+ priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
+ priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
+ priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
+ priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
+ priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
+ priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
+ priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
+ priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
- LEAVE();
- return MESH_STATS_NUM;
+ ret = MESH_STATS_NUM;
+
+done:
+ lbs_deb_enter_args(LBS_DEB_ETHTOOL, "ret %d", ret);
+ return ret;
}
static void libertas_ethtool_get_strings (struct net_device * dev,
@@ -160,7 +168,8 @@ static void libertas_ethtool_get_strings (struct net_device * dev,
{
int i;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
+
switch (stringset) {
case ETH_SS_STATS:
for (i=0; i < MESH_STATS_NUM; i++) {
@@ -170,7 +179,7 @@ static void libertas_ethtool_get_strings (struct net_device * dev,
}
break;
}
- LEAVE();
+ lbs_deb_enter(LBS_DEB_ETHTOOL);
}
struct ethtool_ops libertas_ethtool_ops = {
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index 441123c85e6..2dc84ff7a54 100644
--- a/drivers/net/wireless/libertas/fw.c
+++ b/drivers/net/wireless/libertas/fw.c
@@ -1,28 +1,15 @@
/**
* This file contains the initialization for FW and HW
*/
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-
-#include <linux/vmalloc.h>
#include <linux/firmware.h>
-#include <linux/version.h>
#include "host.h"
-#include "sbi.h"
#include "defs.h"
#include "decl.h"
#include "dev.h"
-#include "fw.h"
#include "wext.h"
#include "if_usb.h"
-char *libertas_fw_name = NULL;
-module_param_named(fw_name, libertas_fw_name, charp, 0644);
-
-unsigned int libertas_debug = 0;
-module_param(libertas_debug, int, 0);
-
/**
* @brief This function checks the validity of Boot2/FW image.
*
@@ -32,7 +19,7 @@ module_param(libertas_debug, int, 0);
*/
static int check_fwfile_format(u8 *data, u32 totlen)
{
- u8 bincmd, exit;
+ u32 bincmd, exit;
u32 blksize, offset, len;
int ret;
@@ -40,8 +27,10 @@ static int check_fwfile_format(u8 *data, u32 totlen)
exit = len = 0;
do {
- bincmd = *data;
- blksize = *(u32*)(data + offsetof(struct fwheader, datalength));
+ struct fwheader *fwh = (void *)data;
+
+ bincmd = le32_to_cpu(fwh->dnldcmd);
+ blksize = le32_to_cpu(fwh->datalength);
switch (bincmd) {
case FW_HAS_DATA_TO_RECV:
offset = sizeof(struct fwheader) + blksize;
@@ -61,9 +50,9 @@ static int check_fwfile_format(u8 *data, u32 totlen)
} while (!exit);
if (ret)
- lbs_pr_err("bin file format check FAIL...\n");
+ lbs_pr_err("firmware file format check FAIL\n");
else
- lbs_pr_debug(1, "bin file format check PASS...\n");
+ lbs_deb_fw("firmware file format check PASS\n");
return ret;
}
@@ -76,32 +65,31 @@ static int check_fwfile_format(u8 *data, u32 totlen)
* @param priv A pointer to wlan_private structure
* @return 0 or -1
*/
-static int wlan_setup_station_hw(wlan_private * priv)
+static int wlan_setup_station_hw(wlan_private * priv, char *fw_name)
{
int ret = -1;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_FW);
- if ((ret = request_firmware(&priv->firmware, libertas_fw_name,
+ if ((ret = request_firmware(&priv->firmware, fw_name,
priv->hotplug_device)) < 0) {
- lbs_pr_err("request_firmware() failed, error code = %#x\n",
- ret);
- lbs_pr_err("%s not found in /lib/firmware\n", libertas_fw_name);
+ lbs_pr_err("request_firmware() failed with %#x\n", ret);
+ lbs_pr_err("firmware %s not found\n", fw_name);
goto done;
}
- if(check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
+ if (check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
release_firmware(priv->firmware);
goto done;
}
- ret = libertas_sbi_prog_firmware(priv);
+ ret = priv->hw_prog_firmware(priv);
release_firmware(priv->firmware);
if (ret) {
- lbs_pr_debug(1, "Bootloader in invalid state!\n");
+ lbs_deb_fw("bootloader in invalid state\n");
ret = -1;
goto done;
}
@@ -133,28 +121,24 @@ static int wlan_setup_station_hw(wlan_private * priv)
ret = 0;
done:
- LEAVE();
-
- return (ret);
+ lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
+ return ret;
}
static int wlan_allocate_adapter(wlan_private * priv)
{
- u32 ulbufsize;
+ size_t bufsize;
wlan_adapter *adapter = priv->adapter;
- struct bss_descriptor *ptempscantable;
-
/* Allocate buffer to store the BSSID list */
- ulbufsize = sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST;
- if (!(ptempscantable = kmalloc(ulbufsize, GFP_KERNEL))) {
+ bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
+ adapter->networks = kzalloc(bufsize, GFP_KERNEL);
+ if (!adapter->networks) {
+ lbs_pr_err("Out of memory allocating beacons\n");
libertas_free_adapter(priv);
- return -1;
+ return -ENOMEM;
}
- adapter->scantable = ptempscantable;
- memset(adapter->scantable, 0, ulbufsize);
-
/* Allocate the command buffers */
libertas_allocate_cmd_buffer(priv);
@@ -202,15 +186,23 @@ static void wlan_init_adapter(wlan_private * priv)
adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
adapter->mode = IW_MODE_INFRA;
- adapter->assoc_req = NULL;
+ adapter->pending_assoc_req = NULL;
+ adapter->in_progress_assoc_req = NULL;
+
+ /* Initialize scan result lists */
+ INIT_LIST_HEAD(&adapter->network_free_list);
+ INIT_LIST_HEAD(&adapter->network_list);
+ for (i = 0; i < MAX_NETWORK_COUNT; i++) {
+ list_add_tail(&adapter->networks[i].list,
+ &adapter->network_free_list);
+ }
- adapter->numinscantable = 0;
- adapter->pattemptedbssdesc = NULL;
mutex_init(&adapter->lock);
adapter->prescan = 1;
memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
+ adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
/* PnP and power profile */
adapter->surpriseremoved = 0;
@@ -230,8 +222,6 @@ static void wlan_init_adapter(wlan_private * priv)
memset(&adapter->capinfo, 0, sizeof(adapter->capinfo));
adapter->capinfo.shortpreamble = SHORT_PREAMBLE_ALLOWED;
- adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
-
adapter->psmode = wlan802_11powermodecam;
adapter->multipledtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
@@ -259,12 +249,12 @@ static void wlan_init_adapter(wlan_private * priv)
static void command_timer_fn(unsigned long data);
-int libertas_init_fw(wlan_private * priv)
+int libertas_init_fw(wlan_private * priv, char *fw_name)
{
int ret = -1;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_FW);
/* Allocate adapter structure */
if ((ret = wlan_allocate_adapter(priv)) != 0)
@@ -278,7 +268,7 @@ int libertas_init_fw(wlan_private * priv)
(unsigned long)priv);
/* download fimrware etc. */
- if ((ret = wlan_setup_station_hw(priv)) != 0) {
+ if ((ret = wlan_setup_station_hw(priv, fw_name)) != 0) {
del_timer_sync(&adapter->command_timer);
goto done;
}
@@ -288,7 +278,7 @@ int libertas_init_fw(wlan_private * priv)
ret = 0;
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
return ret;
}
@@ -297,25 +287,22 @@ void libertas_free_adapter(wlan_private * priv)
wlan_adapter *adapter = priv->adapter;
if (!adapter) {
- lbs_pr_debug(1, "Why double free adapter?:)\n");
+ lbs_deb_fw("why double free adapter?\n");
return;
}
- lbs_pr_debug(1, "Free command buffer\n");
+ lbs_deb_fw("free command buffer\n");
libertas_free_cmd_buffer(priv);
- lbs_pr_debug(1, "Free commandTimer\n");
+ lbs_deb_fw("free command_timer\n");
del_timer(&adapter->command_timer);
- lbs_pr_debug(1, "Free scantable\n");
- if (adapter->scantable) {
- kfree(adapter->scantable);
- adapter->scantable = NULL;
- }
-
- lbs_pr_debug(1, "Free adapter\n");
+ lbs_deb_fw("free scan results table\n");
+ kfree(adapter->networks);
+ adapter->networks = NULL;
/* Free the adapter object itself */
+ lbs_deb_fw("free adapter\n");
kfree(adapter);
priv->adapter = NULL;
}
@@ -333,23 +320,27 @@ static void command_timer_fn(unsigned long data)
unsigned long flags;
ptempnode = adapter->cur_cmd;
+ if (ptempnode == NULL) {
+ lbs_deb_fw("ptempnode empty\n");
+ return;
+ }
+
cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
+ if (!cmd) {
+ lbs_deb_fw("cmd is NULL\n");
+ return;
+ }
- lbs_pr_info("command_timer_fn fired (%x)\n", cmd->command);
+ lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command);
if (!adapter->fw_ready)
return;
- if (ptempnode == NULL) {
- lbs_pr_debug(1, "PTempnode Empty\n");
- return;
- }
-
spin_lock_irqsave(&adapter->driver_lock, flags);
adapter->cur_cmd = NULL;
spin_unlock_irqrestore(&adapter->driver_lock, flags);
- lbs_pr_debug(1, "Re-sending same command as it timeout...!\n");
+ lbs_deb_fw("re-sending same command because of timeout\n");
libertas_queue_cmd(adapter, ptempnode, 0);
wake_up_interruptible(&priv->mainthread.waitq);
diff --git a/drivers/net/wireless/libertas/fw.h b/drivers/net/wireless/libertas/fw.h
deleted file mode 100644
index 1f9ae267a9e..00000000000
--- a/drivers/net/wireless/libertas/fw.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * This header file contains FW interface related definitions.
- */
-#ifndef _WLAN_FW_H_
-#define _WLAN_FW_H_
-
-#ifndef DEV_NAME_LEN
-#define DEV_NAME_LEN 32
-#endif
-
-int libertas_init_fw(wlan_private * priv);
-
-#endif /* _WLAN_FW_H_ */
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index c0faaecaf5b..7509cc10af3 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -99,11 +99,11 @@
#define cmd_bt_access 0x0087
#define cmd_ret_bt_access 0x8087
-#define cmd_fwt_access 0x0088
-#define cmd_ret_fwt_access 0x8088
+#define cmd_fwt_access 0x0095
+#define cmd_ret_fwt_access 0x8095
-#define cmd_mesh_access 0x0090
-#define cmd_ret_mesh_access 0x8090
+#define cmd_mesh_access 0x009b
+#define cmd_ret_mesh_access 0x809b
/* For the IEEE Power Save */
#define cmd_subcmd_enter_ps 0x0030
@@ -287,7 +287,9 @@ enum cmd_bt_access_opts {
cmd_act_bt_access_add = 5,
cmd_act_bt_access_del,
cmd_act_bt_access_list,
- cmd_act_bt_access_reset
+ cmd_act_bt_access_reset,
+ cmd_act_bt_access_set_invert,
+ cmd_act_bt_access_get_invert
};
/* Define action or option for cmd_fwt_access */
@@ -308,8 +310,8 @@ enum cmd_mesh_access_opts {
cmd_act_mesh_get_ttl = 1,
cmd_act_mesh_set_ttl,
cmd_act_mesh_get_stats,
- cmd_act_mesh_get_mpp,
- cmd_act_mesh_set_mpp,
+ cmd_act_mesh_get_anycast,
+ cmd_act_mesh_set_anycast,
};
/** Card Event definition */
@@ -334,5 +336,6 @@ enum cmd_mesh_access_opts {
#define MACREG_INT_CODE_MAX_FAIL 0x0000001b
#define MACREG_INT_CODE_RSSI_HIGH 0x0000001c
#define MACREG_INT_CODE_SNR_HIGH 0x0000001d
+#define MACREG_INT_CODE_MESH_AUTO_STARTED 0x00000023
#endif /* _HOST_H_ */
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index f239e5d2435..3acf9398812 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -14,12 +14,12 @@
/* TxPD descriptor */
struct txpd {
/* Current Tx packet status */
- u32 tx_status;
+ __le32 tx_status;
/* Tx control */
- u32 tx_control;
- u32 tx_packet_location;
+ __le32 tx_control;
+ __le32 tx_packet_location;
/* Tx packet length */
- u16 tx_packet_length;
+ __le16 tx_packet_length;
/* First 2 byte of destination MAC address */
u8 tx_dest_addr_high[2];
/* Last 4 byte of destination MAC address */
@@ -37,7 +37,7 @@ struct txpd {
/* RxPD Descriptor */
struct rxpd {
/* Current Rx packet status */
- u16 status;
+ __le16 status;
/* SNR */
u8 snr;
@@ -46,7 +46,7 @@ struct rxpd {
u8 rx_control;
/* Pkt length */
- u16 pkt_len;
+ __le16 pkt_len;
/* Noise Floor */
u8 nf;
@@ -55,10 +55,10 @@ struct rxpd {
u8 rx_rate;
/* Pkt addr */
- u32 pkt_ptr;
+ __le32 pkt_ptr;
/* Next Rx RxPD addr */
- u32 next_rxpd_ptr;
+ __le32 next_rxpd_ptr;
/* Pkt Priority */
u8 priority;
@@ -89,30 +89,17 @@ struct cmd_ctrl_node {
* is determined from the keylength field.
*/
struct WLAN_802_11_KEY {
- u32 len;
- u32 flags; /* KEY_INFO_* from wlan_defs.h */
+ __le32 len;
+ __le32 flags; /* KEY_INFO_* from wlan_defs.h */
u8 key[MRVL_MAX_KEY_WPA_KEY_LENGTH];
- u16 type; /* KEY_TYPE_* from wlan_defs.h */
+ __le16 type; /* KEY_TYPE_* from wlan_defs.h */
};
struct IE_WPA {
u8 elementid;
u8 len;
u8 oui[4];
- u16 version;
-};
-
-struct WLAN_802_11_SSID {
- /* SSID length */
- u32 ssidlength;
-
- /* SSID information field */
- u8 ssid[IW_ESSID_MAX_SIZE];
-};
-
-struct WPA_SUPPLICANT {
- u8 wpa_ie[256];
- u8 wpa_ie_len;
+ __le16 version;
};
/* wlan_offset_value */
@@ -122,9 +109,9 @@ struct wlan_offset_value {
};
struct WLAN_802_11_FIXED_IEs {
- u8 timestamp[8];
- u16 beaconinterval;
- u16 capabilities;
+ __le64 timestamp;
+ __le16 beaconinterval;
+ u16 capabilities; /* Actually struct ieeetypes_capinfo */
};
struct WLAN_802_11_VARIABLE_IEs {
@@ -136,10 +123,10 @@ struct WLAN_802_11_VARIABLE_IEs {
/* Define general data structure */
/* cmd_DS_GEN */
struct cmd_ds_gen {
- u16 command;
- u16 size;
- u16 seqnum;
- u16 result;
+ __le16 command;
+ __le16 size;
+ __le16 seqnum;
+ __le16 result;
};
#define S_DS_GEN sizeof(struct cmd_ds_gen)
@@ -149,44 +136,44 @@ struct cmd_ds_gen {
*/
struct cmd_ds_get_hw_spec {
/* HW Interface version number */
- u16 hwifversion;
+ __le16 hwifversion;
/* HW version number */
- u16 version;
+ __le16 version;
/* Max number of TxPD FW can handle */
- u16 nr_txpd;
+ __le16 nr_txpd;
/* Max no of Multicast address */
- u16 nr_mcast_adr;
+ __le16 nr_mcast_adr;
/* MAC address */
u8 permanentaddr[6];
/* region Code */
- u16 regioncode;
+ __le16 regioncode;
/* Number of antenna used */
- u16 nr_antenna;
+ __le16 nr_antenna;
- /* FW release number, example 0x1234=1.2.3.4 */
- u32 fwreleasenumber;
+ /* FW release number, example 1,2,3,4 = 3.2.1p4 */
+ u8 fwreleasenumber[4];
/* Base Address of TxPD queue */
- u32 wcb_base;
+ __le32 wcb_base;
/* Read Pointer of RxPd queue */
- u32 rxpd_rdptr;
+ __le32 rxpd_rdptr;
/* Write Pointer of RxPd queue */
- u32 rxpd_wrptr;
+ __le32 rxpd_wrptr;
/*FW/HW capability */
- u32 fwcapinfo;
+ __le32 fwcapinfo;
} __attribute__ ((packed));
struct cmd_ds_802_11_reset {
- u16 action;
+ __le16 action;
};
struct cmd_ds_802_11_subscribe_event {
- u16 action;
- u16 events;
+ __le16 action;
+ __le16 events;
};
/*
@@ -205,35 +192,35 @@ struct cmd_ds_802_11_scan {
};
struct cmd_ds_802_11_scan_rsp {
- u16 bssdescriptsize;
+ __le16 bssdescriptsize;
u8 nr_sets;
u8 bssdesc_and_tlvbuffer[1];
};
struct cmd_ds_802_11_get_log {
- u32 mcasttxframe;
- u32 failed;
- u32 retry;
- u32 multiretry;
- u32 framedup;
- u32 rtssuccess;
- u32 rtsfailure;
- u32 ackfailure;
- u32 rxfrag;
- u32 mcastrxframe;
- u32 fcserror;
- u32 txframe;
- u32 wepundecryptable;
+ __le32 mcasttxframe;
+ __le32 failed;
+ __le32 retry;
+ __le32 multiretry;
+ __le32 framedup;
+ __le32 rtssuccess;
+ __le32 rtsfailure;
+ __le32 ackfailure;
+ __le32 rxfrag;
+ __le32 mcastrxframe;
+ __le32 fcserror;
+ __le32 txframe;
+ __le32 wepundecryptable;
};
struct cmd_ds_mac_control {
- u16 action;
- u16 reserved;
+ __le16 action;
+ __le16 reserved;
};
struct cmd_ds_mac_multicast_adr {
- u16 action;
- u16 nr_of_adrs;
+ __le16 action;
+ __le16 nr_of_adrs;
u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
};
@@ -245,14 +232,14 @@ struct cmd_ds_802_11_authenticate {
struct cmd_ds_802_11_deauthenticate {
u8 macaddr[6];
- u16 reasoncode;
+ __le16 reasoncode;
};
struct cmd_ds_802_11_associate {
u8 peerstaaddr[6];
struct ieeetypes_capinfo capinfo;
- u16 listeninterval;
- u16 bcnperiod;
+ __le16 listeninterval;
+ __le16 bcnperiod;
u8 dtimperiod;
#if 0
@@ -265,7 +252,7 @@ struct cmd_ds_802_11_associate {
struct cmd_ds_802_11_disassociate {
u8 destmacaddr[6];
- u16 reasoncode;
+ __le16 reasoncode;
};
struct cmd_ds_802_11_associate_rsp {
@@ -279,10 +266,10 @@ struct cmd_ds_802_11_ad_hoc_result {
struct cmd_ds_802_11_set_wep {
/* ACT_ADD, ACT_REMOVE or ACT_ENABLE */
- u16 action;
+ __le16 action;
/* key Index selected for Tx */
- u16 keyindex;
+ __le16 keyindex;
/* 40, 128bit or TXWEP */
u8 keytype[4];
@@ -290,96 +277,96 @@ struct cmd_ds_802_11_set_wep {
};
struct cmd_ds_802_3_get_stat {
- u32 xmitok;
- u32 rcvok;
- u32 xmiterror;
- u32 rcverror;
- u32 rcvnobuffer;
- u32 rcvcrcerror;
+ __le32 xmitok;
+ __le32 rcvok;
+ __le32 xmiterror;
+ __le32 rcverror;
+ __le32 rcvnobuffer;
+ __le32 rcvcrcerror;
};
struct cmd_ds_802_11_get_stat {
- u32 txfragmentcnt;
- u32 mcasttxframecnt;
- u32 failedcnt;
- u32 retrycnt;
- u32 Multipleretrycnt;
- u32 rtssuccesscnt;
- u32 rtsfailurecnt;
- u32 ackfailurecnt;
- u32 frameduplicatecnt;
- u32 rxfragmentcnt;
- u32 mcastrxframecnt;
- u32 fcserrorcnt;
- u32 bcasttxframecnt;
- u32 bcastrxframecnt;
- u32 txbeacon;
- u32 rxbeacon;
- u32 wepundecryptable;
+ __le32 txfragmentcnt;
+ __le32 mcasttxframecnt;
+ __le32 failedcnt;
+ __le32 retrycnt;
+ __le32 Multipleretrycnt;
+ __le32 rtssuccesscnt;
+ __le32 rtsfailurecnt;
+ __le32 ackfailurecnt;
+ __le32 frameduplicatecnt;
+ __le32 rxfragmentcnt;
+ __le32 mcastrxframecnt;
+ __le32 fcserrorcnt;
+ __le32 bcasttxframecnt;
+ __le32 bcastrxframecnt;
+ __le32 txbeacon;
+ __le32 rxbeacon;
+ __le32 wepundecryptable;
};
struct cmd_ds_802_11_snmp_mib {
- u16 querytype;
- u16 oid;
- u16 bufsize;
+ __le16 querytype;
+ __le16 oid;
+ __le16 bufsize;
u8 value[128];
};
struct cmd_ds_mac_reg_map {
- u16 buffersize;
+ __le16 buffersize;
u8 regmap[128];
- u16 reserved;
+ __le16 reserved;
};
struct cmd_ds_bbp_reg_map {
- u16 buffersize;
+ __le16 buffersize;
u8 regmap[128];
- u16 reserved;
+ __le16 reserved;
};
struct cmd_ds_rf_reg_map {
- u16 buffersize;
+ __le16 buffersize;
u8 regmap[64];
- u16 reserved;
+ __le16 reserved;
};
struct cmd_ds_mac_reg_access {
- u16 action;
- u16 offset;
- u32 value;
+ __le16 action;
+ __le16 offset;
+ __le32 value;
};
struct cmd_ds_bbp_reg_access {
- u16 action;
- u16 offset;
+ __le16 action;
+ __le16 offset;
u8 value;
u8 reserved[3];
};
struct cmd_ds_rf_reg_access {
- u16 action;
- u16 offset;
+ __le16 action;
+ __le16 offset;
u8 value;
u8 reserved[3];
};
struct cmd_ds_802_11_radio_control {
- u16 action;
- u16 control;
+ __le16 action;
+ __le16 control;
};
struct cmd_ds_802_11_sleep_params {
/* ACT_GET/ACT_SET */
- u16 action;
+ __le16 action;
/* Sleep clock error in ppm */
- u16 error;
+ __le16 error;
/* Wakeup offset in usec */
- u16 offset;
+ __le16 offset;
/* Clock stabilization time in usec */
- u16 stabletime;
+ __le16 stabletime;
/* control periodic calibration */
u8 calcontrol;
@@ -388,100 +375,100 @@ struct cmd_ds_802_11_sleep_params {
u8 externalsleepclk;
/* reserved field, should be set to zero */
- u16 reserved;
+ __le16 reserved;
};
struct cmd_ds_802_11_inactivity_timeout {
/* ACT_GET/ACT_SET */
- u16 action;
+ __le16 action;
/* Inactivity timeout in msec */
- u16 timeout;
+ __le16 timeout;
};
struct cmd_ds_802_11_rf_channel {
- u16 action;
- u16 currentchannel;
- u16 rftype;
- u16 reserved;
+ __le16 action;
+ __le16 currentchannel;
+ __le16 rftype;
+ __le16 reserved;
u8 channellist[32];
};
struct cmd_ds_802_11_rssi {
/* weighting factor */
- u16 N;
+ __le16 N;
- u16 reserved_0;
- u16 reserved_1;
- u16 reserved_2;
+ __le16 reserved_0;
+ __le16 reserved_1;
+ __le16 reserved_2;
};
struct cmd_ds_802_11_rssi_rsp {
- u16 SNR;
- u16 noisefloor;
- u16 avgSNR;
- u16 avgnoisefloor;
+ __le16 SNR;
+ __le16 noisefloor;
+ __le16 avgSNR;
+ __le16 avgnoisefloor;
};
struct cmd_ds_802_11_mac_address {
- u16 action;
+ __le16 action;
u8 macadd[ETH_ALEN];
};
struct cmd_ds_802_11_rf_tx_power {
- u16 action;
- u16 currentlevel;
+ __le16 action;
+ __le16 currentlevel;
};
struct cmd_ds_802_11_rf_antenna {
- u16 action;
+ __le16 action;
/* Number of antennas or 0xffff(diversity) */
- u16 antennamode;
+ __le16 antennamode;
};
struct cmd_ds_802_11_ps_mode {
- u16 action;
- u16 nullpktinterval;
- u16 multipledtim;
- u16 reserved;
- u16 locallisteninterval;
+ __le16 action;
+ __le16 nullpktinterval;
+ __le16 multipledtim;
+ __le16 reserved;
+ __le16 locallisteninterval;
};
struct PS_CMD_ConfirmSleep {
- u16 command;
- u16 size;
- u16 seqnum;
- u16 result;
+ __le16 command;
+ __le16 size;
+ __le16 seqnum;
+ __le16 result;
- u16 action;
- u16 reserved1;
- u16 multipledtim;
- u16 reserved;
- u16 locallisteninterval;
+ __le16 action;
+ __le16 reserved1;
+ __le16 multipledtim;
+ __le16 reserved;
+ __le16 locallisteninterval;
};
struct cmd_ds_802_11_data_rate {
- u16 action;
- u16 reserverd;
+ __le16 action;
+ __le16 reserverd;
u8 datarate[G_SUPPORTED_RATES];
};
struct cmd_ds_802_11_rate_adapt_rateset {
- u16 action;
- u16 enablehwauto;
- u16 bitmap;
+ __le16 action;
+ __le16 enablehwauto;
+ __le16 bitmap;
};
struct cmd_ds_802_11_ad_hoc_start {
u8 SSID[IW_ESSID_MAX_SIZE];
u8 bsstype;
- u16 beaconperiod;
+ __le16 beaconperiod;
u8 dtimperiod;
union IEEEtypes_ssparamset ssparamset;
union ieeetypes_phyparamset phyparamset;
- u16 probedelay;
+ __le16 probedelay;
struct ieeetypes_capinfo cap;
u8 datarate[G_SUPPORTED_RATES];
u8 tlv_memory_size_pad[100];
@@ -491,10 +478,10 @@ struct adhoc_bssdesc {
u8 BSSID[6];
u8 SSID[32];
u8 bsstype;
- u16 beaconperiod;
+ __le16 beaconperiod;
u8 dtimperiod;
- u8 timestamp[8];
- u8 localtime[8];
+ __le64 timestamp;
+ __le64 localtime;
union ieeetypes_phyparamset phyparamset;
union IEEEtypes_ssparamset ssparamset;
struct ieeetypes_capinfo cap;
@@ -508,52 +495,52 @@ struct adhoc_bssdesc {
struct cmd_ds_802_11_ad_hoc_join {
struct adhoc_bssdesc bssdescriptor;
- u16 failtimeout;
- u16 probedelay;
+ __le16 failtimeout;
+ __le16 probedelay;
} __attribute__ ((packed));
struct cmd_ds_802_11_enable_rsn {
- u16 action;
- u16 enable;
+ __le16 action;
+ __le16 enable;
};
struct MrvlIEtype_keyParamSet {
/* type ID */
- u16 type;
+ __le16 type;
/* length of Payload */
- u16 length;
+ __le16 length;
/* type of key: WEP=0, TKIP=1, AES=2 */
- u16 keytypeid;
+ __le16 keytypeid;
/* key control Info specific to a keytypeid */
- u16 keyinfo;
+ __le16 keyinfo;
/* length of key */
- u16 keylen;
+ __le16 keylen;
/* key material of size keylen */
u8 key[32];
};
struct cmd_ds_802_11_key_material {
- u16 action;
+ __le16 action;
struct MrvlIEtype_keyParamSet keyParamSet[2];
} __attribute__ ((packed));
struct cmd_ds_802_11_eeprom_access {
- u16 action;
+ __le16 action;
/* multiple 4 */
- u16 offset;
- u16 bytecount;
+ __le16 offset;
+ __le16 bytecount;
u8 value;
} __attribute__ ((packed));
struct cmd_ds_802_11_tpc_cfg {
- u16 action;
+ __le16 action;
u8 enable;
s8 P0;
s8 P1;
@@ -562,13 +549,13 @@ struct cmd_ds_802_11_tpc_cfg {
} __attribute__ ((packed));
struct cmd_ds_802_11_led_ctrl {
- u16 action;
- u16 numled;
+ __le16 action;
+ __le16 numled;
u8 data[256];
} __attribute__ ((packed));
struct cmd_ds_802_11_pwr_cfg {
- u16 action;
+ __le16 action;
u8 enable;
s8 PA_P0;
s8 PA_P1;
@@ -576,21 +563,21 @@ struct cmd_ds_802_11_pwr_cfg {
} __attribute__ ((packed));
struct cmd_ds_802_11_afc {
- u16 afc_auto;
+ __le16 afc_auto;
union {
struct {
- u16 threshold;
- u16 period;
+ __le16 threshold;
+ __le16 period;
};
struct {
- s16 timing_offset;
- s16 carrier_offset;
+ __le16 timing_offset; /* signed */
+ __le16 carrier_offset; /* signed */
};
};
} __attribute__ ((packed));
struct cmd_tx_rate_query {
- u16 txrate;
+ __le16 txrate;
} __attribute__ ((packed));
struct cmd_ds_get_tsf {
@@ -598,41 +585,46 @@ struct cmd_ds_get_tsf {
} __attribute__ ((packed));
struct cmd_ds_bt_access {
- u16 action;
- u32 id;
+ __le16 action;
+ __le32 id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
} __attribute__ ((packed));
struct cmd_ds_fwt_access {
- u16 action;
- u32 id;
+ __le16 action;
+ __le32 id;
+ u8 valid;
u8 da[ETH_ALEN];
u8 dir;
u8 ra[ETH_ALEN];
- u32 ssn;
- u32 dsn;
- u32 metric;
+ __le32 ssn;
+ __le32 dsn;
+ __le32 metric;
+ u8 rate;
u8 hopcount;
u8 ttl;
- u32 expiration;
+ __le32 expiration;
u8 sleepmode;
- u32 snr;
- u32 references;
+ __le32 snr;
+ __le32 references;
+ u8 prec[ETH_ALEN];
} __attribute__ ((packed));
-#define MESH_STATS_NUM 7
struct cmd_ds_mesh_access {
- u16 action;
- u32 data[MESH_STATS_NUM + 1]; /* last position reserved */
+ __le16 action;
+ __le32 data[32]; /* last position reserved */
} __attribute__ ((packed));
+/* Number of stats counters returned by the firmware */
+#define MESH_STATS_NUM 8
+
struct cmd_ds_command {
/* command header */
- u16 command;
- u16 size;
- u16 seqnum;
- u16 result;
+ __le16 command;
+ __le16 size;
+ __le16 seqnum;
+ __le16 result;
/* command Body */
union {
diff --git a/drivers/net/wireless/libertas/if_bootcmd.c b/drivers/net/wireless/libertas/if_bootcmd.c
index 567000c3e87..8bca306ffad 100644
--- a/drivers/net/wireless/libertas/if_bootcmd.c
+++ b/drivers/net/wireless/libertas/if_bootcmd.c
@@ -8,6 +8,8 @@
#include <linux/netdevice.h>
#include <linux/usb.h>
+#define DRV_NAME "usb8xxx"
+
#include "defs.h"
#include "dev.h"
#include "if_usb.h"
@@ -20,12 +22,12 @@
*/
int if_usb_issue_boot_command(wlan_private *priv, int ivalue)
{
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
struct bootcmdstr sbootcmd;
int i;
/* Prepare command */
- sbootcmd.u32magicnumber = BOOT_CMD_MAGIC_NUMBER;
+ sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
sbootcmd.u8cmd_tag = ivalue;
for (i=0; i<11; i++)
sbootcmd.au8dumy[i]=0x00;
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index ae6f72a6cdf..998317571ec 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -2,12 +2,15 @@
* This file contains functions used in USB interface module.
*/
#include <linux/delay.h>
+#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
+#include <linux/list.h>
#include <linux/usb.h>
+#define DRV_NAME "usb8xxx"
+
#include "host.h"
-#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
@@ -16,15 +19,24 @@
#define MESSAGE_HEADER_LEN 4
static const char usbdriver_name[] = "usb8xxx";
+static u8 *default_fw_name = "usb8388.bin";
+
+char *libertas_fw_name = NULL;
+module_param_named(fw_name, libertas_fw_name, charp, 0644);
+
+/*
+ * We need to send a RESET command to all USB devices before
+ * we tear down the USB connection. Otherwise we would not
+ * be able to re-init device the device if the module gets
+ * loaded again. This is a list of all initialized USB devices,
+ * for the reset code see if_usb_reset_device()
+*/
+static LIST_HEAD(usb_devices);
static struct usb_device_id if_usb_table[] = {
/* Enter the device signature inside */
- {
- USB_DEVICE(USB8388_VID_1, USB8388_PID_1),
- },
- {
- USB_DEVICE(USB8388_VID_2, USB8388_PID_2),
- },
+ { USB_DEVICE(0x1286, 0x2001) },
+ { USB_DEVICE(0x05a3, 0x8388) },
{} /* Terminating entry */
};
@@ -32,6 +44,13 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
static void if_usb_receive(struct urb *urb);
static void if_usb_receive_fwload(struct urb *urb);
+static int if_usb_reset_device(wlan_private *priv);
+static int if_usb_register_dev(wlan_private * priv);
+static int if_usb_unregister_dev(wlan_private *);
+static int if_usb_prog_firmware(wlan_private *);
+static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
+static int if_usb_get_int_status(wlan_private * priv, u8 *);
+static int if_usb_read_event_cause(wlan_private *);
/**
* @brief call back function to handle the status of the URB
@@ -42,23 +61,27 @@ static void if_usb_write_bulk_callback(struct urb *urb)
{
wlan_private *priv = (wlan_private *) (urb->context);
wlan_adapter *adapter = priv->adapter;
- struct net_device *dev = priv->wlan_dev.netdev;
+ struct net_device *dev = priv->dev;
/* handle the transmission complete validations */
if (urb->status != 0) {
/* print the failure status number for debug */
- lbs_pr_info("URB in failure status\n");
+ lbs_pr_info("URB in failure status: %d\n", urb->status);
} else {
- lbs_dev_dbg(2, &urb->dev->dev, "URB status is successfull\n");
- lbs_dev_dbg(2, &urb->dev->dev, "Actual length transmitted %d\n",
+ /*
+ lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
+ lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
urb->actual_length);
- priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
+ */
+ priv->dnld_sent = DNLD_RES_RECEIVED;
/* Wake main thread if commands are pending */
if (!adapter->cur_cmd)
wake_up_interruptible(&priv->mainthread.waitq);
- if ((adapter->connect_status == libertas_connected))
+ if ((adapter->connect_status == libertas_connected)) {
netif_wake_queue(dev);
+ netif_wake_queue(priv->mesh_dev);
+ }
}
return;
@@ -71,7 +94,7 @@ static void if_usb_write_bulk_callback(struct urb *urb)
*/
void if_usb_free(struct usb_card_rec *cardp)
{
- ENTER();
+ lbs_deb_enter(LBS_DEB_USB);
/* Unlink tx & rx urb */
usb_kill_urb(cardp->tx_urb);
@@ -86,8 +109,7 @@ void if_usb_free(struct usb_card_rec *cardp)
kfree(cardp->bulk_out_buffer);
cardp->bulk_out_buffer = NULL;
- LEAVE();
- return;
+ lbs_deb_leave(LBS_DEB_USB);
}
/**
@@ -102,27 +124,27 @@ static int if_usb_probe(struct usb_interface *intf,
struct usb_device *udev;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
- wlan_private *pwlanpriv;
- struct usb_card_rec *usb_cardp;
+ wlan_private *priv;
+ struct usb_card_rec *cardp;
int i;
udev = interface_to_usbdev(intf);
- usb_cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
- if (!usb_cardp) {
+ cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
+ if (!cardp) {
lbs_pr_err("Out of memory allocating private data.\n");
goto error;
}
- usb_cardp->udev = udev;
+ cardp->udev = udev;
iface_desc = intf->cur_altsetting;
- lbs_dev_dbg(1, &udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
+ lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
" bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
- udev->descriptor.bcdUSB,
- udev->descriptor.bDeviceClass,
- udev->descriptor.bDeviceSubClass,
- udev->descriptor.bDeviceProtocol);
+ le16_to_cpu(udev->descriptor.bcdUSB),
+ udev->descriptor.bDeviceClass,
+ udev->descriptor.bDeviceSubClass,
+ udev->descriptor.bDeviceProtocol);
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
@@ -130,23 +152,21 @@ static int if_usb_probe(struct usb_interface *intf,
&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK)) {
/* we found a bulk in endpoint */
- lbs_dev_dbg(1, &udev->dev, "Bulk in size is %d\n",
- endpoint->wMaxPacketSize);
- if (!
- (usb_cardp->rx_urb =
- usb_alloc_urb(0, GFP_KERNEL))) {
- lbs_dev_dbg(1, &udev->dev,
+ lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
+ le16_to_cpu(endpoint->wMaxPacketSize));
+ if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
+ lbs_deb_usbd(&udev->dev,
"Rx URB allocation failed\n");
goto dealloc;
}
- usb_cardp->rx_urb_recall = 0;
+ cardp->rx_urb_recall = 0;
- usb_cardp->bulk_in_size =
- endpoint->wMaxPacketSize;
- usb_cardp->bulk_in_endpointAddr =
+ cardp->bulk_in_size =
+ le16_to_cpu(endpoint->wMaxPacketSize);
+ cardp->bulk_in_endpointAddr =
(endpoint->
bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- lbs_dev_dbg(1, &udev->dev, "in_endpoint = %d\n",
+ lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
endpoint->bEndpointAddress);
}
@@ -156,55 +176,63 @@ static int if_usb_probe(struct usb_interface *intf,
&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_BULK)) {
/* We found bulk out endpoint */
- if (!
- (usb_cardp->tx_urb =
- usb_alloc_urb(0, GFP_KERNEL))) {
- lbs_dev_dbg(1,&udev->dev,
+ if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
+ lbs_deb_usbd(&udev->dev,
"Tx URB allocation failed\n");
goto dealloc;
}
- usb_cardp->bulk_out_size =
- endpoint->wMaxPacketSize;
- lbs_dev_dbg(1, &udev->dev,
- "Bulk out size is %d\n",
- endpoint->wMaxPacketSize);
- usb_cardp->bulk_out_endpointAddr =
+ cardp->bulk_out_size =
+ le16_to_cpu(endpoint->wMaxPacketSize);
+ lbs_deb_usbd(&udev->dev,
+ "Bulk out size is %d\n",
+ le16_to_cpu(endpoint->wMaxPacketSize));
+ cardp->bulk_out_endpointAddr =
endpoint->bEndpointAddress;
- lbs_dev_dbg(1, &udev->dev, "out_endpoint = %d\n",
+ lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
endpoint->bEndpointAddress);
- usb_cardp->bulk_out_buffer =
+ cardp->bulk_out_buffer =
kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
GFP_KERNEL);
- if (!usb_cardp->bulk_out_buffer) {
- lbs_dev_dbg(1, &udev->dev,
+ if (!cardp->bulk_out_buffer) {
+ lbs_deb_usbd(&udev->dev,
"Could not allocate buffer\n");
goto dealloc;
}
}
}
-
- /* At this point wlan_add_card() will be called. Don't worry
- * about keeping pwlanpriv around since it will be set on our
- * usb device data in -> add() -> libertas_sbi_register_dev().
- */
- if (!(pwlanpriv = wlan_add_card(usb_cardp)))
+ if (!(priv = libertas_add_card(cardp, &udev->dev)))
goto dealloc;
+ if (libertas_add_mesh(priv, &udev->dev))
+ goto err_add_mesh;
+
+ priv->hw_register_dev = if_usb_register_dev;
+ priv->hw_unregister_dev = if_usb_unregister_dev;
+ priv->hw_prog_firmware = if_usb_prog_firmware;
+ priv->hw_host_to_card = if_usb_host_to_card;
+ priv->hw_get_int_status = if_usb_get_int_status;
+ priv->hw_read_event_cause = if_usb_read_event_cause;
+
+ if (libertas_activate_card(priv, libertas_fw_name))
+ goto err_activate_card;
+
+ list_add_tail(&cardp->list, &usb_devices);
+
usb_get_dev(udev);
- usb_set_intfdata(intf, usb_cardp);
+ usb_set_intfdata(intf, cardp);
- /*
- * return card structure, which can be got back in the
- * diconnect function as the ptr
- * argument.
- */
return 0;
+err_activate_card:
+ libertas_remove_mesh(priv);
+err_add_mesh:
+ free_netdev(priv->dev);
+ kfree(priv->adapter);
dealloc:
- if_usb_free(usb_cardp);
+ if_usb_free(cardp);
error:
return -ENOMEM;
@@ -212,8 +240,7 @@ error:
/**
* @brief free resource and cleanup
- * @param udev pointer to usb_device
- * @param ptr pointer to usb_cardp
+ * @param intf USB interface structure
* @return N/A
*/
static void if_usb_disconnect(struct usb_interface *intf)
@@ -229,9 +256,12 @@ static void if_usb_disconnect(struct usb_interface *intf)
*/
adapter->surpriseremoved = 1;
+ list_del(&cardp->list);
+
/* card is removed and we can call wlan_remove_card */
- lbs_dev_dbg(1, &cardp->udev->dev, "call remove card\n");
- wlan_remove_card(cardp);
+ lbs_deb_usbd(&cardp->udev->dev, "call remove card\n");
+ libertas_remove_mesh(priv);
+ libertas_remove_card(priv);
/* Unlink and free urb */
if_usb_free(cardp);
@@ -249,7 +279,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
*/
static int if_prog_firmware(wlan_private * priv)
{
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
struct FWData *fwdata;
struct fwheader *fwheader;
u8 *firmware = priv->firmware->data;
@@ -266,8 +296,10 @@ static int if_prog_firmware(wlan_private * priv)
cardp->fwseqnum = cardp->lastseqnum - 1;
}
- lbs_dev_dbg(2, &cardp->udev->dev, "totalbytes = %d\n",
+ /*
+ lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
cardp->totalbytes);
+ */
memcpy(fwheader, &firmware[cardp->totalbytes],
sizeof(struct fwheader));
@@ -275,40 +307,48 @@ static int if_prog_firmware(wlan_private * priv)
cardp->fwlastblksent = cardp->totalbytes;
cardp->totalbytes += sizeof(struct fwheader);
- lbs_dev_dbg(2, &cardp->udev->dev,"Copy Data\n");
+ /* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
memcpy(fwdata->data, &firmware[cardp->totalbytes],
- fwdata->fwheader.datalength);
+ le32_to_cpu(fwdata->fwheader.datalength));
- lbs_dev_dbg(2, &cardp->udev->dev,
- "Data length = %d\n", fwdata->fwheader.datalength);
+ /*
+ lbs_deb_usbd(&cardp->udev->dev,
+ "Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength));
+ */
cardp->fwseqnum = cardp->fwseqnum + 1;
- fwdata->seqnum = cardp->fwseqnum;
- cardp->lastseqnum = fwdata->seqnum;
- cardp->totalbytes += fwdata->fwheader.datalength;
+ fwdata->seqnum = cpu_to_le32(cardp->fwseqnum);
+ cardp->lastseqnum = cardp->fwseqnum;
+ cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength);
- if (fwheader->dnldcmd == FW_HAS_DATA_TO_RECV) {
- lbs_dev_dbg(2, &cardp->udev->dev, "There is data to follow\n");
- lbs_dev_dbg(2, &cardp->udev->dev,
+ if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
+ /*
+ lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n");
+ lbs_deb_usbd(&cardp->udev->dev,
"seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
cardp->totalbytes);
+ */
memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
- } else if (fwdata->fwheader.dnldcmd == FW_HAS_LAST_BLOCK) {
- lbs_dev_dbg(2, &cardp->udev->dev,
+ } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
+ /*
+ lbs_deb_usbd(&cardp->udev->dev,
"Host has finished FW downloading\n");
- lbs_dev_dbg(2, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Donwloading FW JUMP BLOCK\n");
+ */
memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
cardp->fwfinalblk = 1;
}
- lbs_dev_dbg(2, &cardp->udev->dev,
+ /*
+ lbs_deb_usbd(&cardp->udev->dev,
"The firmware download is done size is %d\n",
cardp->totalbytes);
+ */
kfree(fwdata);
@@ -318,14 +358,19 @@ static int if_prog_firmware(wlan_private * priv)
static int libertas_do_reset(wlan_private *priv)
{
int ret;
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
+
+ lbs_deb_enter(LBS_DEB_USB);
ret = usb_reset_device(cardp->udev);
if (!ret) {
msleep(10);
- reset_device(priv);
+ if_usb_reset_device(priv);
msleep(10);
}
+
+ lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
+
return ret;
}
@@ -339,12 +384,12 @@ static int libertas_do_reset(wlan_private *priv)
int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
{
/* pointer to card structure */
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
int ret = -1;
/* check if device is removed */
if (priv->adapter->surpriseremoved) {
- lbs_dev_dbg(1, &cardp->udev->dev, "Device removed\n");
+ lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
goto tx_ret;
}
@@ -357,10 +402,10 @@ int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
/* transfer failed */
- lbs_dev_dbg(1, &cardp->udev->dev, "usb_submit_urb failed\n");
+ lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n");
ret = -1;
} else {
- lbs_dev_dbg(2, &cardp->udev->dev, "usb_submit_urb success\n");
+ /* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
ret = 0;
}
@@ -372,7 +417,7 @@ static int __if_usb_submit_rx_urb(wlan_private * priv,
void (*callbackfn)
(struct urb *urb))
{
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
struct sk_buff *skb;
struct read_cb_info *rinfo = &cardp->rinfo;
int ret = -1;
@@ -394,13 +439,13 @@ static int __if_usb_submit_rx_urb(wlan_private * priv,
cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
- lbs_dev_dbg(2, &cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
+ /* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
/* handle failure conditions */
- lbs_dev_dbg(1, &cardp->udev->dev, "Submit Rx URB failed\n");
+ lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
ret = -1;
} else {
- lbs_dev_dbg(2, &cardp->udev->dev, "Submit Rx URB success\n");
+ /* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
ret = 0;
}
@@ -423,12 +468,12 @@ static void if_usb_receive_fwload(struct urb *urb)
struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
wlan_private *priv = rinfo->priv;
struct sk_buff *skb = rinfo->skb;
- struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
+ struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
struct fwsyncheader *syncfwheader;
struct bootcmdrespStr bootcmdresp;
if (urb->status) {
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"URB status is failed during fw load\n");
kfree_skb(skb);
return;
@@ -437,18 +482,18 @@ static void if_usb_receive_fwload(struct urb *urb)
if (cardp->bootcmdresp == 0) {
memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
sizeof(bootcmdresp));
- if (cardp->udev->descriptor.bcdDevice < 0x3106) {
+ if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
kfree_skb(skb);
if_usb_submit_rx_urb_fwload(priv);
cardp->bootcmdresp = 1;
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Received valid boot command response\n");
return;
}
- if (bootcmdresp.u32magicnumber != BOOT_CMD_MAGIC_NUMBER) {
+ if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
lbs_pr_info(
"boot cmd response wrong magic number (0x%x)\n",
- bootcmdresp.u32magicnumber);
+ le32_to_cpu(bootcmdresp.u32magicnumber));
} else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
lbs_pr_info(
"boot cmd response cmd_tag error (%d)\n",
@@ -459,7 +504,7 @@ static void if_usb_receive_fwload(struct urb *urb)
bootcmdresp.u8result);
} else {
cardp->bootcmdresp = 1;
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Received valid boot command response\n");
}
kfree_skb(skb);
@@ -469,7 +514,7 @@ static void if_usb_receive_fwload(struct urb *urb)
syncfwheader = kmalloc(sizeof(struct fwsyncheader), GFP_ATOMIC);
if (!syncfwheader) {
- lbs_dev_dbg(1, &cardp->udev->dev, "Failure to allocate syncfwheader\n");
+ lbs_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n");
kfree_skb(skb);
return;
}
@@ -478,14 +523,16 @@ static void if_usb_receive_fwload(struct urb *urb)
sizeof(struct fwsyncheader));
if (!syncfwheader->cmd) {
- lbs_dev_dbg(2, &cardp->udev->dev,
+ /*
+ lbs_deb_usbd(&cardp->udev->dev,
"FW received Blk with correct CRC\n");
- lbs_dev_dbg(2, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"FW received Blk seqnum = %d\n",
syncfwheader->seqnum);
+ */
cardp->CRC_OK = 1;
} else {
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"FW received Blk with CRC error\n");
cardp->CRC_OK = 0;
}
@@ -515,7 +562,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
{
if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Packet length is Invalid\n");
kfree_skb(skb);
return;
@@ -525,7 +572,7 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
skb_put(skb, recvlength);
skb_pull(skb, MESSAGE_HEADER_LEN);
libertas_process_rxed_packet(priv, skb);
- priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN);
+ priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
}
static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
@@ -535,7 +582,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
{
u8 *cmdbuf;
if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"The receive buffer is too large\n");
kfree_skb(skb);
return;
@@ -548,21 +595,21 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
/* take care of cur_cmd = NULL case by reading the
* data to clear the interrupt */
if (!priv->adapter->cur_cmd) {
- cmdbuf = priv->wlan_dev.upld_buf;
+ cmdbuf = priv->upld_buf;
priv->adapter->hisregcpy &= ~his_cmdupldrdy;
} else
cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
cardp->usb_int_cause |= his_cmdupldrdy;
- priv->wlan_dev.upld_len = (recvlength - MESSAGE_HEADER_LEN);
+ priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
- priv->wlan_dev.upld_len);
+ priv->upld_len);
kfree_skb(skb);
- libertas_interrupt(priv->wlan_dev.netdev);
+ libertas_interrupt(priv->dev);
spin_unlock(&priv->adapter->driver_lock);
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Wake up main thread to handle cmd response\n");
return;
@@ -580,17 +627,17 @@ static void if_usb_receive(struct urb *urb)
struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
wlan_private *priv = rinfo->priv;
struct sk_buff *skb = rinfo->skb;
- struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
+ struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
int recvlength = urb->actual_length;
u8 *recvbuff = NULL;
u32 recvtype;
- ENTER();
+ lbs_deb_enter(LBS_DEB_USB);
if (recvlength) {
if (urb->status) {
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"URB status is failed\n");
kfree_skb(skb);
goto setup_for_next;
@@ -598,12 +645,12 @@ static void if_usb_receive(struct urb *urb)
recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
memcpy(&recvtype, recvbuff, sizeof(u32));
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Recv length = 0x%x\n", recvlength);
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Receive type = 0x%X\n", recvtype);
recvtype = le32_to_cpu(recvtype);
- lbs_dev_dbg(1, &cardp->udev->dev,
+ lbs_deb_usbd(&cardp->udev->dev,
"Receive type after = 0x%X\n", recvtype);
} else if (urb->status)
goto rx_exit;
@@ -621,18 +668,18 @@ static void if_usb_receive(struct urb *urb)
case CMD_TYPE_INDICATION:
/* Event cause handling */
spin_lock(&priv->adapter->driver_lock);
- cardp->usb_event_cause = *(u32 *) (recvbuff + MESSAGE_HEADER_LEN);
- lbs_dev_dbg(1, &cardp->udev->dev,"**EVENT** 0x%X\n",
+ cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
+ lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
cardp->usb_event_cause);
if (cardp->usb_event_cause & 0xffff0000) {
libertas_send_tx_feedback(priv);
spin_unlock(&priv->adapter->driver_lock);
break;
}
- cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3;
+ cardp->usb_event_cause <<= 3;
cardp->usb_int_cause |= his_cardevent;
kfree_skb(skb);
- libertas_interrupt(priv->wlan_dev.netdev);
+ libertas_interrupt(priv->dev);
spin_unlock(&priv->adapter->driver_lock);
goto rx_exit;
default:
@@ -643,8 +690,7 @@ static void if_usb_receive(struct urb *urb)
setup_for_next:
if_usb_submit_rx_urb(priv);
rx_exit:
- LEAVE();
- return;
+ lbs_deb_leave(LBS_DEB_USB);
}
/**
@@ -655,24 +701,24 @@ rx_exit:
* @param len number of bytes
* @return 0 or -1
*/
-int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
+static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
{
int ret = -1;
u32 tmp;
- struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
+ struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
- lbs_dev_dbg(1, &cardp->udev->dev,"*** type = %u\n", type);
- lbs_dev_dbg(1, &cardp->udev->dev,"size after = %d\n", nb);
+ lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
+ lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
if (type == MVMS_CMD) {
tmp = cpu_to_le32(CMD_TYPE_REQUEST);
- priv->wlan_dev.dnld_sent = DNLD_CMD_SENT;
+ priv->dnld_sent = DNLD_CMD_SENT;
memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
MESSAGE_HEADER_LEN);
} else {
tmp = cpu_to_le32(CMD_TYPE_DATA);
- priv->wlan_dev.dnld_sent = DNLD_DATA_SENT;
+ priv->dnld_sent = DNLD_DATA_SENT;
memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
MESSAGE_HEADER_LEN);
}
@@ -686,39 +732,41 @@ int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb
}
/* called with adapter->driver_lock held */
-int libertas_sbi_get_int_status(wlan_private * priv, u8 * ireg)
+static int if_usb_get_int_status(wlan_private * priv, u8 * ireg)
{
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
*ireg = cardp->usb_int_cause;
cardp->usb_int_cause = 0;
- lbs_dev_dbg(1, &cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
+ lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
return 0;
}
-int libertas_sbi_read_event_cause(wlan_private * priv)
+static int if_usb_read_event_cause(wlan_private * priv)
{
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
priv->adapter->eventcause = cardp->usb_event_cause;
/* Re-submit rx urb here to avoid event lost issue */
if_usb_submit_rx_urb(priv);
return 0;
}
-int reset_device(wlan_private *priv)
+static int if_usb_reset_device(wlan_private *priv)
{
int ret;
+ lbs_deb_enter(LBS_DEB_USB);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_reset,
cmd_act_halt, 0, 0, NULL);
msleep_interruptible(10);
+ lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
return ret;
}
-int libertas_sbi_unregister_dev(wlan_private * priv)
+static int if_usb_unregister_dev(wlan_private * priv)
{
int ret = 0;
@@ -727,7 +775,7 @@ int libertas_sbi_unregister_dev(wlan_private * priv)
* again.
*/
if (priv)
- reset_device(priv);
+ if_usb_reset_device(priv);
return ret;
}
@@ -738,42 +786,41 @@ int libertas_sbi_unregister_dev(wlan_private * priv)
* @param priv pointer to wlan_private
* @return 0 or -1
*/
-int libertas_sbi_register_dev(wlan_private * priv)
+static int if_usb_register_dev(wlan_private * priv)
{
+ struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
- struct usb_card_rec *cardp = (struct usb_card_rec *)priv->wlan_dev.card;
- ENTER();
+ lbs_deb_enter(LBS_DEB_USB);
cardp->priv = priv;
- cardp->eth_dev = priv->wlan_dev.netdev;
+ cardp->eth_dev = priv->dev;
priv->hotplug_device = &(cardp->udev->dev);
- SET_NETDEV_DEV(cardp->eth_dev, &(cardp->udev->dev));
-
- lbs_dev_dbg(1, &cardp->udev->dev, "udev pointer is at %p\n",
+ lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n",
cardp->udev);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_USB);
return 0;
}
-int libertas_sbi_prog_firmware(wlan_private * priv)
+static int if_usb_prog_firmware(wlan_private * priv)
{
- struct usb_card_rec *cardp = priv->wlan_dev.card;
+ struct usb_card_rec *cardp = priv->card;
int i = 0;
static int reset_count = 10;
+ int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_USB);
cardp->rinfo.priv = priv;
restart:
if (if_usb_submit_rx_urb_fwload(priv) < 0) {
- lbs_dev_dbg(1, &cardp->udev->dev, "URB submission is failed\n");
- LEAVE();
- return -1;
+ lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
+ ret = -1;
+ goto done;
}
cardp->bootcmdresp = 0;
@@ -811,7 +858,7 @@ restart:
if_prog_firmware(priv);
do {
- lbs_dev_dbg(1, &cardp->udev->dev,"Wlan sched timeout\n");
+ lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
i++;
msleep_interruptible(100);
if (priv->adapter->surpriseremoved || i >= 20)
@@ -826,8 +873,8 @@ restart:
}
lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
- LEAVE();
- return -1;
+ ret = -1;
+ goto done;
}
if_usb_submit_rx_urb(priv);
@@ -837,32 +884,10 @@ restart:
priv->adapter->fw_ready = 1;
- LEAVE();
- return 0;
-}
-
-/**
- * @brief Given a usb_card_rec return its wlan_private
- * @param card pointer to a usb_card_rec
- * @return pointer to wlan_private
- */
-wlan_private *libertas_sbi_get_priv(void *card)
-{
- struct usb_card_rec *cardp = card;
- return cardp->priv;
-}
-
-#ifdef ENABLE_PM
-int libertas_sbi_suspend(wlan_private * priv)
-{
- return 0;
-}
-
-int libertas_sbi_resume(wlan_private * priv)
-{
- return 0;
+done:
+ lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
+ return ret;
}
-#endif
#ifdef CONFIG_PM
static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
@@ -870,12 +895,13 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
struct usb_card_rec *cardp = usb_get_intfdata(intf);
wlan_private *priv = cardp->priv;
- ENTER();
+ lbs_deb_enter(LBS_DEB_USB);
if (priv->adapter->psstate != PS_STATE_FULL_POWER)
return -1;
netif_device_detach(cardp->eth_dev);
+ netif_device_detach(priv->mesh_dev);
/* Unlink tx & rx urb */
usb_kill_urb(cardp->tx_urb);
@@ -883,23 +909,25 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
cardp->rx_urb_recall = 1;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_USB);
return 0;
}
static int if_usb_resume(struct usb_interface *intf)
{
struct usb_card_rec *cardp = usb_get_intfdata(intf);
+ wlan_private *priv = cardp->priv;
- ENTER();
+ lbs_deb_enter(LBS_DEB_USB);
cardp->rx_urb_recall = 0;
if_usb_submit_rx_urb(cardp->priv);
netif_device_attach(cardp->eth_dev);
+ netif_device_attach(priv->mesh_dev);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_USB);
return 0;
}
#else
@@ -920,32 +948,40 @@ static struct usb_driver if_usb_driver = {
.resume = if_usb_resume,
};
-/**
- * @brief This function registers driver.
- * @param add pointer to add_card callback function
- * @param remove pointer to remove card callback function
- * @param arg pointer to call back function parameter
- * @return dummy success variable
- */
-int libertas_sbi_register(void)
+static int if_usb_init_module(void)
{
- /*
- * API registers the Marvell USB driver
- * to the USB system
- */
- usb_register(&if_usb_driver);
+ int ret = 0;
- /* Return success to wlan layer */
- return 0;
+ lbs_deb_enter(LBS_DEB_MAIN);
+
+ if (libertas_fw_name == NULL) {
+ libertas_fw_name = default_fw_name;
+ }
+
+ ret = usb_register(&if_usb_driver);
+
+ lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
+ return ret;
}
-/**
- * @brief This function removes usb driver.
- * @return N/A
- */
-void libertas_sbi_unregister(void)
+static void if_usb_exit_module(void)
{
+ struct usb_card_rec *cardp, *cardp_temp;
+
+ lbs_deb_enter(LBS_DEB_MAIN);
+
+ list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list)
+ if_usb_reset_device((wlan_private *) cardp->priv);
+
/* API unregisters the driver from USB subsystem */
usb_deregister(&if_usb_driver);
- return;
+
+ lbs_deb_leave(LBS_DEB_MAIN);
}
+
+module_init(if_usb_init_module);
+module_exit(if_usb_exit_module);
+
+MODULE_DESCRIPTION("8388 USB WLAN Driver");
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index 170dfe6809f..156bb485e1a 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -1,3 +1,8 @@
+#ifndef _LIBERTAS_IF_USB_H
+#define _LIBERTAS_IF_USB_H
+
+#include <linux/list.h>
+
/**
* This file contains definition for USB interface.
*/
@@ -7,11 +12,6 @@
#define IPFIELD_ALIGN_OFFSET 2
-#define USB8388_VID_1 0x1286
-#define USB8388_PID_1 0x2001
-#define USB8388_VID_2 0x05a3
-#define USB8388_PID_2 0x8388
-
#define BOOT_CMD_FW_BY_USB 0x01
#define BOOT_CMD_FW_IN_EEPROM 0x02
#define BOOT_CMD_UPDATE_BOOT2 0x03
@@ -20,7 +20,7 @@
struct bootcmdstr
{
- u32 u32magicnumber;
+ __le32 u32magicnumber;
u8 u8cmd_tag;
u8 au8dumy[11];
};
@@ -30,7 +30,7 @@ struct bootcmdstr
struct bootcmdrespStr
{
- u32 u32magicnumber;
+ __le32 u32magicnumber;
u8 u8cmd_tag;
u8 u8result;
u8 au8dumy[2];
@@ -44,6 +44,7 @@ struct read_cb_info {
/** USB card description structure*/
struct usb_card_rec {
+ struct list_head list;
struct net_device *eth_dev;
struct usb_device *udev;
struct urb *rx_urb, *tx_urb;
@@ -75,33 +76,34 @@ struct usb_card_rec {
/** fwheader */
struct fwheader {
- u32 dnldcmd;
- u32 baseaddr;
- u32 datalength;
- u32 CRC;
+ __le32 dnldcmd;
+ __le32 baseaddr;
+ __le32 datalength;
+ __le32 CRC;
};
#define FW_MAX_DATA_BLK_SIZE 600
/** FWData */
struct FWData {
struct fwheader fwheader;
- u32 seqnum;
+ __le32 seqnum;
u8 data[FW_MAX_DATA_BLK_SIZE];
};
/** fwsyncheader */
struct fwsyncheader {
- u32 cmd;
- u32 seqnum;
+ __le32 cmd;
+ __le32 seqnum;
};
#define FW_HAS_DATA_TO_RECV 0x00000001
#define FW_HAS_LAST_BLOCK 0x00000004
#define FW_DATA_XMIT_SIZE \
- sizeof(struct fwheader) + fwdata->fwheader.datalength + sizeof(u32)
+ sizeof(struct fwheader) + le32_to_cpu(fwdata->fwheader.datalength) + sizeof(u32)
int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb);
void if_usb_free(struct usb_card_rec *cardp);
int if_usb_issue_boot_command(wlan_private *priv, int ivalue);
+#endif
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
index a8f76c35899..f4108158556 100644
--- a/drivers/net/wireless/libertas/ioctl.c
+++ b/drivers/net/wireless/libertas/ioctl.c
@@ -30,6 +30,7 @@
static int wlan_set_region(wlan_private * priv, u16 region_code)
{
int i;
+ int ret = 0;
for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
// use the region code to search for the index
@@ -42,17 +43,18 @@ static int wlan_set_region(wlan_private * priv, u16 region_code)
// if it's unidentified region code
if (i >= MRVDRV_MAX_REGION_CODE) {
- lbs_pr_debug(1, "region Code not identified\n");
- LEAVE();
- return -1;
+ lbs_deb_ioctl("region Code not identified\n");
+ ret = -1;
+ goto done;
}
if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) {
- LEAVE();
- return -EINVAL;
+ ret = -EINVAL;
}
- return 0;
+done:
+ lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
+ return ret;
}
static inline int hex2int(char c)
@@ -125,8 +127,10 @@ static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req)
char ethaddrs_str[18];
char *pos;
u8 ethaddr[ETH_ALEN];
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_IOCTL);
- ENTER();
if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
sizeof(ethaddrs_str)))
return -EFAULT;
@@ -136,11 +140,12 @@ static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req)
return -EINVAL;
}
- lbs_pr_debug(1, "BT: adding %s\n", ethaddrs_str);
- LEAVE();
- return (libertas_prepare_and_send_command(priv, cmd_bt_access,
+ lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str);
+ ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
cmd_act_bt_access_add,
- cmd_option_waitforrsp, 0, ethaddr));
+ cmd_option_waitforrsp, 0, ethaddr);
+ lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
+ return ret;
}
/**
@@ -156,7 +161,8 @@ static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
u8 ethaddr[ETH_ALEN];
char *pos;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
+
if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
sizeof(ethaddrs_str)))
return -EFAULT;
@@ -166,13 +172,14 @@ static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
return -EINVAL;
}
- lbs_pr_debug(1, "BT: deleting %s\n", ethaddrs_str);
+ lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str);
return (libertas_prepare_and_send_command(priv,
cmd_bt_access,
cmd_act_bt_access_del,
cmd_option_waitforrsp, 0, ethaddr));
- LEAVE();
+
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -183,7 +190,7 @@ static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
*/
static int wlan_bt_reset_ioctl(wlan_private * priv)
{
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
lbs_pr_alert( "BT: resetting\n");
@@ -192,7 +199,7 @@ static int wlan_bt_reset_ioctl(wlan_private * priv)
cmd_act_bt_access_reset,
cmd_option_waitforrsp, 0, NULL));
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -209,17 +216,17 @@ static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
struct iwreq *wrq = (struct iwreq *)req;
/* used to pass id and store the bt entry returned by the FW */
union {
- int id;
+ u32 id;
char addr1addr2[2 * ETH_ALEN];
} param;
static char outstr[64];
char *pbuf = outstr;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) {
- lbs_pr_debug(1, "Copy from user failed\n");
+ lbs_deb_ioctl("Copy from user failed\n");
return -1;
}
param.id = simple_strtoul(outstr, NULL, 10);
@@ -234,7 +241,7 @@ static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
if (ret == 0) {
addr1 = param.addr1addr2;
- pos = sprintf(pbuf, "ignoring traffic from ");
+ pos = sprintf(pbuf, "BT includes node ");
pbuf += pos;
pos = eth_addr2str(addr1, pbuf);
pbuf += pos;
@@ -246,11 +253,70 @@ static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(outstr);
if (copy_to_user(wrq->u.data.pointer, (char *)outstr,
wrq->u.data.length)) {
- lbs_pr_debug(1, "BT_LIST: Copy to user failed!\n");
+ lbs_deb_ioctl("BT_LIST: Copy to user failed!\n");
return -EFAULT;
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
+ return 0 ;
+}
+
+/**
+ * @brief Sets inverted state of blacklist (non-zero if inverted)
+ * @param priv A pointer to wlan_private structure
+ * @param req A pointer to ifreq structure
+ * @return 0 --success, otherwise fail
+ */
+static int wlan_bt_set_invert_ioctl(wlan_private * priv, struct ifreq *req)
+{
+ int ret;
+ struct iwreq *wrq = (struct iwreq *)req;
+ union {
+ u32 id;
+ char addr1addr2[2 * ETH_ALEN];
+ } param;
+
+ lbs_deb_enter(LBS_DEB_IOCTL);
+
+ param.id = SUBCMD_DATA(wrq) ;
+ ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
+ cmd_act_bt_access_set_invert,
+ cmd_option_waitforrsp, 0,
+ (char *)&param);
+ if (ret != 0)
+ return -EFAULT;
+ lbs_deb_leave(LBS_DEB_IOCTL);
+ return 0;
+}
+
+/**
+ * @brief Gets inverted state of blacklist (non-zero if inverted)
+ * @param priv A pointer to wlan_private structure
+ * @param req A pointer to ifreq structure
+ * @return 0 --success, otherwise fail
+ */
+static int wlan_bt_get_invert_ioctl(wlan_private * priv, struct ifreq *req)
+{
+ struct iwreq *wrq = (struct iwreq *)req;
+ int ret;
+ union {
+ u32 id;
+ char addr1addr2[2 * ETH_ALEN];
+ } param;
+
+ lbs_deb_enter(LBS_DEB_IOCTL);
+
+ ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
+ cmd_act_bt_access_get_invert,
+ cmd_option_waitforrsp, 0,
+ (char *)&param);
+
+ if (ret == 0)
+ wrq->u.param.value = le32_to_cpu(param.id);
+ else
+ return -EFAULT;
+
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -278,8 +344,10 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
char in_str[128];
static struct cmd_ds_fwt_access fwt_access;
char *ptr;
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_IOCTL);
- ENTER();
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
@@ -297,7 +365,7 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
fwt_access.metric =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
- fwt_access.metric = FWT_DEFAULT_METRIC;
+ fwt_access.metric = cpu_to_le32(FWT_DEFAULT_METRIC);
if ((ptr = next_param(ptr)))
fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
@@ -305,16 +373,21 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
fwt_access.dir = FWT_DEFAULT_DIR;
if ((ptr = next_param(ptr)))
+ fwt_access.rate = (u8) simple_strtoul(ptr, &ptr, 10);
+ else
+ fwt_access.rate = FWT_DEFAULT_RATE;
+
+ if ((ptr = next_param(ptr)))
fwt_access.ssn =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
- fwt_access.ssn = FWT_DEFAULT_SSN;
+ fwt_access.ssn = cpu_to_le32(FWT_DEFAULT_SSN);
if ((ptr = next_param(ptr)))
fwt_access.dsn =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
- fwt_access.dsn = FWT_DEFAULT_DSN;
+ fwt_access.dsn = cpu_to_le32(FWT_DEFAULT_DSN);
if ((ptr = next_param(ptr)))
fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10);
@@ -330,7 +403,7 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
fwt_access.expiration =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
- fwt_access.expiration = FWT_DEFAULT_EXPIRATION;
+ fwt_access.expiration = cpu_to_le32(FWT_DEFAULT_EXPIRATION);
if ((ptr = next_param(ptr)))
fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10);
@@ -341,27 +414,29 @@ static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
fwt_access.snr =
cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
else
- fwt_access.snr = FWT_DEFAULT_SNR;
+ fwt_access.snr = cpu_to_le32(FWT_DEFAULT_SNR);
#ifdef DEBUG
{
char ethaddr1_str[18], ethaddr2_str[18];
eth_addr2str(fwt_access.da, ethaddr1_str);
eth_addr2str(fwt_access.ra, ethaddr2_str);
- lbs_pr_debug(1, "FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
+ lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
fwt_access.dir, ethaddr2_str);
- lbs_pr_debug(1, "FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
+ lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
fwt_access.ssn, fwt_access.dsn, fwt_access.metric,
fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration,
fwt_access.sleepmode, fwt_access.snr);
}
#endif
- LEAVE();
- return (libertas_prepare_and_send_command(priv, cmd_fwt_access,
- cmd_act_fwt_access_add,
- cmd_option_waitforrsp, 0,
- (void *)&fwt_access));
+ ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
+ cmd_act_fwt_access_add,
+ cmd_option_waitforrsp, 0,
+ (void *)&fwt_access);
+
+ lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
+ return ret;
}
/**
@@ -376,8 +451,10 @@ static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req)
char in_str[64];
static struct cmd_ds_fwt_access fwt_access;
char *ptr;
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_IOCTL);
- ENTER();
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
@@ -399,20 +476,21 @@ static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
char ethaddr1_str[18], ethaddr2_str[18];
- lbs_pr_debug(1, "FWT_DEL: line is %s\n", in_str);
+ lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str);
eth_addr2str(fwt_access.da, ethaddr1_str);
eth_addr2str(fwt_access.ra, ethaddr2_str);
- lbs_pr_debug(1, "FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
+ lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
ethaddr2_str, fwt_access.dir);
}
#endif
- LEAVE();
- return (libertas_prepare_and_send_command(priv,
- cmd_fwt_access,
- cmd_act_fwt_access_del,
- cmd_option_waitforrsp, 0,
- (void *)&fwt_access));
+ ret = libertas_prepare_and_send_command(priv,
+ cmd_fwt_access,
+ cmd_act_fwt_access_del,
+ cmd_option_waitforrsp, 0,
+ (void *)&fwt_access);
+ lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
+ return ret;
}
@@ -427,15 +505,18 @@ static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf)
buf += eth_addr2str(fwt_access.da, buf);
buf += sprintf(buf, " ");
buf += eth_addr2str(fwt_access.ra, buf);
+ buf += sprintf(buf, " %u", fwt_access.valid);
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric));
buf += sprintf(buf, " %u", fwt_access.dir);
+ buf += sprintf(buf, " %u", fwt_access.rate);
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn));
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn));
buf += sprintf(buf, " %u", fwt_access.hopcount);
buf += sprintf(buf, " %u", fwt_access.ttl);
buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration));
buf += sprintf(buf, " %u", fwt_access.sleepmode);
- buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.snr));
+ buf += sprintf(buf, " %u ", le32_to_cpu(fwt_access.snr));
+ buf += eth_addr2str(fwt_access.prec, buf);
}
/**
@@ -453,7 +534,8 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
static char out_str[128];
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
+
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
@@ -465,9 +547,9 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
char ethaddr1_str[18];
- lbs_pr_debug(1, "FWT_LOOKUP: line is %s\n", in_str);
+ lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str);
eth_addr2str(fwt_access.da, ethaddr1_str);
- lbs_pr_debug(1, "FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
+ lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
}
#endif
@@ -485,11 +567,11 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
- lbs_pr_debug(1, "FWT_LOOKUP: Copy to user failed!\n");
+ lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n");
return -EFAULT;
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -500,7 +582,7 @@ static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
*/
static int wlan_fwt_reset_ioctl(wlan_private * priv)
{
- lbs_pr_debug(1, "FWT: resetting\n");
+ lbs_deb_ioctl("FWT: resetting\n");
return (libertas_prepare_and_send_command(priv,
cmd_fwt_access,
@@ -522,18 +604,21 @@ static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req)
char *ptr = in_str;
static char out_str[128];
char *pbuf = out_str;
- int ret;
+ int ret = 0;
- ENTER();
- if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
- return -EFAULT;
+ lbs_deb_enter(LBS_DEB_IOCTL);
+
+ if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) {
+ ret = -EFAULT;
+ goto out;
+ }
fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
#ifdef DEBUG
{
- lbs_pr_debug(1, "FWT_LIST: line is %s\n", in_str);
- lbs_pr_debug(1, "FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
+ lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str);
+ lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
}
#endif
@@ -549,12 +634,16 @@ static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
- lbs_pr_debug(1, "FWT_LIST: Copy to user failed!\n");
- return -EFAULT;
+ lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n");
+ ret = -EFAULT;
+ goto out;
}
- LEAVE();
- return 0;
+ ret = 0;
+
+out:
+ lbs_deb_leave(LBS_DEB_IOCTL);
+ return ret;
}
/**
@@ -573,7 +662,8 @@ static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
char *pbuf = out_str;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
+
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
@@ -581,8 +671,8 @@ static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
- lbs_pr_debug(1, "FWT_LIST_ROUTE: line is %s\n", in_str);
- lbs_pr_debug(1, "FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
+ lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str);
+ lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
}
#endif
@@ -591,28 +681,18 @@ static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
cmd_option_waitforrsp, 0, (void *)&fwt_access);
if (ret == 0) {
- pbuf += sprintf(pbuf, " ");
- pbuf += eth_addr2str(fwt_access.da, pbuf);
- pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.metric));
- pbuf += sprintf(pbuf, " %u", fwt_access.dir);
- /* note that the firmware returns the nid in the id field */
- pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.id));
- pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.ssn));
- pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.dsn));
- pbuf += sprintf(pbuf, " hop %u", fwt_access.hopcount);
- pbuf += sprintf(pbuf, " ttl %u", fwt_access.ttl);
- pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.expiration));
+ print_route(fwt_access, pbuf);
} else
pbuf += sprintf(pbuf, " (null)");
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
- lbs_pr_debug(1, "FWT_LIST_ROUTE: Copy to user failed!\n");
+ lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n");
return -EFAULT;
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -632,7 +712,8 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
char *pbuf = out_str;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
+
if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
return -EFAULT;
@@ -641,8 +722,8 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
#ifdef DEBUG
{
- lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: line is %s\n", in_str);
- lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
+ lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str);
+ lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
}
#endif
@@ -663,11 +744,11 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
wrq->u.data.length = strlen(out_str);
if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
wrq->u.data.length)) {
- lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: Copy to user failed!\n");
+ lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n");
return -EFAULT;
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -684,9 +765,9 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
static struct cmd_ds_fwt_access fwt_access;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
- lbs_pr_debug(1, "FWT: cleaning up\n");
+ lbs_deb_ioctl("FWT: cleaning up\n");
memset(&fwt_access, 0, sizeof(fwt_access));
@@ -700,7 +781,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
else
return -EFAULT;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -716,9 +797,9 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
static struct cmd_ds_fwt_access fwt_access;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
- lbs_pr_debug(1, "FWT: getting time\n");
+ lbs_deb_ioctl("FWT: getting time\n");
memset(&fwt_access, 0, sizeof(fwt_access));
@@ -732,7 +813,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
else
return -EFAULT;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -748,7 +829,7 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
struct cmd_ds_mesh_access mesh_access;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
memset(&mesh_access, 0, sizeof(mesh_access));
@@ -762,7 +843,7 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
else
return -EFAULT;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return 0;
}
@@ -777,13 +858,13 @@ static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
struct cmd_ds_mesh_access mesh_access;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
if( (ttl > 0xff) || (ttl < 0) )
return -EINVAL;
memset(&mesh_access, 0, sizeof(mesh_access));
- mesh_access.data[0] = ttl;
+ mesh_access.data[0] = cpu_to_le32(ttl);
ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
cmd_act_mesh_set_ttl,
@@ -793,7 +874,7 @@ static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
if (ret != 0)
ret = -EFAULT;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_IOCTL);
return ret;
}
@@ -815,9 +896,9 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
wlan_adapter *adapter = priv->adapter;
struct iwreq *wrq = (struct iwreq *)req;
- ENTER();
+ lbs_deb_enter(LBS_DEB_IOCTL);
- lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
+ lbs_deb_ioctl("libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
switch (cmd) {
case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */
switch (wrq->u.data.flags) {
@@ -848,6 +929,10 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = wlan_mesh_set_ttl_ioctl(priv, idata);
break;
+ case WLAN_SUBCMD_BT_SET_INVERT:
+ ret = wlan_bt_set_invert_ioctl(priv, req);
+ break ;
+
default:
ret = -EOPNOTSUPP;
break;
@@ -905,6 +990,10 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = wlan_mesh_get_ttl_ioctl(priv, req);
break;
+ case WLAN_SUBCMD_BT_GET_INVERT:
+ ret = wlan_bt_get_invert_ioctl(priv, req);
+ break ;
+
default:
ret = -EOPNOTSUPP;
@@ -937,7 +1026,7 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
(data, wrq->u.data.pointer,
sizeof(int) *
wrq->u.data.length)) {
- lbs_pr_debug(1,
+ lbs_deb_ioctl(
"Copy from user failed\n");
return -EFAULT;
}
@@ -970,7 +1059,7 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
if (copy_to_user(wrq->u.data.pointer, data,
sizeof(int) *
gpio->header.len)) {
- lbs_pr_debug(1, "Copy to user failed\n");
+ lbs_deb_ioctl("Copy to user failed\n");
return -EFAULT;
}
@@ -984,7 +1073,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
ret = -EINVAL;
break;
}
- LEAVE();
+
+ lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret);
return ret;
}
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index d4926b83e14..78ac3064a0b 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -7,6 +7,7 @@
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
+#include <linux/etherdevice.h>
#include <net/iw_handler.h>
@@ -14,6 +15,7 @@
#include "decl.h"
#include "join.h"
#include "dev.h"
+#include "assoc.h"
#define AD_HOC_CAP_PRIVACY_ON 1
@@ -60,7 +62,7 @@ static int get_common_rates(wlan_adapter * adapter, u8 * rate1,
lbs_dbg_hex("rate1 (AP) rates:", tmp, sizeof(tmp));
lbs_dbg_hex("rate2 (Card) rates:", rate2, rate2_size);
lbs_dbg_hex("Common rates:", ptr, rate1_size);
- lbs_pr_debug(1, "Tx datarate is set to 0x%X\n", adapter->datarate);
+ lbs_deb_join("Tx datarate is set to 0x%X\n", adapter->datarate);
if (!adapter->is_datarate_auto) {
while (*ptr) {
@@ -104,24 +106,22 @@ int libertas_send_deauth(wlan_private * priv)
*
* @return 0-success, otherwise fail
*/
-int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
+int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_authenticate,
0, cmd_option_waitforrsp,
- 0, pbssdesc->macaddress);
+ 0, assoc_req->bss.bssid);
- if (ret) {
- LEAVE();
- return ret;
- }
+ if (ret)
+ goto done;
/* set preamble to firmware */
- if (adapter->capinfo.shortpreamble && pbssdesc->cap.shortpreamble)
+ if (adapter->capinfo.shortpreamble && assoc_req->bss.cap.shortpreamble)
adapter->preamble = cmd_type_short_preamble;
else
adapter->preamble = cmd_type_long_preamble;
@@ -129,9 +129,10 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
libertas_set_radio_control(priv);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_associate,
- 0, cmd_option_waitforrsp, 0, pbssdesc);
+ 0, cmd_option_waitforrsp, 0, assoc_req);
- LEAVE();
+done:
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
@@ -142,7 +143,7 @@ int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc)
* @param adhocssid The ssid of the Adhoc Network
* @return 0--success, -1--fail
*/
-int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *adhocssid)
+int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
@@ -150,22 +151,20 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a
adapter->adhoccreate = 1;
if (!adapter->capinfo.shortpreamble) {
- lbs_pr_debug(1, "AdhocStart: Long preamble\n");
+ lbs_deb_join("AdhocStart: Long preamble\n");
adapter->preamble = cmd_type_long_preamble;
} else {
- lbs_pr_debug(1, "AdhocStart: Short preamble\n");
+ lbs_deb_join("AdhocStart: Short preamble\n");
adapter->preamble = cmd_type_short_preamble;
}
libertas_set_radio_control(priv);
- lbs_pr_debug(1, "Adhoc channel = %d\n", adapter->adhocchannel);
- lbs_pr_debug(1, "curbssparams.channel = %d\n",
- adapter->curbssparams.channel);
- lbs_pr_debug(1, "curbssparams.band = %d\n", adapter->curbssparams.band);
+ lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
+ lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);
ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_start,
- 0, cmd_option_waitforrsp, 0, adhocssid);
+ 0, cmd_option_waitforrsp, 0, assoc_req);
return ret;
}
@@ -179,52 +178,53 @@ int libertas_start_adhoc_network(wlan_private * priv, struct WLAN_802_11_SSID *a
*
* @return 0--success, -1--fail
*/
-int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbssdesc)
+int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
{
wlan_adapter *adapter = priv->adapter;
+ struct bss_descriptor * bss = &assoc_req->bss;
int ret = 0;
- lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid =%s\n",
- adapter->curbssparams.ssid.ssid);
- lbs_pr_debug(1, "libertas_join_adhoc_network: CurBss.ssid_len =%u\n",
- adapter->curbssparams.ssid.ssidlength);
- lbs_pr_debug(1, "libertas_join_adhoc_network: ssid =%s\n", pbssdesc->ssid.ssid);
- lbs_pr_debug(1, "libertas_join_adhoc_network: ssid len =%u\n",
- pbssdesc->ssid.ssidlength);
+ lbs_deb_join("%s: Current SSID '%s', ssid length %u\n",
+ __func__,
+ escape_essid(adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len),
+ adapter->curbssparams.ssid_len);
+ lbs_deb_join("%s: requested ssid '%s', ssid length %u\n",
+ __func__, escape_essid(bss->ssid, bss->ssid_len),
+ bss->ssid_len);
/* check if the requested SSID is already joined */
- if (adapter->curbssparams.ssid.ssidlength
- && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid)
+ if (adapter->curbssparams.ssid_len
+ && !libertas_ssid_cmp(adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len,
+ bss->ssid, bss->ssid_len)
&& (adapter->mode == IW_MODE_ADHOC)) {
-
- lbs_pr_debug(1,
+ lbs_deb_join(
"ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
"not attempting to re-join");
-
return -1;
}
/*Use shortpreamble only when both creator and card supports
short preamble */
- if (!pbssdesc->cap.shortpreamble || !adapter->capinfo.shortpreamble) {
- lbs_pr_debug(1, "AdhocJoin: Long preamble\n");
+ if (!bss->cap.shortpreamble || !adapter->capinfo.shortpreamble) {
+ lbs_deb_join("AdhocJoin: Long preamble\n");
adapter->preamble = cmd_type_long_preamble;
} else {
- lbs_pr_debug(1, "AdhocJoin: Short preamble\n");
+ lbs_deb_join("AdhocJoin: Short preamble\n");
adapter->preamble = cmd_type_short_preamble;
}
libertas_set_radio_control(priv);
- lbs_pr_debug(1, "curbssparams.channel = %d\n",
- adapter->curbssparams.channel);
- lbs_pr_debug(1, "curbssparams.band = %c\n", adapter->curbssparams.band);
+ lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
+ lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
adapter->adhoccreate = 0;
ret = libertas_prepare_and_send_command(priv, cmd_802_11_ad_hoc_join,
0, cmd_option_waitforrsp,
- OID_802_11_SSID, pbssdesc);
+ OID_802_11_SSID, assoc_req);
return ret;
}
@@ -265,6 +265,8 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
int ret = -1;
u8 *bssid = pdata_buf;
+ lbs_deb_enter(LBS_DEB_JOIN);
+
cmd->command = cpu_to_le16(cmd_802_11_authenticate);
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
+ S_DS_GEN);
@@ -281,18 +283,19 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
pauthenticate->authtype = 0x80;
break;
default:
- lbs_pr_debug(1, "AUTH_CMD: invalid auth alg 0x%X\n",
+ lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
adapter->secinfo.auth_mode);
goto out;
}
memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
- lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n",
- bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
+ lbs_deb_join("AUTH_CMD: BSSID is : " MAC_FMT " auth=0x%X\n",
+ MAC_ARG(bssid), pauthenticate->authtype);
ret = 0;
out:
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
@@ -302,22 +305,20 @@ int libertas_cmd_80211_deauthenticate(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth;
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
cmd->command = cpu_to_le16(cmd_802_11_deauthenticate);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) +
S_DS_GEN);
/* set AP MAC address */
- memmove(dauth->macaddr, adapter->curbssparams.bssid,
- ETH_ALEN);
+ memmove(dauth->macaddr, adapter->curbssparams.bssid, ETH_ALEN);
/* Reason code 3 = Station is leaving */
#define REASON_CODE_STA_LEAVING 3
dauth->reasoncode = cpu_to_le16(REASON_CODE_STA_LEAVING);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_JOIN);
return 0;
}
@@ -327,20 +328,20 @@ int libertas_cmd_80211_associate(wlan_private * priv,
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
int ret = 0;
- struct bss_descriptor *pbssdesc;
+ struct assoc_request * assoc_req = pdata_buf;
+ struct bss_descriptor * bss = &assoc_req->bss;
u8 *card_rates;
u8 *pos;
int card_rates_size;
- u16 tmpcap;
+ u16 tmpcap, tmplen;
struct mrvlietypes_ssidparamset *ssid;
struct mrvlietypes_phyparamset *phy;
struct mrvlietypes_ssparamset *ss;
struct mrvlietypes_ratesparamset *rates;
struct mrvlietypes_rsnparamset *rsn;
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
- pbssdesc = pdata_buf;
pos = (u8 *) passo;
if (!adapter) {
@@ -350,15 +351,11 @@ int libertas_cmd_80211_associate(wlan_private * priv,
cmd->command = cpu_to_le16(cmd_802_11_associate);
- /* Save so we know which BSS Desc to use in the response handler */
- adapter->pattemptedbssdesc = pbssdesc;
-
- memcpy(passo->peerstaaddr,
- pbssdesc->macaddress, sizeof(passo->peerstaaddr));
+ memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
pos += sizeof(passo->peerstaaddr);
/* set the listen interval */
- passo->listeninterval = adapter->listeninterval;
+ passo->listeninterval = cpu_to_le16(adapter->listeninterval);
pos += sizeof(passo->capinfo);
pos += sizeof(passo->listeninterval);
@@ -367,30 +364,30 @@ int libertas_cmd_80211_associate(wlan_private * priv,
ssid = (struct mrvlietypes_ssidparamset *) pos;
ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
- ssid->header.len = pbssdesc->ssid.ssidlength;
- memcpy(ssid->ssid, pbssdesc->ssid.ssid, ssid->header.len);
- pos += sizeof(ssid->header) + ssid->header.len;
- ssid->header.len = cpu_to_le16(ssid->header.len);
+ tmplen = bss->ssid_len;
+ ssid->header.len = cpu_to_le16(tmplen);
+ memcpy(ssid->ssid, bss->ssid, tmplen);
+ pos += sizeof(ssid->header) + tmplen;
phy = (struct mrvlietypes_phyparamset *) pos;
phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
- phy->header.len = sizeof(phy->fh_ds.dsparamset);
+ tmplen = sizeof(phy->fh_ds.dsparamset);
+ phy->header.len = cpu_to_le16(tmplen);
memcpy(&phy->fh_ds.dsparamset,
- &pbssdesc->phyparamset.dsparamset.currentchan,
- sizeof(phy->fh_ds.dsparamset));
- pos += sizeof(phy->header) + phy->header.len;
- phy->header.len = cpu_to_le16(phy->header.len);
+ &bss->phyparamset.dsparamset.currentchan,
+ tmplen);
+ pos += sizeof(phy->header) + tmplen;
ss = (struct mrvlietypes_ssparamset *) pos;
ss->header.type = cpu_to_le16(TLV_TYPE_CF);
- ss->header.len = sizeof(ss->cf_ibss.cfparamset);
- pos += sizeof(ss->header) + ss->header.len;
- ss->header.len = cpu_to_le16(ss->header.len);
+ tmplen = sizeof(ss->cf_ibss.cfparamset);
+ ss->header.len = cpu_to_le16(tmplen);
+ pos += sizeof(ss->header) + tmplen;
rates = (struct mrvlietypes_ratesparamset *) pos;
rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
- memcpy(&rates->rates, &pbssdesc->libertas_supported_rates, WLAN_SUPPORTED_RATES);
+ memcpy(&rates->rates, &bss->libertas_supported_rates, WLAN_SUPPORTED_RATES);
card_rates = libertas_supported_rates;
card_rates_size = sizeof(libertas_supported_rates);
@@ -401,41 +398,42 @@ int libertas_cmd_80211_associate(wlan_private * priv,
goto done;
}
- rates->header.len = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES);
- adapter->curbssparams.numofrates = rates->header.len;
+ tmplen = min_t(size_t, strlen(rates->rates), WLAN_SUPPORTED_RATES);
+ adapter->curbssparams.numofrates = tmplen;
- pos += sizeof(rates->header) + rates->header.len;
- rates->header.len = cpu_to_le16(rates->header.len);
+ pos += sizeof(rates->header) + tmplen;
+ rates->header.len = cpu_to_le16(tmplen);
- if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
+ if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
rsn = (struct mrvlietypes_rsnparamset *) pos;
- rsn->header.type = (u16) adapter->wpa_ie[0]; /* WPA_IE or WPA2_IE */
- rsn->header.type = cpu_to_le16(rsn->header.type);
- rsn->header.len = (u16) adapter->wpa_ie[1];
- memcpy(rsn->rsnie, &adapter->wpa_ie[2], rsn->header.len);
+ /* WPA_IE or WPA2_IE */
+ rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
+ tmplen = (u16) assoc_req->wpa_ie[1];
+ rsn->header.len = cpu_to_le16(tmplen);
+ memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
lbs_dbg_hex("ASSOC_CMD: RSN IE", (u8 *) rsn,
- sizeof(rsn->header) + rsn->header.len);
- pos += sizeof(rsn->header) + rsn->header.len;
- rsn->header.len = cpu_to_le16(rsn->header.len);
+ sizeof(rsn->header) + tmplen);
+ pos += sizeof(rsn->header) + tmplen;
}
/* update curbssparams */
- adapter->curbssparams.channel =
- (pbssdesc->phyparamset.dsparamset.currentchan);
+ adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
/* Copy the infra. association rates into Current BSS state structure */
memcpy(&adapter->curbssparams.datarates, &rates->rates,
- min_t(size_t, sizeof(adapter->curbssparams.datarates), rates->header.len));
+ min_t(size_t, sizeof(adapter->curbssparams.datarates),
+ cpu_to_le16(rates->header.len)));
- lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len);
+ lbs_deb_join("ASSOC_CMD: rates->header.len = %d\n",
+ cpu_to_le16(rates->header.len));
/* set IBSS field */
- if (pbssdesc->mode == IW_MODE_INFRA) {
+ if (bss->mode == IW_MODE_INFRA) {
#define CAPINFO_ESS_MODE 1
passo->capinfo.ess = CAPINFO_ESS_MODE;
}
- if (libertas_parse_dnld_countryinfo_11d(priv)) {
+ if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
ret = -1;
goto done;
}
@@ -443,31 +441,28 @@ int libertas_cmd_80211_associate(wlan_private * priv,
cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
/* set the capability info at last */
- memcpy(&tmpcap, &pbssdesc->cap, sizeof(passo->capinfo));
+ memcpy(&tmpcap, &bss->cap, sizeof(passo->capinfo));
tmpcap &= CAPINFO_MASK;
- lbs_pr_debug(1, "ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
- tmpcap, CAPINFO_MASK);
- tmpcap = cpu_to_le16(tmpcap);
+ lbs_deb_join("ASSOC_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
+ tmpcap, CAPINFO_MASK);
memcpy(&passo->capinfo, &tmpcap, sizeof(passo->capinfo));
- done:
- LEAVE();
+done:
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
- struct cmd_ds_command *cmd, void *pssid)
+ struct cmd_ds_command *cmd, void *pdata_buf)
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
int ret = 0;
int cmdappendsize = 0;
int i;
- u16 tmpcap;
- struct bss_descriptor *pbssdesc;
- struct WLAN_802_11_SSID *ssid = pssid;
+ struct assoc_request * assoc_req = pdata_buf;
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
if (!adapter) {
ret = -1;
@@ -476,9 +471,6 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_start);
- pbssdesc = &adapter->curbssparams.bssdescriptor;
- adapter->pattemptedbssdesc = pbssdesc;
-
/*
* Fill in the parameters for 2 data structures:
* 1. cmd_ds_802_11_ad_hoc_start command
@@ -492,20 +484,16 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
*/
memset(adhs->SSID, 0, IW_ESSID_MAX_SIZE);
+ memcpy(adhs->SSID, assoc_req->ssid, assoc_req->ssid_len);
- memcpy(adhs->SSID, ssid->ssid, ssid->ssidlength);
-
- lbs_pr_debug(1, "ADHOC_S_CMD: SSID = %s\n", adhs->SSID);
-
- memset(pbssdesc->ssid.ssid, 0, IW_ESSID_MAX_SIZE);
- memcpy(pbssdesc->ssid.ssid, ssid->ssid, ssid->ssidlength);
-
- pbssdesc->ssid.ssidlength = ssid->ssidlength;
+ lbs_deb_join("ADHOC_S_CMD: SSID '%s', ssid length %u\n",
+ escape_essid(assoc_req->ssid, assoc_req->ssid_len),
+ assoc_req->ssid_len);
/* set the BSS type */
adhs->bsstype = cmd_bss_type_ibss;
- pbssdesc->mode = IW_MODE_ADHOC;
- adhs->beaconperiod = adapter->beaconperiod;
+ adapter->mode = IW_MODE_ADHOC;
+ adhs->beaconperiod = cpu_to_le16(adapter->beaconperiod);
/* set Physical param set */
#define DS_PARA_IE_ID 3
@@ -514,18 +502,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
- WARN_ON(!adapter->adhocchannel);
+ WARN_ON(!assoc_req->channel);
- lbs_pr_debug(1, "ADHOC_S_CMD: Creating ADHOC on channel %d\n",
- adapter->adhocchannel);
+ lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
+ assoc_req->channel);
- adapter->curbssparams.channel = adapter->adhocchannel;
-
- pbssdesc->channel = adapter->adhocchannel;
- adhs->phyparamset.dsparamset.currentchan = adapter->adhocchannel;
-
- memcpy(&pbssdesc->phyparamset,
- &adhs->phyparamset, sizeof(union ieeetypes_phyparamset));
+ adhs->phyparamset.dsparamset.currentchan = assoc_req->channel;
/* set IBSS param set */
#define IBSS_PARA_IE_ID 6
@@ -533,26 +515,21 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
- adhs->ssparamset.ibssparamset.atimwindow = adapter->atimwindow;
- memcpy(&pbssdesc->ssparamset,
- &adhs->ssparamset, sizeof(union IEEEtypes_ssparamset));
+ adhs->ssparamset.ibssparamset.atimwindow = cpu_to_le16(adapter->atimwindow);
/* set capability info */
adhs->cap.ess = 0;
adhs->cap.ibss = 1;
- pbssdesc->cap.ibss = 1;
/* probedelay */
adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
/* set up privacy in adapter->scantable[i] */
- if (adapter->secinfo.wep_enabled) {
- lbs_pr_debug(1, "ADHOC_S_CMD: WEP enabled, setting privacy on\n");
- pbssdesc->privacy = wlan802_11privfilter8021xWEP;
+ if (assoc_req->secinfo.wep_enabled) {
+ lbs_deb_join("ADHOC_S_CMD: WEP enabled, setting privacy on\n");
adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
} else {
- lbs_pr_debug(1, "ADHOC_S_CMD: WEP disabled, setting privacy off\n");
- pbssdesc->privacy = wlan802_11privfilteracceptall;
+ lbs_deb_join("ADHOC_S_CMD: WEP disabled, setting privacy off\n");
}
memset(adhs->datarate, 0, sizeof(adhs->datarate));
@@ -574,29 +551,24 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
memcpy(&adapter->curbssparams.datarates,
&adhs->datarate, adapter->curbssparams.numofrates);
- lbs_pr_debug(1, "ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
+ lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
adhs->datarate[0], adhs->datarate[1],
adhs->datarate[2], adhs->datarate[3]);
- lbs_pr_debug(1, "ADHOC_S_CMD: AD HOC Start command is ready\n");
+ lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
if (libertas_create_dnld_countryinfo_11d(priv)) {
- lbs_pr_debug(1, "ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
+ lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
ret = -1;
goto done;
}
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start)
- + S_DS_GEN + cmdappendsize);
-
- memcpy(&tmpcap, &adhs->cap, sizeof(u16));
- tmpcap = cpu_to_le16(tmpcap);
- memcpy(&adhs->cap, &tmpcap, sizeof(u16));
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start) +
+ S_DS_GEN + cmdappendsize);
ret = 0;
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
@@ -614,7 +586,8 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_ad_hoc_join *padhocjoin = &cmd->params.adj;
- struct bss_descriptor *pbssdesc = pdata_buf;
+ struct assoc_request * assoc_req = pdata_buf;
+ struct bss_descriptor *bss = &assoc_req->bss;
int cmdappendsize = 0;
int ret = 0;
u8 *card_rates;
@@ -622,70 +595,59 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
u16 tmpcap;
int i;
- ENTER();
-
- adapter->pattemptedbssdesc = pbssdesc;
+ lbs_deb_enter(LBS_DEB_JOIN);
cmd->command = cpu_to_le16(cmd_802_11_ad_hoc_join);
padhocjoin->bssdescriptor.bsstype = cmd_bss_type_ibss;
- padhocjoin->bssdescriptor.beaconperiod = pbssdesc->beaconperiod;
-
- memcpy(&padhocjoin->bssdescriptor.BSSID,
- &pbssdesc->macaddress, ETH_ALEN);
+ padhocjoin->bssdescriptor.beaconperiod = cpu_to_le16(bss->beaconperiod);
- memcpy(&padhocjoin->bssdescriptor.SSID,
- &pbssdesc->ssid.ssid, pbssdesc->ssid.ssidlength);
+ memcpy(&padhocjoin->bssdescriptor.BSSID, &bss->bssid, ETH_ALEN);
+ memcpy(&padhocjoin->bssdescriptor.SSID, &bss->ssid, bss->ssid_len);
memcpy(&padhocjoin->bssdescriptor.phyparamset,
- &pbssdesc->phyparamset, sizeof(union ieeetypes_phyparamset));
+ &bss->phyparamset, sizeof(union ieeetypes_phyparamset));
memcpy(&padhocjoin->bssdescriptor.ssparamset,
- &pbssdesc->ssparamset, sizeof(union IEEEtypes_ssparamset));
+ &bss->ssparamset, sizeof(union IEEEtypes_ssparamset));
- memcpy(&tmpcap, &pbssdesc->cap, sizeof(struct ieeetypes_capinfo));
+ memcpy(&tmpcap, &bss->cap, sizeof(struct ieeetypes_capinfo));
tmpcap &= CAPINFO_MASK;
- lbs_pr_debug(1, "ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
+ lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
tmpcap, CAPINFO_MASK);
memcpy(&padhocjoin->bssdescriptor.cap, &tmpcap,
sizeof(struct ieeetypes_capinfo));
/* information on BSSID descriptor passed to FW */
- lbs_pr_debug(1,
- "ADHOC_J_CMD: BSSID = %2x-%2x-%2x-%2x-%2x-%2x, SSID = %s\n",
- padhocjoin->bssdescriptor.BSSID[0],
- padhocjoin->bssdescriptor.BSSID[1],
- padhocjoin->bssdescriptor.BSSID[2],
- padhocjoin->bssdescriptor.BSSID[3],
- padhocjoin->bssdescriptor.BSSID[4],
- padhocjoin->bssdescriptor.BSSID[5],
+ lbs_deb_join(
+ "ADHOC_J_CMD: BSSID = " MAC_FMT ", SSID = '%s'\n",
+ MAC_ARG(padhocjoin->bssdescriptor.BSSID),
padhocjoin->bssdescriptor.SSID);
/* failtimeout */
padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
/* probedelay */
- padhocjoin->probedelay =
- cpu_to_le16(cmd_scan_probe_delay_time);
+ padhocjoin->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
/* Copy Data rates from the rates recorded in scan response */
memset(padhocjoin->bssdescriptor.datarates, 0,
sizeof(padhocjoin->bssdescriptor.datarates));
- memcpy(padhocjoin->bssdescriptor.datarates, pbssdesc->datarates,
+ memcpy(padhocjoin->bssdescriptor.datarates, bss->datarates,
min(sizeof(padhocjoin->bssdescriptor.datarates),
- sizeof(pbssdesc->datarates)));
+ sizeof(bss->datarates)));
card_rates = libertas_supported_rates;
card_rates_size = sizeof(libertas_supported_rates);
- adapter->curbssparams.channel = pbssdesc->channel;
+ adapter->curbssparams.channel = bss->channel;
if (get_common_rates(adapter, padhocjoin->bssdescriptor.datarates,
sizeof(padhocjoin->bssdescriptor.datarates),
card_rates, card_rates_size)) {
- lbs_pr_debug(1, "ADHOC_J_CMD: get_common_rates returns error.\n");
+ lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
ret = -1;
goto done;
}
@@ -704,17 +666,17 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
adapter->curbssparams.numofrates);
padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
- cpu_to_le16(pbssdesc->atimwindow);
+ cpu_to_le16(bss->atimwindow);
- if (adapter->secinfo.wep_enabled) {
+ if (assoc_req->secinfo.wep_enabled) {
padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
}
if (adapter->psmode == wlan802_11powermodemax_psp) {
/* wake up first */
- enum WLAN_802_11_POWER_MODE Localpsmode;
+ __le32 Localpsmode;
- Localpsmode = wlan802_11powermodecam;
+ Localpsmode = cpu_to_le32(wlan802_11powermodecam);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_ps_mode,
cmd_act_set,
@@ -726,24 +688,16 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
}
}
- if (libertas_parse_dnld_countryinfo_11d(priv)) {
+ if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
ret = -1;
goto done;
}
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join)
- + S_DS_GEN + cmdappendsize);
-
- memcpy(&tmpcap, &padhocjoin->bssdescriptor.cap,
- sizeof(struct ieeetypes_capinfo));
- tmpcap = cpu_to_le16(tmpcap);
-
- memcpy(&padhocjoin->bssdescriptor.cap,
- &tmpcap, sizeof(struct ieeetypes_capinfo));
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join) +
+ S_DS_GEN + cmdappendsize);
- done:
- LEAVE();
+done:
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
@@ -754,19 +708,24 @@ int libertas_ret_80211_associate(wlan_private * priv,
int ret = 0;
union iwreq_data wrqu;
struct ieeetypes_assocrsp *passocrsp;
- struct bss_descriptor *pbssdesc;
+ struct bss_descriptor * bss;
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
- passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
+ if (!adapter->in_progress_assoc_req) {
+ lbs_deb_join("ASSOC_RESP: no in-progress association request\n");
+ ret = -1;
+ goto done;
+ }
+ bss = &adapter->in_progress_assoc_req->bss;
- if (passocrsp->statuscode) {
+ passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
+ if (le16_to_cpu(passocrsp->statuscode)) {
libertas_mac_event_disconnected(priv);
- lbs_pr_debug(1,
- "ASSOC_RESP: Association failed, status code = %d\n",
- passocrsp->statuscode);
+ lbs_deb_join("ASSOC_RESP: Association failed, status code = %d\n",
+ le16_to_cpu(passocrsp->statuscode));
ret = -1;
goto done;
@@ -778,24 +737,15 @@ int libertas_ret_80211_associate(wlan_private * priv,
/* Send a Media Connected event, according to the Spec */
adapter->connect_status = libertas_connected;
- /* Set the attempted BSSID Index to current */
- pbssdesc = adapter->pattemptedbssdesc;
-
- lbs_pr_debug(1, "ASSOC_RESP: %s\n", pbssdesc->ssid.ssid);
+ lbs_deb_join("ASSOC_RESP: assocated to '%s'\n",
+ escape_essid(bss->ssid, bss->ssid_len));
- /* Set the new SSID to current SSID */
- memcpy(&adapter->curbssparams.ssid,
- &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID));
-
- /* Set the new BSSID (AP's MAC address) to current BSSID */
- memcpy(adapter->curbssparams.bssid,
- pbssdesc->macaddress, ETH_ALEN);
-
- /* Make a copy of current BSSID descriptor */
- memcpy(&adapter->curbssparams.bssdescriptor,
- pbssdesc, sizeof(struct bss_descriptor));
+ /* Update current SSID and BSSID */
+ memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+ adapter->curbssparams.ssid_len = bss->ssid_len;
+ memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
- lbs_pr_debug(1, "ASSOC_RESP: currentpacketfilter is %x\n",
+ lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n",
adapter->currentpacketfilter);
adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0;
@@ -806,28 +756,31 @@ int libertas_ret_80211_associate(wlan_private * priv,
adapter->nextSNRNF = 0;
adapter->numSNRNF = 0;
- netif_carrier_on(priv->wlan_dev.netdev);
- netif_wake_queue(priv->wlan_dev.netdev);
+ netif_carrier_on(priv->dev);
+ netif_wake_queue(priv->dev);
- lbs_pr_debug(1, "ASSOC_RESP: Associated \n");
+ netif_carrier_on(priv->mesh_dev);
+ netif_wake_queue(priv->mesh_dev);
+
+ lbs_deb_join("ASSOC_RESP: Associated \n");
memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
+ wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
- done:
- LEAVE();
+done:
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
int libertas_ret_80211_disassociate(wlan_private * priv,
struct cmd_ds_command *resp)
{
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
libertas_mac_event_disconnected(priv);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_JOIN);
return 0;
}
@@ -840,90 +793,85 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
u16 result = le16_to_cpu(resp->result);
struct cmd_ds_802_11_ad_hoc_result *padhocresult;
union iwreq_data wrqu;
- struct bss_descriptor *pbssdesc;
+ struct bss_descriptor *bss;
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
padhocresult = &resp->params.result;
- lbs_pr_debug(1, "ADHOC_S_RESP: size = %d\n", le16_to_cpu(resp->size));
- lbs_pr_debug(1, "ADHOC_S_RESP: command = %x\n", command);
- lbs_pr_debug(1, "ADHOC_S_RESP: result = %x\n", result);
+ lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size));
+ lbs_deb_join("ADHOC_RESP: command = %x\n", command);
+ lbs_deb_join("ADHOC_RESP: result = %x\n", result);
- pbssdesc = adapter->pattemptedbssdesc;
+ if (!adapter->in_progress_assoc_req) {
+ lbs_deb_join("ADHOC_RESP: no in-progress association request\n");
+ ret = -1;
+ goto done;
+ }
+ bss = &adapter->in_progress_assoc_req->bss;
/*
* Join result code 0 --> SUCCESS
*/
if (result) {
- lbs_pr_debug(1, "ADHOC_RESP failed\n");
+ lbs_deb_join("ADHOC_RESP: failed\n");
if (adapter->connect_status == libertas_connected) {
libertas_mac_event_disconnected(priv);
}
-
- memset(&adapter->curbssparams.bssdescriptor,
- 0x00, sizeof(adapter->curbssparams.bssdescriptor));
-
- LEAVE();
- return -1;
+ ret = -1;
+ goto done;
}
/*
* Now the join cmd should be successful
* If BSSID has changed use SSID to compare instead of BSSID
*/
- lbs_pr_debug(1, "ADHOC_J_RESP %s\n", pbssdesc->ssid.ssid);
+ lbs_deb_join("ADHOC_RESP: associated to '%s'\n",
+ escape_essid(bss->ssid, bss->ssid_len));
/* Send a Media Connected event, according to the Spec */
adapter->connect_status = libertas_connected;
if (command == cmd_ret_802_11_ad_hoc_start) {
/* Update the created network descriptor with the new BSSID */
- memcpy(pbssdesc->macaddress,
- padhocresult->BSSID, ETH_ALEN);
- } else {
-
- /* Make a copy of current BSSID descriptor, only needed for join since
- * the current descriptor is already being used for adhoc start
- */
- memmove(&adapter->curbssparams.bssdescriptor,
- pbssdesc, sizeof(struct bss_descriptor));
+ memcpy(bss->bssid, padhocresult->BSSID, ETH_ALEN);
}
/* Set the BSSID from the joined/started descriptor */
- memcpy(&adapter->curbssparams.bssid,
- pbssdesc->macaddress, ETH_ALEN);
+ memcpy(&adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
/* Set the new SSID to current SSID */
- memcpy(&adapter->curbssparams.ssid,
- &pbssdesc->ssid, sizeof(struct WLAN_802_11_SSID));
+ memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+ adapter->curbssparams.ssid_len = bss->ssid_len;
- netif_carrier_on(priv->wlan_dev.netdev);
- netif_wake_queue(priv->wlan_dev.netdev);
+ netif_carrier_on(priv->dev);
+ netif_wake_queue(priv->dev);
+
+ netif_carrier_on(priv->mesh_dev);
+ netif_wake_queue(priv->mesh_dev);
memset(&wrqu, 0, sizeof(wrqu));
memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
+ wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
- lbs_pr_debug(1, "ADHOC_RESP: - Joined/Started Ad Hoc\n");
- lbs_pr_debug(1, "ADHOC_RESP: channel = %d\n", adapter->adhocchannel);
- lbs_pr_debug(1, "ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
- padhocresult->BSSID[0], padhocresult->BSSID[1],
- padhocresult->BSSID[2], padhocresult->BSSID[3],
- padhocresult->BSSID[4], padhocresult->BSSID[5]);
+ lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n");
+ lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel);
+ lbs_deb_join("ADHOC_RESP: BSSID = " MAC_FMT "\n",
+ MAC_ARG(padhocresult->BSSID));
- LEAVE();
+done:
+ lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
return ret;
}
int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
struct cmd_ds_command *resp)
{
- ENTER();
+ lbs_deb_enter(LBS_DEB_JOIN);
libertas_mac_event_disconnected(priv);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_JOIN);
return 0;
}
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h
index 115f5a8ba34..d522630ff8c 100644
--- a/drivers/net/wireless/libertas/join.h
+++ b/drivers/net/wireless/libertas/join.h
@@ -9,6 +9,7 @@
#define _WLAN_JOIN_H
#include "defs.h"
+#include "dev.h"
struct cmd_ds_command;
extern int libertas_cmd_80211_authenticate(wlan_private * priv,
@@ -21,7 +22,7 @@ extern int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
struct cmd_ds_command *cmd);
extern int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
struct cmd_ds_command *cmd,
- void *pssid);
+ void *pdata_buf);
extern int libertas_cmd_80211_deauthenticate(wlan_private * priv,
struct cmd_ds_command *cmd);
extern int libertas_cmd_80211_associate(wlan_private * priv,
@@ -39,12 +40,10 @@ extern int libertas_ret_80211_associate(wlan_private * priv,
extern int libertas_reassociation_thread(void *data);
-struct WLAN_802_11_SSID;
-struct bss_descriptor;
-
extern int libertas_start_adhoc_network(wlan_private * priv,
- struct WLAN_802_11_SSID *adhocssid);
-extern int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor *pbssdesc);
+ struct assoc_request * assoc_req);
+extern int libertas_join_adhoc_network(wlan_private * priv,
+ struct assoc_request * assoc_req);
extern int libertas_stop_adhoc_network(wlan_private * priv);
extern int libertas_send_deauthentication(wlan_private * priv);
@@ -52,6 +51,6 @@ extern int libertas_send_deauth(wlan_private * priv);
extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
-int wlan_associate(wlan_private * priv, struct bss_descriptor * pbssdesc);
+int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req);
#endif
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index b9b25ce6591..623ab4b1697 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -4,6 +4,7 @@
* thread etc..
*/
+#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/freezer.h>
#include <linux/etherdevice.h>
@@ -11,26 +12,28 @@
#include <linux/if_arp.h>
#include <net/iw_handler.h>
+#include <net/ieee80211.h>
#include "host.h"
-#include "sbi.h"
#include "decl.h"
#include "dev.h"
-#include "fw.h"
#include "wext.h"
#include "debugfs.h"
#include "assoc.h"
-#define DRIVER_RELEASE_VERSION "320.p0"
+#define DRIVER_RELEASE_VERSION "322.p0"
const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
#ifdef DEBUG
"-dbg"
#endif
"";
-#ifdef ENABLE_PM
-static struct pm_dev *wlan_pm_dev = NULL;
-#endif
+
+/* Module parameters */
+unsigned int libertas_debug = 0;
+module_param(libertas_debug, int, 0644);
+EXPORT_SYMBOL_GPL(libertas_debug);
+
#define WLAN_TX_PWR_DEFAULT 20 /*100mW */
#define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */
@@ -146,14 +149,6 @@ static struct region_cfp_table region_cfp_table[] = {
};
/**
- * the rates supported by the card
- */
-u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] =
- { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
- 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
-};
-
-/**
* the rates supported
*/
u8 libertas_supported_rates[G_SUPPORTED_RATES] =
@@ -173,66 +168,55 @@ u8 libertas_adhoc_rates_g[G_SUPPORTED_RATES] =
u8 libertas_adhoc_rates_b[4] = { 0x82, 0x84, 0x8b, 0x96 };
/**
- * the global variable of a pointer to wlan_private
- * structure variable
- */
-static wlan_private *wlanpriv = NULL;
-
-#define MAX_DEVS 5
-static struct net_device *libertas_devs[MAX_DEVS];
-static int libertas_found = 0;
-
-/**
* the table to keep region code
*/
u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
{ 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
-static u8 *default_fw_name = "usb8388.bin";
-
/**
* Attributes exported through sysfs
*/
/**
- * @brief Get function for sysfs attribute libertas_mpp
+ * @brief Get function for sysfs attribute anycast_mask
*/
-static ssize_t libertas_mpp_get(struct device * dev,
+static ssize_t libertas_anycast_get(struct device * dev,
struct device_attribute *attr, char * buf) {
struct cmd_ds_mesh_access mesh_access;
memset(&mesh_access, 0, sizeof(mesh_access));
libertas_prepare_and_send_command(to_net_dev(dev)->priv,
cmd_mesh_access,
- cmd_act_mesh_get_mpp,
+ cmd_act_mesh_get_anycast,
cmd_option_waitforrsp, 0, (void *)&mesh_access);
- return snprintf(buf, 3, "%d\n", mesh_access.data[0]);
+ return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
}
/**
- * @brief Set function for sysfs attribute libertas_mpp
+ * @brief Set function for sysfs attribute anycast_mask
*/
-static ssize_t libertas_mpp_set(struct device * dev,
+static ssize_t libertas_anycast_set(struct device * dev,
struct device_attribute *attr, const char * buf, size_t count) {
struct cmd_ds_mesh_access mesh_access;
-
+ uint32_t datum;
memset(&mesh_access, 0, sizeof(mesh_access));
- sscanf(buf, "%d", &(mesh_access.data[0]));
+ sscanf(buf, "%x", &datum);
+ mesh_access.data[0] = cpu_to_le32(datum);
+
libertas_prepare_and_send_command((to_net_dev(dev))->priv,
cmd_mesh_access,
- cmd_act_mesh_set_mpp,
+ cmd_act_mesh_set_anycast,
cmd_option_waitforrsp, 0, (void *)&mesh_access);
return strlen(buf);
}
/**
- * libertas_mpp attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/libertas-mpp)
+ * anycast_mask attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/anycast_mask)
*/
-static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get,
- libertas_mpp_set );
+static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set);
/**
* @brief Check if the device can be open and wait if necessary.
@@ -245,7 +229,8 @@ static DEVICE_ATTR(libertas_mpp, 0644, libertas_mpp_get,
* function to work around the issue.
*
*/
-static int pre_open_check(struct net_device *dev) {
+static int pre_open_check(struct net_device *dev)
+{
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *adapter = priv->adapter;
int i = 0;
@@ -255,8 +240,7 @@ static int pre_open_check(struct net_device *dev) {
msleep_interruptible(100);
}
if (!adapter->fw_ready) {
- lbs_pr_info("FW not ready, pre_open_check() return failure\n");
- LEAVE();
+ lbs_pr_err("firmware not ready\n");
return -1;
}
@@ -274,17 +258,19 @@ static int wlan_dev_open(struct net_device *dev)
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
-
+ lbs_deb_enter(LBS_DEB_NET);
priv->open = 1;
if (adapter->connect_status == libertas_connected) {
- netif_carrier_on(priv->wlan_dev.netdev);
- } else
- netif_carrier_off(priv->wlan_dev.netdev);
+ netif_carrier_on(priv->dev);
+ netif_carrier_on(priv->mesh_dev);
+ } else {
+ netif_carrier_off(priv->dev);
+ netif_carrier_off(priv->mesh_dev);
+ }
- LEAVE();
+ lbs_deb_leave(LBS_DEB_NET);
return 0;
}
/**
@@ -297,12 +283,12 @@ static int mesh_open(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv ;
- if(pre_open_check(dev) == -1)
+ if (pre_open_check(dev) == -1)
return -1;
priv->mesh_open = 1 ;
- netif_start_queue(priv->mesh_dev);
+ netif_wake_queue(priv->mesh_dev);
if (priv->infra_open == 0)
- return wlan_dev_open(priv->wlan_dev.netdev) ;
+ return wlan_dev_open(priv->dev) ;
return 0;
}
@@ -319,9 +305,9 @@ static int wlan_open(struct net_device *dev)
if(pre_open_check(dev) == -1)
return -1;
priv->infra_open = 1 ;
- netif_wake_queue(priv->wlan_dev.netdev);
+ netif_wake_queue(priv->dev);
if (priv->open == 0)
- return wlan_dev_open(priv->wlan_dev.netdev) ;
+ return wlan_dev_open(priv->dev) ;
return 0;
}
@@ -329,12 +315,12 @@ static int wlan_dev_close(struct net_device *dev)
{
wlan_private *priv = dev->priv;
- ENTER();
+ lbs_deb_enter(LBS_DEB_NET);
- netif_carrier_off(priv->wlan_dev.netdev);
+ netif_carrier_off(priv->dev);
priv->open = 0;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_NET);
return 0;
}
@@ -351,7 +337,7 @@ static int mesh_close(struct net_device *dev)
priv->mesh_open = 0;
netif_stop_queue(priv->mesh_dev);
if (priv->infra_open == 0)
- return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ;
+ return wlan_dev_close(dev);
else
return 0;
}
@@ -362,147 +348,38 @@ static int mesh_close(struct net_device *dev)
* @param dev A pointer to net_device structure
* @return 0
*/
-static int wlan_close(struct net_device *dev) {
+static int wlan_close(struct net_device *dev)
+{
wlan_private *priv = (wlan_private *) dev->priv;
- netif_stop_queue(priv->wlan_dev.netdev);
+ netif_stop_queue(dev);
priv->infra_open = 0;
if (priv->mesh_open == 0)
- return wlan_dev_close( ((wlan_private *) dev->priv)->wlan_dev.netdev) ;
+ return wlan_dev_close(dev);
else
return 0;
}
-#ifdef ENABLE_PM
-
-/**
- * @brief This function is a callback function. it is called by
- * kernel to enter or exit power saving mode.
- *
- * @param pmdev A pointer to pm_dev
- * @param pmreq pm_request_t
- * @param pmdata A pointer to pmdata
- * @return 0 or -1
- */
-static int wlan_pm_callback(struct pm_dev *pmdev, pm_request_t pmreq,
- void *pmdata)
-{
- wlan_private *priv = wlanpriv;
- wlan_adapter *adapter = priv->adapter;
- struct net_device *dev = priv->wlan_dev.netdev;
-
- lbs_pr_debug(1, "WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq);
-
- switch (pmreq) {
- case PM_SUSPEND:
- lbs_pr_debug(1, "WPRM_PM_CALLBACK: enter PM_SUSPEND.\n");
-
- /* in associated mode */
- if (adapter->connect_status == libertas_connected) {
- if ((adapter->psstate != PS_STATE_SLEEP)
- ) {
- lbs_pr_debug(1,
- "wlan_pm_callback: can't enter sleep mode\n");
- return -1;
- } else {
-
- /*
- * Detach the network interface
- * if the network is running
- */
- if (netif_running(dev)) {
- netif_device_detach(dev);
- lbs_pr_debug(1,
- "netif_device_detach().\n");
- }
- libertas_sbi_suspend(priv);
- }
- break;
- }
-
- /* in non associated mode */
-
- /*
- * Detach the network interface
- * if the network is running
- */
- if (netif_running(dev))
- netif_device_detach(dev);
-
- /*
- * Storing and restoring of the regs be taken care
- * at the driver rest will be done at wlan driver
- * this makes driver independent of the card
- */
-
- libertas_sbi_suspend(priv);
-
- break;
-
- case PM_RESUME:
- /* in associated mode */
- if (adapter->connect_status == libertas_connected) {
- {
- /*
- * Bring the inteface up first
- * This case should not happen still ...
- */
- libertas_sbi_resume(priv);
-
- /*
- * Attach the network interface
- * if the network is running
- */
- if (netif_running(dev)) {
- netif_device_attach(dev);
- lbs_pr_debug(1,
- "after netif_device_attach().\n");
- }
- lbs_pr_debug(1,
- "After netif attach, in associated mode.\n");
- }
- break;
- }
-
- /* in non associated mode */
-
- /*
- * Bring the inteface up first
- * This case should not happen still ...
- */
-
- libertas_sbi_resume(priv);
-
- if (netif_running(dev))
- netif_device_attach(dev);
-
- lbs_pr_debug(1, "after netif attach, in NON associated mode.\n");
- break;
- }
-
- return 0;
-}
-#endif /* ENABLE_PM */
-
static int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int ret = 0;
wlan_private *priv = dev->priv;
- ENTER();
+ lbs_deb_enter(LBS_DEB_NET);
- if (priv->wlan_dev.dnld_sent || priv->adapter->TxLockFlag) {
+ if (priv->dnld_sent || priv->adapter->TxLockFlag) {
priv->stats.tx_dropped++;
goto done;
}
- netif_stop_queue(priv->wlan_dev.netdev);
+ netif_stop_queue(priv->dev);
+ netif_stop_queue(priv->mesh_dev);
if (libertas_process_tx(priv, skb) == 0)
dev->trans_start = jiffies;
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
return ret;
}
@@ -513,33 +390,43 @@ done:
static int mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
wlan_private *priv = dev->priv;
- ENTER();
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
SET_MESH_FRAME(skb);
- LEAVE();
- return wlan_hard_start_xmit(skb, priv->wlan_dev.netdev);
+ ret = wlan_hard_start_xmit(skb, priv->dev);
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
}
/**
* @brief Mark non-mesh packets and handover them to wlan_hard_start_xmit
*
*/
-static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) {
- ENTER();
+static int wlan_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_NET);
+
UNSET_MESH_FRAME(skb);
- LEAVE();
- return wlan_hard_start_xmit(skb, dev);
+
+ ret = wlan_hard_start_xmit(skb, dev);
+ lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+ return ret;
}
static void wlan_tx_timeout(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
- ENTER();
+ lbs_deb_enter(LBS_DEB_TX);
- lbs_pr_err("tx watch dog timeout!\n");
+ lbs_pr_err("tx watch dog timeout\n");
- priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
+ priv->dnld_sent = DNLD_RES_RECEIVED;
dev->trans_start = jiffies;
if (priv->adapter->currenttxskb) {
@@ -550,10 +437,12 @@ static void wlan_tx_timeout(struct net_device *dev)
libertas_send_tx_feedback(priv);
} else
wake_up_interruptible(&priv->mainthread.waitq);
- } else if (priv->adapter->connect_status == libertas_connected)
- netif_wake_queue(priv->wlan_dev.netdev);
+ } else if (priv->adapter->connect_status == libertas_connected) {
+ netif_wake_queue(priv->dev);
+ netif_wake_queue(priv->mesh_dev);
+ }
- LEAVE();
+ lbs_deb_leave(LBS_DEB_TX);
}
/**
@@ -576,7 +465,10 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr)
wlan_adapter *adapter = priv->adapter;
struct sockaddr *phwaddr = addr;
- ENTER();
+ lbs_deb_enter(LBS_DEB_NET);
+
+ /* In case it was called from the mesh device */
+ dev = priv->dev ;
memset(adapter->current_addr, 0, ETH_ALEN);
@@ -591,17 +483,18 @@ static int wlan_set_mac_address(struct net_device *dev, void *addr)
cmd_option_waitforrsp, 0, NULL);
if (ret) {
- lbs_pr_debug(1, "set mac address failed.\n");
+ lbs_deb_net("set MAC address failed\n");
ret = -1;
goto done;
}
lbs_dbg_hex("adapter->macaddr:", adapter->current_addr, ETH_ALEN);
memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN);
- memcpy(((wlan_private *) dev->priv)->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
+ if (priv->mesh_dev)
+ memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
return ret;
}
@@ -626,12 +519,12 @@ static void wlan_set_multicast_list(struct net_device *dev)
wlan_adapter *adapter = priv->adapter;
int oldpacketfilter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_NET);
oldpacketfilter = adapter->currentpacketfilter;
if (dev->flags & IFF_PROMISC) {
- lbs_pr_debug(1, "enable Promiscuous mode\n");
+ lbs_deb_net("enable promiscuous mode\n");
adapter->currentpacketfilter |=
cmd_act_mac_promiscuous_enable;
adapter->currentpacketfilter &=
@@ -644,7 +537,7 @@ static void wlan_set_multicast_list(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI || dev->mc_count >
MRVDRV_MAX_MULTICAST_LIST_SIZE) {
- lbs_pr_debug(1, "Enabling All Multicast!\n");
+ lbs_deb_net( "enabling all multicast\n");
adapter->currentpacketfilter |=
cmd_act_mac_all_multicast_enable;
adapter->currentpacketfilter &=
@@ -654,8 +547,8 @@ static void wlan_set_multicast_list(struct net_device *dev)
~cmd_act_mac_all_multicast_enable;
if (!dev->mc_count) {
- lbs_pr_debug(1, "No multicast addresses - "
- "disabling multicast!\n");
+ lbs_deb_net("no multicast addresses, "
+ "disabling multicast\n");
adapter->currentpacketfilter &=
~cmd_act_mac_multicast_enable;
} else {
@@ -667,12 +560,12 @@ static void wlan_set_multicast_list(struct net_device *dev)
adapter->nr_of_multicastmacaddr =
wlan_copy_multicast_address(adapter, dev);
- lbs_pr_debug(1, "Multicast addresses: %d\n",
+ lbs_deb_net("multicast addresses: %d\n",
dev->mc_count);
for (i = 0; i < dev->mc_count; i++) {
- lbs_pr_debug(1, "Multicast address %d:"
- "%x %x %x %x %x %x\n", i,
+ lbs_deb_net("Multicast address %d:"
+ MAC_FMT "\n", i,
adapter->multicastlist[i][0],
adapter->multicastlist[i][1],
adapter->multicastlist[i][2],
@@ -680,7 +573,7 @@ static void wlan_set_multicast_list(struct net_device *dev)
adapter->multicastlist[i][4],
adapter->multicastlist[i][5]);
}
- /* set multicast addresses to firmware */
+ /* send multicast addresses to firmware */
libertas_prepare_and_send_command(priv,
cmd_mac_multicast_adr,
cmd_act_set, 0, 0,
@@ -693,13 +586,13 @@ static void wlan_set_multicast_list(struct net_device *dev)
libertas_set_mac_packet_filter(priv);
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_NET);
}
/**
- * @brief This function hanldes the major job in WLAN driver.
- * it handles the event generated by firmware, rx data received
- * from firmware and tx data sent from kernel.
+ * @brief This function handles the major jobs in the WLAN driver.
+ * It handles all events generated by firmware, RX data received
+ * from firmware and TX data sent from kernel.
*
* @param data A pointer to wlan_thread structure
* @return 0
@@ -712,26 +605,26 @@ static int wlan_service_main_thread(void *data)
wait_queue_t wait;
u8 ireg = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_THREAD);
wlan_activate_thread(thread);
init_waitqueue_entry(&wait, current);
for (;;) {
- lbs_pr_debug(1, "main-thread 111: intcounter=%d "
+ lbs_deb_thread( "main-thread 111: intcounter=%d "
"currenttxskb=%p dnld_sent=%d\n",
adapter->intcounter,
- adapter->currenttxskb, priv->wlan_dev.dnld_sent);
+ adapter->currenttxskb, priv->dnld_sent);
add_wait_queue(&thread->waitq, &wait);
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irq(&adapter->driver_lock);
if ((adapter->psstate == PS_STATE_SLEEP) ||
(!adapter->intcounter
- && (priv->wlan_dev.dnld_sent || adapter->cur_cmd ||
+ && (priv->dnld_sent || adapter->cur_cmd ||
list_empty(&adapter->cmdpendingq)))) {
- lbs_pr_debug(1,
+ lbs_deb_thread(
"main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
adapter->connect_status, adapter->intcounter,
adapter->psmode, adapter->psstate);
@@ -741,23 +634,23 @@ static int wlan_service_main_thread(void *data)
spin_unlock_irq(&adapter->driver_lock);
- lbs_pr_debug(1,
+ lbs_deb_thread(
"main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
"dnld_sent=%d\n", adapter->intcounter,
- adapter->currenttxskb, priv->wlan_dev.dnld_sent);
+ adapter->currenttxskb, priv->dnld_sent);
set_current_state(TASK_RUNNING);
remove_wait_queue(&thread->waitq, &wait);
try_to_freeze();
- lbs_pr_debug(1, "main-thread 333: intcounter=%d currenttxskb=%p "
+ lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p "
"dnld_sent=%d\n",
adapter->intcounter,
- adapter->currenttxskb, priv->wlan_dev.dnld_sent);
+ adapter->currenttxskb, priv->dnld_sent);
if (kthread_should_stop()
|| adapter->surpriseremoved) {
- lbs_pr_debug(1,
+ lbs_deb_thread(
"main-thread: break from main thread: surpriseremoved=0x%x\n",
adapter->surpriseremoved);
break;
@@ -768,10 +661,10 @@ static int wlan_service_main_thread(void *data)
if (adapter->intcounter) {
u8 int_status;
adapter->intcounter = 0;
- int_status = libertas_sbi_get_int_status(priv, &ireg);
+ int_status = priv->hw_get_int_status(priv, &ireg);
if (int_status) {
- lbs_pr_debug(1,
+ lbs_deb_thread(
"main-thread: reading HOST_INT_STATUS_REG failed\n");
spin_unlock_irq(&adapter->driver_lock);
continue;
@@ -779,14 +672,14 @@ static int wlan_service_main_thread(void *data)
adapter->hisregcpy |= ireg;
}
- lbs_pr_debug(1, "main-thread 444: intcounter=%d currenttxskb=%p "
+ lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p "
"dnld_sent=%d\n",
adapter->intcounter,
- adapter->currenttxskb, priv->wlan_dev.dnld_sent);
+ adapter->currenttxskb, priv->dnld_sent);
/* command response? */
if (adapter->hisregcpy & his_cmdupldrdy) {
- lbs_pr_debug(1, "main-thread: cmd response ready.\n");
+ lbs_deb_thread("main-thread: cmd response ready\n");
adapter->hisregcpy &= ~his_cmdupldrdy;
spin_unlock_irq(&adapter->driver_lock);
@@ -796,13 +689,13 @@ static int wlan_service_main_thread(void *data)
/* Any Card Event */
if (adapter->hisregcpy & his_cardevent) {
- lbs_pr_debug(1, "main-thread: Card Event Activity.\n");
+ lbs_deb_thread("main-thread: Card Event Activity\n");
adapter->hisregcpy &= ~his_cardevent;
- if (libertas_sbi_read_event_cause(priv)) {
+ if (priv->hw_read_event_cause(priv)) {
lbs_pr_alert(
- "main-thread: libertas_sbi_read_event_cause failed.\n");
+ "main-thread: hw_read_event_cause failed\n");
spin_unlock_irq(&adapter->driver_lock);
continue;
}
@@ -813,15 +706,15 @@ static int wlan_service_main_thread(void *data)
/* Check if we need to confirm Sleep Request received previously */
if (adapter->psstate == PS_STATE_PRE_SLEEP) {
- if (!priv->wlan_dev.dnld_sent && !adapter->cur_cmd) {
+ if (!priv->dnld_sent && !adapter->cur_cmd) {
if (adapter->connect_status ==
libertas_connected) {
- lbs_pr_debug(1,
+ lbs_deb_thread(
"main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
"dnld_sent=%d cur_cmd=%p, confirm now\n",
adapter->intcounter,
adapter->currenttxskb,
- priv->wlan_dev.dnld_sent,
+ priv->dnld_sent,
adapter->cur_cmd);
libertas_ps_confirm_sleep(priv,
@@ -847,7 +740,7 @@ static int wlan_service_main_thread(void *data)
continue;
/* Execute the next command */
- if (!priv->wlan_dev.dnld_sent && !priv->adapter->cur_cmd)
+ if (!priv->dnld_sent && !priv->adapter->cur_cmd)
libertas_execute_next_command(priv);
/* Wake-up command waiters which can't sleep in
@@ -864,7 +757,7 @@ static int wlan_service_main_thread(void *data)
wake_up_all(&adapter->cmd_pending);
wlan_deactivate_thread(thread);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_THREAD);
return 0;
}
@@ -875,49 +768,32 @@ static int wlan_service_main_thread(void *data)
* @param card A pointer to card
* @return A pointer to wlan_private structure
*/
-wlan_private *wlan_add_card(void *card)
+wlan_private *libertas_add_card(void *card, struct device *dmdev)
{
struct net_device *dev = NULL;
- struct net_device *mesh_dev = NULL;
wlan_private *priv = NULL;
- ENTER();
+ lbs_deb_enter(LBS_DEB_NET);
/* Allocate an Ethernet device and register it */
if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
- lbs_pr_alert( "Init ethernet device failed!\n");
+ lbs_pr_err("init ethX device failed\n");
return NULL;
}
-
priv = dev->priv;
/* allocate buffer for wlan_adapter */
- if (!(priv->adapter = kmalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
- lbs_pr_alert( "Allocate buffer for wlan_adapter failed!\n");
- goto err_kmalloc;
- }
-
- /* Allocate a virtual mesh device */
- if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
- lbs_pr_debug(1, "Init ethernet device failed!\n");
- return NULL;
+ if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
+ lbs_pr_err("allocate buffer for wlan_adapter failed\n");
+ goto err_kzalloc;
}
- /* Both intervaces share the priv structure */
- mesh_dev->priv = priv;
-
- /* init wlan_adapter */
- memset(priv->adapter, 0, sizeof(wlan_adapter));
-
- priv->wlan_dev.netdev = dev;
- priv->wlan_dev.card = card;
+ priv->dev = dev;
+ priv->card = card;
priv->mesh_open = 0;
priv->infra_open = 0;
- priv->mesh_dev = mesh_dev;
- wlanpriv = priv;
SET_MODULE_OWNER(dev);
- SET_MODULE_OWNER(mesh_dev);
/* Setup the OS Interface to our functions */
dev->open = wlan_open;
@@ -925,116 +801,172 @@ wlan_private *wlan_add_card(void *card)
dev->stop = wlan_close;
dev->do_ioctl = libertas_do_ioctl;
dev->set_mac_address = wlan_set_mac_address;
- mesh_dev->open = mesh_open;
- mesh_dev->hard_start_xmit = mesh_pre_start_xmit;
- mesh_dev->stop = mesh_close;
- mesh_dev->do_ioctl = libertas_do_ioctl;
- memcpy(mesh_dev->dev_addr, wlanpriv->wlan_dev.netdev->dev_addr,
- sizeof(wlanpriv->wlan_dev.netdev->dev_addr));
-
-#define WLAN_WATCHDOG_TIMEOUT (5 * HZ)
-
dev->tx_timeout = wlan_tx_timeout;
dev->get_stats = wlan_get_stats;
- dev->watchdog_timeo = WLAN_WATCHDOG_TIMEOUT;
+ dev->watchdog_timeo = 5 * HZ;
dev->ethtool_ops = &libertas_ethtool_ops;
- mesh_dev->get_stats = wlan_get_stats;
- mesh_dev->ethtool_ops = &libertas_ethtool_ops;
-
#ifdef WIRELESS_EXT
dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
- mesh_dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
#endif
#define NETIF_F_DYNALLOC 16
dev->features |= NETIF_F_DYNALLOC;
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
dev->set_multicast_list = wlan_set_multicast_list;
+ SET_NETDEV_DEV(dev, dmdev);
+
INIT_LIST_HEAD(&priv->adapter->cmdfreeq);
INIT_LIST_HEAD(&priv->adapter->cmdpendingq);
spin_lock_init(&priv->adapter->driver_lock);
init_waitqueue_head(&priv->adapter->cmd_pending);
priv->adapter->nr_cmd_pending = 0;
+ goto done;
- lbs_pr_debug(1, "Starting kthread...\n");
+err_kzalloc:
+ free_netdev(dev);
+ priv = NULL;
+done:
+ lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
+ return priv;
+}
+EXPORT_SYMBOL_GPL(libertas_add_card);
+
+int libertas_activate_card(wlan_private *priv, char *fw_name)
+{
+ struct net_device *dev = priv->dev;
+ int ret = -1;
+
+ lbs_deb_enter(LBS_DEB_MAIN);
+
+ lbs_deb_thread("Starting kthread...\n");
priv->mainthread.priv = priv;
wlan_create_thread(wlan_service_main_thread,
&priv->mainthread, "wlan_main_service");
priv->assoc_thread =
create_singlethread_workqueue("libertas_assoc");
- INIT_DELAYED_WORK(&priv->assoc_work, wlan_association_worker);
+ INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
+ INIT_WORK(&priv->sync_channel, libertas_sync_channel);
/*
* Register the device. Fillup the private data structure with
* relevant information from the card and request for the required
* IRQ.
*/
- if (libertas_sbi_register_dev(priv) < 0) {
- lbs_pr_info("failed to register wlan device!\n");
+ if (priv->hw_register_dev(priv) < 0) {
+ lbs_pr_err("failed to register WLAN device\n");
goto err_registerdev;
}
/* init FW and HW */
- if (libertas_init_fw(priv)) {
- lbs_pr_debug(1, "Firmware Init failed\n");
+ if (fw_name && libertas_init_fw(priv, fw_name)) {
+ lbs_pr_err("firmware init failed\n");
goto err_registerdev;
}
if (register_netdev(dev)) {
- lbs_pr_err("Cannot register network device!\n");
- goto err_init_fw;
- }
-
- /* Register virtual mesh interface */
- if (register_netdev(mesh_dev)) {
- lbs_pr_info("Cannot register mesh virtual interface!\n");
+ lbs_pr_err("cannot register ethX device\n");
goto err_init_fw;
}
- lbs_pr_info("%s: Marvell Wlan 802.11 adapter ", dev->name);
+ lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
libertas_debugfs_init_one(priv, dev);
- if (libertas_found == MAX_DEVS)
- goto err_init_fw;
- libertas_devs[libertas_found] = dev;
- libertas_found++;
-#ifdef ENABLE_PM
- if (!(wlan_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, wlan_pm_callback)))
- lbs_pr_alert( "failed to register PM callback\n");
-#endif
- if (device_create_file(&(mesh_dev->dev), &dev_attr_libertas_mpp))
- goto err_create_file;
-
- LEAVE();
- return priv;
+ ret = 0;
+ goto done;
-err_create_file:
- device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
err_init_fw:
- libertas_sbi_unregister_dev(priv);
+ priv->hw_unregister_dev(priv);
err_registerdev:
destroy_workqueue(priv->assoc_thread);
/* Stop the thread servicing the interrupts */
wake_up_interruptible(&priv->mainthread.waitq);
wlan_terminate_thread(&priv->mainthread);
- kfree(priv->adapter);
-err_kmalloc:
- free_netdev(dev);
+done:
+ lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(libertas_activate_card);
+
+
+/**
+ * @brief This function adds mshX interface
+ *
+ * @param priv A pointer to the wlan_private structure
+ * @return 0 if successful, -X otherwise
+ */
+int libertas_add_mesh(wlan_private *priv, struct device *dev)
+{
+ struct net_device *mesh_dev = NULL;
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_MESH);
+
+ /* Allocate a virtual mesh device */
+ if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
+ lbs_deb_mesh("init mshX device failed\n");
+ ret = -ENOMEM;
+ goto done;
+ }
+ mesh_dev->priv = priv;
+ priv->mesh_dev = mesh_dev;
+
+ SET_MODULE_OWNER(mesh_dev);
+
+ mesh_dev->open = mesh_open;
+ mesh_dev->hard_start_xmit = mesh_pre_start_xmit;
+ mesh_dev->stop = mesh_close;
+ mesh_dev->do_ioctl = libertas_do_ioctl;
+ mesh_dev->get_stats = wlan_get_stats;
+ mesh_dev->set_mac_address = wlan_set_mac_address;
+ mesh_dev->ethtool_ops = &libertas_ethtool_ops;
+ memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
+ sizeof(priv->dev->dev_addr));
+
+ SET_NETDEV_DEV(priv->mesh_dev, dev);
+
+#ifdef WIRELESS_EXT
+ mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
+#endif
+#define NETIF_F_DYNALLOC 16
+
+ /* Register virtual mesh interface */
+ ret = register_netdev(mesh_dev);
+ if (ret) {
+ lbs_pr_err("cannot register mshX virtual interface\n");
+ goto err_free;
+ }
+
+ ret = device_create_file(&(mesh_dev->dev), &dev_attr_anycast_mask);
+ if (ret)
+ goto err_unregister;
+
+ /* Everything successful */
+ ret = 0;
+ goto done;
+
+
+err_unregister:
+ unregister_netdev(mesh_dev);
+
+err_free:
free_netdev(mesh_dev);
- wlanpriv = NULL;
- LEAVE();
- return NULL;
+done:
+ lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+ return ret;
}
+EXPORT_SYMBOL_GPL(libertas_add_mesh);
static void wake_pending_cmdnodes(wlan_private *priv)
{
struct cmd_ctrl_node *cmdnode;
unsigned long flags;
+ lbs_deb_enter(LBS_DEB_CMD);
+
spin_lock_irqsave(&priv->adapter->driver_lock, flags);
list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
cmdnode->cmdwaitqwoken = 1;
@@ -1044,40 +976,29 @@ static void wake_pending_cmdnodes(wlan_private *priv)
}
-int wlan_remove_card(void *card)
+int libertas_remove_card(wlan_private *priv)
{
- wlan_private *priv = libertas_sbi_get_priv(card);
wlan_adapter *adapter;
struct net_device *dev;
- struct net_device *mesh_dev;
union iwreq_data wrqu;
- int i;
- ENTER();
+ lbs_deb_enter(LBS_DEB_NET);
- if (!priv) {
- LEAVE();
- return 0;
- }
+ if (!priv)
+ goto out;
adapter = priv->adapter;
- if (!adapter) {
- LEAVE();
- return 0;
- }
+ if (!adapter)
+ goto out;
- dev = priv->wlan_dev.netdev;
- mesh_dev = priv->mesh_dev;
+ dev = priv->dev;
- netif_stop_queue(mesh_dev);
- netif_stop_queue(priv->wlan_dev.netdev);
- netif_carrier_off(priv->wlan_dev.netdev);
+ netif_stop_queue(priv->dev);
+ netif_carrier_off(priv->dev);
wake_pending_cmdnodes(priv);
- device_remove_file(&(mesh_dev->dev), &dev_attr_libertas_mpp);
- unregister_netdev(mesh_dev);
unregister_netdev(dev);
cancel_delayed_work(&priv->assoc_work);
@@ -1090,11 +1011,7 @@ int wlan_remove_card(void *card)
memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
-
-#ifdef ENABLE_PM
- pm_unregister(wlan_pm_dev);
-#endif
+ wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
adapter->surpriseremoved = 1;
@@ -1103,28 +1020,45 @@ int wlan_remove_card(void *card)
libertas_debugfs_remove_one(priv);
- lbs_pr_debug(1, "Free adapter\n");
+ lbs_deb_net("free adapter\n");
libertas_free_adapter(priv);
- for (i = 0; i<libertas_found; i++) {
- if (libertas_devs[i]==priv->wlan_dev.netdev) {
- libertas_devs[i] = libertas_devs[--libertas_found];
- libertas_devs[libertas_found] = NULL ;
- break ;
- }
- }
+ lbs_deb_net("unregister finish\n");
+
+ priv->dev = NULL;
+ free_netdev(dev);
+
+out:
+ lbs_deb_leave(LBS_DEB_NET);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(libertas_remove_card);
+
+
+void libertas_remove_mesh(wlan_private *priv)
+{
+ struct net_device *mesh_dev;
+
+ lbs_deb_enter(LBS_DEB_NET);
+
+ if (!priv)
+ goto out;
+
+ mesh_dev = priv->mesh_dev;
+
+ netif_stop_queue(mesh_dev);
+ netif_carrier_off(priv->mesh_dev);
- lbs_pr_debug(1, "Unregister finish\n");
+ device_remove_file(&(mesh_dev->dev), &dev_attr_anycast_mask);
+ unregister_netdev(mesh_dev);
- priv->wlan_dev.netdev = NULL;
priv->mesh_dev = NULL ;
free_netdev(mesh_dev);
- free_netdev(dev);
- wlanpriv = NULL;
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave(LBS_DEB_NET);
}
+EXPORT_SYMBOL_GPL(libertas_remove_mesh);
/**
* @brief This function finds the CFP in
@@ -1139,33 +1073,34 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c
{
int i, end;
- ENTER();
+ lbs_deb_enter(LBS_DEB_MAIN);
end = sizeof(region_cfp_table)/sizeof(struct region_cfp_table);
for (i = 0; i < end ; i++) {
- lbs_pr_debug(1, "region_cfp_table[i].region=%d\n",
+ lbs_deb_main("region_cfp_table[i].region=%d\n",
region_cfp_table[i].region);
if (region_cfp_table[i].region == region) {
*cfp_no = region_cfp_table[i].cfp_no_BG;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_MAIN);
return region_cfp_table[i].cfp_BG;
}
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
return NULL;
}
int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
{
wlan_adapter *adapter = priv->adapter;
+ int ret = 0;
int i = 0;
struct chan_freq_power *cfp;
int cfp_no;
- ENTER();
+ lbs_deb_enter(LBS_DEB_MAIN);
memset(adapter->region_channel, 0, sizeof(adapter->region_channel));
@@ -1175,17 +1110,19 @@ int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
adapter->region_channel[i].nrcfp = cfp_no;
adapter->region_channel[i].CFP = cfp;
} else {
- lbs_pr_debug(1, "wrong region code %#x in band B-G\n",
+ lbs_deb_main("wrong region code %#x in band B/G\n",
region);
- return -1;
+ ret = -1;
+ goto out;
}
adapter->region_channel[i].valid = 1;
adapter->region_channel[i].region = region;
adapter->region_channel[i].band = band;
i++;
}
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
+ return ret;
}
/**
@@ -1200,9 +1137,9 @@ void libertas_interrupt(struct net_device *dev)
{
wlan_private *priv = dev->priv;
- ENTER();
+ lbs_deb_enter(LBS_DEB_THREAD);
- lbs_pr_debug(1, "libertas_interrupt: intcounter=%d\n",
+ lbs_deb_thread("libertas_interrupt: intcounter=%d\n",
priv->adapter->intcounter);
priv->adapter->intcounter++;
@@ -1210,56 +1147,35 @@ void libertas_interrupt(struct net_device *dev)
if (priv->adapter->psstate == PS_STATE_SLEEP) {
priv->adapter->psstate = PS_STATE_AWAKE;
netif_wake_queue(dev);
+ netif_wake_queue(priv->mesh_dev);
}
wake_up_interruptible(&priv->mainthread.waitq);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_THREAD);
}
+EXPORT_SYMBOL_GPL(libertas_interrupt);
-static int wlan_init_module(void)
+static int libertas_init_module(void)
{
- int ret = 0;
-
- ENTER();
-
- if (libertas_fw_name == NULL) {
- libertas_fw_name = default_fw_name;
- }
-
+ lbs_deb_enter(LBS_DEB_MAIN);
libertas_debugfs_init();
-
- if (libertas_sbi_register()) {
- ret = -1;
- libertas_debugfs_remove();
- goto done;
- }
-
-done:
- LEAVE();
- return ret;
+ lbs_deb_leave(LBS_DEB_MAIN);
+ return 0;
}
-static void wlan_cleanup_module(void)
+static void libertas_exit_module(void)
{
- int i;
-
- ENTER();
-
- for (i = 0; i<libertas_found; i++) {
- wlan_private *priv = libertas_devs[i]->priv;
- reset_device(priv);
- }
+ lbs_deb_enter(LBS_DEB_MAIN);
- libertas_sbi_unregister();
libertas_debugfs_remove();
- LEAVE();
+ lbs_deb_leave(LBS_DEB_MAIN);
}
-module_init(wlan_init_module);
-module_exit(wlan_cleanup_module);
+module_init(libertas_init_module);
+module_exit(libertas_exit_module);
-MODULE_DESCRIPTION("M-WLAN Driver");
+MODULE_DESCRIPTION("Libertas WLAN Driver Library");
MODULE_AUTHOR("Marvell International Ltd.");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index d17924f764e..88d9d2d787d 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -106,10 +106,10 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
{
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_RX);
- lbs_pr_debug(1, "rxpd: SNR = %d, NF = %d\n", p_rx_pd->snr, p_rx_pd->nf);
- lbs_pr_debug(1, "Before computing SNR: SNR- avg = %d, NF-avg = %d\n",
+ lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf);
+ lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n",
adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
@@ -121,7 +121,7 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE;
adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE;
- lbs_pr_debug(1, "After computing SNR: SNR-avg = %d, NF-avg = %d\n",
+ lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n",
adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
@@ -133,23 +133,20 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_RX);
}
-int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
+void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
{
- lbs_pr_debug(1, "skb->data=%p\n", skb->data);
+ lbs_deb_rx("skb->data %p\n", skb->data);
- if(IS_MESH_FRAME(skb))
- skb->dev = priv->mesh_dev;
+ if (priv->mesh_dev && IS_MESH_FRAME(skb))
+ skb->protocol = eth_type_trans(skb, priv->mesh_dev);
else
- skb->dev = priv->wlan_dev.netdev;
- skb->protocol = eth_type_trans(skb, priv->wlan_dev.netdev);
+ skb->protocol = eth_type_trans(skb, priv->dev);
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx(skb);
-
- return 0;
}
/**
@@ -173,7 +170,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
- ENTER();
+ lbs_deb_enter(LBS_DEB_RX);
if (priv->adapter->debugmode & MRVDRV_DEBUG_RX_PATH)
lbs_dbg_hex("RX packet: ", skb->data,
@@ -193,7 +190,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
min_t(unsigned int, skb->len, 100));
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
- lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n");
+ lbs_deb_rx("rx err: frame received with bad length\n");
priv->stats.rx_length_errors++;
ret = 0;
goto done;
@@ -202,15 +199,15 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
/*
* Check rxpd status and update 802.3 stat,
*/
- if (!(p_rx_pd->status & MRVDRV_RXPD_STATUS_OK)) {
- lbs_pr_debug(1, "RX error: frame received with bad status\n");
- lbs_pr_alert("rxpd Not OK\n");
+ if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
+ lbs_deb_rx("rx err: frame received with bad status\n");
+ lbs_pr_alert("rxpd not ok\n");
priv->stats.rx_errors++;
ret = 0;
goto done;
}
- lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
+ lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
@@ -268,22 +265,18 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
wlan_compute_rssi(priv, p_rx_pd);
- lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
- if (libertas_upload_rx_packet(priv, skb)) {
- lbs_pr_debug(1, "RX error: libertas_upload_rx_packet"
- " returns failure\n");
- ret = -1;
- goto done;
- }
+ lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
+ libertas_upload_rx_packet(priv, skb);
+
ret = 0;
done:
- LEAVE();
-
+ lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
return ret;
}
+EXPORT_SYMBOL_GPL(libertas_process_rxed_packet);
/**
* @brief This function converts Tx/Rx rates from the Marvell WLAN format
@@ -320,7 +313,7 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
case 11: /* 54 Mbps */
return 108;
}
- lbs_pr_alert( "Invalid Marvell WLAN rate (%i)\n", rate);
+ lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate);
return 0;
}
@@ -342,7 +335,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
struct rx_radiotap_hdr radiotap_hdr;
struct rx_radiotap_hdr *pradiotap_hdr;
- ENTER();
+ lbs_deb_enter(LBS_DEB_RX);
p_rx_pkt = (struct rx80211packethdr *) skb->data;
prxpd = &p_rx_pkt->rx_pd;
@@ -350,7 +343,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
// lbs_dbg_hex("RX Data: Before chop rxpd", skb->data, min(skb->len, 100));
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
- lbs_pr_debug(1, "RX error: FRAME RECEIVED WITH BAD LENGTH\n");
+ lbs_deb_rx("rx err: frame received wit bad length\n");
priv->stats.rx_length_errors++;
ret = 0;
goto done;
@@ -359,12 +352,12 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
/*
* Check rxpd status and update 802.3 stat,
*/
- if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK)) {
- //lbs_pr_debug(1, "RX error: frame received with bad status\n");
+ if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
+ //lbs_deb_rx("rx err: frame received with bad status\n");
priv->stats.rx_errors++;
}
- lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
+ lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
/* create the exported radio header */
@@ -392,7 +385,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
/* XXX must check no carryout */
radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
radiotap_hdr.rx_flags = 0;
- if (!(prxpd->status & MRVDRV_RXPD_STATUS_OK))
+ if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
//memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
@@ -405,7 +398,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
GFP_ATOMIC)) {
- lbs_pr_alert( "%s: couldn't pskb_expand_head\n",
+ lbs_pr_alert("%s: couldn't pskb_expand_head\n",
__func__);
}
@@ -420,7 +413,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
default:
/* unknown header */
- lbs_pr_alert( "Unknown radiomode (%i)\n",
+ lbs_pr_alert("Unknown radiomode %i\n",
priv->adapter->radiomode);
/* don't export any header */
/* chop the rxpd */
@@ -437,23 +430,16 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
wlan_compute_rssi(priv, prxpd);
- lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
-
- if (libertas_upload_rx_packet(priv, skb)) {
- lbs_pr_debug(1, "RX error: libertas_upload_rx_packet "
- "returns failure\n");
- ret = -1;
- goto done;
- }
-
+ lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
+ libertas_upload_rx_packet(priv, skb);
+
ret = 0;
-done:
- LEAVE();
+done:
skb->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */
-
- return (ret);
+ lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
+ return ret;
}
diff --git a/drivers/net/wireless/libertas/sbi.h b/drivers/net/wireless/libertas/sbi.h
deleted file mode 100644
index 59d3a59ccef..00000000000
--- a/drivers/net/wireless/libertas/sbi.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * This file contains IF layer definitions.
- */
-
-#ifndef _SBI_H_
-#define _SBI_H_
-
-#include <linux/interrupt.h>
-
-#include "defs.h"
-
-/** INT status Bit Definition*/
-#define his_cmddnldrdy 0x01
-#define his_cardevent 0x02
-#define his_cmdupldrdy 0x04
-
-#ifndef DEV_NAME_LEN
-#define DEV_NAME_LEN 32
-#endif
-
-#define SBI_EVENT_CAUSE_SHIFT 3
-
-/* Probe and Check if the card is present*/
-int libertas_sbi_register_dev(wlan_private * priv);
-int libertas_sbi_unregister_dev(wlan_private *);
-int libertas_sbi_get_int_status(wlan_private * priv, u8 *);
-int libertas_sbi_register(void);
-void libertas_sbi_unregister(void);
-int libertas_sbi_prog_firmware(wlan_private *);
-
-int libertas_sbi_read_event_cause(wlan_private *);
-int libertas_sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
-wlan_private *libertas_sbi_get_priv(void *card);
-
-#ifdef ENABLE_PM
-int libertas_sbi_suspend(wlan_private *);
-int libertas_sbi_resume(wlan_private *);
-#endif
-
-#endif /* _SBI_H */
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 3c0b1a2a172..606af50fa09 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -8,6 +8,7 @@
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
+#include <linux/etherdevice.h>
#include <net/ieee80211.h>
#include <net/iw_handler.h>
@@ -58,12 +59,82 @@
//! Scan time specified in the channel TLV for each channel for active scans
#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
-//! Macro to enable/disable SSID checking before storing a scan table
-#ifdef DISCARD_BAD_SSID
-#define CHECK_SSID_IS_VALID(x) ssid_valid(&bssidEntry.ssid)
-#else
-#define CHECK_SSID_IS_VALID(x) 1
-#endif
+static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+static inline void clear_bss_descriptor (struct bss_descriptor * bss)
+{
+ /* Don't blow away ->list, just BSS data */
+ memset(bss, 0, offsetof(struct bss_descriptor, list));
+}
+
+static inline int match_bss_no_security(struct wlan_802_11_security * secinfo,
+ struct bss_descriptor * match_bss)
+{
+ if ( !secinfo->wep_enabled
+ && !secinfo->WPAenabled
+ && !secinfo->WPA2enabled
+ && match_bss->wpa_ie[0] != WPA_IE
+ && match_bss->rsn_ie[0] != WPA2_IE
+ && !match_bss->privacy) {
+ return 1;
+ }
+ return 0;
+}
+
+static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo,
+ struct bss_descriptor * match_bss)
+{
+ if ( secinfo->wep_enabled
+ && !secinfo->WPAenabled
+ && !secinfo->WPA2enabled
+ && match_bss->privacy) {
+ return 1;
+ }
+ return 0;
+}
+
+static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
+ struct bss_descriptor * match_bss)
+{
+ if ( !secinfo->wep_enabled
+ && secinfo->WPAenabled
+ && (match_bss->wpa_ie[0] == WPA_IE)
+ /* privacy bit may NOT be set in some APs like LinkSys WRT54G
+ && bss->privacy */
+ ) {
+ return 1;
+ }
+ return 0;
+}
+
+static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
+ struct bss_descriptor * match_bss)
+{
+ if ( !secinfo->wep_enabled
+ && secinfo->WPA2enabled
+ && (match_bss->rsn_ie[0] == WPA2_IE)
+ /* privacy bit may NOT be set in some APs like LinkSys WRT54G
+ && bss->privacy */
+ ) {
+ return 1;
+ }
+ return 0;
+}
+
+static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
+ struct bss_descriptor * match_bss)
+{
+ if ( !secinfo->wep_enabled
+ && !secinfo->WPAenabled
+ && !secinfo->WPA2enabled
+ && (match_bss->wpa_ie[0] != WPA_IE)
+ && (match_bss->rsn_ie[0] != WPA2_IE)
+ && match_bss->privacy) {
+ return 1;
+ }
+ return 0;
+}
/**
* @brief Check if a scanned network compatible with the driver settings
@@ -84,123 +155,63 @@
*
* @return Index in scantable, or error code if negative
*/
-static int is_network_compatible(wlan_adapter * adapter, int index, u8 mode)
+static int is_network_compatible(wlan_adapter * adapter,
+ struct bss_descriptor * bss, u8 mode)
{
- ENTER();
-
- if (adapter->scantable[index].mode == mode) {
- if ( !adapter->secinfo.wep_enabled
- && !adapter->secinfo.WPAenabled
- && !adapter->secinfo.WPA2enabled
- && adapter->scantable[index].wpa_ie[0] != WPA_IE
- && adapter->scantable[index].rsn_ie[0] != WPA2_IE
- && !adapter->scantable[index].privacy) {
- /* no security */
- LEAVE();
- return index;
- } else if ( adapter->secinfo.wep_enabled
- && !adapter->secinfo.WPAenabled
- && !adapter->secinfo.WPA2enabled
- && adapter->scantable[index].privacy) {
- /* static WEP enabled */
- LEAVE();
- return index;
- } else if ( !adapter->secinfo.wep_enabled
- && adapter->secinfo.WPAenabled
- && !adapter->secinfo.WPA2enabled
- && (adapter->scantable[index].wpa_ie[0] == WPA_IE)
- /* privacy bit may NOT be set in some APs like LinkSys WRT54G
- && adapter->scantable[index].privacy */
- ) {
- /* WPA enabled */
- lbs_pr_debug(1,
- "is_network_compatible() WPA: index=%d wpa_ie=%#x "
- "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
- "privacy=%#x\n", index,
- adapter->scantable[index].wpa_ie[0],
- adapter->scantable[index].rsn_ie[0],
- adapter->secinfo.wep_enabled ? "e" : "d",
- adapter->secinfo.WPAenabled ? "e" : "d",
- adapter->secinfo.WPA2enabled ? "e" : "d",
- adapter->scantable[index].privacy);
- LEAVE();
- return index;
- } else if ( !adapter->secinfo.wep_enabled
- && !adapter->secinfo.WPAenabled
- && adapter->secinfo.WPA2enabled
- && (adapter->scantable[index].rsn_ie[0] == WPA2_IE)
- /* privacy bit may NOT be set in some APs like LinkSys WRT54G
- && adapter->scantable[index].privacy */
- ) {
- /* WPA2 enabled */
- lbs_pr_debug(1,
- "is_network_compatible() WPA2: index=%d wpa_ie=%#x "
- "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
- "privacy=%#x\n", index,
- adapter->scantable[index].wpa_ie[0],
- adapter->scantable[index].rsn_ie[0],
- adapter->secinfo.wep_enabled ? "e" : "d",
- adapter->secinfo.WPAenabled ? "e" : "d",
- adapter->secinfo.WPA2enabled ? "e" : "d",
- adapter->scantable[index].privacy);
- LEAVE();
- return index;
- } else if ( !adapter->secinfo.wep_enabled
- && !adapter->secinfo.WPAenabled
- && !adapter->secinfo.WPA2enabled
- && (adapter->scantable[index].wpa_ie[0] != WPA_IE)
- && (adapter->scantable[index].rsn_ie[0] != WPA2_IE)
- && adapter->scantable[index].privacy) {
- /* dynamic WEP enabled */
- lbs_pr_debug(1,
- "is_network_compatible() dynamic WEP: index=%d "
- "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
- index,
- adapter->scantable[index].wpa_ie[0],
- adapter->scantable[index].rsn_ie[0],
- adapter->scantable[index].privacy);
- LEAVE();
- return index;
- }
-
- /* security doesn't match */
- lbs_pr_debug(1,
- "is_network_compatible() FAILED: index=%d wpa_ie=%#x "
- "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
- index,
- adapter->scantable[index].wpa_ie[0],
- adapter->scantable[index].rsn_ie[0],
+ int matched = 0;
+
+ lbs_deb_enter(LBS_DEB_ASSOC);
+
+ if (bss->mode != mode)
+ goto done;
+
+ if ((matched = match_bss_no_security(&adapter->secinfo, bss))) {
+ goto done;
+ } else if ((matched = match_bss_static_wep(&adapter->secinfo, bss))) {
+ goto done;
+ } else if ((matched = match_bss_wpa(&adapter->secinfo, bss))) {
+ lbs_deb_scan(
+ "is_network_compatible() WPA: wpa_ie=%#x "
+ "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
+ "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
adapter->secinfo.wep_enabled ? "e" : "d",
adapter->secinfo.WPAenabled ? "e" : "d",
adapter->secinfo.WPA2enabled ? "e" : "d",
- adapter->scantable[index].privacy);
- LEAVE();
- return -ECONNREFUSED;
- }
-
- /* mode doesn't match */
- LEAVE();
- return -ENETUNREACH;
-}
-
-/**
- * @brief This function validates a SSID as being able to be printed
- *
- * @param pssid SSID structure to validate
- *
- * @return TRUE or FALSE
- */
-static u8 ssid_valid(struct WLAN_802_11_SSID *pssid)
-{
- int ssididx;
-
- for (ssididx = 0; ssididx < pssid->ssidlength; ssididx++) {
- if (!isprint(pssid->ssid[ssididx])) {
- return 0;
- }
+ bss->privacy);
+ goto done;
+ } else if ((matched = match_bss_wpa2(&adapter->secinfo, bss))) {
+ lbs_deb_scan(
+ "is_network_compatible() WPA2: wpa_ie=%#x "
+ "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
+ "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
+ adapter->secinfo.wep_enabled ? "e" : "d",
+ adapter->secinfo.WPAenabled ? "e" : "d",
+ adapter->secinfo.WPA2enabled ? "e" : "d",
+ bss->privacy);
+ goto done;
+ } else if ((matched = match_bss_dynamic_wep(&adapter->secinfo, bss))) {
+ lbs_deb_scan(
+ "is_network_compatible() dynamic WEP: "
+ "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
+ bss->wpa_ie[0],
+ bss->rsn_ie[0],
+ bss->privacy);
+ goto done;
}
- return 1;
+ /* bss security settings don't match those configured on card */
+ lbs_deb_scan(
+ "is_network_compatible() FAILED: wpa_ie=%#x "
+ "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
+ bss->wpa_ie[0], bss->rsn_ie[0],
+ adapter->secinfo.wep_enabled ? "e" : "d",
+ adapter->secinfo.WPAenabled ? "e" : "d",
+ adapter->secinfo.WPA2enabled ? "e" : "d",
+ bss->privacy);
+
+done:
+ lbs_deb_leave(LBS_DEB_SCAN);
+ return matched;
}
/**
@@ -220,44 +231,19 @@ static u8 ssid_valid(struct WLAN_802_11_SSID *pssid)
static void wlan_scan_process_results(wlan_private * priv)
{
wlan_adapter *adapter = priv->adapter;
- int foundcurrent;
- int i;
-
- foundcurrent = 0;
-
- if (adapter->connect_status == libertas_connected) {
- /* try to find the current BSSID in the new scan list */
- for (i = 0; i < adapter->numinscantable; i++) {
- if (!libertas_SSID_cmp(&adapter->scantable[i].ssid,
- &adapter->curbssparams.ssid) &&
- !memcmp(adapter->curbssparams.bssid,
- adapter->scantable[i].macaddress,
- ETH_ALEN)) {
- foundcurrent = 1;
- }
- }
+ struct bss_descriptor * iter_bss;
+ int i = 0;
- if (foundcurrent) {
- /* Make a copy of current BSSID descriptor */
- memcpy(&adapter->curbssparams.bssdescriptor,
- &adapter->scantable[i],
- sizeof(adapter->curbssparams.bssdescriptor));
- }
- }
+ if (adapter->connect_status == libertas_connected)
+ return;
- for (i = 0; i < adapter->numinscantable; i++) {
- lbs_pr_debug(1, "Scan:(%02d) %02x:%02x:%02x:%02x:%02x:%02x, "
- "RSSI[%03d], SSID[%s]\n",
- i,
- adapter->scantable[i].macaddress[0],
- adapter->scantable[i].macaddress[1],
- adapter->scantable[i].macaddress[2],
- adapter->scantable[i].macaddress[3],
- adapter->scantable[i].macaddress[4],
- adapter->scantable[i].macaddress[5],
- (s32) adapter->scantable[i].rssi,
- adapter->scantable[i].ssid.ssid);
+ mutex_lock(&adapter->lock);
+ list_for_each_entry (iter_bss, &adapter->network_list, list) {
+ lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n",
+ i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi,
+ escape_essid(iter_bss->ssid, iter_bss->ssid_len));
}
+ mutex_unlock(&adapter->lock);
}
/**
@@ -338,14 +324,12 @@ static void wlan_scan_create_channel_list(wlan_private * priv,
if (scantype == cmd_scan_type_passive) {
scanchanlist[chanidx].maxscantime =
- cpu_to_le16
- (MRVDRV_PASSIVE_SCAN_CHAN_TIME);
+ cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME);
scanchanlist[chanidx].chanscanmode.passivescan =
1;
} else {
scanchanlist[chanidx].maxscantime =
- cpu_to_le16
- (MRVDRV_ACTIVE_SCAN_CHAN_TIME);
+ cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME);
scanchanlist[chanidx].chanscanmode.passivescan =
0;
}
@@ -408,13 +392,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
u8 * pscancurrentonly)
{
wlan_adapter *adapter = priv->adapter;
- const u8 zeromac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
struct mrvlietypes_numprobes *pnumprobestlv;
struct mrvlietypes_ssidparamset *pssidtlv;
struct wlan_scan_cmd_config * pscancfgout = NULL;
u8 *ptlvpos;
u16 numprobes;
- u16 ssidlen;
int chanidx;
int scantype;
int scandur;
@@ -471,21 +453,18 @@ wlan_scan_setup_scan_config(wlan_private * priv,
* Set the BSSID filter to the incoming configuration,
* if non-zero. If not set, it will remain disabled (all zeros).
*/
- memcpy(pscancfgout->specificBSSID,
- puserscanin->specificBSSID,
- sizeof(pscancfgout->specificBSSID));
-
- ssidlen = strlen(puserscanin->specificSSID);
+ memcpy(pscancfgout->bssid, puserscanin->bssid,
+ sizeof(pscancfgout->bssid));
- if (ssidlen) {
+ if (puserscanin->ssid_len) {
pssidtlv =
(struct mrvlietypes_ssidparamset *) pscancfgout->
tlvbuffer;
pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
- pssidtlv->header.len = cpu_to_le16(ssidlen);
- memcpy(pssidtlv->ssid, puserscanin->specificSSID,
- ssidlen);
- ptlvpos += sizeof(pssidtlv->header) + ssidlen;
+ pssidtlv->header.len = cpu_to_le16(puserscanin->ssid_len);
+ memcpy(pssidtlv->ssid, puserscanin->ssid,
+ puserscanin->ssid_len);
+ ptlvpos += sizeof(pssidtlv->header) + puserscanin->ssid_len;
}
/*
@@ -494,8 +473,8 @@ wlan_scan_setup_scan_config(wlan_private * priv,
* scan results. That is not an issue with an SSID or BSSID
* filter applied to the scan results in the firmware.
*/
- if (ssidlen || (memcmp(pscancfgout->specificBSSID,
- &zeromac, sizeof(zeromac)) != 0)) {
+ if ( puserscanin->ssid_len
+ || (compare_ether_addr(pscancfgout->bssid, &zeromac[0]) != 0)) {
*pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN;
*pfilteredscan = 1;
}
@@ -507,16 +486,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
/* If the input config or adapter has the number of Probes set, add tlv */
if (numprobes) {
pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos;
- pnumprobestlv->header.type =
- cpu_to_le16(TLV_TYPE_NUMPROBES);
- pnumprobestlv->header.len = sizeof(pnumprobestlv->numprobes);
+ pnumprobestlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
+ pnumprobestlv->header.len = cpu_to_le16(2);
pnumprobestlv->numprobes = cpu_to_le16(numprobes);
- ptlvpos +=
- sizeof(pnumprobestlv->header) + pnumprobestlv->header.len;
-
- pnumprobestlv->header.len =
- cpu_to_le16(pnumprobestlv->header.len);
+ ptlvpos += sizeof(*pnumprobestlv);
}
/*
@@ -529,7 +503,7 @@ wlan_scan_setup_scan_config(wlan_private * priv,
if (puserscanin && puserscanin->chanlist[0].channumber) {
- lbs_pr_debug(1, "Scan: Using supplied channel list\n");
+ lbs_deb_scan("Scan: Using supplied channel list\n");
for (chanidx = 0;
chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX
@@ -573,11 +547,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
==
priv->adapter->curbssparams.channel)) {
*pscancurrentonly = 1;
- lbs_pr_debug(1, "Scan: Scanning current channel only");
+ lbs_deb_scan("Scan: Scanning current channel only");
}
} else {
- lbs_pr_debug(1, "Scan: Creating full region channel list\n");
+ lbs_deb_scan("Scan: Creating full region channel list\n");
wlan_scan_create_channel_list(priv, pscanchanlist,
*pfilteredscan);
}
@@ -613,7 +587,9 @@ static int wlan_scan_channel_list(wlan_private * priv,
u8 filteredscan,
struct wlan_scan_cmd_config * pscancfgout,
struct mrvlietypes_chanlistparamset * pchantlvout,
- struct chanscanparamset * pscanchanlist)
+ struct chanscanparamset * pscanchanlist,
+ const struct wlan_ioctl_user_scan_cfg * puserscanin,
+ int full_scan)
{
struct chanscanparamset *ptmpchan;
struct chanscanparamset *pstartchan;
@@ -621,11 +597,13 @@ static int wlan_scan_channel_list(wlan_private * priv,
int doneearly;
int tlvidx;
int ret = 0;
+ int scanned = 0;
+ union iwreq_data wrqu;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
if (pscancfgout == 0 || pchantlvout == 0 || pscanchanlist == 0) {
- lbs_pr_debug(1, "Scan: Null detect: %p, %p, %p\n",
+ lbs_deb_scan("Scan: Null detect: %p, %p, %p\n",
pscancfgout, pchantlvout, pscanchanlist);
return -1;
}
@@ -635,6 +613,9 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Set the temp channel struct pointer to the start of the desired list */
ptmpchan = pscanchanlist;
+ if (priv->adapter->last_scanned_channel && !puserscanin)
+ ptmpchan += priv->adapter->last_scanned_channel;
+
/* Loop through the desired channel list, sending a new firmware scan
* commands for each maxchanperscan channels (or for 1,6,11 individually
* if configured accordingly)
@@ -654,9 +635,9 @@ static int wlan_scan_channel_list(wlan_private * priv,
* - doneearly is set (controlling individual scanning of 1,6,11)
*/
while (tlvidx < maxchanperscan && ptmpchan->channumber
- && !doneearly) {
+ && !doneearly && scanned < 2) {
- lbs_pr_debug(1,
+ lbs_deb_scan(
"Scan: Chan(%3d), Radio(%d), mode(%d,%d), Dur(%d)\n",
ptmpchan->channumber, ptmpchan->radiotype,
ptmpchan->chanscanmode.passivescan,
@@ -668,8 +649,11 @@ static int wlan_scan_channel_list(wlan_private * priv,
ptmpchan, sizeof(pchantlvout->chanscanparam));
/* Increment the TLV header length by the size appended */
- pchantlvout->header.len +=
- sizeof(pchantlvout->chanscanparam);
+ /* Ew, it would be _so_ nice if we could just declare the
+ variable little-endian and let GCC handle it for us */
+ pchantlvout->header.len =
+ cpu_to_le16(le16_to_cpu(pchantlvout->header.len) +
+ sizeof(pchantlvout->chanscanparam));
/*
* The tlv buffer length is set to the number of bytes of the
@@ -683,7 +667,7 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Add the size of the channel tlv header and the data length */
pscancfgout->tlvbufferlen +=
(sizeof(pchantlvout->header)
- + pchantlvout->header.len);
+ + le16_to_cpu(pchantlvout->header.len));
/* Increment the index to the channel tlv we are constructing */
tlvidx++;
@@ -701,6 +685,7 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Increment the tmp pointer to the next channel to be scanned */
ptmpchan++;
+ scanned++;
/* Stop the loop if the *next* channel is in the 1,6,11 set.
* This will cause it to be the only channel scanned on the next
@@ -716,12 +701,71 @@ static int wlan_scan_channel_list(wlan_private * priv,
/* Send the scan command to the firmware with the specified cfg */
ret = libertas_prepare_and_send_command(priv, cmd_802_11_scan, 0,
0, 0, pscancfgout);
+ if (scanned >= 2 && !full_scan) {
+ ret = 0;
+ goto done;
+ }
+ scanned = 0;
}
- LEAVE();
+done:
+ priv->adapter->last_scanned_channel = ptmpchan->channumber;
+
+ /* Tell userspace the scan table has been updated */
+ memset(&wrqu, 0, sizeof(union iwreq_data));
+ wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
+
+ lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
+static void
+clear_selected_scan_list_entries(wlan_adapter * adapter,
+ const struct wlan_ioctl_user_scan_cfg * scan_cfg)
+{
+ struct bss_descriptor * bss;
+ struct bss_descriptor * safe;
+ u32 clear_ssid_flag = 0, clear_bssid_flag = 0;
+
+ if (!scan_cfg)
+ return;
+
+ if (scan_cfg->clear_ssid && scan_cfg->ssid_len)
+ clear_ssid_flag = 1;
+
+ if (scan_cfg->clear_bssid
+ && (compare_ether_addr(scan_cfg->bssid, &zeromac[0]) != 0)
+ && (compare_ether_addr(scan_cfg->bssid, &bcastmac[0]) != 0)) {
+ clear_bssid_flag = 1;
+ }
+
+ if (!clear_ssid_flag && !clear_bssid_flag)
+ return;
+
+ mutex_lock(&adapter->lock);
+ list_for_each_entry_safe (bss, safe, &adapter->network_list, list) {
+ u32 clear = 0;
+
+ /* Check for an SSID match */
+ if ( clear_ssid_flag
+ && (bss->ssid_len == scan_cfg->ssid_len)
+ && !memcmp(bss->ssid, scan_cfg->ssid, bss->ssid_len))
+ clear = 1;
+
+ /* Check for a BSSID match */
+ if ( clear_bssid_flag
+ && !compare_ether_addr(bss->bssid, scan_cfg->bssid))
+ clear = 1;
+
+ if (clear) {
+ list_move_tail (&bss->list, &adapter->network_free_list);
+ clear_bss_descriptor(bss);
+ }
+ }
+ mutex_unlock(&adapter->lock);
+}
+
+
/**
* @brief Internal function used to start a scan based on an input config
*
@@ -736,19 +780,19 @@ static int wlan_scan_channel_list(wlan_private * priv,
* @return 0 or < 0 if error
*/
int wlan_scan_networks(wlan_private * priv,
- const struct wlan_ioctl_user_scan_cfg * puserscanin)
+ const struct wlan_ioctl_user_scan_cfg * puserscanin,
+ int full_scan)
{
- wlan_adapter *adapter = priv->adapter;
+ wlan_adapter * adapter = priv->adapter;
struct mrvlietypes_chanlistparamset *pchantlvout;
struct chanscanparamset * scan_chan_list = NULL;
struct wlan_scan_cmd_config * scan_cfg = NULL;
- u8 keeppreviousscan;
u8 filteredscan;
u8 scancurrentchanonly;
int maxchanperscan;
int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
scan_chan_list = kzalloc(sizeof(struct chanscanparamset) *
WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
@@ -769,22 +813,14 @@ int wlan_scan_networks(wlan_private * priv,
goto out;
}
- keeppreviousscan = 0;
-
- if (puserscanin) {
- keeppreviousscan = puserscanin->keeppreviousscan;
- }
-
- if (!keeppreviousscan) {
- memset(adapter->scantable, 0x00,
- sizeof(struct bss_descriptor) * MRVDRV_MAX_BSSID_LIST);
- adapter->numinscantable = 0;
- }
+ clear_selected_scan_list_entries(adapter, puserscanin);
/* Keep the data path active if we are only scanning our current channel */
if (!scancurrentchanonly) {
- netif_stop_queue(priv->wlan_dev.netdev);
- netif_carrier_off(priv->wlan_dev.netdev);
+ netif_stop_queue(priv->dev);
+ netif_carrier_off(priv->dev);
+ netif_stop_queue(priv->mesh_dev);
+ netif_carrier_off(priv->mesh_dev);
}
ret = wlan_scan_channel_list(priv,
@@ -792,7 +828,9 @@ int wlan_scan_networks(wlan_private * priv,
filteredscan,
scan_cfg,
pchantlvout,
- scan_chan_list);
+ scan_chan_list,
+ puserscanin,
+ full_scan);
/* Process the resulting scan table:
* - Remove any bad ssids
@@ -801,8 +839,10 @@ int wlan_scan_networks(wlan_private * priv,
wlan_scan_process_results(priv);
if (priv->adapter->connect_status == libertas_connected) {
- netif_carrier_on(priv->wlan_dev.netdev);
- netif_wake_queue(priv->wlan_dev.netdev);
+ netif_carrier_on(priv->dev);
+ netif_wake_queue(priv->dev);
+ netif_carrier_on(priv->mesh_dev);
+ netif_wake_queue(priv->mesh_dev);
}
out:
@@ -812,7 +852,7 @@ out:
if (scan_chan_list)
kfree(scan_chan_list);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
@@ -843,7 +883,7 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
tlvbufleft = tlvbufsize;
*ptsftlv = NULL;
- lbs_pr_debug(1, "SCAN_RESP: tlvbufsize = %d\n", tlvbufsize);
+ lbs_deb_scan("SCAN_RESP: tlvbufsize = %d\n", tlvbufsize);
lbs_dbg_hex("SCAN_RESP: TLV Buf", (u8 *) ptlv, tlvbufsize);
while (tlvbufleft >= sizeof(struct mrvlietypesheader)) {
@@ -856,7 +896,7 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
break;
default:
- lbs_pr_debug(1, "SCAN_RESP: Unhandled TLV = %d\n",
+ lbs_deb_scan("SCAN_RESP: Unhandled TLV = %d\n",
tlvtype);
/* Give up, this seems corrupted */
return;
@@ -875,12 +915,12 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
* response or beacon from the scan command. Record information as needed
* in the scan table struct bss_descriptor for that entry.
*
- * @param pBSSIDEntry Output parameter: Pointer to the BSS Entry
+ * @param bss Output parameter: Pointer to the BSS Entry
*
* @return 0 or -1
*/
-static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
- u8 ** pbeaconinfo, int *bytesleft)
+static int libertas_process_bss(struct bss_descriptor * bss,
+ u8 ** pbeaconinfo, int *bytesleft)
{
enum ieeetypes_elementid elemID;
struct ieeetypes_fhparamset *pFH;
@@ -897,13 +937,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
u16 beaconsize;
u8 founddatarateie;
int bytesleftforcurrentbeacon;
+ int ret;
struct IE_WPA *pIe;
const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
struct ieeetypes_countryinfoset *pcountryinfo;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
founddatarateie = 0;
ratesize = 0;
@@ -911,8 +952,7 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
if (*bytesleft >= sizeof(beaconsize)) {
/* Extract & convert beacon size from the command buffer */
- memcpy(&beaconsize, *pbeaconinfo, sizeof(beaconsize));
- beaconsize = le16_to_cpu(beaconsize);
+ beaconsize = le16_to_cpup((void *)*pbeaconinfo);
*bytesleft -= sizeof(beaconsize);
*pbeaconinfo += sizeof(beaconsize);
}
@@ -934,17 +974,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
bytesleftforcurrentbeacon = beaconsize;
- memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN);
- lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n",
- pBSSEntry->macaddress[0], pBSSEntry->macaddress[1],
- pBSSEntry->macaddress[2], pBSSEntry->macaddress[3],
- pBSSEntry->macaddress[4], pBSSEntry->macaddress[5]);
+ memcpy(bss->bssid, pcurrentptr, ETH_ALEN);
+ lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid));
pcurrentptr += ETH_ALEN;
bytesleftforcurrentbeacon -= ETH_ALEN;
if (bytesleftforcurrentbeacon < 12) {
- lbs_pr_debug(1, "InterpretIE: Not enough bytes left\n");
+ lbs_deb_scan("process_bss: Not enough bytes left\n");
return -1;
}
@@ -954,51 +991,48 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
*/
/* RSSI is 1 byte long */
- pBSSEntry->rssi = le32_to_cpu((long)(*pcurrentptr));
- lbs_pr_debug(1, "InterpretIE: RSSI=%02X\n", *pcurrentptr);
+ bss->rssi = *pcurrentptr;
+ lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr);
pcurrentptr += 1;
bytesleftforcurrentbeacon -= 1;
/* time stamp is 8 bytes long */
- memcpy(fixedie.timestamp, pcurrentptr, 8);
- memcpy(pBSSEntry->timestamp, pcurrentptr, 8);
+ fixedie.timestamp = bss->timestamp = le64_to_cpup((void *)pcurrentptr);
pcurrentptr += 8;
bytesleftforcurrentbeacon -= 8;
/* beacon interval is 2 bytes long */
- memcpy(&fixedie.beaconinterval, pcurrentptr, 2);
- pBSSEntry->beaconperiod = le16_to_cpu(fixedie.beaconinterval);
+ fixedie.beaconinterval = bss->beaconperiod = le16_to_cpup((void *)pcurrentptr);
pcurrentptr += 2;
bytesleftforcurrentbeacon -= 2;
/* capability information is 2 bytes long */
- memcpy(&fixedie.capabilities, pcurrentptr, 2);
- lbs_pr_debug(1, "InterpretIE: fixedie.capabilities=0x%X\n",
+ memcpy(&fixedie.capabilities, pcurrentptr, 2);
+ lbs_deb_scan("process_bss: fixedie.capabilities=0x%X\n",
fixedie.capabilities);
- fixedie.capabilities = le16_to_cpu(fixedie.capabilities);
pcap = (struct ieeetypes_capinfo *) & fixedie.capabilities;
- memcpy(&pBSSEntry->cap, pcap, sizeof(struct ieeetypes_capinfo));
+ memcpy(&bss->cap, pcap, sizeof(struct ieeetypes_capinfo));
pcurrentptr += 2;
bytesleftforcurrentbeacon -= 2;
/* rest of the current buffer are IE's */
- lbs_pr_debug(1, "InterpretIE: IElength for this AP = %d\n",
+ lbs_deb_scan("process_bss: IE length for this AP = %d\n",
bytesleftforcurrentbeacon);
- lbs_dbg_hex("InterpretIE: IE info", (u8 *) pcurrentptr,
+ lbs_dbg_hex("process_bss: IE info", (u8 *) pcurrentptr,
bytesleftforcurrentbeacon);
if (pcap->privacy) {
- lbs_pr_debug(1, "InterpretIE: AP WEP enabled\n");
- pBSSEntry->privacy = wlan802_11privfilter8021xWEP;
+ lbs_deb_scan("process_bss: AP WEP enabled\n");
+ bss->privacy = wlan802_11privfilter8021xWEP;
} else {
- pBSSEntry->privacy = wlan802_11privfilteracceptall;
+ bss->privacy = wlan802_11privfilteracceptall;
}
if (pcap->ibss == 1) {
- pBSSEntry->mode = IW_MODE_ADHOC;
+ bss->mode = IW_MODE_ADHOC;
} else {
- pBSSEntry->mode = IW_MODE_INFRA;
+ bss->mode = IW_MODE_INFRA;
}
/* process variable IE */
@@ -1007,94 +1041,83 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
elemlen = *((u8 *) pcurrentptr + 1);
if (bytesleftforcurrentbeacon < elemlen) {
- lbs_pr_debug(1, "InterpretIE: error in processing IE, "
+ lbs_deb_scan("process_bss: error in processing IE, "
"bytes left < IE length\n");
bytesleftforcurrentbeacon = 0;
continue;
}
switch (elemID) {
-
case SSID:
- pBSSEntry->ssid.ssidlength = elemlen;
- memcpy(pBSSEntry->ssid.ssid, (pcurrentptr + 2),
- elemlen);
- lbs_pr_debug(1, "ssid: %32s", pBSSEntry->ssid.ssid);
+ bss->ssid_len = elemlen;
+ memcpy(bss->ssid, (pcurrentptr + 2), elemlen);
+ lbs_deb_scan("ssid '%s', ssid length %u\n",
+ escape_essid(bss->ssid, bss->ssid_len),
+ bss->ssid_len);
break;
case SUPPORTED_RATES:
- memcpy(pBSSEntry->datarates, (pcurrentptr + 2),
- elemlen);
- memmove(pBSSEntry->libertas_supported_rates, (pcurrentptr + 2),
+ memcpy(bss->datarates, (pcurrentptr + 2), elemlen);
+ memmove(bss->libertas_supported_rates, (pcurrentptr + 2),
elemlen);
ratesize = elemlen;
founddatarateie = 1;
break;
case EXTRA_IE:
- lbs_pr_debug(1, "InterpretIE: EXTRA_IE Found!\n");
- pBSSEntry->extra_ie = 1;
+ lbs_deb_scan("process_bss: EXTRA_IE Found!\n");
break;
case FH_PARAM_SET:
pFH = (struct ieeetypes_fhparamset *) pcurrentptr;
- memmove(&pBSSEntry->phyparamset.fhparamset, pFH,
+ memmove(&bss->phyparamset.fhparamset, pFH,
sizeof(struct ieeetypes_fhparamset));
- pBSSEntry->phyparamset.fhparamset.dwelltime
- =
- le16_to_cpu(pBSSEntry->phyparamset.fhparamset.
- dwelltime);
+#if 0 /* I think we can store these LE */
+ bss->phyparamset.fhparamset.dwelltime
+ = le16_to_cpu(bss->phyparamset.fhparamset.dwelltime);
+#endif
break;
case DS_PARAM_SET:
pDS = (struct ieeetypes_dsparamset *) pcurrentptr;
-
- pBSSEntry->channel = pDS->currentchan;
-
- memcpy(&pBSSEntry->phyparamset.dsparamset, pDS,
+ bss->channel = pDS->currentchan;
+ memcpy(&bss->phyparamset.dsparamset, pDS,
sizeof(struct ieeetypes_dsparamset));
break;
case CF_PARAM_SET:
pCF = (struct ieeetypes_cfparamset *) pcurrentptr;
-
- memcpy(&pBSSEntry->ssparamset.cfparamset, pCF,
+ memcpy(&bss->ssparamset.cfparamset, pCF,
sizeof(struct ieeetypes_cfparamset));
break;
case IBSS_PARAM_SET:
pibss = (struct ieeetypes_ibssparamset *) pcurrentptr;
- pBSSEntry->atimwindow =
- le32_to_cpu(pibss->atimwindow);
-
- memmove(&pBSSEntry->ssparamset.ibssparamset, pibss,
+ bss->atimwindow = le32_to_cpu(pibss->atimwindow);
+ memmove(&bss->ssparamset.ibssparamset, pibss,
sizeof(struct ieeetypes_ibssparamset));
-
- pBSSEntry->ssparamset.ibssparamset.atimwindow
- =
- le16_to_cpu(pBSSEntry->ssparamset.ibssparamset.
- atimwindow);
+#if 0
+ bss->ssparamset.ibssparamset.atimwindow
+ = le16_to_cpu(bss->ssparamset.ibssparamset.atimwindow);
+#endif
break;
/* Handle Country Info IE */
case COUNTRY_INFO:
- pcountryinfo =
- (struct ieeetypes_countryinfoset *) pcurrentptr;
-
- if (pcountryinfo->len <
- sizeof(pcountryinfo->countrycode)
+ pcountryinfo = (struct ieeetypes_countryinfoset *) pcurrentptr;
+ if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
|| pcountryinfo->len > 254) {
- lbs_pr_debug(1, "InterpretIE: 11D- Err "
+ lbs_deb_scan("process_bss: 11D- Err "
"CountryInfo len =%d min=%zd max=254\n",
pcountryinfo->len,
sizeof(pcountryinfo->countrycode));
- LEAVE();
- return -1;
+ ret = -1;
+ goto done;
}
- memcpy(&pBSSEntry->countryinfo,
+ memcpy(&bss->countryinfo,
pcountryinfo, pcountryinfo->len + 2);
- lbs_dbg_hex("InterpretIE: 11D- CountryInfo:",
+ lbs_dbg_hex("process_bss: 11D- CountryInfo:",
(u8 *) pcountryinfo,
(u32) (pcountryinfo->len + 2));
break;
@@ -1114,12 +1137,10 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
bytestocopy = elemlen;
}
- pRate = (u8 *) pBSSEntry->datarates;
+ pRate = (u8 *) bss->datarates;
pRate += ratesize;
memmove(pRate, (pcurrentptr + 2), bytestocopy);
-
- pRate = (u8 *) pBSSEntry->libertas_supported_rates;
-
+ pRate = (u8 *) bss->libertas_supported_rates;
pRate += ratesize;
memmove(pRate, (pcurrentptr + 2), bytestocopy);
}
@@ -1132,24 +1153,17 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
if (memcmp(pIe->oui, oui01, sizeof(oui01)))
break;
- pBSSEntry->wpa_ie_len = min_t(size_t,
- elemlen + IE_ID_LEN_FIELDS_BYTES,
- sizeof(pBSSEntry->wpa_ie));
- memcpy(pBSSEntry->wpa_ie, pcurrentptr,
- pBSSEntry->wpa_ie_len);
- lbs_dbg_hex("InterpretIE: Resp WPA_IE",
- pBSSEntry->wpa_ie, elemlen);
+ bss->wpa_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
+ MAX_WPA_IE_LEN);
+ memcpy(bss->wpa_ie, pcurrentptr, bss->wpa_ie_len);
+ lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie, elemlen);
break;
case WPA2_IE:
pIe = (struct IE_WPA *)pcurrentptr;
-
- pBSSEntry->rsn_ie_len = min_t(size_t,
- elemlen + IE_ID_LEN_FIELDS_BYTES,
- sizeof(pBSSEntry->rsn_ie));
- memcpy(pBSSEntry->rsn_ie, pcurrentptr,
- pBSSEntry->rsn_ie_len);
- lbs_dbg_hex("InterpretIE: Resp WPA2_IE",
- pBSSEntry->rsn_ie, elemlen);
+ bss->rsn_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
+ MAX_WPA_IE_LEN);
+ memcpy(bss->rsn_ie, pcurrentptr, bss->rsn_ie_len);
+ lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elemlen);
break;
case TIM:
break;
@@ -1165,7 +1179,14 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
} /* while (bytesleftforcurrentbeacon > 2) */
- return 0;
+ /* Timestamp */
+ bss->last_scanned = jiffies;
+
+ ret = 0;
+
+done:
+ lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
+ return ret;
}
/**
@@ -1176,15 +1197,12 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
*
* @return 0--ssid is same, otherwise is different
*/
-int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *ssid2)
+int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
{
- if (!ssid1 || !ssid2)
- return -1;
-
- if (ssid1->ssidlength != ssid2->ssidlength)
+ if (ssid1_len != ssid2_len)
return -1;
- return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssidlength);
+ return memcmp(ssid1, ssid2, ssid1_len);
}
/**
@@ -1196,38 +1214,41 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s
*
* @return index in BSSID list, or error return code (< 0)
*/
-int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode)
+struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
+ u8 * bssid, u8 mode)
{
- int ret = -ENETUNREACH;
- int i;
+ struct bss_descriptor * iter_bss;
+ struct bss_descriptor * found_bss = NULL;
if (!bssid)
- return -EFAULT;
+ return NULL;
- lbs_pr_debug(1, "FindBSSID: Num of BSSIDs = %d\n",
- adapter->numinscantable);
+ lbs_dbg_hex("libertas_find_BSSID_in_list: looking for ",
+ bssid, ETH_ALEN);
- /* Look through the scan table for a compatible match. The ret return
- * variable will be equal to the index in the scan table (greater
- * than zero) if the network is compatible. The loop will continue
- * past a matched bssid that is not compatible in case there is an
- * AP with multiple SSIDs assigned to the same BSSID
+ /* Look through the scan table for a compatible match. The loop will
+ * continue past a matched bssid that is not compatible in case there
+ * is an AP with multiple SSIDs assigned to the same BSSID
*/
- for (i = 0; ret < 0 && i < adapter->numinscantable; i++) {
- if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) {
- switch (mode) {
- case IW_MODE_INFRA:
- case IW_MODE_ADHOC:
- ret = is_network_compatible(adapter, i, mode);
- break;
- default:
- ret = i;
+ mutex_lock(&adapter->lock);
+ list_for_each_entry (iter_bss, &adapter->network_list, list) {
+ if (compare_ether_addr(iter_bss->bssid, bssid))
+ continue; /* bssid doesn't match */
+ switch (mode) {
+ case IW_MODE_INFRA:
+ case IW_MODE_ADHOC:
+ if (!is_network_compatible(adapter, iter_bss, mode))
break;
- }
+ found_bss = iter_bss;
+ break;
+ default:
+ found_bss = iter_bss;
+ break;
}
}
+ mutex_unlock(&adapter->lock);
- return ret;
+ return found_bss;
}
/**
@@ -1240,61 +1261,60 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode)
*
* @return index in BSSID list
*/
-int libertas_find_SSID_in_list(wlan_adapter * adapter,
- struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode)
+struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
+ u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
+ int channel)
{
- int net = -ENETUNREACH;
u8 bestrssi = 0;
- int i;
- int j;
+ struct bss_descriptor * iter_bss = NULL;
+ struct bss_descriptor * found_bss = NULL;
+ struct bss_descriptor * tmp_oldest = NULL;
- lbs_pr_debug(1, "Num of Entries in Table = %d\n", adapter->numinscantable);
-
- for (i = 0; i < adapter->numinscantable; i++) {
- if (!libertas_SSID_cmp(&adapter->scantable[i].ssid, ssid) &&
- (!bssid ||
- !memcmp(adapter->scantable[i].
- macaddress, bssid, ETH_ALEN))) {
- switch (mode) {
- case IW_MODE_INFRA:
- case IW_MODE_ADHOC:
- j = is_network_compatible(adapter, i, mode);
-
- if (j >= 0) {
- if (bssid) {
- return i;
- }
-
- if (SCAN_RSSI
- (adapter->scantable[i].rssi)
- > bestrssi) {
- bestrssi =
- SCAN_RSSI(adapter->
- scantable[i].
- rssi);
- net = i;
- }
- } else {
- if (net == -ENETUNREACH) {
- net = j;
- }
- }
- break;
- case IW_MODE_AUTO:
- default:
- if (SCAN_RSSI(adapter->scantable[i].rssi)
- > bestrssi) {
- bestrssi =
- SCAN_RSSI(adapter->scantable[i].
- rssi);
- net = i;
- }
+ mutex_lock(&adapter->lock);
+
+ list_for_each_entry (iter_bss, &adapter->network_list, list) {
+ if ( !tmp_oldest
+ || (iter_bss->last_scanned < tmp_oldest->last_scanned))
+ tmp_oldest = iter_bss;
+
+ if (libertas_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
+ ssid, ssid_len) != 0)
+ continue; /* ssid doesn't match */
+ if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0)
+ continue; /* bssid doesn't match */
+ if ((channel > 0) && (iter_bss->channel != channel))
+ continue; /* channel doesn't match */
+
+ switch (mode) {
+ case IW_MODE_INFRA:
+ case IW_MODE_ADHOC:
+ if (!is_network_compatible(adapter, iter_bss, mode))
break;
+
+ if (bssid) {
+ /* Found requested BSSID */
+ found_bss = iter_bss;
+ goto out;
+ }
+
+ if (SCAN_RSSI(iter_bss->rssi) > bestrssi) {
+ bestrssi = SCAN_RSSI(iter_bss->rssi);
+ found_bss = iter_bss;
}
+ break;
+ case IW_MODE_AUTO:
+ default:
+ if (SCAN_RSSI(iter_bss->rssi) > bestrssi) {
+ bestrssi = SCAN_RSSI(iter_bss->rssi);
+ found_bss = iter_bss;
+ }
+ break;
}
}
- return net;
+out:
+ mutex_unlock(&adapter->lock);
+ return found_bss;
}
/**
@@ -1307,43 +1327,38 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
*
* @return index in BSSID list
*/
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode)
+struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
+ u8 mode)
{
- int bestnet = -ENETUNREACH;
u8 bestrssi = 0;
- int i;
+ struct bss_descriptor * iter_bss;
+ struct bss_descriptor * best_bss = NULL;
- ENTER();
+ mutex_lock(&adapter->lock);
- lbs_pr_debug(1, "Num of BSSIDs = %d\n", adapter->numinscantable);
-
- for (i = 0; i < adapter->numinscantable; i++) {
+ list_for_each_entry (iter_bss, &adapter->network_list, list) {
switch (mode) {
case IW_MODE_INFRA:
case IW_MODE_ADHOC:
- if (is_network_compatible(adapter, i, mode) >= 0) {
- if (SCAN_RSSI(adapter->scantable[i].rssi) >
- bestrssi) {
- bestrssi =
- SCAN_RSSI(adapter->scantable[i].
- rssi);
- bestnet = i;
- }
- }
+ if (!is_network_compatible(adapter, iter_bss, mode))
+ break;
+ if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
+ break;
+ bestrssi = SCAN_RSSI(iter_bss->rssi);
+ best_bss = iter_bss;
break;
case IW_MODE_AUTO:
default:
- if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) {
- bestrssi =
- SCAN_RSSI(adapter->scantable[i].rssi);
- bestnet = i;
- }
+ if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
+ break;
+ bestrssi = SCAN_RSSI(iter_bss->rssi);
+ best_bss = iter_bss;
break;
}
}
- LEAVE();
- return bestnet;
+ mutex_unlock(&adapter->lock);
+ return best_bss;
}
/**
@@ -1354,41 +1369,30 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode)
*
* @return 0--success, otherwise--fail
*/
-int libertas_find_best_network_SSID(wlan_private * priv,
- struct WLAN_802_11_SSID *pSSID,
- u8 preferred_mode, u8 *out_mode)
+int libertas_find_best_network_ssid(wlan_private * priv,
+ u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode)
{
wlan_adapter *adapter = priv->adapter;
- int ret = 0;
- struct bss_descriptor *preqbssid;
- int i;
+ int ret = -1;
+ struct bss_descriptor * found;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
- memset(pSSID, 0, sizeof(struct WLAN_802_11_SSID));
-
- wlan_scan_networks(priv, NULL);
+ wlan_scan_networks(priv, NULL, 1);
if (adapter->surpriseremoved)
return -1;
- wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
- i = libertas_find_best_SSID_in_list(adapter, preferred_mode);
- if (i < 0) {
- ret = -1;
- goto out;
- }
-
- preqbssid = &adapter->scantable[i];
- memcpy(pSSID, &preqbssid->ssid,
- sizeof(struct WLAN_802_11_SSID));
- *out_mode = preqbssid->mode;
+ wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
- if (!pSSID->ssidlength) {
- ret = -1;
+ found = libertas_find_best_ssid_in_list(adapter, preferred_mode);
+ if (found && (found->ssid_len > 0)) {
+ memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE);
+ *out_ssid_len = found->ssid_len;
+ *out_mode = found->mode;
+ ret = 0;
}
-out:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
}
@@ -1407,20 +1411,15 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
{
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- union iwreq_data wrqu;
- ENTER();
+ lbs_deb_enter(LBS_DEB_SCAN);
- if (!wlan_scan_networks(priv, NULL)) {
- memset(&wrqu, 0, sizeof(union iwreq_data));
- wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu,
- NULL);
- }
+ wlan_scan_networks(priv, NULL, 0);
if (adapter->surpriseremoved)
return -1;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_SCAN);
return 0;
}
@@ -1433,32 +1432,31 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
*
* @return 0-success, otherwise fail
*/
-int libertas_send_specific_SSID_scan(wlan_private * priv,
- struct WLAN_802_11_SSID *prequestedssid,
- u8 keeppreviousscan)
+int libertas_send_specific_ssid_scan(wlan_private * priv,
+ u8 *ssid, u8 ssid_len, u8 clear_ssid)
{
wlan_adapter *adapter = priv->adapter;
struct wlan_ioctl_user_scan_cfg scancfg;
+ int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
- if (prequestedssid == NULL) {
- return -1;
- }
+ if (!ssid_len)
+ goto out;
memset(&scancfg, 0x00, sizeof(scancfg));
+ memcpy(scancfg.ssid, ssid, ssid_len);
+ scancfg.ssid_len = ssid_len;
+ scancfg.clear_ssid = clear_ssid;
- memcpy(scancfg.specificSSID, prequestedssid->ssid,
- prequestedssid->ssidlength);
- scancfg.keeppreviousscan = keeppreviousscan;
-
- wlan_scan_networks(priv, &scancfg);
+ wlan_scan_networks(priv, &scancfg, 1);
if (adapter->surpriseremoved)
return -1;
wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave(LBS_DEB_ASSOC);
+ return ret;
}
/**
@@ -1470,304 +1468,235 @@ int libertas_send_specific_SSID_scan(wlan_private * priv,
*
* @return 0-success, otherwise fail
*/
-int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 keeppreviousscan)
+int libertas_send_specific_bssid_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid)
{
struct wlan_ioctl_user_scan_cfg scancfg;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
- if (bssid == NULL) {
- return -1;
- }
+ if (bssid == NULL)
+ goto out;
memset(&scancfg, 0x00, sizeof(scancfg));
- memcpy(scancfg.specificBSSID, bssid, sizeof(scancfg.specificBSSID));
- scancfg.keeppreviousscan = keeppreviousscan;
+ memcpy(scancfg.bssid, bssid, ETH_ALEN);
+ scancfg.clear_bssid = clear_bssid;
- wlan_scan_networks(priv, &scancfg);
+ wlan_scan_networks(priv, &scancfg, 1);
if (priv->adapter->surpriseremoved)
return -1;
wait_event_interruptible(priv->adapter->cmd_pending,
!priv->adapter->nr_cmd_pending);
- LEAVE();
+out:
+ lbs_deb_leave(LBS_DEB_ASSOC);
return 0;
}
-/**
- * @brief Retrieve the scan table entries via wireless tools IOCTL call
- *
- * @param dev A pointer to net_device structure
- * @param info A pointer to iw_request_info structure
- * @param dwrq A pointer to iw_point structure
- * @param extra A pointer to extra data buf
- *
- * @return 0 --success, otherwise fail
- */
-int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *dwrq, char *extra)
+static inline char *libertas_translate_scan(wlan_private *priv,
+ char *start, char *stop,
+ struct bss_descriptor *bss)
{
- wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- int ret = 0;
- char *current_ev = extra;
- char *end_buf = extra + IW_SCAN_MAX_DATA;
struct chan_freq_power *cfp;
- struct bss_descriptor *pscantable;
char *current_val; /* For rates */
struct iw_event iwe; /* Temporary buffer */
- int i;
int j;
- int rate;
#define PERFECT_RSSI ((u8)50)
#define WORST_RSSI ((u8)0)
#define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI))
u8 rssi;
- u8 buf[16 + 256 * 2];
- u8 *ptr;
-
- ENTER();
-
- /*
- * if there's either commands in the queue or one being
- * processed return -EAGAIN for iwlist to retry later.
- */
- if (adapter->nr_cmd_pending)
- return -EAGAIN;
-
- if (adapter->connect_status == libertas_connected)
- lbs_pr_debug(1, "Current ssid: %32s\n",
- adapter->curbssparams.ssid.ssid);
+ cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, bss->channel);
+ if (!cfp) {
+ lbs_deb_scan("Invalid channel number %d\n", bss->channel);
+ return NULL;
+ }
- lbs_pr_debug(1, "Scan: Get: numinscantable = %d\n",
- adapter->numinscantable);
+ /* First entry *MUST* be the AP BSSID */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
+ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+
+ /* SSID */
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE);
+ start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+
+ /* Mode */
+ iwe.cmd = SIOCGIWMODE;
+ iwe.u.mode = bss->mode;
+ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+
+ /* Frequency */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = (long)cfp->freq * 100000;
+ iwe.u.freq.e = 1;
+ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+
+ /* Add quality statistics */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.updated = IW_QUAL_ALL_UPDATED;
+ iwe.u.qual.level = SCAN_RSSI(bss->rssi);
+
+ rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE;
+ iwe.u.qual.qual =
+ (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) *
+ (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) /
+ (RSSI_DIFF * RSSI_DIFF);
+ if (iwe.u.qual.qual > 100)
+ iwe.u.qual.qual = 100;
+
+ if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
+ iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
+ } else {
+ iwe.u.qual.noise =
+ CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
+ }
- /* The old API using SIOCGIWAPLIST had a hard limit of IW_MAX_AP.
- * The new API using SIOCGIWSCAN is only limited by buffer size
- * WE-14 -> WE-16 the buffer is limited to IW_SCAN_MAX_DATA bytes
- * which is 4096.
+ /* Locally created ad-hoc BSSs won't have beacons if this is the
+ * only station in the adhoc network; so get signal strength
+ * from receive statistics.
*/
- for (i = 0; i < adapter->numinscantable; i++) {
- if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) {
- lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p "
- "MAX_SCAN_CELL_SIZE=%zd\n",
- i, current_ev, end_buf, MAX_SCAN_CELL_SIZE);
- break;
- }
-
- pscantable = &adapter->scantable[i];
-
- lbs_pr_debug(1, "i=%d ssid: %32s\n", i, pscantable->ssid.ssid);
-
- cfp =
- libertas_find_cfp_by_band_and_channel(adapter, 0,
- pscantable->channel);
- if (!cfp) {
- lbs_pr_debug(1, "Invalid channel number %d\n",
- pscantable->channel);
- continue;
- }
-
- if (!ssid_valid(&adapter->scantable[i].ssid)) {
- continue;
- }
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data,
- &adapter->scantable[i].macaddress, ETH_ALEN);
-
- iwe.len = IW_EV_ADDR_LEN;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
-
- //Add the ESSID
- iwe.u.data.length = adapter->scantable[i].ssid.ssidlength;
-
- if (iwe.u.data.length > 32) {
- iwe.u.data.length = 32;
- }
-
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- adapter->scantable[i].ssid.
- ssid);
-
- //Add mode
- iwe.cmd = SIOCGIWMODE;
- iwe.u.mode = adapter->scantable[i].mode;
- iwe.len = IW_EV_UINT_LEN;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
-
- //frequency
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = (long)cfp->freq * 100000;
- iwe.u.freq.e = 1;
- iwe.len = IW_EV_FREQ_LEN;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
-
- /* Add quality statistics */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.updated = IW_QUAL_ALL_UPDATED;
- iwe.u.qual.level = SCAN_RSSI(adapter->scantable[i].rssi);
-
- rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE;
- iwe.u.qual.qual =
- (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) *
- (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) /
- (RSSI_DIFF * RSSI_DIFF);
- if (iwe.u.qual.qual > 100)
- iwe.u.qual.qual = 100;
- else if (iwe.u.qual.qual < 1)
- iwe.u.qual.qual = 0;
-
- if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
- iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
- } else {
- iwe.u.qual.noise =
- CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
- }
- if ((adapter->mode == IW_MODE_ADHOC) &&
- !libertas_SSID_cmp(&adapter->curbssparams.ssid,
- &adapter->scantable[i].ssid)
- && adapter->adhoccreate) {
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_rssi,
- 0,
- cmd_option_waitforrsp,
- 0, NULL);
-
- if (!ret) {
- iwe.u.qual.level =
- CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] /
- AVG_SCALE,
- adapter->NF[TYPE_RXPD][TYPE_AVG] /
- AVG_SCALE);
- }
- }
- iwe.len = IW_EV_QUAL_LEN;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (adapter->scantable[i].privacy) {
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- } else {
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- }
- iwe.u.data.length = 0;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- adapter->scantable->ssid.
- ssid);
+ if ((adapter->mode == IW_MODE_ADHOC)
+ && adapter->adhoccreate
+ && !libertas_ssid_cmp(adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len,
+ bss->ssid, bss->ssid_len)) {
+ int snr, nf;
+ snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
+ nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
+ iwe.u.qual.level = CAL_RSSI(snr, nf);
+ }
+ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
- current_val = current_ev + IW_EV_LCP_LEN;
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (bss->privacy) {
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ } else {
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ }
+ iwe.u.data.length = 0;
+ start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
- iwe.cmd = SIOCGIWRATE;
+ current_val = start + IW_EV_LCP_LEN;
- iwe.u.bitrate.fixed = 0;
- iwe.u.bitrate.disabled = 0;
- iwe.u.bitrate.value = 0;
+ iwe.cmd = SIOCGIWRATE;
+ iwe.u.bitrate.fixed = 0;
+ iwe.u.bitrate.disabled = 0;
+ iwe.u.bitrate.value = 0;
+ for (j = 0; j < sizeof(bss->libertas_supported_rates); j++) {
+ u8 rate = bss->libertas_supported_rates[j];
+ if (rate == 0)
+ break; /* no more rates */
/* Bit rate given in 500 kb/s units (+ 0x80) */
- for (j = 0; j < sizeof(adapter->scantable[i].libertas_supported_rates);
- j++) {
- if (adapter->scantable[i].libertas_supported_rates[j] == 0) {
- break;
- }
- rate =
- (adapter->scantable[i].libertas_supported_rates[j] & 0x7F) *
- 500000;
- if (rate > iwe.u.bitrate.value) {
- iwe.u.bitrate.value = rate;
- }
-
- iwe.u.bitrate.value =
- (adapter->scantable[i].libertas_supported_rates[j]
- & 0x7f) * 500000;
- iwe.len = IW_EV_PARAM_LEN;
- current_ev =
- iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe, iwe.len);
+ iwe.u.bitrate.value = (rate & 0x7f) * 500000;
+ current_val = iwe_stream_add_value(start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
+ }
+ if ((bss->mode == IW_MODE_ADHOC)
+ && !libertas_ssid_cmp(adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len,
+ bss->ssid, bss->ssid_len)
+ && adapter->adhoccreate) {
+ iwe.u.bitrate.value = 22 * 500000;
+ current_val = iwe_stream_add_value(start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
+ }
+ /* Check if we added any event */
+ if((current_val - start) > IW_EV_LCP_LEN)
+ start = current_val;
+
+ memset(&iwe, 0, sizeof(iwe));
+ if (bss->wpa_ie_len) {
+ char buf[MAX_WPA_IE_LEN];
+ memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = bss->wpa_ie_len;
+ start = iwe_stream_add_point(start, stop, &iwe, buf);
+ }
- }
- if ((adapter->scantable[i].mode == IW_MODE_ADHOC)
- && !libertas_SSID_cmp(&adapter->curbssparams.ssid,
- &adapter->scantable[i].ssid)
- && adapter->adhoccreate) {
- iwe.u.bitrate.value = 22 * 500000;
- }
- iwe.len = IW_EV_PARAM_LEN;
- current_ev =
- iwe_stream_add_value(current_ev, current_val, end_buf, &iwe,
- iwe.len);
-
- /* Add new value to event */
- current_val = current_ev + IW_EV_LCP_LEN;
-
- if (adapter->scantable[i].rsn_ie[0] == WPA2_IE) {
- memset(&iwe, 0, sizeof(iwe));
- memset(buf, 0, sizeof(buf));
- memcpy(buf, adapter->scantable[i].rsn_ie,
- adapter->scantable[i].rsn_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = adapter->scantable[i].rsn_ie_len;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
- }
- if (adapter->scantable[i].wpa_ie[0] == WPA_IE) {
- memset(&iwe, 0, sizeof(iwe));
- memset(buf, 0, sizeof(buf));
- memcpy(buf, adapter->scantable[i].wpa_ie,
- adapter->scantable[i].wpa_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = adapter->scantable[i].wpa_ie_len;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
- }
+ memset(&iwe, 0, sizeof(iwe));
+ if (bss->rsn_ie_len) {
+ char buf[MAX_WPA_IE_LEN];
+ memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = bss->rsn_ie_len;
+ start = iwe_stream_add_point(start, stop, &iwe, buf);
+ }
+ return start;
+}
- if (adapter->scantable[i].extra_ie != 0) {
- memset(&iwe, 0, sizeof(iwe));
- memset(buf, 0, sizeof(buf));
- ptr = buf;
- ptr += sprintf(ptr, "extra_ie");
- iwe.u.data.length = strlen(buf);
+/**
+ * @brief Retrieve the scan table entries via wireless tools IOCTL call
+ *
+ * @param dev A pointer to net_device structure
+ * @param info A pointer to iw_request_info structure
+ * @param dwrq A pointer to iw_point structure
+ * @param extra A pointer to extra data buf
+ *
+ * @return 0 --success, otherwise fail
+ */
+int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+#define SCAN_ITEM_SIZE 128
+ wlan_private *priv = dev->priv;
+ wlan_adapter *adapter = priv->adapter;
+ int err = 0;
+ char *ev = extra;
+ char *stop = ev + dwrq->length;
+ struct bss_descriptor * iter_bss;
+ struct bss_descriptor * safe;
+
+ lbs_deb_enter(LBS_DEB_ASSOC);
+
+ /* If we've got an uncompleted scan, schedule the next part */
+ if (!adapter->nr_cmd_pending && adapter->last_scanned_channel)
+ wlan_scan_networks(priv, NULL, 0);
+
+ /* Update RSSI if current BSS is a locally created ad-hoc BSS */
+ if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) {
+ libertas_prepare_and_send_command(priv, cmd_802_11_rssi, 0,
+ cmd_option_waitforrsp, 0, NULL);
+ }
- lbs_pr_debug(1, "iwe.u.data.length %d\n",
- iwe.u.data.length);
- lbs_pr_debug(1, "BUF: %s \n", buf);
+ mutex_lock(&adapter->lock);
+ list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
+ char * next_ev;
+ unsigned long stale_time;
- iwe.cmd = IWEVCUSTOM;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
- current_ev =
- iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ if (stop - ev < SCAN_ITEM_SIZE) {
+ err = -E2BIG;
+ break;
}
- current_val = current_ev + IW_EV_LCP_LEN;
+ /* Prune old an old scan result */
+ stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
+ if (time_after(jiffies, stale_time)) {
+ list_move_tail (&iter_bss->list,
+ &adapter->network_free_list);
+ clear_bss_descriptor(iter_bss);
+ continue;
+ }
- /*
- * Check if we added any event
- */
- if ((current_val - current_ev) > IW_EV_LCP_LEN)
- current_ev = current_val;
+ /* Translate to WE format this entry */
+ next_ev = libertas_translate_scan(priv, ev, stop, iter_bss);
+ if (next_ev == NULL)
+ continue;
+ ev = next_ev;
}
+ mutex_unlock(&adapter->lock);
- dwrq->length = (current_ev - extra);
+ dwrq->length = (ev - extra);
dwrq->flags = 0;
- LEAVE();
- return 0;
+ lbs_deb_leave(LBS_DEB_ASSOC);
+ return err;
}
/**
@@ -1796,13 +1725,13 @@ int libertas_cmd_80211_scan(wlan_private * priv,
struct cmd_ds_802_11_scan *pscan = &cmd->params.scan;
struct wlan_scan_cmd_config *pscancfg;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
pscancfg = pdata_buf;
/* Set fixed field variables in scan command */
pscan->bsstype = pscancfg->bsstype;
- memcpy(pscan->BSSID, pscancfg->specificBSSID, sizeof(pscan->BSSID));
+ memcpy(pscan->BSSID, pscancfg->bssid, sizeof(pscan->BSSID));
memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
cmd->command = cpu_to_le16(cmd_802_11_scan);
@@ -1812,12 +1741,26 @@ int libertas_cmd_80211_scan(wlan_private * priv,
+ sizeof(pscan->BSSID)
+ pscancfg->tlvbufferlen + S_DS_GEN);
- lbs_pr_debug(1, "SCAN_CMD: command=%x, size=%x, seqnum=%x\n",
- cmd->command, cmd->size, cmd->seqnum);
- LEAVE();
+ lbs_deb_scan("SCAN_CMD: command=%x, size=%x, seqnum=%x\n",
+ le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
+ le16_to_cpu(cmd->seqnum));
+
+ lbs_deb_leave(LBS_DEB_ASSOC);
return 0;
}
+static inline int is_same_network(struct bss_descriptor *src,
+ struct bss_descriptor *dst)
+{
+ /* A network is only a duplicate if the channel, BSSID, and ESSID
+ * all match. We treat all <hidden> with the same BSSID and channel
+ * as one network */
+ return ((src->ssid_len == dst->ssid_len) &&
+ (src->channel == dst->channel) &&
+ !compare_ether_addr(src->bssid, dst->bssid) &&
+ !memcmp(src->ssid, dst->ssid, src->ssid_len));
+}
+
/**
* @brief This function handles the command response of scan
*
@@ -1846,38 +1789,45 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
{
wlan_adapter *adapter = priv->adapter;
struct cmd_ds_802_11_scan_rsp *pscan;
- struct bss_descriptor newbssentry;
struct mrvlietypes_data *ptlv;
struct mrvlietypes_tsftimestamp *ptsftlv;
+ struct bss_descriptor * iter_bss;
+ struct bss_descriptor * safe;
u8 *pbssinfo;
u16 scanrespsize;
int bytesleft;
- int numintable;
- int bssIdx;
int idx;
int tlvbufsize;
- u64 tsfval;
+ int ret;
- ENTER();
+ lbs_deb_enter(LBS_DEB_ASSOC);
+
+ /* Prune old entries from scan table */
+ list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
+ unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
+ if (time_before(jiffies, stale_time))
+ continue;
+ list_move_tail (&iter_bss->list, &adapter->network_free_list);
+ clear_bss_descriptor(iter_bss);
+ }
pscan = &resp->params.scanresp;
- if (pscan->nr_sets > MRVDRV_MAX_BSSID_LIST) {
- lbs_pr_debug(1,
- "SCAN_RESP: Invalid number of AP returned (%d)!!\n",
- pscan->nr_sets);
- LEAVE();
- return -1;
+ if (pscan->nr_sets > MAX_NETWORK_COUNT) {
+ lbs_deb_scan(
+ "SCAN_RESP: too many scan results (%d, max %d)!!\n",
+ pscan->nr_sets, MAX_NETWORK_COUNT);
+ ret = -1;
+ goto done;
}
bytesleft = le16_to_cpu(pscan->bssdescriptsize);
- lbs_pr_debug(1, "SCAN_RESP: bssdescriptsize %d\n", bytesleft);
+ lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
scanrespsize = le16_to_cpu(resp->size);
- lbs_pr_debug(1, "SCAN_RESP: returned %d AP before parsing\n",
+ lbs_deb_scan("SCAN_RESP: returned %d AP before parsing\n",
pscan->nr_sets);
- numintable = adapter->numinscantable;
pbssinfo = pscan->bssdesc_and_tlvbuffer;
/* The size of the TLV buffer is equal to the entire command response
@@ -1901,105 +1851,68 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
* or as an addition at the end of the table
*/
for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) {
- /* Zero out the newbssentry we are about to store info in */
- memset(&newbssentry, 0x00, sizeof(newbssentry));
+ struct bss_descriptor new;
+ struct bss_descriptor * found = NULL;
+ struct bss_descriptor * oldest = NULL;
/* Process the data fields and IEs returned for this BSS */
- if ((InterpretBSSDescriptionWithIE(&newbssentry,
- &pbssinfo,
- &bytesleft) ==
- 0)
- && CHECK_SSID_IS_VALID(&newbssentry.ssid)) {
-
- lbs_pr_debug(1,
- "SCAN_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
- newbssentry.macaddress[0],
- newbssentry.macaddress[1],
- newbssentry.macaddress[2],
- newbssentry.macaddress[3],
- newbssentry.macaddress[4],
- newbssentry.macaddress[5]);
-
- /*
- * Search the scan table for the same bssid
- */
- for (bssIdx = 0; bssIdx < numintable; bssIdx++) {
- if (memcmp(newbssentry.macaddress,
- adapter->scantable[bssIdx].
- macaddress,
- sizeof(newbssentry.macaddress)) ==
- 0) {
- /*
- * If the SSID matches as well, it is a duplicate of
- * this entry. Keep the bssIdx set to this
- * entry so we replace the old contents in the table
- */
- if ((newbssentry.ssid.ssidlength ==
- adapter->scantable[bssIdx].ssid.
- ssidlength)
- &&
- (memcmp
- (newbssentry.ssid.ssid,
- adapter->scantable[bssIdx].ssid.
- ssid,
- newbssentry.ssid.ssidlength) ==
- 0)) {
- lbs_pr_debug(1,
- "SCAN_RESP: Duplicate of index: %d\n",
- bssIdx);
- break;
- }
- }
- }
- /*
- * If the bssIdx is equal to the number of entries in the table,
- * the new entry was not a duplicate; append it to the scan
- * table
- */
- if (bssIdx == numintable) {
- /* Range check the bssIdx, keep it limited to the last entry */
- if (bssIdx == MRVDRV_MAX_BSSID_LIST) {
- bssIdx--;
- } else {
- numintable++;
- }
- }
-
- /*
- * If the TSF TLV was appended to the scan results, save the
- * this entries TSF value in the networktsf field. The
- * networktsf is the firmware's TSF value at the time the
- * beacon or probe response was received.
- */
- if (ptsftlv) {
- memcpy(&tsfval, &ptsftlv->tsftable[idx],
- sizeof(tsfval));
- tsfval = le64_to_cpu(tsfval);
+ memset(&new, 0, sizeof (struct bss_descriptor));
+ if (libertas_process_bss(&new, &pbssinfo, &bytesleft) != 0) {
+ /* error parsing the scan response, skipped */
+ lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n");
+ continue;
+ }
- memcpy(&newbssentry.networktsf,
- &tsfval, sizeof(newbssentry.networktsf));
+ /* Try to find this bss in the scan table */
+ list_for_each_entry (iter_bss, &adapter->network_list, list) {
+ if (is_same_network(iter_bss, &new)) {
+ found = iter_bss;
+ break;
}
- /* Copy the locally created newbssentry to the scan table */
- memcpy(&adapter->scantable[bssIdx],
- &newbssentry,
- sizeof(adapter->scantable[bssIdx]));
+ if ((oldest == NULL) ||
+ (iter_bss->last_scanned < oldest->last_scanned))
+ oldest = iter_bss;
+ }
+ if (found) {
+ /* found, clear it */
+ clear_bss_descriptor(found);
+ } else if (!list_empty(&adapter->network_free_list)) {
+ /* Pull one from the free list */
+ found = list_entry(adapter->network_free_list.next,
+ struct bss_descriptor, list);
+ list_move_tail(&found->list, &adapter->network_list);
+ } else if (oldest) {
+ /* If there are no more slots, expire the oldest */
+ found = oldest;
+ clear_bss_descriptor(found);
+ list_move_tail(&found->list, &adapter->network_list);
} else {
+ continue;
+ }
+
+ lbs_deb_scan("SCAN_RESP: BSSID = " MAC_FMT "\n",
+ new.bssid[0], new.bssid[1], new.bssid[2],
+ new.bssid[3], new.bssid[4], new.bssid[5]);
- /* error parsing/interpreting the scan response, skipped */
- lbs_pr_debug(1, "SCAN_RESP: "
- "InterpretBSSDescriptionWithIE returned ERROR\n");
+ /*
+ * If the TSF TLV was appended to the scan results, save the
+ * this entries TSF value in the networktsf field. The
+ * networktsf is the firmware's TSF value at the time the
+ * beacon or probe response was received.
+ */
+ if (ptsftlv) {
+ new.networktsf = le64_to_cpup(&ptsftlv->tsftable[idx]);
}
- }
- lbs_pr_debug(1, "SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
- pscan->nr_sets, numintable - adapter->numinscantable,
- numintable);
+ /* Copy the locally created newbssentry to the scan table */
+ memcpy(found, &new, offsetof(struct bss_descriptor, list));
+ }
- /* Update the total number of BSSIDs in the scan table */
- adapter->numinscantable = numintable;
+ ret = 0;
- LEAVE();
- return 0;
+done:
+ lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
+ return ret;
}
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
index 405f4f0fe57..bd019e5ff1e 100644
--- a/drivers/net/wireless/libertas/scan.h
+++ b/drivers/net/wireless/libertas/scan.h
@@ -51,7 +51,7 @@ struct wlan_scan_cmd_config {
/**
* @brief Specific BSSID used to filter scan results in the firmware
*/
- u8 specificBSSID[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
/**
* @brief length of TLVs sent in command starting at tlvBuffer
@@ -91,15 +91,6 @@ struct wlan_ioctl_user_scan_chan {
* @sa libertas_set_user_scan_ioctl
*/
struct wlan_ioctl_user_scan_cfg {
-
- /**
- * @brief Flag set to keep the previous scan table intact
- *
- * If set, the scan results will accumulate, replacing any previous
- * matched entries for a BSS with the new scan data
- */
- u8 keeppreviousscan; //!< Do not erase the existing scan results
-
/**
* @brief BSS type to be sent in the firmware command
*
@@ -117,15 +108,22 @@ struct wlan_ioctl_user_scan_cfg {
*/
u8 numprobes;
- /**
- * @brief BSSID filter sent in the firmware command to limit the results
- */
- u8 specificBSSID[ETH_ALEN];
+ /**
+ * @brief BSSID filter sent in the firmware command to limit the results
+ */
+ u8 bssid[ETH_ALEN];
- /**
- * @brief SSID filter sent in the firmware command to limit the results
- */
- char specificSSID[IW_ESSID_MAX_SIZE + 1];
+ /* Clear existing scan results matching this BSSID */
+ u8 clear_bssid;
+
+ /**
+ * @brief SSID filter sent in the firmware command to limit the results
+ */
+ char ssid[IW_ESSID_MAX_SIZE];
+ u8 ssid_len;
+
+ /* Clear existing scan results matching this SSID */
+ u8 clear_ssid;
/**
* @brief Variable number (fixed maximum) of channels to scan up
@@ -137,9 +135,10 @@ struct wlan_ioctl_user_scan_cfg {
* @brief Structure used to store information for each beacon/probe response
*/
struct bss_descriptor {
- u8 macaddress[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
- struct WLAN_802_11_SSID ssid;
+ u8 ssid[IW_ESSID_MAX_SIZE + 1];
+ u8 ssid_len;
/* WEP encryption requirement */
u32 privacy;
@@ -156,15 +155,15 @@ struct bss_descriptor {
u8 mode;
u8 libertas_supported_rates[WLAN_SUPPORTED_RATES];
- int extra_ie;
+ __le64 timestamp; //!< TSF value included in the beacon/probe response
+ unsigned long last_scanned;
- u8 timestamp[8]; //!< TSF value included in the beacon/probe response
union ieeetypes_phyparamset phyparamset;
union IEEEtypes_ssparamset ssparamset;
struct ieeetypes_capinfo cap;
u8 datarates[WLAN_SUPPORTED_RATES];
- __le64 networktsf; //!< TSF timestamp from the current firmware TSF
+ u64 networktsf; //!< TSF timestamp from the current firmware TSF
struct ieeetypes_countryinfofullset countryinfo;
@@ -172,24 +171,29 @@ struct bss_descriptor {
size_t wpa_ie_len;
u8 rsn_ie[MAX_WPA_IE_LEN];
size_t rsn_ie_len;
+
+ struct list_head list;
};
-extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1,
- struct WLAN_802_11_SSID *ssid2);
-extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid,
- u8 * bssid, u8 mode);
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode);
-extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode);
+extern int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
+
+struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
+ u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
+ int channel);
+
+struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
+ u8 mode);
+
+extern struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
+ u8 * bssid, u8 mode);
-int libertas_find_best_network_SSID(wlan_private * priv,
- struct WLAN_802_11_SSID *pSSID,
- u8 preferred_mode, u8 *out_mode);
+int libertas_find_best_network_ssid(wlan_private * priv, u8 *out_ssid,
+ u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode);
-extern int libertas_send_specific_SSID_scan(wlan_private * priv,
- struct WLAN_802_11_SSID *prequestedssid,
- u8 keeppreviousscan);
-extern int libertas_send_specific_BSSID_scan(wlan_private * priv,
- u8 * bssid, u8 keeppreviousscan);
+extern int libertas_send_specific_ssid_scan(wlan_private * priv, u8 *ssid,
+ u8 ssid_len, u8 clear_ssid);
+extern int libertas_send_specific_bssid_scan(wlan_private * priv,
+ u8 * bssid, u8 clear_bssid);
extern int libertas_cmd_80211_scan(wlan_private * priv,
struct cmd_ds_command *cmd,
@@ -199,7 +203,8 @@ extern int libertas_ret_80211_scan(wlan_private * priv,
struct cmd_ds_command *resp);
int wlan_scan_networks(wlan_private * priv,
- const struct wlan_ioctl_user_scan_cfg * puserscanin);
+ const struct wlan_ioctl_user_scan_cfg * puserscanin,
+ int full_scan);
struct ifreq;
diff --git a/drivers/net/wireless/libertas/thread.h b/drivers/net/wireless/libertas/thread.h
index 207b8a6cc33..b1f34d92ff3 100644
--- a/drivers/net/wireless/libertas/thread.h
+++ b/drivers/net/wireless/libertas/thread.h
@@ -21,11 +21,11 @@ static inline void wlan_activate_thread(struct wlan_thread * thr)
static inline void wlan_deactivate_thread(struct wlan_thread * thr)
{
- ENTER();
+ lbs_deb_enter(LBS_DEB_THREAD);
thr->pid = 0;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_THREAD);
}
static inline void wlan_create_thread(int (*wlanfunc) (void *),
@@ -36,7 +36,7 @@ static inline void wlan_create_thread(int (*wlanfunc) (void *),
static inline int wlan_terminate_thread(struct wlan_thread * thr)
{
- ENTER();
+ lbs_deb_enter(LBS_DEB_THREAD);
/* Check if the thread is active or not */
if (!thr->pid) {
@@ -45,7 +45,7 @@ static inline int wlan_terminate_thread(struct wlan_thread * thr)
}
kthread_stop(thr->task);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_THREAD);
return 0;
}
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index d4b13478c9a..17c437635a0 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -5,7 +5,6 @@
#include "hostcmd.h"
#include "radiotap.h"
-#include "sbi.h"
#include "decl.h"
#include "defs.h"
#include "dev.h"
@@ -68,7 +67,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
u32 new_rate;
u8 *ptr = priv->adapter->tmptxbuf;
- ENTER();
+ lbs_deb_enter(LBS_DEB_TX);
if (priv->adapter->surpriseremoved)
return -1;
@@ -78,7 +77,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
min_t(unsigned int, skb->len, 100));
if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
- lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n",
+ lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
ret = -1;
goto done;
@@ -86,13 +85,13 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
memset(plocaltxpd, 0, sizeof(struct txpd));
- plocaltxpd->tx_packet_length = skb->len;
+ plocaltxpd->tx_packet_length = cpu_to_le16(skb->len);
/* offset of actual data */
- plocaltxpd->tx_packet_location = sizeof(struct txpd);
+ plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
/* TxCtrl set by user or default */
- plocaltxpd->tx_control = adapter->pkttxctrl;
+ plocaltxpd->tx_control = cpu_to_le32(adapter->pkttxctrl);
p802x_hdr = skb->data;
if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP) {
@@ -103,15 +102,16 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
/* set txpd fields from the radiotap header */
new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate);
if (new_rate != 0) {
- /* erase tx_control[4:0] */
- plocaltxpd->tx_control &= ~0x1f;
- /* write new tx_control[4:0] */
- plocaltxpd->tx_control |= new_rate;
+ /* use new tx_control[4:0] */
+ new_rate |= (adapter->pkttxctrl & ~0x1f);
+ plocaltxpd->tx_control = cpu_to_le32(new_rate);
}
/* skip the radiotap header */
p802x_hdr += sizeof(struct tx_radiotap_hdr);
- plocaltxpd->tx_packet_length -= sizeof(struct tx_radiotap_hdr);
+ plocaltxpd->tx_packet_length =
+ cpu_to_le16(le16_to_cpu(plocaltxpd->tx_packet_length)
+ - sizeof(struct tx_radiotap_hdr));
}
/* copy destination address from 802.3 or 802.11 header */
@@ -123,28 +123,28 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
lbs_dbg_hex("txpd", (u8 *) plocaltxpd, sizeof(struct txpd));
if (IS_MESH_FRAME(skb)) {
- plocaltxpd->tx_control |= TxPD_MESH_FRAME;
+ plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
}
memcpy(ptr, plocaltxpd, sizeof(struct txpd));
ptr += sizeof(struct txpd);
- lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, plocaltxpd->tx_packet_length);
- memcpy(ptr, p802x_hdr, plocaltxpd->tx_packet_length);
- ret = libertas_sbi_host_to_card(priv, MVMS_DAT,
- priv->adapter->tmptxbuf,
- plocaltxpd->tx_packet_length +
- sizeof(struct txpd));
+ lbs_dbg_hex("Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
+ memcpy(ptr, p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
+ ret = priv->hw_host_to_card(priv, MVMS_DAT,
+ priv->adapter->tmptxbuf,
+ le16_to_cpu(plocaltxpd->tx_packet_length) +
+ sizeof(struct txpd));
if (ret) {
- lbs_pr_debug(1, "Tx error: libertas_sbi_host_to_card failed: 0x%X\n", ret);
+ lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
goto done;
}
- lbs_pr_debug(1, "SendSinglePacket succeeds\n");
+ lbs_deb_tx("SendSinglePacket succeeds\n");
- done:
+done:
if (!ret) {
priv->stats.tx_packets++;
priv->stats.tx_bytes += skb->len;
@@ -158,7 +158,8 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
received from FW */
skb_orphan(skb);
/* stop processing outgoing pkts */
- netif_stop_queue(priv->wlan_dev.netdev);
+ netif_stop_queue(priv->dev);
+ netif_stop_queue(priv->mesh_dev);
/* freeze any packets already in our queues */
priv->adapter->TxLockFlag = 1;
} else {
@@ -166,7 +167,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
priv->adapter->currenttxskb = NULL;
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
return ret;
}
@@ -195,10 +196,13 @@ static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb)
WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE);
adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb;
- if (adapter->tx_queue_idx == NR_TX_QUEUE)
- netif_stop_queue(priv->wlan_dev.netdev);
- else
- netif_start_queue(priv->wlan_dev.netdev);
+ if (adapter->tx_queue_idx == NR_TX_QUEUE) {
+ netif_stop_queue(priv->dev);
+ netif_stop_queue(priv->mesh_dev);
+ } else {
+ netif_start_queue(priv->dev);
+ netif_start_queue(priv->mesh_dev);
+ }
spin_unlock(&adapter->txqueue_lock);
}
@@ -214,13 +218,12 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
{
int ret = -1;
- ENTER();
-
+ lbs_deb_enter(LBS_DEB_TX);
lbs_dbg_hex("TX Data", skb->data, min_t(unsigned int, skb->len, 100));
- if (priv->wlan_dev.dnld_sent) {
+ if (priv->dnld_sent) {
lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
- priv->wlan_dev.dnld_sent);
+ priv->dnld_sent);
goto done;
}
@@ -234,7 +237,7 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
ret = SendSinglePacket(priv, skb);
done:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
return ret;
}
@@ -280,6 +283,9 @@ void libertas_send_tx_feedback(wlan_private * priv)
libertas_upload_rx_packet(priv, adapter->currenttxskb);
adapter->currenttxskb = NULL;
priv->adapter->TxLockFlag = 0;
- if (priv->adapter->connect_status == libertas_connected)
- netif_wake_queue(priv->wlan_dev.netdev);
+ if (priv->adapter->connect_status == libertas_connected) {
+ netif_wake_queue(priv->dev);
+ netif_wake_queue(priv->mesh_dev);
+ }
}
+EXPORT_SYMBOL_GPL(libertas_send_tx_feedback);
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index 09d62f8b1a1..028e2f3b53d 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -5,6 +5,7 @@
#define _WLAN_TYPES_
#include <linux/if_ether.h>
+#include <asm/byteorder.h>
/** IEEE type definitions */
enum ieeetypes_elementid {
@@ -29,9 +30,30 @@ enum ieeetypes_elementid {
EXTRA_IE = 133,
} __attribute__ ((packed));
+#ifdef __BIG_ENDIAN
#define CAPINFO_MASK (~(0xda00))
+#else
+#define CAPINFO_MASK (~(0x00da))
+#endif
struct ieeetypes_capinfo {
+#ifdef __BIG_ENDIAN_BITFIELD
+ u8 chanagility:1;
+ u8 pbcc:1;
+ u8 shortpreamble:1;
+ u8 privacy:1;
+ u8 cfpollrqst:1;
+ u8 cfpollable:1;
+ u8 ibss:1;
+ u8 ess:1;
+ u8 rsrvd1:2;
+ u8 dsssofdm:1;
+ u8 rsvrd2:1;
+ u8 apsd:1;
+ u8 shortslottime:1;
+ u8 rsrvd3:1;
+ u8 spectrummgmt:1;
+#else
u8 ess:1;
u8 ibss:1;
u8 cfpollable:1;
@@ -47,6 +69,7 @@ struct ieeetypes_capinfo {
u8 rsvrd2:1;
u8 dsssofdm:1;
u8 rsrvd1:2;
+#endif
} __attribute__ ((packed));
struct ieeetypes_cfparamset {
@@ -54,15 +77,15 @@ struct ieeetypes_cfparamset {
u8 len;
u8 cfpcnt;
u8 cfpperiod;
- u16 cfpmaxduration;
- u16 cfpdurationremaining;
+ __le16 cfpmaxduration;
+ __le16 cfpdurationremaining;
} __attribute__ ((packed));
struct ieeetypes_ibssparamset {
u8 elementid;
u8 len;
- u16 atimwindow;
+ __le16 atimwindow;
} __attribute__ ((packed));
union IEEEtypes_ssparamset {
@@ -73,7 +96,7 @@ union IEEEtypes_ssparamset {
struct ieeetypes_fhparamset {
u8 elementid;
u8 len;
- u16 dwelltime;
+ __le16 dwelltime;
u8 hopset;
u8 hoppattern;
u8 hopindex;
@@ -92,8 +115,8 @@ union ieeetypes_phyparamset {
struct ieeetypes_assocrsp {
struct ieeetypes_capinfo capability;
- u16 statuscode;
- u16 aid;
+ __le16 statuscode;
+ __le16 aid;
u8 iebuffer[1];
} __attribute__ ((packed));
@@ -138,8 +161,8 @@ struct ieeetypes_assocrsp {
/** TLV related data structures*/
struct mrvlietypesheader {
- u16 type;
- u16 len;
+ __le16 type;
+ __le16 len;
} __attribute__ ((packed));
struct mrvlietypes_data {
@@ -164,17 +187,23 @@ struct mrvlietypes_wildcardssidparamset {
} __attribute__ ((packed));
struct chanscanmode {
+#ifdef __BIG_ENDIAN_BITFIELD
+ u8 reserved_2_7:6;
+ u8 disablechanfilt:1;
+ u8 passivescan:1;
+#else
u8 passivescan:1;
u8 disablechanfilt:1;
u8 reserved_2_7:6;
+#endif
} __attribute__ ((packed));
struct chanscanparamset {
u8 radiotype;
u8 channumber;
struct chanscanmode chanscanmode;
- u16 minscantime;
- u16 maxscantime;
+ __le16 minscantime;
+ __le16 maxscantime;
} __attribute__ ((packed));
struct mrvlietypes_chanlistparamset {
@@ -185,12 +214,12 @@ struct mrvlietypes_chanlistparamset {
struct cfparamset {
u8 cfpcnt;
u8 cfpperiod;
- u16 cfpmaxduration;
- u16 cfpdurationremaining;
+ __le16 cfpmaxduration;
+ __le16 cfpdurationremaining;
} __attribute__ ((packed));
struct ibssparamset {
- u16 atimwindow;
+ __le16 atimwindow;
} __attribute__ ((packed));
struct mrvlietypes_ssparamset {
@@ -202,7 +231,7 @@ struct mrvlietypes_ssparamset {
} __attribute__ ((packed));
struct fhparamset {
- u16 dwelltime;
+ __le16 dwelltime;
u8 hopset;
u8 hoppattern;
u8 hopindex;
@@ -263,17 +292,17 @@ struct mrvlietypes_beaconsmissed {
struct mrvlietypes_numprobes {
struct mrvlietypesheader header;
- u16 numprobes;
+ __le16 numprobes;
} __attribute__ ((packed));
struct mrvlietypes_bcastprobe {
struct mrvlietypesheader header;
- u16 bcastprobe;
+ __le16 bcastprobe;
} __attribute__ ((packed));
struct mrvlietypes_numssidprobe {
struct mrvlietypesheader header;
- u16 numssidprobe;
+ __le16 numssidprobe;
} __attribute__ ((packed));
struct led_pin {
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 69f52b6e59c..8939251a2f4 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -22,6 +22,14 @@
/**
+ * the rates supported by the card
+ */
+static u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] =
+ { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
+ 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
+};
+
+/**
* @brief Convert mw value to dbm value
*
* @param mw the value of mw
@@ -102,8 +110,8 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada
}
if (!cfp && channel)
- lbs_pr_debug(1, "libertas_find_cfp_by_band_and_channel(): cannot find "
- "cfp by band %d & channel %d\n", band, channel);
+ lbs_deb_wext("libertas_find_cfp_by_band_and_channel: can't find "
+ "cfp by band %d / channel %d\n", band, channel);
return cfp;
}
@@ -143,113 +151,12 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
}
if (!cfp && freq)
- lbs_pr_debug(1, "find_cfp_by_band_and_freql(): cannot find cfp by "
- "band %d & freq %d\n", band, freq);
+ lbs_deb_wext("find_cfp_by_band_and_freql: can't find cfp by "
+ "band %d / freq %d\n", band, freq);
return cfp;
}
-static int updatecurrentchannel(wlan_private * priv)
-{
- int ret;
-
- /*
- ** the channel in f/w could be out of sync, get the current channel
- */
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
- cmd_opt_802_11_rf_channel_get,
- cmd_option_waitforrsp, 0, NULL);
-
- lbs_pr_debug(1, "Current channel = %d\n",
- priv->adapter->curbssparams.channel);
-
- return ret;
-}
-
-static int setcurrentchannel(wlan_private * priv, int channel)
-{
- lbs_pr_debug(1, "Set channel = %d\n", channel);
-
- /*
- ** Current channel is not set to adhocchannel requested, set channel
- */
- return (libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
- cmd_opt_802_11_rf_channel_set,
- cmd_option_waitforrsp, 0, &channel));
-}
-
-static int changeadhocchannel(wlan_private * priv, int channel)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
-
- adapter->adhocchannel = channel;
-
- updatecurrentchannel(priv);
-
- if (adapter->curbssparams.channel == adapter->adhocchannel) {
- /* adhocchannel is set to the current channel already */
- LEAVE();
- return 0;
- }
-
- lbs_pr_debug(1, "Updating channel from %d to %d\n",
- adapter->curbssparams.channel, adapter->adhocchannel);
-
- setcurrentchannel(priv, adapter->adhocchannel);
-
- updatecurrentchannel(priv);
-
- if (adapter->curbssparams.channel != adapter->adhocchannel) {
- lbs_pr_debug(1, "failed to updated channel to %d, channel = %d\n",
- adapter->adhocchannel, adapter->curbssparams.channel);
- LEAVE();
- return -1;
- }
-
- if (adapter->connect_status == libertas_connected) {
- int i;
- struct WLAN_802_11_SSID curadhocssid;
-
- lbs_pr_debug(1, "channel Changed while in an IBSS\n");
-
- /* Copy the current ssid */
- memcpy(&curadhocssid, &adapter->curbssparams.ssid,
- sizeof(struct WLAN_802_11_SSID));
-
- /* Exit Adhoc mode */
- lbs_pr_debug(1, "In changeadhocchannel(): Sending Adhoc Stop\n");
- ret = libertas_stop_adhoc_network(priv);
-
- if (ret) {
- LEAVE();
- return ret;
- }
- /* Scan for the network, do not save previous results. Stale
- * scan data will cause us to join a non-existant adhoc network
- */
- libertas_send_specific_SSID_scan(priv, &curadhocssid, 0);
-
- // find out the BSSID that matches the current SSID
- i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
- IW_MODE_ADHOC);
-
- if (i >= 0) {
- lbs_pr_debug(1, "SSID found at %d in List,"
- "so join\n", i);
- libertas_join_adhoc_network(priv, &adapter->scantable[i]);
- } else {
- // else send START command
- lbs_pr_debug(1, "SSID not found in list, "
- "so creating adhoc with ssid = %s\n",
- curadhocssid.ssid);
- libertas_start_adhoc_network(priv, &curadhocssid);
- } // end of else (START command)
- }
-
- LEAVE();
- return 0;
-}
/**
* @brief Set Radio On/OFF
@@ -263,10 +170,10 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option)
int ret = 0;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->radioon != option) {
- lbs_pr_debug(1, "Switching %s the Radio\n", option ? "On" : "Off");
+ lbs_deb_wext("switching radio %s\n", option ? "on" : "off");
adapter->radioon = option;
ret = libertas_prepare_and_send_command(priv,
@@ -275,7 +182,7 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option)
cmd_option_waitforrsp, 0, NULL);
}
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -312,15 +219,15 @@ static int get_active_data_rates(wlan_adapter * adapter,
{
int k = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->connect_status != libertas_connected) {
if (adapter->mode == IW_MODE_INFRA) {
- lbs_pr_debug(1, "Infra\n");
+ lbs_deb_wext("infra\n");
k = copyrates(rates, k, libertas_supported_rates,
sizeof(libertas_supported_rates));
} else {
- lbs_pr_debug(1, "Adhoc G\n");
+ lbs_deb_wext("Adhoc G\n");
k = copyrates(rates, k, libertas_adhoc_rates_g,
sizeof(libertas_adhoc_rates_g));
}
@@ -329,8 +236,7 @@ static int get_active_data_rates(wlan_adapter * adapter,
adapter->curbssparams.numofrates);
}
- LEAVE();
-
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", k);
return k;
}
@@ -342,7 +248,7 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
char mrvl[6] = { "MRVL-" };
int cnt;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
strcpy(cwrq, mrvl);
@@ -360,8 +266,7 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
}
*cwrq = '\0';
- LEAVE();
-
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -372,14 +277,14 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
wlan_adapter *adapter = priv->adapter;
struct chan_freq_power *cfp;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
cfp = libertas_find_cfp_by_band_and_channel(adapter, 0,
adapter->curbssparams.channel);
if (!cfp) {
if (adapter->curbssparams.channel)
- lbs_pr_debug(1, "Invalid channel=%d\n",
+ lbs_deb_wext("invalid channel %d\n",
adapter->curbssparams.channel);
return -EINVAL;
}
@@ -387,9 +292,8 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
fwrq->m = (long)cfp->freq * 100000;
fwrq->e = 1;
- lbs_pr_debug(1, "freq=%u\n", fwrq->m);
-
- LEAVE();
+ lbs_deb_wext("freq %u\n", fwrq->m);
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -399,7 +303,7 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->connect_status == libertas_connected) {
memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN);
@@ -408,7 +312,7 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
}
awrq->sa_family = ARPHRD_ETHER;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -418,7 +322,7 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
/*
* Check the size of the string
@@ -433,7 +337,7 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
memcpy(adapter->nodename, extra, dwrq->length);
mutex_unlock(&adapter->lock);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -443,7 +347,7 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
/*
* Get the Nick Name saved
@@ -464,19 +368,43 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
*/
dwrq->length = strlen(extra) + 1;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
+static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ wlan_private *priv = dev->priv;
+ wlan_adapter *adapter = priv->adapter;
+
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ /* Use nickname to indicate that mesh is on */
+
+ if (adapter->connect_status == libertas_connected) {
+ strncpy(extra, "Mesh", 12);
+ extra[12] = '\0';
+ dwrq->length = strlen(extra) + 1;
+ }
+
+ else {
+ extra[0] = '\0';
+ dwrq->length = 1 ;
+ }
+
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return 0;
+}
static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- int rthr = vwrq->value;
+ u32 rthr = vwrq->value;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->disabled) {
adapter->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;
@@ -490,7 +418,7 @@ static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
cmd_act_set, cmd_option_waitforrsp,
OID_802_11_RTS_THRESHOLD, &rthr);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -501,35 +429,34 @@ static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
adapter->rtsthsd = 0;
ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
cmd_act_get, cmd_option_waitforrsp,
OID_802_11_RTS_THRESHOLD, NULL);
- if (ret) {
- LEAVE();
- return ret;
- }
+ if (ret)
+ goto out;
vwrq->value = adapter->rtsthsd;
vwrq->disabled = ((vwrq->value < MRVDRV_RTS_MIN_VALUE)
|| (vwrq->value > MRVDRV_RTS_MAX_VALUE));
vwrq->fixed = 1;
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
int ret = 0;
- int fthr = vwrq->value;
+ u32 fthr = vwrq->value;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->disabled) {
adapter->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;
@@ -543,7 +470,8 @@ static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
ret = libertas_prepare_and_send_command(priv, cmd_802_11_snmp_mib,
cmd_act_set, cmd_option_waitforrsp,
OID_802_11_FRAGMENTATION_THRESHOLD, &fthr);
- LEAVE();
+
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -554,24 +482,23 @@ static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
adapter->fragthsd = 0;
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_snmp_mib,
cmd_act_get, cmd_option_waitforrsp,
OID_802_11_FRAGMENTATION_THRESHOLD, NULL);
- if (ret) {
- LEAVE();
- return ret;
- }
+ if (ret)
+ goto out;
vwrq->value = adapter->fragthsd;
vwrq->disabled = ((vwrq->value < MRVDRV_FRAG_MIN_VALUE)
|| (vwrq->value > MRVDRV_FRAG_MAX_VALUE));
vwrq->fixed = 1;
- LEAVE();
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -581,11 +508,23 @@ static int wlan_get_mode(struct net_device *dev,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
*uwrq = adapter->mode;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
+ return 0;
+}
+
+static int mesh_wlan_get_mode(struct net_device *dev,
+ struct iw_request_info *info, u32 * uwrq,
+ char *extra)
+{
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ *uwrq = IW_MODE_REPEAT ;
+
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -597,19 +536,17 @@ static int wlan_get_txpow(struct net_device *dev,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_rf_tx_power,
cmd_act_tx_power_opt_get,
cmd_option_waitforrsp, 0, NULL);
- if (ret) {
- LEAVE();
- return ret;
- }
+ if (ret)
+ goto out;
- lbs_pr_debug(1, "TXPOWER GET %d dbm.\n", adapter->txpowerlevel);
+ lbs_deb_wext("tx power level %d dbm\n", adapter->txpowerlevel);
vwrq->value = adapter->txpowerlevel;
vwrq->fixed = 1;
if (adapter->radioon) {
@@ -619,8 +556,9 @@ static int wlan_get_txpow(struct net_device *dev,
vwrq->disabled = 1;
}
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
@@ -630,7 +568,7 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->flags == IW_RETRY_LIMIT) {
/* The MAC has a 4-bit Total_Tx_Count register
@@ -648,16 +586,15 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
cmd_option_waitforrsp,
OID_802_11_TX_RETRYCOUNT, NULL);
- if (ret) {
- LEAVE();
- return ret;
- }
+ if (ret)
+ goto out;
} else {
return -EOPNOTSUPP;
}
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
@@ -667,16 +604,16 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
+
adapter->txretrycount = 0;
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_snmp_mib,
cmd_act_get, cmd_option_waitforrsp,
OID_802_11_TX_RETRYCOUNT, NULL);
- if (ret) {
- LEAVE();
- return ret;
- }
+ if (ret)
+ goto out;
+
vwrq->disabled = 0;
if (!vwrq->flags) {
vwrq->flags = IW_RETRY_LIMIT;
@@ -684,8 +621,9 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
vwrq->value = adapter->txretrycount - 1;
}
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
static inline void sort_channels(struct iw_freq *freq, int num)
@@ -739,7 +677,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
u8 flag = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
dwrq->length = sizeof(struct iw_range);
memset(range, 0, sizeof(struct iw_range));
@@ -755,7 +693,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
range->bitrate[i] = (rates[i] & 0x7f) * 500000;
}
range->num_bitrates = i;
- lbs_pr_debug(1, "IW_MAX_BITRATES=%d num_bitrates=%d\n", IW_MAX_BITRATES,
+ lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES,
range->num_bitrates);
range->num_frequency = 0;
@@ -768,18 +706,17 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
&adapter->parsed_region_chan;
if (parsed_region_chan == NULL) {
- lbs_pr_debug(1, "11D:parsed_region_chan is NULL\n");
- LEAVE();
- return 0;
+ lbs_deb_wext("11d: parsed_region_chan is NULL\n");
+ goto out;
}
band = parsed_region_chan->band;
- lbs_pr_debug(1, "band=%d NoOfChan=%d\n", band,
+ lbs_deb_wext("band %d, nr_char %d\n", band,
parsed_region_chan->nr_chan);
for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
&& (i < parsed_region_chan->nr_chan); i++) {
chan_no = parsed_region_chan->chanpwr[i].chan;
- lbs_pr_debug(1, "chan_no=%d\n", chan_no);
+ lbs_deb_wext("chan_no %d\n", chan_no);
range->freq[range->num_frequency].i = (long)chan_no;
range->freq[range->num_frequency].m =
(long)libertas_chan_2_freq(chan_no, band) * 100000;
@@ -808,7 +745,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
}
}
- lbs_pr_debug(1, "IW_MAX_FREQUENCIES=%d num_frequency=%d\n",
+ lbs_deb_wext("IW_MAX_FREQUENCIES %d, num_frequency %d\n",
IW_MAX_FREQUENCIES, range->num_frequency);
range->num_channels = range->num_frequency;
@@ -903,7 +840,8 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
| IW_ENC_CAPA_CIPHER_CCMP;
}
- LEAVE();
+out:
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -913,7 +851,7 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
/* PS is currently supported only in Infrastructure mode
* Remove this check if it is to be supported in IBSS mode also
@@ -929,11 +867,11 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
}
if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- lbs_pr_debug(1,
- "Setting power timeout command is not supported\n");
+ lbs_deb_wext(
+ "setting power timeout is not supported\n");
return -EINVAL;
} else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
- lbs_pr_debug(1, "Setting power period command is not supported\n");
+ lbs_deb_wext("setting power period not supported\n");
return -EINVAL;
}
@@ -947,7 +885,7 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
libertas_ps_sleep(priv, cmd_option_waitforrsp);
}
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -958,19 +896,20 @@ static int wlan_get_power(struct net_device *dev, struct iw_request_info *info,
wlan_adapter *adapter = priv->adapter;
int mode;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
mode = adapter->psmode;
if ((vwrq->disabled = (mode == wlan802_11powermodecam))
- || adapter->connect_status == libertas_disconnected) {
- LEAVE();
- return 0;
+ || adapter->connect_status == libertas_disconnected)
+ {
+ goto out;
}
vwrq->value = 0;
- LEAVE();
+out:
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -1063,6 +1002,16 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_CHAR | 128,
IW_PRIV_TYPE_CHAR | 128,
"bt_list"},
+ {
+ WLAN_SUBCMD_BT_SET_INVERT,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_NONE,
+ "bt_set_invert"},
+ {
+ WLAN_SUBCMD_BT_GET_INVERT,
+ IW_PRIV_TYPE_NONE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "bt_get_invert"},
/* FWT Management */
{
WLAN_SUBCMD_FWT_ADD,
@@ -1125,7 +1074,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
u8 rssi;
u32 tx_retries;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
priv->wstats.status = adapter->mode;
@@ -1145,8 +1094,8 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
}
- lbs_pr_debug(1, "Signal Level = %#x\n", priv->wstats.qual.level);
- lbs_pr_debug(1, "Noise = %#x\n", priv->wstats.qual.noise);
+ lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);
+ lbs_deb_wext("noise %#x\n", priv->wstats.qual.noise);
rssi = priv->wstats.qual.level - priv->wstats.qual.noise;
if (rssi < 15)
@@ -1166,7 +1115,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
/* Quality by TX errors */
priv->wstats.discard.retries = priv->stats.tx_errors;
- tx_retries = adapter->logmsg.retry;
+ tx_retries = le16_to_cpu(adapter->logmsg.retry);
if (tx_retries > 75)
tx_qual = (90 - tx_retries) * POOR / 15;
@@ -1182,10 +1131,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
(PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
quality = min(quality, tx_qual);
- priv->wstats.discard.code = adapter->logmsg.wepundecryptable;
- priv->wstats.discard.fragment = adapter->logmsg.fcserror;
+ priv->wstats.discard.code = le16_to_cpu(adapter->logmsg.wepundecryptable);
+ priv->wstats.discard.fragment = le16_to_cpu(adapter->logmsg.rxfrag);
priv->wstats.discard.retries = tx_retries;
- priv->wstats.discard.misc = adapter->logmsg.ackfailure;
+ priv->wstats.discard.misc = le16_to_cpu(adapter->logmsg.ackfailure);
/* Calculate quality */
priv->wstats.qual.qual = max(quality, (u32)100);
@@ -1209,7 +1158,7 @@ out:
IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
}
- LEAVE ();
+ lbs_deb_leave(LBS_DEB_WEXT);
return &priv->wstats;
@@ -1218,81 +1167,59 @@ out:
static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
struct iw_freq *fwrq, char *extra)
{
- int ret = 0;
+ int ret = -EINVAL;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- int rc = -EINPROGRESS; /* Call commit handler */
struct chan_freq_power *cfp;
+ struct assoc_request * assoc_req;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
- /*
- * If setting by frequency, convert to a channel
- */
- if (fwrq->e == 1) {
+ mutex_lock(&adapter->lock);
+ assoc_req = wlan_get_association_request(adapter);
+ if (!assoc_req) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ /* If setting by frequency, convert to a channel */
+ if (fwrq->e == 1) {
long f = fwrq->m / 100000;
- int c = 0;
cfp = find_cfp_by_band_and_freq(adapter, 0, f);
if (!cfp) {
- lbs_pr_debug(1, "Invalid freq=%ld\n", f);
- return -EINVAL;
+ lbs_deb_wext("invalid freq %ld\n", f);
+ goto out;
}
- c = (int)cfp->channel;
-
- if (c < 0)
- return -EINVAL;
-
fwrq->e = 0;
- fwrq->m = c;
+ fwrq->m = (int) cfp->channel;
}
- /*
- * Setting by channel number
- */
+ /* Setting by channel number */
if (fwrq->m > 1000 || fwrq->e > 0) {
- rc = -EOPNOTSUPP;
- } else {
- int channel = fwrq->m;
+ goto out;
+ }
- cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, channel);
- if (!cfp) {
- rc = -EINVAL;
- } else {
- if (adapter->mode == IW_MODE_ADHOC) {
- rc = changeadhocchannel(priv, channel);
- /* If station is WEP enabled, send the
- * command to set WEP in firmware
- */
- if (adapter->secinfo.wep_enabled) {
- lbs_pr_debug(1, "set_freq: WEP enabled\n");
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_set_wep,
- cmd_act_add,
- cmd_option_waitforrsp,
- 0,
- NULL);
-
- if (ret) {
- LEAVE();
- return ret;
- }
-
- adapter->currentpacketfilter |=
- cmd_act_mac_wep_enable;
-
- libertas_set_mac_packet_filter(priv);
- }
- } else {
- rc = -EOPNOTSUPP;
- }
- }
+ cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);
+ if (!cfp) {
+ goto out;
+ }
+
+ assoc_req->channel = fwrq->m;
+ ret = 0;
+
+out:
+ if (ret == 0) {
+ set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
+ wlan_postpone_association_work(priv);
+ } else {
+ wlan_cancel_association_work(priv);
}
+ mutex_unlock(&adapter->lock);
- LEAVE();
- return rc;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
/**
@@ -1338,9 +1265,9 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
u8 rates[WLAN_SUPPORTED_RATES];
u8 *rate;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
- lbs_pr_debug(1, "Vwrq->value = %d\n", vwrq->value);
+ lbs_deb_wext("vwrq->value %d\n", vwrq->value);
if (vwrq->value == -1) {
action = cmd_act_set_tx_auto; // Auto
@@ -1357,15 +1284,15 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
get_active_data_rates(adapter, rates);
rate = rates;
while (*rate) {
- lbs_pr_debug(1, "Rate=0x%X Wanted=0x%X\n", *rate,
+ lbs_deb_wext("rate=0x%X, wanted data_rate 0x%X\n", *rate,
data_rate);
if ((*rate & 0x7f) == (data_rate & 0x7f))
break;
rate++;
}
if (!*rate) {
- lbs_pr_alert( "The fixed data rate 0x%X is out "
- "of range.\n", data_rate);
+ lbs_pr_alert("fixed data rate 0x%X out "
+ "of range\n", data_rate);
return -EINVAL;
}
@@ -1377,7 +1304,7 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
ret = libertas_prepare_and_send_command(priv, cmd_802_11_data_rate,
action, cmd_option_waitforrsp, 0, NULL);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -1387,7 +1314,7 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->is_datarate_auto) {
vwrq->fixed = 0;
@@ -1397,7 +1324,7 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
vwrq->value = adapter->datarate * 500000;
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -1409,12 +1336,12 @@ static int wlan_set_mode(struct net_device *dev,
wlan_adapter *adapter = priv->adapter;
struct assoc_request * assoc_req;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if ( (*uwrq != IW_MODE_ADHOC)
&& (*uwrq != IW_MODE_INFRA)
&& (*uwrq != IW_MODE_AUTO)) {
- lbs_pr_debug(1, "Invalid mode: 0x%x\n", *uwrq);
+ lbs_deb_wext("Invalid mode: 0x%x\n", *uwrq);
ret = -EINVAL;
goto out;
}
@@ -1428,12 +1355,12 @@ static int wlan_set_mode(struct net_device *dev,
assoc_req->mode = *uwrq;
set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
wlan_postpone_association_work(priv);
- lbs_pr_debug(1, "Switching to mode: 0x%x\n", *uwrq);
+ lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq);
}
mutex_unlock(&adapter->lock);
out:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -1455,9 +1382,9 @@ static int wlan_get_encode(struct net_device *dev,
wlan_adapter *adapter = priv->adapter;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
- lbs_pr_debug(1, "flags=0x%x index=%d length=%d wep_tx_keyidx=%d\n",
+ lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n",
dwrq->flags, index, dwrq->length, adapter->wep_tx_keyidx);
dwrq->flags = 0;
@@ -1513,13 +1440,13 @@ static int wlan_get_encode(struct net_device *dev,
dwrq->flags |= IW_ENCODE_NOKEY;
- lbs_pr_debug(1, "key:%02x:%02x:%02x:%02x:%02x:%02x keylen=%d\n",
+ lbs_deb_wext("key: " MAC_FMT ", keylen %d\n",
extra[0], extra[1], extra[2],
extra[3], extra[4], extra[5], dwrq->length);
- lbs_pr_debug(1, "Return flags=0x%x\n", dwrq->flags);
+ lbs_deb_wext("return flags 0x%x\n", dwrq->flags);
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -1539,20 +1466,21 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req,
u16 index,
int set_tx_key)
{
+ int ret = 0;
struct WLAN_802_11_KEY *pkey;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
/* Paranoid validation of key index */
if (index > 3) {
- LEAVE();
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
/* validate max key length */
if (key_length > KEY_LEN_WEP_104) {
- LEAVE();
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
pkey = &assoc_req->wep_keys[index];
@@ -1570,17 +1498,18 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req,
if (set_tx_key) {
/* Ensure the chosen key is valid */
if (!pkey->len) {
- lbs_pr_debug(1, "key not set, so cannot enable it\n");
- LEAVE();
- return -EINVAL;
+ lbs_deb_wext("key not set, so cannot enable it\n");
+ ret = -EINVAL;
+ goto out;
}
assoc_req->wep_tx_keyidx = index;
}
assoc_req->secinfo.wep_enabled = 1;
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
static int validate_key_index(u16 def_index, u16 raw_index,
@@ -1605,6 +1534,8 @@ static void disable_wep(struct assoc_request *assoc_req)
{
int i;
+ lbs_deb_enter(LBS_DEB_WEXT);
+
/* Set Open System auth mode */
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
@@ -1615,6 +1546,27 @@ static void disable_wep(struct assoc_request *assoc_req)
set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
+
+ lbs_deb_leave(LBS_DEB_WEXT);
+}
+
+static void disable_wpa(struct assoc_request *assoc_req)
+{
+ lbs_deb_enter(LBS_DEB_WEXT);
+
+ memset(&assoc_req->wpa_mcast_key, 0, sizeof (struct WLAN_802_11_KEY));
+ assoc_req->wpa_mcast_key.flags = KEY_INFO_WPA_MCAST;
+ set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
+
+ memset(&assoc_req->wpa_unicast_key, 0, sizeof (struct WLAN_802_11_KEY));
+ assoc_req->wpa_unicast_key.flags = KEY_INFO_WPA_UNICAST;
+ set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
+
+ assoc_req->secinfo.WPAenabled = 0;
+ assoc_req->secinfo.WPA2enabled = 0;
+ set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
+
+ lbs_deb_leave(LBS_DEB_WEXT);
}
/**
@@ -1636,7 +1588,7 @@ static int wlan_set_encode(struct net_device *dev,
struct assoc_request * assoc_req;
u16 is_default = 0, index = 0, set_tx_key = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
@@ -1647,6 +1599,7 @@ static int wlan_set_encode(struct net_device *dev,
if (dwrq->flags & IW_ENCODE_DISABLED) {
disable_wep (assoc_req);
+ disable_wpa (assoc_req);
goto out;
}
@@ -1688,7 +1641,7 @@ out:
}
mutex_unlock(&adapter->lock);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -1712,7 +1665,7 @@ static int wlan_get_encodeext(struct net_device *dev,
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
int index, max_key_len;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
max_key_len = dwrq->length - sizeof(*ext);
if (max_key_len < 0)
@@ -1748,6 +1701,7 @@ static int wlan_get_encodeext(struct net_device *dev,
if ( adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled) {
+ /* WEP */
ext->alg = IW_ENCODE_ALG_WEP;
ext->key_len = adapter->wep_keys[index].len;
key = &adapter->wep_keys[index].key[0];
@@ -1755,8 +1709,27 @@ static int wlan_get_encodeext(struct net_device *dev,
&& (adapter->secinfo.WPAenabled ||
adapter->secinfo.WPA2enabled)) {
/* WPA */
- ext->alg = IW_ENCODE_ALG_TKIP;
- ext->key_len = 0;
+ struct WLAN_802_11_KEY * pkey = NULL;
+
+ if ( adapter->wpa_mcast_key.len
+ && (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
+ pkey = &adapter->wpa_mcast_key;
+ else if ( adapter->wpa_unicast_key.len
+ && (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
+ pkey = &adapter->wpa_unicast_key;
+
+ if (pkey) {
+ if (pkey->type == KEY_TYPE_ID_AES) {
+ ext->alg = IW_ENCODE_ALG_CCMP;
+ } else {
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ }
+ ext->key_len = pkey->len;
+ key = &pkey->key[0];
+ } else {
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ ext->key_len = 0;
+ }
} else {
goto out;
}
@@ -1775,7 +1748,7 @@ static int wlan_get_encodeext(struct net_device *dev,
ret = 0;
out:
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -1800,7 +1773,7 @@ static int wlan_set_encodeext(struct net_device *dev,
int alg = ext->alg;
struct assoc_request * assoc_req;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
@@ -1811,6 +1784,7 @@ static int wlan_set_encodeext(struct net_device *dev,
if ((alg == IW_ENCODE_ALG_NONE) || (dwrq->flags & IW_ENCODE_DISABLED)) {
disable_wep (assoc_req);
+ disable_wpa (assoc_req);
} else if (alg == IW_ENCODE_ALG_WEP) {
u16 is_default = 0, index, set_tx_key = 0;
@@ -1846,7 +1820,6 @@ static int wlan_set_encodeext(struct net_device *dev,
set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags);
if (set_tx_key)
set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
-
} else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
struct WLAN_802_11_KEY * pkey;
@@ -1855,36 +1828,43 @@ static int wlan_set_encodeext(struct net_device *dev,
&& (ext->key_len != KEY_LEN_WPA_TKIP))
|| ((alg == IW_ENCODE_ALG_CCMP)
&& (ext->key_len != KEY_LEN_WPA_AES))) {
- lbs_pr_debug(1, "Invalid size %d for key of alg"
- "type %d.\n",
+ lbs_deb_wext("invalid size %d for key of alg"
+ "type %d\n",
ext->key_len,
alg);
ret = -EINVAL;
goto out;
}
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
pkey = &assoc_req->wpa_mcast_key;
- else
+ set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
+ } else {
pkey = &assoc_req->wpa_unicast_key;
+ set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
+ }
memset(pkey, 0, sizeof (struct WLAN_802_11_KEY));
memcpy(pkey->key, ext->key, ext->key_len);
pkey->len = ext->key_len;
- pkey->flags = KEY_INFO_WPA_ENABLED;
+ if (pkey->len)
+ pkey->flags |= KEY_INFO_WPA_ENABLED;
+ /* Do this after zeroing key structure */
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
pkey->flags |= KEY_INFO_WPA_MCAST;
- set_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
} else {
pkey->flags |= KEY_INFO_WPA_UNICAST;
- set_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
}
- if (alg == IW_ENCODE_ALG_TKIP)
+ if (alg == IW_ENCODE_ALG_TKIP) {
pkey->type = KEY_TYPE_ID_TKIP;
- else if (alg == IW_ENCODE_ALG_CCMP)
+ } else if (alg == IW_ENCODE_ALG_CCMP) {
pkey->type = KEY_TYPE_ID_AES;
+ } else {
+ ret = -EINVAL;
+ goto out;
+ }
/* If WPA isn't enabled yet, do that now */
if ( assoc_req->secinfo.WPAenabled == 0
@@ -1905,7 +1885,7 @@ out:
}
mutex_unlock(&adapter->lock);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -1920,7 +1900,7 @@ static int wlan_set_genie(struct net_device *dev,
int ret = 0;
struct assoc_request * assoc_req;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
@@ -1952,7 +1932,7 @@ out:
}
mutex_unlock(&adapter->lock);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -1961,27 +1941,28 @@ static int wlan_get_genie(struct net_device *dev,
struct iw_point *dwrq,
char *extra)
{
+ int ret = 0;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (adapter->wpa_ie_len == 0) {
dwrq->length = 0;
- LEAVE();
- return 0;
+ goto out;
}
if (dwrq->length < adapter->wpa_ie_len) {
- LEAVE();
- return -E2BIG;
+ ret = -E2BIG;
+ goto out;
}
dwrq->length = adapter->wpa_ie_len;
memcpy(extra, &adapter->wpa_ie[0], adapter->wpa_ie_len);
- LEAVE();
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
@@ -1996,7 +1977,7 @@ static int wlan_set_auth(struct net_device *dev,
int ret = 0;
int updated = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
@@ -2010,6 +1991,7 @@ static int wlan_set_auth(struct net_device *dev,
case IW_AUTH_CIPHER_PAIRWISE:
case IW_AUTH_CIPHER_GROUP:
case IW_AUTH_KEY_MGMT:
+ case IW_AUTH_DROP_UNENCRYPTED:
/*
* libertas does not use these parameters
*/
@@ -2019,6 +2001,7 @@ static int wlan_set_auth(struct net_device *dev,
if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) {
assoc_req->secinfo.WPAenabled = 0;
assoc_req->secinfo.WPA2enabled = 0;
+ disable_wpa (assoc_req);
}
if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
assoc_req->secinfo.WPAenabled = 1;
@@ -2033,17 +2016,6 @@ static int wlan_set_auth(struct net_device *dev,
updated = 1;
break;
- case IW_AUTH_DROP_UNENCRYPTED:
- if (dwrq->value) {
- adapter->currentpacketfilter |=
- cmd_act_mac_strict_protection_enable;
- } else {
- adapter->currentpacketfilter &=
- ~cmd_act_mac_strict_protection_enable;
- }
- updated = 1;
- break;
-
case IW_AUTH_80211_AUTH_ALG:
if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
@@ -2069,6 +2041,7 @@ static int wlan_set_auth(struct net_device *dev,
} else {
assoc_req->secinfo.WPAenabled = 0;
assoc_req->secinfo.WPA2enabled = 0;
+ disable_wpa (assoc_req);
}
updated = 1;
break;
@@ -2088,7 +2061,7 @@ out:
}
mutex_unlock(&adapter->lock);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -2097,10 +2070,11 @@ static int wlan_get_auth(struct net_device *dev,
struct iw_param *dwrq,
char *extra)
{
+ int ret = 0;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
switch (dwrq->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
@@ -2113,13 +2087,6 @@ static int wlan_get_auth(struct net_device *dev,
dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
break;
- case IW_AUTH_DROP_UNENCRYPTED:
- dwrq->value = 0;
- if (adapter->currentpacketfilter &
- cmd_act_mac_strict_protection_enable)
- dwrq->value = 1;
- break;
-
case IW_AUTH_80211_AUTH_ALG:
dwrq->value = adapter->secinfo.auth_mode;
break;
@@ -2130,12 +2097,11 @@ static int wlan_get_auth(struct net_device *dev,
break;
default:
- LEAVE();
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
}
- LEAVE();
- return 0;
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
@@ -2148,7 +2114,7 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
u16 dbm;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (vwrq->disabled) {
wlan_radio_ioctl(priv, RADIO_OFF);
@@ -2169,14 +2135,14 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
if (vwrq->fixed == 0)
dbm = 0xffff;
- lbs_pr_debug(1, "<1>TXPOWER SET %d dbm.\n", dbm);
+ lbs_deb_wext("txpower set %d dbm\n", dbm);
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_rf_tx_power,
cmd_act_tx_power_opt_set_low,
cmd_option_waitforrsp, 0, (void *)&dbm);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -2186,7 +2152,8 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
+
/*
* Note : if dwrq->flags != 0, we should get the relevant SSID from
* the SSID list...
@@ -2196,12 +2163,12 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
* Get the current SSID
*/
if (adapter->connect_status == libertas_connected) {
- memcpy(extra, adapter->curbssparams.ssid.ssid,
- adapter->curbssparams.ssid.ssidlength);
- extra[adapter->curbssparams.ssid.ssidlength] = '\0';
+ memcpy(extra, adapter->curbssparams.ssid,
+ adapter->curbssparams.ssid_len);
+ extra[adapter->curbssparams.ssid_len] = '\0';
} else {
memset(extra, 0, 32);
- extra[adapter->curbssparams.ssid.ssidlength] = '\0';
+ extra[adapter->curbssparams.ssid_len] = '\0';
}
/*
* If none, we may want to get the one that was set
@@ -2209,14 +2176,14 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
/* To make the driver backward compatible with WPA supplicant v0.2.4 */
if (dwrq->length == 32) /* check with WPA supplicant buffer size */
- dwrq->length = min_t(size_t, adapter->curbssparams.ssid.ssidlength,
+ dwrq->length = min_t(size_t, adapter->curbssparams.ssid_len,
IW_ESSID_MAX_SIZE);
else
- dwrq->length = adapter->curbssparams.ssid.ssidlength + 1;
+ dwrq->length = adapter->curbssparams.ssid_len + 1;
dwrq->flags = 1; /* active */
- LEAVE();
+ lbs_deb_leave(LBS_DEB_WEXT);
return 0;
}
@@ -2226,38 +2193,43 @@ static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- struct WLAN_802_11_SSID ssid;
+ u8 ssid[IW_ESSID_MAX_SIZE];
+ u8 ssid_len = 0;
struct assoc_request * assoc_req;
- int ssid_len = dwrq->length;
+ int in_ssid_len = dwrq->length;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
/*
* WE-20 and earlier NULL pad the end of the SSID and increment
* SSID length so it can be used like a string. WE-21 and later don't,
* but some userspace tools aren't able to cope with the change.
*/
- if ((ssid_len > 0) && (extra[ssid_len - 1] == '\0'))
- ssid_len--;
+ if ((in_ssid_len > 0) && (extra[in_ssid_len - 1] == '\0'))
+ in_ssid_len--;
/* Check the size of the string */
- if (ssid_len > IW_ESSID_MAX_SIZE) {
+ if (in_ssid_len > IW_ESSID_MAX_SIZE) {
ret = -E2BIG;
goto out;
}
- memset(&ssid, 0, sizeof(struct WLAN_802_11_SSID));
+ memset(&ssid, 0, sizeof(ssid));
- if (!dwrq->flags || !ssid_len) {
+ if (!dwrq->flags || !in_ssid_len) {
/* "any" SSID requested; leave SSID blank */
} else {
/* Specific SSID requested */
- memcpy(&ssid.ssid, extra, ssid_len);
- ssid.ssidlength = ssid_len;
+ memcpy(&ssid, extra, in_ssid_len);
+ ssid_len = in_ssid_len;
}
- lbs_pr_debug(1, "Requested new SSID = %s\n",
- (ssid.ssidlength > 0) ? (char *)ssid.ssid : "any");
+ if (!ssid_len) {
+ lbs_deb_wext("requested any SSID\n");
+ } else {
+ lbs_deb_wext("requested SSID '%s'\n",
+ escape_essid(ssid, ssid_len));
+ }
out:
mutex_lock(&adapter->lock);
@@ -2268,7 +2240,8 @@ out:
ret = -ENOMEM;
} else {
/* Copy the SSID to the association request */
- memcpy(&assoc_req->ssid, &ssid, sizeof(struct WLAN_802_11_SSID));
+ memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE);
+ assoc_req->ssid_len = ssid_len;
set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
wlan_postpone_association_work(priv);
}
@@ -2281,7 +2254,7 @@ out:
mutex_unlock(&adapter->lock);
- LEAVE();
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
}
@@ -2302,12 +2275,12 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
struct assoc_request * assoc_req;
int ret = 0;
- ENTER();
+ lbs_deb_enter(LBS_DEB_WEXT);
if (awrq->sa_family != ARPHRD_ETHER)
return -EINVAL;
- lbs_pr_debug(1, "ASSOC: WAP: sa_data: " MAC_FMT "\n", MAC_ARG(awrq->sa_data));
+ lbs_deb_wext("ASSOC: WAP: sa_data " MAC_FMT "\n", MAC_ARG(awrq->sa_data));
mutex_lock(&adapter->lock);
@@ -2330,22 +2303,23 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen)
{
- union {
- u32 l;
- u8 c[4];
- } ver;
char fwver[32];
mutex_lock(&adapter->lock);
- ver.l = adapter->fwreleasenumber;
- mutex_unlock(&adapter->lock);
- if (ver.c[3] == 0)
- sprintf(fwver, "%u.%u.%u", ver.c[2], ver.c[1], ver.c[0]);
+ if (adapter->fwreleasenumber[3] == 0)
+ sprintf(fwver, "%u.%u.%u",
+ adapter->fwreleasenumber[2],
+ adapter->fwreleasenumber[1],
+ adapter->fwreleasenumber[0]);
else
sprintf(fwver, "%u.%u.%u.p%u",
- ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
+ adapter->fwreleasenumber[2],
+ adapter->fwreleasenumber[1],
+ adapter->fwreleasenumber[0],
+ adapter->fwreleasenumber[3]);
+ mutex_unlock(&adapter->lock);
snprintf(fwversion, maxlen, fwver);
}
@@ -2411,6 +2385,63 @@ static const iw_handler wlan_handler[] = {
(iw_handler) NULL, /* SIOCSIWPMKSA */
};
+static const iw_handler mesh_wlan_handler[] = {
+ (iw_handler) NULL, /* SIOCSIWCOMMIT */
+ (iw_handler) wlan_get_name, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) wlan_set_freq, /* SIOCSIWFREQ */
+ (iw_handler) wlan_get_freq, /* SIOCGIWFREQ */
+ (iw_handler) NULL, /* SIOCSIWMODE */
+ (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL, /* SIOCSIWRANGE */
+ (iw_handler) wlan_get_range, /* SIOCGIWRANGE */
+ (iw_handler) NULL, /* SIOCSIWPRIV */
+ (iw_handler) NULL, /* SIOCGIWPRIV */
+ (iw_handler) NULL, /* SIOCSIWSTATS */
+ (iw_handler) NULL, /* SIOCGIWSTATS */
+ iw_handler_set_spy, /* SIOCSIWSPY */
+ iw_handler_get_spy, /* SIOCGIWSPY */
+ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
+ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
+ (iw_handler) NULL, /* SIOCSIWAP */
+ (iw_handler) NULL, /* SIOCGIWAP */
+ (iw_handler) NULL, /* SIOCSIWMLME */
+ (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */
+ (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */
+ (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */
+ (iw_handler) NULL, /* SIOCSIWESSID */
+ (iw_handler) NULL, /* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) wlan_set_rate, /* SIOCSIWRATE */
+ (iw_handler) wlan_get_rate, /* SIOCGIWRATE */
+ (iw_handler) wlan_set_rts, /* SIOCSIWRTS */
+ (iw_handler) wlan_get_rts, /* SIOCGIWRTS */
+ (iw_handler) wlan_set_frag, /* SIOCSIWFRAG */
+ (iw_handler) wlan_get_frag, /* SIOCGIWFRAG */
+ (iw_handler) wlan_set_txpow, /* SIOCSIWTXPOW */
+ (iw_handler) wlan_get_txpow, /* SIOCGIWTXPOW */
+ (iw_handler) wlan_set_retry, /* SIOCSIWRETRY */
+ (iw_handler) wlan_get_retry, /* SIOCGIWRETRY */
+ (iw_handler) wlan_set_encode, /* SIOCSIWENCODE */
+ (iw_handler) wlan_get_encode, /* SIOCGIWENCODE */
+ (iw_handler) wlan_set_power, /* SIOCSIWPOWER */
+ (iw_handler) wlan_get_power, /* SIOCGIWPOWER */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) wlan_set_genie, /* SIOCSIWGENIE */
+ (iw_handler) wlan_get_genie, /* SIOCGIWGENIE */
+ (iw_handler) wlan_set_auth, /* SIOCSIWAUTH */
+ (iw_handler) wlan_get_auth, /* SIOCGIWAUTH */
+ (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */
+ (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */
+ (iw_handler) NULL, /* SIOCSIWPMKSA */
+};
struct iw_handler_def libertas_handler_def = {
.num_standard = sizeof(wlan_handler) / sizeof(iw_handler),
.num_private = sizeof(wlan_private_handler) / sizeof(iw_handler),
@@ -2421,3 +2452,14 @@ struct iw_handler_def libertas_handler_def = {
.private_args = (struct iw_priv_args *)wlan_private_args,
.get_wireless_stats = wlan_get_wireless_stats,
};
+
+struct iw_handler_def mesh_handler_def = {
+ .num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler),
+ .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler),
+ .num_private_args = sizeof(wlan_private_args) /
+ sizeof(struct iw_priv_args),
+ .standard = (iw_handler *) mesh_wlan_handler,
+ .private = (iw_handler *) wlan_private_handler,
+ .private_args = (struct iw_priv_args *)wlan_private_args,
+ .get_wireless_stats = wlan_get_wireless_stats,
+};
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
index 15cfaaf0797..d555056b25b 100644
--- a/drivers/net/wireless/libertas/wext.h
+++ b/drivers/net/wireless/libertas/wext.h
@@ -20,21 +20,23 @@
#define WLAN_SUBCMD_FWT_CLEANUP 15
#define WLAN_SUBCMD_FWT_TIME 16
#define WLAN_SUBCMD_MESH_GET_TTL 17
+#define WLAN_SUBCMD_BT_GET_INVERT 18
#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24)
#define WLANSETREGION 8
#define WLAN_SUBCMD_MESH_SET_TTL 18
+#define WLAN_SUBCMD_BT_SET_INVERT 19
#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25)
#define WLAN_SUBCMD_BT_ADD 18
#define WLAN_SUBCMD_BT_DEL 19
#define WLAN_SUBCMD_BT_LIST 20
-#define WLAN_SUBCMD_FWT_ADD 21
-#define WLAN_SUBCMD_FWT_DEL 22
-#define WLAN_SUBCMD_FWT_LOOKUP 23
-#define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24
+#define WLAN_SUBCMD_FWT_ADD 21
+#define WLAN_SUBCMD_FWT_DEL 22
+#define WLAN_SUBCMD_FWT_LOOKUP 23
+#define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24
#define WLAN_SUBCMD_FWT_LIST 25
-#define WLAN_SUBCMD_FWT_LIST_ROUTE 26
+#define WLAN_SUBCMD_FWT_LIST_ROUTE 26
#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29)
#define WLAN_LED_GPIO_CTRL 5
@@ -56,6 +58,7 @@ struct wlan_ioctl_regrdwr {
};
extern struct iw_handler_def libertas_handler_def;
+extern struct iw_handler_def mesh_handler_def;
int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i);
int wlan_radio_ioctl(wlan_private * priv, u8 option);
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index dd070cccf32..f49eb068c7d 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -378,9 +378,10 @@ islpci_eth_receive(islpci_private *priv)
display_buffer((char *) skb->data, skb->len);
#endif
/* take care of monitor mode and spy monitoring. */
- if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
+ if (unlikely(priv->iw_mode == IW_MODE_MONITOR)) {
+ skb->dev = ndev;
discard = islpci_monitor_rx(priv, &skb);
- else {
+ } else {
if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
/* The packet has a rx_annex. Read it for spy monitoring, Then
* remove it, while keeping the 2 leading MAC addr.
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d9cbd586ae4..be1df85e5e2 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -15,10 +15,10 @@
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/msi.h>
+#include <linux/smp.h>
#include <asm/errno.h>
#include <asm/io.h>
-#include <asm/smp.h>
#include "pci.h"
#include "msi.h"
@@ -333,7 +333,7 @@ static int msi_capability_init(struct pci_dev *dev)
msi_mask_bits_reg(pos, is_64bit_address(control)),
maskbits);
}
- list_add(&entry->list, &dev->msi_list);
+ list_add_tail(&entry->list, &dev->msi_list);
/* Configure MSI capability structure */
ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI);
@@ -404,7 +404,7 @@ static int msix_capability_init(struct pci_dev *dev,
entry->dev = dev;
entry->mask_base = base;
- list_add(&entry->list, &dev->msi_list);
+ list_add_tail(&entry->list, &dev->msi_list);
}
ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
@@ -558,12 +558,12 @@ static int msi_free_irqs(struct pci_dev* dev)
list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) {
- if (list_is_last(&entry->list, &dev->msi_list))
- iounmap(entry->mask_base);
-
writel(1, entry->mask_base + entry->msi_attrib.entry_nr
* PCI_MSIX_ENTRY_SIZE
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+
+ if (list_is_last(&entry->list, &dev->msi_list))
+ iounmap(entry->mask_base);
}
list_del(&entry->list);
kfree(entry);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6ccc2e95930..01d8f8a8843 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1625,18 +1625,22 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap);
#ifdef CONFIG_PCI_MSI
-/* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely
- * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
- * some other busses controlled by the chipset even if Linux is not aware of it.
- * Instead of setting the flag on all busses in the machine, simply disable MSI
- * globally.
+/* Some chipsets do not support MSI. We cannot easily rely on setting
+ * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
+ * some other busses controlled by the chipset even if Linux is not
+ * aware of it. Instead of setting the flag on all busses in the
+ * machine, simply disable MSI globally.
*/
-static void __init quirk_svw_msi(struct pci_dev *dev)
+static void __init quirk_disable_all_msi(struct pci_dev *dev)
{
pci_no_msi();
printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n");
}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
/* Disable MSI on chipsets that are known to not support it */
static void __devinit quirk_disable_msi(struct pci_dev *dev)
@@ -1649,8 +1653,6 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_msi);
/* Go through the list of Hypertransport capabilities and
* return 1 if a HT MSI capability is found and enabled */
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index b137a27472c..c13232435dc 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -403,10 +403,11 @@ const struct pci_device_id *pci_find_present(const struct pci_device_id *ids)
while (ids->vendor || ids->subvendor || ids->class_mask) {
list_for_each_entry(dev, &pci_devices, global_list) {
if ((found = pci_match_one_device(ids, dev)) != NULL)
- break;
+ goto exit;
}
ids++;
}
+exit:
up_read(&pci_bus_sem);
return found;
}
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 948efc775a7..eb6abd3f922 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -336,16 +336,21 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
enable_irq_wake(board->det_pin);
if (board->irq_pin)
enable_irq_wake(board->irq_pin);
- } else {
- disable_irq_wake(board->det_pin);
- if (board->irq_pin)
- disable_irq_wake(board->irq_pin);
}
return 0;
}
static int at91_cf_resume(struct platform_device *pdev)
{
+ struct at91_cf_socket *cf = platform_get_drvdata(pdev);
+ struct at91_cf_data *board = cf->board;
+
+ if (device_may_wakeup(&pdev->dev)) {
+ disable_irq_wake(board->det_pin);
+ if (board->irq_pin)
+ disable_irq_wake(board->irq_pin);
+ }
+
pcmcia_socket_dev_resume(&pdev->dev);
return 0;
}
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 6085261aa2c..e24ea82dc35 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -641,9 +641,16 @@ cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
* drivers can't provide shutdown() methods to disable IRQs.
* Or better yet, fix PNP to allow those methods...
*/
- return cmos_do_probe(&pnp->dev,
- &pnp->res.port_resource[0],
- pnp->res.irq_resource[0].start);
+ if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
+ /* Some machines contain a PNP entry for the RTC, but
+ * don't define the IRQ. It should always be safe to
+ * hardcode it in these cases
+ */
+ return cmos_do_probe(&pnp->dev, &pnp->res.port_resource[0], 8);
+ else
+ return cmos_do_probe(&pnp->dev,
+ &pnp->res.port_resource[0],
+ pnp->res.irq_resource[0].start);
}
static void __exit cmos_pnp_remove(struct pnp_dev *pnp)
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index a1dc8c466ec..0c081a664ee 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -14,9 +14,9 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/poll.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
-#include <asm/semaphore.h>
#include <asm/atomic.h>
#include <asm/ebcdic.h>
@@ -514,7 +514,7 @@ void dasd_eer_disable(struct dasd_device *device)
* to transfer in a readbuffer, which is protected by the readbuffer_mutex.
*/
static char readbuffer[PAGE_SIZE];
-static DECLARE_MUTEX(readbuffer_mutex);
+static DEFINE_MUTEX(readbuffer_mutex);
static int dasd_eer_open(struct inode *inp, struct file *filp)
{
@@ -579,7 +579,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
struct eerbuffer *eerb;
eerb = (struct eerbuffer *) filp->private_data;
- if (down_interruptible(&readbuffer_mutex))
+ if (mutex_lock_interruptible(&readbuffer_mutex))
return -ERESTARTSYS;
spin_lock_irqsave(&bufferlock, flags);
@@ -588,7 +588,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
/* has been deleted */
eerb->residual = 0;
spin_unlock_irqrestore(&bufferlock, flags);
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
return -EIO;
} else if (eerb->residual > 0) {
/* OK we still have a second half of a record to deliver */
@@ -602,7 +602,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
if (!tc) {
/* no data available */
spin_unlock_irqrestore(&bufferlock, flags);
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
rc = wait_event_interruptible(
@@ -610,7 +610,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
eerb->head != eerb->tail);
if (rc)
return rc;
- if (down_interruptible(&readbuffer_mutex))
+ if (mutex_lock_interruptible(&readbuffer_mutex))
return -ERESTARTSYS;
spin_lock_irqsave(&bufferlock, flags);
}
@@ -626,11 +626,11 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
spin_unlock_irqrestore(&bufferlock, flags);
if (copy_to_user(buf, readbuffer, effective_count)) {
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
return -EFAULT;
}
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
return effective_count;
}
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index f6ef90ee3e7..743944ad61e 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -487,7 +487,7 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */
} __attribute__ ((packed));
static struct diag210 raw3270_init_diag210;
-static DECLARE_MUTEX(raw3270_init_sem);
+static DEFINE_MUTEX(raw3270_init_mutex);
static int
raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
@@ -713,7 +713,7 @@ raw3270_size_device(struct raw3270 *rp)
{
int rc;
- down(&raw3270_init_sem);
+ mutex_lock(&raw3270_init_mutex);
rp->view = &raw3270_init_view;
raw3270_init_view.dev = rp;
if (MACHINE_IS_VM)
@@ -722,7 +722,7 @@ raw3270_size_device(struct raw3270 *rp)
rc = __raw3270_size_device(rp);
raw3270_init_view.dev = NULL;
rp->view = NULL;
- up(&raw3270_init_sem);
+ mutex_unlock(&raw3270_init_mutex);
if (rc == 0) { /* Found something. */
/* Try to find a model. */
rp->model = 0;
@@ -749,7 +749,7 @@ raw3270_reset_device(struct raw3270 *rp)
{
int rc;
- down(&raw3270_init_sem);
+ mutex_lock(&raw3270_init_mutex);
memset(&rp->init_request, 0, sizeof(rp->init_request));
memset(&rp->init_data, 0, sizeof(rp->init_data));
/* Store reset data stream to init_data/init_request */
@@ -764,7 +764,7 @@ raw3270_reset_device(struct raw3270 *rp)
rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
raw3270_init_view.dev = NULL;
rp->view = NULL;
- up(&raw3270_init_sem);
+ mutex_unlock(&raw3270_init_mutex);
return rc;
}
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index a8b373f69cf..6b264bdb5bf 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -296,30 +296,57 @@ static void ccw_device_unregister(struct ccw_device *cdev)
device_del(&cdev->dev);
}
+static void ccw_device_remove_orphan_cb(struct device *dev)
+{
+ struct ccw_device *cdev = to_ccwdev(dev);
+
+ ccw_device_unregister(cdev);
+ put_device(&cdev->dev);
+}
+
+static void ccw_device_remove_sch_cb(struct device *dev)
+{
+ struct subchannel *sch;
+
+ sch = to_subchannel(dev);
+ css_sch_device_unregister(sch);
+ /* Reset intparm to zeroes. */
+ sch->schib.pmcw.intparm = 0;
+ cio_modify(sch);
+ put_device(&sch->dev);
+}
+
static void
ccw_device_remove_disconnected(struct ccw_device *cdev)
{
- struct subchannel *sch;
unsigned long flags;
+ int rc;
+
/*
* Forced offline in disconnected state means
* 'throw away device'.
*/
if (ccw_device_is_orphan(cdev)) {
- /* Deregister ccw device. */
+ /*
+ * Deregister ccw device.
+ * Unfortunately, we cannot do this directly from the
+ * attribute method.
+ */
spin_lock_irqsave(cdev->ccwlock, flags);
cdev->private->state = DEV_STATE_NOT_OPER;
spin_unlock_irqrestore(cdev->ccwlock, flags);
- ccw_device_unregister(cdev);
- put_device(&cdev->dev);
- return ;
+ rc = device_schedule_callback(&cdev->dev,
+ ccw_device_remove_orphan_cb);
+ if (rc)
+ dev_info(&cdev->dev, "Couldn't unregister orphan\n");
+ return;
}
- sch = to_subchannel(cdev->dev.parent);
- css_sch_device_unregister(sch);
- /* Reset intparm to zeroes. */
- sch->schib.pmcw.intparm = 0;
- cio_modify(sch);
- put_device(&sch->dev);
+ /* Deregister subchannel, which will kill the ccw device. */
+ rc = device_schedule_callback(cdev->dev.parent,
+ ccw_device_remove_sch_cb);
+ if (rc)
+ dev_info(&cdev->dev,
+ "Couldn't unregister disconnected device\n");
}
int
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 898ec3b2beb..6bba8092957 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -688,6 +688,12 @@ ccw_device_disband_done(struct ccw_device *cdev, int err)
ccw_device_done(cdev, DEV_STATE_BOXED);
break;
default:
+ cdev->private->flags.donotify = 0;
+ if (get_device(&cdev->dev)) {
+ PREPARE_WORK(&cdev->private->kick_work,
+ ccw_device_call_sch_unregister);
+ queue_work(ccw_device_work, &cdev->private->kick_work);
+ }
ccw_device_done(cdev, DEV_STATE_NOT_OPER);
break;
}
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index ddff40c4212..821cde65e36 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -1127,6 +1127,7 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
int retval = 0;
unsigned long flags;
+ zfcp_adapter_scsi_unregister(adapter);
device_unregister(&adapter->generic_services);
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 81680efa172..1c8f71a5985 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -189,9 +189,7 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
* @ccw_device: pointer to belonging ccw device
*
* This function gets called by the common i/o layer and sets an adapter
- * into state offline. Setting an fcp device offline means that it will be
- * unregistered from the SCSI stack and that the adapter will be shut down
- * asynchronously.
+ * into state offline.
*/
static int
zfcp_ccw_set_offline(struct ccw_device *ccw_device)
@@ -202,7 +200,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
adapter = dev_get_drvdata(&ccw_device->dev);
zfcp_erp_adapter_shutdown(adapter, 0);
zfcp_erp_wait(adapter);
- zfcp_adapter_scsi_unregister(adapter);
zfcp_erp_thread_kill(adapter);
zfcp_adapter_debug_unregister(adapter);
up(&zfcp_data.config_sema);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index a8b02542ac2..0eb31e162b1 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -156,44 +156,30 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
kfree(fsf_req);
}
-/**
- * zfcp_fsf_req_dismiss - dismiss a single fsf request
- */
-static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
- struct zfcp_fsf_req *fsf_req,
- unsigned int counter)
-{
- u64 dbg_tmp[2];
-
- dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
- dbg_tmp[1] = (u64) counter;
- debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
- list_del(&fsf_req->list);
- fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
- zfcp_fsf_req_complete(fsf_req);
-}
-
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
+/*
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
*/
void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
- struct zfcp_fsf_req *request, *tmp;
+ struct zfcp_fsf_req *fsf_req, *tmp;
unsigned long flags;
LIST_HEAD(remove_queue);
- unsigned int i, counter;
+ unsigned int i;
+ BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status));
spin_lock_irqsave(&adapter->req_list_lock, flags);
atomic_set(&adapter->reqs_active, 0);
- for (i=0; i<REQUEST_LIST_SIZE; i++)
+ for (i = 0; i < REQUEST_LIST_SIZE; i++)
list_splice_init(&adapter->req_list[i], &remove_queue);
-
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
- counter = 0;
- list_for_each_entry_safe(request, tmp, &remove_queue, list) {
- zfcp_fsf_req_dismiss(adapter, request, counter);
- counter++;
+ list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
+ list_del(&fsf_req->list);
+ fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+ zfcp_fsf_req_complete(fsf_req);
}
}
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 16e2d64658a..0acf6db0a08 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -569,6 +569,9 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
int retval = 0;
static unsigned int unique_id = 0;
+ if (adapter->scsi_host)
+ goto out;
+
/* register adapter as SCSI host with mid layer of SCSI stack */
adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template,
sizeof (struct zfcp_adapter *));
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 262f01e6859..44e039865aa 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
+#include <linux/mm.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d28c14e23c3..2b2f5c12019 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1532,6 +1532,7 @@ source "drivers/scsi/arm/Kconfig"
config JAZZ_ESP
bool "MIPS JAZZ FAS216 SCSI support"
depends on MACH_JAZZ && SCSI
+ select SCSI_SPI_ATTRS
help
This is the driver for the onboard SCSI host adapter of MIPS Magnum
4000, Acer PICA, Olivetti M700-10 and a few other identical OEM
@@ -1753,23 +1754,10 @@ config SUN3X_ESP
The ESP was an on-board SCSI controller used on Sun 3/80
machines. Say Y here to compile in support for it.
-config SCSI_ESP_CORE
- tristate "ESP Scsi Driver Core"
- depends on SCSI
- select SCSI_SPI_ATTRS
- help
- This is a core driver for NCR53c9x based scsi chipsets,
- also known as "ESP" for Emulex Scsi Processor or
- Enhanced Scsi Processor. This driver does not exist by
- itself, there are front-end drivers which, when enabled,
- select and enable this driver. One example is SCSI_SUNESP.
- These front-end drivers provide probing, DMA, and register
- access support for the core driver.
-
config SCSI_SUNESP
tristate "Sparc ESP Scsi Driver"
depends on SBUS && SCSI
- select SCSI_ESP_CORE
+ select SCSI_SPI_ATTRS
help
This is the driver for the Sun ESP SCSI host adapter. The ESP
chipset is present in most SPARC SBUS-based computers.
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 51e884fa10b..b1b63279158 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -106,8 +106,7 @@ obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
-obj-$(CONFIG_SCSI_ESP_CORE) += esp_scsi.o
-obj-$(CONFIG_SCSI_SUNESP) += sun_esp.o
+obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o
obj-$(CONFIG_SCSI_GDTH) += gdth.o
obj-$(CONFIG_SCSI_INITIO) += initio.o
obj-$(CONFIG_SCSI_INIA100) += a100u2w.o
@@ -121,7 +120,7 @@ obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o
obj-$(CONFIG_SCSI_PPA) += ppa.o
obj-$(CONFIG_SCSI_IMM) += imm.o
-obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
+obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o
obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
obj-$(CONFIG_SCSI_FCAL) += fcal.o
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index bb3cb336054..88ea5a1fb60 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -2625,7 +2625,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
#ifdef REAL_DMA
static void NCR5380_dma_complete(NCR5380_instance * instance) {
NCR5380_local_declare();
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata * instance->hostdata);
+ struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
int transferred;
NCR5380_setup(instance);
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 1e82c69b36b..8dcfe4ec35c 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -146,7 +146,7 @@ static char *aac_get_status_string(u32 status);
static int nondasd = -1;
static int dacmode = -1;
-static int commit = -1;
+int aac_commit = -1;
int startup_timeout = 180;
int aif_timeout = 120;
@@ -154,7 +154,7 @@ module_param(nondasd, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
-module_param(commit, int, S_IRUGO|S_IWUSR);
+module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
@@ -173,6 +173,9 @@ int expose_physicals = -1;
module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
+int aac_reset_devices = 0;
+module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
struct fib *fibptr) {
@@ -246,7 +249,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
aac_fib_complete(fibptr);
/* Send a CT_COMMIT_CONFIG to enable discovery of devices */
if (status >= 0) {
- if ((commit == 1) || commit_flag) {
+ if ((aac_commit == 1) || commit_flag) {
struct aac_commit_config * dinfo;
aac_fib_init(fibptr);
dinfo = (struct aac_commit_config *) fib_data(fibptr);
@@ -261,7 +264,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
1, 1,
NULL, NULL);
aac_fib_complete(fibptr);
- } else if (commit == 0) {
+ } else if (aac_commit == 0) {
printk(KERN_WARNING
"aac_get_config_status: Foreign device configurations are being ignored\n");
}
@@ -340,7 +343,7 @@ int aac_get_containers(struct aac_dev *dev)
static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
{
void *buf;
- unsigned int transfer_len;
+ int transfer_len;
struct scatterlist *sg = scsicmd->request_buffer;
if (scsicmd->use_sg) {
@@ -351,7 +354,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
transfer_len = min(scsicmd->request_bufflen, len + offset);
}
transfer_len -= offset;
- if (buf && transfer_len)
+ if (buf && transfer_len > 0)
memcpy(buf + offset, data, transfer_len);
if (scsicmd->use_sg)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 45ca3e80161..c81edf36913 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1823,9 +1823,12 @@ int aac_send_shutdown(struct aac_dev *dev);
int aac_probe_container(struct aac_dev *dev, int cid);
int _aac_rx_init(struct aac_dev *dev);
int aac_rx_select_comm(struct aac_dev *dev, int comm);
+int aac_rx_deliver_producer(struct fib * fib);
extern int numacb;
extern int acbsize;
extern char aac_driver_version[];
extern int startup_timeout;
extern int aif_timeout;
extern int expose_physicals;
+extern int aac_reset_devices;
+extern int aac_commit;
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 350ea7feb61..5c487ff096c 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -863,6 +863,14 @@ static struct scsi_host_template aac_driver_template = {
.emulated = 1,
};
+static void __aac_shutdown(struct aac_dev * aac)
+{
+ kthread_stop(aac->thread);
+ aac_send_shutdown(aac);
+ aac_adapter_disable_int(aac);
+ free_irq(aac->pdev->irq, aac);
+}
+
static int __devinit aac_probe_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -1015,10 +1023,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
return 0;
out_deinit:
- kthread_stop(aac->thread);
- aac_send_shutdown(aac);
- aac_adapter_disable_int(aac);
- free_irq(pdev->irq, aac);
+ __aac_shutdown(aac);
out_unmap:
aac_fib_map_free(aac);
pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
@@ -1038,7 +1043,8 @@ static void aac_shutdown(struct pci_dev *dev)
{
struct Scsi_Host *shost = pci_get_drvdata(dev);
struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
- aac_send_shutdown(aac);
+ scsi_block_requests(shost);
+ __aac_shutdown(aac);
}
static void __devexit aac_remove_one(struct pci_dev *pdev)
@@ -1048,16 +1054,12 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
scsi_remove_host(shost);
- kthread_stop(aac->thread);
-
- aac_send_shutdown(aac);
- aac_adapter_disable_int(aac);
+ __aac_shutdown(aac);
aac_fib_map_free(aac);
pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
aac->comm_phys);
kfree(aac->queues);
- free_irq(pdev->irq, aac);
aac_adapter_ioremap(aac, 0);
kfree(aac->fibs);
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 291cd14f4e9..ae978a373c5 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -378,7 +378,7 @@ static int aac_rx_check_health(struct aac_dev *dev)
*
* Will send a fib, returning 0 if successful.
*/
-static int aac_rx_deliver_producer(struct fib * fib)
+int aac_rx_deliver_producer(struct fib * fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
@@ -488,6 +488,8 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
return -EINVAL;
if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
return -ENODEV;
+ if (startup_timeout < 300)
+ startup_timeout = 300;
return 0;
}
@@ -542,7 +544,7 @@ int _aac_rx_init(struct aac_dev *dev)
dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
- if ((((status & 0x0c) != 0x0c) || reset_devices) &&
+ if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
!aac_rx_restart_adapter(dev, 0))
++restart;
/*
@@ -594,6 +596,8 @@ int _aac_rx_init(struct aac_dev *dev)
}
msleep(1);
}
+ if (restart)
+ aac_commit = 1;
/*
* Fill in the common function dispatch table.
*/
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index f4b5e9742ab..85b91bc578c 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -5,7 +5,7 @@
* based on the old aacraid driver that is..
* Adaptec aacraid device driver for Linux.
*
- * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
+ * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -257,6 +257,11 @@ static void aac_sa_start_adapter(struct aac_dev *dev)
NULL, NULL, NULL, NULL, NULL);
}
+static int aac_sa_restart_adapter(struct aac_dev *dev, int bled)
+{
+ return -EINVAL;
+}
+
/**
* aac_sa_check_health
* @dev: device to check if healthy
@@ -366,7 +371,9 @@ int aac_sa_init(struct aac_dev *dev)
dev->a_ops.adapter_notify = aac_sa_notify_adapter;
dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
dev->a_ops.adapter_check_health = aac_sa_check_health;
+ dev->a_ops.adapter_restart = aac_sa_restart_adapter;
dev->a_ops.adapter_intr = aac_sa_intr;
+ dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
dev->a_ops.adapter_ioremap = aac_sa_ioremap;
/*
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 9ddc6e4a74b..05f692bd0ad 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -5180,7 +5180,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
cur_lun = lun;
max_lun = lun;
}
- for (cur_lun <= max_lun; cur_lun++) {
+ for (;cur_lun <= max_lun; cur_lun++) {
struct ahd_tmode_lstate* lstate;
lstate = tstate->enabled_luns[cur_lun];
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
index c328596def3..6066998ed56 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
@@ -106,6 +106,7 @@ static void make_expression(expression_t *immed, int value);
static void add_conditional(symbol_t *symbol);
static void add_version(const char *verstring);
static int is_download_const(expression_t *immed);
+void yyerror(const char *string);
#define SRAM_SYMNAME "SRAM_BASE"
#define SCB_SYMNAME "SCB_BASE"
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
index 439f760b34b..ff46aa6801b 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
@@ -65,6 +65,7 @@
static symbol_t *macro_symbol;
static void add_macro_arg(const char *argtext, int position);
+void mmerror(const char *string);
%}
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index 9a14a6d9727..c0d0b7d7a8c 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -290,6 +290,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
static inline int asd_clear_nexus(struct sas_task *task)
{
int res = TMF_RESP_FUNC_FAILED;
+ int leftover;
struct asd_ascb *tascb = task->lldd_task;
unsigned long flags;
@@ -298,10 +299,12 @@ static inline int asd_clear_nexus(struct sas_task *task)
res = asd_clear_nexus_tag(task);
else
res = asd_clear_nexus_index(task);
- wait_for_completion_timeout(&tascb->completion,
- AIC94XX_SCB_TIMEOUT);
+ leftover = wait_for_completion_timeout(&tascb->completion,
+ AIC94XX_SCB_TIMEOUT);
ASD_DPRINTK("came back from clear nexus\n");
spin_lock_irqsave(&task->task_state_lock, flags);
+ if (leftover < 1)
+ res = TMF_RESP_FUNC_FAILED;
if (task->task_state_flags & SAS_TASK_STATE_DONE)
res = TMF_RESP_FUNC_COMPLETE;
spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -350,6 +353,7 @@ int asd_abort_task(struct sas_task *task)
unsigned long flags;
struct asd_ascb *ascb = NULL;
struct scb *scb;
+ int leftover;
spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
@@ -455,9 +459,11 @@ int asd_abort_task(struct sas_task *task)
break;
case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */
res = TMF_RESP_FUNC_FAILED;
- wait_for_completion_timeout(&tascb->completion,
- AIC94XX_SCB_TIMEOUT);
+ leftover = wait_for_completion_timeout(&tascb->completion,
+ AIC94XX_SCB_TIMEOUT);
spin_lock_irqsave(&task->task_state_lock, flags);
+ if (leftover < 1)
+ res = TMF_RESP_FUNC_FAILED;
if (task->task_state_flags & SAS_TASK_STATE_DONE)
res = TMF_RESP_FUNC_COMPLETE;
spin_unlock_irqrestore(&task->task_state_lock, flags);
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index eff846ae0af..03dbe60c264 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -894,45 +894,6 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
}
/*
- * our own old-style timeout update
- */
-/*
- * The strategy is to cause the timer code to call scsi_times_out()
- * when the soonest timeout is pending.
- * The arguments are used when we are queueing a new command, because
- * we do not want to subtract the time used from this time, but when we
- * set the timer, we want to take this value into account.
- */
-
-int atari_scsi_update_timeout(Scsi_Cmnd * SCset, int timeout)
-{
- int rtn;
-
- /*
- * We are using the new error handling code to actually register/deregister
- * timers for timeout.
- */
-
- if (!timer_pending(&SCset->eh_timeout))
- rtn = 0;
- else
- rtn = SCset->eh_timeout.expires - jiffies;
-
- if (timeout == 0) {
- del_timer(&SCset->eh_timeout);
- SCset->eh_timeout.data = (unsigned long)NULL;
- SCset->eh_timeout.expires = 0;
- } else {
- if (SCset->eh_timeout.data != (unsigned long)NULL)
- del_timer(&SCset->eh_timeout);
- SCset->eh_timeout.data = (unsigned long)SCset;
- SCset->eh_timeout.expires = jiffies + timeout;
- add_timer(&SCset->eh_timeout);
- }
- return rtn;
-}
-
-/*
* Function : int NCR5380_queue_command (Scsi_Cmnd *cmd,
* void (*done)(Scsi_Cmnd *))
*
@@ -956,7 +917,6 @@ static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
Scsi_Cmnd *tmp;
int oldto;
unsigned long flags;
- // extern int update_timeout(Scsi_Cmnd * SCset, int timeout);
#if (NDEBUG & NDEBUG_NO_WRITE)
switch (cmd->cmnd[0]) {
@@ -1029,9 +989,9 @@ static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
* alter queues and touch the lock.
*/
if (!IS_A_TT()) {
- oldto = atari_scsi_update_timeout(cmd, 0);
+ /* perhaps stop command timer here */
falcon_get_lock();
- atari_scsi_update_timeout(cmd, oldto);
+ /* perhaps restart command timer here */
}
if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
LIST(cmd, hostdata->issue_queue);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 4baa79e6867..fa6ff295e56 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3954,6 +3954,13 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
spin_unlock_irq(scsi_cmd->device->host->host_lock);
ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
spin_lock_irq(scsi_cmd->device->host->host_lock);
+
+ list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+ if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+ rc = -EIO;
+ break;
+ }
+ }
} else
rc = ipr_device_reset(ioa_cfg, res);
res->resetting_device = 0;
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
index 19dd4b962e1..81e497d9eae 100644
--- a/drivers/scsi/jazz_esp.c
+++ b/drivers/scsi/jazz_esp.c
@@ -1,307 +1,244 @@
-/*
- * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture)
+/* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
*
- * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
- *
- * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
+ * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende)
*/
-#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/delay.h>
#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/blkdev.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "NCR53C9x.h"
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
#include <asm/jazz.h>
#include <asm/jazzdma.h>
-#include <asm/dma.h>
-#include <asm/pgtable.h>
-
-static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
-static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_dump_state(struct NCR_ESP *esp);
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
-static void dma_ints_off(struct NCR_ESP *esp);
-static void dma_ints_on(struct NCR_ESP *esp);
-static int dma_irq_p(struct NCR_ESP *esp);
-static int dma_ports_p(struct NCR_ESP *esp);
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
-static void dma_advance_sg (struct scsi_cmnd *sp);
-static void dma_led_off(struct NCR_ESP *);
-static void dma_led_on(struct NCR_ESP *);
-
-
-static volatile unsigned char cmd_buffer[16];
- /* This is where all commands are put
- * before they are trasfered to the ESP chip
- * via PIO.
- */
-
-static int jazz_esp_release(struct Scsi_Host *shost)
-{
- if (shost->irq)
- free_irq(shost->irq, NULL);
- if (shost->dma_channel != 0xff)
- free_dma(shost->dma_channel);
- if (shost->io_port && shost->n_io_port)
- release_region(shost->io_port, shost->n_io_port);
- scsi_unregister(shost);
- return 0;
-}
+#include <scsi/scsi_host.h>
-/***************************************************************** Detection */
-static int jazz_esp_detect(struct scsi_host_template *tpnt)
-{
- struct NCR_ESP *esp;
- struct ConfigDev *esp_dev;
-
- /*
- * first assumption it is there:-)
- */
- if (1) {
- esp_dev = NULL;
- esp = esp_allocate(tpnt, esp_dev, 0);
-
- /* Do command transfer with programmed I/O */
- esp->do_pio_cmds = 1;
-
- /* Required functions */
- esp->dma_bytes_sent = &dma_bytes_sent;
- esp->dma_can_transfer = &dma_can_transfer;
- esp->dma_dump_state = &dma_dump_state;
- esp->dma_init_read = &dma_init_read;
- esp->dma_init_write = &dma_init_write;
- esp->dma_ints_off = &dma_ints_off;
- esp->dma_ints_on = &dma_ints_on;
- esp->dma_irq_p = &dma_irq_p;
- esp->dma_ports_p = &dma_ports_p;
- esp->dma_setup = &dma_setup;
-
- /* Optional functions */
- esp->dma_barrier = NULL;
- esp->dma_drain = NULL;
- esp->dma_invalidate = NULL;
- esp->dma_irq_entry = NULL;
- esp->dma_irq_exit = NULL;
- esp->dma_poll = NULL;
- esp->dma_reset = NULL;
- esp->dma_led_off = &dma_led_off;
- esp->dma_led_on = &dma_led_on;
-
- /* virtual DMA functions */
- esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
- esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
- esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one;
- esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl;
- esp->dma_advance_sg = &dma_advance_sg;
-
-
- /* SCSI chip speed */
- esp->cfreq = 40000000;
+#include "esp_scsi.h"
- /*
- * we don't give the address of DMA channel, but the number
- * of DMA channel, so we can use the jazz DMA functions
- *
- */
- esp->dregs = (void *) JAZZ_SCSI_DMA;
-
- /* ESP register base */
- esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE);
-
- /* Set the command buffer */
- esp->esp_command = (volatile unsigned char *)cmd_buffer;
-
- /* get virtual dma address for command buffer */
- esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer));
-
- esp->irq = JAZZ_SCSI_IRQ;
- request_irq(JAZZ_SCSI_IRQ, esp_intr, IRQF_DISABLED, "JAZZ SCSI",
- esp->ehost);
-
- /*
- * FIXME, look if the scsi id is available from NVRAM
- */
- esp->scsi_id = 7;
-
- /* Check for differential SCSI-bus */
- /* What is this stuff? */
- esp->diff = 0;
-
- esp_initialize(esp);
-
- printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
- esps_running = esps_in_use;
- return esps_in_use;
- }
- return 0;
-}
+#define DRV_MODULE_NAME "jazz_esp"
+#define PFX DRV_MODULE_NAME ": "
+#define DRV_VERSION "1.000"
+#define DRV_MODULE_RELDATE "May 19, 2007"
-/************************************************************* DMA Functions */
-static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
+static void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg)
{
- return fifo_count;
+ *(volatile u8 *)(esp->regs + reg) = val;
}
-static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static u8 jazz_esp_read8(struct esp *esp, unsigned long reg)
{
- /*
- * maximum DMA size is 1MB
- */
- unsigned long sz = sp->SCp.this_residual;
- if(sz > 0x100000)
- sz = 0x100000;
- return sz;
+ return *(volatile u8 *)(esp->regs + reg);
}
-static void dma_dump_state(struct NCR_ESP *esp)
+static dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf,
+ size_t sz, int dir)
{
-
- ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
- esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_residue((int)esp->dregs)));
+ return dma_map_single(esp->dev, buf, sz, dir);
}
-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
+static int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg,
+ int num_sg, int dir)
{
- dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);
- vdma_disable ((int)esp->dregs);
- vdma_set_mode ((int)esp->dregs, DMA_MODE_READ);
- vdma_set_addr ((int)esp->dregs, vaddress);
- vdma_set_count ((int)esp->dregs, length);
- vdma_enable ((int)esp->dregs);
+ return dma_map_sg(esp->dev, sg, num_sg, dir);
}
-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
+static void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr,
+ size_t sz, int dir)
{
- dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);
- vdma_disable ((int)esp->dregs);
- vdma_set_mode ((int)esp->dregs, DMA_MODE_WRITE);
- vdma_set_addr ((int)esp->dregs, vaddress);
- vdma_set_count ((int)esp->dregs, length);
- vdma_enable ((int)esp->dregs);
+ dma_unmap_single(esp->dev, addr, sz, dir);
}
-static void dma_ints_off(struct NCR_ESP *esp)
+static void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
+ int num_sg, int dir)
{
- disable_irq(esp->irq);
+ dma_unmap_sg(esp->dev, sg, num_sg, dir);
}
-static void dma_ints_on(struct NCR_ESP *esp)
+static int jazz_esp_irq_pending(struct esp *esp)
{
- enable_irq(esp->irq);
+ if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)
+ return 1;
+ return 0;
}
-static int dma_irq_p(struct NCR_ESP *esp)
+static void jazz_esp_reset_dma(struct esp *esp)
{
- return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR);
+ vdma_disable ((int)esp->dma_regs);
}
-static int dma_ports_p(struct NCR_ESP *esp)
+static void jazz_esp_dma_drain(struct esp *esp)
{
- int enable = vdma_get_enable((int)esp->dregs);
-
- return (enable & R4030_CHNL_ENABLE);
+ /* nothing to do */
}
-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
+static void jazz_esp_dma_invalidate(struct esp *esp)
{
- /*
- * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
- * so when (write) is true, it actually means READ!
- */
- if(write){
- dma_init_read(esp, addr, count);
- } else {
- dma_init_write(esp, addr, count);
- }
+ vdma_disable ((int)esp->dma_regs);
}
-static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static void jazz_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
+ u32 dma_count, int write, u8 cmd)
{
- sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
- sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in);
+ BUG_ON(!(cmd & ESP_CMD_DMA));
+
+ jazz_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
+ jazz_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
+ vdma_disable ((int)esp->dma_regs);
+ if (write)
+ vdma_set_mode ((int)esp->dma_regs, DMA_MODE_READ);
+ else
+ vdma_set_mode ((int)esp->dma_regs, DMA_MODE_WRITE);
+
+ vdma_set_addr ((int)esp->dma_regs, addr);
+ vdma_set_count ((int)esp->dma_regs, dma_count);
+ vdma_enable ((int)esp->dma_regs);
+
+ scsi_esp_cmd(esp, cmd);
}
-static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
-{
- int sz = sp->SCp.buffers_residual;
- struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
-
- while (sz >= 0) {
- sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
- sz--;
- }
- sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
-}
-
-static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static int jazz_esp_dma_error(struct esp *esp)
{
- vdma_free(sp->SCp.have_data_in);
+ u32 enable = vdma_get_enable((int)esp->dma_regs);
+
+ if (enable & (R4030_MEM_INTR|R4030_ADDR_INTR))
+ return 1;
+
+ return 0;
}
-static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
+static const struct esp_driver_ops jazz_esp_ops = {
+ .esp_write8 = jazz_esp_write8,
+ .esp_read8 = jazz_esp_read8,
+ .map_single = jazz_esp_map_single,
+ .map_sg = jazz_esp_map_sg,
+ .unmap_single = jazz_esp_unmap_single,
+ .unmap_sg = jazz_esp_unmap_sg,
+ .irq_pending = jazz_esp_irq_pending,
+ .reset_dma = jazz_esp_reset_dma,
+ .dma_drain = jazz_esp_dma_drain,
+ .dma_invalidate = jazz_esp_dma_invalidate,
+ .send_dma_cmd = jazz_esp_send_dma_cmd,
+ .dma_error = jazz_esp_dma_error,
+};
+
+static int __devinit esp_jazz_probe(struct platform_device *dev)
{
- int sz = sp->use_sg - 1;
- struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
-
- while(sz >= 0) {
- vdma_free(sg[sz].dma_address);
- sz--;
- }
+ struct scsi_host_template *tpnt = &scsi_esp_template;
+ struct Scsi_Host *host;
+ struct esp *esp;
+ struct resource *res;
+ int err;
+
+ host = scsi_host_alloc(tpnt, sizeof(struct esp));
+
+ err = -ENOMEM;
+ if (!host)
+ goto fail;
+
+ host->max_id = 8;
+ esp = host_to_esp(host);
+
+ esp->host = host;
+ esp->dev = dev;
+ esp->ops = &jazz_esp_ops;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ goto fail_unlink;
+
+ esp->regs = (void __iomem *)res->start;
+ if (!esp->regs)
+ goto fail_unlink;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+ if (!res)
+ goto fail_unlink;
+
+ esp->dma_regs = (void __iomem *)res->start;
+
+ esp->command_block = dma_alloc_coherent(esp->dev, 16,
+ &esp->command_block_dma,
+ GFP_KERNEL);
+ if (!esp->command_block)
+ goto fail_unmap_regs;
+
+ host->irq = platform_get_irq(dev, 0);
+ err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
+ if (err < 0)
+ goto fail_unmap_command_block;
+
+ esp->scsi_id = 7;
+ esp->host->this_id = esp->scsi_id;
+ esp->scsi_id_mask = (1 << esp->scsi_id);
+ esp->cfreq = 40000000;
+
+ dev_set_drvdata(&dev->dev, esp);
+
+ err = scsi_esp_register(esp, &dev->dev);
+ if (err)
+ goto fail_free_irq;
+
+ return 0;
+
+fail_free_irq:
+ free_irq(host->irq, esp);
+fail_unmap_command_block:
+ dma_free_coherent(esp->dev, 16,
+ esp->command_block,
+ esp->command_block_dma);
+fail_unmap_regs:
+fail_unlink:
+ scsi_host_put(host);
+fail:
+ return err;
}
-static void dma_advance_sg (struct scsi_cmnd *sp)
+static int __devexit esp_jazz_remove(struct platform_device *dev)
{
- sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
+ struct esp *esp = dev_get_drvdata(&dev->dev);
+ unsigned int irq = esp->host->irq;
+
+ scsi_esp_unregister(esp);
+
+ free_irq(irq, esp);
+ dma_free_coherent(esp->dev, 16,
+ esp->command_block,
+ esp->command_block_dma);
+
+ scsi_host_put(esp->host);
+
+ return 0;
}
-#define JAZZ_HDC_LED 0xe000d100 /* FIXME, find correct address */
+static struct platform_driver esp_jazz_driver = {
+ .probe = esp_jazz_probe,
+ .remove = __devexit_p(esp_jazz_remove),
+ .driver = {
+ .name = "jazz_esp",
+ },
+};
-static void dma_led_off(struct NCR_ESP *esp)
+static int __init jazz_esp_init(void)
{
-#if 0
- *(unsigned char *)JAZZ_HDC_LED = 0;
-#endif
+ return platform_driver_register(&esp_jazz_driver);
}
-static void dma_led_on(struct NCR_ESP *esp)
-{
-#if 0
- *(unsigned char *)JAZZ_HDC_LED = 1;
-#endif
+static void __exit jazz_esp_exit(void)
+{
+ platform_driver_unregister(&esp_jazz_driver);
}
-static struct scsi_host_template driver_template = {
- .proc_name = "jazz_esp",
- .proc_info = esp_proc_info,
- .name = "ESP 100/100a/200",
- .detect = jazz_esp_detect,
- .slave_alloc = esp_slave_alloc,
- .slave_destroy = esp_slave_destroy,
- .release = jazz_esp_release,
- .info = esp_info,
- .queuecommand = esp_queue,
- .eh_abort_handler = esp_abort,
- .eh_bus_reset_handler = esp_reset,
- .can_queue = 7,
- .this_id = 7,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 1,
- .use_clustering = DISABLE_CLUSTERING,
-};
-#include "scsi_module.c"
+MODULE_DESCRIPTION("JAZZ ESP SCSI driver");
+MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(jazz_esp_init);
+module_exit(jazz_esp_exit);
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 5631c199a8e..732446e6396 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -254,6 +254,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
sg_init_one(&dummy, md, id->table_desc.len);
sg_dma_address(&dummy) = token;
+ sg_dma_len(&dummy) = id->table_desc.len;
err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
id->table_desc.len);
if (err) {
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 7a812677ff8..e2cf12ef368 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -10,7 +10,7 @@
* 2 of the License, or (at your option) any later version.
*
* FILE : megaraid_sas.c
- * Version : v00.00.03.10-rc1
+ * Version : v00.00.03.10-rc5
*
* Authors:
* (email-id : megaraidlinux@lsi.com)
@@ -886,6 +886,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
goto out_return_cmd;
cmd->scmd = scmd;
+ scmd->SCp.ptr = (char *)cmd;
/*
* Issue the command to the FW
@@ -919,7 +920,7 @@ static int megasas_slave_configure(struct scsi_device *sdev)
* The RAID firmware may require extended timeouts.
*/
if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
- sdev->timeout = 90 * HZ;
+ sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ;
return 0;
}
@@ -981,8 +982,8 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
instance = (struct megasas_instance *)scmd->device->host->hostdata;
- scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n",
- scmd->serial_number, scmd->cmnd[0]);
+ scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
+ scmd->serial_number, scmd->cmnd[0], scmd->retries);
if (instance->hw_crit_error) {
printk(KERN_ERR "megasas: cannot recover from previous reset "
@@ -1000,6 +1001,39 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd)
}
/**
+ * megasas_reset_timer - quiesce the adapter if required
+ * @scmd: scsi cmnd
+ *
+ * Sets the FW busy flag and reduces the host->can_queue if the
+ * cmd has not been completed within the timeout period.
+ */
+static enum
+scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
+{
+ struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
+ struct megasas_instance *instance;
+ unsigned long flags;
+
+ if (time_after(jiffies, scmd->jiffies_at_alloc +
+ (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
+ return EH_NOT_HANDLED;
+ }
+
+ instance = cmd->instance;
+ if (!(instance->flag & MEGASAS_FW_BUSY)) {
+ /* FW is busy, throttle IO */
+ spin_lock_irqsave(instance->host->host_lock, flags);
+
+ instance->host->can_queue = 16;
+ instance->last_time = jiffies;
+ instance->flag |= MEGASAS_FW_BUSY;
+
+ spin_unlock_irqrestore(instance->host->host_lock, flags);
+ }
+ return EH_RESET_TIMER;
+}
+
+/**
* megasas_reset_device - Device reset handler entry point
*/
static int megasas_reset_device(struct scsi_cmnd *scmd)
@@ -1112,6 +1146,7 @@ static struct scsi_host_template megasas_template = {
.eh_device_reset_handler = megasas_reset_device,
.eh_bus_reset_handler = megasas_reset_bus_host,
.eh_host_reset_handler = megasas_reset_bus_host,
+ .eh_timed_out = megasas_reset_timer,
.bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING,
};
@@ -1215,9 +1250,8 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
int exception = 0;
struct megasas_header *hdr = &cmd->frame->hdr;
- if (cmd->scmd) {
- cmd->scmd->SCp.ptr = (char *)0;
- }
+ if (cmd->scmd)
+ cmd->scmd->SCp.ptr = NULL;
switch (hdr->cmd) {
@@ -1806,6 +1840,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
u32 context;
struct megasas_cmd *cmd;
struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
+ unsigned long flags;
/* If we have already declared adapter dead, donot complete cmds */
if (instance->hw_crit_error)
@@ -1828,6 +1863,22 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
}
*instance->consumer = producer;
+
+ /*
+ * Check if we can restore can_queue
+ */
+ if (instance->flag & MEGASAS_FW_BUSY
+ && time_after(jiffies, instance->last_time + 5 * HZ)
+ && atomic_read(&instance->fw_outstanding) < 17) {
+
+ spin_lock_irqsave(instance->host->host_lock, flags);
+ instance->flag &= ~MEGASAS_FW_BUSY;
+ instance->host->can_queue =
+ instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+ spin_unlock_irqrestore(instance->host->host_lock, flags);
+ }
+
}
/**
@@ -2398,6 +2449,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
instance->init_id = MEGASAS_DEFAULT_INIT_ID;
megasas_dbg_lvl = 0;
+ instance->flag = 0;
+ instance->last_time = 0;
/*
* Initialize MFI Firmware
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index e862992ee37..4dffc918a41 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -18,9 +18,9 @@
/*
* MegaRAID SAS Driver meta data
*/
-#define MEGASAS_VERSION "00.00.03.10-rc1"
-#define MEGASAS_RELDATE "Feb 14, 2007"
-#define MEGASAS_EXT_VERSION "Wed Feb 14 10:14:25 PST 2007"
+#define MEGASAS_VERSION "00.00.03.10-rc5"
+#define MEGASAS_RELDATE "May 17, 2007"
+#define MEGASAS_EXT_VERSION "Thu May 17 10:09:32 PDT 2007"
/*
* Device IDs
@@ -539,6 +539,8 @@ struct megasas_ctrl_info {
#define MEGASAS_DBG_LVL 1
+#define MEGASAS_FW_BUSY 1
+
/*
* When SCSI mid-layer calls driver's reset routine, driver waits for
* MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
@@ -549,8 +551,8 @@ struct megasas_ctrl_info {
#define MEGASAS_RESET_WAIT_TIME 180
#define MEGASAS_INTERNAL_CMD_WAIT_TIME 180
#define MEGASAS_RESET_NOTICE_INTERVAL 5
-
#define MEGASAS_IOCTL_CMD 0
+#define MEGASAS_DEFAULT_CMD_TIMEOUT 90
/*
* FW reports the maximum of number of commands that it can accept (maximum
@@ -1073,7 +1075,6 @@ struct megasas_instance {
struct megasas_register_set __iomem *reg_set;
s8 init_id;
- u8 reserved[3];
u16 max_num_sge;
u16 max_fw_cmds;
@@ -1104,6 +1105,9 @@ struct megasas_instance {
struct megasas_instance_template *instancet;
struct tasklet_struct isr_tasklet;
+
+ u8 flag;
+ unsigned long last_time;
};
#define MEGASAS_IS_LOGICAL(scp) \
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 3b2e1a53e6e..d953d43fe2e 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -4,6 +4,7 @@
*
*/
+#include <linux/completion.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -50,16 +51,10 @@ static struct ctrl_inquiry {
} *fcs __initdata;
static int fcscount __initdata = 0;
static atomic_t fcss __initdata = ATOMIC_INIT(0);
-DECLARE_MUTEX_LOCKED(fc_sem);
+static DECLARE_COMPLETION(fc_detect_complete);
static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd);
-static void __init pluto_detect_timeout(unsigned long data)
-{
- PLND(("Timeout\n"))
- up(&fc_sem);
-}
-
static void __init pluto_detect_done(Scsi_Cmnd *SCpnt)
{
/* Do nothing */
@@ -69,7 +64,7 @@ static void __init pluto_detect_scsi_done(Scsi_Cmnd *SCpnt)
{
PLND(("Detect done %08lx\n", (long)SCpnt))
if (atomic_dec_and_test (&fcss))
- up(&fc_sem);
+ complete(&fc_detect_complete);
}
int pluto_slave_configure(struct scsi_device *device)
@@ -96,7 +91,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
int i, retry, nplutos;
fc_channel *fc;
struct scsi_device dev;
- DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0);
tpnt->proc_name = "pluto";
fcscount = 0;
@@ -187,15 +181,11 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
}
}
- fc_timer.expires = jiffies + 10 * HZ;
- add_timer(&fc_timer);
-
- down(&fc_sem);
+ wait_for_completion_timeout(&fc_detect_complete, 10 * HZ);
PLND(("Woken up\n"))
if (!atomic_read(&fcss))
break; /* All fc channels have answered us */
}
- del_timer_sync(&fc_timer);
PLND(("Finished search\n"))
for (i = 0, nplutos = 0; i < fcscount; i++) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index dd076da86a4..b98136adaaa 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2590,7 +2590,7 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
return 0;
if (msleep_interruptible(step))
break;
- } while (--iterations >= 0);
+ } while (--iterations > 0);
return -ETIMEDOUT;
}
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index ce63044b1ec..18dd5cc4d7c 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -209,6 +209,7 @@ static struct {
{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"Promise", "", NULL, BLIST_SPARSELUN},
{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
{"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a67f315244d..662577fbe7a 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -184,6 +184,15 @@ int scsi_complete_async_scans(void)
/* Only exported for the benefit of scsi_wait_scan */
EXPORT_SYMBOL_GPL(scsi_complete_async_scans);
+#ifndef MODULE
+/*
+ * For async scanning we need to wait for all the scans to complete before
+ * trying to mount the root fs. Otherwise non-modular drivers may not be ready
+ * yet.
+ */
+late_initcall(scsi_complete_async_scans);
+#endif
+
/**
* scsi_unlock_floptical - unlock device via a special MODE SENSE command
* @sdev: scsi device to send command to
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 00e46662296..3d8c9cb24f9 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1789,7 +1789,7 @@ static void sd_shutdown(struct device *dev)
static int sd_suspend(struct device *dev, pm_message_t mesg)
{
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
- int ret;
+ int ret = 0;
if (!sdkp)
return 0; /* this can happen */
@@ -1798,30 +1798,34 @@ static int sd_suspend(struct device *dev, pm_message_t mesg)
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
ret = sd_sync_cache(sdkp);
if (ret)
- return ret;
+ goto done;
}
if (mesg.event == PM_EVENT_SUSPEND &&
sdkp->device->manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
ret = sd_start_stop_device(sdkp, 0);
- if (ret)
- return ret;
}
- return 0;
+done:
+ scsi_disk_put(sdkp);
+ return ret;
}
static int sd_resume(struct device *dev)
{
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+ int ret = 0;
if (!sdkp->device->manage_start_stop)
- return 0;
+ goto done;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
+ ret = sd_start_stop_device(sdkp, 1);
- return sd_start_stop_device(sdkp, 1);
+done:
+ scsi_disk_put(sdkp);
+ return ret;
}
/**
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 69be1324b11..9ac83abc402 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -32,11 +32,12 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
#define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "3.1.0.1"
+#define ST_DRIVER_VERSION "3.6.0000.1"
#define ST_VER_MAJOR 3
-#define ST_VER_MINOR 1
+#define ST_VER_MINOR 6
#define ST_OEM 0
#define ST_BUILD_VER 1
@@ -113,10 +114,6 @@ enum {
SG_CF_64B = 0x40, /* 64 bit item */
SG_CF_HOST = 0x20, /* sg in host memory */
- ST_MAX_ARRAY_SUPPORTED = 16,
- ST_MAX_TARGET_NUM = (ST_MAX_ARRAY_SUPPORTED+1),
- ST_MAX_LUN_PER_TARGET = 16,
-
st_shasta = 0,
st_vsc = 1,
st_vsc1 = 2,
@@ -586,7 +583,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
u16 tag;
host = cmd->device->host;
id = cmd->device->id;
- lun = cmd->device->channel; /* firmware lun issue work around */
+ lun = cmd->device->lun;
hba = (struct st_hba *) &host->hostdata[0];
switch (cmd->cmnd[0]) {
@@ -605,8 +602,26 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
stex_invalid_field(cmd, done);
return 0;
}
+ case REPORT_LUNS:
+ /*
+ * The shasta firmware does not report actual luns in the
+ * target, so fail the command to force sequential lun scan.
+ * Also, the console device does not support this command.
+ */
+ if (hba->cardtype == st_shasta || id == host->max_id - 1) {
+ stex_invalid_field(cmd, done);
+ return 0;
+ }
+ break;
+ case TEST_UNIT_READY:
+ if (id == host->max_id - 1) {
+ cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+ done(cmd);
+ return 0;
+ }
+ break;
case INQUIRY:
- if (id != ST_MAX_ARRAY_SUPPORTED)
+ if (id != host->max_id - 1)
break;
if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
stex_direct_copy(cmd, console_inq_page,
@@ -624,7 +639,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
ver.oem = ST_OEM;
ver.build = ST_BUILD_VER;
ver.signature[0] = PASSTHRU_SIGNATURE;
- ver.console_id = ST_MAX_ARRAY_SUPPORTED;
+ ver.console_id = host->max_id - 1;
ver.host_no = hba->host->host_no;
cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ?
DID_OK << 16 | COMMAND_COMPLETE << 8 :
@@ -645,13 +660,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
req = stex_alloc_req(hba);
- if (hba->cardtype == st_yosemite) {
- req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
- req->target = 0;
- } else {
- req->lun = lun;
- req->target = id;
- }
+ req->lun = lun;
+ req->target = id;
/* cdb */
memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
@@ -767,18 +777,6 @@ static void stex_ys_commands(struct st_hba *hba,
ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
else
ccb->srb_status = SRB_STATUS_SUCCESS;
- } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
- u8 *report_lun_data = (u8 *)hba->copy_buffer;
-
- count = STEX_EXTRA_SIZE;
- stex_internal_copy(ccb->cmd, report_lun_data,
- &count, ccb->sg_count, ST_FROM_CMD);
- if (report_lun_data[2] || report_lun_data[3]) {
- report_lun_data[2] = 0x00;
- report_lun_data[3] = 0x08;
- stex_internal_copy(ccb->cmd, report_lun_data,
- &count, ccb->sg_count, ST_TO_CMD);
- }
}
}
@@ -995,6 +993,11 @@ static int stex_abort(struct scsi_cmnd *cmd)
u32 data;
int result = SUCCESS;
unsigned long flags;
+
+ printk(KERN_INFO DRV_NAME
+ "(%s): aborting command\n", pci_name(hba->pdev));
+ scsi_print_command(cmd);
+
base = hba->mmio_base;
spin_lock_irqsave(host->host_lock, flags);
if (tag < host->can_queue && hba->ccb[tag].cmd == cmd)
@@ -1051,7 +1054,12 @@ static void stex_hard_reset(struct st_hba *hba)
pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl);
pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
- msleep(1);
+
+ /*
+ * 1 ms may be enough for 8-port controllers. But 16-port controllers
+ * require more time to finish bus reset. Use 100 ms here for safety
+ */
+ msleep(100);
pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
@@ -1075,6 +1083,10 @@ static int stex_reset(struct scsi_cmnd *cmd)
unsigned long before;
hba = (struct st_hba *) &cmd->device->host->hostdata[0];
+ printk(KERN_INFO DRV_NAME
+ "(%s): resetting host\n", pci_name(hba->pdev));
+ scsi_print_command(cmd);
+
hba->mu_status = MU_STATE_RESETTING;
if (hba->cardtype == st_shasta)
@@ -1194,7 +1206,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_scsi_host_put;
}
- hba->mmio_base = ioremap(pci_resource_start(pdev, 0),
+ hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if ( !hba->mmio_base) {
printk(KERN_ERR DRV_NAME "(%s): memory map failed\n",
@@ -1229,12 +1241,18 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
hba->mu_status = MU_STATE_STARTING;
- /* firmware uses id/lun pair for a logical drive, but lun would be
- always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use
- channel to map lun here */
- host->max_channel = ST_MAX_LUN_PER_TARGET - 1;
- host->max_id = ST_MAX_TARGET_NUM;
- host->max_lun = 1;
+ if (hba->cardtype == st_shasta) {
+ host->max_lun = 8;
+ host->max_id = 16 + 1;
+ } else if (hba->cardtype == st_yosemite) {
+ host->max_lun = 128;
+ host->max_id = 1 + 1;
+ } else {
+ /* st_vsc and st_vsc1 */
+ host->max_lun = 1;
+ host->max_id = 128 + 1;
+ }
+ host->max_channel = 0;
host->unique_id = host->host_no;
host->max_cmd_len = STEX_CDB_LENGTH;
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 1a9a24b8263..e88da72f830 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -167,8 +167,9 @@ static void pl010_rx_chars(struct uart_amba_port *uap)
ignore_char:
status = readb(uap->port.membase + UART01x_FR);
}
+ spin_unlock(&uap->port.lock);
tty_flip_buffer_push(tty);
- return;
+ spin_lock(&uap->port.lock);
}
static void pl010_tx_chars(struct uart_amba_port *uap)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 44639e71372..954073c6ce3 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -153,8 +153,9 @@ static void pl011_rx_chars(struct uart_amba_port *uap)
ignore_char:
status = readw(uap->port.membase + UART01x_FR);
}
+ spin_unlock(&uap->port.lock);
tty_flip_buffer_push(tty);
- return;
+ spin_lock(&uap->port.lock);
}
static void pl011_tx_chars(struct uart_amba_port *uap)
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 698763b28dd..8721afe1ae4 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -589,7 +589,7 @@ static int __init ks8695_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-extern struct uart_driver ks8695_reg;
+static struct uart_driver ks8695_reg;
static struct console ks8695_console = {
.name = SERIAL_KS8695_DEVNAME,
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index e35d9ab359f..b45ba5392dd 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -30,9 +30,9 @@ void
sunserial_console_termios(struct console *con)
{
char mode[16], buf[16], *s;
- char *mode_prop = "ttyX-mode";
- char *cd_prop = "ttyX-ignore-cd";
- char *dtr_prop = "ttyX-rts-dtr-off";
+ char mode_prop[] = "ttyX-mode";
+ char cd_prop[] = "ttyX-ignore-cd";
+ char dtr_prop[] = "ttyX-rts-dtr-off";
char *ssp_console_modes_prop = "ssp-console-modes";
int baud, bits, stop, cflag;
char parity;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 0985193dc57..15b6e1cb040 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1239,7 +1239,7 @@ static inline struct console *SUNZILOG_CONSOLE(void)
#define SUNZILOG_CONSOLE() (NULL)
#endif
-static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
+static void __devinit sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
{
int baud, brg;
@@ -1259,7 +1259,7 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
}
#ifdef CONFIG_SERIO
-static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
+static void __devinit sunzilog_register_serio(struct uart_sunzilog_port *up)
{
struct serio *serio = &up->serio;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 1d8a2f6bb8e..8b2601de363 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -113,16 +113,16 @@ static void atmel_spi_next_xfer(struct spi_master *master,
len = as->remaining_bytes;
- tx_dma = xfer->tx_dma;
- rx_dma = xfer->rx_dma;
+ tx_dma = xfer->tx_dma + xfer->len - len;
+ rx_dma = xfer->rx_dma + xfer->len - len;
/* use scratch buffer only when rx or tx data is unspecified */
- if (rx_dma == INVALID_DMA_ADDRESS) {
+ if (!xfer->rx_buf) {
rx_dma = as->buffer_dma;
if (len > BUFFER_SIZE)
len = BUFFER_SIZE;
}
- if (tx_dma == INVALID_DMA_ADDRESS) {
+ if (!xfer->tx_buf) {
tx_dma = as->buffer_dma;
if (len > BUFFER_SIZE)
len = BUFFER_SIZE;
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 052359fc41e..11f36bef305 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -329,8 +329,8 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
int ret = 0;
#if defined(CONFIG_PPC_MERGE)
- cdm = mpc52xx_find_and_map("mpc52xx-cdm");
- gpio = mpc52xx_find_and_map("mpc52xx-gpio");
+ cdm = mpc52xx_find_and_map("mpc5200-cdm");
+ gpio = mpc52xx_find_and_map("mpc5200-gpio");
#else
cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
@@ -445,9 +445,6 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
struct spi_master *master;
int ret;
- if (pdata == NULL)
- return -ENODEV;
-
master = spi_alloc_master(dev, sizeof *mps);
if (master == NULL)
return -ENOMEM;
@@ -594,17 +591,17 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
}
regaddr64 = of_translate_address(op->node, regaddr_p);
+ /* get PSC id (1..6, used by port_config) */
if (op->dev.platform_data == NULL) {
- struct device_node *np;
- int i = 0;
+ const u32 *psc_nump;
- for_each_node_by_type(np, "spi") {
- if (of_find_device_by_node(np) == op) {
- id = i;
- break;
- }
- i++;
+ psc_nump = of_get_property(op->node, "cell-index", NULL);
+ if (!psc_nump || *psc_nump > 5) {
+ printk(KERN_ERR "mpc52xx_psc_spi: Device node %s has invalid "
+ "cell-index property\n", op->node->full_name);
+ return -EINVAL;
}
+ id = *psc_nump + 1;
}
return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
@@ -617,7 +614,7 @@ static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op)
}
static struct of_device_id mpc52xx_psc_spi_of_match[] = {
- { .type = "spi", .compatible = "mpc52xx-psc-spi", },
+ { .type = "spi", .compatible = "mpc5200-psc-spi", },
{},
};
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index 96f62b2df30..95183e1df52 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -358,11 +358,11 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
case SPI_MODE_0:
case SPI_MODE_3:
- flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
+ flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
break;
case SPI_MODE_1:
case SPI_MODE_2:
- flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
+ flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
break;
}
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c3219b29b5a..4831edbae2d 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -411,7 +411,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
*/
int spi_register_master(struct spi_master *master)
{
- static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
+ static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
struct device *dev = master->cdev.dev;
int status = -ENODEV;
int dynamic = 0;
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 51daa212c6b..656be4a5094 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -121,7 +121,7 @@
32.768 KHz Clock */
/* SPI DMA Register Bit Fields & Masks */
-#define SPI_DMA_RHDMA (0xF << 4) /* RXFIFO Half Status */
+#define SPI_DMA_RHDMA (0x1 << 4) /* RXFIFO Half Status */
#define SPI_DMA_RFDMA (0x1 << 5) /* RXFIFO Full Status */
#define SPI_DMA_TEDMA (0x1 << 6) /* TXFIFO Empty Status */
#define SPI_DMA_THDMA (0x1 << 7) /* TXFIFO Half Status */
@@ -1355,6 +1355,7 @@ static int setup(struct spi_device *spi)
spi->bits_per_word,
spi_speed_hz(SPI_CONTROL_DATARATE_MIN),
spi->max_speed_hz);
+ return status;
err_first_setup:
kfree(chip);
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 225d6b2f82d..d04242aee40 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -168,6 +168,12 @@ static int spidev_message(struct spidev_data *spidev,
n--, k_tmp++, u_tmp++) {
k_tmp->len = u_tmp->len;
+ total += k_tmp->len;
+ if (total > bufsiz) {
+ status = -EMSGSIZE;
+ goto done;
+ }
+
if (u_tmp->rx_buf) {
k_tmp->rx_buf = buf;
if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len))
@@ -179,12 +185,6 @@ static int spidev_message(struct spidev_data *spidev,
u_tmp->len))
goto done;
}
-
- total += k_tmp->len;
- if (total > bufsiz) {
- status = -EMSGSIZE;
- goto done;
- }
buf += k_tmp->len;
k_tmp->cs_change = !!u_tmp->cs_change;
@@ -364,6 +364,7 @@ spidev_ioctl(struct inode *inode, struct file *filp,
break;
}
if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
+ kfree(ioc);
retval = -EFAULT;
break;
}
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 3524e3fc08b..61de78a9f6e 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -2182,7 +2182,7 @@ struct dec_serial_hook zs_kgdbhook = {
.init_info = kgdbhook_init_info,
.rx_char = kgdbhook_rx_char,
.cflags = B38400 | CS8 | CLOCAL,
-}
+};
void __init zs_kgdb_hook(int tty_num)
{
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 30b7bfbc985..8bcf7fe1dd8 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -476,8 +476,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
add_timer(&timer);
wait_for_completion(done);
status = urb->status;
- if (status == -ECONNRESET)
- status = -ETIMEDOUT;
del_timer_sync(&timer);
if (actual_length)
@@ -629,10 +627,22 @@ static int cxacru_card_status(struct cxacru_data *instance)
return 0;
}
+static void cxacru_remove_device_files(struct usbatm_data *usbatm_instance,
+ struct atm_dev *atm_dev)
+{
+ struct usb_interface *intf = usbatm_instance->usb_intf;
+
+ #define CXACRU_DEVICE_REMOVE_FILE(_name) \
+ device_remove_file(&intf->dev, &dev_attr_##_name);
+ CXACRU_ALL_FILES(REMOVE);
+ #undef CXACRU_DEVICE_REMOVE_FILE
+}
+
static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
struct atm_dev *atm_dev)
{
struct cxacru_data *instance = usbatm_instance->driver_data;
+ struct usb_interface *intf = usbatm_instance->usb_intf;
/*
struct atm_dev *atm_dev = usbatm_instance->atm_dev;
*/
@@ -649,14 +659,18 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
return ret;
}
+ #define CXACRU_DEVICE_CREATE_FILE(_name) \
+ ret = device_create_file(&intf->dev, &dev_attr_##_name); \
+ if (unlikely(ret)) \
+ goto fail_sysfs;
+ CXACRU_ALL_FILES(CREATE);
+ #undef CXACRU_DEVICE_CREATE_FILE
+
/* start ADSL */
mutex_lock(&instance->adsl_state_serialize);
ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
- if (ret < 0) {
+ if (ret < 0)
atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
- mutex_unlock(&instance->adsl_state_serialize);
- return ret;
- }
/* Start status polling */
mutex_lock(&instance->poll_state_serialize);
@@ -680,6 +694,11 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
if (start_polling)
cxacru_poll_status(&instance->poll_work.work);
return 0;
+
+fail_sysfs:
+ usb_err(usbatm_instance, "cxacru_atm_start: device_create_file failed (%d)\n", ret);
+ cxacru_remove_device_files(usbatm_instance, atm_dev);
+ return ret;
}
static void cxacru_poll_status(struct work_struct *work)
@@ -1065,13 +1084,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
goto fail;
}
- #define CXACRU_DEVICE_CREATE_FILE(_name) \
- ret = device_create_file(&intf->dev, &dev_attr_##_name); \
- if (unlikely(ret)) \
- goto fail_sysfs;
- CXACRU_ALL_FILES(CREATE);
- #undef CXACRU_DEVICE_CREATE_FILE
-
usb_fill_int_urb(instance->rcv_urb,
usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
instance->rcv_buf, PAGE_SIZE,
@@ -1092,14 +1104,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
return 0;
- fail_sysfs:
- dbg("cxacru_bind: device_create_file failed (%d)\n", ret);
-
- #define CXACRU_DEVICE_REMOVE_FILE(_name) \
- device_remove_file(&intf->dev, &dev_attr_##_name);
- CXACRU_ALL_FILES(REMOVE);
- #undef CXACRU_DEVICE_REVOVE_FILE
-
fail:
free_page((unsigned long) instance->snd_buf);
free_page((unsigned long) instance->rcv_buf);
@@ -1146,11 +1150,6 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
free_page((unsigned long) instance->snd_buf);
free_page((unsigned long) instance->rcv_buf);
- #define CXACRU_DEVICE_REMOVE_FILE(_name) \
- device_remove_file(&intf->dev, &dev_attr_##_name);
- CXACRU_ALL_FILES(REMOVE);
- #undef CXACRU_DEVICE_REVOVE_FILE
-
kfree(instance);
usbatm_instance->driver_data = NULL;
@@ -1231,6 +1230,7 @@ static struct usbatm_driver cxacru_driver = {
.heavy_init = cxacru_heavy_init,
.unbind = cxacru_unbind,
.atm_start = cxacru_atm_start,
+ .atm_stop = cxacru_remove_device_files,
.bulk_in = CXACRU_EP_DATA,
.bulk_out = CXACRU_EP_DATA,
.rx_padding = 3,
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 15e740e3a5c..6778f9af794 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -347,10 +347,8 @@ static int handle_bidir (struct usblp *usblp)
if (usblp->bidir && usblp->used && !usblp->sleeping) {
usblp->readcount = 0;
usblp->readurb->dev = usblp->dev;
- if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) {
- usblp->used = 0;
+ if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0)
return -EIO;
- }
}
return 0;
@@ -412,6 +410,7 @@ static int usblp_open(struct inode *inode, struct file *file)
usblp->readurb->status = 0;
if (handle_bidir(usblp) < 0) {
+ usblp->used = 0;
file->private_data = NULL;
retval = -EIO;
}
@@ -1003,7 +1002,7 @@ abort:
usblp->writebuf, usblp->writeurb->transfer_dma);
if (usblp->readbuf)
usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
- usblp->readbuf, usblp->writeurb->transfer_dma);
+ usblp->readbuf, usblp->readurb->transfer_dma);
kfree(usblp->statusbuf);
kfree(usblp->device_id_string);
usb_free_urb(usblp->writeurb);
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index f493fb1eaa2..346fc030c92 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -40,21 +40,25 @@ config USB_DEVICEFS
config USB_DEVICE_CLASS
bool "USB device class-devices (DEPRECATED)"
depends on USB
- default n
+ default y
---help---
Userspace access to USB devices is granted by device-nodes exported
directly from the usbdev in sysfs. Old versions of the driver
core and udev needed additional class devices to export device nodes.
These additional devices are difficult to handle in userspace, if
- information about USB interfaces must be available. One device contains
- the device node, the other device contains the interface data. Both
- devices are at the same level in sysfs (siblings) and one can't access
- the other. The device node created directly by the usbdev is the parent
- device of the interface and therefore easily accessible from the interface
- event.
-
- This option provides backward compatibility if needed.
+ information about USB interfaces must be available. One device
+ contains the device node, the other device contains the interface
+ data. Both devices are at the same level in sysfs (siblings) and one
+ can't access the other. The device node created directly by the
+ usb device is the parent device of the interface and therefore
+ easily accessible from the interface event.
+
+ This option provides backward compatibility for libusb device
+ nodes (lsusb) when usbfs is not used, and the following udev rule
+ doesn't exist:
+ SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \
+ NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
config USB_DYNAMIC_MINORS
bool "Dynamic USB minor allocation (EXPERIMENTAL)"
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index bfb3731d42d..dd3482328ad 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -1,4 +1,5 @@
#include <linux/usb.h>
+#include <linux/usb/ch9.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -49,7 +50,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
unsigned char *buffer0 = buffer;
struct usb_endpoint_descriptor *d;
struct usb_host_endpoint *endpoint;
- int n, i;
+ int n, i, j;
d = (struct usb_endpoint_descriptor *) buffer;
buffer += d->bLength;
@@ -84,6 +85,45 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
memcpy(&endpoint->desc, d, n);
INIT_LIST_HEAD(&endpoint->urb_list);
+ /* If the bInterval value is outside the legal range,
+ * set it to a default value: 32 ms */
+ i = 0; /* i = min, j = max, n = default */
+ j = 255;
+ if (usb_endpoint_xfer_int(d)) {
+ i = 1;
+ switch (to_usb_device(ddev)->speed) {
+ case USB_SPEED_HIGH:
+ n = 9; /* 32 ms = 2^(9-1) uframes */
+ j = 16;
+ break;
+ default: /* USB_SPEED_FULL or _LOW */
+ /* For low-speed, 10 ms is the official minimum.
+ * But some "overclocked" devices might want faster
+ * polling so we'll allow it. */
+ n = 32;
+ break;
+ }
+ } else if (usb_endpoint_xfer_isoc(d)) {
+ i = 1;
+ j = 16;
+ switch (to_usb_device(ddev)->speed) {
+ case USB_SPEED_HIGH:
+ n = 9; /* 32 ms = 2^(9-1) uframes */
+ break;
+ default: /* USB_SPEED_FULL */
+ n = 6; /* 32 ms = 2^(6-1) frames */
+ break;
+ }
+ }
+ if (d->bInterval < i || d->bInterval > j) {
+ dev_warn(ddev, "config %d interface %d altsetting %d "
+ "endpoint 0x%X has an invalid bInterval %d, "
+ "changing to %d\n",
+ cfgno, inum, asnum,
+ d->bEndpointAddress, d->bInterval, n);
+ endpoint->desc.bInterval = n;
+ }
+
/* Skip over any Class Specific or Vendor Specific descriptors;
* find the next endpoint or interface descriptor */
endpoint->extra = buffer;
@@ -185,10 +225,12 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
num_ep = USB_MAXENDPOINTS;
}
- len = sizeof(struct usb_host_endpoint) * num_ep;
- alt->endpoint = kzalloc(len, GFP_KERNEL);
- if (!alt->endpoint)
- return -ENOMEM;
+ if (num_ep > 0) { /* Can't allocate 0 bytes */
+ len = sizeof(struct usb_host_endpoint) * num_ep;
+ alt->endpoint = kzalloc(len, GFP_KERNEL);
+ if (!alt->endpoint)
+ return -ENOMEM;
+ }
/* Parse all the endpoint descriptors */
n = 0;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index b9f7f90aef8..2619986e530 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -983,7 +983,10 @@ static int autosuspend_check(struct usb_device *udev)
#else
-#define autosuspend_check(udev) 0
+static inline int autosuspend_check(struct usb_device *udev)
+{
+ return 0;
+}
#endif /* CONFIG_USB_SUSPEND */
@@ -1041,7 +1044,6 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
if (status < 0)
goto done;
}
- cancel_delayed_work(&udev->autosuspend);
/* Suspend all the interfaces and then udev itself */
if (udev->actconfig) {
@@ -1062,9 +1064,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
usb_resume_interface(intf);
}
+ /* Try another autosuspend when the interfaces aren't busy */
+ if (udev->auto_pm)
+ autosuspend_check(udev);
+
/* If the suspend succeeded, propagate it up the tree */
- } else if (parent)
- usb_autosuspend_device(parent);
+ } else {
+ cancel_delayed_work(&udev->autosuspend);
+ if (parent)
+ usb_autosuspend_device(parent);
+ }
done:
// dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
@@ -1475,6 +1484,7 @@ int usb_external_resume_device(struct usb_device *udev)
usb_pm_lock(udev);
udev->auto_pm = 0;
status = usb_resume_both(udev);
+ udev->last_busy = jiffies;
usb_pm_unlock(udev);
/* Now that the device is awake, we can start trying to autosuspend
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 40cf882293e..8969e42434b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1018,8 +1018,8 @@ done:
atomic_dec (&urb->use_count);
if (urb->reject)
wake_up (&usb_kill_urb_queue);
- usb_put_urb (urb);
usbmon_urb_submit_error(&hcd->self, urb, status);
+ usb_put_urb (urb);
}
return status;
}
@@ -1175,10 +1175,6 @@ void usb_hcd_endpoint_disable (struct usb_device *udev,
struct urb *urb;
hcd = bus_to_hcd(udev->bus);
-
- WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT &&
- udev->state != USB_STATE_NOTATTACHED);
-
local_irq_disable ();
/* ep is already gone from udev->ep_{in,out}[]; no more submits */
@@ -1685,7 +1681,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
spin_unlock_irq (&hcd_root_hub_lock);
#ifdef CONFIG_PM
- flush_workqueue(ksuspend_usb_wq);
+ cancel_work_sync(&hcd->wakeup_work);
#endif
mutex_lock(&usb_bus_list_lock);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index f6b74a678de..24f10a19dbd 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1158,6 +1158,30 @@ static void release_address(struct usb_device *udev)
}
}
+#ifdef CONFIG_USB_SUSPEND
+
+static void usb_stop_pm(struct usb_device *udev)
+{
+ /* Synchronize with the ksuspend thread to prevent any more
+ * autosuspend requests from being submitted, and decrement
+ * the parent's count of unsuspended children.
+ */
+ usb_pm_lock(udev);
+ if (udev->parent && !udev->discon_suspended)
+ usb_autosuspend_device(udev->parent);
+ usb_pm_unlock(udev);
+
+ /* Stop any autosuspend requests already submitted */
+ cancel_rearming_delayed_work(&udev->autosuspend);
+}
+
+#else
+
+static inline void usb_stop_pm(struct usb_device *udev)
+{ }
+
+#endif
+
/**
* usb_disconnect - disconnect a device (usbcore-internal)
* @pdev: pointer to device being disconnected
@@ -1224,13 +1248,7 @@ void usb_disconnect(struct usb_device **pdev)
*pdev = NULL;
spin_unlock_irq(&device_state_lock);
- /* Decrement the parent's count of unsuspended children */
- if (udev->parent) {
- usb_pm_lock(udev);
- if (!udev->discon_suspended)
- usb_autosuspend_device(udev->parent);
- usb_pm_unlock(udev);
- }
+ usb_stop_pm(udev);
put_device(&udev->dev);
}
@@ -2201,14 +2219,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
continue;
}
- /* Use a short timeout the first time through,
- * so that recalcitrant full-speed devices with
- * 8- or 16-byte ep0-maxpackets won't slow things
- * down tremendously by NAKing the unexpectedly
- * early status stage. Also, retry on all errors;
- * some devices are flakey.
- * 255 is for WUSB devices, we actually need to use 512.
- * WUSB1.0[4.8.1].
+ /* Retry on all errors; some devices are flakey.
+ * 255 is for WUSB devices, we actually need to use
+ * 512 (WUSB1.0[4.8.1]).
*/
for (j = 0; j < 3; ++j) {
buf->bMaxPacketSize0 = 0;
@@ -2216,7 +2229,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
USB_DT_DEVICE << 8, 0,
buf, GET_DESCRIPTOR_BUFSIZE,
- (i ? USB_CTRL_GET_TIMEOUT : 1000));
+ USB_CTRL_GET_TIMEOUT);
switch (buf->bMaxPacketSize0) {
case 8: case 16: case 32: case 64: case 255:
if (buf->bDescriptorType ==
@@ -2426,10 +2439,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
if (portchange & USB_PORT_STAT_C_CONNECTION) {
status = hub_port_debounce(hub, port1);
- if (status < 0 && printk_ratelimit()) {
- dev_err (hub_dev,
- "connect-debounce failed, port %d disabled\n",
- port1);
+ if (status < 0) {
+ if (printk_ratelimit())
+ dev_err (hub_dev, "connect-debounce failed, "
+ "port %d disabled\n", port1);
goto done;
}
portstatus = status;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b7434787db5..f9fed34bf7d 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -221,15 +221,10 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_INT) {
- int interval;
-
- if (usb_dev->speed == USB_SPEED_HIGH)
- interval = 1 << min(15, ep->desc.bInterval - 1);
- else
- interval = ep->desc.bInterval;
pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
usb_fill_int_urb(urb, usb_dev, pipe, data, len,
- usb_api_blocking_completion, NULL, interval);
+ usb_api_blocking_completion, NULL,
+ ep->desc.bInterval);
} else
usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
usb_api_blocking_completion, NULL);
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index e7c98237748..be37c863fdf 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -232,12 +232,15 @@ set_level(struct device *dev, struct device_attribute *attr,
int len = count;
char *cp;
int rc = 0;
+ int old_autosuspend_disabled, old_autoresume_disabled;
cp = memchr(buf, '\n', count);
if (cp)
len = cp - buf;
usb_lock_device(udev);
+ old_autosuspend_disabled = udev->autosuspend_disabled;
+ old_autoresume_disabled = udev->autoresume_disabled;
/* Setting the flags without calling usb_pm_lock is a subject to
* races, but who cares...
@@ -263,6 +266,10 @@ set_level(struct device *dev, struct device_attribute *attr,
} else
rc = -EINVAL;
+ if (rc) {
+ udev->autosuspend_disabled = old_autosuspend_disabled;
+ udev->autoresume_disabled = old_autoresume_disabled;
+ }
usb_unlock_device(udev);
return (rc < 0 ? rc : count);
}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 18ddc5e67e3..4a6299bd004 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -184,10 +184,6 @@ static void usb_release_dev(struct device *dev)
udev = to_usb_device(dev);
-#ifdef CONFIG_USB_SUSPEND
- cancel_delayed_work(&udev->autosuspend);
- flush_workqueue(ksuspend_usb_wq);
-#endif
usb_destroy_configuration(udev);
usb_put_hcd(bus_to_hcd(udev->bus));
kfree(udev->product);
@@ -205,7 +201,11 @@ struct device_type usb_device_type = {
static int ksuspend_usb_init(void)
{
- ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd");
+ /* This workqueue is supposed to be both freezable and
+ * singlethreaded. Its job doesn't justify running on more
+ * than one CPU.
+ */
+ ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
if (!ksuspend_usb_wq)
return -ENOMEM;
return 0;
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index f28af06905a..6042364402b 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -132,7 +132,7 @@ ep_matches (
* where it's an output parameter representing the full speed limit.
* the usb spec fixes high speed bulk maxpacket at 512 bytes.
*/
- max = 0x7ff & le16_to_cpup (&desc->wMaxPacketSize);
+ max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
switch (type) {
case USB_ENDPOINT_XFER_INT:
/* INT: limit 64 bytes full speed, 1024 high speed */
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index 157054ea397..3ca2b3159f0 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -228,13 +228,15 @@ static int dr_controller_setup(struct fsl_udc *udc)
/* Config PHY interface */
portctrl = fsl_readl(&dr_regs->portsc1);
- portctrl &= ~PORTSCX_PHY_TYPE_SEL;
+ portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH);
switch (udc->phy_mode) {
case FSL_USB2_PHY_ULPI:
portctrl |= PORTSCX_PTS_ULPI;
break;
- case FSL_USB2_PHY_UTMI:
case FSL_USB2_PHY_UTMI_WIDE:
+ portctrl |= PORTSCX_PTW_16BIT;
+ /* fall through */
+ case FSL_USB2_PHY_UTMI:
portctrl |= PORTSCX_PTS_UTMI;
break;
case FSL_USB2_PHY_SERIAL:
@@ -625,7 +627,7 @@ static void fsl_free_buffer(struct usb_ep *_ep, void *buf,
struct fsl_ep *ep;
if (!_ep)
- return NULL;
+ return;
ep = container_of(_ep, struct fsl_ep, ep);
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 188c74a9521..46d0e525274 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1369,12 +1369,12 @@ config_buf (struct dev_data *dev, u8 type, unsigned index)
hs = !hs;
if (hs) {
dev->req->buf = dev->hs_config;
- len = le16_to_cpup (&dev->hs_config->wTotalLength);
+ len = le16_to_cpu(dev->hs_config->wTotalLength);
} else
#endif
{
dev->req->buf = dev->config;
- len = le16_to_cpup (&dev->config->wTotalLength);
+ len = le16_to_cpu(dev->config->wTotalLength);
}
((u8 *)dev->req->buf) [1] = type;
return len;
@@ -1885,7 +1885,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* full or low speed config */
dev->config = (void *) kbuf;
- total = le16_to_cpup (&dev->config->wTotalLength);
+ total = le16_to_cpu(dev->config->wTotalLength);
if (!is_valid_config (dev->config) || total >= length)
goto fail;
kbuf += total;
@@ -1894,7 +1894,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* optional high speed config */
if (kbuf [1] == USB_DT_CONFIG) {
dev->hs_config = (void *) kbuf;
- total = le16_to_cpup (&dev->hs_config->wTotalLength);
+ total = le16_to_cpu(dev->hs_config->wTotalLength);
if (!is_valid_config (dev->hs_config) || total >= length)
goto fail;
kbuf += total;
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 52779c52b56..d975ecf18e0 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2440,9 +2440,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
tmp = 0;
-#define w_value le16_to_cpup (&u.r.wValue)
-#define w_index le16_to_cpup (&u.r.wIndex)
-#define w_length le16_to_cpup (&u.r.wLength)
+#define w_value le16_to_cpu(u.r.wValue)
+#define w_index le16_to_cpu(u.r.wIndex)
+#define w_length le16_to_cpu(u.r.wLength)
/* ack the irq */
writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index b394e63894d..c4975a6cf77 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -1651,9 +1651,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src)
UDC_EP_NUM_REG = 0;
} while (UDC_IRQ_SRC_REG & UDC_SETUP);
-#define w_value le16_to_cpup (&u.r.wValue)
-#define w_index le16_to_cpup (&u.r.wIndex)
-#define w_length le16_to_cpup (&u.r.wLength)
+#define w_value le16_to_cpu(u.r.wValue)
+#define w_index le16_to_cpu(u.r.wIndex)
+#define w_length le16_to_cpu(u.r.wLength)
/* Delegate almost all control requests to the gadget driver,
* except for a handful of ch9 status/feature requests that
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 6ec8cf1a3cc..708657c8913 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -186,10 +186,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
DEBUG("query OID %08x value, len %d:\n", OID, buf_len);
for (i = 0; i < buf_len; i += 16) {
DEBUG ("%03d: %08x %08x %08x %08x\n", i,
- le32_to_cpup((__le32 *)&buf[i]),
- le32_to_cpup((__le32 *)&buf[i + 4]),
- le32_to_cpup((__le32 *)&buf[i + 8]),
- le32_to_cpup((__le32 *)&buf[i + 12]));
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i])),
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i + 4])),
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i + 8])),
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i + 12])));
}
}
@@ -665,7 +669,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
break;
case OID_PNP_QUERY_POWER:
DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
- le32_to_cpup((__le32 *) buf) - 1);
+ le32_to_cpu(get_unaligned((__le32 *)buf)) - 1);
/* only suspend is a real power state, and
* it can't be entered by OID_PNP_SET_POWER...
*/
@@ -704,10 +708,14 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
for (i = 0; i < buf_len; i += 16) {
DEBUG ("%03d: %08x %08x %08x %08x\n", i,
- le32_to_cpup((__le32 *)&buf[i]),
- le32_to_cpup((__le32 *)&buf[i + 4]),
- le32_to_cpup((__le32 *)&buf[i + 8]),
- le32_to_cpup((__le32 *)&buf[i + 12]));
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i])),
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i + 4])),
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i + 8])),
+ le32_to_cpu(get_unaligned((__le32 *)
+ &buf[i + 12])));
}
}
@@ -721,7 +729,8 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
* PROMISCUOUS, DIRECTED,
* MULTICAST, ALL_MULTICAST, BROADCAST
*/
- *params->filter = (u16) le32_to_cpup((__le32 *)buf);
+ *params->filter = (u16) le32_to_cpu(get_unaligned(
+ (__le32 *)buf));
DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
__FUNCTION__, *params->filter);
@@ -771,7 +780,7 @@ update_linkstate:
* resuming, Windows forces a reset, and then SET_POWER D0.
* FIXME ... then things go batty; Windows wedges itself.
*/
- i = le32_to_cpup((__force __le32 *)buf);
+ i = le32_to_cpu(get_unaligned((__le32 *)buf));
DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
switch (i) {
case NdisDeviceStateD0:
@@ -1058,8 +1067,8 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
return -ENOMEM;
tmp = (__le32 *) buf;
- MsgType = le32_to_cpup(tmp++);
- MsgLength = le32_to_cpup(tmp++);
+ MsgType = le32_to_cpu(get_unaligned(tmp++));
+ MsgLength = le32_to_cpu(get_unaligned(tmp++));
if (configNr >= RNDIS_MAX_CONFIGS)
return -ENOTSUPP;
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index a52480505f7..c7a7c590426 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -193,6 +193,19 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004);
out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+ /*
+ * Turn on cache snooping hardware, since some PowerPC platforms
+ * wholly rely on hardware to deal with cache coherent
+ */
+
+ /* Setup Snooping for all the 4GB space */
+ /* SNOOP1 starts from 0x0, size 2G */
+ out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0 | SNOOP_SIZE_2GB);
+ /* SNOOP2 starts from 0x80000000, size 2G */
+ out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB);
+#endif
+
if (pdata->operating_mode == FSL_USB2_DR_HOST)
mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index f28736a917e..b5e59db5334 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -34,4 +34,5 @@
#define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */
#define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */
#define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */
+#define SNOOP_SIZE_2GB 0x1e
#endif /* _EHCI_FSL_H */
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 216c9c9d4d6..bb9cc595219 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -417,6 +417,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
unsigned long flags;
spin_lock_irqsave (&ohci->lock, flags);
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+ goto done;
/* undocumented erratum seen on at least rev D */
if ((ohci->flags & OHCI_QUIRK_AMD756)
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 79705609fd0..ca62cb58322 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -137,7 +137,7 @@ static const struct pci_device_id ohci_pci_quirks[] = {
/* Toshiba portege 4000 */
.vendor = PCI_VENDOR_ID_AL,
.device = 0x5237,
- .subvendor = PCI_VENDOR_ID_TOSHIBA_2,
+ .subvendor = PCI_VENDOR_ID_TOSHIBA,
.subdevice = 0x0004,
.driver_data = (unsigned long) broken_suspend,
},
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 20861650905..c225159ca3d 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -44,6 +44,7 @@
#define EHCI_USBSTS 4 /* status register */
#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
#define EHCI_USBINTR 8 /* interrupt register */
+#define EHCI_CONFIGFLAG 0x40 /* configured flag register */
#define EHCI_USBLEGSUP 0 /* legacy support register */
#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
@@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
u32 hcc_params, val;
u8 offset, cap_length;
int count = 256/4;
+ int tried_handoff = 0;
if (!mmio_resource_enabled(pdev, 0))
return;
@@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
*/
msec = 5000;
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
+ tried_handoff = 1;
msleep(10);
msec -= 10;
pci_read_config_dword(pdev, offset, &cap);
@@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
pci_write_config_dword(pdev,
offset + EHCI_USBLEGCTLSTS,
0);
+
+ /* If the BIOS ever owned the controller then we
+ * can't expect any power sessions to remain intact.
+ */
+ if (tried_handoff)
+ writel(0, op_reg_base + EHCI_CONFIGFLAG);
break;
case 0: /* illegal reserved capability */
cap = 0;
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index ff0dba01f1c..e98df2ee990 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -57,6 +57,13 @@
#include <asm/system.h>
#include <asm/byteorder.h>
#include "../core/hcd.h"
+
+ /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+ * If you're going to try stuff like this, you need to split
+ * out shareable stuff (register declarations?) into its own
+ * file, maybe name <linux/usb/ohci.h>
+ */
+
#include "ohci.h"
#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
@@ -173,11 +180,6 @@ struct u132_ring {
struct u132_endp *curr_endp;
struct delayed_work scheduler;
};
-#define OHCI_QUIRK_AMD756 0x01
-#define OHCI_QUIRK_SUPERIO 0x02
-#define OHCI_QUIRK_INITRESET 0x04
-#define OHCI_BIG_ENDIAN 0x08
-#define OHCI_QUIRK_ZFMICRO 0x10
struct u132 {
struct kref kref;
struct list_head u132_list;
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 88fb56d5db8..cac1500cba6 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -1822,16 +1822,10 @@ static int auerchar_release (struct inode *inode, struct file *file)
pauerswald_t cp;
dbg("release");
- /* get the mutexes */
- if (down_interruptible (&ccp->mutex)) {
- return -ERESTARTSYS;
- }
+ down(&ccp->mutex);
cp = ccp->auerdev;
if (cp) {
- if (down_interruptible (&cp->mutex)) {
- up (&ccp->mutex);
- return -ERESTARTSYS;
- }
+ down(&cp->mutex);
/* remove an open service */
auerswald_removeservice (cp, &ccp->scontext);
/* detach from device */
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index e2172e5cf15..e0f122e131d 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -73,6 +73,13 @@ static struct list_head ftdi_static_list;
#include "usb_u132.h"
#include <asm/io.h>
#include "../core/hcd.h"
+
+ /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+ * If you're going to try stuff like this, you need to split
+ * out shareable stuff (register declarations?) into its own
+ * file, maybe name <linux/usb/ohci.h>
+ */
+
#include "../host/ohci.h"
/* Define these values to match your devices*/
#define USB_FTDI_ELAN_VENDOR_ID 0x0403
@@ -2300,10 +2307,7 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi)
offsetof(struct ohci_regs, member), 0, data);
#define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \
offsetof(struct ohci_regs, member), 0, data);
-#define OHCI_QUIRK_AMD756 0x01
-#define OHCI_QUIRK_SUPERIO 0x02
-#define OHCI_QUIRK_INITRESET 0x04
-#define OHCI_BIG_ENDIAN 0x08
+
#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
OHCI_INTR_WDH)
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 11555bde655..7bad4940476 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -165,6 +165,8 @@ struct ld_usb {
size_t interrupt_in_endpoint_size;
int interrupt_in_running;
int interrupt_in_done;
+ int buffer_overflow;
+ spinlock_t rbsl;
char* interrupt_out_buffer;
struct usb_endpoint_descriptor* interrupt_out_endpoint;
@@ -230,10 +232,12 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
} else {
dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
__FUNCTION__, urb->status);
+ spin_lock(&dev->rbsl);
goto resubmit; /* maybe we can recover */
}
}
+ spin_lock(&dev->rbsl);
if (urb->actual_length > 0) {
next_ring_head = (dev->ring_head+1) % ring_buffer_size;
if (next_ring_head != dev->ring_tail) {
@@ -244,21 +248,25 @@ static void ld_usb_interrupt_in_callback(struct urb *urb)
dev->ring_head = next_ring_head;
dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
__FUNCTION__, urb->actual_length);
- } else
+ } else {
dev_warn(&dev->intf->dev,
"Ring buffer overflow, %d bytes dropped\n",
urb->actual_length);
+ dev->buffer_overflow = 1;
+ }
}
resubmit:
/* resubmit if we're still running */
- if (dev->interrupt_in_running && dev->intf) {
+ if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) {
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
- if (retval)
+ if (retval) {
dev_err(&dev->intf->dev,
"usb_submit_urb failed (%d)\n", retval);
+ dev->buffer_overflow = 1;
+ }
}
-
+ spin_unlock(&dev->rbsl);
exit:
dev->interrupt_in_done = 1;
wake_up_interruptible(&dev->read_wait);
@@ -330,6 +338,7 @@ static int ld_usb_open(struct inode *inode, struct file *file)
/* initialize in direction */
dev->ring_head = 0;
dev->ring_tail = 0;
+ dev->buffer_overflow = 0;
usb_fill_int_urb(dev->interrupt_in_urb,
interface_to_usbdev(interface),
usb_rcvintpipe(interface_to_usbdev(interface),
@@ -439,6 +448,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
size_t *actual_buffer;
size_t bytes_to_read;
int retval = 0;
+ int rv;
dev = file->private_data;
@@ -460,7 +470,10 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
}
/* wait for data */
+ spin_lock_irq(&dev->rbsl);
if (dev->ring_head == dev->ring_tail) {
+ dev->interrupt_in_done = 0;
+ spin_unlock_irq(&dev->rbsl);
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
goto unlock_exit;
@@ -468,6 +481,8 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
if (retval < 0)
goto unlock_exit;
+ } else {
+ spin_unlock_irq(&dev->rbsl);
}
/* actual_buffer contains actual_length + interrupt_in_buffer */
@@ -486,6 +501,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
retval = bytes_to_read;
+ spin_lock_irq(&dev->rbsl);
+ if (dev->buffer_overflow) {
+ dev->buffer_overflow = 0;
+ spin_unlock_irq(&dev->rbsl);
+ rv = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ if (rv < 0)
+ dev->buffer_overflow = 1;
+ } else {
+ spin_unlock_irq(&dev->rbsl);
+ }
+
unlock_exit:
/* unlock the device */
up(&dev->sem);
@@ -635,6 +661,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *
goto exit;
}
init_MUTEX(&dev->sem);
+ spin_lock_init(&dev->rbsl);
dev->intf = intf;
init_waitqueue_head(&dev->read_wait);
init_waitqueue_head(&dev->write_wait);
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index ea2175bb227..fe437125f14 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -63,7 +63,8 @@ static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
request, requesttype, value, index,
buf, 0x0000001, 1000);
if (result)
- dbg("%03d < %d bytes [0x%02X]", seq, result, buf[0]);
+ dbg("%03d < %d bytes [0x%02X]", seq, result,
+ ((unsigned char *)buf)[0]);
else
dbg("%03d < 0 bytes", seq);
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 95a1805b064..2353679f601 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -273,12 +273,18 @@ static __u16 product;
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
struct ftdi_sio_quirk {
+ int (*probe)(struct usb_serial *);
void (*setup)(struct usb_serial *); /* Special settings during startup. */
};
+static int ftdi_olimex_probe (struct usb_serial *serial);
static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
+static struct ftdi_sio_quirk ftdi_olimex_quirk = {
+ .probe = ftdi_olimex_probe,
+};
+
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
.setup = ftdi_USB_UIRT_setup,
};
@@ -319,6 +325,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
@@ -525,6 +532,9 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -669,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = {
/*
* ***************************************************************************
- * Utlity functions
+ * Utility functions
* ***************************************************************************
*/
@@ -1171,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
/* Probe function to check for special devices */
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
{
+ struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
+
+ if (quirk && quirk->probe) {
+ int ret = quirk->probe(serial);
+ if (ret != 0)
+ return ret;
+ }
+
usb_set_serial_data(serial, (void *)id->driver_info);
- return (0);
+ return 0;
}
static int ftdi_sio_port_probe(struct usb_serial_port *port)
@@ -1268,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
priv->force_rtscts = 1;
} /* ftdi_HE_TIRA1_setup */
+/*
+ * First port on Olimex arm-usb-ocd is reserved for JTAG interface
+ * and can be accessed from userspace using openocd.
+ */
+static int ftdi_olimex_probe(struct usb_serial *serial)
+{
+ struct usb_device *udev = serial->dev;
+ struct usb_interface *interface = serial->interface;
+
+ dbg("%s",__FUNCTION__);
+
+ if (interface == udev->actconfig->interface[0]) {
+ info("Ignoring reserved serial port on Olimex arm-usb-ocd\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
* it is called when the usb device is disconnected
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 77ad0a09b38..33aee904724 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -60,6 +60,9 @@
/* DMX4ALL DMX Interfaces */
#define FTDI_DMX4ALL 0xC850
+/* OpenDCC (www.opendcc.de) product id */
+#define FTDI_OPENDCC_PID 0xBFD8
+
/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
/* they use the ftdi chipset for the USB interface and the vendor id is the same */
#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */
@@ -518,6 +521,15 @@
#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */
#define FTDI_IBS_PROD_PID 0xff3f /* future device */
+/*
+ * MaxStream devices www.maxstream.net
+ */
+#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */
+
+/* Olimex */
+#define OLIMEX_VID 0x15BA
+#define OLIMEX_ARM_USB_OCD_PID 0x0003
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 2366e7b63ec..36620c65107 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -769,11 +769,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
return;
}
- if (!mos7840_port) {
- dbg("%s", "NULL mos7840_port pointer \n");
- return;
- }
-
if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) {
dbg("%s", "Port Paranoia failed \n");
return;
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 4adfab988e8..00afc1712c3 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -165,12 +165,10 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
struct usb_serial_port *wport;
- struct omninet_data *od = usb_get_serial_port_data(port);
int result = 0;
dbg("%s - port %d", __FUNCTION__, port->number);
- od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
wport = serial->port[1];
wport->tty = port->tty;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 8c3f55b080b..89f067d9507 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -165,7 +165,6 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */
- { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel XU870 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 644607de4c1..ac1829c6e8f 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -35,6 +35,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
@@ -60,6 +61,7 @@ static struct usb_device_id id_table_3port [] = {
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 6d3dad3d1da..d35369392fe 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -84,7 +84,7 @@ resubmit:
static int usb_onetouch_open(struct input_dev *dev)
{
- struct usb_onetouch *onetouch = dev->private;
+ struct usb_onetouch *onetouch = input_get_drvdata(dev);
onetouch->is_open = 1;
onetouch->irq->dev = onetouch->udev;
@@ -98,7 +98,7 @@ static int usb_onetouch_open(struct input_dev *dev)
static void usb_onetouch_close(struct input_dev *dev)
{
- struct usb_onetouch *onetouch = dev->private;
+ struct usb_onetouch *onetouch = input_get_drvdata(dev);
usb_kill_urb(onetouch->irq);
onetouch->is_open = 0;
@@ -185,13 +185,14 @@ int onetouch_connect_input(struct us_data *ss)
input_dev->name = onetouch->name;
input_dev->phys = onetouch->phys;
usb_to_input_id(udev, &input_dev->id);
- input_dev->cdev.dev = &udev->dev;
+ input_dev->dev.parent = &udev->dev;
set_bit(EV_KEY, input_dev->evbit);
set_bit(ONETOUCH_BUTTON, input_dev->keybit);
clear_bit(0, input_dev->keybit);
- input_dev->private = onetouch;
+ input_set_drvdata(input_dev, onetouch);
+
input_dev->open = usb_onetouch_open;
input_dev->close = usb_onetouch_close;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 8b3145ab775..54979c239c6 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1179,14 +1179,28 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
-/* This is a virtual windows driver CD, which the zd1211rw driver automatically
- * converts into a WLAN device. */
+/* These are virtual windows driver CDs, which the zd1211rw driver
+ * automatically converts into WLAN devices. */
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
"ZyXEL",
"G-220F USB-WLAN Install",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_DEVICE ),
+UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
+ "SiteCom",
+ "WL-117 USB-WLAN Install",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE ),
+
+/* SanDisk that has a second LUN for a driver ISO, reported by
+ * Ben Collins <bcollins@ubuntu.com> */
+UNUSUAL_DEV( 0x0781, 0x5406, 0x0000, 0xffff,
+ "SanDisk",
+ "U3 Cruzer Micro driver ISO",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN ),
+
#ifdef CONFIG_USB_STORAGE_ISD200
UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
"ATI",
@@ -1265,6 +1279,15 @@ UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
+/* Reported by Edward Chapman (taken from linux-usb mailing list)
+ Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive */
+UNUSUAL_DEV( 0x0dd8, 0xd202, 0x0000, 0x9999,
+ "Netac",
+ "USB Flash Disk",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
+
/* Patch by Stephan Walter <stephan.walter@epfl.ch>
* I don't know why, but it works... */
UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4d7485fa553..403dac787eb 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -704,6 +704,91 @@ config FB_CG6
This is the frame buffer device driver for the CGsix (GX, TurboGX)
frame buffer.
+config FB_FFB
+ bool "Creator/Creator3D/Elite3D support"
+ depends on FB_SBUS && SPARC64
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Creator, Creator3D,
+ and Elite3D graphics boards.
+
+config FB_TCX
+ bool "TCX (SS4/SS5 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the TCX 24/8bit frame
+ buffer.
+
+config FB_CG14
+ bool "CGfourteen (SX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGfourteen frame
+ buffer on Desktop SPARCsystems with the SX graphics option.
+
+config FB_P9100
+ bool "P9100 (Sparcbook 3 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the P9100 card
+ supported on Sparcbook 3 machines.
+
+config FB_LEO
+ bool "Leo (ZX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the SBUS-based Sun ZX
+ (leo) frame buffer cards.
+
+config FB_IGA
+ bool "IGA 168x display support"
+ depends on (FB = y) && SPARC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the INTERGRAPHICS 1680 and
+ successor frame buffer cards.
+
+config FB_XVR500
+ bool "Sun XVR-500 3DLABS Wildcat support"
+ depends on (FB = y) && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firwmare has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
+config FB_XVR2500
+ bool "Sun XVR-2500 3DLABS Wildcat support"
+ depends on (FB = y) && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-2500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firwmare has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
config FB_PVR2
tristate "NEC PowerVR 2 display support"
depends on FB && SH_DREAMCAST
@@ -1195,7 +1280,7 @@ config FB_ATY
config FB_ATY_CT
bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
depends on PCI && FB_ATY
- default y if SPARC64 && FB_PCI
+ default y if SPARC64 && PCI
help
Say Y here to support use of ATI's 64-bit Rage boards (or other
boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
@@ -1484,95 +1569,6 @@ config FB_AU1200
source "drivers/video/geode/Kconfig"
-config FB_FFB
- bool "Creator/Creator3D/Elite3D support"
- depends on FB_SBUS && SPARC64
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Creator, Creator3D,
- and Elite3D graphics boards.
-
-config FB_TCX
- bool "TCX (SS4/SS5 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the TCX 24/8bit frame
- buffer.
-
-config FB_CG14
- bool "CGfourteen (SX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGfourteen frame
- buffer on Desktop SPARCsystems with the SX graphics option.
-
-config FB_P9100
- bool "P9100 (Sparcbook 3 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the P9100 card
- supported on Sparcbook 3 machines.
-
-config FB_LEO
- bool "Leo (ZX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the SBUS-based Sun ZX
- (leo) frame buffer cards.
-
-config FB_XVR500
- bool "Sun XVR-500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firwmare has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_XVR2500
- bool "Sun XVR-2500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-2500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firwmare has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_PCI
- bool "PCI framebuffers"
- depends on (FB = y) && PCI && SPARC
-
-config FB_IGA
- bool "IGA 168x display support"
- depends on SPARC32 && FB_PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the INTERGRAPHICS 1680 and
- successor frame buffer cards.
-
config FB_HIT
tristate "HD64461 Frame Buffer support"
depends on FB && HD64461
@@ -1796,9 +1792,10 @@ config FB_IBM_GXT4500
config FB_PS3
bool "PS3 GPU framebuffer driver"
depends on (FB = y) && PS3_PS3AV
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
---help---
Include support for the virtual frame buffer in the PS3 platform.
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index ba6fede5c46..8a1b07c7439 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -1055,9 +1055,10 @@ err_enable_device:
static void __devexit ark_pci_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
- struct arkfb_info *par = info->par;
if (info) {
+ struct arkfb_info *par = info->par;
+
#ifdef CONFIG_MTRR
if (par->mtrr_reg >= 0) {
mtrr_del(par->mtrr_reg, 0, 0);
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 9b26dda18a3..ac46cc3f6a2 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -47,7 +47,7 @@ targets := promcon_tbl.c
quiet_cmd_conmakehash = CNMKHSH $@
cmd_conmakehash = scripts/conmakehash $< | \
sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \
- -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+ -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@
$(obj)/promcon_tbl.c: $(src)/prom.uni
$(call cmd,conmakehash)
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 71f24e00fcd..8e6ef4bc7a5 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -176,7 +176,6 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
#endif
extern void fbcon_set_bitops(struct fbcon_ops *ops);
extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
-extern struct class *fb_class;
#define FBCON_ATTRIBUTE_UNDERLINE 1
#define FBCON_ATTRIBUTE_REVERSE 2
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 1d4e8354b56..3f6c98fad43 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -656,7 +656,7 @@ static int ffb_setcolreg(unsigned regno,
{
u32 value;
- if (regno >= 256)
+ if (regno >= 16)
return 1;
red >>= 8;
@@ -903,7 +903,7 @@ ffb_init_fix(struct fb_info *info)
struct all_info {
struct fb_info info;
struct ffb_par par;
- u32 pseudo_palette[256];
+ u32 pseudo_palette[16];
};
static int ffb_init_one(struct of_device *op)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 267c1ff9ebd..a1258989859 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -394,26 +394,18 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
/* initialize GPIOs */
imx_gpio_mode(PD6_PF_LSCLK);
- imx_gpio_mode(PD10_PF_SPL_SPR);
imx_gpio_mode(PD11_PF_CONTRAST);
imx_gpio_mode(PD14_PF_FLM_VSYNC);
imx_gpio_mode(PD13_PF_LP_HSYNC);
- imx_gpio_mode(PD7_PF_REV);
- imx_gpio_mode(PD8_PF_CLS);
-
-#ifndef CONFIG_MACH_PIMX1
- /* on PiMX1 used as buffers enable signal
- */
- imx_gpio_mode(PD9_PF_PS);
-#endif
-
-#ifndef CONFIG_MACH_MX1FS2
- /* on mx1fs2 this pin is used to (de)activate the display, so we need
- * it as a normal gpio
- */
imx_gpio_mode(PD12_PF_ACD_OE);
-#endif
+ /* These are only needed for Sharp HR TFT displays */
+ if (fbi->pcr & PCR_SHARP) {
+ imx_gpio_mode(PD7_PF_REV);
+ imx_gpio_mode(PD8_PF_CLS);
+ imx_gpio_mode(PD9_PF_PS);
+ imx_gpio_mode(PD10_PF_SPL_SPR);
+ }
}
#ifdef CONFIG_PM
@@ -476,7 +468,6 @@ static int __init imxfb_init_fbinfo(struct device *dev)
info->fbops = &imxfb_ops;
info->flags = FBINFO_FLAG_DEFAULT;
- info->pseudo_palette = (fbi + 1);
fbi->rgb[RGB_16] = &def_rgb_16;
fbi->rgb[RGB_8] = &def_rgb_8;
@@ -499,6 +490,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
info->var.sync = inf->sync;
info->var.grayscale = inf->cmap_greyscale;
fbi->cmap_inverse = inf->cmap_inverse;
+ fbi->cmap_static = inf->cmap_static;
fbi->pcr = inf->pcr;
fbi->lscr1 = inf->lscr1;
fbi->dmacr = inf->dmacr;
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index bd30aba242d..731d7a5c5aa 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1286,34 +1286,36 @@ static int neofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
if (regno >= fb->cmap.len || regno > 255)
return -EINVAL;
- switch (fb->var.bits_per_pixel) {
- case 8:
+ if (fb->var.bits_per_pixel <= 8) {
outb(regno, 0x3c8);
outb(red >> 10, 0x3c9);
outb(green >> 10, 0x3c9);
outb(blue >> 10, 0x3c9);
- break;
- case 16:
- ((u32 *) fb->pseudo_palette)[regno] =
+ } else if (regno < 16) {
+ switch (fb->var.bits_per_pixel) {
+ case 16:
+ ((u32 *) fb->pseudo_palette)[regno] =
((red & 0xf800)) | ((green & 0xfc00) >> 5) |
((blue & 0xf800) >> 11);
- break;
- case 24:
- ((u32 *) fb->pseudo_palette)[regno] =
+ break;
+ case 24:
+ ((u32 *) fb->pseudo_palette)[regno] =
((red & 0xff00) << 8) | ((green & 0xff00)) |
((blue & 0xff00) >> 8);
- break;
+ break;
#ifdef NO_32BIT_SUPPORT_YET
- case 32:
- ((u32 *) fb->pseudo_palette)[regno] =
+ case 32:
+ ((u32 *) fb->pseudo_palette)[regno] =
((transp & 0xff00) << 16) | ((red & 0xff00) << 8) |
((green & 0xff00)) | ((blue & 0xff00) >> 8);
- break;
+ break;
#endif
- default:
- return 1;
+ default:
+ return 1;
+ }
}
+
return 0;
}
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index ab5e66890e4..0a04483aa3e 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -183,15 +183,17 @@ static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
index = PM2VR_RD_INDEXED_DATA;
break;
}
- mb();
+ wmb();
pm2_WR(p, index, v);
+ wmb();
}
static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
- mb();
+ wmb();
pm2_WR(p, PM2VR_RD_INDEXED_DATA, v);
+ wmb();
}
#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
@@ -466,11 +468,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
WAIT_FIFO(par, 8);
pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
- wmb();
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
- wmb();
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
rmb();
for (i = 256;
@@ -483,12 +483,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
pm2_mnp(clk, &m, &n, &p);
WAIT_FIFO(par, 10);
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
- wmb();
pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
rmb();
for (i = 256;
@@ -509,12 +506,9 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
pm2_mnp(clk, &m, &n, &p);
WAIT_FIFO(par, 8);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
- wmb();
pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
rmb();
for (i = 256;
@@ -1066,10 +1060,9 @@ static void pm2fb_block_op(struct fb_info* info, int copy,
if (!w || !h)
return;
- WAIT_FIFO(par, 6);
+ WAIT_FIFO(par, 5);
pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
- pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0);
if (copy)
pm2_WR(par, PM2R_FB_SOURCE_DELTA,
((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index c77a1a1fd46..b52e883f0a5 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -52,11 +52,6 @@
static char *mode_option __devinitdata;
/*
- * If your driver supports multiple boards, you should make the
- * below data types arrays, or allocate them dynamically (using kmalloc()).
- */
-
-/*
* This structure defines the hardware state of the graphics card. Normally
* you place this in a header file in linux/include/video. This file usually
* also includes register information. That allows other driver subsystems
@@ -67,7 +62,7 @@ struct pm3_par {
unsigned char __iomem *v_regs;/* virtual address of p_regs */
u32 video; /* video flags before blanking */
u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */
- u32 palette[16];
+ u32 palette[16];
};
/*
@@ -104,36 +99,28 @@ static inline void PM3_WAIT(struct pm3_par *par, u32 n)
while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
}
-static inline void PM3_SLOW_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
-{
- if (par->v_regs) {
- mb();
- PM3_WAIT(par, 1);
- wmb();
- PM3_WRITE_REG(par, off, v);
- }
-}
-
-static inline void PM3_SET_INDEX(struct pm3_par *par, unsigned index)
-{
- PM3_SLOW_WRITE_REG(par, PM3RD_IndexHigh, (index >> 8) & 0xff);
- PM3_SLOW_WRITE_REG(par, PM3RD_IndexLow, index & 0xff);
-}
-
static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
{
- PM3_SET_INDEX(par, r);
+ PM3_WAIT(par, 3);
+ PM3_WRITE_REG(par, PM3RD_IndexHigh, (r >> 8) & 0xff);
+ PM3_WRITE_REG(par, PM3RD_IndexLow, r & 0xff);
wmb();
PM3_WRITE_REG(par, PM3RD_IndexedData, v);
+ wmb();
}
static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno,
unsigned char r, unsigned char g, unsigned char b)
{
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, r);
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, g);
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, b);
+ PM3_WAIT(par, 4);
+ PM3_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
+ wmb();
+ PM3_WRITE_REG(par, PM3RD_PaletteData, r);
+ wmb();
+ PM3_WRITE_REG(par, PM3RD_PaletteData, g);
+ wmb();
+ PM3_WRITE_REG(par, PM3RD_PaletteData, b);
+ wmb();
}
static void pm3fb_clear_colormap(struct pm3_par *par,
@@ -141,7 +128,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par,
{
int i;
- for (i = 0; i < 256 ; i++) /* fill color map with white */
+ for (i = 0; i < 256 ; i++)
pm3fb_set_color(par, i, r, g, b);
}
@@ -175,19 +162,26 @@ static void pm3fb_calculate_clock(unsigned long reqclock,
}
}
-static inline int pm3fb_shift_bpp(unsigned long depth, int v)
+static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
{
- switch (depth) {
+ if ( var->bits_per_pixel == 16 )
+ return var->red.length + var->green.length
+ + var->blue.length;
+
+ return var->bits_per_pixel;
+}
+
+static inline int pm3fb_shift_bpp(unsigned bpp, int v)
+{
+ switch (bpp) {
case 8:
return (v >> 4);
- case 12:
- case 15:
case 16:
return (v >> 3);
case 32:
return (v >> 2);
}
- DPRINTK("Unsupported depth %ld\n", depth);
+ DPRINTK("Unsupported depth %u\n", bpp);
return 0;
}
@@ -206,56 +200,50 @@ static void pm3fb_write_mode(struct fb_info *info)
const u32 vbend = vsend + info->var.upper_margin;
const u32 vtotal = info->var.yres + vbend;
const u32 width = (info->var.xres_virtual + 7) & ~7;
-
- PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
- PM3_SLOW_WRITE_REG(par, PM3Aperture0, 0x00000000);
- PM3_SLOW_WRITE_REG(par, PM3Aperture1, 0x00000000);
- PM3_SLOW_WRITE_REG(par, PM3FIFODis, 0x00000007);
-
- PM3_SLOW_WRITE_REG(par, PM3HTotal,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- htotal - 1));
- PM3_SLOW_WRITE_REG(par, PM3HsEnd,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hsend));
- PM3_SLOW_WRITE_REG(par, PM3HsStart,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hsstart));
- PM3_SLOW_WRITE_REG(par, PM3HbEnd,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hbend));
- PM3_SLOW_WRITE_REG(par, PM3HgEnd,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hbend));
- PM3_SLOW_WRITE_REG(par, PM3ScreenStride,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- width));
- PM3_SLOW_WRITE_REG(par, PM3VTotal, vtotal - 1);
- PM3_SLOW_WRITE_REG(par, PM3VsEnd, vsend - 1);
- PM3_SLOW_WRITE_REG(par, PM3VsStart, vsstart - 1);
- PM3_SLOW_WRITE_REG(par, PM3VbEnd, vbend);
-
- switch (info->var.bits_per_pixel) {
+ const unsigned bpp = info->var.bits_per_pixel;
+
+ PM3_WAIT(par, 20);
+ PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
+ PM3_WRITE_REG(par, PM3Aperture0, 0x00000000);
+ PM3_WRITE_REG(par, PM3Aperture1, 0x00000000);
+ PM3_WRITE_REG(par, PM3FIFODis, 0x00000007);
+
+ PM3_WRITE_REG(par, PM3HTotal,
+ pm3fb_shift_bpp(bpp, htotal - 1));
+ PM3_WRITE_REG(par, PM3HsEnd,
+ pm3fb_shift_bpp(bpp, hsend));
+ PM3_WRITE_REG(par, PM3HsStart,
+ pm3fb_shift_bpp(bpp, hsstart));
+ PM3_WRITE_REG(par, PM3HbEnd,
+ pm3fb_shift_bpp(bpp, hbend));
+ PM3_WRITE_REG(par, PM3HgEnd,
+ pm3fb_shift_bpp(bpp, hbend));
+ PM3_WRITE_REG(par, PM3ScreenStride,
+ pm3fb_shift_bpp(bpp, width));
+ PM3_WRITE_REG(par, PM3VTotal, vtotal - 1);
+ PM3_WRITE_REG(par, PM3VsEnd, vsend - 1);
+ PM3_WRITE_REG(par, PM3VsStart, vsstart - 1);
+ PM3_WRITE_REG(par, PM3VbEnd, vbend);
+
+ switch (bpp) {
case 8:
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_8BIT);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_8BIT);
break;
- case 12:
- case 15:
case 16:
#ifndef __BIG_ENDIAN
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_16BIT);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_16BIT);
#else
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_16BIT |
PM3ByApertureMode_BYTESWAP_BADC);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_16BIT |
PM3ByApertureMode_BYTESWAP_BADC);
#endif /* ! __BIG_ENDIAN */
@@ -263,23 +251,22 @@ static void pm3fb_write_mode(struct fb_info *info)
case 32:
#ifndef __BIG_ENDIAN
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_32BIT);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_32BIT);
#else
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_32BIT |
PM3ByApertureMode_BYTESWAP_DCBA);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_32BIT |
PM3ByApertureMode_BYTESWAP_DCBA);
#endif /* ! __BIG_ENDIAN */
break;
default:
- DPRINTK("Unsupported depth %d\n",
- info->var.bits_per_pixel);
+ DPRINTK("Unsupported depth %d\n", bpp);
break;
}
@@ -296,14 +283,15 @@ static void pm3fb_write_mode(struct fb_info *info)
PM3VideoControl_VSYNC_MASK);
video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
PM3VideoControl_VSYNC_ACTIVE_HIGH;
- PM3_SLOW_WRITE_REG(par, PM3VideoControl, video);
+ PM3_WRITE_REG(par, PM3VideoControl, video);
}
- PM3_SLOW_WRITE_REG(par, PM3VClkCtl,
+ PM3_WRITE_REG(par, PM3VClkCtl,
(PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC));
- PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
- PM3_SLOW_WRITE_REG(par, PM3ChipConfig,
+ PM3_WRITE_REG(par, PM3ScreenBase, par->base);
+ PM3_WRITE_REG(par, PM3ChipConfig,
(PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD));
+ wmb();
{
unsigned char uninitialized_var(m); /* ClkPreScale */
unsigned char uninitialized_var(n); /* ClkFeedBackScale */
@@ -337,7 +325,7 @@ static void pm3fb_write_mode(struct fb_info *info)
PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00);
- switch (info->var.bits_per_pixel) {
+ switch (pm3fb_depth(&info->var)) {
case 8:
PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
PM3RD_PixelSize_8_BIT_PIXELS);
@@ -393,57 +381,44 @@ static void pm3fb_write_mode(struct fb_info *info)
* hardware independent functions
*/
int pm3fb_init(void);
-int pm3fb_setup(char*);
static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
u32 lpitch;
+ unsigned bpp = var->red.length + var->green.length
+ + var->blue.length + var->transp.length;
- var->transp.offset = 0;
- var->transp.length = 0;
- switch(var->bits_per_pixel) {
- case 8:
- var->red.length = var->green.length = var->blue.length = 8;
- var->red.offset = var->green.offset = var->blue.offset = 0;
- break;
- case 12:
- var->red.offset = 8;
- var->red.length = 4;
- var->green.offset = 4;
- var->green.length = 4;
- var->blue.offset = 0;
- var->blue.length = 4;
- var->transp.offset = 12;
- var->transp.length = 4;
- case 15:
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 15;
- var->transp.length = 1;
- break;
- case 16:
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- break;
- case 32:
- var->transp.offset = 24;
- var->transp.length = 8;
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 8;
- break;
- default:
- DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
- return -EINVAL;
+ if ( bpp != var->bits_per_pixel ) {
+ /* set predefined mode for bits_per_pixel settings */
+
+ switch(var->bits_per_pixel) {
+ case 8:
+ var->red.length = var->green.length = var->blue.length = 8;
+ var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case 16:
+ var->red.length = var->blue.length = 5;
+ var->green.length = 6;
+ var->transp.length = 0;
+ break;
+ case 32:
+ var->red.length = var->green.length = var->blue.length = 8;
+ var->transp.length = 8;
+ break;
+ default:
+ DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
+ return -EINVAL;
+ }
+ }
+ /* it is assumed BGRA order */
+ if (var->bits_per_pixel > 8 )
+ {
+ var->blue.offset = 0;
+ var->green.offset = var->blue.length;
+ var->red.offset = var->green.offset + var->green.length;
+ var->transp.offset = var->red.offset + var->red.length;
}
var->height = var->width = -1;
@@ -502,10 +477,9 @@ static int pm3fb_set_par(struct fb_info *info)
{
struct pm3_par *par = info->par;
const u32 xres = (info->var.xres + 31) & ~31;
- const int depth = (info->var.bits_per_pixel + 7) & ~7;
+ const unsigned bpp = info->var.bits_per_pixel;
- par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
- (info->var.yoffset * xres)
+ par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres)
+ info->var.xoffset);
par->video = 0;
@@ -524,18 +498,16 @@ static int pm3fb_set_par(struct fb_info *info)
else
par->video |= PM3VideoControl_LINE_DOUBLE_OFF;
- if (info->var.activate == FB_ACTIVATE_NOW)
+ if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
par->video |= PM3VideoControl_ENABLE;
else {
par->video |= PM3VideoControl_DISABLE;
DPRINTK("PM3Video disabled\n");
}
- switch (depth) {
+ switch (bpp) {
case 8:
par->video |= PM3VideoControl_PIXELSIZE_8BIT;
break;
- case 12:
- case 15:
case 16:
par->video |= PM3VideoControl_PIXELSIZE_16BIT;
break;
@@ -548,9 +520,9 @@ static int pm3fb_set_par(struct fb_info *info)
}
info->fix.visual =
- (depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
info->fix.line_length = ((info->var.xres_virtual + 7) & ~7)
- * depth / 8;
+ * bpp / 8;
/* pm3fb_clear_memory(info, 0);*/
pm3fb_clear_colormap(par, 0, 0, 0);
@@ -580,8 +552,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
* var->{color}.length contains length of bitfield
* {hardwarespecific} contains width of DAC
* pseudo_palette[X] is programmed to (X << red.offset) |
- * (X << green.offset) |
- * (X << blue.offset)
+ * (X << green.offset) |
+ * (X << blue.offset)
* RAMDAC[X] is programmed to (red, green, blue)
* color depth = SUM(var->{color}.length)
*
@@ -621,7 +593,6 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
case 8:
break;
case 16:
- case 24:
case 32:
((u32*)(info->pseudo_palette))[regno] = v;
break;
@@ -643,7 +614,8 @@ static int pm3fb_pan_display(struct fb_var_screeninfo *var,
par->base = pm3fb_shift_bpp(var->bits_per_pixel,
(var->yoffset * xres)
+ var->xoffset);
- PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par, PM3ScreenBase, par->base);
return 0;
}
@@ -665,31 +637,31 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
switch (blank_mode) {
case FB_BLANK_UNBLANK:
- video = video | PM3VideoControl_ENABLE;
+ video |= PM3VideoControl_ENABLE;
break;
- case FB_BLANK_NORMAL: /* FIXME */
- video = video & ~(PM3VideoControl_ENABLE);
+ case FB_BLANK_NORMAL:
+ video &= ~(PM3VideoControl_ENABLE);
break;
case FB_BLANK_HSYNC_SUSPEND:
- video = video & ~(PM3VideoControl_HSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
+ video &= ~(PM3VideoControl_HSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
case FB_BLANK_VSYNC_SUSPEND:
- video = video & ~(PM3VideoControl_VSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
+ video &= ~(PM3VideoControl_VSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
case FB_BLANK_POWERDOWN:
- video = video & ~(PM3VideoControl_HSYNC_MASK |
- PM3VideoControl_VSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
+ video &= ~(PM3VideoControl_HSYNC_MASK |
+ PM3VideoControl_VSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
default:
DPRINTK("Unsupported blanking %d\n", blank_mode);
return 1;
}
- PM3_SLOW_WRITE_REG(par,PM3VideoControl, video);
-
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par,PM3VideoControl, video);
return 0;
}
@@ -703,9 +675,9 @@ static struct fb_ops pm3fb_ops = {
.fb_set_par = pm3fb_set_par,
.fb_setcolreg = pm3fb_setcolreg,
.fb_pan_display = pm3fb_pan_display,
- .fb_fillrect = cfb_fillrect, /* Needed !!! */
- .fb_copyarea = cfb_copyarea, /* Needed !!! */
- .fb_imageblit = cfb_imageblit, /* Needed !!! */
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
.fb_blank = pm3fb_blank,
};
@@ -722,7 +694,7 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
unsigned long memsize = 0, tempBypass, i, temp1, temp2;
unsigned char __iomem *screen_mem;
- pm3fb_fix.smem_len = 64 * 1024 * 1024; /* request full aperture size */
+ pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
/* Linear frame buffer - request region and map it. */
if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
"pm3fb smem")) {
@@ -744,7 +716,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
- PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
/* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
for (i = 0; i < 32; i++) {
@@ -765,10 +738,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
if (memsize + 1 == i) {
for (i = 0; i < 32; i++) {
/* Clear first 32MB ; 0 is 0, no need to byteswap */
- writel(0x0000000,
- (screen_mem + (i * 1048576)));
- mb();
+ writel(0x0000000, (screen_mem + (i * 1048576)));
}
+ wmb();
for (i = 32; i < 64; i++) {
fb_writel(i * 0x00345678,
@@ -787,7 +759,8 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
}
DPRINTK("Second detect pass got %ld MB\n", memsize + 1);
- PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
iounmap(screen_mem);
release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
@@ -890,7 +863,6 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
goto err_exit_both;
}
- /* This has to been done !!! */
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
retval = -ENOMEM;
goto err_exit_both;
@@ -907,7 +879,7 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
}
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
info->fix.id);
- pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */
+ pci_set_drvdata(dev, info);
return 0;
err_exit_all:
@@ -949,8 +921,7 @@ static void __devexit pm3fb_remove(struct pci_dev *dev)
static struct pci_device_id pm3fb_id_table[] = {
{ PCI_VENDOR_ID_3DLABS, 0x0a,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
};
@@ -964,6 +935,22 @@ static struct pci_driver pm3fb_driver = {
MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
+#ifndef MODULE
+ /*
+ * Setup
+ */
+
+/*
+ * Only necessary if your driver takes special options,
+ * otherwise we fall back on the generic fb_setup().
+ */
+static int __init pm3fb_setup(char *options)
+{
+ /* Parse user speficied options (`video=pm3fb:') */
+ return 0;
+}
+#endif /* MODULE */
+
int __init pm3fb_init(void)
{
/*
@@ -985,22 +972,6 @@ static void __exit pm3fb_exit(void)
pci_unregister_driver(&pm3fb_driver);
}
-#ifndef MODULE
- /*
- * Setup
- */
-
-/*
- * Only necessary if your driver takes special options,
- * otherwise we fall back on the generic fb_setup().
- */
-int __init pm3fb_setup(char *options)
-{
- /* Parse user speficied options (`video=pm3fb:') */
- return 0;
-}
-#endif /* MODULE */
-
module_init(pm3fb_init);
module_exit(pm3fb_exit);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 9756a728b74..9cf92ba5d6e 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -951,12 +951,14 @@ static int ps3fb_xdr_settings(u64 xdr_lpar)
static struct fb_ops ps3fb_ops = {
.fb_open = ps3fb_open,
.fb_release = ps3fb_release,
+ .fb_read = fb_sys_read,
+ .fb_write = fb_sys_write,
.fb_check_var = ps3fb_check_var,
.fb_set_par = ps3fb_set_par,
.fb_setcolreg = ps3fb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
.fb_mmap = ps3fb_mmap,
.fb_blank = ps3fb_blank,
.fb_ioctl = ps3fb_ioctl,
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 836a612af97..64779e70408 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -132,7 +132,6 @@ static struct fb_info info;
static struct xxx_par __initdata current_par;
int xxxfb_init(void);
-int xxxfb_setup(char*);
/**
* xxxfb_open - Optional function. Called when the framebuffer is
@@ -975,6 +974,21 @@ static struct platform_device xxxfb_device = {
.name = "xxxfb",
};
+#ifndef MODULE
+ /*
+ * Setup
+ */
+
+/*
+ * Only necessary if your driver takes special options,
+ * otherwise we fall back on the generic fb_setup().
+ */
+int __init xxxfb_setup(char *options)
+{
+ /* Parse user speficied options (`video=xxxfb:') */
+}
+#endif /* MODULE */
+
static int __init xxxfb_init(void)
{
int ret;
@@ -1006,21 +1020,6 @@ static void __exit xxxfb_exit(void)
}
#endif /* CONFIG_PCI */
-#ifdef MODULE
- /*
- * Setup
- */
-
-/*
- * Only necessary if your driver takes special options,
- * otherwise we fall back on the generic fb_setup().
- */
-int __init xxxfb_setup(char *options)
-{
- /* Parse user speficied options (`video=xxxfb:') */
-}
-#endif /* MODULE */
-
/* ------------------------------------------------------------------------- */
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
index 4316c7fe8e2..c3869a96ab5 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/sunxvr2500.c
@@ -28,7 +28,7 @@ struct s3d_info {
unsigned int depth;
unsigned int fb_size;
- u32 pseudo_palette[256];
+ u32 pseudo_palette[16];
};
static int __devinit s3d_get_props(struct s3d_info *sp)
@@ -52,15 +52,14 @@ static int s3d_setcolreg(unsigned regno,
{
u32 value;
- if (regno >= 256)
- return 1;
+ if (regno < 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
- red >>= 8;
- green >>= 8;
- blue >>= 8;
-
- value = (blue << 24) | (green << 16) | (red << 8);
- ((u32 *)info->pseudo_palette)[regno] = value;
+ value = (blue << 24) | (green << 16) | (red << 8);
+ ((u32 *)info->pseudo_palette)[regno] = value;
+ }
return 0;
}
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index 08880a62bfa..71bf3f1f00b 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -50,7 +50,7 @@ struct e3d_info {
u32 fb8_0_off;
u32 fb8_1_off;
- u32 pseudo_palette[256];
+ u32 pseudo_palette[16];
};
static int __devinit e3d_get_props(struct e3d_info *ep)
@@ -126,7 +126,9 @@ static int e3d_setcolreg(unsigned regno,
blue_8 = blue >> 8;
value = (blue_8 << 24) | (green_8 << 16) | (red_8 << 8);
- ((u32 *)info->pseudo_palette)[regno] = value;
+
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16)
+ ((u32 *)info->pseudo_palette)[regno] = value;
red_10 = red >> 6;
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index 5e9755e464a..30c0b948852 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -778,9 +778,10 @@ err_enable_device:
static void __devexit vt8623_pci_remove(struct pci_dev *dev)
{
struct fb_info *info = pci_get_drvdata(dev);
- struct vt8623fb_info *par = info->par;
if (info) {
+ struct vt8623fb_info *par = info->par;
+
#ifdef CONFIG_MTRR
if (par->mtrr_reg >= 0) {
mtrr_del(par->mtrr_reg, 0, 0);
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 5fc86ea2069..003c49a490e 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -660,7 +660,7 @@ int __init w100fb_probe(struct platform_device *pdev)
err = -ENODEV;
goto out;
}
- printk(" at 0x%08lx.\n", mem->start+W100_CFG_BASE);
+ printk(" at 0x%08lx.\n", (unsigned long) mem->start+W100_CFG_BASE);
/* Remap the framebuffer */
remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE);
@@ -753,10 +753,14 @@ int __init w100fb_probe(struct platform_device *pdev)
goto out;
}
- device_create_file(&pdev->dev, &dev_attr_fastpllclk);
- device_create_file(&pdev->dev, &dev_attr_reg_read);
- device_create_file(&pdev->dev, &dev_attr_reg_write);
- device_create_file(&pdev->dev, &dev_attr_flip);
+ err = device_create_file(&pdev->dev, &dev_attr_fastpllclk);
+ err |= device_create_file(&pdev->dev, &dev_attr_reg_read);
+ err |= device_create_file(&pdev->dev, &dev_attr_reg_write);
+ err |= device_create_file(&pdev->dev, &dev_attr_flip);
+
+ if (err != 0)
+ printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n",
+ info->node, err);
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
return 0;