Merge branch 'for-2.6.29' of git://linux-nfs.org/~bfields/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Mar 2009 16:27:20 +0000 (09:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Mar 2009 16:27:20 +0000 (09:27 -0700)
* 'for-2.6.29' of git://linux-nfs.org/~bfields/linux:
  nfsd: nfsd should drop CAP_MKNOD for non-root
  NFSD: provide encode routine for OP_OPENATTR

33 files changed:
arch/powerpc/configs/ps3_defconfig
arch/powerpc/include/asm/cputable.h
arch/powerpc/kernel/head_32.S
arch/powerpc/platforms/ps3/Kconfig
drivers/block/Makefile
drivers/block/ps3vram.c [new file with mode: 0644]
drivers/mtd/devices/Kconfig
drivers/mtd/devices/Makefile
drivers/mtd/devices/ps3vram.c [deleted file]
drivers/usb/atm/cxacru.c
drivers/usb/class/usbtmc.c
drivers/usb/core/devio.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/image/mdc800.c
drivers/usb/misc/adutux.c
drivers/usb/misc/vstusb.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/option.c
drivers/usb/storage/unusual_devs.h
drivers/usb/wusbcore/wa-xfer.c
fs/ext4/extents.c
fs/ext4/ialloc.c
fs/ext4/mballoc.c
kernel/module.c
sound/core/oss/mixer_oss.c
sound/core/oss/pcm_oss.c
sound/core/sgbuf.c
sound/isa/opl3sa2.c
sound/pci/hda/hda_intel.c
sound/pci/mixart/mixart.c

index b6eee7c..ac14f52 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc3
-# Wed Aug 20 08:16:53 2008
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 09:28:45 2009
 #
 CONFIG_PPC64=y
 
@@ -16,13 +16,14 @@ CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 # CONFIG_VSX is not set
 CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_64=y
 CONFIG_PPC_MM_SLICES=y
 CONFIG_VIRT_CPU_ACCOUNTING=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_64BIT=y
 CONFIG_WORD_SIZE=64
-CONFIG_PPC_MERGE=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
@@ -46,7 +47,7 @@ CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_OF=y
@@ -74,10 +75,19 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -86,11 +96,13 @@ CONFIG_NAMESPACES=y
 # CONFIG_IPC_NS is not set
 # CONFIG_USER_NS is not set
 # CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
@@ -99,37 +111,36 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_MARKERS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
 CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
-# CONFIG_HAVE_CLK is not set
-CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -137,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
@@ -157,7 +167,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Platform support
@@ -183,18 +193,20 @@ CONFIG_PS3_STORAGE=y
 CONFIG_PS3_DISK=y
 CONFIG_PS3_ROM=y
 CONFIG_PS3_FLASH=y
-CONFIG_OPROFILE_PS3=y
+CONFIG_PS3_VRAM=m
 CONFIG_PS3_LPM=m
 CONFIG_PPC_CELL=y
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_IBM_CELL_BLADE is not set
 # CONFIG_PPC_CELLEB is not set
+# CONFIG_PPC_CELL_QPACE is not set
 
 #
 # Cell Broadband Engine options
 #
 CONFIG_SPU_FS=y
 CONFIG_SPU_FS_64K_LS=y
+# CONFIG_SPU_TRACE is not set
 CONFIG_SPU_BASE=y
 # CONFIG_PQ2ADS is not set
 # CONFIG_IPIC is not set
@@ -210,6 +222,7 @@ CONFIG_SPU_BASE=y
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
 # CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
 
 #
 # Kernel options
@@ -229,6 +242,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_COMPAT_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
 CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
 # CONFIG_IOMMU_VMERGE is not set
@@ -251,7 +266,6 @@ CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
-# CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 # CONFIG_SPARSEMEM_VMEMMAP is not set
@@ -261,11 +275,14 @@ CONFIG_MEMORY_HOTPLUG_SPARSE=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
-CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
+CONFIG_UNEVICTABLE_LRU=y
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_PPC_HAS_HASH_64K=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_SCHED_SMT=y
@@ -299,6 +316,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -361,6 +379,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -371,6 +390,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -392,39 +412,37 @@ CONFIG_BT_HIDP=m
 #
 # Bluetooth device drivers
 #
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIBTUSB=m
 # CONFIG_BT_HCIUART is not set
 # CONFIG_BT_HCIBCM203X is not set
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 CONFIG_CFG80211=m
+# CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_NL80211=y
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 # CONFIG_WIRELESS_EXT_SYSFS is not set
+# CONFIG_LIB80211 is not set
 CONFIG_MAC80211=m
 
 #
 # Rate control algorithm selection
 #
 CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
 CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
 CONFIG_MAC80211_RC_DEFAULT="pid"
 # CONFIG_MAC80211_MESH is not set
 # CONFIG_MAC80211_LEDS is not set
 # CONFIG_MAC80211_DEBUGFS is not set
 # CONFIG_MAC80211_DEBUG_MENU is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -450,6 +468,7 @@ CONFIG_MTD_DEBUG=y
 CONFIG_MTD_DEBUG_VERBOSE=0
 # CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
 
 #
 # User Modules And Translation Layers
@@ -494,7 +513,6 @@ CONFIG_MTD_CFI_I2=y
 #
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
-CONFIG_MTD_PS3VRAM=y
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
@@ -508,6 +526,11 @@ CONFIG_MTD_PS3VRAM=y
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -528,8 +551,13 @@ CONFIG_BLK_DEV_RAM_SIZE=65535
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -575,7 +603,17 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
-# CONFIG_MD is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+# CONFIG_DM_CRYPT is not set
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
@@ -591,6 +629,9 @@ CONFIG_MII=m
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_GELIC_NET=y
@@ -604,6 +645,7 @@ CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y
 # CONFIG_WLAN_PRE80211 is not set
 CONFIG_WLAN_80211=y
 # CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
 # CONFIG_RTL8187 is not set
@@ -615,13 +657,11 @@ CONFIG_WLAN_80211=y
 # CONFIG_B43LEGACY is not set
 CONFIG_ZD1211RW=m
 # CONFIG_ZD1211RW_DEBUG is not set
-CONFIG_RT2X00=m
-CONFIG_RT2X00_LIB=m
-CONFIG_RT2X00_LIB_USB=m
-CONFIG_RT2X00_LIB_FIRMWARE=y
-# CONFIG_RT2500USB is not set
-CONFIG_RT73USB=m
-# CONFIG_RT2X00_DEBUG is not set
+# CONFIG_RT2X00 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -634,6 +674,7 @@ CONFIG_USB_USBNET=m
 CONFIG_USB_NET_AX8817X=m
 # CONFIG_USB_NET_CDCETHER is not set
 # CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC95XX is not set
 # CONFIG_USB_NET_GL620A is not set
 # CONFIG_USB_NET_NET1080 is not set
 # CONFIG_USB_NET_PLUSB is not set
@@ -664,7 +705,7 @@ CONFIG_SLHC=m
 # Input device support
 #
 CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
 
 #
@@ -735,8 +776,10 @@ CONFIG_DEVKMEM=y
 # Non-8250 serial port support
 #
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
@@ -753,11 +796,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -767,6 +810,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -792,6 +836,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
@@ -817,6 +862,8 @@ CONFIG_FB_SYS_FOPS=y
 CONFIG_FB_PS3=y
 CONFIG_FB_PS3_DEFAULT_SIZE_M=9
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -841,6 +888,7 @@ CONFIG_FB_LOGO_EXTRA=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -849,6 +897,7 @@ CONFIG_SND_RAWMIDI=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
@@ -873,15 +922,40 @@ CONFIG_HIDRAW=y
 # USB Input Devices
 #
 CONFIG_USB_HID=m
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
 
 #
 # USB HID Boot Protocol drivers
 #
 # CONFIG_USB_KBD is not set
 # CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_COMPAT is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -898,7 +972,11 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
-CONFIG_USB_MON=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=m
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
@@ -909,6 +987,7 @@ CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
 CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=m
@@ -918,6 +997,7 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
 
 #
 # Enable Host or Gadget support to see Inventra options
@@ -929,20 +1009,20 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 # CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
 #
 
 #
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -950,7 +1030,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_SIERRA is not set
 # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -971,6 +1050,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -988,7 +1068,12 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1014,12 +1099,15 @@ CONFIG_RTC_INTF_DEV=y
 # Platform RTC drivers
 #
 # CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1028,6 +1116,7 @@ CONFIG_RTC_INTF_DEV=y
 CONFIG_RTC_DRV_PPC=m
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -1035,26 +1124,35 @@ CONFIG_RTC_DRV_PPC=m
 CONFIG_EXT2_FS=m
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS=m
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4DEV_COMPAT is not set
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 # CONFIG_QUOTA_NETLINK_INTERFACE is not set
 CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=y
 CONFIG_QUOTACTL=y
@@ -1087,16 +1185,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1106,6 +1202,7 @@ CONFIG_HUGETLB_PAGE=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1126,6 +1223,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1190,9 +1288,9 @@ CONFIG_NLS_ISO8859_1=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
@@ -1250,27 +1348,44 @@ CONFIG_DEBUG_WRITECOUNT=y
 CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
 CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
 # CONFIG_XMON is not set
 CONFIG_IRQSTACKS=y
 # CONFIG_VIRQ_DEBUG is not set
@@ -1282,16 +1397,26 @@ CONFIG_IRQSTACKS=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
@@ -1363,6 +1488,11 @@ CONFIG_CRYPTO_SALSA20=m
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
index 4911104..21172ba 100644 (file)
@@ -241,9 +241,11 @@ extern const char *powerpc_base_platform;
 /* We need to mark all pages as being coherent if we're SMP or we have a
  * 74[45]x and an MPC107 host bridge. Also 83xx and PowerQUICC II
  * require it for PCI "streaming/prefetch" to work properly.
+ * This is also required by 52xx family.
  */
 #if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE) \
-       || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260)
+       || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260) \
+       || defined(CONFIG_PPC_MPC52xx)
 #define CPU_FTR_COMMON                  CPU_FTR_NEED_COHERENT
 #else
 #define CPU_FTR_COMMON                  0
index a1c4cfd..7db2e42 100644 (file)
@@ -511,7 +511,7 @@ InstructionTLBMiss:
        and     r1,r1,r2                /* writable if _RW and _DIRTY */
        rlwimi  r3,r3,32-1,30,30        /* _PAGE_USER -> PP msb */
        rlwimi  r3,r3,32-1,31,31        /* _PAGE_USER -> PP lsb */
-       ori     r1,r1,0xe14             /* clear out reserved bits and M */
+       ori     r1,r1,0xe04             /* clear out reserved bits */
        andc    r1,r3,r1                /* PP = user? (rw&dirty? 2: 3): 0 */
        mtspr   SPRN_RPA,r1
        mfspr   r3,SPRN_IMISS
@@ -585,7 +585,7 @@ DataLoadTLBMiss:
        and     r1,r1,r2                /* writable if _RW and _DIRTY */
        rlwimi  r3,r3,32-1,30,30        /* _PAGE_USER -> PP msb */
        rlwimi  r3,r3,32-1,31,31        /* _PAGE_USER -> PP lsb */
-       ori     r1,r1,0xe14             /* clear out reserved bits and M */
+       ori     r1,r1,0xe04             /* clear out reserved bits */
        andc    r1,r3,r1                /* PP = user? (rw&dirty? 2: 3): 0 */
        mtspr   SPRN_RPA,r1
        mfspr   r3,SPRN_DMISS
@@ -653,7 +653,7 @@ DataStoreTLBMiss:
        stw     r3,0(r2)                /* update PTE (accessed/dirty bits) */
        /* Convert linux-style PTE to low word of PPC-style PTE */
        rlwimi  r3,r3,32-1,30,30        /* _PAGE_USER -> PP msb */
-       li      r1,0xe15                /* clear out reserved bits and M */
+       li      r1,0xe05                /* clear out reserved bits & PP lsb */
        andc    r1,r3,r1                /* PP = user? 2: 0 */
        mtspr   SPRN_RPA,r1
        mfspr   r3,SPRN_DMISS
index 920cf7a..740ef56 100644 (file)
@@ -128,6 +128,13 @@ config PS3_FLASH
          be disabled on the kernel command line using "ps3flash=off", to
          not allocate this fixed buffer.
 
+config PS3_VRAM
+       tristate "PS3 Video RAM Storage Driver"
+       depends on FB_PS3=y && BLOCK && m
+       help
+         This driver allows you to use excess PS3 video RAM as volatile
+         storage or system swap.
+
 config PS3_LPM
        tristate "PS3 Logical Performance Monitor support"
        depends on PPC_PS3
index 204332b..87e120e 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_MAC_FLOPPY)        += swim3.o
 obj-$(CONFIG_BLK_DEV_FD)       += floppy.o
 obj-$(CONFIG_AMIGA_FLOPPY)     += amiflop.o
 obj-$(CONFIG_PS3_DISK)         += ps3disk.o
+obj-$(CONFIG_PS3_VRAM)         += ps3vram.o
 obj-$(CONFIG_ATARI_FLOPPY)     += ataflop.o
 obj-$(CONFIG_AMIGA_Z2RAM)      += z2ram.o
 obj-$(CONFIG_BLK_DEV_RAM)      += brd.o
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
new file mode 100644 (file)
index 0000000..393ed67
--- /dev/null
@@ -0,0 +1,865 @@
+/*
+ * ps3vram - Use extra PS3 video ram as MTD block device.
+ *
+ * Copyright 2009 Sony Corporation
+ *
+ * Based on the MTD ps3vram driver, which is
+ * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
+ * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
+ */
+
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include <asm/firmware.h>
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+
+
+#define DEVICE_NAME            "ps3vram"
+
+
+#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
+#define XDR_IOIF 0x0c000000
+
+#define FIFO_BASE XDR_IOIF
+#define FIFO_SIZE (64 * 1024)
+
+#define DMA_PAGE_SIZE (4 * 1024)
+
+#define CACHE_PAGE_SIZE (256 * 1024)
+#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
+
+#define CACHE_OFFSET CACHE_PAGE_SIZE
+#define FIFO_OFFSET 0
+
+#define CTRL_PUT 0x10
+#define CTRL_GET 0x11
+#define CTRL_TOP 0x15
+
+#define UPLOAD_SUBCH   1
+#define DOWNLOAD_SUBCH 2
+
+#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN   0x0000030c
+#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY      0x00000104
+
+#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
+
+#define CACHE_PAGE_PRESENT 1
+#define CACHE_PAGE_DIRTY   2
+
+struct ps3vram_tag {
+       unsigned int address;
+       unsigned int flags;
+};
+
+struct ps3vram_cache {
+       unsigned int page_count;
+       unsigned int page_size;
+       struct ps3vram_tag *tags;
+       unsigned int hit;
+       unsigned int miss;
+};
+
+struct ps3vram_priv {
+       struct request_queue *queue;
+       struct gendisk *gendisk;
+
+       u64 size;
+
+       u64 memory_handle;
+       u64 context_handle;
+       u32 *ctrl;
+       u32 *reports;
+       u8 __iomem *ddr_base;
+       u8 *xdr_buf;
+
+       u32 *fifo_base;
+       u32 *fifo_ptr;
+
+       struct ps3vram_cache cache;
+
+       /* Used to serialize cache/DMA operations */
+       struct mutex lock;
+};
+
+
+static int ps3vram_major;
+
+
+static struct block_device_operations ps3vram_fops = {
+       .owner          = THIS_MODULE,
+};
+
+
+#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
+#define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */
+#define DMA_NOTIFIER_SIZE        0x40
+#define NOTIFIER 7     /* notifier used for completion report */
+
+static char *size = "256M";
+module_param(size, charp, 0);
+MODULE_PARM_DESC(size, "memory size");
+
+static u32 *ps3vram_get_notifier(u32 *reports, int notifier)
+{
+       return (void *)reports + DMA_NOTIFIER_OFFSET_BASE +
+              DMA_NOTIFIER_SIZE * notifier;
+}
+
+static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
+       int i;
+
+       for (i = 0; i < 4; i++)
+               notify[i] = 0xffffffff;
+}
+
+static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
+                                unsigned int timeout_ms)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
+       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+       do {
+               if (!notify[3])
+                       return 0;
+               msleep(1);
+       } while (time_before(jiffies, timeout));
+
+       return -ETIMEDOUT;
+}
+
+static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+
+       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
+       priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
+}
+
+static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
+                            unsigned int timeout_ms)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
+
+       do {
+               if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET])
+                       return 0;
+               msleep(1);
+       } while (time_before(jiffies, timeout));
+
+       dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n",
+                priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET],
+                priv->ctrl[CTRL_TOP]);
+
+       return -ETIMEDOUT;
+}
+
+static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
+{
+       *(priv->fifo_ptr)++ = data;
+}
+
+static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag,
+                              u32 size)
+{
+       ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
+}
+
+static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       int status;
+
+       ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
+
+       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
+
+       /* asking the HV for a blit will kick the FIFO */
+       status = lv1_gpu_context_attribute(priv->context_handle,
+                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
+                                          0, 0, 0);
+       if (status)
+               dev_err(&dev->core,
+                       "%s: lv1_gpu_context_attribute failed %d\n", __func__,
+                       status);
+
+       priv->fifo_ptr = priv->fifo_base;
+}
+
+static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       int status;
+
+       mutex_lock(&ps3_gpu_mutex);
+
+       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET +
+                              (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
+
+       /* asking the HV for a blit will kick the FIFO */
+       status = lv1_gpu_context_attribute(priv->context_handle,
+                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
+                                          0, 0, 0);
+       if (status)
+               dev_err(&dev->core,
+                       "%s: lv1_gpu_context_attribute failed %d\n", __func__,
+                       status);
+
+       if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
+           FIFO_SIZE - 1024) {
+               dev_dbg(&dev->core, "FIFO full, rewinding\n");
+               ps3vram_wait_ring(dev, 200);
+               ps3vram_rewind_ring(dev);
+       }
+
+       mutex_unlock(&ps3_gpu_mutex);
+}
+
+static void ps3vram_bind(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+
+       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
+       ps3vram_out_ring(priv, 0x31337303);
+       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
+       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
+       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
+       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
+
+       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
+       ps3vram_out_ring(priv, 0x3137c0de);
+       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
+       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
+       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
+       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
+
+       ps3vram_fire_ring(dev);
+}
+
+static int ps3vram_upload(struct ps3_system_bus_device *dev,
+                         unsigned int src_offset, unsigned int dst_offset,
+                         int len, int count)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+
+       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
+                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+       ps3vram_out_ring(priv, XDR_IOIF + src_offset);
+       ps3vram_out_ring(priv, dst_offset);
+       ps3vram_out_ring(priv, len);
+       ps3vram_out_ring(priv, len);
+       ps3vram_out_ring(priv, len);
+       ps3vram_out_ring(priv, count);
+       ps3vram_out_ring(priv, (1 << 8) | 1);
+       ps3vram_out_ring(priv, 0);
+
+       ps3vram_notifier_reset(dev);
+       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
+                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
+       ps3vram_out_ring(priv, 0);
+       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
+       ps3vram_out_ring(priv, 0);
+       ps3vram_fire_ring(dev);
+       if (ps3vram_notifier_wait(dev, 200) < 0) {
+               dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int ps3vram_download(struct ps3_system_bus_device *dev,
+                           unsigned int src_offset, unsigned int dst_offset,
+                           int len, int count)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+
+       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
+                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+       ps3vram_out_ring(priv, src_offset);
+       ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
+       ps3vram_out_ring(priv, len);
+       ps3vram_out_ring(priv, len);
+       ps3vram_out_ring(priv, len);
+       ps3vram_out_ring(priv, count);
+       ps3vram_out_ring(priv, (1 << 8) | 1);
+       ps3vram_out_ring(priv, 0);
+
+       ps3vram_notifier_reset(dev);
+       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
+                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
+       ps3vram_out_ring(priv, 0);
+       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
+       ps3vram_out_ring(priv, 0);
+       ps3vram_fire_ring(dev);
+       if (ps3vram_notifier_wait(dev, 200) < 0) {
+               dev_warn(&dev->core, "%s: Notifier timeout\n", __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       struct ps3vram_cache *cache = &priv->cache;
+
+       if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY))
+               return;
+
+       dev_dbg(&dev->core, "Flushing %d: 0x%08x\n", entry,
+               cache->tags[entry].address);
+       if (ps3vram_upload(dev, CACHE_OFFSET + entry * cache->page_size,
+                          cache->tags[entry].address, DMA_PAGE_SIZE,
+                          cache->page_size / DMA_PAGE_SIZE) < 0) {
+               dev_err(&dev->core,
+                       "Failed to upload from 0x%x to " "0x%x size 0x%x\n",
+                       entry * cache->page_size, cache->tags[entry].address,
+                       cache->page_size);
+       }
+       cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
+}
+
+static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
+                              unsigned int address)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       struct ps3vram_cache *cache = &priv->cache;
+
+       dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address);
+       if (ps3vram_download(dev, address,
+                            CACHE_OFFSET + entry * cache->page_size,
+                            DMA_PAGE_SIZE,
+                            cache->page_size / DMA_PAGE_SIZE) < 0) {
+               dev_err(&dev->core,
+                       "Failed to download from 0x%x to 0x%x size 0x%x\n",
+                       address, entry * cache->page_size, cache->page_size);
+       }
+
+       cache->tags[entry].address = address;
+       cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
+}
+
+
+static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       struct ps3vram_cache *cache = &priv->cache;
+       int i;
+
+       dev_dbg(&dev->core, "FLUSH\n");
+       for (i = 0; i < cache->page_count; i++) {
+               ps3vram_cache_evict(dev, i);
+               cache->tags[i].flags = 0;
+       }
+}
+
+static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
+                                       loff_t address)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       struct ps3vram_cache *cache = &priv->cache;
+       unsigned int base;
+       unsigned int offset;
+       int i;
+       static int counter;
+
+       offset = (unsigned int) (address & (cache->page_size - 1));
+       base = (unsigned int) (address - offset);
+
+       /* fully associative check */
+       for (i = 0; i < cache->page_count; i++) {
+               if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
+                   cache->tags[i].address == base) {
+                       cache->hit++;
+                       dev_dbg(&dev->core, "Found entry %d: 0x%08x\n", i,
+                               cache->tags[i].address);
+                       return i;
+               }
+       }
+
+       /* choose a random entry */
+       i = (jiffies + (counter++)) % cache->page_count;
+       dev_dbg(&dev->core, "Using entry %d\n", i);
+
+       ps3vram_cache_evict(dev, i);
+       ps3vram_cache_load(dev, i, base);
+
+       cache->miss++;
+       return i;
+}
+
+static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+
+       priv->cache.page_count = CACHE_PAGE_COUNT;
+       priv->cache.page_size = CACHE_PAGE_SIZE;
+       priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) *
+                                  CACHE_PAGE_COUNT, GFP_KERNEL);
+       if (priv->cache.tags == NULL) {
+               dev_err(&dev->core, "Could not allocate cache tags\n");
+               return -ENOMEM;
+       }
+
+       dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n",
+               CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
+
+       return 0;
+}
+
+static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+
+       ps3vram_cache_flush(dev);
+       kfree(priv->cache.tags);
+}
+
+static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
+                       size_t len, size_t *retlen, u_char *buf)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       unsigned int cached, count;
+
+       dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__,
+               (unsigned int)from, len);
+
+       if (from >= priv->size)
+               return -EIO;
+
+       if (len > priv->size - from)
+               len = priv->size - from;
+
+       /* Copy from vram to buf */
+       count = len;
+       while (count) {
+               unsigned int offset, avail;
+               unsigned int entry;
+
+               offset = (unsigned int) (from & (priv->cache.page_size - 1));
+               avail  = priv->cache.page_size - offset;
+
+               mutex_lock(&priv->lock);
+
+               entry = ps3vram_cache_match(dev, from);
+               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
+
+               dev_dbg(&dev->core, "%s: from=%08x cached=%08x offset=%08x "
+                       "avail=%08x count=%08x\n", __func__,
+                       (unsigned int)from, cached, offset, avail, count);
+
+               if (avail > count)
+                       avail = count;
+               memcpy(buf, priv->xdr_buf + cached, avail);
+
+               mutex_unlock(&priv->lock);
+
+               buf += avail;
+               count -= avail;
+               from += avail;
+       }
+
+       *retlen = len;
+       return 0;
+}
+
+static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
+                        size_t len, size_t *retlen, const u_char *buf)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       unsigned int cached, count;
+
+       if (to >= priv->size)
+               return -EIO;
+
+       if (len > priv->size - to)
+               len = priv->size - to;
+
+       /* Copy from buf to vram */
+       count = len;
+       while (count) {
+               unsigned int offset, avail;
+               unsigned int entry;
+
+               offset = (unsigned int) (to & (priv->cache.page_size - 1));
+               avail  = priv->cache.page_size - offset;
+
+               mutex_lock(&priv->lock);
+
+               entry = ps3vram_cache_match(dev, to);
+               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
+
+               dev_dbg(&dev->core, "%s: to=%08x cached=%08x offset=%08x "
+                       "avail=%08x count=%08x\n", __func__, (unsigned int)to,
+                       cached, offset, avail, count);
+
+               if (avail > count)
+                       avail = count;
+               memcpy(priv->xdr_buf + cached, buf, avail);
+
+               priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
+
+               mutex_unlock(&priv->lock);
+
+               buf += avail;
+               count -= avail;
+               to += avail;
+       }
+
+       *retlen = len;
+       return 0;
+}
+
+static int ps3vram_proc_show(struct seq_file *m, void *v)
+{
+       struct ps3vram_priv *priv = m->private;
+
+       seq_printf(m, "hit:%u\nmiss:%u\n", priv->cache.hit, priv->cache.miss);
+       return 0;
+}
+
+static int ps3vram_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ps3vram_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations ps3vram_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = ps3vram_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+       struct proc_dir_entry *pde;
+
+       pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops);
+       if (!pde) {
+               dev_warn(&dev->core, "failed to create /proc entry\n");
+               return;
+       }
+
+       pde->owner = THIS_MODULE;
+       pde->data = priv;
+}
+
+static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
+{
+       struct ps3_system_bus_device *dev = q->queuedata;
+       int write = bio_data_dir(bio) == WRITE;
+       const char *op = write ? "write" : "read";
+       loff_t offset = bio->bi_sector << 9;
+       int error = 0;
+       struct bio_vec *bvec;
+       unsigned int i;
+
+       dev_dbg(&dev->core, "%s\n", __func__);
+
+       bio_for_each_segment(bvec, bio, i) {
+               /* PS3 is ppc64, so we don't handle highmem */
+               char *ptr = page_address(bvec->bv_page) + bvec->bv_offset;
+               size_t len = bvec->bv_len, retlen;
+
+               dev_dbg(&dev->core, "    %s %zu bytes at offset %llu\n", op,
+                       len, offset);
+               if (write)
+                       error = ps3vram_write(dev, offset, len, &retlen, ptr);
+               else
+                       error = ps3vram_read(dev, offset, len, &retlen, ptr);
+
+               if (error) {
+                       dev_err(&dev->core, "%s failed\n", op);
+                       goto out;
+               }
+
+               if (retlen != len) {
+                       dev_err(&dev->core, "Short %s\n", op);
+                       goto out;
+               }
+
+               offset += len;
+       }
+
+       dev_dbg(&dev->core, "%s completed\n", op);
+
+out:
+       bio_endio(bio, error);
+       return 0;
+}
+
+static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv;
+       int error, status;
+       struct request_queue *queue;
+       struct gendisk *gendisk;
+       u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size,
+           reports_size;
+       char *rest;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               error = -ENOMEM;
+               goto fail;
+       }
+
+       mutex_init(&priv->lock);
+       dev->core.driver_data = priv;
+
+       priv = dev->core.driver_data;
+
+       /* Allocate XDR buffer (1MiB aligned) */
+       priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
+               get_order(XDR_BUF_SIZE));
+       if (priv->xdr_buf == NULL) {
+               dev_err(&dev->core, "Could not allocate XDR buffer\n");
+               error = -ENOMEM;
+               goto fail_free_priv;
+       }
+
+       /* Put FIFO at begginning of XDR buffer */
+       priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
+       priv->fifo_ptr = priv->fifo_base;
+
+       /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
+       if (ps3_open_hv_device(dev)) {
+               dev_err(&dev->core, "ps3_open_hv_device failed\n");
+               error = -EAGAIN;
+               goto out_close_gpu;
+       }
+
+       /* Request memory */
+       status = -1;
+       ddr_size = ALIGN(memparse(size, &rest), 1024*1024);
+       if (!ddr_size) {
+               dev_err(&dev->core, "Specified size is too small\n");
+               error = -EINVAL;
+               goto out_close_gpu;
+       }
+
+       while (ddr_size > 0) {
+               status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
+                                                &priv->memory_handle,
+                                                &ddr_lpar);
+               if (!status)
+                       break;
+               ddr_size -= 1024*1024;
+       }
+       if (status) {
+               dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n",
+                       status);
+               error = -ENOMEM;
+               goto out_free_xdr_buf;
+       }
+
+       /* Request context */
+       status = lv1_gpu_context_allocate(priv->memory_handle, 0,
+                                         &priv->context_handle, &ctrl_lpar,
+                                         &info_lpar, &reports_lpar,
+                                         &reports_size);
+       if (status) {
+               dev_err(&dev->core, "lv1_gpu_context_allocate failed %d\n",
+                       status);
+               error = -ENOMEM;
+               goto out_free_memory;
+       }
+
+       /* Map XDR buffer to RSX */
+       status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
+                                      ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
+                                      XDR_BUF_SIZE, 0);
+       if (status) {
+               dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n",
+                       status);
+               error = -ENOMEM;
+               goto out_free_context;
+       }
+
+       priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
+
+       if (!priv->ddr_base) {
+               dev_err(&dev->core, "ioremap DDR failed\n");
+               error = -ENOMEM;
+               goto out_free_context;
+       }
+
+       priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
+       if (!priv->ctrl) {
+               dev_err(&dev->core, "ioremap CTRL failed\n");
+               error = -ENOMEM;
+               goto out_unmap_vram;
+       }
+
+       priv->reports = ioremap(reports_lpar, reports_size);
+       if (!priv->reports) {
+               dev_err(&dev->core, "ioremap REPORTS failed\n");
+               error = -ENOMEM;
+               goto out_unmap_ctrl;
+       }
+
+       mutex_lock(&ps3_gpu_mutex);
+       ps3vram_init_ring(dev);
+       mutex_unlock(&ps3_gpu_mutex);
+
+       priv->size = ddr_size;
+
+       ps3vram_bind(dev);
+
+       mutex_lock(&ps3_gpu_mutex);
+       error = ps3vram_wait_ring(dev, 100);
+       mutex_unlock(&ps3_gpu_mutex);
+       if (error < 0) {
+               dev_err(&dev->core, "Failed to initialize channels\n");
+               error = -ETIMEDOUT;
+               goto out_unmap_reports;
+       }
+
+       ps3vram_cache_init(dev);
+       ps3vram_proc_init(dev);
+
+       queue = blk_alloc_queue(GFP_KERNEL);
+       if (!queue) {
+               dev_err(&dev->core, "blk_alloc_queue failed\n");
+               error = -ENOMEM;
+               goto out_cache_cleanup;
+       }
+
+       priv->queue = queue;
+       queue->queuedata = dev;
+       blk_queue_make_request(queue, ps3vram_make_request);
+       blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS);
+       blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS);
+       blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE);
+       blk_queue_max_sectors(queue, SAFE_MAX_SECTORS);
+
+       gendisk = alloc_disk(1);
+       if (!gendisk) {
+               dev_err(&dev->core, "alloc_disk failed\n");
+               error = -ENOMEM;
+               goto fail_cleanup_queue;
+       }
+
+       priv->gendisk = gendisk;
+       gendisk->major = ps3vram_major;
+       gendisk->first_minor = 0;
+       gendisk->fops = &ps3vram_fops;
+       gendisk->queue = queue;
+       gendisk->private_data = dev;
+       gendisk->driverfs_dev = &dev->core;
+       strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name));
+       set_capacity(gendisk, priv->size >> 9);
+
+       dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n",
+                gendisk->disk_name, get_capacity(gendisk) >> 11);
+
+       add_disk(gendisk);
+       return 0;
+
+fail_cleanup_queue:
+       blk_cleanup_queue(queue);
+out_cache_cleanup:
+       remove_proc_entry(DEVICE_NAME, NULL);
+       ps3vram_cache_cleanup(dev);
+out_unmap_reports:
+       iounmap(priv->reports);
+out_unmap_ctrl:
+       iounmap(priv->ctrl);
+out_unmap_vram:
+       iounmap(priv->ddr_base);
+out_free_context:
+       lv1_gpu_context_free(priv->context_handle);
+out_free_memory:
+       lv1_gpu_memory_free(priv->memory_handle);
+out_close_gpu:
+       ps3_close_hv_device(dev);
+out_free_xdr_buf:
+       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
+fail_free_priv:
+       kfree(priv);
+       dev->core.driver_data = NULL;
+fail:
+       return error;
+}
+
+static int ps3vram_remove(struct ps3_system_bus_device *dev)
+{
+       struct ps3vram_priv *priv = dev->core.driver_data;
+
+       del_gendisk(priv->gendisk);
+       put_disk(priv->gendisk);
+       blk_cleanup_queue(priv->queue);
+       remove_proc_entry(DEVICE_NAME, NULL);
+       ps3vram_cache_cleanup(dev);
+       iounmap(priv->reports);
+       iounmap(priv->ctrl);
+       iounmap(priv->ddr_base);
+       lv1_gpu_context_free(priv->context_handle);
+       lv1_gpu_memory_free(priv->memory_handle);
+       ps3_close_hv_device(dev);
+       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
+       kfree(priv);
+       dev->core.driver_data = NULL;
+       return 0;
+}
+
+static struct ps3_system_bus_driver ps3vram = {
+       .match_id       = PS3_MATCH_ID_GPU,
+       .match_sub_id   = PS3_MATCH_SUB_ID_GPU_RAMDISK,
+       .core.name      = DEVICE_NAME,
+       .core.owner     = THIS_MODULE,
+       .probe          = ps3vram_probe,
+       .remove         = ps3vram_remove,
+       .shutdown       = ps3vram_remove,
+};
+
+
+static int __init ps3vram_init(void)
+{
+       int error;
+
+       if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+               return -ENODEV;
+
+       error = register_blkdev(0, DEVICE_NAME);
+       if (error <= 0) {
+               pr_err("%s: register_blkdev failed %d\n", DEVICE_NAME, error);
+               return error;
+       }
+       ps3vram_major = error;
+
+       pr_info("%s: registered block device major %d\n", DEVICE_NAME,
+               ps3vram_major);
+
+       error = ps3_system_bus_driver_register(&ps3vram);
+       if (error)
+               unregister_blkdev(ps3vram_major, DEVICE_NAME);
+
+       return error;
+}
+
+static void __exit ps3vram_exit(void)
+{
+       ps3_system_bus_driver_unregister(&ps3vram);
+       unregister_blkdev(ps3vram_major, DEVICE_NAME);
+}
+
+module_init(ps3vram_init);
+module_exit(ps3vram_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PS3 Video RAM Storage Driver");
+MODULE_AUTHOR("Sony Corporation");
+MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);
index bc33200..6fde0a2 100644 (file)
@@ -120,13 +120,6 @@ config MTD_PHRAM
          doesn't have access to, memory beyond the mem=xxx limit, nvram,
          memory on the video card, etc...
 
-config MTD_PS3VRAM
-       tristate "PS3 video RAM"
-       depends on FB_PS3
-       help
-         This driver allows you to use excess PS3 video RAM as volatile
-         storage or system swap.
-
 config MTD_LART
        tristate "28F160xx flash driver for LART"
        depends on SA1100_LART
index e51521d..0993d5c 100644 (file)
@@ -16,4 +16,3 @@ obj-$(CONFIG_MTD_LART)                += lart.o
 obj-$(CONFIG_MTD_BLOCK2MTD)    += block2mtd.o
 obj-$(CONFIG_MTD_DATAFLASH)    += mtd_dataflash.o
 obj-$(CONFIG_MTD_M25P80)       += m25p80.o
-obj-$(CONFIG_MTD_PS3VRAM)      += ps3vram.o
diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c
deleted file mode 100644 (file)
index d21e9be..0000000
+++ /dev/null
@@ -1,768 +0,0 @@
-/**
- * ps3vram - Use extra PS3 video ram as MTD block device.
- *
- * Copyright (c) 2007-2008 Jim Paris <jim@jtan.com>
- * Added support RSX DMA Vivien Chappelier <vivien.chappelier@free.fr>
- */
-
-#include <linux/io.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/version.h>
-#include <linux/gfp.h>
-#include <linux/delay.h>
-#include <linux/mtd/mtd.h>
-
-#include <asm/lv1call.h>
-#include <asm/ps3.h>
-
-#define DEVICE_NAME            "ps3vram"
-
-#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */
-#define XDR_IOIF 0x0c000000
-
-#define FIFO_BASE XDR_IOIF
-#define FIFO_SIZE (64 * 1024)
-
-#define DMA_PAGE_SIZE (4 * 1024)
-
-#define CACHE_PAGE_SIZE (256 * 1024)
-#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE)
-
-#define CACHE_OFFSET CACHE_PAGE_SIZE
-#define FIFO_OFFSET 0
-
-#define CTRL_PUT 0x10
-#define CTRL_GET 0x11
-#define CTRL_TOP 0x15
-
-#define UPLOAD_SUBCH   1
-#define DOWNLOAD_SUBCH 2
-
-#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN   0x0000030c
-#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY      0x00000104
-
-#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
-
-struct mtd_info ps3vram_mtd;
-
-#define CACHE_PAGE_PRESENT 1
-#define CACHE_PAGE_DIRTY   2
-
-struct ps3vram_tag {
-       unsigned int address;
-       unsigned int flags;
-};
-
-struct ps3vram_cache {
-       unsigned int page_count;
-       unsigned int page_size;
-       struct ps3vram_tag *tags;
-};
-
-struct ps3vram_priv {
-       u64 memory_handle;
-       u64 context_handle;
-       u32 *ctrl;
-       u32 *reports;
-       u8 __iomem *ddr_base;
-       u8 *xdr_buf;
-
-       u32 *fifo_base;
-       u32 *fifo_ptr;
-
-       struct device *dev;
-       struct ps3vram_cache cache;
-
-       /* Used to serialize cache/DMA operations */
-       struct mutex lock;
-};
-
-#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */
-#define DMA_NOTIFIER_OFFSET_BASE 0x1000     /* first DMA notifier offset */
-#define DMA_NOTIFIER_SIZE        0x40
-#define NOTIFIER 7     /* notifier used for completion report */
-
-/* A trailing '-' means to subtract off ps3fb_videomemory.size */
-char *size = "256M-";
-module_param(size, charp, 0);
-MODULE_PARM_DESC(size, "memory size");
-
-static u32 *ps3vram_get_notifier(u32 *reports, int notifier)
-{
-       return (void *) reports +
-               DMA_NOTIFIER_OFFSET_BASE +
-               DMA_NOTIFIER_SIZE * notifier;
-}
-
-static void ps3vram_notifier_reset(struct mtd_info *mtd)
-{
-       int i;
-
-       struct ps3vram_priv *priv = mtd->priv;
-       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
-       for (i = 0; i < 4; i++)
-               notify[i] = 0xffffffff;
-}
-
-static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
-       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
-
-       do {
-               if (!notify[3])
-                       return 0;
-               msleep(1);
-       } while (time_before(jiffies, timeout));
-
-       return -ETIMEDOUT;
-}
-
-static void ps3vram_init_ring(struct mtd_info *mtd)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-
-       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
-       priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
-}
-
-static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
-
-       do {
-               if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET])
-                       return 0;
-               msleep(1);
-       } while (time_before(jiffies, timeout));
-
-       dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__,
-               __LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET],
-               priv->ctrl[CTRL_TOP]);
-
-       return -ETIMEDOUT;
-}
-
-static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data)
-{
-       *(priv->fifo_ptr)++ = data;
-}
-
-static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan,
-                                     u32 tag, u32 size)
-{
-       ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag);
-}
-
-static void ps3vram_rewind_ring(struct mtd_info *mtd)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       u64 status;
-
-       ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
-
-       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
-
-       /* asking the HV for a blit will kick the fifo */
-       status = lv1_gpu_context_attribute(priv->context_handle,
-                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
-                                          0, 0, 0, 0);
-       if (status)
-               dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
-                       __func__, __LINE__);
-
-       priv->fifo_ptr = priv->fifo_base;
-}
-
-static void ps3vram_fire_ring(struct mtd_info *mtd)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       u64 status;
-
-       mutex_lock(&ps3_gpu_mutex);
-
-       priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET +
-               (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
-
-       /* asking the HV for a blit will kick the fifo */
-       status = lv1_gpu_context_attribute(priv->context_handle,
-                                          L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
-                                          0, 0, 0, 0);
-       if (status)
-               dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n",
-                       __func__, __LINE__);
-
-       if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
-               FIFO_SIZE - 1024) {
-               dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__,
-                       __LINE__);
-               ps3vram_wait_ring(mtd, 200);
-               ps3vram_rewind_ring(mtd);
-       }
-
-       mutex_unlock(&ps3_gpu_mutex);
-}
-
-static void ps3vram_bind(struct mtd_info *mtd)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-
-       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
-       ps3vram_out_ring(priv, 0x31337303);
-       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3);
-       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
-       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
-       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
-
-       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1);
-       ps3vram_out_ring(priv, 0x3137c0de);
-       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3);
-       ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER);
-       ps3vram_out_ring(priv, 0xfeed0000);     /* DMA video RAM instance */
-       ps3vram_out_ring(priv, 0xfeed0001);     /* DMA system RAM instance */
-
-       ps3vram_fire_ring(mtd);
-}
-
-static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset,
-                         unsigned int dst_offset, int len, int count)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-
-       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
-                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
-       ps3vram_out_ring(priv, XDR_IOIF + src_offset);
-       ps3vram_out_ring(priv, dst_offset);
-       ps3vram_out_ring(priv, len);
-       ps3vram_out_ring(priv, len);
-       ps3vram_out_ring(priv, len);
-       ps3vram_out_ring(priv, count);
-       ps3vram_out_ring(priv, (1 << 8) | 1);
-       ps3vram_out_ring(priv, 0);
-
-       ps3vram_notifier_reset(mtd);
-       ps3vram_begin_ring(priv, UPLOAD_SUBCH,
-                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
-       ps3vram_out_ring(priv, 0);
-       ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1);
-       ps3vram_out_ring(priv, 0);
-       ps3vram_fire_ring(mtd);
-       if (ps3vram_notifier_wait(mtd, 200) < 0) {
-               dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
-                       __LINE__);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset,
-                           unsigned int dst_offset, int len, int count)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-
-       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
-                          NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
-       ps3vram_out_ring(priv, src_offset);
-       ps3vram_out_ring(priv, XDR_IOIF + dst_offset);
-       ps3vram_out_ring(priv, len);
-       ps3vram_out_ring(priv, len);
-       ps3vram_out_ring(priv, len);
-       ps3vram_out_ring(priv, count);
-       ps3vram_out_ring(priv, (1 << 8) | 1);
-       ps3vram_out_ring(priv, 0);
-
-       ps3vram_notifier_reset(mtd);
-       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
-                          NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
-       ps3vram_out_ring(priv, 0);
-       ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1);
-       ps3vram_out_ring(priv, 0);
-       ps3vram_fire_ring(mtd);
-       if (ps3vram_notifier_wait(mtd, 200) < 0) {
-               dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__,
-                       __LINE__);
-               return -1;
-       }
-
-       return 0;
-}
-
-static void ps3vram_cache_evict(struct mtd_info *mtd, int entry)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       struct ps3vram_cache *cache = &priv->cache;
-
-       if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) {
-               dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__,
-                       __LINE__, entry, cache->tags[entry].address);
-               if (ps3vram_upload(mtd,
-                                  CACHE_OFFSET + entry * cache->page_size,
-                                  cache->tags[entry].address,
-                                  DMA_PAGE_SIZE,
-                                  cache->page_size / DMA_PAGE_SIZE) < 0) {
-                       dev_dbg(priv->dev, "%s:%d: failed to upload from "
-                               "0x%x to 0x%x size 0x%x\n", __func__, __LINE__,
-                               entry * cache->page_size,
-                               cache->tags[entry].address, cache->page_size);
-               }
-               cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY;
-       }
-}
-
-static void ps3vram_cache_load(struct mtd_info *mtd, int entry,
-                              unsigned int address)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       struct ps3vram_cache *cache = &priv->cache;
-
-       dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__,
-               entry, address);
-       if (ps3vram_download(mtd,
-                            address,
-                            CACHE_OFFSET + entry * cache->page_size,
-                            DMA_PAGE_SIZE,
-                            cache->page_size / DMA_PAGE_SIZE) < 0) {
-               dev_err(priv->dev, "%s:%d: failed to download from "
-                       "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address,
-                       entry * cache->page_size, cache->page_size);
-       }
-
-       cache->tags[entry].address = address;
-       cache->tags[entry].flags |= CACHE_PAGE_PRESENT;
-}
-
-
-static void ps3vram_cache_flush(struct mtd_info *mtd)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       struct ps3vram_cache *cache = &priv->cache;
-       int i;
-
-       dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__);
-       for (i = 0; i < cache->page_count; i++) {
-               ps3vram_cache_evict(mtd, i);
-               cache->tags[i].flags = 0;
-       }
-}
-
-static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       struct ps3vram_cache *cache = &priv->cache;
-       unsigned int base;
-       unsigned int offset;
-       int i;
-       static int counter;
-
-       offset = (unsigned int) (address & (cache->page_size - 1));
-       base = (unsigned int) (address - offset);
-
-       /* fully associative check */
-       for (i = 0; i < cache->page_count; i++) {
-               if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) &&
-                   cache->tags[i].address == base) {
-                       dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n",
-                               __func__, __LINE__, i, cache->tags[i].address);
-                       return i;
-               }
-       }
-
-       /* choose a random entry */
-       i = (jiffies + (counter++)) % cache->page_count;
-       dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i);
-
-       ps3vram_cache_evict(mtd, i);
-       ps3vram_cache_load(mtd, i, base);
-
-       return i;
-}
-
-static int ps3vram_cache_init(struct mtd_info *mtd)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-
-       priv->cache.page_count = CACHE_PAGE_COUNT;
-       priv->cache.page_size = CACHE_PAGE_SIZE;
-       priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) *
-                                  CACHE_PAGE_COUNT, GFP_KERNEL);
-       if (priv->cache.tags == NULL) {
-               dev_err(priv->dev, "%s:%d: could not allocate cache tags\n",
-                       __func__, __LINE__);
-               return -ENOMEM;
-       }
-
-       dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n",
-               CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024);
-
-       return 0;
-}
-
-static void ps3vram_cache_cleanup(struct mtd_info *mtd)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-
-       ps3vram_cache_flush(mtd);
-       kfree(priv->cache.tags);
-}
-
-static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-
-       if (instr->addr + instr->len > mtd->size)
-               return -EINVAL;
-
-       mutex_lock(&priv->lock);
-
-       ps3vram_cache_flush(mtd);
-
-       /* Set bytes to 0xFF */
-       memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len);
-
-       mutex_unlock(&priv->lock);
-
-       instr->state = MTD_ERASE_DONE;
-       mtd_erase_callback(instr);
-
-       return 0;
-}
-
-static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len,
-                       size_t *retlen, u_char *buf)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       unsigned int cached, count;
-
-       dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__,
-               (unsigned int)from, len);
-
-       if (from >= mtd->size)
-               return -EINVAL;
-
-       if (len > mtd->size - from)
-               len = mtd->size - from;
-
-       /* Copy from vram to buf */
-       count = len;
-       while (count) {
-               unsigned int offset, avail;
-               unsigned int entry;
-
-               offset = (unsigned int) (from & (priv->cache.page_size - 1));
-               avail  = priv->cache.page_size - offset;
-
-               mutex_lock(&priv->lock);
-
-               entry = ps3vram_cache_match(mtd, from);
-               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
-
-               dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x "
-                       "avail=%08x count=%08x\n", __func__, __LINE__,
-                       (unsigned int)from, cached, offset, avail, count);
-
-               if (avail > count)
-                       avail = count;
-               memcpy(buf, priv->xdr_buf + cached, avail);
-
-               mutex_unlock(&priv->lock);
-
-               buf += avail;
-               count -= avail;
-               from += avail;
-       }
-
-       *retlen = len;
-       return 0;
-}
-
-static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len,
-                        size_t *retlen, const u_char *buf)
-{
-       struct ps3vram_priv *priv = mtd->priv;
-       unsigned int cached, count;
-
-       if (to >= mtd->size)
-               return -EINVAL;
-
-       if (len > mtd->size - to)
-               len = mtd->size - to;
-
-       /* Copy from buf to vram */
-       count = len;
-       while (count) {
-               unsigned int offset, avail;
-               unsigned int entry;
-
-               offset = (unsigned int) (to & (priv->cache.page_size - 1));
-               avail  = priv->cache.page_size - offset;
-
-               mutex_lock(&priv->lock);
-
-               entry = ps3vram_cache_match(mtd, to);
-               cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
-
-               dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x "
-                       "avail=%08x count=%08x\n", __func__, __LINE__,
-                       (unsigned int)to, cached, offset, avail, count);
-
-               if (avail > count)
-                       avail = count;
-               memcpy(priv->xdr_buf + cached, buf, avail);
-
-               priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
-
-               mutex_unlock(&priv->lock);
-
-               buf += avail;
-               count -= avail;
-               to += avail;
-       }
-
-       *retlen = len;
-       return 0;
-}
-
-static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
-{
-       struct ps3vram_priv *priv;
-       int status;
-       u64 ddr_lpar;
-       u64 ctrl_lpar;
-       u64 info_lpar;
-       u64 reports_lpar;
-       u64 ddr_size;
-       u64 reports_size;
-       int ret = -ENOMEM;
-       char *rest;
-
-       ret = -EIO;
-       ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL);
-       if (!ps3vram_mtd.priv)
-               goto out;
-       priv = ps3vram_mtd.priv;
-
-       mutex_init(&priv->lock);
-       priv->dev = &dev->core;
-
-       /* Allocate XDR buffer (1MiB aligned) */
-       priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
-               get_order(XDR_BUF_SIZE));
-       if (priv->xdr_buf == NULL) {
-               dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n",
-                       __func__, __LINE__);
-               ret = -ENOMEM;
-               goto out_free_priv;
-       }
-
-       /* Put FIFO at begginning of XDR buffer */
-       priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET);
-       priv->fifo_ptr = priv->fifo_base;
-
-       /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */
-       if (ps3_open_hv_device(dev)) {
-               dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
-                       __func__, __LINE__);
-               ret = -EAGAIN;
-               goto out_close_gpu;
-       }
-
-       /* Request memory */
-       status = -1;
-       ddr_size = memparse(size, &rest);
-       if (*rest == '-')
-               ddr_size -= ps3fb_videomemory.size;
-       ddr_size = ALIGN(ddr_size, 1024*1024);
-       if (ddr_size <= 0) {
-               dev_err(&dev->core, "%s:%d: specified size is too small\n",
-                       __func__, __LINE__);
-               ret = -EINVAL;
-               goto out_close_gpu;
-       }
-
-       while (ddr_size > 0) {
-               status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0,
-                                                &priv->memory_handle,
-                                                &ddr_lpar);
-               if (!status)
-                       break;
-               ddr_size -= 1024*1024;
-       }
-       if (status || ddr_size <= 0) {
-               dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n",
-                       __func__, __LINE__);
-               ret = -ENOMEM;
-               goto out_free_xdr_buf;
-       }
-
-       /* Request context */
-       status = lv1_gpu_context_allocate(priv->memory_handle,
-                                         0,
-                                         &priv->context_handle,
-                                         &ctrl_lpar,
-                                         &info_lpar,
-                                         &reports_lpar,
-                                         &reports_size);
-       if (status) {
-               dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n",
-                       __func__, __LINE__);
-               ret = -ENOMEM;
-               goto out_free_memory;
-       }
-
-       /* Map XDR buffer to RSX */
-       status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
-                                      ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
-                                      XDR_BUF_SIZE, 0);
-       if (status) {
-               dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n",
-                       __func__, __LINE__);
-               ret = -ENOMEM;
-               goto out_free_context;
-       }
-
-       priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
-
-       if (!priv->ddr_base) {
-               dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
-                       __LINE__);
-               ret = -ENOMEM;
-               goto out_free_context;
-       }
-
-       priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
-       if (!priv->ctrl) {
-               dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
-                       __LINE__);
-               ret = -ENOMEM;
-               goto out_unmap_vram;
-       }
-
-       priv->reports = ioremap(reports_lpar, reports_size);
-       if (!priv->reports) {
-               dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__,
-                       __LINE__);
-               ret = -ENOMEM;
-               goto out_unmap_ctrl;
-       }
-
-       mutex_lock(&ps3_gpu_mutex);
-       ps3vram_init_ring(&ps3vram_mtd);
-       mutex_unlock(&ps3_gpu_mutex);
-
-       ps3vram_mtd.name = "ps3vram";
-       ps3vram_mtd.size = ddr_size;
-       ps3vram_mtd.flags = MTD_CAP_RAM;
-       ps3vram_mtd.erase = ps3vram_erase;
-       ps3vram_mtd.point = NULL;
-       ps3vram_mtd.unpoint = NULL;
-       ps3vram_mtd.read = ps3vram_read;
-       ps3vram_mtd.write = ps3vram_write;
-       ps3vram_mtd.owner = THIS_MODULE;
-       ps3vram_mtd.type = MTD_RAM;
-       ps3vram_mtd.erasesize = CACHE_PAGE_SIZE;
-       ps3vram_mtd.writesize = 1;
-
-       ps3vram_bind(&ps3vram_mtd);
-
-       mutex_lock(&ps3_gpu_mutex);
-       ret = ps3vram_wait_ring(&ps3vram_mtd, 100);
-       mutex_unlock(&ps3_gpu_mutex);
-       if (ret < 0) {
-               dev_err(&dev->core, "%s:%d: failed to initialize channels\n",
-                       __func__, __LINE__);
-               ret = -ETIMEDOUT;
-               goto out_unmap_reports;
-       }
-
-       ps3vram_cache_init(&ps3vram_mtd);
-
-       if (add_mtd_device(&ps3vram_mtd)) {
-               dev_err(&dev->core, "%s:%d: add_mtd_device failed\n",
-                       __func__, __LINE__);
-               ret = -EAGAIN;
-               goto out_cache_cleanup;
-       }
-
-       dev_info(&dev->core, "reserved %u MiB of gpu memory\n",
-               (unsigned int)(ddr_size / 1024 / 1024));
-
-       return 0;
-
-out_cache_cleanup:
-       ps3vram_cache_cleanup(&ps3vram_mtd);
-out_unmap_reports:
-       iounmap(priv->reports);
-out_unmap_ctrl:
-       iounmap(priv->ctrl);
-out_unmap_vram:
-       iounmap(priv->ddr_base);
-out_free_context:
-       lv1_gpu_context_free(priv->context_handle);
-out_free_memory:
-       lv1_gpu_memory_free(priv->memory_handle);
-out_close_gpu:
-       ps3_close_hv_device(dev);
-out_free_xdr_buf:
-       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
-out_free_priv:
-       kfree(ps3vram_mtd.priv);
-       ps3vram_mtd.priv = NULL;
-out:
-       return ret;
-}
-
-static int ps3vram_shutdown(struct ps3_system_bus_device *dev)
-{
-       struct ps3vram_priv *priv;
-
-       priv = ps3vram_mtd.priv;
-
-       del_mtd_device(&ps3vram_mtd);
-       ps3vram_cache_cleanup(&ps3vram_mtd);
-       iounmap(priv->reports);
-       iounmap(priv->ctrl);
-       iounmap(priv->ddr_base);
-       lv1_gpu_context_free(priv->context_handle);
-       lv1_gpu_memory_free(priv->memory_handle);
-       ps3_close_hv_device(dev);
-       free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
-       kfree(priv);
-       return 0;
-}
-
-static struct ps3_system_bus_driver ps3vram_driver = {
-       .match_id       = PS3_MATCH_ID_GPU,
-       .match_sub_id   = PS3_MATCH_SUB_ID_GPU_RAMDISK,
-       .core.name      = DEVICE_NAME,
-       .core.owner     = THIS_MODULE,
-       .probe          = ps3vram_probe,
-       .remove         = ps3vram_shutdown,
-       .shutdown       = ps3vram_shutdown,
-};
-
-static int __init ps3vram_init(void)
-{
-       return ps3_system_bus_driver_register(&ps3vram_driver);
-}
-
-static void __exit ps3vram_exit(void)
-{
-       ps3_system_bus_driver_unregister(&ps3vram_driver);
-}
-
-module_init(ps3vram_init);
-module_exit(ps3vram_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jim Paris <jim@jtan.com>");
-MODULE_DESCRIPTION("MTD driver for PS3 video RAM");
-MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK);
index 5ed4ae0..6789089 100644 (file)
@@ -485,7 +485,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
                        usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n",
                                wbuflen, rbuflen);
                ret = -ENOMEM;
-               goto fail;
+               goto err;
        }
 
        mutex_lock(&instance->cm_serialize);
@@ -565,6 +565,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
        dbg("cm %#x", cm);
 fail:
        mutex_unlock(&instance->cm_serialize);
+err:
        return ret;
 }
 
index 0f5c05f..c40a9b2 100644 (file)
@@ -50,6 +50,7 @@
 
 static struct usb_device_id usbtmc_devices[] = {
        { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), },
+       { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), },
        { 0, } /* terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, usbtmc_devices);
@@ -106,12 +107,13 @@ static int usbtmc_open(struct inode *inode, struct file *filp)
 {
        struct usb_interface *intf;
        struct usbtmc_device_data *data;
-       int retval = -ENODEV;
+       int retval = 0;
 
        intf = usb_find_interface(&usbtmc_driver, iminor(inode));
        if (!intf) {
                printk(KERN_ERR KBUILD_MODNAME
                       ": can not find device for minor %d", iminor(inode));
+               retval = -ENODEV;
                goto exit;
        }
 
index 7513bb0..6585f52 100644 (file)
@@ -359,11 +359,6 @@ static void destroy_async(struct dev_state *ps, struct list_head *list)
                spin_lock_irqsave(&ps->lock, flags);
        }
        spin_unlock_irqrestore(&ps->lock, flags);
-       as = async_getcompleted(ps);
-       while (as) {
-               free_async(as);
-               as = async_getcompleted(ps);
-       }
 }
 
 static void destroy_async_on_interface(struct dev_state *ps,
@@ -643,6 +638,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
        struct dev_state *ps = file->private_data;
        struct usb_device *dev = ps->dev;
        unsigned int ifnum;
+       struct async *as;
 
        usb_lock_device(dev);
 
@@ -661,6 +657,12 @@ static int usbdev_release(struct inode *inode, struct file *file)
        usb_unlock_device(dev);
        usb_put_dev(dev);
        put_pid(ps->disc_pid);
+
+       as = async_getcompleted(ps);
+       while (as) {
+               free_async(as);
+               as = async_getcompleted(ps);
+       }
        kfree(ps);
        return 0;
 }
index 3712b92..ecc9b66 100644 (file)
@@ -1095,7 +1095,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        prev->qh_next = qh->qh_next;
        wmb ();
 
-       if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) {
+       /* If the controller isn't running, we don't have to wait for it */
+       if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) {
                /* if (unlikely (qh->reclaim != 0))
                 *      this will recurse, probably not much
                 */
index 07bcb93..1d0b49e 100644 (file)
@@ -1536,7 +1536,7 @@ itd_link_urb (
                                        struct ehci_itd, itd_list);
                        list_move_tail (&itd->itd_list, &stream->td_list);
                        itd->stream = iso_stream_get (stream);
-                       itd->urb = usb_get_urb (urb);
+                       itd->urb = urb;
                        itd_init (ehci, stream, itd);
                }
 
@@ -1645,7 +1645,7 @@ itd_complete (
        (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
-       if (unlikely (list_empty (&stream->td_list))) {
+       if (unlikely(list_is_singular(&stream->td_list))) {
                ehci_to_hcd(ehci)->self.bandwidth_allocated
                                -= stream->bandwidth;
                ehci_vdbg (ehci,
@@ -1656,7 +1656,6 @@ itd_complete (
        iso_stream_put (ehci, stream);
 
 done:
-       usb_put_urb(urb);
        itd->urb = NULL;
        if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
                /* OK to recycle this ITD now. */
@@ -1949,7 +1948,7 @@ sitd_link_urb (
                                struct ehci_sitd, sitd_list);
                list_move_tail (&sitd->sitd_list, &stream->td_list);
                sitd->stream = iso_stream_get (stream);
-               sitd->urb = usb_get_urb (urb);
+               sitd->urb = urb;
 
                sitd_patch(ehci, stream, sitd, sched, packet);
                sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size,
@@ -2034,7 +2033,7 @@ sitd_complete (
        (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
-       if (list_empty (&stream->td_list)) {
+       if (list_is_singular(&stream->td_list)) {
                ehci_to_hcd(ehci)->self.bandwidth_allocated
                                -= stream->bandwidth;
                ehci_vdbg (ehci,
@@ -2045,7 +2044,6 @@ sitd_complete (
        iso_stream_put (ehci, stream);
        /* OK to recycle this SITD now that its completion callback ran. */
 done:
-       usb_put_urb(urb);
        sitd->urb = NULL;
        sitd->stream = NULL;
        list_move(&sitd->sitd_list, &stream->free_list);
index 878c77c..972f20b 100644 (file)
@@ -499,6 +499,7 @@ static int mdc800_usb_probe (struct usb_interface *intf,
        retval = usb_register_dev(intf, &mdc800_class);
        if (retval) {
                dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+               mutex_unlock(&mdc800->io_lock);
                return -ENODEV;
        }
 
index 7b6922e..2035265 100644 (file)
@@ -376,7 +376,7 @@ static int adu_release(struct inode *inode, struct file *file)
        if (dev->open_count <= 0) {
                dbg(1," %s : device not opened", __func__);
                retval = -ENODEV;
-               goto exit;
+               goto unlock;
        }
 
        adu_release_internal(dev);
@@ -385,9 +385,9 @@ static int adu_release(struct inode *inode, struct file *file)
                if (!dev->open_count)   /* ... and we're the last user */
                        adu_delete(dev);
        }
-
-exit:
+unlock:
        mutex_unlock(&adutux_mutex);
+exit:
        dbg(2," %s : leave, return value %d", __func__, retval);
        return retval;
 }
index 63dff9b..f26ea8d 100644 (file)
@@ -401,6 +401,7 @@ static ssize_t vstusb_write(struct file *file, const char __user *buffer,
        }
 
        if (copy_from_user(buf, buffer, count)) {
+               mutex_unlock(&vstdev->lock);
                dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__);
                retval = -EFAULT;
                goto exit;
index 027f4b7..9b4082b 100644 (file)
@@ -79,6 +79,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
+       { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
        { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
        { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
        { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
index f92f4d7..ae84c32 100644 (file)
@@ -663,6 +663,11 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
        { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
+       { USB_DEVICE(ATMEL_VID, STK541_PID) },
+       { USB_DEVICE(DE_VID, STB_PID) },
+       { USB_DEVICE(DE_VID, WHT_PID) },
+       { USB_DEVICE(ADI_VID, ADI_GNICE_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index e300c84..daaf63d 100644 (file)
 #define DIEBOLD_BCS_SE923_PID  0xfb99
 
 /*
+ * Atmel STK541
+ */
+#define ATMEL_VID              0x03eb /* Vendor ID */
+#define STK541_PID             0x2109 /* Zigbee Controller */
+
+/*
+ * Dresden Elektronic Sensor Terminal Board
+ */
+#define DE_VID                 0x1cf1 /* Vendor ID */
+#define STB_PID                        0x0001 /* Sensor Terminal Board */
+#define WHT_PID                        0x0004 /* Wireless Handheld Terminal */
+
+/*
+ * Blackfin gnICE JTAG
+ * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice
+ */
+#define ADI_VID                0x0456
+#define ADI_GNICE_PID          0xF000
+
+/*
  *   BmRequestType:  1100 0000b
  *   bRequest:       FTDI_E2_READ
  *   wValue:         0
index b7c132b..61ebddc 100644 (file)
@@ -89,6 +89,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 #define OPTION_PRODUCT_ETNA_MODEM_GT           0x7041
 #define OPTION_PRODUCT_ETNA_MODEM_EX           0x7061
 #define OPTION_PRODUCT_ETNA_KOI_MODEM          0x7100
+#define OPTION_PRODUCT_GTM380_MODEM            0x7201
 
 #define HUAWEI_VENDOR_ID                       0x12D1
 #define HUAWEI_PRODUCT_E600                    0x1001
@@ -197,6 +198,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 /* OVATION PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_MC727          0x4100
 #define NOVATELWIRELESS_PRODUCT_MC950D         0x4400
+#define NOVATELWIRELESS_PRODUCT_U727           0x5010
 
 /* FUTURE NOVATEL PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000
@@ -288,15 +290,11 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID                          0x19d2
+#define ZTE_PRODUCT_MF622                      0x0001
 #define ZTE_PRODUCT_MF628                      0x0015
 #define ZTE_PRODUCT_MF626                      0x0031
 #define ZTE_PRODUCT_CDMA_TECH                  0xfffe
 
-/* Ericsson products */
-#define ERICSSON_VENDOR_ID                     0x0bdb
-#define ERICSSON_PRODUCT_F3507G_1              0x1900
-#define ERICSSON_PRODUCT_F3507G_2              0x1902
-
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
 
@@ -325,6 +323,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
+       { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) },
        { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) },
        { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) },
        { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) },
@@ -415,6 +414,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
@@ -442,7 +442,6 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) },    /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) },   /* Dell Wireless HSDPA 5520 */
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) },   /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8147) },                                 /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) },      /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) },       /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
        { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) },         /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
@@ -510,11 +509,10 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
        { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
-       { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_1) },
-       { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_2) },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
        { } /* Terminating entry */
index 6f59c8e..cfde74a 100644 (file)
@@ -226,7 +226,7 @@ UNUSUAL_DEV(  0x0421, 0x047c, 0x0370, 0x0610,
                US_FL_MAX_SECTORS_64 ),
 
 /* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */
-UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452,
+UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999,
                "Nokia",
                "Nokia 6233",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -951,7 +951,9 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001,
                US_FL_FIX_CAPACITY ),
 
 /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */
-UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100,
+/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by
+ * Thomas Bartosik <tbartdev@gmx-topmail.de> */
+UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100,
                "Prolific Technology Inc.",
                "Mass Storage Device",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -1390,6 +1392,16 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                0 ),
 
+/* Reported by Jan Dumon <j.dumon@option.com>
+ * This device (wrongly) has a vendor-specific device descriptor.
+ * The entry is needed so usb-storage can bind to it's mass-storage
+ * interface as an interface driver */
+UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000,
+               "Option",
+               "GI 0431 SD-Card",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               0 ),
+
 /* Reported by Ben Efros <ben@pc-doctor.com> */
 UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000,
                "Seagate",
index 238a96a..613a5fc 100644 (file)
@@ -921,8 +921,10 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
        result = -ENODEV;
        /* FIXME: segmentation broken -- kills DWA */
        mutex_lock(&wusbhc->mutex);             /* get a WUSB dev */
-       if (urb->dev == NULL)
+       if (urb->dev == NULL) {
+               mutex_unlock(&wusbhc->mutex);
                goto error_dev_gone;
+       }
        wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
        if (wusb_dev == NULL) {
                mutex_unlock(&wusbhc->mutex);
index e2eab19..e0aa4fe 100644 (file)
@@ -1122,7 +1122,8 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
        struct ext4_extent_idx *ix;
        struct ext4_extent *ex;
        ext4_fsblk_t block;
-       int depth, ee_len;
+       int depth;      /* Note, NOT eh_depth; depth from top of tree */
+       int ee_len;
 
        BUG_ON(path == NULL);
        depth = path->p_depth;
@@ -1179,7 +1180,8 @@ got_index:
                if (bh == NULL)
                        return -EIO;
                eh = ext_block_hdr(bh);
-               if (ext4_ext_check_header(inode, eh, depth)) {
+               /* subtract from p_depth to get proper eh_depth */
+               if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) {
                        put_bh(bh);
                        return -EIO;
                }
index 627f8c3..2d2b358 100644 (file)
@@ -698,6 +698,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
        struct inode *ret;
        ext4_group_t i;
        int free = 0;
+       static int once = 1;
        ext4_group_t flex_group;
 
        /* Cannot create files in a deleted directory */
@@ -719,7 +720,8 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
                ret2 = find_group_flex(sb, dir, &group);
                if (ret2 == -1) {
                        ret2 = find_group_other(sb, dir, &group);
-                       if (ret2 == 0 && printk_ratelimit())
+                       if (ret2 == 0 && once)
+                               once = 0;
                                printk(KERN_NOTICE "ext4: find_group_flex "
                                       "failed, fallback succeeded dir %lu\n",
                                       dir->i_ino);
index 4415bee..9f61e62 100644 (file)
@@ -1447,7 +1447,7 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac,
        struct ext4_free_extent *gex = &ac->ac_g_ex;
 
        BUG_ON(ex->fe_len <= 0);
-       BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
+       BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
        BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
        BUG_ON(ac->ac_status != AC_STATUS_CONTINUE);
 
@@ -3292,7 +3292,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
        }
        BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
                        start > ac->ac_o_ex.fe_logical);
-       BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
+       BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
 
        /* now prepare goal request */
 
@@ -3589,6 +3589,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
                        struct super_block *sb, struct ext4_prealloc_space *pa)
 {
        ext4_group_t grp;
+       ext4_fsblk_t grp_blk;
 
        if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)
                return;
@@ -3603,8 +3604,12 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
        pa->pa_deleted = 1;
        spin_unlock(&pa->pa_lock);
 
-       /* -1 is to protect from crossing allocation group */
-       ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL);
+       grp_blk = pa->pa_pstart;
+       /* If linear, pa_pstart may be in the next group when pa is used up */
+       if (pa->pa_linear)
+               grp_blk--;
+
+       ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL);
 
        /*
         * possible race:
index ba22484..1196f5d 100644 (file)
@@ -2015,14 +2015,6 @@ static noinline struct module *load_module(void __user *umod,
        if (err < 0)
                goto free_mod;
 
-#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
-       mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t),
-                                     mod->name);
-       if (!mod->refptr) {
-               err = -ENOMEM;
-               goto free_mod;
-       }
-#endif
        if (pcpuindex) {
                /* We have a special allocation for this section. */
                percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
@@ -2030,7 +2022,7 @@ static noinline struct module *load_module(void __user *umod,
                                         mod->name);
                if (!percpu) {
                        err = -ENOMEM;
-                       goto free_percpu;
+                       goto free_mod;
                }
                sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
                mod->percpu = percpu;
@@ -2082,6 +2074,14 @@ static noinline struct module *load_module(void __user *umod,
        /* Module has been moved. */
        mod = (void *)sechdrs[modindex].sh_addr;
 
+#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+       mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t),
+                                     mod->name);
+       if (!mod->refptr) {
+               err = -ENOMEM;
+               goto free_init;
+       }
+#endif
        /* Now we've moved module, initialize linked lists, etc. */
        module_unload_init(mod);
 
@@ -2288,15 +2288,17 @@ static noinline struct module *load_module(void __user *umod,
        ftrace_release(mod->module_core, mod->core_size);
  free_unload:
        module_unload_free(mod);
+ free_init:
+#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+       percpu_modfree(mod->refptr);
+#endif
        module_free(mod, mod->module_init);
  free_core:
        module_free(mod, mod->module_core);
+       /* mod will be freed with core. Don't access it beyond this line! */
  free_percpu:
        if (percpu)
                percpu_modfree(percpu);
-#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
-       percpu_modfree(mod->refptr);
-#endif
  free_mod:
        kfree(args);
  free_hdr:
index 4690b8b..e570649 100644 (file)
@@ -692,6 +692,9 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
                snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
                if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME)
                        snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
+       } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) {
+               snd_mixer_oss_put_volume1_vol(fmixer, pslot,
+                       slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
        } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {
                snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right);
        } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) {
index 0a1798e..699d289 100644 (file)
@@ -2872,7 +2872,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
                        setup = kmalloc(sizeof(*setup), GFP_KERNEL);
                        if (! setup) {
                                buffer->error = -ENOMEM;
-                               mutex_lock(&pstr->oss.setup_mutex);
+                               mutex_unlock(&pstr->oss.setup_mutex);
                                return;
                        }
                        if (pstr->oss.setup_list == NULL)
@@ -2886,7 +2886,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
                        if (! template.task_name) {
                                kfree(setup);
                                buffer->error = -ENOMEM;
-                               mutex_lock(&pstr->oss.setup_mutex);
+                               mutex_unlock(&pstr->oss.setup_mutex);
                                return;
                        }
                }
index d4564ed..4e7ec2b 100644 (file)
@@ -38,6 +38,10 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
        if (! sgbuf)
                return -EINVAL;
 
+       if (dmab->area)
+               vunmap(dmab->area);
+       dmab->area = NULL;
+
        tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
        tmpb.dev.dev = sgbuf->dev;
        for (i = 0; i < sgbuf->pages; i++) {
@@ -48,9 +52,6 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
                tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
                snd_dma_free_pages(&tmpb);
        }
-       if (dmab->area)
-               vunmap(dmab->area);
-       dmab->area = NULL;
 
        kfree(sgbuf->table);
        kfree(sgbuf->page_table);
index 58c972b..b848d10 100644 (file)
@@ -550,21 +550,27 @@ static int __devinit snd_opl3sa2_mixer(struct snd_card *card)
 #ifdef CONFIG_PM
 static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
 {
-       struct snd_opl3sa2 *chip = card->private_data;
+       if (card) {
+               struct snd_opl3sa2 *chip = card->private_data;
 
-       snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-       chip->wss->suspend(chip->wss);
-       /* power down */
-       snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
+               snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+               chip->wss->suspend(chip->wss);
+               /* power down */
+               snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
+       }
 
        return 0;
 }
 
 static int snd_opl3sa2_resume(struct snd_card *card)
 {
-       struct snd_opl3sa2 *chip = card->private_data;
+       struct snd_opl3sa2 *chip;
        int i;
 
+       if (!card)
+               return 0;
+
+       chip = card->private_data;
        /* power up */
        snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0);
 
index 5e909e0..f3b5723 100644 (file)
@@ -2059,26 +2059,31 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
 {
        const struct snd_pci_quirk *q;
 
-       /* Check VIA HD Audio Controller exist */
-       if (chip->pci->vendor == PCI_VENDOR_ID_VIA &&
-           chip->pci->device == VIA_HDAC_DEVICE_ID) {
+       switch (fix) {
+       case POS_FIX_LPIB:
+       case POS_FIX_POSBUF:
+               return fix;
+       }
+
+       /* Check VIA/ATI HD Audio Controller exist */
+       switch (chip->driver_type) {
+       case AZX_DRIVER_VIA:
+       case AZX_DRIVER_ATI:
                chip->via_dmapos_patch = 1;
                /* Use link position directly, avoid any transfer problem. */
                return POS_FIX_LPIB;
        }
        chip->via_dmapos_patch = 0;
 
-       if (fix == POS_FIX_AUTO) {
-               q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
-               if (q) {
-                       printk(KERN_INFO
-                                   "hda_intel: position_fix set to %d "
-                                   "for device %04x:%04x\n",
-                                   q->value, q->subvendor, q->subdevice);
-                       return q->value;
-               }
+       q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
+       if (q) {
+               printk(KERN_INFO
+                      "hda_intel: position_fix set to %d "
+                      "for device %04x:%04x\n",
+                      q->value, q->subvendor, q->subdevice);
+               return q->value;
        }
-       return fix;
+       return POS_FIX_AUTO;
 }
 
 /*
@@ -2210,9 +2215,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
        gcap = azx_readw(chip, GCAP);
        snd_printdd("chipset global capabilities = 0x%x\n", gcap);
 
+       /* ATI chips seems buggy about 64bit DMA addresses */
+       if (chip->driver_type == AZX_DRIVER_ATI)
+               gcap &= ~0x01;
+
        /* allow 64bit DMA address if supported by H/W */
        if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK))
                pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK);
+       else {
+               pci_set_dma_mask(pci, DMA_32BIT_MASK);
+               pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK);
+       }
 
        /* read number of streams from GCAP register instead of using
         * hardcoded value
index f23a735..bb16250 100644 (file)
@@ -607,6 +607,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs,
        /* set the format to the board */
        err = mixart_set_format(stream, format);
        if(err < 0) {
+               mutex_unlock(&mgr->setup_mutex);
                return err;
        }